Skip to content

Commit a7d0e91

Browse files
committed
Implement cx_bn_gf2_n_mul()
1 parent 65e3aad commit a7d0e91

File tree

8 files changed

+124
-2
lines changed

8 files changed

+124
-2
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ else()
8585
openssl
8686
URL https://www.openssl.org/source/openssl-1.1.1k.tar.gz
8787
URL_HASH SHA256=892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5
88-
CONFIGURE_COMMAND ./Configure "CC=${CMAKE_C_COMPILER}" "CFLAGS=${OPENSSL_CFLAGS}" no-afalgeng no-aria no-asan no-asm no-async no-autoalginit no-autoerrinit no-autoload-config no-bf no-buildtest-c++ no-camellia no-capieng no-cast no-chacha no-cmac no-cms no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-ct no-deprecated no-des no-devcryptoeng no-dgram no-dh no-dsa no-dso no-dtls no-ec2m no-ecdh no-egd no-engine no-err no-external-tests no-filenames no-fuzz-afl no-fuzz-libfuzzer no-gost no-heartbeats no-hw no-idea no-makedepend no-md2 no-md4 no-mdc2 no-msan no-multiblock no-nextprotoneg no-ocb no-ocsp no-pinshared no-poly1305 no-posix-io no-psk no-rc2 no-rc4 no-rc5 no-rdrand no-rfc3779 no-scrypt no-sctp no-seed no-shared no-siphash no-sm2 no-sm3 no-sm4 no-sock no-srp no-srtp no-sse2 no-ssl no-ssl3-method no-ssl-trace no-stdio no-tests no-threads no-tls no-ts no-ubsan no-ui-console no-unit-test no-whirlpool no-zlib no-zlib-dynamic linux-armv4 --prefix=${INSTALL_DIR}
88+
CONFIGURE_COMMAND ./Configure "CC=${CMAKE_C_COMPILER}" "CFLAGS=${OPENSSL_CFLAGS}" no-afalgeng no-aria no-asan no-asm no-async no-autoalginit no-autoerrinit no-autoload-config no-bf no-buildtest-c++ no-camellia no-capieng no-cast no-chacha no-cmac no-cms no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-ct no-deprecated no-des no-devcryptoeng no-dgram no-dh no-dsa no-dso no-dtls no-ecdh no-egd no-engine no-err no-external-tests no-filenames no-fuzz-afl no-fuzz-libfuzzer no-gost no-heartbeats no-hw no-idea no-makedepend no-md2 no-md4 no-mdc2 no-msan no-multiblock no-nextprotoneg no-ocb no-ocsp no-pinshared no-poly1305 no-posix-io no-psk no-rc2 no-rc4 no-rc5 no-rdrand no-rfc3779 no-scrypt no-sctp no-seed no-shared no-siphash no-sm2 no-sm3 no-sm4 no-sock no-srp no-srtp no-sse2 no-ssl no-ssl3-method no-ssl-trace no-stdio no-tests no-threads no-tls no-ts no-ubsan no-ui-console no-unit-test no-whirlpool no-zlib no-zlib-dynamic linux-armv4 --prefix=${INSTALL_DIR}
8989
BUILD_COMMAND make
9090
INSTALL_COMMAND make install_sw
9191
BUILD_IN_SOURCE 1

src/bolos/cx_bn.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,3 +481,21 @@ cx_err_t sys_cx_bn_next_prime(const cx_bn_t bn_x)
481481
end:
482482
return error;
483483
}
484+
485+
cx_err_t sys_cx_bn_gf2_n_mul(cx_bn_t bn_r, const cx_bn_t bn_a,
486+
const cx_bn_t bn_b, const cx_bn_t bn_n,
487+
const cx_bn_t bn_h)
488+
{
489+
cx_err_t error = CX_OK; // By default, until some error occurs
490+
cx_mpi_t *r, *a, *b, *n, *h;
491+
492+
// Convert bn to mpi
493+
CX_CHECK(cx_bn_rab_to_mpi(bn_r, &r, bn_a, &a, bn_b, &b));
494+
CX_CHECK(cx_bn_ab_to_mpi(bn_n, &n, bn_h, &h));
495+
496+
// Perform a Galois field multiplication operation reduced by n
497+
CX_CHECK(cx_mpi_gf2_n_mul(r, a, b, n, h));
498+
499+
end:
500+
return error;
501+
}

src/bolos/cx_mpi.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,19 @@ cx_err_t cx_mpi_next_prime(cx_mpi_t *x)
11671167
return error;
11681168
}
11691169

1170+
cx_err_t cx_mpi_gf2_n_mul(cx_mpi_t *r, const cx_mpi_t *a, const cx_mpi_t *b,
1171+
const cx_mpi_t *n,
1172+
const cx_mpi_t *h __attribute__((unused)))
1173+
{
1174+
cx_err_t error = CX_OK; // By default, until some error occurs
1175+
1176+
if (!BN_GF2m_mod_mul(r, a, b, n, local_bn_ctx)) {
1177+
error = CX_INTERNAL_ERROR;
1178+
}
1179+
1180+
return error;
1181+
}
1182+
11701183
#define MAX_BYTE_LEN 128
11711184
void cx_mpi_reverse(cx_mpi_t *x, uint32_t nbytes)
11721185
{

src/bolos/cxlib.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ cx_err_t cx_mpi_mod_pow(cx_mpi_t *r, const cx_mpi_t *a, const cx_mpi_t *e,
134134
const cx_mpi_t *n);
135135
cx_err_t cx_mpi_is_prime(cx_mpi_t *x, bool *prime);
136136
cx_err_t cx_mpi_next_prime(cx_mpi_t *x);
137+
cx_err_t cx_mpi_gf2_n_mul(cx_mpi_t *r, const cx_mpi_t *a, const cx_mpi_t *b,
138+
const cx_mpi_t *n, const cx_mpi_t *h);
137139
void cx_mpi_reverse(cx_mpi_t *x, uint32_t nbytes);
138140
void cx_mpi_swap(cx_mpi_t *a, cx_mpi_t *b, const int c);
139141

@@ -196,6 +198,9 @@ cx_err_t sys_cx_bn_mod_pow2(cx_bn_t bn_r, const cx_bn_t bn_a, const uint8_t *e,
196198
uint32_t len_e, const cx_bn_t bn_n);
197199
cx_err_t sys_cx_bn_is_prime(const cx_bn_t bn_x, bool *prime);
198200
cx_err_t sys_cx_bn_next_prime(const cx_bn_t bn_x);
201+
cx_err_t sys_cx_bn_gf2_n_mul(cx_bn_t bn_r, const cx_bn_t bn_a,
202+
const cx_bn_t bn_b, const cx_bn_t bn_n,
203+
const cx_bn_t bn_h);
199204

200205
// cx_ecdomain.c
201206
int cx_nid_from_curve(cx_curve_t curve);

src/emulate_lnsp_1.0.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,9 @@ int emulate_nanosp_1_0(unsigned long syscall, unsigned long *parameters,
266266

267267
SYSCALL1(cx_bn_next_prime, "(%u)", uint32_t, a);
268268

269+
SYSCALL5(cx_bn_gf2_n_mul, "(%u, %u, %u, %u, %u)", uint32_t, r, uint32_t, a,
270+
uint32_t, b, uint32_t, n, uint32_t, h);
271+
269272
// SYSCALLs that may exists on other SDK versions, but with a different ID:
270273

271274
SYSCALL0i(os_perso_isonboarded, os_perso_isonboarded_2_0);

src/emulate_unified_sdk.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,13 @@ int emulate_syscall_cx(unsigned long syscall, unsigned long *parameters,
524524
SYSCALL1(cx_bn_next_prime, "(%u)",
525525
uint32_t, a);
526526

527+
SYSCALL5(cx_bn_gf2_n_mul, "(%u, %u, %u, %u, %u)",
528+
uint32_t, r,
529+
uint32_t, a,
530+
uint32_t, b,
531+
uint32_t, n,
532+
uint32_t, h);
533+
527534
SYSCALL10(cx_bls12381_key_gen, "(%u, %p, %u, %p, %u, %p, %u, %p, %p, %u)",
528535
uint8_t, mode,
529536
uint8_t *, secret,

tests/syscalls/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_executable(test_aes test_aes.c nist_cavp.c utils.c)
88
add_executable(test_bip32 test_bip32.c utils.c)
99
add_executable(test_blake2 test_blake2.c nist_cavp.c utils.c)
1010
add_executable(test_bls test_bls.c utils.c)
11+
add_executable(test_bn test_bn.c)
1112
add_executable(test_crc16 test_crc16.c)
1213
add_executable(test_ecdh test_ecdh.c utils.c)
1314
add_executable(test_ecdsa test_ecdsa.c utils.c)
@@ -26,6 +27,6 @@ add_executable(test_sha2 test_sha2.c nist_cavp.c utils.c)
2627
add_executable(test_sha3 test_sha3.c nist_cavp.c utils.c)
2728
add_executable(test_slip21 test_slip21.c)
2829

29-
foreach(target hello test_aes test_bip32 test_blake2 test_bls test_crc16 test_ec test_ecpoint test_ecdh test_ecdsa test_eddsa test_endorsement test_hmac test_math test_os_global_pin_is_validated test_rfc6979 test_ripemd test_sha2 test_sha3 test_slip21 test_eip2333)
30+
foreach(target hello test_aes test_bip32 test_blake2 test_bls test_bn test_crc16 test_ec test_ecpoint test_ecdh test_ecdsa test_eddsa test_endorsement test_hmac test_math test_os_global_pin_is_validated test_rfc6979 test_ripemd test_sha2 test_sha3 test_slip21 test_eip2333)
3031
add_test(NAME ${target} COMMAND qemu-arm-static ${target} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
3132
endforeach()

tests/syscalls/test_bn.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include <setjmp.h>
2+
#include <stdarg.h>
3+
#include <stddef.h>
4+
// must come after setjmp.h
5+
#include <cmocka.h>
6+
7+
#include "bolos/cxlib.h"
8+
9+
#define GF2_8_MPI_BYTES 1
10+
11+
static void test_cx_bn_gf2_n_mul(void **state __attribute__((unused)))
12+
{
13+
cx_err_t error = CX_OK;
14+
15+
cx_bn_t a, // multiplicand
16+
b, // multiplier
17+
m, // modulus
18+
r, // result
19+
r2; // Montgomery constant
20+
21+
// A(x)
22+
const uint8_t multiplicand[1] = { 0x1B }; // 27
23+
// B(x)
24+
const uint8_t multiplier[1] = { 0x3D }; // 61
25+
26+
// The irreducible polynomial N(x) = x^8 + x^4 + x^3 + x + 1
27+
const uint8_t N[2] = { 0x01, 0x1B }; // 283
28+
29+
// 2nd Montgomery constant: R2 = x^(2*t*8) mod N(x)
30+
// t = 1 since the number of bytes of R is 1.
31+
const uint8_t R2[1] = { 0x56 };
32+
33+
// Expected result of N(x) = A(x )* B(x)
34+
const uint32_t re = 0x49; // result expected = 71
35+
int diff;
36+
37+
CX_CHECK(sys_cx_bn_lock(GF2_8_MPI_BYTES, 0));
38+
CX_CHECK(sys_cx_bn_alloc(&r, GF2_8_MPI_BYTES));
39+
CX_CHECK(sys_cx_bn_alloc_init(&a, GF2_8_MPI_BYTES, multiplicand,
40+
sizeof(multiplicand)));
41+
CX_CHECK(sys_cx_bn_alloc_init(&b, GF2_8_MPI_BYTES, multiplier,
42+
sizeof(multiplier)));
43+
CX_CHECK(sys_cx_bn_alloc_init(&m, GF2_8_MPI_BYTES, N, sizeof(N)));
44+
CX_CHECK(sys_cx_bn_alloc_init(&r2, GF2_8_MPI_BYTES, R2, sizeof(R2)));
45+
46+
// Perform the Galois Field GF(2m) multiplication operation
47+
CX_CHECK(sys_cx_bn_gf2_n_mul(r, a, b, m, r2));
48+
49+
// Compare result to expected result
50+
CX_CHECK(sys_cx_bn_cmp_u32(r, re, &diff));
51+
52+
CX_CHECK(sys_cx_bn_destroy(&r));
53+
CX_CHECK(sys_cx_bn_destroy(&a));
54+
CX_CHECK(sys_cx_bn_destroy(&b));
55+
CX_CHECK(sys_cx_bn_destroy(&m));
56+
CX_CHECK(sys_cx_bn_destroy(&r2));
57+
58+
end:
59+
if (sys_cx_bn_is_locked()) {
60+
sys_cx_bn_unlock();
61+
}
62+
63+
// Assert that there are no errors
64+
assert_int_equal(error, CX_OK);
65+
66+
// Assert that the result is correct
67+
assert_int_equal(diff, 0);
68+
}
69+
70+
int main(void)
71+
{
72+
const struct CMUnitTest tests[] = { cmocka_unit_test(test_cx_bn_gf2_n_mul) };
73+
74+
return cmocka_run_group_tests(tests, NULL, NULL);
75+
}

0 commit comments

Comments
 (0)