|
|
|
@ -23,17 +23,15 @@ Derived from public domain code by D. J. Bernstein.
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
#define crypto_uint32 uint32_t
|
|
|
|
|
#define crypto_hash_sha512_BYTES 64
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
typedef uint8_t u8;
|
|
|
|
|
typedef int32_t s32;
|
|
|
|
|
typedef int64_t limb;
|
|
|
|
|
|
|
|
|
|
static inline void fsum(limb *output, const limb *in) {
|
|
|
|
|
ZT_ALWAYS_INLINE void fsum(limb *output, const limb *in) {
|
|
|
|
|
unsigned i;
|
|
|
|
|
for (i = 0; i < 10; i += 2) {
|
|
|
|
|
output[0+i] = output[0+i] + in[0+i];
|
|
|
|
@ -41,21 +39,21 @@ static inline void fsum(limb *output, const limb *in) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fdifference(limb *output, const limb *in) {
|
|
|
|
|
ZT_ALWAYS_INLINE void fdifference(limb *output, const limb *in) {
|
|
|
|
|
unsigned i;
|
|
|
|
|
for (i = 0; i < 10; ++i) {
|
|
|
|
|
output[i] = in[i] - output[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fscalar_product(limb *output, const limb *in, const limb scalar) {
|
|
|
|
|
ZT_ALWAYS_INLINE void fscalar_product(limb *output, const limb *in, const limb scalar) {
|
|
|
|
|
unsigned i;
|
|
|
|
|
for (i = 0; i < 10; ++i) {
|
|
|
|
|
output[i] = in[i] * scalar;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fproduct(limb *output, const limb *in2, const limb *in) {
|
|
|
|
|
void fproduct(limb *output, const limb *in2, const limb *in) {
|
|
|
|
|
output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]);
|
|
|
|
|
output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) +
|
|
|
|
|
((limb) ((s32) in2[1])) * ((s32) in[0]);
|
|
|
|
@ -158,7 +156,7 @@ static inline void fproduct(limb *output, const limb *in2, const limb *in) {
|
|
|
|
|
output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void freduce_degree(limb *output) {
|
|
|
|
|
void freduce_degree(limb *output) {
|
|
|
|
|
output[8] += output[18] << 4;
|
|
|
|
|
output[8] += output[18] << 1;
|
|
|
|
|
output[8] += output[18];
|
|
|
|
@ -192,7 +190,7 @@ static inline void freduce_degree(limb *output) {
|
|
|
|
|
#error "This code only works on a two's complement system"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static inline limb div_by_2_26(const limb v)
|
|
|
|
|
ZT_ALWAYS_INLINE limb div_by_2_26(const limb v)
|
|
|
|
|
{
|
|
|
|
|
/* High word of v; no shift needed. */
|
|
|
|
|
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
|
|
|
@ -204,7 +202,7 @@ static inline limb div_by_2_26(const limb v)
|
|
|
|
|
return (v + roundoff) >> 26;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline limb div_by_2_25(const limb v)
|
|
|
|
|
ZT_ALWAYS_INLINE limb div_by_2_25(const limb v)
|
|
|
|
|
{
|
|
|
|
|
/* High word of v; no shift needed*/
|
|
|
|
|
const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
|
|
|
|
@ -216,7 +214,7 @@ static inline limb div_by_2_25(const limb v)
|
|
|
|
|
return (v + roundoff) >> 25;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void freduce_coefficients(limb *output) {
|
|
|
|
|
void freduce_coefficients(limb *output) {
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
output[10] = 0;
|
|
|
|
@ -259,7 +257,7 @@ static inline void freduce_coefficients(limb *output) {
|
|
|
|
|
* bound on |output[1]| is sufficient to meet our needs. */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fmul(limb *output, const limb *in, const limb *in2) {
|
|
|
|
|
ZT_ALWAYS_INLINE void fmul(limb *output, const limb *in, const limb *in2) {
|
|
|
|
|
limb t[19];
|
|
|
|
|
fproduct(t, in, in2);
|
|
|
|
|
/* |t[i]| < 14*2^54 */
|
|
|
|
@ -269,7 +267,7 @@ static inline void fmul(limb *output, const limb *in, const limb *in2) {
|
|
|
|
|
memcpy(output, t, sizeof(limb) * 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fsquare_inner(limb *output, const limb *in) {
|
|
|
|
|
ZT_ALWAYS_INLINE void fsquare_inner(limb *output, const limb *in) {
|
|
|
|
|
output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]);
|
|
|
|
|
output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]);
|
|
|
|
|
output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
|
|
|
|
@ -327,7 +325,7 @@ static inline void fsquare_inner(limb *output, const limb *in) {
|
|
|
|
|
output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fsquare(limb *output, const limb *in) {
|
|
|
|
|
void fsquare(limb *output, const limb *in) {
|
|
|
|
|
limb t[19];
|
|
|
|
|
fsquare_inner(t, in);
|
|
|
|
|
/* |t[i]| < 14*2^54 because the largest product of two limbs will be <
|
|
|
|
@ -339,7 +337,7 @@ static inline void fsquare(limb *output, const limb *in) {
|
|
|
|
|
memcpy(output, t, sizeof(limb) * 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fexpand(limb *output, const u8 *input) {
|
|
|
|
|
ZT_ALWAYS_INLINE void fexpand(limb *output, const u8 *input) {
|
|
|
|
|
#define F(n,start,shift,mask) \
|
|
|
|
|
output[n] = ((((limb) input[start + 0]) | \
|
|
|
|
|
((limb) input[start + 1]) << 8 | \
|
|
|
|
@ -362,7 +360,7 @@ static inline void fexpand(limb *output, const u8 *input) {
|
|
|
|
|
#error "This code only works when >> does sign-extension on negative numbers"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static inline s32 s32_eq(s32 a, s32 b) {
|
|
|
|
|
ZT_ALWAYS_INLINE s32 s32_eq(s32 a, s32 b) {
|
|
|
|
|
a = ~(a ^ b);
|
|
|
|
|
a &= a << 16;
|
|
|
|
|
a &= a << 8;
|
|
|
|
@ -372,13 +370,13 @@ static inline s32 s32_eq(s32 a, s32 b) {
|
|
|
|
|
return a >> 31;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline s32 s32_gte(s32 a, s32 b) {
|
|
|
|
|
ZT_ALWAYS_INLINE s32 s32_gte(s32 a, s32 b) {
|
|
|
|
|
a -= b;
|
|
|
|
|
/* a >= 0 iff a >= b. */
|
|
|
|
|
return ~(a >> 31);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fcontract(u8 *output, limb *input_limbs) {
|
|
|
|
|
ZT_ALWAYS_INLINE void fcontract(u8 *output, limb *input_limbs) {
|
|
|
|
|
int i;
|
|
|
|
|
int j;
|
|
|
|
|
s32 input[10];
|
|
|
|
@ -477,7 +475,7 @@ static inline void fcontract(u8 *output, limb *input_limbs) {
|
|
|
|
|
#undef F
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fmonty(limb *x2, limb *z2, /* output 2Q */
|
|
|
|
|
ZT_ALWAYS_INLINE void fmonty(limb *x2, limb *z2, /* output 2Q */
|
|
|
|
|
limb *x3, limb *z3, /* output Q + Q' */
|
|
|
|
|
limb *x, limb *z, /* input Q */
|
|
|
|
|
limb *xprime, limb *zprime, /* input Q' */
|
|
|
|
@ -552,7 +550,7 @@ static inline void fmonty(limb *x2, limb *z2, /* output 2Q */
|
|
|
|
|
/* |z2|i| < 2^26 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void swap_conditional(limb a[19], limb b[19], limb iswap) {
|
|
|
|
|
ZT_ALWAYS_INLINE void swap_conditional(limb a[19], limb b[19], limb iswap) {
|
|
|
|
|
unsigned i;
|
|
|
|
|
const s32 swap = (s32) -iswap;
|
|
|
|
|
|
|
|
|
@ -563,7 +561,7 @@ static inline void swap_conditional(limb a[19], limb b[19], limb iswap) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
|
|
|
|
|
ZT_ALWAYS_INLINE void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
|
|
|
|
|
limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
|
|
|
|
|
limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
|
|
|
|
|
limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};
|
|
|
|
@ -609,7 +607,7 @@ static inline void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *
|
|
|
|
|
memcpy(resultz, nqz, sizeof(limb) * 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void crecip(limb *out, const limb *z) {
|
|
|
|
|
ZT_ALWAYS_INLINE void crecip(limb *out, const limb *z) {
|
|
|
|
|
limb z2[10];
|
|
|
|
|
limb z9[10];
|
|
|
|
|
limb z11[10];
|
|
|
|
@ -675,7 +673,7 @@ static inline void crecip(limb *out, const limb *z) {
|
|
|
|
|
/* 2^255 - 21 */ fmul(out,t1,z11);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
|
|
|
|
|
void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
|
|
|
|
|
limb bp[10], x[10], z[11], zmone[10];
|
|
|
|
|
uint8_t e[32];
|
|
|
|
|
int i;
|
|
|
|
@ -693,10 +691,9 @@ static inline void crypto_scalarmult(u8 *mypublic, const u8 *secret, const u8 *b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const unsigned char base[32] = {9};
|
|
|
|
|
static inline void crypto_scalarmult_base(unsigned char *q,const unsigned char *n) { crypto_scalarmult(q,n,base); }
|
|
|
|
|
ZT_ALWAYS_INLINE void crypto_scalarmult_base(unsigned char *q,const unsigned char *n) { crypto_scalarmult(q,n,base); }
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Ed25519 ref from: http://bench.cr.yp.to/supercop.html
|
|
|
|
|
|
|
|
|
@ -749,9 +746,9 @@ typedef struct
|
|
|
|
|
fe25519 y;
|
|
|
|
|
} ge25519_aff;
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
|
|
|
|
|
void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
|
|
|
|
|
|
|
|
|
|
static inline crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
|
|
|
|
|
ZT_ALWAYS_INLINE crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
|
|
|
|
|
{
|
|
|
|
|
crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */
|
|
|
|
|
x -= 1; /* 4294967295: yes; 0..65534: no */
|
|
|
|
@ -759,7 +756,7 @@ static inline crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inp
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
|
|
|
|
|
ZT_ALWAYS_INLINE crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
|
|
|
|
|
{
|
|
|
|
|
unsigned int x = a;
|
|
|
|
|
x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
|
|
|
|
@ -768,10 +765,10 @@ static inline crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline crypto_uint32 times19(crypto_uint32 a) { return (a << 4) + (a << 1) + a; }
|
|
|
|
|
static inline crypto_uint32 times38(crypto_uint32 a) { return (a << 5) + (a << 2) + (a << 1); }
|
|
|
|
|
ZT_ALWAYS_INLINE crypto_uint32 times19(crypto_uint32 a) { return (a << 4) + (a << 1) + a; }
|
|
|
|
|
ZT_ALWAYS_INLINE crypto_uint32 times38(crypto_uint32 a) { return (a << 5) + (a << 2) + (a << 1); }
|
|
|
|
|
|
|
|
|
|
static inline void reduce_add_sub(fe25519 *r)
|
|
|
|
|
ZT_ALWAYS_INLINE void reduce_add_sub(fe25519 *r)
|
|
|
|
|
{
|
|
|
|
|
int i,rep;
|
|
|
|
|
for(rep=0;rep<4;rep++)
|
|
|
|
@ -789,7 +786,7 @@ static inline void reduce_add_sub(fe25519 *r)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void reduce_mul(fe25519 *r)
|
|
|
|
|
ZT_ALWAYS_INLINE void reduce_mul(fe25519 *r)
|
|
|
|
|
{
|
|
|
|
|
int i,rep;
|
|
|
|
|
for(rep=0;rep<2;rep++)
|
|
|
|
@ -807,7 +804,7 @@ static inline void reduce_mul(fe25519 *r)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_freeze(fe25519 *r)
|
|
|
|
|
ZT_ALWAYS_INLINE void fe25519_freeze(fe25519 *r)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
crypto_uint32 mm = equal(r->v[31],127);
|
|
|
|
@ -823,14 +820,14 @@ static inline void fe25519_freeze(fe25519 *r)
|
|
|
|
|
r->v[0] -= mm&237;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_unpack(fe25519 *r, const unsigned char x[32])
|
|
|
|
|
ZT_ALWAYS_INLINE void fe25519_unpack(fe25519 *r, const unsigned char x[32])
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0;i<32;i++) r->v[i] = x[i];
|
|
|
|
|
r->v[31] &= 127;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_pack(unsigned char r[32], const fe25519 *x)
|
|
|
|
|
ZT_ALWAYS_INLINE void fe25519_pack(unsigned char r[32], const fe25519 *x)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
fe25519 y = *x;
|
|
|
|
@ -839,7 +836,7 @@ static inline void fe25519_pack(unsigned char r[32], const fe25519 *x)
|
|
|
|
|
r[i] = y.v[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
|
|
|
|
|
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
fe25519 t1 = *x;
|
|
|
|
@ -851,7 +848,7 @@ static inline int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
|
|
|
|
|
ZT_ALWAYS_INLINE void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
crypto_uint32 mask = b;
|
|
|
|
@ -859,27 +856,27 @@ static inline void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
|
|
|
|
|
for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline unsigned char fe25519_getparity(const fe25519 *x)
|
|
|
|
|
ZT_ALWAYS_INLINE unsigned char fe25519_getparity(const fe25519 *x)
|
|
|
|
|
{
|
|
|
|
|
fe25519 t = *x;
|
|
|
|
|
fe25519_freeze(&t);
|
|
|
|
|
return t.v[0] & 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_setone(fe25519 *r)
|
|
|
|
|
ZT_ALWAYS_INLINE void fe25519_setone(fe25519 *r)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
r->v[0] = 1;
|
|
|
|
|
for(i=1;i<32;i++) r->v[i]=0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_setzero(fe25519 *r)
|
|
|
|
|
ZT_ALWAYS_INLINE void fe25519_setzero(fe25519 *r)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0;i<32;i++) r->v[i]=0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_neg(fe25519 *r, const fe25519 *x)
|
|
|
|
|
void fe25519_neg(fe25519 *r, const fe25519 *x)
|
|
|
|
|
{
|
|
|
|
|
fe25519 t;
|
|
|
|
|
int i;
|
|
|
|
@ -888,14 +885,14 @@ static inline void fe25519_neg(fe25519 *r, const fe25519 *x)
|
|
|
|
|
fe25519_sub(r, r, &t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
|
|
|
|
void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
|
|
|
|
|
reduce_add_sub(r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
|
|
|
|
void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
crypto_uint32 t[32];
|
|
|
|
@ -906,7 +903,7 @@ static inline void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
|
|
|
|
reduce_add_sub(r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
|
|
|
|
void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
|
|
|
|
{
|
|
|
|
|
int i,j;
|
|
|
|
|
crypto_uint32 t[63];
|
|
|
|
@ -923,9 +920,9 @@ static inline void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
|
|
|
|
reduce_mul(r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_square(fe25519 *r, const fe25519 *x) { fe25519_mul(r, x, x); }
|
|
|
|
|
ZT_ALWAYS_INLINE void fe25519_square(fe25519 *r, const fe25519 *x) { fe25519_mul(r, x, x); }
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_invert(fe25519 *r, const fe25519 *x)
|
|
|
|
|
void fe25519_invert(fe25519 *r, const fe25519 *x)
|
|
|
|
|
{
|
|
|
|
|
fe25519 z2;
|
|
|
|
|
fe25519 z9;
|
|
|
|
@ -992,7 +989,7 @@ static inline void fe25519_invert(fe25519 *r, const fe25519 *x)
|
|
|
|
|
/* 2^255 - 21 */ fe25519_mul(r,&t1,&z11);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void fe25519_pow2523(fe25519 *r, const fe25519 *x)
|
|
|
|
|
void fe25519_pow2523(fe25519 *r, const fe25519 *x)
|
|
|
|
|
{
|
|
|
|
|
fe25519 z2;
|
|
|
|
|
fe25519 z9;
|
|
|
|
@ -1046,10 +1043,10 @@ static inline void fe25519_pow2523(fe25519 *r, const fe25519 *x)
|
|
|
|
|
/* 2^252 - 3 */ fe25519_mul(r,&t,x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
|
|
|
|
|
static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
|
|
|
|
|
const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
|
|
|
|
|
const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
|
|
|
|
|
|
|
|
|
|
static inline crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
|
|
|
|
|
ZT_ALWAYS_INLINE crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
|
|
|
|
|
{
|
|
|
|
|
unsigned int x = a;
|
|
|
|
|
x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
|
|
|
|
@ -1057,7 +1054,7 @@ static inline crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs
|
|
|
|
|
return x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void reduce_add_sub(sc25519 *r)
|
|
|
|
|
oid reduce_add_sub(sc25519 *r)
|
|
|
|
|
{
|
|
|
|
|
crypto_uint32 pb = 0;
|
|
|
|
|
crypto_uint32 b;
|
|
|
|
@ -1077,7 +1074,7 @@ static inline void reduce_add_sub(sc25519 *r)
|
|
|
|
|
r->v[i] ^= mask & (r->v[i] ^ t[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
|
|
|
|
|
void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
|
|
|
|
|
{
|
|
|
|
|
/* See HAC, Alg. 14.42 */
|
|
|
|
|
int i,j;
|
|
|
|
@ -1119,7 +1116,7 @@ static inline void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])
|
|
|
|
|
reduce_add_sub(r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
|
|
|
|
|
ZT_ALWAYS_INLINE void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
crypto_uint32 t[64];
|
|
|
|
@ -1128,7 +1125,7 @@ static inline void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
|
|
|
|
|
barrett_reduce(r, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
|
|
|
|
|
ZT_ALWAYS_INLINE void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
crypto_uint32 t[64];
|
|
|
|
@ -1136,13 +1133,13 @@ static inline void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
|
|
|
|
|
barrett_reduce(r, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
|
|
|
|
|
ZT_ALWAYS_INLINE void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0;i<32;i++) r[i] = x->v[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
|
|
|
|
ZT_ALWAYS_INLINE void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
|
|
|
|
@ -1154,7 +1151,7 @@ static inline void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
|
|
|
|
reduce_add_sub(r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
|
|
|
|
void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
|
|
|
|
{
|
|
|
|
|
int i,j;
|
|
|
|
|
crypto_uint32 t[64];
|
|
|
|
@ -1173,7 +1170,7 @@ static inline void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
|
|
|
|
|
barrett_reduce(r, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sc25519_window3(signed char r[85], const sc25519 *s)
|
|
|
|
|
void sc25519_window3(signed char r[85], const sc25519 *s)
|
|
|
|
|
{
|
|
|
|
|
char carry;
|
|
|
|
|
int i;
|
|
|
|
@ -1210,7 +1207,7 @@ static inline void sc25519_window3(signed char r[85], const sc25519 *s)
|
|
|
|
|
r[84] += carry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
|
|
|
|
|
ZT_ALWAYS_INLINE void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0;i<31;i++)
|
|
|
|
@ -2099,27 +2096,27 @@ static const ge25519_aff ge25519_base_multiples_affine[425] = {
|
|
|
|
|
{{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static inline void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
|
|
|
|
|
ZT_ALWAYS_INLINE void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
|
|
|
|
|
{
|
|
|
|
|
fe25519_mul(&r->x, &p->x, &p->t);
|
|
|
|
|
fe25519_mul(&r->y, &p->y, &p->z);
|
|
|
|
|
fe25519_mul(&r->z, &p->z, &p->t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void p1p1_to_p2_2(ge25519_p3 *r, const ge25519_p1p1 *p)
|
|
|
|
|
ZT_ALWAYS_INLINE void p1p1_to_p2_2(ge25519_p3 *r, const ge25519_p1p1 *p)
|
|
|
|
|
{
|
|
|
|
|
fe25519_mul(&r->x, &p->x, &p->t);
|
|
|
|
|
fe25519_mul(&r->y, &p->y, &p->z);
|
|
|
|
|
fe25519_mul(&r->z, &p->z, &p->t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
|
|
|
|
|
ZT_ALWAYS_INLINE void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
|
|
|
|
|
{
|
|
|
|
|
p1p1_to_p2_2(r, p);
|
|
|
|
|
fe25519_mul(&r->t, &p->x, &p->y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
|
|
|
|
|
ZT_ALWAYS_INLINE void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
|
|
|
|
|
{
|
|
|
|
|
fe25519 a,b,t1,t2,c,d,e,f,g,h,qt;
|
|
|
|
|
fe25519_mul(&qt, &q->x, &q->y);
|
|
|
|
@ -2142,7 +2139,7 @@ static inline void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
|
|
|
|
|
fe25519_mul(&r->t, &e, &h);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)
|
|
|
|
|
ZT_ALWAYS_INLINE void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)
|
|
|
|
|
{
|
|
|
|
|
fe25519 a, b, c, d, t;
|
|
|
|
|
|
|
|
|
@ -2163,7 +2160,7 @@ static inline void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
|
|
|
|
|
static inline void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
|
|
|
|
|
ZT_ALWAYS_INLINE void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
|
|
|
|
|
{
|
|
|
|
|
fe25519 a,b,c,d;
|
|
|
|
|
fe25519_square(&a, &p->x);
|
|
|
|
@ -2182,13 +2179,13 @@ static inline void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Constant-time version of: if(b) r = p */
|
|
|
|
|
static inline void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
|
|
|
|
|
ZT_ALWAYS_INLINE void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
|
|
|
|
|
{
|
|
|
|
|
fe25519_cmov(&r->x, &p->x, b);
|
|
|
|
|
fe25519_cmov(&r->y, &p->y, b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline unsigned char equal(signed char b,signed char c)
|
|
|
|
|
ZT_ALWAYS_INLINE unsigned char equal(signed char b,signed char c)
|
|
|
|
|
{
|
|
|
|
|
unsigned char ub = b;
|
|
|
|
|
unsigned char uc = c;
|
|
|
|
@ -2199,14 +2196,14 @@ static inline unsigned char equal(signed char b,signed char c)
|
|
|
|
|
return (unsigned char)y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline unsigned char negative(signed char b)
|
|
|
|
|
ZT_ALWAYS_INLINE unsigned char negative(signed char b)
|
|
|
|
|
{
|
|
|
|
|
unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
|
|
|
|
|
x >>= 63; /* 1: yes; 0: no */
|
|
|
|
|
return (unsigned char)x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
|
|
|
|
|
ZT_ALWAYS_INLINE void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
|
|
|
|
|
{
|
|
|
|
|
/* constant time */
|
|
|
|
|
fe25519 v;
|
|
|
|
@ -2219,7 +2216,7 @@ static inline void choose_t(ge25519_aff *t, unsigned long long pos, signed char
|
|
|
|
|
fe25519_cmov(&t->x, &v, negative(b));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void setneutral(ge25519 *r)
|
|
|
|
|
ZT_ALWAYS_INLINE void setneutral(ge25519 *r)
|
|
|
|
|
{
|
|
|
|
|
fe25519_setzero(&r->x);
|
|
|
|
|
fe25519_setone(&r->y);
|
|
|
|
@ -2228,7 +2225,7 @@ static inline void setneutral(ge25519 *r)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* return 0 on success, -1 otherwise */
|
|
|
|
|
static inline int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
|
|
|
|
|
int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
|
|
|
|
|
{
|
|
|
|
|
unsigned char par;
|
|
|
|
|
fe25519 t, chk, num, den, den2, den4, den6;
|
|
|
|
@ -2275,7 +2272,7 @@ static inline int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
|
|
|
|
|
ZT_ALWAYS_INLINE void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
|
|
|
|
|
{
|
|
|
|
|
fe25519 tx, ty, zi;
|
|
|
|
|
fe25519_invert(&zi, &p->z);
|
|
|
|
@ -2286,7 +2283,7 @@ static inline void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* computes [s1]p1 + [s2]p2 */
|
|
|
|
|
static inline void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)
|
|
|
|
|
void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)
|
|
|
|
|
{
|
|
|
|
|
ge25519_p1p1 tp1p1;
|
|
|
|
|
ge25519_p3 pre[16];
|
|
|
|
@ -2331,7 +2328,7 @@ static inline void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge2551
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
|
|
|
|
|
ZT_ALWAYS_INLINE void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
|
|
|
|
|
{
|
|
|
|
|
signed char b[85];
|
|
|
|
|
int i;
|
|
|
|
@ -2348,7 +2345,7 @@ static inline void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
|
|
|
|
|
ZT_ALWAYS_INLINE void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)
|
|
|
|
|
{
|
|
|
|
|
unsigned long long i;
|
|
|
|
|
|
|
|
|
@ -2359,8 +2356,7 @@ static inline void get_hram(unsigned char *hram, const unsigned char *sm, const
|
|
|
|
|
ZeroTier::SHA512(hram,playground,(unsigned int)smlen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
|
|