Skip to content

Instantly share code, notes, and snippets.

@xhliu

xhliu/deriveAddress.js

Last active Apr 28, 2021
Embed
What would you like to do?
A simple demo for derived bitcoin addresses
// Copyright (c) 2020 Xiaohui Liu.
// Use of this source code is governed by a MIT-style license.
// This is an implementation of https://craigwright.net/blog/bitcoin-blockchain-tech/offline-addressing
// For more info, also see Episode 4 of Bitcoin Class with Satoshi: Extended Address https://youtu.be/rezvcJ4j-7U
const bsv = require('bsv');
const BN = bsv.crypto.BN
const Hash = bsv.crypto.Hash
const G = bsv.crypto.Point.getG()
const N = bsv.crypto.Point.getN()
const privKeyA = new bsv.PrivateKey.fromRandom()
const pubKeyA = privKeyA.publicKey
const privKeyB = new bsv.PrivateKey.fromRandom()
const pubKeyB = privKeyB.publicKey
// Diffie-Helman key exchange
const sharedAB = pubKeyA.point.mul(privKeyB.bn)
const sharedAB_ = pubKeyB.point.mul(privKeyA.bn)
const samePoint = (p, q) => p.getX().eq(q.getX()) && p.getY().eq(q.getY())
console.log(samePoint(sharedAB, sharedAB_) ? "same secret" : "different secret")
const Hm = i => {
const hmac = Hash.sha256hmac(sharedAB.toBuffer(), BN.fromNumber(i).toBuffer())
return BN.fromBuffer(hmac)
}
// derived public key for Bob: Alice can send to this address as a regular P2PKH address
const pubKey = i => G.mul(Hm(i))
const derivePubKeyB = i => bsv.PublicKey.fromPoint(pubKeyB.point.add(pubKey(i)))
// derived private key for Bob
const derivePrivKeyB = i => {
const sumKey = privKeyB.bn.add(Hm(i)).mod(N)
return new bsv.PrivateKey(sumKey)
}
// message can be anything: use invoice index as message here
for (let i = 0; i < 10; i++) {
// derived key pair matches: Bob can receive Alice's fund sent to the derived address
console.log(derivePrivKeyB(i).publicKey.toHex() === derivePubKeyB(i).toHex() ? "Succeed: derived key matches" : "Fail: derived key mismatches")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment