I am trying to implement the function in the following section: Per-commitment Secret Requirements.
generate_from_seed(seed, I):
P = seed
for B in 47 down to 0:
if B set in I:
flip(B) in P
P = SHA256(P)
return P
Where "flip(B)" alternates the B'th least significant bit in the value P.
According to this definition, if we have seed=0x0101010101010101010101010101010101010101010101010101010101010101
and I=1
, I would expect the result to be
>>> from hashlib import sha256
>>> from binascii import hexlify
>>> hexlify(sha256(int(("00000001"*31)+"00000000",2).to_bytes(length=32,byteorder="big")).digest())
b'79356295f56e69998b9140cb77c63d3d80c93874259793a38d1dbd8678809ca9'
Because the flip
function is executed once, setting the 0th LSB (the rightmost bit) to 0.
Instead the result is (test vectors):
>>> hexlify(sha256(int("00000000"+("00000001"*31),2).to_bytes(length=32,byteorder="big")).digest())
b'915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c'
And looking at one implementation, it is clear that people are implementing this using:
output[lp / 8] ^= (1 << (lp % 8));
Which seems to me as wrong, since it is changing the LSB of the byte which, if lp
is small, would be more significant, and therefore the "most significant" according to my interpretation. But inside the byte, it is changing a bit that could be, if we are working in big-endian mode, indexed in the opposite direction. Which doesn't follow from the spec, since it only talks about bits.
While I could use little-endianness in this example, and it would fix this specific test, it wouldn't work on the other test vectors, so I don't consider that a proper fix, and that wouldn't make sense since the spec says nothing about using little-endianness.
Somebody please help me understand the definition of "least significant bit" such that these test vectors make sense. It seems to me, that it requires me to consider the existence of bytes, which doesn't follow from my understanding of LSB.
It was a spec bug, it didn't mention that this used little-endian: https://github.com/lightningnetwork/lightning-rfc/pull/779