从种子生成闪电秘密
Lightning secret generation from seed
我正在尝试实现以下部分中的功能: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
其中 "flip(B)" 替换值 P 中的第 B 个最低有效位。
根据这个定义,如果我们有 seed=0x0101010101010101010101010101010101010101010101010101010101010101
和 I=1
,我希望结果是
>>> from hashlib import sha256
>>> from binascii import hexlify
>>> hexlify(sha256(int(("00000001"*31)+"00000000",2).to_bytes(length=32,byteorder="big")).digest())
b'79356295f56e69998b9140cb77c63d3d80c93874259793a38d1dbd8678809ca9'
因为flip
函数执行了一次,设置第0个LSB(最右边的位)为0。
结果是 (test vectors):
>>> hexlify(sha256(int("00000000"+("00000001"*31),2).to_bytes(length=32,byteorder="big")).digest())
b'915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c'
并且查看 one implementation,很明显人们正在使用以下方式实现此功能:
output[lp / 8] ^= (1 << (lp % 8));
这在我看来是错误的,因为它改变了字节的 LSB,如果 lp
很小,那么它会更重要,因此根据我的解释 "most significant"。但是在字节内部,如果我们在大端模式下工作,它可能会发生一些变化,索引方向相反。这不符合规范,因为它只讨论位。
虽然我可以在这个例子中使用小字节序,它会修复这个特定的测试,但它不会在其他测试向量上工作,所以我不认为这是一个正确的修复,那不会'没有意义,因为规范中没有提到使用小字节序。
有人请帮助我理解 "least significant bit" 的定义,以便这些测试向量有意义。在我看来,它需要我考虑字节的存在,这不是我对 LSB 的理解。
这适用于 generate_from_seed 的所有五个测试:
byte[] p = new byte[32];
for (int i = 0; i < 32; ++i)
p[i] = seed[i];
for (int i = 47; i >= 0; --i)
{
int byteNumber = i / 8;
int bitNumber = (i % 8);
byte mask = (byte) (1 << bitNumber);
// access index in little endian order !!!
if ((index[5 - byteNumber] & mask) == mask)
{
p[byteNumber] ^= mask;
p = Utils.SHA256Hash(p);
}
}
return p;
这是一个规范错误,它没有提到这使用了小端:https://github.com/lightningnetwork/lightning-rfc/pull/779
我正在尝试实现以下部分中的功能: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
其中 "flip(B)" 替换值 P 中的第 B 个最低有效位。
根据这个定义,如果我们有 seed=0x0101010101010101010101010101010101010101010101010101010101010101
和 I=1
,我希望结果是
>>> from hashlib import sha256
>>> from binascii import hexlify
>>> hexlify(sha256(int(("00000001"*31)+"00000000",2).to_bytes(length=32,byteorder="big")).digest())
b'79356295f56e69998b9140cb77c63d3d80c93874259793a38d1dbd8678809ca9'
因为flip
函数执行了一次,设置第0个LSB(最右边的位)为0。
结果是 (test vectors):
>>> hexlify(sha256(int("00000000"+("00000001"*31),2).to_bytes(length=32,byteorder="big")).digest())
b'915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c'
并且查看 one implementation,很明显人们正在使用以下方式实现此功能:
output[lp / 8] ^= (1 << (lp % 8));
这在我看来是错误的,因为它改变了字节的 LSB,如果 lp
很小,那么它会更重要,因此根据我的解释 "most significant"。但是在字节内部,如果我们在大端模式下工作,它可能会发生一些变化,索引方向相反。这不符合规范,因为它只讨论位。
虽然我可以在这个例子中使用小字节序,它会修复这个特定的测试,但它不会在其他测试向量上工作,所以我不认为这是一个正确的修复,那不会'没有意义,因为规范中没有提到使用小字节序。
有人请帮助我理解 "least significant bit" 的定义,以便这些测试向量有意义。在我看来,它需要我考虑字节的存在,这不是我对 LSB 的理解。
这适用于 generate_from_seed 的所有五个测试:
byte[] p = new byte[32];
for (int i = 0; i < 32; ++i)
p[i] = seed[i];
for (int i = 47; i >= 0; --i)
{
int byteNumber = i / 8;
int bitNumber = (i % 8);
byte mask = (byte) (1 << bitNumber);
// access index in little endian order !!!
if ((index[5 - byteNumber] & mask) == mask)
{
p[byteNumber] ^= mask;
p = Utils.SHA256Hash(p);
}
}
return p;
这是一个规范错误,它没有提到这使用了小端:https://github.com/lightningnetwork/lightning-rfc/pull/779