diff --git a/extmod/modtrezorcrypto/base58.c b/extmod/modtrezorcrypto/base58.c deleted file mode 100644 index de83c133b4..0000000000 --- a/extmod/modtrezorcrypto/base58.c +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Copyright (c) 2012-2014 Luke Dashjr - * Copyright (c) 2013-2014 Pavol Rusnak - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include "base58.h" - -static const int8_t b58digits_map[] = { - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1, - -1, 9,10,11,12,13,14,15,16,-1,17,18,19,20,21,-1, - 22,23,24,25,26,27,28,29,30,31,32,-1,-1,-1,-1,-1, - -1,33,34,35,36,37,38,39,40,41,42,43,-1,44,45,46, - 47,48,49,50,51,52,53,54,55,56,57,-1,-1,-1,-1,-1, -}; - -bool b58tobin(void *bin, size_t *binszp, const char *b58) -{ - size_t binsz = *binszp; - const unsigned char *b58u = (void*)b58; - unsigned char *binu = bin; - size_t outisz = (binsz + 3) / 4; - uint32_t outi[outisz]; - uint64_t t; - uint32_t c; - size_t i, j; - uint8_t bytesleft = binsz % 4; - uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0; - unsigned zerocount = 0; - size_t b58sz; - - b58sz = strlen(b58); - - memset(outi, 0, outisz * sizeof(*outi)); - - // Leading zeros, just count - for (i = 0; i < b58sz && !b58digits_map[b58u[i]]; ++i) - ++zerocount; - - for ( ; i < b58sz; ++i) - { - if (b58u[i] & 0x80) - // High-bit set on invalid digit - return false; - if (b58digits_map[b58u[i]] == -1) - // Invalid base58 digit - return false; - c = (unsigned)b58digits_map[b58u[i]]; - for (j = outisz; j--; ) - { - t = ((uint64_t)outi[j]) * 58 + c; - c = (t & 0x3f00000000) >> 32; - outi[j] = t & 0xffffffff; - } - if (c) - // Output number too big (carry to the next int32) - return false; - if (outi[0] & zeromask) - // Output number too big (last int32 filled too far) - return false; - } - - j = 0; - switch (bytesleft) { - case 3: - *(binu++) = (outi[0] & 0xff0000) >> 16; - case 2: - *(binu++) = (outi[0] & 0xff00) >> 8; - case 1: - *(binu++) = (outi[0] & 0xff); - ++j; - default: - break; - } - - for (; j < outisz; ++j) - { - *(binu++) = (outi[j] >> 0x18) & 0xff; - *(binu++) = (outi[j] >> 0x10) & 0xff; - *(binu++) = (outi[j] >> 8) & 0xff; - *(binu++) = (outi[j] >> 0) & 0xff; - } - - // Count canonical base58 byte count - binu = bin; - for (i = 0; i < binsz; ++i) - { - if (binu[i]) - break; - --*binszp; - } - *binszp += zerocount; - - return true; -} - -static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; - -bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) -{ - const uint8_t *bin = data; - int carry; - ssize_t i, j, high, zcount = 0; - size_t size; - - while (zcount < (ssize_t)binsz && !bin[zcount]) - ++zcount; - - size = (binsz - zcount) * 138 / 100 + 1; - uint8_t buf[size]; - memset(buf, 0, size); - - for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) - { - for (carry = bin[i], j = size - 1; (j > high) || carry; --j) - { - carry += 256 * buf[j]; - buf[j] = carry % 58; - carry /= 58; - } - } - - for (j = 0; j < (ssize_t)size && !buf[j]; ++j); - - if (*b58sz <= zcount + size - j) - { - *b58sz = zcount + size - j + 1; - return false; - } - - if (zcount) - memset(b58, '1', zcount); - for (i = zcount; j < (ssize_t)size; ++i, ++j) - b58[i] = b58digits_ordered[buf[j]]; - b58[i] = '\0'; - *b58sz = i + 1; - - return true; -} diff --git a/extmod/modtrezorcrypto/base58.h b/extmod/modtrezorcrypto/base58.h deleted file mode 100644 index aa78a0b42e..0000000000 --- a/extmod/modtrezorcrypto/base58.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) 2013-2014 Tomas Dzetkulic - * Copyright (c) 2013-2014 Pavol Rusnak - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES - * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef __BASE58_H__ -#define __BASE58_H__ - -#include -#include - -bool b58tobin(void *bin, size_t *binszp, const char *b58); -bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz); - -#endif diff --git a/extmod/modtrezorcrypto/modtrezorcrypto-base58.h b/extmod/modtrezorcrypto/modtrezorcrypto-base58.h deleted file mode 100644 index dbf8410aac..0000000000 --- a/extmod/modtrezorcrypto/modtrezorcrypto-base58.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) Pavol Rusnak, SatoshiLabs - * - * Licensed under Microsoft Reference Source License (Ms-RSL) - * see LICENSE.md file for details - */ - -#include "base58.h" - -// class Base58(object): -typedef struct _mp_obj_Base58_t { - mp_obj_base_t base; -} mp_obj_Base58_t; - -// def Base58.__init__(self) -STATIC mp_obj_t mod_TrezorCrypto_Base58_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, 0, false); - mp_obj_Base58_t *o = m_new_obj(mp_obj_Base58_t); - o->base.type = type; - return MP_OBJ_FROM_PTR(o); -} - -// def Base58.encode(self, data: bytes) -> str -STATIC mp_obj_t mod_TrezorCrypto_Base58_encode(mp_obj_t self, mp_obj_t data) { - mp_buffer_info_t databuf; - mp_get_buffer_raise(data, &databuf, MP_BUFFER_READ); - vstr_t vstr; - vstr_init_len(&vstr, databuf.len * 8000 / 5857 + 1); // 256 = 2^8 ; 58 > 2^5.857 - bool r = b58enc(vstr.buf, &vstr.len, databuf.buf, databuf.len); - if (!r) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid input")); - } - vstr.len--; // b58enc returns length including the trailing zero - return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_TrezorCrypto_Base58_encode_obj, mod_TrezorCrypto_Base58_encode); - -// def Base58.decode(self, string: str) -> bytes -STATIC mp_obj_t mod_TrezorCrypto_Base58_decode(mp_obj_t self, mp_obj_t string) { - mp_buffer_info_t stringbuf; - mp_get_buffer_raise(string, &stringbuf, MP_BUFFER_READ); - vstr_t vstr; - vstr_init_len(&vstr, stringbuf.len * 5858 / 8000 + 1); // 256 = 2^8 ; 58 < 2^5.858 - bool r = b58tobin(vstr.buf, &vstr.len, stringbuf.buf); - if (!r) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid input")); - } - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_TrezorCrypto_Base58_decode_obj, mod_TrezorCrypto_Base58_decode); - -// Base58 stuff - -STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Base58_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_encode), MP_ROM_PTR(&mod_TrezorCrypto_Base58_encode_obj) }, - { MP_ROM_QSTR(MP_QSTR_decode), MP_ROM_PTR(&mod_TrezorCrypto_Base58_decode_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(mod_TrezorCrypto_Base58_locals_dict, mod_TrezorCrypto_Base58_locals_dict_table); - -STATIC const mp_obj_type_t mod_TrezorCrypto_Base58_type = { - { &mp_type_type }, - .name = MP_QSTR_Base58, - .make_new = mod_TrezorCrypto_Base58_make_new, - .locals_dict = (void*)&mod_TrezorCrypto_Base58_locals_dict, -}; diff --git a/extmod/modtrezorcrypto/modtrezorcrypto.c b/extmod/modtrezorcrypto/modtrezorcrypto.c index 89f3c16587..520f2c71c7 100644 --- a/extmod/modtrezorcrypto/modtrezorcrypto.c +++ b/extmod/modtrezorcrypto/modtrezorcrypto.c @@ -15,7 +15,6 @@ #if MICROPY_PY_TREZORCRYPTO -#include "modtrezorcrypto-base58.h" #include "modtrezorcrypto-pbkdf2_hmac.h" #include "modtrezorcrypto-ripemd160.h" #include "modtrezorcrypto-sha256.h" @@ -25,7 +24,6 @@ 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/trezor/crypto/base58.py b/src/trezor/crypto/base58.py index 04a2c2a287..3c1cd00910 100644 --- a/src/trezor/crypto/base58.py +++ b/src/trezor/crypto/base58.py @@ -1,22 +1,70 @@ -from TrezorCrypto import Base58 +# +# Copyright (c) 2015 David Keijser +# Copyright (c) 2016 Pavol Rusnak +# +# Licensed under MIT License +# +# Implementations of Base58 and Base58Check encodings that are compatible +# with the bitcoin network. +# +# This module is based upon base58 snippets found scattered over many bitcoin +# tools written in python. From what I gather the original source is from a +# forum post by Gavin Andresen, so direct your praise to him. +# This module adds shiny packaging and support for python3. +# + from .hashlib import sha256 -_base58 = Base58() +# 58 character alphabet used +alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' -def encode(data): - return _base58.encode(data) +def encode(v): + origlen = len(v) + v = v.lstrip(b'\0') + newlen = len(v) -def decode(string): - return _base58.decode(string) + p, acc = 1, 0 + for c in reversed(v): + acc += p * c + p = p << 8 -def encode_check(data, hashlen=4): - h = sha256(sha256(data).digest()).digest() - return encode(data + h[:hashlen]) + result = '' + while acc > 0: + acc, mod = divmod(acc, 58) + result += alphabet[mod] -def decode_check(string, hashlen=4): - data = decode(string) - d, h1 = data[:-hashlen], data[-hashlen:] - h2 = sha256(sha256(d).digest).digest()[:4] - if h1 != h2: - raise RuntimeError('Checksum error') - return d + return ''.join([c for c in reversed(result + alphabet[0] * (origlen - newlen))]) + + +def decode(v): + origlen = len(v) + v = v.lstrip(alphabet[0]) + newlen = len(v) + + p, acc = 1, 0 + for c in reversed(v): + acc += p * alphabet.index(c) + p *= 58 + + result = [] + while acc > 0: + acc, mod = divmod(acc, 256) + result.append(mod) + + return bytes([b for b in reversed(result +[0] * (origlen - newlen))]) + + +def encode_check(v): + digest = sha256(sha256(v).digest()).digest() + return encode(v + digest[:4]) + + +def decode_check(v): + result = decode(v) + result, check = result[:-4], result[-4:] + digest = sha256(sha256(result).digest()).digest() + + if check != digest[:4]: + raise ValueError("Invalid checksum") + + return result diff --git a/vendor/micropython b/vendor/micropython index 07d410191a..220438d7b9 160000 --- a/vendor/micropython +++ b/vendor/micropython @@ -1 +1 @@ -Subproject commit 07d410191ad0bb5560a7a35a234291a8488f8e56 +Subproject commit 220438d7b96746cf5f53114c1b946acb56ff83e9