stealth: add dual key example
This commit is contained in:
parent
1304527c1d
commit
b4062d56d1
1 changed files with 50 additions and 5 deletions
|
@ -12,10 +12,8 @@ var n = secp256k1.n
|
||||||
// vG = (dG * sha256(e * dG)G)
|
// vG = (dG * sha256(e * dG)G)
|
||||||
function stealthSend (e, Q) {
|
function stealthSend (e, Q) {
|
||||||
var eQ = Q.multiply(e) // shared secret
|
var eQ = Q.multiply(e) // shared secret
|
||||||
|
|
||||||
var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded()))
|
var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded()))
|
||||||
var cG = G.multiply(c)
|
var cG = G.multiply(c)
|
||||||
|
|
||||||
var vG = new bitcoin.ECPair(null, Q.add(cG))
|
var vG = new bitcoin.ECPair(null, Q.add(cG))
|
||||||
|
|
||||||
return vG
|
return vG
|
||||||
|
@ -24,7 +22,6 @@ function stealthSend (e, Q) {
|
||||||
// v = (d + sha256(eG * d))
|
// v = (d + sha256(eG * d))
|
||||||
function stealthReceive (d, eG) {
|
function stealthReceive (d, eG) {
|
||||||
var eQ = eG.multiply(d) // shared secret
|
var eQ = eG.multiply(d) // shared secret
|
||||||
|
|
||||||
var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded()))
|
var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded()))
|
||||||
var v = new bitcoin.ECPair(d.add(c).mod(n))
|
var v = new bitcoin.ECPair(d.add(c).mod(n))
|
||||||
|
|
||||||
|
@ -40,6 +37,34 @@ function stealthRecoverLeaked (v, e, Q) {
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// vG = (rG * (dG * sha256(e * dG)G))
|
||||||
|
function stealthDualSend (e, R, Q) {
|
||||||
|
var eQ = Q.multiply(e) // shared secret
|
||||||
|
var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded()))
|
||||||
|
var cG = G.multiply(c)
|
||||||
|
var vG = new bitcoin.ECPair(null, R.add(Q.add(cG)))
|
||||||
|
|
||||||
|
return vG
|
||||||
|
}
|
||||||
|
|
||||||
|
// vG = (rG * (d + sha256(eG * d))G)
|
||||||
|
function stealthDualScan (d, R, eG) {
|
||||||
|
var eQ = eG.multiply(d) // shared secret
|
||||||
|
var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded()))
|
||||||
|
var vG = new bitcoin.ECPair(null, R.add(G.multiply(d.add(c).mod(n))))
|
||||||
|
|
||||||
|
return vG
|
||||||
|
}
|
||||||
|
|
||||||
|
// v = (r + d + sha256(eG * d))
|
||||||
|
function stealthDualReceive (d, r, eG) {
|
||||||
|
var eQ = eG.multiply(d) // shared secret
|
||||||
|
var c = bigi.fromBuffer(bitcoin.crypto.sha256(eQ.getEncoded()))
|
||||||
|
var v = new bitcoin.ECPair(r.add(d).add(c).mod(n))
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
describe('bitcoinjs-lib (crypto)', function () {
|
describe('bitcoinjs-lib (crypto)', function () {
|
||||||
it('can generate a single-key stealth address', function () {
|
it('can generate a single-key stealth address', function () {
|
||||||
// XXX: should be randomly generated, see next test for example
|
// XXX: should be randomly generated, see next test for example
|
||||||
|
@ -93,6 +118,26 @@ describe('bitcoinjs-lib (crypto)', function () {
|
||||||
assert.equal(leaked.toWIF(), recipient.toWIF())
|
assert.equal(leaked.toWIF(), recipient.toWIF())
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO
|
it('can generate a dual-key stealth address (randomly)', function () {
|
||||||
it.skip('can generate a dual-key stealth address', function () {})
|
// XXX: should be randomly generated, see next test for example
|
||||||
|
var recipient = bitcoin.ECPair.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss') // private to recipient
|
||||||
|
var scan = bitcoin.ECPair.fromWIF('L5DkCk3xLLoGKncqKsWQTdaPSR4V8gzc14WVghysQGkdryRudjBM') // private to scanner/recipient
|
||||||
|
var nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender
|
||||||
|
|
||||||
|
// ... recipient reveals public key(s) (recipient.Q, scan.Q) to sender
|
||||||
|
var forSender = stealthDualSend(nonce.d, recipient.Q, scan.Q)
|
||||||
|
assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
|
||||||
|
|
||||||
|
// ... sender reveals nonce public key (nonce.Q) to scanner
|
||||||
|
var forScanner = stealthDualScan(scan.d, recipient.Q, nonce.Q)
|
||||||
|
assert.throws(function () { forScanner.toWIF() }, /Error: Missing private key/)
|
||||||
|
|
||||||
|
// ... scanner reveals relevant transaction + nonce public key (nonce.Q) to recipient
|
||||||
|
var forRecipient = stealthDualReceive(scan.d, recipient.d, nonce.Q)
|
||||||
|
assert.doesNotThrow(function () { forRecipient.toWIF() })
|
||||||
|
|
||||||
|
// scanner, sender and recipient, all derived same address
|
||||||
|
assert.equal(forSender.getAddress(), forScanner.getAddress())
|
||||||
|
assert.equal(forSender.getAddress(), forRecipient.getAddress())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue