Skip to content

Commit

Permalink
Implement Montgomery multiplication
Browse files Browse the repository at this point in the history
  • Loading branch information
aido committed Jan 24, 2024
1 parent e262a0c commit 1bf8286
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 0 deletions.
133 changes: 133 additions & 0 deletions src/bolos/cx_bn.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,3 +499,136 @@ cx_err_t sys_cx_bn_gf2_n_mul(cx_bn_t bn_r, const cx_bn_t bn_a,
end:
return error;
}

/* ========================================================================= */
/* === MONTGOMERY MODULAR ARITHMETIC === */
/* ========================================================================= */

#define _2POWB \
{ \
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00 \
} /*2^128*/
#define _2POWBm1 \
{ \
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
0xff, 0xff, 0xff, 0xff \
} /* 2^128-1*/

cx_err_t sys_cx_mont_alloc(cx_bn_mont_ctx_t *ctx, size_t length)
{
cx_err_t error;

CX_CHECK(sys_cx_bn_alloc(&ctx->n, length));
CX_CHECK(sys_cx_bn_alloc(&ctx->h, length));

end:
return error;
}

cx_err_t sys_cx_mont_init(cx_bn_mont_ctx_t *ctx, const cx_bn_t n)
{
cx_err_t error;
size_t sizen;
uint8_t tu8_basis[] = _2POWB;
uint8_t tu8_basism1[] = _2POWBm1;
cx_bn_t basis, temp;

CX_CHECK(sys_cx_bn_nbytes(n, &sizen));
CX_CHECK(sys_cx_bn_alloc_init(&basis, sizen, tu8_basis,
(size_t)sizeof(tu8_basis)));
CX_CHECK(sys_cx_bn_alloc(&temp, sizen));

/* copy modulus*/
CX_CHECK(sys_cx_bn_copy((ctx->n), n));
/* -p^-1 mod 2^sizeword*/
CX_CHECK(sys_cx_bn_reduce(temp, n, basis));

CX_CHECK(sys_cx_bn_mod_pow(ctx->h, temp, tu8_basism1, sizeof(tu8_basism1),
basis)); /*1/P mod 2^n*/

/* 2^bitsizeof(n) mod n */
CX_CHECK(sys_cx_bn_xor(basis, basis, basis)); /* zero*/
CX_CHECK(sys_cx_bn_set_bit(
basis,
(sizen << 3) - 1)); /*2^(sizeofp)-1 to fit in memory before reduction*/
CX_CHECK(sys_cx_bn_mod_add(temp, basis, basis, n)); /* 2^(bitsize(p))*/
CX_CHECK(sys_cx_bn_mod_mul(ctx->h, temp, temp, n)); /* 2^(bitsize(p))^2*/

sys_cx_bn_destroy(&temp);
sys_cx_bn_destroy(&basis);

end:
return error;
}

cx_err_t sys_cx_mont_init2(cx_bn_mont_ctx_t *ctx, const cx_bn_t n,
const cx_bn_t h)
{
cx_err_t error = CX_OK; // By default, until some error occurs

CX_CHECK(sys_cx_bn_copy((ctx->n), n));
CX_CHECK(sys_cx_bn_copy((ctx->h), h));

end:
return error;
}

/* a horrible emulation of cx_mont_mul, not present in speculos, compute
* aR*bR=abR mod p*/
/* todo: integrate some decent Montgomery implementation (maybe OpenSSL
* BN_mod_mul_montgomery()) */
x_err_t sys_cx_mont_mul(cx_bn_t r, const cx_bn_t a, const cx_bn_t b,
const cx_bn_mont_ctx_t *ctx)
{
cx_err_t error = CX_OK; // By default, until some error occurs
size_t field;

cx_bn_t temp;

CX_CHECK(sys_cx_bn_nbytes(ctx->n, &field));

CX_CHECK(sys_cx_bn_alloc(&temp, field));

CX_CHECK(sys_cx_bn_mod_invert_nprime(
temp, ctx->h,
ctx->n)); /* R^-1 (yes an inversion to emulate a mul, god forgive me)*/

CX_CHECK(sys_cx_bn_mod_mul(temp, a, temp, ctx->n));
CX_CHECK(sys_cx_bn_mod_mul(r, b, temp, ctx->n));

sys_cx_bn_destroy(&temp);

end:
return error;
}

cx_err_t sys_cx_mont_to_montgomery(cx_bn_t x, const cx_bn_t z,
const cx_bn_mont_ctx_t *ctx)
{
cx_err_t error = CX_OK; // By default, until some error occurs

CX_CHECK(sys_cx_bn_mod_mul(x, ctx->h, z, ctx->n));

end:
return error;
}

