1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-10 15:30:55 +00:00

slip39: cstyle and documentation.

This commit is contained in:
Andrew Kozlik 2019-04-14 21:07:25 +02:00
parent cd08c6937b
commit f06416eeff
3 changed files with 239 additions and 270 deletions

View File

@ -18,7 +18,6 @@
*/ */
#include "py/obj.h" #include "py/obj.h"
#include "py/objstr.h"
#include "embed/extmod/trezorobj.h" #include "embed/extmod/trezorobj.h"
@ -30,8 +29,9 @@
/// ''' /// '''
/// Returns f(x) given the Shamir shares (x_1, f(x_1)), ... , (x_k, f(x_k)). /// Returns f(x) given the Shamir shares (x_1, f(x_1)), ... , (x_k, f(x_k)).
/// :param shares: The Shamir shares. /// :param shares: The Shamir shares.
/// :type shares: A list of pairs (x_i, y_i), where x_i is an integer and y_i is an array of /// :type shares: A list of pairs (x_i, y_i), where x_i is an integer and
/// bytes representing the evaluations of the polynomials in x_i. /// y_i is an array of bytes representing the evaluations of the
/// polynomials in x_i.
/// :param int x: The x coordinate of the result. /// :param int x: The x coordinate of the result.
/// :return: Evaluations of the polynomials in x. /// :return: Evaluations of the polynomials in x.
/// :rtype: Array of bytes. /// :rtype: Array of bytes.
@ -39,10 +39,7 @@
mp_obj_t mod_trezorcrypto_shamir_interpolate(mp_obj_t shares, mp_obj_t x) { mp_obj_t mod_trezorcrypto_shamir_interpolate(mp_obj_t shares, mp_obj_t x) {
size_t share_count; size_t share_count;
mp_obj_t *share_items; mp_obj_t *share_items;
if (!MP_OBJ_IS_TYPE(shares, &mp_type_list)) { mp_obj_get_array(shares, &share_count, &share_items);
mp_raise_TypeError("Expected a list.");
}
mp_obj_list_get(shares, &share_count, &share_items);
if (share_count < 1 || share_count > MAX_SHARE_COUNT) { if (share_count < 1 || share_count > MAX_SHARE_COUNT) {
mp_raise_ValueError("Invalid number of shares."); mp_raise_ValueError("Invalid number of shares.");
} }
@ -51,15 +48,8 @@ mp_obj_t mod_trezorcrypto_shamir_interpolate(mp_obj_t shares, mp_obj_t x) {
const uint8_t *share_values[MAX_SHARE_COUNT]; const uint8_t *share_values[MAX_SHARE_COUNT];
size_t value_len = 0; size_t value_len = 0;
for (int i = 0; i < share_count; ++i) { for (int i = 0; i < share_count; ++i) {
if (!MP_OBJ_IS_TYPE(share_items[i], &mp_type_tuple)) {
mp_raise_TypeError("Expected a tuple.");
}
size_t tuple_len;
mp_obj_t *share; mp_obj_t *share;
mp_obj_tuple_get(share_items[i], &tuple_len, &share); mp_obj_get_array_fixed_n(share_items[i], 2, &share);
if (tuple_len != 2) {
mp_raise_ValueError("Expected a tuple of length 2.");
}
share_indices[i] = trezor_obj_get_uint8(share[0]); share_indices[i] = trezor_obj_get_uint8(share[0]);
mp_buffer_info_t value; mp_buffer_info_t value;
mp_get_buffer_raise(share[1], &value, MP_BUFFER_READ); mp_get_buffer_raise(share[1], &value, MP_BUFFER_READ);
@ -76,7 +66,8 @@ mp_obj_t mod_trezorcrypto_shamir_interpolate(mp_obj_t shares, mp_obj_t x) {
} }
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, value_len); vstr_init_len(&vstr, value_len);
shamir_interpolate((uint8_t*) vstr.buf, x_uint8, share_indices, share_values, share_count, value_len); shamir_interpolate((uint8_t *)vstr.buf, x_uint8, share_indices, share_values,
share_count, value_len);
vstr_cut_tail_bytes(&vstr, vstr_len(&vstr) - value_len); vstr_cut_tail_bytes(&vstr, vstr_len(&vstr) - value_len);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
} }
@ -85,7 +76,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorcrypto_shamir_interpolate_obj,
STATIC const mp_rom_map_elem_t mod_trezorcrypto_shamir_globals_table[] = { STATIC const mp_rom_map_elem_t mod_trezorcrypto_shamir_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_shamir)}, {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_shamir)},
{MP_ROM_QSTR(MP_QSTR_interpolate), MP_ROM_PTR(&mod_trezorcrypto_shamir_interpolate_obj)}, {MP_ROM_QSTR(MP_QSTR_interpolate),
MP_ROM_PTR(&mod_trezorcrypto_shamir_interpolate_obj)},
}; };
STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_shamir_globals, STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_shamir_globals,
mod_trezorcrypto_shamir_globals_table); mod_trezorcrypto_shamir_globals_table);

