@@ -92,7 +92,7 @@ gf_cpy(gf x, const gf y) { x[0] = y[0]; } | |||
/** Constant time, x = is_z ? z : y */ | |||
static INLINE void | |||
cond_sel(gf x, const gf y, const gf z, decaf_bool_t is_z) { | |||
constant_time_select(x,z,y,sizeof(gf),is_z); | |||
constant_time_select(x,z,y,sizeof(gf),is_z,0); | |||
} | |||
/** Constant time, if (neg) x=-x; */ | |||
@@ -115,6 +115,8 @@ cond_swap(gf x, gf_s *__restrict__ y, decaf_bool_t swap) { | |||
/** Compare a==b */ | |||
/* Not static because it's used in inverse square root. */ | |||
decaf_word_t gf_eq(const gf a, const gf b); | |||
decaf_word_t | |||
gf_eq(const gf a, const gf b) { | |||
gf c; | |||
@@ -300,7 +302,7 @@ decaf_error_t API_NS(scalar_invert) ( | |||
residue = 0; | |||
} | |||
if (trailing > 0 && (trailing & (1<<SCALAR_WINDOW_BITS)-1) == 0) { | |||
if (trailing > 0 && (trailing & ((1<<SCALAR_WINDOW_BITS)-1)) == 0) { | |||
if (started) { | |||
sc_montmul(out,out,precmp[trailing>>(SCALAR_WINDOW_BITS+1)]); | |||
} else { | |||
@@ -1328,8 +1330,8 @@ static void gf_batch_invert ( | |||
static void batch_normalize_niels ( | |||
niels_t *table, | |||
gf *zs, | |||
gf *zis, | |||
const gf *zs, | |||
gf *__restrict__ zis, | |||
int n | |||
) { | |||
int i; | |||
@@ -1408,7 +1410,7 @@ void API_NS(precompute) ( | |||
} | |||
} | |||
batch_normalize_niels(table->table,zs,zis,n<<(t-1)); | |||
batch_normalize_niels(table->table,(const gf *)zs,zis,n<<(t-1)); | |||
decaf_bzero(zs,sizeof(zs)); | |||
decaf_bzero(zis,sizeof(zis)); | |||
@@ -1484,7 +1486,7 @@ void API_NS(point_cond_sel) ( | |||
decaf_bool_t pick_b | |||
) { | |||
pick_b = ~word_is_zero(pick_b); | |||
constant_time_select(out,b,a,sizeof(point_t),pick_b); | |||
constant_time_select(out,b,a,sizeof(point_t),pick_b,0); | |||
} | |||
void API_NS(scalar_cond_sel) ( | |||
@@ -1494,7 +1496,7 @@ void API_NS(scalar_cond_sel) ( | |||
decaf_bool_t pick_b | |||
) { | |||
pick_b = ~word_is_zero(pick_b); | |||
constant_time_select(out,b,a,sizeof(scalar_t),pick_b); | |||
constant_time_select(out,b,a,sizeof(scalar_t),pick_b,sizeof(out->limb[0])); | |||
} | |||
/* FUTURE: restore Curve25519 Montgomery ladder? */ | |||
@@ -1627,7 +1629,7 @@ void API_NS(precompute_wnafs) ( | |||
memcpy(out[i], tmp[i]->n, sizeof(niels_t)); | |||
gf_cpy(zs[i], tmp[i]->z); | |||
} | |||
batch_normalize_niels(out, zs, zis, 1<<DECAF_WNAF_FIXED_TABLE_BITS); | |||
batch_normalize_niels(out, (const gf *)zs, zis, 1<<DECAF_WNAF_FIXED_TABLE_BITS); | |||
decaf_bzero(tmp,sizeof(tmp)); | |||
decaf_bzero(zs,sizeof(zs)); | |||
@@ -234,7 +234,8 @@ constant_time_mask ( | |||
/** | |||
* @brief Constant-time a = mask ? bTrue : bFalse. | |||
* | |||
* The input and output must be at least as aligned as elem_bytes. | |||
* The input and output must be at least as aligned as alignment_bytes | |||
* or their size, whichever is smaller. | |||
* | |||
* Note that the output is not __restrict__, but if it overlaps either | |||
* input, it must be equal and not partially overlap. | |||
@@ -249,16 +250,19 @@ constant_time_select ( | |||
const void *bTrue_, | |||
const void *bFalse_, | |||
word_t elem_bytes, | |||
mask_t mask | |||
mask_t mask, | |||
size_t alignment_bytes | |||
) { | |||
unsigned char *a = (unsigned char *)a_; | |||
const unsigned char *bTrue = (const unsigned char *)bTrue_; | |||
const unsigned char *bFalse = (const unsigned char *)bFalse_; | |||
alignment_bytes |= elem_bytes; | |||
word_t k; | |||
big_register_t br_mask = br_set_to_mask(mask); | |||
for (k=0; k<=elem_bytes-sizeof(big_register_t); k+=sizeof(big_register_t)) { | |||
if (elem_bytes % sizeof(big_register_t)) { | |||
if (alignment_bytes % sizeof(big_register_t)) { | |||
/* unaligned */ | |||
((unaligned_br_t*)(&a[k]))->unaligned = | |||
( br_mask & ((const unaligned_br_t*)(&bTrue [k]))->unaligned) | |||
@@ -273,7 +277,7 @@ constant_time_select ( | |||
if (elem_bytes % sizeof(big_register_t) >= sizeof(word_t)) { | |||
for (; k<=elem_bytes-sizeof(word_t); k+=sizeof(word_t)) { | |||
if (elem_bytes % sizeof(word_t)) { | |||
if (alignment_bytes % sizeof(word_t)) { | |||
/* unaligned */ | |||
((unaligned_word_t*)(&a[k]))->unaligned = | |||
( mask & ((const unaligned_word_t*)(&bTrue [k]))->unaligned) | |||
@@ -43,6 +43,6 @@ gf_isr ( | |||
mask_t mask = decaf_255_gf_eq(st[1],decaf_255_ONE) | decaf_255_gf_eq(st[1],SQRT_MINUS_ONE); | |||
constant_time_select(tmp1, decaf_255_ONE, SQRT_MINUS_ONE, sizeof(tmp1), mask); | |||
constant_time_select(tmp1, decaf_255_ONE, SQRT_MINUS_ONE, sizeof(tmp1), mask, 0); | |||
gf_mul(a,tmp1,st[0]); | |||
} |
@@ -21,14 +21,11 @@ extern "C" { | |||
#define DECAF_255_SCALAR_BITS 253 | |||
#define DECAF_255_SCALAR_LIMBS (256/DECAF_WORD_BITS) | |||
#ifndef __DECAF_255_GF_DEFINED__ | |||
#define __DECAF_255_GF_DEFINED__ 1 | |||
/** Galois field element internal structure */ | |||
typedef struct gf_25519_s { | |||
decaf_word_t limb[DECAF_255_LIMBS]; | |||
} gf_25519_s, gf_25519_t[1]; | |||
} __attribute__((aligned(32))) gf_25519_s, gf_25519_t[1]; | |||
/** @endcond */ | |||
#endif /* __DECAF_255_GF_DEFINED__ */ | |||
/** Number of bytes in a serialized point. */ | |||
#define DECAF_255_SER_BYTES 32 | |||