You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/src/apps/zcash/f4jumble.py

59 lines
1.6 KiB

"""
Memory-optimized implementation of F4jumble permutation specified in ZIP-316.
specification: https://zips.z.cash/zip-0316#jumbling
reference implementation: https://github.com/zcash/librustzcash/blob/main/components/f4jumble/src/lib.rs
"""
from micropython import const
from trezor.crypto.hashlib import blake2b
HASH_LENGTH = const(64)
def xor(target: memoryview, mask: bytes) -> None:
for i in range(len(target)):
target[i] ^= mask[i]
def G_round(i: int, left: memoryview, right: memoryview) -> None:
for j in range((len(right) + HASH_LENGTH - 1) // HASH_LENGTH):
mask = blake2b(
personal=b"UA_F4Jumble_G" + bytes([i]) + j.to_bytes(2, "little"),
data=bytes(left),
).digest()
xor(right[j * HASH_LENGTH : (j + 1) * HASH_LENGTH], mask)
def H_round(i: int, left: memoryview, right: memoryview) -> None:
mask = blake2b(
personal=b"UA_F4Jumble_H" + bytes([i, 0, 0]),
outlen=len(left),
data=bytes(right),
).digest()
xor(left, mask)
def f4jumble(message: memoryview) -> None:
assert 48 <= len(message) <= 4194368
left_length = min(HASH_LENGTH, len(message) // 2)
left = message[:left_length]
right = message[left_length:]
G_round(0, left, right)
H_round(0, left, right)
G_round(1, left, right)
H_round(1, left, right)
def f4unjumble(message: memoryview) -> None:
assert 48 <= len(message) <= 4194368
left_length = min(HASH_LENGTH, len(message) // 2)
left = message[:left_length]
right = message[left_length:]
H_round(1, left, right)
G_round(1, left, right)
H_round(0, left, right)
G_round(0, left, right)