@@ -6,42 +6,67 @@ var bitcoin = require('../../')
66
77var ecurve = require ( 'ecurve' )
88var secp256k1 = ecurve . getCurveByName ( 'secp256k1' )
9+ var G = secp256k1 . G
10+ var n = secp256k1 . n
11+
12+ // c = sha256: e * (d * G)
13+ // cQ = (d * G) + (c * G)
14+ function stealthSend ( e , Q ) {
15+ var eQ = Q . multiply ( e ) // shared secret
16+
17+ var c = bigi . fromBuffer ( bitcoin . crypto . sha256 ( eQ . getEncoded ( ) ) )
18+ var cG = G . multiply ( c )
19+
20+ var cQ = new bitcoin . ECPair ( null , Q . add ( cG ) )
21+
22+ return cQ
23+ }
24+
25+ // c = sha256: d * (e * G)
26+ // cQ = (d + c) * G
27+ function stealthReceive ( d , eG ) {
28+ var eQ = eG . multiply ( d ) // shared secret
29+
30+ var c = bigi . fromBuffer ( bitcoin . crypto . sha256 ( eQ . getEncoded ( ) ) )
31+ var cQ = new bitcoin . ECPair ( d . add ( c ) . mod ( n ) )
32+
33+ return cQ
34+ }
935
1036describe ( 'bitcoinjs-lib (crypto)' , function ( ) {
1137 it ( 'can generate a single-key stealth address' , function ( ) {
12- var G = secp256k1 . G
13- var n = secp256k1 . n
14-
15- function stealthSend ( Q ) {
16- var noncePair = bitcoin . ECPair . makeRandom ( )
17- var e = noncePair . d
18- var eQ = Q . multiply ( e ) // shared secret
19- var c = bigi . fromBuffer ( bitcoin . crypto . sha256 ( eQ . getEncoded ( ) ) )
20- var cG = G . multiply ( c )
21- var Qprime = Q . add ( cG )
22-
23- return {
24- shared : new bitcoin . ECPair ( null , Qprime ) ,
25- nonce : noncePair . Q
26- }
27- }
28-
29- function stealthReceive ( d , P ) {
30- var dP = P . multiply ( d ) // shared secret
31- var c = bigi . fromBuffer ( bitcoin . crypto . sha256 ( dP . getEncoded ( ) ) )
32- return new bitcoin . ECPair ( d . add ( c ) . mod ( n ) )
33- }
34-
35- // receiver private key
36- var receiver = bitcoin . ECPair . fromWIF ( '5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss' )
37-
38- var stealthS = stealthSend ( receiver . Q ) // public, done by sender
39- // ... sender now reveals nonce to receiver
40-
41- var stealthR = stealthReceive ( receiver . d , stealthS . nonce ) // private, done by receiver
42-
43- // and check that we derived both sides correctly
44- assert . equal ( stealthS . shared . getAddress ( ) , stealthR . getAddress ( ) )
38+ // XXX: should be randomly generated, see next test for example
39+ var recipient = bitcoin . ECPair . fromWIF ( '5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss' ) // private to recipient
40+ var nonce = bitcoin . ECPair . fromWIF ( 'KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9' ) // private to sender
41+
42+ // ... recipient reveals public key (recipient.Q) to sender
43+ var forSender = stealthSend ( nonce . d , recipient . Q )
44+ assert . equal ( forSender . getAddress ( ) , '1CcZWwCpACJL3AxqoDbwEt4JgDFuTHUspE' )
45+ assert . throws ( function ( ) { forSender . toWIF ( ) } , / E r r o r : M i s s i n g p r i v a t e k e y / )
46+
47+ // ... sender reveals nonce public key (nonce.Q) to recipient
48+ var forRecipient = stealthReceive ( recipient . d , nonce . Q )
49+ assert . equal ( forRecipient . getAddress ( ) , '1CcZWwCpACJL3AxqoDbwEt4JgDFuTHUspE' )
50+ assert . equal ( forRecipient . toWIF ( ) , 'L1yjUN3oYyCXV3LcsBrmxCNTa62bZKWCybxVJMvqjMmmfDE8yk7n' )
51+
52+ // sender and recipient, both derived same address
53+ assert . equal ( forSender . getAddress ( ) , forRecipient . getAddress ( ) )
54+ } )
55+
56+ it ( 'can generate a single-key stealth address (randomly)' , function ( ) {
57+ var recipient = bitcoin . ECPair . makeRandom ( ) // private to recipient
58+ var nonce = bitcoin . ECPair . makeRandom ( ) // private to sender
59+
60+ // ... recipient reveals public key (recipient.Q) to sender
61+ var forSender = stealthSend ( nonce . d , recipient . Q )
62+ assert . throws ( function ( ) { forSender . toWIF ( ) } , / E r r o r : M i s s i n g p r i v a t e k e y / )
63+
64+ // ... sender reveals nonce public key (nonce.Q) to recipient
65+ var forRecipient = stealthReceive ( recipient . d , nonce . Q )
66+ assert . doesNotThrow ( function ( ) { forRecipient . toWIF ( ) } )
67+
68+ // sender and recipient, both derived same address
69+ assert . equal ( forSender . getAddress ( ) , forRecipient . getAddress ( ) )
4570 } )
4671
4772 // TODO
0 commit comments