从种子

时间:2018-04-19 18:44:36

标签: bitwise-operators endianness pseudocode

我正在尝试在以下部分中实现该功能: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

其中"翻转(B)"交替值P中的B&#39最低有效位。

根据这个定义,如果我们有seed=0x0101010101010101010101010101010101010101010101010101010101010101I=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很小,则会更重要,因此最重要的是&#34;根据我的解释。但是在字节内部,它正在改变一点,如果我们在big-endian模式下工作,则指向相反的方向。从规范中可以得出哪些内容,因为它只讨论了比特。

虽然我可以在这个例子中使用little-endianness,并且它会修复这个特定的测试,但它不会对其他测试向量起作用,所以我不认为这是一个正确的修复,那个因为规范没有说明使用小端语,所以没有意义。

有人请帮助我理解&#34;最不重要的位&#34;这样的测试向量是有意义的。在我看来,它需要我考虑字节的存在,而这并不是我对LSB的理解。

2 个答案:

答案 0 :(得分:0)

这适用于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;

答案 1 :(得分:0)

这是一个规范错误,它没有提到它使用了小端:https://github.com/lightningnetwork/lightning-rfc/pull/779