Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: support derive key example #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions derive-key-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const assert = require('assert')
const { secp256k1, BN, SHA256 } = require('bcrypto')

const lightning = require('./src/index.js')

const LND_SOCKET = 'localhost:10009' // should be socket where your node is running
const LND_MACAROON = 'admin.macaroon' // should be absolute path to your macaroon file
const LND_CERT = 'tls.cert' // abs path to cert file

lightning.setCredentials(LND_SOCKET, LND_MACAROON, LND_CERT)

let client = lightning.lightning()
let wallet = lightning.wallet()

// key derivation function, using simple sha256 hash
function kdf(data) {
assert(Buffer.isBuffer(data), 'Must pass a buffer to be hashed')
return SHA256.digest(data)
}

function pubKeyToPoint(pubKey) {
const s = BN.fromBuffer(pubKey).isOdd()
const x = BN.fromBuffer(pubKey.slice(1, 33))
return secp256k1.curve.pointFromX(x, s)
}

;(async function() {
try {
const { identity_pubkey } = await client.getInfoAsync({})

// get the public key point coordinates for the authorizing lnd node
const pubKeyN = Buffer.from(identity_pubkey, 'hex')
const pubKeyNPoint = pubKeyToPoint(pubKeyN)

// get ephemeral keys for generating shared secret
const ephemeralPriv = secp256k1.privateKeyGenerate()
const ephemeralPub = secp256k1.publicKeyCreate(ephemeralPriv, true)
const ephemeralPubBuff = secp256k1.publicKeyConvert(ephemeralPub, true)

// multiply node's public key by our ephemeral private key to generate shared pub key
const sharedPubKey = pubKeyNPoint.mul(BN.fromBuffer(ephemeralPriv))

// generate shared key by using our chosen KDF (Key Derivation Function)
const sharedKey = kdf(sharedPubKey.encode(true)) // must encode (compressed) pubkey as a Buffer

// get shared key from node with ephemeral pubkey
const { shared_key: derivedKey } = await wallet.deriveSharedKeyAsync({ ephemeral_pubkey: ephemeralPubBuff })

// assert that the derived shared key from the node is the same as
// the one generated with the ephemeral key pair
assert(sharedKey.toString('hex') === derivedKey.toString('hex'), 'Keys did not match!')

console.log('Success!')
console.log('Shared key:', sharedKey.toString('hex'))
} catch (e) {
console.error(e)
}
})()
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
},
"dependencies": {
"@grpc/proto-loader": "^0.5.2",
"bcrypto": "^4.2.9",
"bluebird": "^3.5.5",
"grpc": "^1.23.3",
"is-base64": "1.0.0"
Expand Down
40 changes: 19 additions & 21 deletions src/walletkit.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,7 @@ message KeyReq {
int32 key_family = 2;
}

message KeyForAddressRequest {
/** Provide a bech32 encoded in-wallet address
*/
string addr_in = 1;
}

message AddrRequest{
message AddrRequest {
// No fields, as we always give out a p2wkh address.
}
message AddrResponse {
Expand Down Expand Up @@ -226,52 +220,54 @@ message BumpFeeRequest {
message BumpFeeResponse {
}

message SharedKeyRequest {
bytes ephemeral_pubkey = 1;
}

message SharedKeyResponse {
bytes shared_key = 1;
}

service WalletKit {
/**
DeriveNextKey attempts to derive the *next* key within the key family
(account in BIP43) specified. This method should return the next external
child within this branch.
*/
rpc DeriveNextKey(KeyReq) returns (signrpc.KeyDescriptor);
rpc DeriveNextKey (KeyReq) returns (signrpc.KeyDescriptor);

/**
DeriveKey attempts to derive an arbitrary key specified by the passed
KeyLocator.
*/
rpc DeriveKey(signrpc.KeyLocator) returns (signrpc.KeyDescriptor);
rpc DeriveKey (signrpc.KeyLocator) returns (signrpc.KeyDescriptor);

/**
NextAddr returns the next unused address within the wallet.
*/
rpc NextAddr(AddrRequest) returns (AddrResponse);

/**
KeyForAddress returns a KeyDescriptor containing the pubkey
corresponding to a given address, assuming it is owned by the wallet.
*/
rpc KeyForAddress(KeyForAddressRequest) returns (signrpc.KeyDescriptor);
rpc NextAddr (AddrRequest) returns (AddrResponse);

/**
PublishTransaction attempts to publish the passed transaction to the
network. Once this returns without an error, the wallet will continually
attempt to re-broadcast the transaction on start up, until it enters the
chain.
*/
rpc PublishTransaction(Transaction) returns (PublishResponse);
rpc PublishTransaction (Transaction) returns (PublishResponse);

/**
SendOutputs is similar to the existing sendmany call in Bitcoind, and
allows the caller to create a transaction that sends to several outputs at
once. This is ideal when wanting to batch create a set of transactions.
*/
rpc SendOutputs(SendOutputsRequest) returns (SendOutputsResponse);
rpc SendOutputs (SendOutputsRequest) returns (SendOutputsResponse);

/**
EstimateFee attempts to query the internal fee estimator of the wallet to
determine the fee (in sat/kw) to attach to a transaction in order to
achieve the confirmation target.
*/
rpc EstimateFee(EstimateFeeRequest) returns (EstimateFeeResponse);
rpc EstimateFee (EstimateFeeRequest) returns (EstimateFeeResponse);

/*
PendingSweeps returns lists of on-chain outputs that lnd is currently
Expand All @@ -283,7 +279,7 @@ service WalletKit {
remain supported. This is an advanced API that depends on the internals of
the UtxoSweeper, so things may change.
*/
rpc PendingSweeps(PendingSweepsRequest) returns (PendingSweepsResponse);
rpc PendingSweeps (PendingSweepsRequest) returns (PendingSweepsResponse);

/*
BumpFee bumps the fee of an arbitrary input within a transaction. This RPC
Expand Down Expand Up @@ -312,5 +308,7 @@ service WalletKit {
fee preference being provided. For now, the responsibility of ensuring that
the new fee preference is sufficient is delegated to the user.
*/
rpc BumpFee(BumpFeeRequest) returns (BumpFeeResponse);
rpc BumpFee (BumpFeeRequest) returns (BumpFeeResponse);

rpc DeriveSharedKey (SharedKeyRequest) returns (SharedKeyResponse);
}
25 changes: 25 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,16 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=

bcrypto@^4.2.9:
version "4.2.9"
resolved "https://registry.yarnpkg.com/bcrypto/-/bcrypto-4.2.9.tgz#d57794196c1c230d20bb12319387f733452a6a53"
integrity sha512-upd5xGkB3REZwOOM2wGgUrc29HFQcm+mbXYLN8fKI2GcnWiCXmDU7f0wzr/ye2o1t0smhX3ddSzAqXIYEXehIw==
dependencies:
bsert "~0.0.10"
bufio "~1.0.6"
loady "~0.0.1"
nan "^2.13.2"

bluebird@^3.5.5:
version "3.5.5"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f"
Expand All @@ -287,6 +297,16 @@ braces@^3.0.1:
dependencies:
fill-range "^7.0.1"

bsert@~0.0.10:
version "0.0.10"
resolved "https://registry.yarnpkg.com/bsert/-/bsert-0.0.10.tgz#231ac82873a1418c6ade301ab5cd9ae385895597"
integrity sha512-NHNwlac+WPy4t2LoNh8pXk8uaIGH3NSaIUbTTRXGpE2WEbq0te/tDykYHkFK57YKLPjv/aGHmbqvnGeVWDz57Q==

bufio@~1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.0.6.tgz#e0eb6d70b2efcc997b6f8872173540967f90fa4d"
integrity sha512-mjYZFRHmI9bk3Oeexu0rWjHFY+w6hGLabdmwSFzq+EFr4MHHsNOYduDVdYl71NG5pTPL7GGzUCMk9cYuV34/Qw==

bytebuffer@~5:
version "5.0.1"
resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd"
Expand Down Expand Up @@ -1264,6 +1284,11 @@ listr@^0.14.3:
p-map "^2.0.0"
rxjs "^6.3.3"

loady@~0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/loady/-/loady-0.0.1.tgz#24a99c14cfed9cd0bffed365b1836035303f7e5d"
integrity sha512-PW5Z13Jd0v6ZcA1P6ZVUc3EV8BJwQuAiwUvvT6VQGHoaZ1d/tu7r1QZctuKfQqwy9SFBWeAGfcIdLxhp7ZW3Rw==

locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
Expand Down