View File

@ -35,73 +35,58 @@
* lookup operations, as all proper crypto code must be. * lookup operations, as all proper crypto code must be.
*/ */
#include "shamir.h" #include "shamir.h"
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
static void static void bitslice(uint32_t r[8], const uint8_t *x, size_t len) {
bitslice(uint32_t r[8], const uint8_t *x, size_t len)
{
size_t bit_idx, arr_idx; size_t bit_idx, arr_idx;
uint32_t cur; uint32_t cur;
memset(r, 0, sizeof(uint32_t[8])); memset(r, 0, sizeof(uint32_t[8]));
for (arr_idx = 0; arr_idx < len; arr_idx++) { for (arr_idx = 0; arr_idx < len; arr_idx++) {
cur = (uint32_t) x[arr_idx]; cur = (uint32_t)x[arr_idx];
for (bit_idx = 0; bit_idx < 8; bit_idx++) { for (bit_idx = 0; bit_idx < 8; bit_idx++) {
r[bit_idx] |= ((cur & (1 << bit_idx)) >> bit_idx) << arr_idx; r[bit_idx] |= ((cur & (1 << bit_idx)) >> bit_idx) << arr_idx;
} }
} }
} }
static void unbitslice(uint8_t *r, const uint32_t x[8], size_t len) {
static void
unbitslice(uint8_t *r, const uint32_t x[8], size_t len)
{
size_t bit_idx, arr_idx; size_t bit_idx, arr_idx;
uint32_t cur; uint32_t cur;
memset(r, 0, sizeof(uint8_t) * len); memset(r, 0, sizeof(uint8_t) * len);
for (bit_idx = 0; bit_idx < 8; bit_idx++) { for (bit_idx = 0; bit_idx < 8; bit_idx++) {
cur = (uint32_t) x[bit_idx]; cur = (uint32_t)x[bit_idx];
for (arr_idx = 0; arr_idx < len; arr_idx++) { for (arr_idx = 0; arr_idx < len; arr_idx++) {
r[arr_idx] |= ((cur & (1 << arr_idx)) >> arr_idx) << bit_idx; r[arr_idx] |= ((cur & (1 << arr_idx)) >> arr_idx) << bit_idx;
} }
} }
} }
static void bitslice_setall(uint32_t r[8], const uint8_t x) {
static void
bitslice_setall(uint32_t r[8], const uint8_t x)
{
size_t idx; size_t idx;
for (idx = 0; idx < 8; idx++) { for (idx = 0; idx < 8; idx++) {
r[idx] = ((int32_t) ((x & (1 << idx)) << (31 - idx))) >> 31; r[idx] = ((int32_t)((x & (1 << idx)) << (31 - idx))) >> 31;
} }
} }
/* /*
* Add (XOR) `r` with `x` and store the result in `r`. * Add (XOR) `r` with `x` and store the result in `r`.
*/ */
static void static void gf256_add(uint32_t r[8], const uint32_t x[8]) {
gf256_add(uint32_t r[8], const uint32_t x[8])
{
size_t idx; size_t idx;
for (idx = 0; idx < 8; idx++) r[idx] ^= x[idx]; for (idx = 0; idx < 8; idx++) r[idx] ^= x[idx];
} }
/* /*
* Safely multiply two bitsliced polynomials in GF(2^8) reduced by * Safely multiply two bitsliced polynomials in GF(2^8) reduced by
* x^8 + x^4 + x^3 + x + 1. `r` and `a` may overlap, but overlapping of `r` * x^8 + x^4 + x^3 + x + 1. `r` and `a` may overlap, but overlapping of `r`
* and `b` will produce an incorrect result! If you need to square a polynomial * and `b` will produce an incorrect result! If you need to square a polynomial
* use `gf256_square` instead. * use `gf256_square` instead.
*/ */
static void static void gf256_mul(uint32_t r[8], const uint32_t a[8], const uint32_t b[8]) {
gf256_mul(uint32_t r[8], const uint32_t a[8], const uint32_t b[8])
{
/* This function implements Russian Peasant multiplication on two /* This function implements Russian Peasant multiplication on two
* bitsliced polynomials. * bitsliced polynomials.
* *
@ -208,13 +193,10 @@ gf256_mul(uint32_t r[8], const uint32_t a[8], const uint32_t b[8])
r[7] ^= a2[0] & b[7]; r[7] ^= a2[0] & b[7];
} }
/* /*
* Square `x` in GF(2^8) and write the result to `r`. `r` and `x` may overlap. * Square `x` in GF(2^8) and write the result to `r`. `r` and `x` may overlap.
*/ */
static void static void gf256_square(uint32_t r[8], const uint32_t x[8]) {
gf256_square(uint32_t r[8], const uint32_t x[8])
{
uint32_t r8, r10, r12, r14; uint32_t r8, r10, r12, r14;
/* Use the Freshman's Dream rule to square the polynomial /* Use the Freshman's Dream rule to square the polynomial
* Assignments are done from 7 downto 0, because this allows the user * Assignments are done from 7 downto 0, because this allows the user
@ -253,13 +235,10 @@ gf256_square(uint32_t r[8], const uint32_t x[8])
r[4] ^= r8; r[4] ^= r8;
} }
/* /*
* Invert `x` in GF(2^8) and write the result to `r` * Invert `x` in GF(2^8) and write the result to `r`
*/ */
static void static void gf256_inv(uint32_t r[8], uint32_t x[8]) {
gf256_inv(uint32_t r[8], uint32_t x[8])
{
uint32_t y[8], z[8]; uint32_t y[8], z[8];
gf256_square(y, x); // y = x^2 gf256_square(y, x); // y = x^2
@ -275,14 +254,10 @@ gf256_inv(uint32_t r[8], uint32_t x[8])
gf256_mul(r, r, y); // r = x^254 gf256_mul(r, r, y); // r = x^254
} }
void shamir_interpolate(uint8_t *result, uint8_t result_index,
void shamir_interpolate(uint8_t *result,
uint8_t result_index,
const uint8_t *share_indices, const uint8_t *share_indices,
const uint8_t **share_values, const uint8_t **share_values, uint8_t share_count,
uint8_t share_count, size_t len) {
size_t len)
{
size_t i, j; size_t i, j;
uint32_t xs[share_count][8], ys[share_count][8]; uint32_t xs[share_count][8], ys[share_count][8];
uint32_t x[8]; uint32_t x[8];
@ -290,8 +265,7 @@ void shamir_interpolate(uint8_t *result,
uint32_t num[8] = {~0}; /* num is the numerator (=1) */ uint32_t num[8] = {~0}; /* num is the numerator (=1) */
uint32_t secret[8] = {0}; uint32_t secret[8] = {0};
if (len > SHAMIR_MAX_LEN) if (len > SHAMIR_MAX_LEN) return;
return;
/* Collect the x and y values */ /* Collect the x and y values */
for (i = 0; i < share_count; i++) { for (i = 0; i < share_count; i++) {
@ -323,4 +297,3 @@ void shamir_interpolate(uint8_t *result,
} }
unbitslice(result, secret, len); unbitslice(result, secret, len);
} }

View File

@ -26,7 +26,6 @@
* intermediate level API. You have been warned! * intermediate level API. You have been warned!
*/ */
#ifndef __SHAMIR_H__ #ifndef __SHAMIR_H__
#define __SHAMIR_H__ #define __SHAMIR_H__
@ -36,12 +35,19 @@
#define SHAMIR_MAX_LEN 32 #define SHAMIR_MAX_LEN 32
/* /*
A list of pairs (x_i, y_i), where x_i is an integer and y_i is an array of bytes representing the evaluations of the polynomials in x_i. * Computes f(x) given the Shamir shares (x_1, f(x_1)), ... , (x_m, f(x_m)).
The x coordinate of the result. * result: Array of length len where the evaluations of the polynomials in x
Evaluations of the polynomials in x. * will be written.
* Interpolate the `m` shares provided in `shares` and write the evaluation at * result_index: The x coordinate of the result.
* point `x` to `result`. The number of shares used to compute the result may * share_indices: Points to an array of integers x_1, ... , x_m.
* be larger than the threshold needed to . * share_values: Points to an array of y_1, ... , y_m, where each y_i is an
* array of bytes of length len representing the evaluations of the
* polynomials in x_i.
* share_count: The number of shares m.
* len: The length of the result array and each of the y_1, ... , y_m arrays.
* The number of shares used to compute the result may be larger than the
* required threshold.
* *
* This function does *not* do *any* checking for integrity. If any of the * This function does *not* do *any* checking for integrity. If any of the
* shares are not original, this will result in an invalid restored value. * shares are not original, this will result in an invalid restored value.
@ -49,14 +55,12 @@ Evaluations of the polynomials in x.
* the shares that were provided as input were incorrect, the result *still* * the shares that were provided as input were incorrect, the result *still*
* allows an attacker to gain information about the correct result. * allows an attacker to gain information about the correct result.
* *
* This function treats `shares` and `result` as secret values. `m` is treated as * This function treats `shares_values`, `share_indices` and `result` as secret
* a public value (for performance reasons). * values. `share_count` is treated as a public value (for performance reasons).
*/ */
void shamir_interpolate(uint8_t *result, void shamir_interpolate(uint8_t *result, uint8_t result_index,
uint8_t result_index,
const uint8_t *share_indices, const uint8_t *share_indices,
const uint8_t **share_values, const uint8_t **share_values, uint8_t share_count,
uint8_t share_count,
size_t len); size_t len);
#endif /* __SHAMIR_H__ */ #endif /* __SHAMIR_H__ */