New "i15" implementation of big integers (faster, and constant-time, on ARM Cortex M0/M0+); imported into EC, ECDSA, RSA.
This commit is contained in:
parent
6dd8c51ba7
commit
28e4e120b8
29 changed files with 2993 additions and 326 deletions
108
src/inner.h
108
src/inner.h
|
|
@ -532,11 +532,30 @@ MAX(uint32_t x, uint32_t y)
|
|||
* (old) platforms where the default MUL31 is not. Unfortunately, it is
|
||||
* also substantially slower, and yields larger code, on more modern
|
||||
* platforms, which is why it is deactivated by default.
|
||||
*
|
||||
* MUL31_lo() must do some extra work because on some platforms, the
|
||||
* _signed_ multiplication may return early if the top bits are 1.
|
||||
* Simply truncating (casting) the output of MUL31() would not be
|
||||
* sufficient, because the compiler may notice that we keep only the low
|
||||
* word, and then replace automatically the unsigned multiplication with
|
||||
* a signed multiplication opcode.
|
||||
*/
|
||||
#define MUL31(x, y) ((uint64_t)((x) | (uint32_t)0x80000000) \
|
||||
* (uint64_t)((y) | (uint32_t)0x80000000) \
|
||||
- ((uint64_t)(x) << 31) - ((uint64_t)(y) << 31) \
|
||||
- ((uint64_t)1 << 62))
|
||||
static inline uint32_t
|
||||
MUL31_lo(uint32_t x, uint32_t y)
|
||||
{
|
||||
uint32_t xl, xh;
|
||||
uint32_t yl, yh;
|
||||
|
||||
xl = (x & 0xFFFF) | (uint32_t)0x80000000;
|
||||
xh = (x >> 16) | (uint32_t)0x80000000;
|
||||
yl = (y & 0xFFFF) | (uint32_t)0x80000000;
|
||||
yh = (y >> 16) | (uint32_t)0x80000000;
|
||||
return (xl * yl + ((xl * yh + xh * yl) << 16)) & (uint32_t)0x7FFFFFFF;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
|
@ -544,8 +563,10 @@ MAX(uint32_t x, uint32_t y)
|
|||
* Multiply two 31-bit integers, with a 62-bit result. This default
|
||||
* implementation assumes that the basic multiplication operator
|
||||
* yields constant-time code.
|
||||
* The MUL31_lo() macro returns only the low 31 bits of the product.
|
||||
*/
|
||||
#define MUL31(x, y) ((uint64_t)(x) * (uint64_t)(y))
|
||||
#define MUL31(x, y) ((uint64_t)(x) * (uint64_t)(y))
|
||||
#define MUL31_lo(x, y) (((uint32_t)(x) * (uint32_t)(y)) & (uint32_t)0x7FFFFFFF)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -558,7 +579,7 @@ MAX(uint32_t x, uint32_t y)
|
|||
*/
|
||||
#if BR_CT_MUL15
|
||||
#define MUL15(x, y) (((uint32_t)(x) | (uint32_t)0x80000000) \
|
||||
* ((uint32_t)(x) | (uint32_t)0x80000000) \
|
||||
* ((uint32_t)(y) | (uint32_t)0x80000000) \
|
||||
& (uint32_t)0x3FFFFFFF)
|
||||
#else
|
||||
#define MUL15(x, y) ((uint32_t)(x) * (uint32_t)(y))
|
||||
|
|
@ -1046,6 +1067,53 @@ void br_i31_mulacc(uint32_t *d, const uint32_t *a, const uint32_t *b);
|
|||
|
||||
/* ==================================================================== */
|
||||
|
||||
static inline void
|
||||
br_i15_zero(uint16_t *x, uint16_t bit_len)
|
||||
{
|
||||
*x ++ = bit_len;
|
||||
memset(x, 0, ((bit_len + 15) >> 4) * sizeof *x);
|
||||
}
|
||||
|
||||
uint32_t br_i15_iszero(const uint16_t *x);
|
||||
|
||||
uint16_t br_i15_ninv15(uint16_t x);
|
||||
|
||||
uint32_t br_i15_add(uint16_t *a, const uint16_t *b, uint32_t ctl);
|
||||
|
||||
uint32_t br_i15_sub(uint16_t *a, const uint16_t *b, uint32_t ctl);
|
||||
|
||||
void br_i15_muladd_small(uint16_t *x, uint16_t z, const uint16_t *m);
|
||||
|
||||
void br_i15_montymul(uint16_t *d, const uint16_t *x, const uint16_t *y,
|
||||
const uint16_t *m, uint16_t m0i);
|
||||
|
||||
void br_i15_to_monty(uint16_t *x, const uint16_t *m);
|
||||
|
||||
void br_i15_modpow(uint16_t *x, const unsigned char *e, size_t elen,
|
||||
const uint16_t *m, uint16_t m0i, uint16_t *t1, uint16_t *t2);
|
||||
|
||||
void br_i15_encode(void *dst, size_t len, const uint16_t *x);
|
||||
|
||||
uint32_t br_i15_decode_mod(uint16_t *x,
|
||||
const void *src, size_t len, const uint16_t *m);
|
||||
|
||||
void br_i15_rshift(uint16_t *x, int count);
|
||||
|
||||
uint32_t br_i15_bit_length(uint16_t *x, size_t xlen);
|
||||
|
||||
void br_i15_decode(uint16_t *x, const void *src, size_t len);
|
||||
|
||||
void br_i15_from_monty(uint16_t *x, const uint16_t *m, uint16_t m0i);
|
||||
|
||||
void br_i15_decode_reduce(uint16_t *x,
|
||||
const void *src, size_t len, const uint16_t *m);
|
||||
|
||||
void br_i15_reduce(uint16_t *x, const uint16_t *a, const uint16_t *m);
|
||||
|
||||
void br_i15_mulacc(uint16_t *d, const uint16_t *a, const uint16_t *b);
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static inline size_t
|
||||
br_digest_size(const br_hash_class *digest_class)
|
||||
{
|
||||
|
|
@ -1343,6 +1411,29 @@ unsigned br_aes_ct64_keysched(uint64_t *comp_skey,
|
|||
void br_aes_ct64_skey_expand(uint64_t *skey,
|
||||
unsigned num_rounds, const uint64_t *comp_skey);
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* RSA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Apply proper PKCS#1 v1.5 padding (for signatures). 'hash_oid' is
|
||||
* the encoded hash function OID, or NULL.
|
||||
*/
|
||||
uint32_t br_rsa_pkcs1_sig_pad(const unsigned char *hash_oid,
|
||||
const unsigned char *hash, size_t hash_len,
|
||||
uint32_t n_bitlen, unsigned char *x);
|
||||
|
||||
/*
|
||||
* Check PKCS#1 v1.5 padding (for signatures). 'hash_oid' is the encoded
|
||||
* hash function OID, or NULL. The provided 'sig' value is _after_ the
|
||||
* modular exponentiation, i.e. it should be the padded hash. On
|
||||
* success, the hashed message is extracted.
|
||||
*/
|
||||
uint32_t br_rsa_pkcs1_sig_unpad(const unsigned char *sig, size_t sig_len,
|
||||
const unsigned char *hash_oid, size_t hash_len,
|
||||
unsigned char *hash_out);
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Elliptic curves.
|
||||
|
|
@ -1364,6 +1455,8 @@ extern const br_ec_curve_def br_secp256r1;
|
|||
extern const br_ec_curve_def br_secp384r1;
|
||||
extern const br_ec_curve_def br_secp521r1;
|
||||
|
||||
#if 0
|
||||
/* obsolete */
|
||||
/*
|
||||
* Type for the parameters for a "prime curve":
|
||||
* coordinates are in GF(p), with p prime
|
||||
|
|
@ -1383,6 +1476,7 @@ extern const br_ec_prime_i31_curve br_ec_prime_i31_secp384r1;
|
|||
extern const br_ec_prime_i31_curve br_ec_prime_i31_secp521r1;
|
||||
|
||||
#define BR_EC_I31_LEN ((BR_MAX_EC_SIZE + 61) / 31)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Decode some bytes as an i31 integer, with truncation (corresponding
|
||||
|
|
@ -1394,6 +1488,16 @@ extern const br_ec_prime_i31_curve br_ec_prime_i31_secp521r1;
|
|||
void br_ecdsa_i31_bits2int(uint32_t *x,
|
||||
const void *src, size_t len, uint32_t ebitlen);
|
||||
|
||||
/*
|
||||
* Decode some bytes as an i15 integer, with truncation (corresponding
|
||||
* to the 'bits2int' operation in RFC 6979). The target ENCODED bit
|
||||
* length is provided as last parameter. The resulting value will have
|
||||
* this declared bit length, and consists the big-endian unsigned decoding
|
||||
* of exactly that many bits in the source (capped at the source length).
|
||||
*/
|
||||
void br_ecdsa_i15_bits2int(uint16_t *x,
|
||||
const void *src, size_t len, uint32_t ebitlen);
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* SSL/TLS support functions.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue