Skip to content

Commit

Permalink
Improve efficiency of SSS interpolate() function
Browse files Browse the repository at this point in the history
  • Loading branch information
aido committed Mar 6, 2024
1 parent a8e9bba commit 315ec8d
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 106 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Change log

## [1.7.1] - 2024-03-06
### Added
-

### Changed
- Improve efficiency of SSS `interpolate()` function

### Fixed
-

## [1.7.0] - 2024-03-03
### Added
- Added detailed documentation for all SSKR and SSS functions
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ all: default
APPNAME = "Seed Tool"
APPVERSION_M = 1
APPVERSION_N = 7
APPVERSION_P = 0
APPVERSION_P = 1
APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)"

APP_LOAD_PARAMS = --appFlags 0x10 $(COMMON_LOAD_PARAMS) --curve secp256k1 --path ""
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
[![Release](https://img.shields.io/github/release/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/releases)
[![License](https://img.shields.io/github/license/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/blob/develop/LICENSE)

![nanos](https://img.shields.io/badge/nanos-working-green)
![nanox](https://img.shields.io/badge/nanox-working-green)
![nanosp](https://img.shields.io/badge/nanosp-working-green)
![stax](https://img.shields.io/badge/stax-in_progress-orange)
![nanos](https://img.shields.io/badge/nanos-working-green?logo=data:image/svg%2bxml;base64,PHN2ZyB3aWR0aD0iMTQ3IiBoZWlnaHQ9IjEyOCIgdmlld0JveD0iMCAwIDE0NyAxMjgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTAgOTEuNjU0OFYxMjhINTUuMjkzVjExOS45NEg4LjA1NjMxVjkxLjY1NDhIMFpNMTM4Ljk0NCA5MS42NTQ4VjExOS45NEg5MS43MDdWMTI3Ljk5OEgxNDdWOTEuNjU0OEgxMzguOTQ0Wk01NS4zNzMzIDM2LjM0NTJWOTEuNjUyOUg5MS43MDdWODQuMzg0Mkg2My40Mjk2VjM2LjM0NTJINTUuMzczM1pNMCAwVjM2LjM0NTJIOC4wNTYzMVY4LjA1ODQ0SDU1LjI5M1YwSDBaTTkxLjcwNyAwVjguMDU4NDRIMTM4Ljk0NFYzNi4zNDUySDE0N1YwSDkxLjcwN1oiIGZpbGw9IndoaXRlIi8+PC9zdmc+)
![nanox](https://img.shields.io/badge/nanox-working-green?logo=data:image/svg%2bxml;base64,PHN2ZyB3aWR0aD0iMTQ3IiBoZWlnaHQ9IjEyOCIgdmlld0JveD0iMCAwIDE0NyAxMjgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTAgOTEuNjU0OFYxMjhINTUuMjkzVjExOS45NEg4LjA1NjMxVjkxLjY1NDhIMFpNMTM4Ljk0NCA5MS42NTQ4VjExOS45NEg5MS43MDdWMTI3Ljk5OEgxNDdWOTEuNjU0OEgxMzguOTQ0Wk01NS4zNzMzIDM2LjM0NTJWOTEuNjUyOUg5MS43MDdWODQuMzg0Mkg2My40Mjk2VjM2LjM0NTJINTUuMzczM1pNMCAwVjM2LjM0NTJIOC4wNTYzMVY4LjA1ODQ0SDU1LjI5M1YwSDBaTTkxLjcwNyAwVjguMDU4NDRIMTM4Ljk0NFYzNi4zNDUySDE0N1YwSDkxLjcwN1oiIGZpbGw9IndoaXRlIi8+PC9zdmc+)
![nanosp](https://img.shields.io/badge/nanosp-working-green?logo=data:image/svg%2bxml;base64,PHN2ZyB3aWR0aD0iMTQ3IiBoZWlnaHQ9IjEyOCIgdmlld0JveD0iMCAwIDE0NyAxMjgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTAgOTEuNjU0OFYxMjhINTUuMjkzVjExOS45NEg4LjA1NjMxVjkxLjY1NDhIMFpNMTM4Ljk0NCA5MS42NTQ4VjExOS45NEg5MS43MDdWMTI3Ljk5OEgxNDdWOTEuNjU0OEgxMzguOTQ0Wk01NS4zNzMzIDM2LjM0NTJWOTEuNjUyOUg5MS43MDdWODQuMzg0Mkg2My40Mjk2VjM2LjM0NTJINTUuMzczM1pNMCAwVjM2LjM0NTJIOC4wNTYzMVY4LjA1ODQ0SDU1LjI5M1YwSDBaTTkxLjcwNyAwVjguMDU4NDRIMTM4Ljk0NFYzNi4zNDUySDE0N1YwSDkxLjcwN1oiIGZpbGw9IndoaXRlIi8+PC9zdmc+)
![stax](https://img.shields.io/badge/stax-in_progress-orange?logo=data:image/svg%2bxml;base64,PHN2ZyB3aWR0aD0iMTQ3IiBoZWlnaHQ9IjEyOCIgdmlld0JveD0iMCAwIDE0NyAxMjgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTAgOTEuNjU0OFYxMjhINTUuMjkzVjExOS45NEg4LjA1NjMxVjkxLjY1NDhIMFpNMTM4Ljk0NCA5MS42NTQ4VjExOS45NEg5MS43MDdWMTI3Ljk5OEgxNDdWOTEuNjU0OEgxMzguOTQ0Wk01NS4zNzMzIDM2LjM0NTJWOTEuNjUyOUg5MS43MDdWODQuMzg0Mkg2My40Mjk2VjM2LjM0NTJINTUuMzczM1pNMCAwVjM2LjM0NTJIOC4wNTYzMVY4LjA1ODQ0SDU1LjI5M1YwSDBaTTkxLjcwNyAwVjguMDU4NDRIMTM4Ljk0NFYzNi4zNDUySDE0N1YwSDkxLjcwN1oiIGZpbGw9IndoaXRlIi8+PC9zdmc+)

[![Build app-seed-tool](https://github.com/aido/app-seed-tool/actions/workflows/ci-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/ci-workflow.yml)
[![CodeQL](https://github.com/aido/app-seed-tool/actions/workflows/codeql-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/codeql-workflow.yml)
Expand Down
2 changes: 0 additions & 2 deletions src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

#pragma once

#define memzero(...) explicit_bzero(__VA_ARGS__)

#define ONBOARDING_WORD_COMPLETION_MAX_ITEMS 8
#define BOLOS_UX_HASH_LENGTH 4 // as on the blue

Expand Down
131 changes: 37 additions & 94 deletions src/sskr/sss/interpolate.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
// Minimal required bytes for BN storing a GF(256) value
#define GF2_8_MPI_BYTES 1

#define memzero(...) explicit_bzero(__VA_ARGS__)

#ifdef TARGET_NANOS
/**
* @brief Performs a multiplication over GF(2^n).
Expand Down Expand Up @@ -135,81 +133,6 @@ cx_err_t cx_bn_gf2_n_mul(cx_bn_t bn_r,
}
#endif

/**
* @brief Performs an invert operation over GF(2^8).
*
* @param[out] bn_r BN index for the result.
*
* @param[in] bn_a BN index of the first operand.
*
* @param[in] bn_n BN index of the modulus.
* The modulus must be an irreducible polynomial over GF(2)
* of degree n.
*
* @param[in] bn_h BN index of the second montgomery constant.
*
* @return Error code:
* - CX_OK on success
* - CX_NOT_LOCKED
* - CX_INVALID_PARAMETER
* - CX_MEMORY_FULL
*/
cx_err_t bn_gf2_8_inv(cx_bn_t bn_r, const cx_bn_t bn_a, const cx_bn_t bn_n, const cx_bn_t bn_h) {
cx_err_t error = CX_OK; // By default, until some error occurs
cx_bn_t bn_x, bn_y, bn_z;

CX_CHECK(cx_bn_alloc(&bn_x, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_y, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_z, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_copy(bn_x, bn_a));

CX_CHECK(cx_bn_gf2_n_mul(bn_y, bn_x, bn_x, bn_n, bn_h)); // bn_y = bn_x^2
CX_CHECK(cx_bn_gf2_n_mul(bn_y, bn_y, bn_y, bn_n, bn_h)); // bn_y = bn_x^4
CX_CHECK(cx_bn_gf2_n_mul(bn_r, bn_y, bn_y, bn_n, bn_h)); // bn_r = bn_x^8
CX_CHECK(cx_bn_gf2_n_mul(bn_z, bn_r, bn_x, bn_n, bn_h)); // bn_z = bn_x^9
CX_CHECK(cx_bn_gf2_n_mul(bn_r, bn_r, bn_r, bn_n, bn_h)); // bn_r = bn_x^16
CX_CHECK(cx_bn_gf2_n_mul(bn_r, bn_r, bn_z, bn_n, bn_h)); // bn_r = bn_x^25
CX_CHECK(cx_bn_gf2_n_mul(bn_r, bn_r, bn_r, bn_n, bn_h)); // bn_r = bn_x^50
CX_CHECK(cx_bn_gf2_n_mul(bn_z, bn_r, bn_r, bn_n, bn_h)); // bn_z = bn_x^100
CX_CHECK(cx_bn_gf2_n_mul(bn_z, bn_z, bn_z, bn_n, bn_h)); // bn_z = bn_x^200
CX_CHECK(cx_bn_gf2_n_mul(bn_r, bn_r, bn_z, bn_n, bn_h)); // bn_r = bn_x^250
CX_CHECK(cx_bn_gf2_n_mul(bn_r, bn_r, bn_y, bn_n, bn_h)); // bn_r = bn_x^254

CX_CHECK(cx_bn_destroy(&bn_x));
CX_CHECK(cx_bn_destroy(&bn_y));
CX_CHECK(cx_bn_destroy(&bn_z));

end:
return error;
}

/**
* @brief Performs polynomial interpolation on SSS shares.
*
* @details This function interpolates a polynomial that passes through the provided points
* represented by `xi` (x-coordinates) and `yij` (y-coordinate arrays) i.e.
* where:
* xi points to [x0 x1 ... xn-1 ]
* y contains an array of pointers to 32-bit arrays of y values
* y contains [y0 y1 y2 ... yn-1]
* and each of the yi arrays contain [yi_0 yi_i ... yi_31].
*
* This interpolation is used in Shamir's Secret Sharing (SSS) to recover
* the secret from a set of shares.
*
* @param[in] n Number of points to interpolate (length of `xi` and `yij`).
* @param[in] xi Pointer to an array containing the x-coordinates of the points (length `n`).
* @param[in] yl Length of each y-coordinate array in bytes.
* @param[in] yij Pointer to an array of `n` pointers, each pointing to a y-coordinate array of
* length `yl`.
* @param[in] x X-coordinate at which to perform the interpolation.
* @param[out] result Pointer to a buffer where the interpolated value will be stored (must be `yl`
* bytes long).
*
* @return - CX_OK on success
* - A negative error code on failure (specific error codes not defined here,
* consult implementation details for specific error handling)
*/
cx_err_t interpolate(uint8_t n,
const uint8_t* xi,
uint8_t yl,
Expand All @@ -220,21 +143,20 @@ cx_err_t interpolate(uint8_t n,
const uint8_t R2[1] = MONTGOMERY_CONSTANT_R2;

cx_err_t error = CX_OK; // By default, until some error occurs
cx_bn_t bn_x, bn_xc_i, bn_xc_j;
cx_bn_t bn_numerator, bn_denominator;
cx_bn_t bn_lagrange, bn_y, bn_result, bn_temp, bn_n, bn_r2;
cx_bn_t bn_x, bn_xc_i;
cx_bn_t bn_numerator, bn_denominator, bn_lagrange;
cx_bn_t bn_result, bn_tempa, bn_tempb, bn_n, bn_r2;
uint32_t result_u32;

CX_CHECK(cx_bn_lock(GF2_8_MPI_BYTES, 0));
CX_CHECK(cx_bn_alloc(&bn_x, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_xc_i, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_xc_j, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_numerator, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_denominator, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_lagrange, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_y, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_result, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_temp, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_tempa, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc(&bn_tempb, GF2_8_MPI_BYTES));
CX_CHECK(cx_bn_alloc_init(&bn_n, GF2_8_MPI_BYTES, N, sizeof(N)));
CX_CHECK(cx_bn_alloc_init(&bn_r2, GF2_8_MPI_BYTES, R2, sizeof(R2)));

Expand All @@ -255,16 +177,38 @@ cx_err_t interpolate(uint8_t n,
// j != i (xi[i]-xi[j])
for (uint8_t j = 0; j < n; j++) {
if (j != i) {
CX_CHECK(cx_bn_set_u32(bn_xc_j, (uint32_t) xi[j]));
CX_CHECK(cx_bn_set_u32(bn_tempa, (uint32_t) xi[j]));

// Calculate the numerator (x - xc[j])
CX_CHECK(cx_bn_xor(bn_numerator, bn_x, bn_xc_j));
CX_CHECK(cx_bn_xor(bn_numerator, bn_x, bn_tempa));

// Calculate the denominator (xc[i] - xc[j])
CX_CHECK(cx_bn_xor(bn_denominator, bn_xc_i, bn_xc_j));
CX_CHECK(cx_bn_xor(bn_denominator, bn_xc_i, bn_tempa));

// Calculate the inverse of the denominator
CX_CHECK(bn_gf2_8_inv(bn_denominator, bn_denominator, bn_n, bn_r2));
// In GF(2^8) the inverse of x = x^254
// bn_result = bn_denominator^2
CX_CHECK(cx_bn_gf2_n_mul(bn_result, bn_denominator, bn_denominator, bn_n, bn_r2));
// bn_result = bn_denominator^4
CX_CHECK(cx_bn_gf2_n_mul(bn_result, bn_result, bn_result, bn_n, bn_r2));
// bn_tempa = bn_denominator^8
CX_CHECK(cx_bn_gf2_n_mul(bn_tempa, bn_result, bn_result, bn_n, bn_r2));
// bn_tempb = bn_denominator^9
CX_CHECK(cx_bn_gf2_n_mul(bn_tempb, bn_tempa, bn_denominator, bn_n, bn_r2));
// bn_tempa = bn_denominator^16
CX_CHECK(cx_bn_gf2_n_mul(bn_tempa, bn_tempa, bn_tempa, bn_n, bn_r2));
// bn_tempa = bn_denominator^25
CX_CHECK(cx_bn_gf2_n_mul(bn_tempa, bn_tempa, bn_tempb, bn_n, bn_r2));
// bn_tempa = bn_denominator^50
CX_CHECK(cx_bn_gf2_n_mul(bn_tempa, bn_tempa, bn_tempa, bn_n, bn_r2));
// bn_tempb = bn_denominator^100
CX_CHECK(cx_bn_gf2_n_mul(bn_tempb, bn_tempa, bn_tempa, bn_n, bn_r2));
// bn_tempb = bn_denominator^200
CX_CHECK(cx_bn_gf2_n_mul(bn_tempb, bn_tempb, bn_tempb, bn_n, bn_r2));
// bn_tempa = bn_denominator^250
CX_CHECK(cx_bn_gf2_n_mul(bn_tempa, bn_tempa, bn_tempb, bn_n, bn_r2));
// bn_denominator = bn_denominator^254
CX_CHECK(cx_bn_gf2_n_mul(bn_denominator, bn_result, bn_tempa, bn_n, bn_r2));

// Calculate the lagrange basis coefficient
CX_CHECK(cx_bn_gf2_n_mul(bn_lagrange, bn_numerator, bn_lagrange, bn_n, bn_r2));
Expand All @@ -273,12 +217,12 @@ cx_err_t interpolate(uint8_t n,
}

for (uint8_t j = 0; j < yl; j++) {
CX_CHECK(cx_bn_set_u32(bn_y, (uint32_t) yij[i][j]));
CX_CHECK(cx_bn_set_u32(bn_tempa, (uint32_t) yij[i][j]));
CX_CHECK(cx_bn_set_u32(bn_result, (uint32_t) result[j]));

CX_CHECK(cx_bn_gf2_n_mul(bn_y, bn_lagrange, bn_y, bn_n, bn_r2));
CX_CHECK(cx_bn_copy(bn_temp, bn_result));
CX_CHECK(cx_bn_xor(bn_result, bn_temp, bn_y));
CX_CHECK(cx_bn_gf2_n_mul(bn_tempa, bn_lagrange, bn_tempa, bn_n, bn_r2));
CX_CHECK(cx_bn_copy(bn_tempb, bn_result));
CX_CHECK(cx_bn_xor(bn_result, bn_tempa, bn_tempb));
CX_CHECK(cx_bn_get_u32(bn_result, &result_u32));
result[j] = (uint8_t) result_u32;
result_u32 = 0;
Expand All @@ -288,13 +232,12 @@ cx_err_t interpolate(uint8_t n,
// clean up stack
CX_CHECK(cx_bn_destroy(&bn_x));
CX_CHECK(cx_bn_destroy(&bn_xc_i));
CX_CHECK(cx_bn_destroy(&bn_xc_j));
CX_CHECK(cx_bn_destroy(&bn_numerator));
CX_CHECK(cx_bn_destroy(&bn_denominator));
CX_CHECK(cx_bn_destroy(&bn_lagrange));
CX_CHECK(cx_bn_destroy(&bn_y));
CX_CHECK(cx_bn_destroy(&bn_result));
CX_CHECK(cx_bn_destroy(&bn_temp));
CX_CHECK(cx_bn_destroy(&bn_tempa));
CX_CHECK(cx_bn_destroy(&bn_tempb));
CX_CHECK(cx_bn_destroy(&bn_n));
CX_CHECK(cx_bn_destroy(&bn_r2));

Expand Down
2 changes: 2 additions & 0 deletions src/sskr/sss/interpolate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#ifndef INTERPOLATE_H
#define INTERPOLATE_H

#define memzero(...) explicit_bzero(__VA_ARGS__)

/**
* @brief Performs polynomial interpolation on SSS shares.
*
Expand Down
2 changes: 0 additions & 2 deletions src/sskr/sss/sss.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#include "sss.h"
#include "interpolate.h"

#define memzero(...) explicit_bzero(__VA_ARGS__)

/**
* @brief Validates the parameters for Shamir's Secret Sharing (SSS) functions.
*
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ function(install_apk_packages)
if(${result} EQUAL 0)
message(STATUS "Installed ${package} package")
else()
message(FATAL_ERROR "Failed to install package :${package}\n"
"Command: ${output}\n"
"Error: ${error}")
message(FATAL_ERROR "Failed to install package: ${package}\n"
"Command: ${output}\n"
"Error: ${error}")
endif()
endforeach()
endfunction()
Expand Down

0 comments on commit 315ec8d

Please sign in to comment.