cx_err_t sys_cx_mont_from_montgomery(cx_bn_t z, const cx_bn_t x,
const cx_bn_mont_ctx_t *ctx)
{
cx_err_t error = CX_OK; // By default, until some error occurs
cx_bn_t temp;
size_t field;

CX_CHECK(sys_cx_bn_nbytes(ctx->h, &field));
CX_CHECK(sys_cx_bn_alloc(&temp, field));

CX_CHECK(sys_cx_bn_set_u32(temp, 1));
CX_CHECK(sys_cx_mont_mul(z, temp, x, ctx));

CX_CHECK(sys_cx_bn_destroy(&temp));

end:
return error;
}
16 changes: 16 additions & 0 deletions src/bolos/cxlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ typedef struct cx_mpi_ecpoint_s {

} cx_mpi_ecpoint_t;

// Montgomery context.
typedef struct {
cx_bn_t n; // Modulus
cx_bn_t h; // Second Montgomery constant
} cx_bn_mont_ctx_t;

//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -201,6 +207,16 @@ cx_err_t sys_cx_bn_next_prime(const cx_bn_t bn_x);
cx_err_t sys_cx_bn_gf2_n_mul(cx_bn_t bn_r, const cx_bn_t bn_a,
const cx_bn_t bn_b, const cx_bn_t bn_n,
const cx_bn_t bn_h);
cx_err_t sys_cx_mont_alloc(cx_bn_mont_ctx_t *ctx, size_t length);
cx_err_t sys_cx_mont_init(cx_bn_mont_ctx_t *ctx, const cx_bn_t n);
cx_err_t sys_cx_mont_init2(cx_bn_mont_ctx_t *ctx, const cx_bn_t n,
const cx_bn_t h);
cx_err_t sys_cx_mont_to_montgomery(cx_bn_t x, const cx_bn_t z,
const cx_bn_mont_ctx_t *ctx);
cx_err_t sys_cx_mont_from_montgomery(cx_bn_t z, const cx_bn_t x,
const cx_bn_mont_ctx_t *ctx);
cx_err_t sys_cx_mont_mul(cx_bn_t r, const cx_bn_t a, const cx_bn_t b,
const cx_bn_mont_ctx_t *ctx);

// cx_ecdomain.c
int cx_nid_from_curve(cx_curve_t curve);
Expand Down
16 changes: 16 additions & 0 deletions src/emulate_lnsp_1.0.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,22 @@ int emulate_nanosp_1_0(unsigned long syscall, unsigned long *parameters,
SYSCALL5(cx_bn_gf2_n_mul, "(%u, %u, %u, %u, %u)", uint32_t, r, uint32_t, a,
uint32_t, b, uint32_t, n, uint32_t, h);

SYSCALL2(cx_mont_alloc, "(%p, %u)", void *, ctx, size_t, length);

SYSCALL2(cx_mont_init, "(%p, %u)", void *, ctx, uint32_t, n);

SYSCALL3(cx_mont_init2, "(%p, %u, %u)", void *, ctx, uint32_t, n, uint32_t,
h);

SYSCALL4(cx_mont_mul, "(%u, %u, %u, %p)", uint32_t, r, uint32_t, a,
uint32_t, b, void *, ctx);

SYSCALL3(cx_mont_to_montgomery, "(%u, %u, %p)", uint32_t, x, uint32_t, z,
void *, ctx);

SYSCALL3(cx_mont_from_montgomery, "(%u, %u, %p)", uint32_t, z, uint32_t, x,
void *, ctx);

// SYSCALLs that may exists on other SDK versions, but with a different ID:

SYSCALL0i(os_perso_isonboarded, os_perso_isonboarded_2_0);
Expand Down
30 changes: 30 additions & 0 deletions src/emulate_unified_sdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,36 @@ int emulate_syscall_cx(unsigned long syscall, unsigned long *parameters,
uint32_t, n,
uint32_t, h);

SYSCALL2(cx_mont_alloc, "(%p, %u)",
void *, ctx,
size_t, length);


SYSCALL2(cx_mont_init, "(%p, %u)",
void *, ctx,
uint32_t, n);

SYSCALL3(cx_mont_init2, "(%p, %u, %u)",
void *, ctx,
uint32_t, n,
uint32_t, h);

SYSCALL4(cx_mont_mul, "(%u, %u, %u, %p)",
uint32_t, r,
uint32_t, a,
uint32_t, b,
void *, ctx);

SYSCALL3(cx_mont_to_montgomery, "(%u, %u, %p)",
uint32_t, x,
uint32_t, z,
void *, ctx);

SYSCALL3(cx_mont_from_montgomery, "(%u, %u, %p)",
uint32_t, z,
uint32_t, x,
void *, ctx);

SYSCALL10(cx_bls12381_key_gen, "(%u, %p, %u, %p, %u, %p, %u, %p, %p, %u)",
uint8_t, mode,
uint8_t *, secret,
Expand Down

0 comments on commit 1bf8286

Please sign in to comment.