Генерация молниеносного секрета из семян

Я пытаюсь реализовать функцию в следующем разделе: Требования к секрету для каждого обязательства.

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)" заменяет B-й младший бит в значении P.

Согласно этому определению, если у нас есть 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-й младший бит (крайний правый бит) в 0.

Вместо этого результатом будет (тестовые векторы >):

>>> hexlify(sha256(int("00000000"+("00000001"*31),2).to_bytes(length=32,byteorder="big")).digest())
b'915c75942a26bb3a433a8ce2cb0427c29ec6c1775cfc78328b57f6ba7bfeaa9c'

И глядя на одну реализацию, ясно, что люди реализуют это, используя:

output[lp / 8] ^= (1 << (lp % 8));

Что мне кажется неправильным, поскольку он изменяет младший бит байта, который, если lp маленький, был бы более значимым и, следовательно, «наиболее значимым» согласно моей интерпретации. Но внутри байта он немного меняется, что может быть, если мы работаем в режиме прямого байта, проиндексировано в обратном направлении. Этого не следует из спецификации, поскольку речь идет только о битах.

Хотя в этом примере я мог бы использовать прямой порядок следования байтов, и он исправил бы этот конкретный тест, он не работал бы с другими тестовыми векторами, поэтому я не считаю это правильным исправлением, и это не имеет смысла, поскольку spec ничего не говорит об использовании прямого порядка байтов.

Кто-нибудь, пожалуйста, помогите мне понять определение «наименее значимого бита», чтобы эти тестовые векторы имели смысл. Мне кажется, что это требует от меня учитывать существование байтов, что не следует из моего понимания LSB.


person Janus Troelsen    schedule 19.04.2018    source источник


Ответы (2)


Это работает во всех пяти тестах 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;
person hxsquid    schedule 14.07.2018
comment
Я не прошу программу, которая проходит тест, я прошу объяснения, как тесты могут соответствовать псевдокоду. Кроме того, я не понимаю, какой вклад вносит ваше решение, поскольку оно сложнее, чем решение с куропаткой. - person Janus Troelsen; 18.07.2018

Это была ошибка спецификации, в ней не упоминалось, что здесь используется прямой порядок байтов: https://github.com/lightningnetwork/lightning-rfc/pull/779

person Janus Troelsen    schedule 25.07.2021