mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-17 05:03:07 +00:00
crypto/bignum: change limb size to 29, add tests
This commit is contained in:
parent
a5eecf7a3c
commit
24ceb0ab6b
@ -519,13 +519,21 @@ STATIC mp_obj_t mod_trezorcrypto_monero_inv256_modm(size_t n_args,
|
||||
assert_scalar(args[1 + off]);
|
||||
|
||||
// bn_prime = curve order, little endian encoded
|
||||
bignum256 bn_prime = {.val = {0x1cf5d3ed, 0x20498c69, 0x2f79cd65, 0x37be77a8,
|
||||
0x14, 0x0, 0x0, 0x0, 0x1000}};
|
||||
bignum256 bn_prime = {.val = {0x1cf5d3ed, 0x9318d2, 0x1de73596, 0x1df3bd45,
|
||||
0x14d, 0x0, 0x0, 0x0, 0x100000}};
|
||||
bignum256 bn_x;
|
||||
bignum256modm bm_x;
|
||||
uint8_t raw_x[32];
|
||||
|
||||
memcpy(bm_x, MP_OBJ_C_SCALAR(args[1 + off]), sizeof(bignum256modm));
|
||||
contract256_modm(raw_x, bm_x);
|
||||
bn_read_le(raw_x, &bn_x);
|
||||
|
||||
memcpy(&bn_x.val, MP_OBJ_C_SCALAR(args[1 + off]), sizeof(bignum256modm));
|
||||
bn_inverse(&bn_x, &bn_prime);
|
||||
memcpy(MP_OBJ_SCALAR(res), bn_x.val, sizeof(bignum256modm));
|
||||
|
||||
bn_write_le(&bn_x, raw_x);
|
||||
expand_raw256_modm(bm_x, raw_x);
|
||||
memcpy(MP_OBJ_SCALAR(res), bm_x, sizeof(bignum256modm));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
2414
crypto/bignum.c
2414
crypto/bignum.c
File diff suppressed because it is too large
Load Diff
206
crypto/bignum.h
206
crypto/bignum.h
@ -28,141 +28,145 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "options.h"
|
||||
|
||||
// bignum256 are 256 bits stored as 8*30 bit + 1*16 bit
|
||||
// val[0] are lowest 30 bits, val[8] highest 16 bits
|
||||
#define BN_LIMBS 9
|
||||
#define BN_BITS_PER_LIMB 29
|
||||
#define BN_BASE (1u << BN_BITS_PER_LIMB)
|
||||
#define BN_LIMB_MASK ((1u << BN_BITS_PER_LIMB) - 1)
|
||||
#define BN_EXTRA_BITS (32 - BN_BITS_PER_LIMB)
|
||||
#define BN_BITS_LAST_LIMB (256 - (BN_LIMBS - 1) * BN_BITS_PER_LIMB)
|
||||
|
||||
// Represents the number sum([val[i] * 2**(29*i) for i in range(9))
|
||||
typedef struct {
|
||||
uint32_t val[9];
|
||||
uint32_t val[BN_LIMBS];
|
||||
} bignum256;
|
||||
|
||||
// read 4 big endian bytes into uint32
|
||||
uint32_t read_be(const uint8_t *data);
|
||||
static inline uint32_t read_be(const uint8_t *data) {
|
||||
return (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) |
|
||||
(((uint32_t)data[2]) << 8) | (((uint32_t)data[3]));
|
||||
}
|
||||
|
||||
// write 4 big endian bytes
|
||||
void write_be(uint8_t *data, uint32_t x);
|
||||
static inline void write_be(uint8_t *data, uint32_t x) {
|
||||
data[0] = x >> 24;
|
||||
data[1] = x >> 16;
|
||||
data[2] = x >> 8;
|
||||
data[3] = x;
|
||||
}
|
||||
|
||||
// read 4 little endian bytes into uint32
|
||||
uint32_t read_le(const uint8_t *data);
|
||||
static inline uint32_t read_le(const uint8_t *data) {
|
||||
return (((uint32_t)data[3]) << 24) | (((uint32_t)data[2]) << 16) |
|
||||
(((uint32_t)data[1]) << 8) | (((uint32_t)data[0]));
|
||||
}
|
||||
|
||||
// write 4 little endian bytes
|
||||
void write_le(uint8_t *data, uint32_t x);
|
||||
static inline void write_le(uint8_t *data, uint32_t x) {
|
||||
data[3] = x >> 24;
|
||||
data[2] = x >> 16;
|
||||
data[1] = x >> 8;
|
||||
data[0] = x;
|
||||
}
|
||||
|
||||
void bn_read_be(const uint8_t *in_number, bignum256 *out_number);
|
||||
|
||||
void bn_write_be(const bignum256 *in_number, uint8_t *out_number);
|
||||
|
||||
void bn_read_le(const uint8_t *in_number, bignum256 *out_number);
|
||||
|
||||
void bn_write_le(const bignum256 *in_number, uint8_t *out_number);
|
||||
|
||||
void bn_read_uint32(uint32_t in_number, bignum256 *out_number);
|
||||
|
||||
void bn_read_uint64(uint64_t in_number, bignum256 *out_number);
|
||||
|
||||
static inline uint32_t bn_write_uint32(const bignum256 *in_number) {
|
||||
return in_number->val[0] | (in_number->val[1] << 30);
|
||||
}
|
||||
|
||||
static inline uint64_t bn_write_uint64(const bignum256 *in_number) {
|
||||
uint64_t tmp;
|
||||
tmp = in_number->val[2];
|
||||
tmp <<= 30;
|
||||
tmp |= in_number->val[1];
|
||||
tmp <<= 30;
|
||||
tmp |= in_number->val[0];
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// copies number a to b
|
||||
static inline void bn_copy(const bignum256 *a, bignum256 *b) { *b = *a; }
|
||||
|
||||
int bn_bitcount(const bignum256 *a);
|
||||
|
||||
unsigned int bn_digitcount(const bignum256 *a);
|
||||
|
||||
void bn_zero(bignum256 *a);
|
||||
|
||||
int bn_is_zero(const bignum256 *a);
|
||||
|
||||
void bn_one(bignum256 *a);
|
||||
|
||||
static inline int bn_is_even(const bignum256 *a) {
|
||||
return (a->val[0] & 1) == 0;
|
||||
}
|
||||
|
||||
static inline int bn_is_odd(const bignum256 *a) { return (a->val[0] & 1) == 1; }
|
||||
|
||||
int bn_is_less(const bignum256 *a, const bignum256 *b);
|
||||
|
||||
int bn_is_equal(const bignum256 *a, const bignum256 *b);
|
||||
|
||||
void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase,
|
||||
int bn_bitcount(const bignum256 *x);
|
||||
unsigned int bn_digitcount(const bignum256 *x);
|
||||
void bn_zero(bignum256 *x);
|
||||
void bn_one(bignum256 *x);
|
||||
int bn_is_zero(const bignum256 *x);
|
||||
int bn_is_one(const bignum256 *x);
|
||||
int bn_is_less(const bignum256 *x, const bignum256 *y);
|
||||
int bn_is_equal(const bignum256 *x, const bignum256 *y);
|
||||
void bn_cmov(bignum256 *res, volatile uint32_t cond, const bignum256 *truecase,
|
||||
const bignum256 *falsecase);
|
||||
|
||||
void bn_lshift(bignum256 *a);
|
||||
|
||||
void bn_rshift(bignum256 *a);
|
||||
|
||||
void bn_setbit(bignum256 *a, uint8_t bit);
|
||||
|
||||
void bn_clearbit(bignum256 *a, uint8_t bit);
|
||||
|
||||
uint32_t bn_testbit(bignum256 *a, uint8_t bit);
|
||||
|
||||
void bn_xor(bignum256 *a, const bignum256 *b, const bignum256 *c);
|
||||
|
||||
void bn_cnegate(volatile uint32_t cond, bignum256 *x, const bignum256 *prime);
|
||||
void bn_lshift(bignum256 *x);
|
||||
void bn_rshift(bignum256 *x);
|
||||
void bn_setbit(bignum256 *x, uint16_t i);
|
||||
void bn_clearbit(bignum256 *x, uint16_t i);
|
||||
uint32_t bn_testbit(const bignum256 *x, uint16_t i);
|
||||
void bn_xor(bignum256 *res, const bignum256 *x, const bignum256 *y);
|
||||
void bn_mult_half(bignum256 *x, const bignum256 *prime);
|
||||
|
||||
void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime);
|
||||
|
||||
void bn_mod(bignum256 *x, const bignum256 *prime);
|
||||
|
||||
void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime);
|
||||
|
||||
void bn_fast_mod_old(bignum256 *x, const bignum256 *prime);
|
||||
void bn_fast_mod(bignum256 *x, const bignum256 *prime);
|
||||
|
||||
void bn_power_mod(const bignum256 *x, const bignum256 *e,
|
||||
const bignum256 *prime, bignum256 *res);
|
||||
void bn_sqrt(bignum256 *x, const bignum256 *prime);
|
||||
|
||||
void bn_inverse(bignum256 *x, const bignum256 *prime);
|
||||
|
||||
void bn_normalize(bignum256 *a);
|
||||
|
||||
void bn_add(bignum256 *a, const bignum256 *b);
|
||||
|
||||
void bn_addmod(bignum256 *a, const bignum256 *b, const bignum256 *prime);
|
||||
|
||||
void bn_addi(bignum256 *a, uint32_t b);
|
||||
|
||||
void bn_subi(bignum256 *a, uint32_t b, const bignum256 *prime);
|
||||
|
||||
void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res,
|
||||
uint32_t inverse_mod_power_two(uint32_t a, uint32_t n);
|
||||
void bn_divide_base(bignum256 *x, const bignum256 *prime);
|
||||
void bn_inverse_slow(bignum256 *x, const bignum256 *prime);
|
||||
void bn_inverse_fast_1(bignum256 *x, const bignum256 *prime);
|
||||
void bn_inverse_fast_2(bignum256 *x, const bignum256 *prime);
|
||||
void bn_inverse_fast_3(bignum256 *x, const bignum256 *prime);
|
||||
void bn_inverse_old(bignum256 *x, const bignum256 *prime);
|
||||
void bn_normalize(bignum256 *x);
|
||||
void bn_add(bignum256 *x, const bignum256 *y);
|
||||
void bn_addmod(bignum256 *x, const bignum256 *y, const bignum256 *prime);
|
||||
void bn_addi(bignum256 *x, uint32_t y);
|
||||
void bn_subi(bignum256 *x, uint32_t y, const bignum256 *prime);
|
||||
void bn_subtractmod(const bignum256 *x, const bignum256 *y, bignum256 *res,
|
||||
const bignum256 *prime);
|
||||
void bn_subtract(const bignum256 *x, const bignum256 *y, bignum256 *res);
|
||||
void bn_long_division(bignum256 *x, uint32_t d, bignum256 *q, uint32_t *r);
|
||||
void bn_divmod58(bignum256 *x, uint32_t *r);
|
||||
void bn_divmod1000(bignum256 *x, uint32_t *r);
|
||||
void bn_inverse(bignum256 *x, const bignum256 *prime);
|
||||
size_t bn_format(const bignum256 *amount, const char *prefix,
|
||||
const char *suffix, unsigned int decimals, int exponent,
|
||||
bool trailing, char *output, size_t output_length);
|
||||
|
||||
void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res);
|
||||
// Returns (uint32_t) in_number
|
||||
// Assumes in_number < 2**32
|
||||
// Assumes in_number is normalized
|
||||
static inline uint32_t bn_write_uint32(const bignum256 *in_number) {
|
||||
return in_number->val[0] | (in_number->val[1] << BN_BITS_PER_LIMB);
|
||||
}
|
||||
|
||||
void bn_divmod58(bignum256 *a, uint32_t *r);
|
||||
// Returns (uint64_t) in_number
|
||||
// Assumes in_number < 2**64
|
||||
// Assumes in_number is normalized
|
||||
static inline uint64_t bn_write_uint64(const bignum256 *in_number) {
|
||||
uint64_t acc;
|
||||
acc = in_number->val[2];
|
||||
acc <<= BN_BITS_PER_LIMB;
|
||||
acc |= in_number->val[1];
|
||||
acc <<= BN_BITS_PER_LIMB;
|
||||
acc |= in_number->val[0];
|
||||
return acc;
|
||||
}
|
||||
|
||||
void bn_divmod1000(bignum256 *a, uint32_t *r);
|
||||
// y = x
|
||||
static inline void bn_copy(const bignum256 *x, bignum256 *y) { *y = *x; }
|
||||
|
||||
size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix,
|
||||
unsigned int decimals, int exponent, bool trailing, char *out,
|
||||
size_t outlen);
|
||||
// Returns x % 2 == 0
|
||||
static inline int bn_is_even(const bignum256 *x) {
|
||||
return (x->val[0] & 1) == 0;
|
||||
}
|
||||
|
||||
// Returns x % 2 == 0
|
||||
static inline int bn_is_odd(const bignum256 *x) { return (x->val[0] & 1) == 1; }
|
||||
|
||||
static inline size_t bn_format_uint64(uint64_t amount, const char *prefix,
|
||||
const char *suffix, unsigned int decimals,
|
||||
int exponent, bool trailing, char *out,
|
||||
size_t outlen) {
|
||||
bignum256 amnt;
|
||||
bn_read_uint64(amount, &amnt);
|
||||
int exponent, bool trailing, char *output,
|
||||
size_t output_length) {
|
||||
bignum256 bn_amount;
|
||||
bn_read_uint64(amount, &bn_amount);
|
||||
|
||||
return bn_format(&amnt, prefix, suffix, decimals, exponent, trailing, out,
|
||||
outlen);
|
||||
return bn_format(&bn_amount, prefix, suffix, decimals, exponent, trailing,
|
||||
output, output_length);
|
||||
}
|
||||
|
||||
#if USE_BN_PRINT
|
||||
void bn_print(const bignum256 *a);
|
||||
void bn_print_raw(const bignum256 *a);
|
||||
void bn_print(const bignum256 *x);
|
||||
void bn_print_raw(const bignum256 *x);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -61,6 +61,7 @@ void point_add(const ecdsa_curve *curve, const curve_point *cp1,
|
||||
return;
|
||||
}
|
||||
|
||||
// lambda = (y2 - y1) / (x2 - x1)
|
||||
bn_subtractmod(&(cp2->x), &(cp1->x), &inv, &curve->prime);
|
||||
bn_inverse(&inv, &curve->prime);
|
||||
bn_subtractmod(&(cp2->y), &(cp1->y), &lambda, &curve->prime);
|
||||
@ -101,6 +102,8 @@ void point_double(const ecdsa_curve *curve, curve_point *cp) {
|
||||
// lambda = (3 x^2 + a) / (2 y)
|
||||
lambda = cp->y;
|
||||
bn_mult_k(&lambda, 2, &curve->prime);
|
||||
bn_fast_mod(&lambda, &curve->prime);
|
||||
bn_mod(&lambda, &curve->prime);
|
||||
bn_inverse(&lambda, &curve->prime);
|
||||
|
||||
xr = cp->x;
|
||||
@ -162,22 +165,6 @@ int point_is_negative_of(const curve_point *p, const curve_point *q) {
|
||||
return !bn_is_equal(&(p->y), &(q->y));
|
||||
}
|
||||
|
||||
// Negate a (modulo prime) if cond is 0xffffffff, keep it if cond is 0.
|
||||
// The timing of this function does not depend on cond.
|
||||
void conditional_negate(uint32_t cond, bignum256 *a, const bignum256 *prime) {
|
||||
int j = 0;
|
||||
uint32_t tmp = 1;
|
||||
assert(a->val[8] < 0x20000);
|
||||
for (j = 0; j < 8; j++) {
|
||||
tmp += 0x3fffffff + 2 * prime->val[j] - a->val[j];
|
||||
a->val[j] = ((tmp & 0x3fffffff) & cond) | (a->val[j] & ~cond);
|
||||
tmp >>= 30;
|
||||
}
|
||||
tmp += 0x3fffffff + 2 * prime->val[j] - a->val[j];
|
||||
a->val[j] = ((tmp & 0x3fffffff) & cond) | (a->val[j] & ~cond);
|
||||
assert(a->val[8] < 0x20000);
|
||||
}
|
||||
|
||||
typedef struct jacobian_curve_point {
|
||||
bignum256 x, y, z;
|
||||
} jacobian_curve_point;
|
||||
@ -187,9 +174,9 @@ static void generate_k_random(bignum256 *k, const bignum256 *prime) {
|
||||
do {
|
||||
int i = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
k->val[i] = random32() & 0x3FFFFFFF;
|
||||
k->val[i] = random32() & ((1u << BN_BITS_PER_LIMB) - 1);
|
||||
}
|
||||
k->val[8] = random32() & 0xFFFF;
|
||||
k->val[8] = random32() & ((1u << BN_BITS_LAST_LIMB) - 1);
|
||||
// check that k is in range and not zero.
|
||||
} while (bn_is_zero(k) || !bn_is_less(k, prime));
|
||||
}
|
||||
@ -443,12 +430,12 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k,
|
||||
uint32_t is_non_zero = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
is_non_zero |= k->val[j];
|
||||
tmp += 0x3fffffff + k->val[j] - (curve->order.val[j] & is_even);
|
||||
a.val[j] = tmp & 0x3fffffff;
|
||||
tmp >>= 30;
|
||||
tmp += (BN_BASE - 1) + k->val[j] - (curve->order.val[j] & is_even);
|
||||
a.val[j] = tmp & (BN_BASE - 1);
|
||||
tmp >>= BN_BITS_PER_LIMB;
|
||||
}
|
||||
is_non_zero |= k->val[j];
|
||||
a.val[j] = tmp + 0xffff + k->val[j] - (curve->order.val[j] & is_even);
|
||||
a.val[j] = tmp + 0xffffff + k->val[j] - (curve->order.val[j] & is_even);
|
||||
assert((a.val[0] & 1) != 0);
|
||||
|
||||
// special case 0*p: just return zero. We don't care about constant time.
|
||||
@ -490,7 +477,7 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k,
|
||||
// since a is odd.
|
||||
aptr = &a.val[8];
|
||||
abits = *aptr;
|
||||
ashift = 12;
|
||||
ashift = 256 - (BN_BITS_PER_LIMB * 8) - 4;
|
||||
bits = abits >> ashift;
|
||||
sign = (bits >> 4) - 1;
|
||||
bits ^= sign;
|
||||
@ -513,7 +500,7 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k,
|
||||
// leaks no private information to a side-channel.
|
||||
bits = abits << (-ashift);
|
||||
abits = *(--aptr);
|
||||
ashift += 30;
|
||||
ashift += BN_BITS_PER_LIMB;
|
||||
bits |= abits >> ashift;
|
||||
} else {
|
||||
bits = abits >> ashift;
|
||||
@ -525,13 +512,13 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k,
|
||||
|
||||
// negate last result to make signs of this round and the
|
||||
// last round equal.
|
||||
conditional_negate(sign ^ nsign, &jres.z, prime);
|
||||
bn_cnegate((sign ^ nsign) & 1, &jres.z, prime);
|
||||
|
||||
// add odd factor
|
||||
point_jacobian_add(&pmult[bits >> 1], &jres, curve);
|
||||
sign = nsign;
|
||||
}
|
||||
conditional_negate(sign, &jres.z, prime);
|
||||
bn_cnegate(sign & 1, &jres.z, prime);
|
||||
jacobian_to_curve(&jres, res, prime);
|
||||
memzero(&a, sizeof(a));
|
||||
memzero(&jres, sizeof(jres));
|
||||
@ -560,12 +547,12 @@ void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k,
|
||||
uint32_t is_non_zero = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
is_non_zero |= k->val[j];
|
||||
tmp += 0x3fffffff + k->val[j] - (curve->order.val[j] & is_even);
|
||||
a.val[j] = tmp & 0x3fffffff;
|
||||
tmp >>= 30;
|
||||
tmp += (BN_BASE - 1) + k->val[j] - (curve->order.val[j] & is_even);
|
||||
a.val[j] = tmp & (BN_BASE - 1);
|
||||
tmp >>= BN_BITS_PER_LIMB;
|
||||
}
|
||||
is_non_zero |= k->val[j];
|
||||
a.val[j] = tmp + 0xffff + k->val[j] - (curve->order.val[j] & is_even);
|
||||
a.val[j] = tmp + 0xffffff + k->val[j] - (curve->order.val[j] & is_even);
|
||||
assert((a.val[0] & 1) != 0);
|
||||
|
||||
// special case 0*G: just return zero. We don't care about constant time.
|
||||
@ -603,7 +590,8 @@ void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k,
|
||||
|
||||
// shift a by 4 places.
|
||||
for (j = 0; j < 8; j++) {
|
||||
a.val[j] = (a.val[j] >> 4) | ((a.val[j + 1] & 0xf) << 26);
|
||||
a.val[j] =
|
||||
(a.val[j] >> 4) | ((a.val[j + 1] & 0xf) << (BN_BITS_PER_LIMB - 4));
|
||||
}
|
||||
a.val[j] >>= 4;
|
||||
// a = old(a)>>(4*i)
|
||||
@ -614,12 +602,12 @@ void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k,
|
||||
lowbits &= 15;
|
||||
// negate last result to make signs of this round and the
|
||||
// last round equal.
|
||||
conditional_negate((lowbits & 1) - 1, &jres.y, prime);
|
||||
bn_cnegate(~lowbits & 1, &jres.y, prime);
|
||||
|
||||
// add odd factor
|
||||
point_jacobian_add(&curve->cp[i][lowbits >> 1], &jres, curve);
|
||||
}
|
||||
conditional_negate(((a.val[0] >> 4) & 1) - 1, &jres.y, prime);
|
||||
bn_cnegate(~(a.val[0] >> 4) & 1, &jres.y, prime);
|
||||
jacobian_to_curve(&jres, res, prime);
|
||||
memzero(&a, sizeof(a));
|
||||
memzero(&jres, sizeof(jres));
|
||||
|
@ -24,30 +24,31 @@
|
||||
#include "nist256p1.h"
|
||||
|
||||
const ecdsa_curve nist256p1 = {
|
||||
/* .prime */ {/*.val =*/{0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3f, 0x0, 0x0,
|
||||
0x1000, 0x3fffc000, 0xffff}},
|
||||
/* .prime */ {/*.val =*/{0x1fffffff, 0x1fffffff, 0x1fffffff, 0x000001ff,
|
||||
0x00000000, 0x00000000, 0x00040000, 0x1fe00000,
|
||||
0xffffff}},
|
||||
|
||||
/* G */
|
||||
{/*.x =*/{/*.val =*/{0x1898c296, 0x1284e517, 0x1eb33a0f, 0xdf604b,
|
||||
0x2440f277, 0x339b958e, 0x4247f8b, 0x347cb84b,
|
||||
0x6b17}},
|
||||
/*.y =*/{/*.val =*/{0x37bf51f5, 0x2ed901a0, 0x3315ecec, 0x338cd5da,
|
||||
0xf9e162b, 0x1fad29f0, 0x27f9b8ee, 0x10b8bf86,
|
||||
0x4fe3}}},
|
||||
{/*.x =*/{/*.val =*/{0x1898c296, 0x0509ca2e, 0x1acce83d, 0x06fb025b,
|
||||
0x040f2770, 0x1372b1d2, 0x091fe2f3, 0x1e5c2588,
|
||||
0x6b17d1}},
|
||||
/*.y =*/{/*.val =*/{0x17bf51f5, 0x1db20341, 0x0c57b3b2, 0x1c66aed6,
|
||||
0x19e162bc, 0x15a53e07, 0x1e6e3b9f, 0x1c5fc34f,
|
||||
0x4fe342}}},
|
||||
|
||||
/* order */
|
||||
{/*.val =*/{0x3c632551, 0xee72b0b, 0x3179e84f, 0x39beab69, 0x3fffffbc,
|
||||
0x3fffffff, 0xfff, 0x3fffc000, 0xffff}},
|
||||
{/*.val =*/{0x1c632551, 0x1dce5617, 0x05e7a13c, 0x0df55b4e, 0x1ffffbce,
|
||||
0x1fffffff, 0x0003ffff, 0x1fe00000, 0xffffff}},
|
||||
|
||||
/* order_half */
|
||||
{/*.val =*/{0x3e3192a8, 0x27739585, 0x38bcf427, 0x1cdf55b4, 0x3fffffde,
|
||||
0x3fffffff, 0x7ff, 0x3fffe000, 0x7fff}},
|
||||
{/*.val =*/{0x1e3192a8, 0x0ee72b0b, 0x02f3d09e, 0x06faada7, 0x1ffffde7,
|
||||
0x1fffffff, 0x0001ffff, 0x1ff00000, 0x7fffff}},
|
||||
|
||||
/* a */ -3,
|
||||
|
||||
/* b */
|
||||
{/*.val =*/{0x27d2604b, 0x2f38f0f8, 0x53b0f63, 0x741ac33, 0x1886bc65,
|
||||
0x2ef555da, 0x293e7b3e, 0xd762a8e, 0x5ac6}}
|
||||
{/*.val =*/{0x07d2604b, 0x1e71e1f1, 0x14ec3d8e, 0x1a0d6198, 0x086bc651,
|
||||
0x1eaabb4c, 0x0f9ecfae, 0x1b154752, 0x005ac635}}
|
||||
|
||||
#if USE_PRECOMPUTED_CP
|
||||
,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,24 +24,25 @@
|
||||
#include "secp256k1.h"
|
||||
|
||||
const ecdsa_curve secp256k1 = {
|
||||
/* .prime */ {/*.val =*/{0x3ffffc2f, 0x3ffffffb, 0x3fffffff, 0x3fffffff,
|
||||
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
|
||||
0xffff}},
|
||||
/* .prime */ {/*.val =*/{0x1ffffc2f, 0x1ffffff7, 0x1fffffff, 0x1fffffff,
|
||||
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
|
||||
0xffffff}},
|
||||
|
||||
/* G */
|
||||
{/*.x =*/{/*.val =*/{0x16f81798, 0x27ca056c, 0x1ce28d95, 0x26ff36cb,
|
||||
0x70b0702, 0x18a573a, 0xbbac55a, 0x199fbe77, 0x79be}},
|
||||
/*.y =*/{/*.val =*/{0x3b10d4b8, 0x311f423f, 0x28554199, 0x5ed1229,
|
||||
0x1108a8fd, 0x13eff038, 0x3c4655da, 0x369dc9a8,
|
||||
0x483a}}},
|
||||
{/*.x =*/{/*.val =*/{0x16f81798, 0x0f940ad8, 0x138a3656, 0x17f9b65b,
|
||||
0x10b07029, 0x114ae743, 0x0eb15681, 0x0fdf3b97,
|
||||
0x79be66}},
|
||||
/*.y =*/{/*.val =*/{0x1b10d4b8, 0x023e847f, 0x01550667, 0x0f68914d,
|
||||
0x108a8fd1, 0x1dfe0708, 0x11957693, 0x0ee4d478,
|
||||
0x483ada}}},
|
||||
|
||||
/* order */
|
||||
{/*.val =*/{0x10364141, 0x3f497a33, 0x348a03bb, 0x2bb739ab, 0x3ffffeba,
|
||||
0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff}},
|
||||
{/*.val =*/{0x10364141, 0x1e92f466, 0x12280eef, 0x1db9cd5e, 0x1fffebaa,
|
||||
0x1fffffff, 0x1fffffff, 0x1fffffff, 0xffffff}},
|
||||
|
||||
/* order_half */
|
||||
{/*.val =*/{0x281b20a0, 0x3fa4bd19, 0x3a4501dd, 0x15db9cd5, 0x3fffff5d,
|
||||
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x7fff}},
|
||||
{/*.val =*/{0x081b20a0, 0x1f497a33, 0x09140777, 0x0edce6af, 0x1ffff5d5,
|
||||
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x7fffff}},
|
||||
|
||||
/* a */ 0,
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
1028
crypto/tests/test_bignum.py
Executable file
1028
crypto/tests/test_bignum.py
Executable file
File diff suppressed because it is too large
Load Diff
@ -131,8 +131,8 @@ START_TEST(test_bignum_read_be) {
|
||||
|
||||
bn_read_be(input, &a);
|
||||
|
||||
bignum256 b = {{0x286d8bd5, 0x380c7c17, 0x3c6a2ec1, 0x2d787ef5, 0x14437cd3,
|
||||
0x25a043f8, 0x1dd5263f, 0x33a162c3, 0x0000c55e}};
|
||||
bignum256 b = {{0x086d8bd5, 0x1018f82f, 0x11a8bb07, 0x0bc3f7af, 0x0437cd3b,
|
||||
0x14087f0a, 0x15498fe5, 0x10b161bb, 0xc55ece}};
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
ck_assert_int_eq(a.val[i], b.val[i]);
|
||||
@ -141,8 +141,8 @@ START_TEST(test_bignum_read_be) {
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_bignum_write_be) {
|
||||
bignum256 a = {{0x286d8bd5, 0x380c7c17, 0x3c6a2ec1, 0x2d787ef5, 0x14437cd3,
|
||||
0x25a043f8, 0x1dd5263f, 0x33a162c3, 0x0000c55e}};
|
||||
bignum256 a = {{0x086d8bd5, 0x1018f82f, 0x11a8bb07, 0x0bc3f7af, 0x0437cd3b,
|
||||
0x14087f0a, 0x15498fe5, 0x10b161bb, 0xc55ece}};
|
||||
uint8_t tmp[32];
|
||||
|
||||
bn_write_be(&a, tmp);
|
||||
@ -156,10 +156,10 @@ START_TEST(test_bignum_write_be) {
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_bignum_is_equal) {
|
||||
bignum256 a = {{0x286d8bd5, 0x380c7c17, 0x3c6a2ec1, 0x2d787ef5, 0x14437cd3,
|
||||
0x25a043f8, 0x1dd5263f, 0x33a162c3, 0x0000c55e}};
|
||||
bignum256 b = {{0x286d8bd5, 0x380c7c17, 0x3c6a2ec1, 0x2d787ef5, 0x14437cd3,
|
||||
0x25a043f8, 0x1dd5263f, 0x33a162c3, 0x0000c55e}};
|
||||
bignum256 a = {{0x086d8bd5, 0x1018f82f, 0x11a8bb07, 0x0bc3f7af, 0x0437cd3b,
|
||||
0x14087f0a, 0x15498fe5, 0x10b161bb, 0xc55ece}};
|
||||
bignum256 b = {{0x086d8bd5, 0x1018f82f, 0x11a8bb07, 0x0bc3f7af, 0x0437cd3b,
|
||||
0x14087f0a, 0x15498fe5, 0x10b161bb, 0xc55ece}};
|
||||
bignum256 c = {{
|
||||
0,
|
||||
}};
|
||||
@ -339,6 +339,13 @@ END_TEST
|
||||
START_TEST(test_bignum_write_uint32) {
|
||||
bignum256 a;
|
||||
|
||||
// lowest 29 bits set
|
||||
bn_read_be(
|
||||
fromhex(
|
||||
"000000000000000000000000000000000000000000000000000000001fffffff"),
|
||||
&a);
|
||||
ck_assert_int_eq(bn_write_uint32(&a), 0x1fffffff);
|
||||
|
||||
// lowest 30 bits set
|
||||
bn_read_be(
|
||||
fromhex(
|
||||
@ -637,8 +644,8 @@ START_TEST(test_bignum_format) {
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
&a);
|
||||
r = bn_format(&a, NULL, NULL, 18, 0, false, buf, sizeof(buf));
|
||||
ck_assert_int_eq(r, 3);
|
||||
ck_assert_str_eq(buf, "0.0");
|
||||
ck_assert_int_eq(r, 1);
|
||||
ck_assert_str_eq(buf, "0");
|
||||
|
||||
bn_read_be(
|
||||
fromhex(
|
||||
@ -757,8 +764,8 @@ START_TEST(test_bignum_format) {
|
||||
"0000000000000000000000000000000000000000000000000000000000989680"),
|
||||
&a);
|
||||
r = bn_format(&a, NULL, NULL, 7, 0, false, buf, sizeof(buf));
|
||||
ck_assert_int_eq(r, 3);
|
||||
ck_assert_str_eq(buf, "1.0");
|
||||
ck_assert_int_eq(r, 1);
|
||||
ck_assert_str_eq(buf, "1");
|
||||
|
||||
bn_read_be(
|
||||
fromhex(
|
||||
@ -805,10 +812,10 @@ START_TEST(test_bignum_format) {
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3bbb00"),
|
||||
&a);
|
||||
r = bn_format(&a, NULL, NULL, 8, 0, false, buf, sizeof(buf));
|
||||
ck_assert_int_eq(r, 72);
|
||||
ck_assert_int_eq(r, 70);
|
||||
ck_assert_str_eq(buf,
|
||||
"11579208923731619542357098500868790785326998466564056403945"
|
||||
"75840079131.0");
|
||||
"75840079131");
|
||||
|
||||
bn_read_be(
|
||||
fromhex(
|
||||
@ -825,9 +832,9 @@ START_TEST(test_bignum_format) {
|
||||
"fffffffffffffffffffffffffffffffffffffffffffffffff7e52fe5afe40000"),
|
||||
&a);
|
||||
r = bn_format(&a, NULL, NULL, 18, 0, false, buf, sizeof(buf));
|
||||
ck_assert_int_eq(r, 62);
|
||||
ck_assert_int_eq(r, 60);
|
||||
ck_assert_str_eq(
|
||||
buf, "115792089237316195423570985008687907853269984665640564039457.0");
|
||||
buf, "115792089237316195423570985008687907853269984665640564039457");
|
||||
|
||||
bn_read_be(
|
||||
fromhex(
|
||||
@ -875,7 +882,69 @@ START_TEST(test_bignum_format) {
|
||||
memset(buf, 'a', sizeof(buf));
|
||||
r = bn_format(&a, "prefix", "suffix", 10, 0, false, buf, 30);
|
||||
ck_assert_int_eq(r, 0);
|
||||
ck_assert_str_eq(buf, "prefix198552.9216486895suffix");
|
||||
ck_assert_str_eq(buf, "");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_bignum_sqrt) {
|
||||
uint32_t quadratic_residua[] = {
|
||||
1, 2, 4, 8, 9, 11, 15, 16, 17, 18, 19, 21, 22, 25, 29,
|
||||
30, 31, 32, 34, 35, 36, 38, 39, 42, 43, 44, 47, 49, 50, 58,
|
||||
59, 60, 61, 62, 64, 65, 67, 68, 69, 70, 71, 72, 76, 78, 81,
|
||||
83, 84, 86, 88, 91, 94, 98, 99, 100, 103, 107, 111, 115, 116, 118,
|
||||
120, 121, 122, 123, 124, 127, 128, 130, 131, 134, 135, 136, 137, 138, 139,
|
||||
140, 142, 144, 149, 152, 153, 156, 159, 161, 162, 165, 166, 167, 168, 169,
|
||||
171, 172, 176, 181, 182, 185, 187, 188, 189, 191, 193, 196, 197, 198, 200,
|
||||
205, 206, 209, 214, 219, 222, 223, 225, 229, 230, 231, 232, 233, 236, 237,
|
||||
239, 240, 242, 244, 246, 248, 254, 255, 256, 259, 260, 261, 262, 265, 267,
|
||||
268, 269, 270, 272, 274, 275, 276, 277, 278, 279, 280, 281, 284, 285, 287,
|
||||
288, 289, 291, 293, 298, 299, 303, 304, 306, 311, 312, 315, 318, 319, 322,
|
||||
323, 324, 327, 330, 331, 332, 334, 336, 337, 338, 339, 341, 342, 344, 349,
|
||||
351, 352, 353, 357, 359, 361, 362, 364, 365, 370, 371, 373, 374, 375, 376,
|
||||
378, 379, 382, 383, 385, 386, 387, 389, 392, 394, 395, 396, 399, 400, 409,
|
||||
410, 412, 418, 421, 423, 425, 428, 429, 431, 435, 438, 439, 441, 443, 444,
|
||||
445, 446, 450, 453, 458, 460, 461, 462, 463, 464, 465, 466, 467, 471, 472,
|
||||
473, 474, 475, 478, 479, 480, 481, 484, 485, 487, 488, 489, 492, 493, 496,
|
||||
503, 505, 508, 510, 511, 512, 517, 518, 519, 520, 521, 522, 523, 524, 525,
|
||||
527, 529, 530, 531, 533, 534, 536, 537, 538, 539, 540, 541, 544, 545, 547,
|
||||
548, 549, 550, 551, 552, 553, 554, 556, 557, 558, 560, 562, 563, 565, 568,
|
||||
570, 571, 574, 576, 578, 582, 585, 586, 587, 589, 595, 596, 597, 598, 599,
|
||||
603, 606, 607, 608, 609, 612, 613, 619, 621, 622, 623, 624, 625, 630, 633,
|
||||
636, 638, 639, 644, 645, 646, 648, 649, 651, 653, 654, 660, 662, 663, 664,
|
||||
665, 668, 671, 672, 673, 674, 676, 678, 679, 681, 682, 684, 688, 689, 698,
|
||||
702, 704, 705, 706, 707, 714, 715, 718, 722, 723, 724, 725, 728, 729, 730,
|
||||
731, 733, 735, 737, 740, 741, 742, 746, 747, 748, 750, 751, 752, 753, 755,
|
||||
756, 758, 759, 761, 763, 764, 766, 769, 770, 771, 772, 774, 775, 778, 781,
|
||||
784, 785, 788, 789, 790, 791, 792, 797, 798, 799, 800, 813, 815, 817, 818,
|
||||
819, 820, 823, 824, 833, 836, 841, 842, 846, 849, 850, 851, 856, 857, 858,
|
||||
862, 865, 870, 875, 876, 878, 882, 885, 886, 887, 888, 890, 891, 892, 893,
|
||||
895, 899, 900, 903, 906, 907, 911, 913, 915, 916, 919, 920, 921, 922, 924,
|
||||
926, 927, 928, 930, 931, 932, 934, 937, 939, 942, 943, 944, 946, 948, 949,
|
||||
950, 951, 953, 956, 958, 960, 961, 962, 963, 968, 970, 971, 974, 975, 976,
|
||||
977, 978, 984, 986, 987, 992, 995, 999};
|
||||
|
||||
bignum256 a, b;
|
||||
|
||||
bn_zero(&a);
|
||||
b = a;
|
||||
bn_sqrt(&b, &secp256k1.prime);
|
||||
ck_assert_int_eq(bn_is_equal(&a, &b), 1);
|
||||
|
||||
bn_one(&a);
|
||||
b = a;
|
||||
bn_sqrt(&b, &secp256k1.prime);
|
||||
ck_assert_int_eq(bn_is_equal(&a, &b), 1);
|
||||
|
||||
// test some quadratic residua
|
||||
for (size_t i = 0; i < sizeof(quadratic_residua) / sizeof(*quadratic_residua);
|
||||
i++) {
|
||||
bn_read_uint32(quadratic_residua[i], &a);
|
||||
b = a;
|
||||
bn_sqrt(&b, &secp256k1.prime);
|
||||
bn_multiply(&b, &b, &secp256k1.prime);
|
||||
bn_mod(&b, &secp256k1.prime);
|
||||
ck_assert_int_eq(bn_is_equal(&a, &b), 1);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -1102,12 +1171,16 @@ START_TEST(test_bignum_divmod) {
|
||||
uint32_t r;
|
||||
int i;
|
||||
|
||||
bignum256 a = {{0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
|
||||
0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff}};
|
||||
bignum256 a;
|
||||
uint32_t ar[] = {15, 14, 55, 29, 44, 24, 53, 49, 18, 55, 2, 28, 5, 4, 12,
|
||||
43, 18, 37, 28, 14, 30, 46, 12, 11, 17, 10, 10, 13, 24, 45,
|
||||
4, 33, 44, 42, 2, 46, 34, 43, 45, 28, 21, 18, 13, 17};
|
||||
|
||||
bn_read_be(
|
||||
fromhex(
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||
&a);
|
||||
|
||||
i = 0;
|
||||
while (!bn_is_zero(&a) && i < 44) {
|
||||
bn_divmod58(&a, &r);
|
||||
@ -1116,12 +1189,15 @@ START_TEST(test_bignum_divmod) {
|
||||
}
|
||||
ck_assert_int_eq(i, 44);
|
||||
|
||||
bignum256 b = {{0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
|
||||
0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff}};
|
||||
bignum256 b;
|
||||
uint32_t br[] = {935, 639, 129, 913, 7, 584, 457, 39, 564,
|
||||
640, 665, 984, 269, 853, 907, 687, 8, 985,
|
||||
570, 423, 195, 316, 237, 89, 792, 115};
|
||||
|
||||
bn_read_be(
|
||||
fromhex(
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||
&b);
|
||||
i = 0;
|
||||
while (!bn_is_zero(&b) && i < 26) {
|
||||
bn_divmod1000(&b, &r);
|
||||
@ -5904,7 +5980,8 @@ static void test_codepoints_curve(const ecdsa_curve *curve) {
|
||||
for (i = 0; i < 64; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
bn_zero(&a);
|
||||
a.val[(4 * i) / 30] = (uint32_t)(2 * j + 1) << (4 * i % 30);
|
||||
a.val[(4 * i) / BN_BITS_PER_LIMB] = (uint32_t)(2 * j + 1)
|
||||
<< (4 * i % BN_BITS_PER_LIMB);
|
||||
bn_normalize(&a);
|
||||
// note that this is not a trivial test. We add 64 curve
|
||||
// points in the table to get that particular curve point.
|
||||
@ -8670,6 +8747,7 @@ Suite *test_suite(void) {
|
||||
tcase_add_test(tc, test_bignum_is_less);
|
||||
tcase_add_test(tc, test_bignum_format);
|
||||
tcase_add_test(tc, test_bignum_format_uint64);
|
||||
tcase_add_test(tc, test_bignum_sqrt);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("base32");
|
||||
|
@ -80,14 +80,29 @@ random_iters = int(os.environ.get("ITERS", 1))
|
||||
DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
lib = c.cdll.LoadLibrary(os.path.join(DIR, "libtrezor-crypto.so"))
|
||||
|
||||
BIGNUM = c.c_uint32 * 9
|
||||
|
||||
|
||||
class curve_info(c.Structure):
|
||||
_fields_ = [("bip32_name", c.c_char_p), ("params", c.c_void_p)]
|
||||
|
||||
|
||||
lib.get_curve_by_name.restype = c.POINTER(curve_info)
|
||||
class curve_point(c.Structure):
|
||||
_fields_ = [("x", BIGNUM), ("y", BIGNUM)]
|
||||
|
||||
BIGNUM = c.c_uint32 * 9
|
||||
|
||||
class ecdsa_curve(c.Structure):
|
||||
_fields_ = [
|
||||
("prime", BIGNUM),
|
||||
("G", curve_point),
|
||||
("order", BIGNUM),
|
||||
("order_half", BIGNUM),
|
||||
("a", c.c_int),
|
||||
("b", BIGNUM),
|
||||
]
|
||||
|
||||
|
||||
lib.get_curve_by_name.restype = c.POINTER(curve_info)
|
||||
|
||||
|
||||
class Random(random.Random):
|
||||
@ -106,15 +121,15 @@ def int2bn(x, bn_type=BIGNUM):
|
||||
b = bn_type()
|
||||
b._int = x
|
||||
for i in range(len(b)):
|
||||
b[i] = x % (1 << 30)
|
||||
x = x >> 30
|
||||
b[i] = x % (1 << 29)
|
||||
x = x >> 29
|
||||
return b
|
||||
|
||||
|
||||
def bn2int(b):
|
||||
x = 0
|
||||
for i in range(len(b)):
|
||||
x += b[i] << (30 * i)
|
||||
x += b[i] << (29 * i)
|
||||
return x
|
||||
|
||||
|
||||
@ -130,7 +145,7 @@ def curve(request):
|
||||
curve_ptr = lib.get_curve_by_name(bytes(name, "ascii")).contents.params
|
||||
assert curve_ptr, "curve {} not found".format(name)
|
||||
curve_obj = curves[name]
|
||||
curve_obj.ptr = c.c_void_p(curve_ptr)
|
||||
curve_obj.ptr = c.cast(curve_ptr, c.POINTER(ecdsa_curve))
|
||||
curve_obj.p = curve_obj.curve.p() # shorthand
|
||||
return curve_obj
|
||||
|
||||
@ -148,176 +163,6 @@ def point(request):
|
||||
return curve_obj
|
||||
|
||||
|
||||
def test_inverse(curve, r):
|
||||
x = r.randrange(1, curve.p)
|
||||
y = int2bn(x)
|
||||
lib.bn_inverse(y, int2bn(curve.p))
|
||||
y = bn2int(y)
|
||||
y_ = ecdsa.numbertheory.inverse_mod(x, curve.p)
|
||||
assert y == y_
|
||||
|
||||
|
||||
def test_is_less(curve, r):
|
||||
x = r.randrange(0, curve.p)
|
||||
y = r.randrange(0, curve.p)
|
||||
x_ = int2bn(x)
|
||||
y_ = int2bn(y)
|
||||
|
||||
res = lib.bn_is_less(x_, y_)
|
||||
assert res == (x < y)
|
||||
|
||||
res = lib.bn_is_less(y_, x_)
|
||||
assert res == (y < x)
|
||||
|
||||
|
||||
def test_is_equal(curve, r):
|
||||
x = r.randrange(0, curve.p)
|
||||
y = r.randrange(0, curve.p)
|
||||
x_ = int2bn(x)
|
||||
y_ = int2bn(y)
|
||||
|
||||
assert lib.bn_is_equal(x_, y_) == (x == y)
|
||||
assert lib.bn_is_equal(x_, x_) == 1
|
||||
assert lib.bn_is_equal(y_, y_) == 1
|
||||
|
||||
|
||||
def test_is_zero(curve, r):
|
||||
x = r.randrange(0, curve.p)
|
||||
assert lib.bn_is_zero(int2bn(x)) == (not x)
|
||||
|
||||
|
||||
def test_simple_comparisons():
|
||||
assert lib.bn_is_zero(int2bn(0)) == 1
|
||||
assert lib.bn_is_zero(int2bn(1)) == 0
|
||||
|
||||
assert lib.bn_is_less(int2bn(0), int2bn(0)) == 0
|
||||
assert lib.bn_is_less(int2bn(1), int2bn(0)) == 0
|
||||
assert lib.bn_is_less(int2bn(0), int2bn(1)) == 1
|
||||
|
||||
assert lib.bn_is_equal(int2bn(0), int2bn(0)) == 1
|
||||
assert lib.bn_is_equal(int2bn(1), int2bn(0)) == 0
|
||||
assert lib.bn_is_equal(int2bn(0), int2bn(1)) == 0
|
||||
|
||||
|
||||
def test_mult_half(curve, r):
|
||||
x = r.randrange(0, 2 * curve.p)
|
||||
y = int2bn(x)
|
||||
lib.bn_mult_half(y, int2bn(curve.p))
|
||||
y = bn2int(y)
|
||||
if y >= curve.p:
|
||||
y -= curve.p
|
||||
half = ecdsa.numbertheory.inverse_mod(2, curve.p)
|
||||
assert y == (x * half) % curve.p
|
||||
|
||||
|
||||
def test_subtractmod(curve, r):
|
||||
x = r.randrange(0, 2 ** 256)
|
||||
y = r.randrange(0, 2 ** 256)
|
||||
z = int2bn(0)
|
||||
lib.bn_subtractmod(int2bn(x), int2bn(y), z, int2bn(curve.p))
|
||||
z = bn2int(z)
|
||||
z_ = x + 2 * curve.p - y
|
||||
assert z == z_
|
||||
|
||||
|
||||
def test_subtract2(r):
|
||||
x = r.randrange(0, 2 ** 256)
|
||||
y = r.randrange(0, 2 ** 256)
|
||||
x, y = max(x, y), min(x, y)
|
||||
z = int2bn(0)
|
||||
lib.bn_subtract(int2bn(x), int2bn(y), z)
|
||||
z = bn2int(z)
|
||||
z_ = x - y
|
||||
assert z == z_
|
||||
|
||||
|
||||
def test_add(curve, r):
|
||||
x = r.randrange(0, 2 ** 256)
|
||||
y = r.randrange(0, 2 ** 256)
|
||||
z_ = x + y
|
||||
z = int2bn(x)
|
||||
lib.bn_add(z, int2bn(y))
|
||||
z = bn2int(z)
|
||||
|
||||
assert z == z_
|
||||
|
||||
|
||||
def test_addmod(curve, r):
|
||||
x = r.randrange(0, 2 ** 256)
|
||||
y = r.randrange(0, 2 ** 256)
|
||||
z_ = (x + y) % curve.p
|
||||
z = int2bn(x)
|
||||
lib.bn_addmod(z, int2bn(y), int2bn(curve.p))
|
||||
z = bn2int(z)
|
||||
if z >= curve.p:
|
||||
z = z - curve.p
|
||||
assert z == z_
|
||||
|
||||
|
||||
def test_multiply(curve, r):
|
||||
k = r.randrange(0, 2 * curve.p)
|
||||
x = r.randrange(0, 2 * curve.p)
|
||||
z = (k * x) % curve.p
|
||||
k = int2bn(k)
|
||||
z_ = int2bn(x)
|
||||
p_ = int2bn(curve.p)
|
||||
lib.bn_multiply(k, z_, p_)
|
||||
z_ = bn2int(z_)
|
||||
assert z_ < 2 * curve.p
|
||||
if z_ >= curve.p:
|
||||
z_ = z_ - curve.p
|
||||
assert z_ == z
|
||||
|
||||
|
||||
def test_multiply1(curve, r):
|
||||
k = r.randrange(0, 2 * curve.p)
|
||||
x = r.randrange(0, 2 * curve.p)
|
||||
kx = k * x
|
||||
res = int2bn(0, bn_type=(c.c_uint32 * 18))
|
||||
lib.bn_multiply_long(int2bn(k), int2bn(x), res)
|
||||
res = bn2int(res)
|
||||
assert res == kx
|
||||
|
||||
|
||||
def test_multiply2(curve, r):
|
||||
x = int2bn(0)
|
||||
s = r.randrange(0, 2 ** 526)
|
||||
res = int2bn(s, bn_type=(c.c_uint32 * 18))
|
||||
prime = int2bn(curve.p)
|
||||
lib.bn_multiply_reduce(x, res, prime)
|
||||
|
||||
x = bn2int(x) % curve.p
|
||||
x_ = s % curve.p
|
||||
|
||||
assert x == x_
|
||||
|
||||
|
||||
def test_fast_mod(curve, r):
|
||||
x = r.randrange(0, 128 * curve.p)
|
||||
y = int2bn(x)
|
||||
lib.bn_fast_mod(y, int2bn(curve.p))
|
||||
y = bn2int(y)
|
||||
assert y < 2 * curve.p
|
||||
if y >= curve.p:
|
||||
y -= curve.p
|
||||
assert x % curve.p == y
|
||||
|
||||
|
||||
def test_mod(curve, r):
|
||||
x = r.randrange(0, 2 * curve.p)
|
||||
y = int2bn(x)
|
||||
lib.bn_mod(y, int2bn(curve.p))
|
||||
assert bn2int(y) == x % curve.p
|
||||
|
||||
|
||||
def test_mod_specific(curve):
|
||||
p = curve.p
|
||||
for x in [0, 1, 2, p - 2, p - 1, p, p + 1, p + 2, 2 * p - 2, 2 * p - 1]:
|
||||
y = int2bn(x)
|
||||
lib.bn_mod(y, int2bn(curve.p))
|
||||
assert bn2int(y) == x % p
|
||||
|
||||
|
||||
POINT = BIGNUM * 2
|
||||
|
||||
|
||||
@ -340,6 +185,16 @@ def from_JACOBIAN(p):
|
||||
return (bn2int(p[0]), bn2int(p[1]), bn2int(p[2]))
|
||||
|
||||
|
||||
def test_curve_parameters(curve):
|
||||
assert curve.curve.p() == bn2int(curve.ptr.contents.prime)
|
||||
assert curve.generator.x() == bn2int(curve.ptr.contents.G.x)
|
||||
assert curve.generator.y() == bn2int(curve.ptr.contents.G.y)
|
||||
assert curve.order == bn2int(curve.ptr.contents.order)
|
||||
assert curve.order // 2 == bn2int(curve.ptr.contents.order_half)
|
||||
assert curve.curve.a() == curve.ptr.contents.a
|
||||
assert curve.curve.b() == bn2int(curve.ptr.contents.b)
|
||||
|
||||
|
||||
def test_point_multiply(curve, r):
|
||||
p = r.randpoint(curve)
|
||||
k = r.randrange(0, 2 ** 256)
|
||||
@ -385,15 +240,6 @@ def test_point_to_jacobian(curve, r):
|
||||
assert q == (p.x(), p.y())
|
||||
|
||||
|
||||
def test_cond_negate(curve, r):
|
||||
x = r.randrange(0, curve.p)
|
||||
a = int2bn(x)
|
||||
lib.conditional_negate(0, a, int2bn(curve.p))
|
||||
assert bn2int(a) == x
|
||||
lib.conditional_negate(-1, a, int2bn(curve.p))
|
||||
assert bn2int(a) == 2 * curve.p - x
|
||||
|
||||
|
||||
def test_jacobian_add(curve, r):
|
||||
p1 = r.randpoint(curve)
|
||||
p2 = r.randpoint(curve)
|
||||
|
@ -39,7 +39,8 @@ int main(int argc, char **argv) {
|
||||
curve_point checkresult;
|
||||
bignum256 a;
|
||||
bn_zero(&a);
|
||||
a.val[(4 * i) / 30] = ((uint32_t)2 * j + 1) << ((4 * i) % 30);
|
||||
a.val[(4 * i) / BN_BITS_PER_LIMB] = ((uint32_t)2 * j + 1)
|
||||
<< ((4 * i) % BN_BITS_PER_LIMB);
|
||||
bn_normalize(&a);
|
||||
point_multiply(curve, &a, &curve->G, &checkresult);
|
||||
assert(point_is_equal(&checkresult, &ng));
|
||||
|
Loading…
Reference in New Issue
Block a user