I'm trying to create Bob's first receive (ephemeral) address according to the BIP 47 spec after the Notification Transaction has taken place, which I believe to be:


according to these test vectors. I have been unable to calculate the correct ephemeral public key (B') corresponding to this address via:

B' = B + sG

or the correct private key (b') for the ephemeral address via:

b' = b + s

The variables I have come up with so far for this first address include:

// Alice selects the 0th private key derived from her payment code:
a = 8d6a8ecd8ee5e0042ad0cb56e3a971c760b5145c3917a8e7beaf0ed92d7a520c

// Alice selects the next unused public key derived from Bob's payment code, 
// starting from zero:
B = 024ce8e3b04ea205ff49f529950616c3db615b1e37753858cc60c1ce64d17e2ad8

// Alice calculates a secret point:
S = 03f5bb84706ee366052471e6139e6a9a969d586e5fe6471a9b96c3d8caefe86fef

// Alice calculates a scalar shared secret using the x value of S:
// x value = f5bb84706ee366052471e6139e6a9a969d586e5fe6471a9b96c3d8caefe86fef
// SHA256(x value)
s = d24366e662da47c0cccca4cc2d2d817af54e4d21039c0cc4fc441624efe273f7

// s multiplied by generator point
sG = 0283850c6835576554261fbab5845a099638859528b2725455e6a48e7566415c02

// Alice uses the scalar shared secret to calculate the ephemeral public key 
// used to generate the P2PKH address for this transaction:
B' = 0344b4795e48df097bd87e6cf87a70e4f0c30b2d847b6e34cddde64af10296952d

// Bob's first private key
b = 04448fd1be0c9c13a5ca0b530e464b619dc091b299b98c5cab9978b32b4a1b8b

b' = d687f6b820e6e3d47296b01f3b73ccdc930eded39d559921a7dd8ed81b2c8f82

Are any of these variables incorrect, and if so, how are the correct ones obtained?

  • how did you come up with S = 03f5bb84706ee366052471e6139e6a9a969d586e5fe6471a9b96c3d8caefe86fef the shared secretes in the test vectors are supposed to be different. which software / lib are u using? – Rene Pickhardt Feb 23 at 16:27
  • Multiplied the point "B" (pub key) times scalar "a" (private key). They are supposed to be different? I'm using Core Bitcoin for iOS. – doffing81 Feb 23 at 16:30

Felix Engelmann and I sat down tonight and we used bx via libbitcoin. We have been able to produce the address from the test vector and exactly your intermediate results

S=$(bx ec-multiply $B $a)
echo $S
> 03f5bb84706ee366052471e6139e6a9a969d586e5fe6471a9b96c3d8caefe86fef

s=$(bx sha256 'f5bb84706ee366052471e6139e6a9a969d586e5fe6471a9b96c3d8caefe86fef')
echo $s
> d24366e662da47c0cccca4cc2d2d817af54e4d21039c0cc4fc441624efe273f7

sG=$(bx ec-to-public $s)
echo $sG
> 0283850c6835576554261fbab5845a099638859528b2725455e6a48e7566415c02

B_prime=$(bx ec-add $B $s)
echo $B_prime
> 0344b4795e48df097bd87e6cf87a70e4f0c30b2d847b6e34cddde64af10296952d

addr=$(bx ec-to-address -v 0 $B_prime)
echo $addr
> 141fi7TY3h936vRUKh1qfUZr8rSBuYbVBK

Note that our value for B_prime was 0344b4795e48df097bd87e6cf87a70e4f0c30b2d847b6e34cddde64af10296952d as you suggested. Actually encoding it to a Bitcoin address seemed a little bit tricky as without passing -v 0 it would use a testnet address. Maybe you have a similar problem while using Bitcoin core? I don't know the API though for transforming a pub key / ec point to an Adress in Bitcoin core out of my head.

Anyway I think you did everything correctly and you just did a mistake in encoding the P2PKH address.

  • 1
    Beautiful! In knowing that my parameters matched yours, I became certain that it was simply that last step in creating the address that was causing me problems. Instead of creating a new key via BTCKey(curvePoint: BPrime), I tried a different initializer via BTCKey(publicKey: BPrime?.data), and it worked!. Gah, I knew it was something ridiculous. Never looked at the initializers because it just seemed straightforward. – doffing81 Feb 24 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.