Я пытаюсь реализовать функцию в следующем разделе: Требования к секрету для каждого обязательства.
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.