From 0ab2170cc6b575c5685009918c24854d65e4abae Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Wed, 13 Apr 2016 20:41:33 +0200 Subject: [PATCH] add ripemd160 --- .../modTrezorCrypto-ripemd160.h | 59 +++++++++++++++++++ .../modTrezorCrypto/modTrezorCrypto-sha256.h | 3 +- .../modTrezorCrypto/modTrezorCrypto-sha512.h | 3 +- extmod/modTrezorCrypto/modTrezorCrypto.c | 2 + src/tests/test_crypto_ripemd160.py | 24 ++++++++ src/trezor/crypto/hash.py | 1 + vendor/micropython | 2 +- 7 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 extmod/modTrezorCrypto/modTrezorCrypto-ripemd160.h create mode 100644 src/tests/test_crypto_ripemd160.py diff --git a/extmod/modTrezorCrypto/modTrezorCrypto-ripemd160.h b/extmod/modTrezorCrypto/modTrezorCrypto-ripemd160.h new file mode 100644 index 000000000..d29c2be4c --- /dev/null +++ b/extmod/modTrezorCrypto/modTrezorCrypto-ripemd160.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) Pavol Rusnak, SatoshiLabs + * + * Licensed under Microsoft Reference Source License (Ms-RSL) + * see LICENSE.md file for details + */ + +#include "py/objstr.h" + +#include "trezor-crypto/ripemd160.h" + +// class Ripemd160(object): +typedef struct _mp_obj_Ripemd160_t { + mp_obj_base_t base; + uint8_t hash[20]; +} mp_obj_Ripemd160_t; + +// def Ripemd160.__init__(self, data: bytes = None) +STATIC mp_obj_t mod_TrezorCrypto_Ripemd160_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_obj_Ripemd160_t *o = m_new_obj(mp_obj_Ripemd160_t); + o->base.type = type; + // constructor called with bytes/str as first parameter + if (n_args == 1) { + if (!MP_OBJ_IS_STR_OR_BYTES(args[0])) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Invalid argument")); + } + GET_STR_DATA_LEN(args[0], data, datalen); + ripemd160(data, datalen, o->hash); + } else { + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Invalid arguments")); + } + return MP_OBJ_FROM_PTR(o); +} + +// no update for now ... + +// def Ripemd160.digest(self) -> bytes +STATIC mp_obj_t mod_TrezorCrypto_Ripemd160_digest(mp_obj_t self) { + mp_obj_Ripemd160_t *o = MP_OBJ_TO_PTR(self); + vstr_t vstr; + vstr_init_len(&vstr, 20); // 160 bit = 20 bytes + memcpy(vstr.buf, o->hash, 20); + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Ripemd160_digest_obj, mod_TrezorCrypto_Ripemd160_digest); + +// Ripemd160 stuff + +STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Ripemd160_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_TrezorCrypto_Ripemd160_digest_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(mod_TrezorCrypto_Ripemd160_locals_dict, mod_TrezorCrypto_Ripemd160_locals_dict_table); + +STATIC const mp_obj_type_t mod_TrezorCrypto_Ripemd160_type = { + { &mp_type_type }, + .name = MP_QSTR_Ripemd160, + .make_new = mod_TrezorCrypto_Ripemd160_make_new, + .locals_dict = (void*)&mod_TrezorCrypto_Ripemd160_locals_dict, +}; diff --git a/extmod/modTrezorCrypto/modTrezorCrypto-sha256.h b/extmod/modTrezorCrypto/modTrezorCrypto-sha256.h index 9564a4296..afd88a8c4 100644 --- a/extmod/modTrezorCrypto/modTrezorCrypto-sha256.h +++ b/extmod/modTrezorCrypto/modTrezorCrypto-sha256.h @@ -5,9 +5,10 @@ * see LICENSE.md file for details */ -#include "trezor-crypto/sha2.h" #include "py/objstr.h" +#include "trezor-crypto/sha2.h" + // class Sha256(object): typedef struct _mp_obj_Sha256_t { mp_obj_base_t base; diff --git a/extmod/modTrezorCrypto/modTrezorCrypto-sha512.h b/extmod/modTrezorCrypto/modTrezorCrypto-sha512.h index d32900f22..ba0104124 100644 --- a/extmod/modTrezorCrypto/modTrezorCrypto-sha512.h +++ b/extmod/modTrezorCrypto/modTrezorCrypto-sha512.h @@ -5,9 +5,10 @@ * see LICENSE.md file for details */ -#include "trezor-crypto/sha2.h" #include "py/objstr.h" +#include "trezor-crypto/sha2.h" + // class Sha512(object): typedef struct _mp_obj_Sha512_t { mp_obj_base_t base; diff --git a/extmod/modTrezorCrypto/modTrezorCrypto.c b/extmod/modTrezorCrypto/modTrezorCrypto.c index baa7ba57e..776939095 100644 --- a/extmod/modTrezorCrypto/modTrezorCrypto.c +++ b/extmod/modTrezorCrypto/modTrezorCrypto.c @@ -16,6 +16,7 @@ #if MICROPY_PY_TREZORCRYPTO #include "modTrezorCrypto-base58.h" +#include "modTrezorCrypto-ripemd160.h" #include "modTrezorCrypto-sha256.h" #include "modTrezorCrypto-sha512.h" @@ -24,6 +25,7 @@ STATIC const mp_rom_map_elem_t mp_module_TrezorCrypto_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_TrezorCrypto) }, { MP_ROM_QSTR(MP_QSTR_Base58), MP_ROM_PTR(&mod_TrezorCrypto_Base58_type) }, + { MP_ROM_QSTR(MP_QSTR_Ripemd160), MP_ROM_PTR(&mod_TrezorCrypto_Ripemd160_type) }, { MP_ROM_QSTR(MP_QSTR_Sha256), MP_ROM_PTR(&mod_TrezorCrypto_Sha256_type) }, { MP_ROM_QSTR(MP_QSTR_Sha512), MP_ROM_PTR(&mod_TrezorCrypto_Sha512_type) }, }; diff --git a/src/tests/test_crypto_ripemd160.py b/src/tests/test_crypto_ripemd160.py new file mode 100644 index 000000000..4fa22dd6c --- /dev/null +++ b/src/tests/test_crypto_ripemd160.py @@ -0,0 +1,24 @@ +import sys +sys.path.append('..') +sys.path.append('../lib') +import unittest +import trezor.utils + +import trezor.crypto.hash + +class TestCryptoRipemd160(unittest.TestCase): + + # vectors from http://homes.esat.kuleuven.be/~bosselae/ripemd160.html + + def test_digest(self): + self.assertEqual(trezor.crypto.hash.ripemd160(b'').digest(), trezor.utils.unhexlify('9c1185a5c5e9fc54612808977ee8f548b2258d31')) + self.assertEqual(trezor.crypto.hash.ripemd160(b'a').digest(), trezor.utils.unhexlify('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe')) + self.assertEqual(trezor.crypto.hash.ripemd160(b'abc').digest(), trezor.utils.unhexlify('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc')) + self.assertEqual(trezor.crypto.hash.ripemd160(b'message digest').digest(), trezor.utils.unhexlify('5d0689ef49d2fae572b881b123a85ffa21595f36')) + self.assertEqual(trezor.crypto.hash.ripemd160(b'abcdefghijklmnopqrstuvwxyz').digest(), trezor.utils.unhexlify('f71c27109c692c1b56bbdceb5b9d2865b3708dbc')) + self.assertEqual(trezor.crypto.hash.ripemd160(b'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq').digest(), trezor.utils.unhexlify('12a053384a9c0c88e405a06c27dcf49ada62eb2b')) + self.assertEqual(trezor.crypto.hash.ripemd160(b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789').digest(), trezor.utils.unhexlify('b0e20b6e3116640286ed3a87a5713079b21f5189')) + self.assertEqual(trezor.crypto.hash.ripemd160(b'12345678901234567890123456789012345678901234567890123456789012345678901234567890').digest(), trezor.utils.unhexlify('9b752e45573d4b39f4dbd3323cab82bf63326bfb')) + +if __name__ == '__main__': + unittest.main() diff --git a/src/trezor/crypto/hash.py b/src/trezor/crypto/hash.py index 514359a3d..3c4d35264 100644 --- a/src/trezor/crypto/hash.py +++ b/src/trezor/crypto/hash.py @@ -1,2 +1,3 @@ +from TrezorCrypto import Ripemd160 as ripemd160 from TrezorCrypto import Sha256 as sha256 from TrezorCrypto import Sha512 as sha512 diff --git a/vendor/micropython b/vendor/micropython index fc29254cd..52d6f0318 160000 --- a/vendor/micropython +++ b/vendor/micropython @@ -1 +1 @@ -Subproject commit fc29254cd7037b817154f9154509018594f77d5c +Subproject commit 52d6f0318203eaa2c1ab58da944aafdb857e0119