diff --git a/embed/extmod/modtrezorcrypto/modtrezorcrypto-blake2b.h b/embed/extmod/modtrezorcrypto/modtrezorcrypto-blake2b.h index eb4a219c2f..d860237e46 100644 --- a/embed/extmod/modtrezorcrypto/modtrezorcrypto-blake2b.h +++ b/embed/extmod/modtrezorcrypto/modtrezorcrypto-blake2b.h @@ -40,29 +40,49 @@ STATIC mp_obj_t mod_trezorcrypto_Blake2b_update(mp_obj_t self, mp_obj_t data); /// Creates a hash context object. /// ''' STATIC mp_obj_t mod_trezorcrypto_Blake2b_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 3, false); + + STATIC const mp_arg_t allowed_args[] = { + { MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, + { MP_QSTR_outlen, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = BLAKE2B_DIGEST_LENGTH} }, + { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, + { MP_QSTR_personal, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, + }; + mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals); + + size_t data_len; + const uint8_t *data = (const uint8_t *)mp_obj_str_get_data(vals[0].u_obj, &data_len); + const mp_int_t outlen = vals[1].u_int; + size_t key_len; + const uint8_t *key = (const uint8_t *)mp_obj_str_get_data(vals[2].u_obj, &key_len); + size_t personal_len; + const uint8_t *personal = (const uint8_t *)mp_obj_str_get_data(vals[3].u_obj, &personal_len); + + if (key_len > 0 && personal_len > 0) { + mp_raise_ValueError("Invalid Blake2b parameters: cannot use key and personal at the same time"); + } + mp_obj_Blake2b_t *o = m_new_obj(mp_obj_Blake2b_t); o->base.type = type; int res = 0; - // constructor called with personal argument set - if (n_args == 3) { - size_t outlen = trezor_obj_get_uint(args[1]); - mp_buffer_info_t personal; - mp_get_buffer_raise(args[2], &personal, MP_BUFFER_READ); - res = blake2b_InitPersonal(&(o->ctx), outlen, personal.buf, personal.len); - } else if (n_args == 2) { - size_t outlen = trezor_obj_get_uint(args[1]); - res = blake2b_Init(&(o->ctx), outlen); + + if (key_len > 0) { + res = blake2b_InitKey(&(o->ctx), outlen, key, key_len); + } else if (personal_len > 0) { + res = blake2b_InitPersonal(&(o->ctx), outlen, personal, personal_len); } else { - res = blake2b_Init(&(o->ctx), BLAKE2B_DIGEST_LENGTH); + res = blake2b_Init(&(o->ctx), outlen); } + if (res < 0) { mp_raise_ValueError("Invalid Blake2b parameters"); } + // constructor called with data argument set - if (n_args >= 1) { - mod_trezorcrypto_Blake2b_update(MP_OBJ_FROM_PTR(o), args[0]); + if (data_len > 0) { + blake2b_Update(&(o->ctx), data, data_len); } + return MP_OBJ_FROM_PTR(o); } diff --git a/embed/extmod/modtrezorcrypto/modtrezorcrypto-blake2s.h b/embed/extmod/modtrezorcrypto/modtrezorcrypto-blake2s.h index 1f30c8d34f..fb14b352a1 100644 --- a/embed/extmod/modtrezorcrypto/modtrezorcrypto-blake2s.h +++ b/embed/extmod/modtrezorcrypto/modtrezorcrypto-blake2s.h @@ -35,34 +35,54 @@ typedef struct _mp_obj_Blake2s_t { STATIC mp_obj_t mod_trezorcrypto_Blake2s_update(mp_obj_t self, mp_obj_t data); -/// def __init__(self, data: bytes = None, outlen: int = Blake2s.digest_size, key: bytes = None) -> None: +/// def __init__(self, data: bytes = None, outlen: int = Blake2s.digest_size, key: bytes = None, personal: bytes = None) -> None: /// ''' /// Creates a hash context object. /// ''' STATIC mp_obj_t mod_trezorcrypto_Blake2s_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 3, false); + + STATIC const mp_arg_t allowed_args[] = { + { MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, + { MP_QSTR_outlen, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = BLAKE2S_DIGEST_LENGTH} }, + { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, + { MP_QSTR_personal, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} }, + }; + mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals); + + size_t data_len; + const uint8_t *data = (const uint8_t *)mp_obj_str_get_data(vals[0].u_obj, &data_len); + const mp_int_t outlen = vals[1].u_int; + size_t key_len; + const uint8_t *key = (const uint8_t *)mp_obj_str_get_data(vals[2].u_obj, &key_len); + size_t personal_len; + const uint8_t *personal = (const uint8_t *)mp_obj_str_get_data(vals[3].u_obj, &personal_len); + + if (key_len > 0 && personal_len > 0) { + mp_raise_ValueError("Invalid Blake2s parameters: cannot use key and personal at the same time"); + } + mp_obj_Blake2s_t *o = m_new_obj(mp_obj_Blake2s_t); o->base.type = type; int res = 0; - // constructor called with key argument set - if (n_args == 3) { - size_t outlen = trezor_obj_get_uint(args[1]); - mp_buffer_info_t key; - mp_get_buffer_raise(args[2], &key, MP_BUFFER_READ); - res = blake2s_InitKey(&(o->ctx), outlen, key.buf, key.len); - } else if (n_args == 2) { - size_t outlen = trezor_obj_get_uint(args[1]); - res = blake2s_Init(&(o->ctx), outlen); + + if (key_len > 0) { + res = blake2s_InitKey(&(o->ctx), outlen, key, key_len); + } else if (personal_len > 0) { + res = blake2s_InitPersonal(&(o->ctx), outlen, personal, personal_len); } else { - res = blake2s_Init(&(o->ctx), BLAKE2S_DIGEST_LENGTH); + res = blake2s_Init(&(o->ctx), outlen); } + if (res < 0) { mp_raise_ValueError("Invalid Blake2s parameters"); } + // constructor called with data argument set - if (n_args >= 1) { - mod_trezorcrypto_Blake2s_update(MP_OBJ_FROM_PTR(o), args[0]); + if (data_len > 0) { + blake2s_Update(&(o->ctx), data, data_len); } + return MP_OBJ_FROM_PTR(o); } diff --git a/src/apps/wallet/sign_tx/overwinter_zip143.py b/src/apps/wallet/sign_tx/overwinter_zip143.py index 4489685dc0..553a0aa123 100644 --- a/src/apps/wallet/sign_tx/overwinter_zip143.py +++ b/src/apps/wallet/sign_tx/overwinter_zip143.py @@ -23,9 +23,9 @@ class Zip143Error(ValueError): class Zip143: def __init__(self): - self.h_prevouts = HashWriter(blake2b, b'', 32, b'ZcashPrevoutHash') - self.h_sequence = HashWriter(blake2b, b'', 32, b'ZcashSequencHash') - self.h_outputs = HashWriter(blake2b, b'', 32, b'ZcashOutputsHash') + self.h_prevouts = HashWriter(blake2b, outlen=32, personal=b'ZcashPrevoutHash') + self.h_sequence = HashWriter(blake2b, outlen=32, personal=b'ZcashSequencHash') + self.h_outputs = HashWriter(blake2b, outlen=32, personal=b'ZcashOutputsHash') def add_prevouts(self, txi: TxInputType): write_bytes_rev(self.h_prevouts, txi.prev_hash) @@ -47,7 +47,7 @@ class Zip143: return get_tx_hash(self.h_outputs) def preimage_hash(self, coin: CoinInfo, tx: SignTx, txi: TxInputType, pubkeyhash: bytes, sighash: int) -> bytes: - h_preimage = HashWriter(blake2b, b'', 32, b'ZcashSigHash\x19\x1b\xa8\x5b') # BRANCH_ID = 0x5ba81b19 + h_preimage = HashWriter(blake2b, outlen=32, personal=b'ZcashSigHash\x19\x1b\xa8\x5b') # BRANCH_ID = 0x5ba81b19 assert tx.overwintered diff --git a/src/trezor/utils.py b/src/trezor/utils.py index d19ac73a09..9ff4f381e3 100644 --- a/src/trezor/utils.py +++ b/src/trezor/utils.py @@ -73,8 +73,8 @@ def format_ordinal(number): class HashWriter: - def __init__(self, hashfunc, *hashargs): - self.ctx = hashfunc(*hashargs) + def __init__(self, hashfunc, *hashargs, **hashkwargs): + self.ctx = hashfunc(*hashargs, **hashkwargs) self.buf = bytearray(1) # used in append() def extend(self, buf: bytearray): diff --git a/tests/test_trezor.crypto.hashlib.blake2b.py b/tests/test_trezor.crypto.hashlib.blake2b.py index 20255e7dc1..ad04645dd9 100644 --- a/tests/test_trezor.crypto.hashlib.blake2b.py +++ b/tests/test_trezor.crypto.hashlib.blake2b.py @@ -18,11 +18,11 @@ class TestCryptoBlake2b(unittest.TestCase): def test_digest(self): key = unhexlify('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f') for d, h in self.vectors: - self.assertEqual(hashlib.blake2b(unhexlify(d), hashlib.blake2b.digest_size, key).digest(), unhexlify(h)) + self.assertEqual(hashlib.blake2b(unhexlify(d), key=key).digest(), unhexlify(h)) def test_update(self): key = unhexlify('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f') - x = hashlib.blake2b(b'', hashlib.blake2b.digest_size, key) + x = hashlib.blake2b(key=key) x.update(bytes(range(10))) self.assertEqual(x.digest(), unhexlify('4fe181f54ad63a2983feaaf77d1e7235c2beb17fa328b6d9505bda327df19fc37f02c4b6f0368ce23147313a8e5738b5fa2a95b29de1c7f8264eb77b69f585cd')) x.update(bytes(range(10, 30))) diff --git a/tests/test_trezor.crypto.hashlib.blake2s.py b/tests/test_trezor.crypto.hashlib.blake2s.py index 6f389b6f3c..0b5dcfb085 100644 --- a/tests/test_trezor.crypto.hashlib.blake2s.py +++ b/tests/test_trezor.crypto.hashlib.blake2s.py @@ -19,11 +19,11 @@ class TestCryptoBlake2s(unittest.TestCase): def test_digest(self): key = unhexlify('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f') for d, h in self.vectors: - self.assertEqual(hashlib.blake2s(unhexlify(d), hashlib.blake2s.digest_size, key).digest(), unhexlify(h)) + self.assertEqual(hashlib.blake2s(unhexlify(d), key=key).digest(), unhexlify(h)) def test_update(self): key = unhexlify('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f') - x = hashlib.blake2s(b'', hashlib.blake2s.digest_size, key) + x = hashlib.blake2s(b'', key=key) x.update(bytes(range(10))) self.assertEqual(x.digest(), unhexlify('f5c4b2ba1a00781b13aba0425242c69cb1552f3f71a9a3bb22b4a6b4277b46dd')) x.update(bytes(range(10, 30))) diff --git a/vendor/trezor-crypto b/vendor/trezor-crypto index 669acd7331..c26867d6f2 160000 --- a/vendor/trezor-crypto +++ b/vendor/trezor-crypto @@ -1 +1 @@ -Subproject commit 669acd7331fc02b6ef41c4a91112e6e6d6e831be +Subproject commit c26867d6f2d75a3d5da85f8f9f4a40195525ad4d