diff --git a/extmod/modtrezorcrypto/modtrezorcrypto-ssss.h b/extmod/modtrezorcrypto/modtrezorcrypto-ssss.h index 82372c7dac..828fd8c223 100644 --- a/extmod/modtrezorcrypto/modtrezorcrypto-ssss.h +++ b/extmod/modtrezorcrypto/modtrezorcrypto-ssss.h @@ -7,6 +7,9 @@ #include "py/objstr.h" +#include "trezor-crypto/bignum.h" +#include "ssss.h" + typedef struct _mp_obj_SSSS_t { mp_obj_base_t base; } mp_obj_SSSS_t; @@ -27,12 +30,23 @@ STATIC mp_obj_t mod_TrezorCrypto_SSSS_split(size_t n_args, const mp_obj_t *args) mp_int_t n = mp_obj_get_int(args[2]); mp_buffer_info_t secret; mp_get_buffer_raise(args[3], &secret, MP_BUFFER_READ); - (void)m; + if (secret.len != 32) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Length of the secret has to be 256 bits")); + } + if (m < 1 || n < 1 || m > 15 || n > 15 || m > n) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid number of shares")); + } + bignum256 sk; + bignum256 shares[n]; + bn_read_be(secret.buf, &sk); + if (!ssss_split(&sk, m, n, shares)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Error splitting secret")); + } mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(n, NULL)); vstr_t vstr[n]; for (int i = 0; i < n; i++) { vstr_init_len(&vstr[i], secret.len); - memcpy(vstr[i].buf, secret.buf, secret.len); + bn_write_be(&shares[i], secret.buf); tuple->items[i] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr[i]); } return MP_OBJ_FROM_PTR(tuple); @@ -44,16 +58,37 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_TrezorCrypto_SSSS_split_obj, 4, 4 /// Combine M shares of Shamir's Secret Sharing Scheme into secret /// STATIC mp_obj_t mod_TrezorCrypto_SSSS_combine(mp_obj_t self, mp_obj_t shares) { - mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(shares); - mp_int_t m = 0; - mp_int_t n = tuple->len; - for (int i = 0; i < n; i++) { - mp_obj_t share = tuple->items[i]; - if (share != mp_const_none) { - m++; + mp_uint_t n; + mp_obj_t *share; + if (MP_OBJ_IS_TYPE(shares, &mp_type_tuple)) { + mp_obj_tuple_get(shares, &n, &share); + } else + if (MP_OBJ_IS_TYPE(shares, &mp_type_list)) { + mp_obj_list_get(shares, &n, &share); + } else { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "List or tuple expected")); + } + if (n < 1 || n > 15) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid number of shares")); + } + bignum256 bnshares[n]; + for (mp_uint_t i = 0; i < n; i++) { + if (MP_OBJ_IS_TYPE(share[i], &mp_type_bytes)) { + mp_buffer_info_t s; + mp_get_buffer_raise(share[i], &s, MP_BUFFER_READ); + bn_read_be(s.buf, &bnshares[n]); + } else { + memset(&bnshares[i], 0, sizeof(bignum256)); } } - return tuple->items[0]; + bignum256 sk; + if (!ssss_combine(bnshares, n, &sk)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Error combining secret")); + } + vstr_t vstr; + vstr_init_len(&vstr, 32); + bn_write_be(&sk, (uint8_t *)vstr.buf); + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_TrezorCrypto_SSSS_combine_obj, mod_TrezorCrypto_SSSS_combine); diff --git a/extmod/modtrezorcrypto/ssss.c b/extmod/modtrezorcrypto/ssss.c new file mode 100644 index 0000000000..6665821409 --- /dev/null +++ b/extmod/modtrezorcrypto/ssss.c @@ -0,0 +1,14 @@ +#include "ssss.h" + +bool ssss_split(const bignum256 *secret, int m, int n, bignum256 *shares) +{ + if (m < 1 || n < 1 || m > 15 || n > 15 || m > n) { + return false; + } + return true; +} + +bool ssss_combine(const bignum256 *shares, int n, bignum256 *secret) +{ + return true; +} diff --git a/extmod/modtrezorcrypto/ssss.h b/extmod/modtrezorcrypto/ssss.h new file mode 100644 index 0000000000..5fc12b787e --- /dev/null +++ b/extmod/modtrezorcrypto/ssss.h @@ -0,0 +1,10 @@ +#ifndef __SSSS_H__ +#define __SSSS_H__ + +#include +#include "bignum.h" + +bool ssss_split(const bignum256 *secret, int m, int n, bignum256 *shares); +bool ssss_combine(const bignum256 *shares, int n, bignum256 *secret); + +#endif diff --git a/vendor/micropython b/vendor/micropython index 4509a515d6..579656fb2f 160000 --- a/vendor/micropython +++ b/vendor/micropython @@ -1 +1 @@ -Subproject commit 4509a515d6057d2fca4b642b055108c2ff6bf78b +Subproject commit 579656fb2f3c020b4e1c94d3ac8b5f3eb249bcb7