@@ -7,6 +7,11 @@ | |||
* @author Mike Hamburg | |||
* @warning This file was automatically generated. | |||
* Then it was edited by hand. Good luck, have fun. | |||
* | |||
* This file contains a huge number of different options for EC point arithmetic, | |||
* but only a few of them will be used by any given library. They are here for | |||
* reference and for consistency checks. The Goldilocks library link step strips | |||
* out unused functions. | |||
*/ | |||
#include "ec_point.h" | |||
@@ -19,7 +24,7 @@ add_tw_niels_to_tw_extensible ( | |||
) { | |||
ANALYZE_THIS_ROUTINE_CAREFULLY; | |||
field_a_t L0, L1; | |||
field_sub ( L1, d->y, d->x ); | |||
field_subx_nr ( L1, d->y, d->x ); | |||
field_mul ( L0, e->a, L1 ); | |||
field_add_nr ( L1, d->x, d->y ); | |||
field_mul ( d->y, e->b, L1 ); | |||
@@ -34,6 +39,62 @@ add_tw_niels_to_tw_extensible ( | |||
field_mul ( d->y, L0, d->u ); | |||
} | |||
void | |||
add_tw_extended ( | |||
tw_extended_a_t d, | |||
const tw_extended_a_t e | |||
) { | |||
ANALYZE_THIS_ROUTINE_CAREFULLY; | |||
field_a_t L0, L1, L2; | |||
field_subx_nr ( L1, d->y, d->x ); | |||
field_subx_nr ( L2, e->y, e->x ); | |||
field_mul ( L0, L2, L1 ); | |||
field_add_nr ( L1, d->y, d->x ); | |||
field_add_nr ( L2, e->y, e->x ); | |||
field_mul ( d->y, L2, L1 ); | |||
field_mul ( L1, e->t, d->t ); | |||
field_mulw_scc_wr ( d->x, L1, 2-2*EDWARDS_D ); | |||
field_add_nr ( L1, L0, d->y ); | |||
field_subx_nr ( L2, d->y, L0 ); | |||
field_mul ( L0, d->z, e->z ); | |||
field_add_nr ( L0, L0, L0 ); | |||
field_add_nr ( d->y, L0, d->x ); | |||
field_subx_nr ( L0, L0, d->x ); | |||
field_mul ( d->z, L0, d->y ); | |||
field_mul ( d->x, d->y, L2 ); | |||
field_mul ( d->y, L0, L1 ); | |||
field_mul ( d->t, L1, L2 ); | |||
} | |||
void | |||
add_sub_tw_extended ( | |||
tw_extended_a_t d, | |||
const tw_extended_a_t e, | |||
mask_t sub | |||
) { | |||
field_a_t L0, L1, L2, L3; | |||
field_sub ( L1, d->y, d->x ); | |||
field_sub ( L2, e->y, e->x ); | |||
field_add ( L3, e->y, e->x ); | |||
constant_time_cond_swap(L2,L3,sizeof(L2),sub); | |||
field_mul ( L0, L2, L1 ); | |||
field_add ( L1, d->y, d->x ); | |||
field_mul ( d->y, L3, L1 ); | |||
field_mul ( L1, e->t, d->t ); | |||
field_mulw_scc_wr ( d->x, L1, 2-2*EDWARDS_D ); | |||
field_add ( L1, L0, d->y ); | |||
field_sub ( L2, d->y, L0 ); | |||
field_mul ( L0, d->z, e->z ); | |||
field_add ( L0, L0, L0 ); | |||
field_add ( d->y, L0, d->x ); | |||
field_sub ( L0, L0, d->x ); | |||
constant_time_cond_swap(L0,d->y,sizeof(L0),sub); | |||
field_mul ( d->z, L0, d->y ); | |||
field_mul ( d->x, d->y, L2 ); | |||
field_mul ( d->y, L0, L1 ); | |||
field_mul ( d->t, L1, L2 ); | |||
} | |||
void | |||
sub_tw_niels_from_tw_extensible ( | |||
tw_extensible_a_t d, | |||
@@ -194,6 +255,17 @@ convert_tw_affine_to_tw_extensible ( | |||
field_copy ( b->u, a->y ); | |||
} | |||
void | |||
convert_tw_extensible_to_tw_extended ( | |||
tw_extended_a_t b, | |||
const tw_extensible_a_t a | |||
) { | |||
field_copy ( b->x, a->x ); | |||
field_copy ( b->y, a->y ); | |||
field_copy ( b->z, a->z ); | |||
field_mul ( b->t, a->t, a->u ); | |||
} | |||
void | |||
convert_affine_to_extensible ( | |||
extensible_a_t b, | |||
@@ -523,6 +595,90 @@ decaf_serialize_tw_extensible ( | |||
decaf_abs ( b ); | |||
} | |||
void | |||
decaf_serialize_tw_extended ( | |||
field_a_t b, | |||
const tw_extended_a_t a | |||
) { | |||
field_a_t L0, L1, L2, L3; | |||
field_mulw_scc ( L0, a->y, 1-EDWARDS_D ); | |||
field_mul ( L2, L0, a->t ); | |||
field_mul ( L0, a->x, a->z ); | |||
field_sub ( L3, L2, L0 ); | |||
field_add ( L0, a->z, a->y ); | |||
field_sub ( L1, a->z, a->y ); | |||
field_mul ( L2, L1, L0 ); | |||
field_mulw_scc ( L1, L2, -EDWARDS_D ); | |||
field_isr ( L0, L1 ); | |||
field_mulw_scc ( L1, L0, -EDWARDS_D ); | |||
field_mul ( L2, L1, L0 ); | |||
field_mul ( L0, L2, L3 ); | |||
field_add ( L3, L1, L1 ); | |||
field_mul ( L2, L3, a->z ); | |||
field_cond_neg ( L1, ~field_high_bit(L2) ); | |||
field_mul ( L2, L1, a->y ); | |||
field_add ( b, L0, L2 ); | |||
decaf_abs ( b ); | |||
} | |||
/* | |||
static void | |||
tw_extended_efgh ( | |||
tw_extended_a_t a, | |||
field_a_t x, | |||
field_a_t xz, | |||
field_a_t y, | |||
field_a_t yz | |||
) { | |||
field_mul(a->x,x,yz); | |||
field_mul(a->y,y,xz); | |||
field_mul(a->z,xz,yz); | |||
field_mul(a->t,x,y); | |||
} | |||
*/ | |||
mask_t | |||
decaf_deserialize_tw_extended ( | |||
tw_extended_a_t a, | |||
const field_a_t s, | |||
mask_t allow_identity | |||
) { | |||
field_a_t L0, L1, L2, L3, L4; | |||
mask_t succ, zero; | |||
zero = field_is_zero(s); | |||
succ = allow_identity | ~zero; | |||
succ &= ~field_high_bit(s); | |||
field_sqr ( L0, s ); // L0 = s^2 | |||
field_neg ( a->z, L0 ); | |||
field_addw ( a->z, 1 ); | |||
field_sqr ( L1, a->z ); | |||
field_mulw_scc_wr ( L2, L0, 4-4*EDWARDS_D ); | |||
field_add ( L2, L2, L1 ); // L2 = [t^2] | |||
field_mul ( L1, L2, L0 ); // L1 = [t^2] s^2 | |||
field_isr ( L3, L1 ); // L3 =? 1/ts; check it | |||
field_sqr ( L4, L3 ); | |||
field_mul ( L0, L4, L1 ); | |||
field_addw( L0, 1 ); | |||
succ &= ~field_is_zero( L0 ); | |||
field_mul ( L1, L2, L3 ); // L1 = t^2 * 1/ts = t/s | |||
field_cond_neg ( L3, field_high_bit(L1) ); // negate 1/ts? | |||
field_add( a->x, s, s ); | |||
field_mul ( L2, L3, s ); | |||
field_neg ( L1, a->z ); | |||
field_addw ( L1, 2 ); | |||
field_mul ( L0, L1, L2 ); | |||
field_mul(a->y,L0,a->z); | |||
field_mul(a->t,a->x,L0); | |||
field_addw ( a->y, -zero ); | |||
return succ; | |||
} | |||
mask_t | |||
decaf_deserialize_affine ( | |||
affine_a_t a, | |||
@@ -803,6 +959,16 @@ set_identity_extensible ( | |||
field_set_ui( a->u, 0 ); | |||
} | |||
void | |||
set_identity_tw_extended ( | |||
tw_extended_a_t a | |||
) { | |||
field_set_ui( a->x, 0 ); | |||
field_set_ui( a->y, 1 ); | |||
field_set_ui( a->z, 1 ); | |||
field_set_ui( a->t, 0 ); | |||
} | |||
void | |||
set_identity_tw_extensible ( | |||
tw_extensible_a_t a | |||
@@ -827,12 +993,21 @@ decaf_eq_extensible ( | |||
const struct extensible_t* a, | |||
const struct extensible_t* b | |||
) { | |||
field_a_t L0, L1, L2; | |||
field_mul ( L2, b->y, a->x ); | |||
field_a_t L0, L1; | |||
field_mul ( L0, b->y, a->x ); | |||
field_mul ( L1, a->y, b->x ); | |||
field_sub ( L0, L2, L1 ); | |||
field_bias ( L0, 2 ); | |||
return field_is_zero ( L0 ); | |||
return field_eq(L0,L1); | |||
} | |||
mask_t | |||
decaf_eq_tw_extended ( | |||
const tw_extended_a_t a, | |||
const tw_extended_a_t b | |||
) { | |||
field_a_t L0, L1; | |||
field_mul ( L0, b->y, a->x ); | |||
field_mul ( L1, a->y, b->x ); | |||
return field_eq(L0,L1); | |||
} | |||
mask_t | |||
@@ -4,7 +4,11 @@ | |||
* Copyright (c) 2014 Cryptography Research, Inc. \n | |||
* Released under the MIT License. See LICENSE.txt for license information. | |||
* @author Mike Hamburg | |||
* @warning This file was automatically generated. | |||
* | |||
* This file contains a huge number of different options for EC point arithmetic, | |||
* but only a few of them will be used by any given library. They are here for | |||
* reference and for consistency checks. The Goldilocks library link step strips | |||
* out unused functions. | |||
*/ | |||
#ifndef __CC_INCLUDED_EC_POINT_H__ | |||
@@ -75,6 +79,14 @@ typedef struct tw_extensible_t { | |||
field_a_t x, y, z, t, u; | |||
} tw_extensible_a_t[1]; | |||
/** | |||
* Extended coordinates for twisted Edwards curves. | |||
* Jack of all trades, master of none. | |||
*/ | |||
typedef struct tw_extended_t { | |||
field_a_t x, y, z, t; | |||
} tw_extended_a_t[1]; | |||
/** | |||
* Niels coordinates for twisted Edwards curves. | |||
* | |||
@@ -140,6 +152,15 @@ copy_tw_extensible ( | |||
const tw_extensible_a_t ds | |||
) __attribute__((unused,always_inline)); | |||
/** | |||
* Auto-generated copy method. | |||
*/ | |||
static __inline__ void | |||
copy_tw_extended ( | |||
tw_extended_a_t a, | |||
const tw_extended_a_t ds | |||
) __attribute__((unused,always_inline)); | |||
/** | |||
* Auto-generated copy method. | |||
*/ | |||
@@ -272,6 +293,25 @@ convert_tw_niels_to_tw_extensible ( | |||
const tw_niels_a_t d | |||
); | |||
void | |||
convert_tw_extensible_to_tw_extended ( | |||
tw_extended_a_t b, | |||
const tw_extensible_a_t a | |||
); | |||
void | |||
add_tw_extended ( | |||
tw_extended_a_t d, | |||
const tw_extended_a_t e | |||
); | |||
void | |||
add_sub_tw_extended ( | |||
tw_extended_a_t d, | |||
const tw_extended_a_t e, | |||
mask_t sub | |||
); | |||
void | |||
montgomery_step ( | |||
montgomery_a_t a | |||
@@ -435,6 +475,21 @@ decaf_serialize_tw_extensible ( | |||
const tw_extensible_a_t a | |||
); | |||
mask_t | |||
decaf_deserialize_tw_extended ( | |||
tw_extended_a_t a, | |||
const field_a_t s, | |||
mask_t allow_identity | |||
) | |||
__attribute__((warn_unused_result)); | |||
void | |||
decaf_serialize_tw_extended ( | |||
field_a_t b, | |||
const tw_extended_a_t a | |||
); | |||
void | |||
set_identity_extensible ( | |||
extensible_a_t a | |||
@@ -445,6 +500,11 @@ set_identity_tw_extensible ( | |||
tw_extensible_a_t a | |||
); | |||
void | |||
set_identity_tw_extended ( | |||
tw_extended_a_t a | |||
); | |||
void | |||
set_identity_affine ( | |||
affine_a_t a | |||
@@ -486,6 +546,13 @@ decaf_eq_tw_extensible ( | |||
) | |||
__attribute__((warn_unused_result)); | |||
mask_t | |||
decaf_eq_tw_extended ( | |||
const tw_extended_a_t a, | |||
const tw_extended_a_t b | |||
) | |||
__attribute__((warn_unused_result)); | |||
mask_t | |||
decaf_eq_extensible ( | |||
const extensible_a_t a, | |||
@@ -592,6 +659,17 @@ copy_tw_extensible ( | |||
field_copy ( a->u, ds->u ); | |||
} | |||
void | |||
copy_tw_extended ( | |||
tw_extended_a_t a, | |||
const tw_extended_a_t ds | |||
) { | |||
field_copy ( a->x, ds->x ); | |||
field_copy ( a->y, ds->y ); | |||
field_copy ( a->z, ds->z ); | |||
field_copy ( a->t, ds->t ); | |||
} | |||
void | |||
copy_tw_niels ( | |||
tw_niels_a_t a, | |||
@@ -145,6 +145,23 @@ scalarmul ( | |||
/* TODO? int nbits */ | |||
); | |||
/** | |||
* Scalar multiply a twisted Edwards-form point, simply, in extended coordinates. | |||
* | |||
* This function takes constant time. | |||
* | |||
* Currently the scalar is always exactly 448 bits long. | |||
* | |||
* @param [inout] working The point to multply. | |||
* @param [in] scalar The scalar, in little-endian form. | |||
*/ | |||
void | |||
scalarmul_ed ( | |||
tw_extended_a_t working, | |||
const word_t scalar[SCALAR_WORDS] | |||
/* TODO? int nbits */ | |||
); | |||
/** | |||
* Scalar multiply a twisted Edwards-form point. Use the same | |||
* algorithm as scalarmul(), but uses variable array indices. | |||
@@ -88,6 +88,17 @@ constant_time_lookup_tw_pniels ( | |||
constant_time_lookup(out,in,sizeof(*out),nin,idx); | |||
} | |||
static __inline__ void | |||
__attribute__((unused,always_inline)) | |||
constant_time_lookup_tw_extended ( | |||
tw_extended_a_t out, | |||
const tw_extended_a_t *in, | |||
int nin, | |||
int idx | |||
) { | |||
constant_time_lookup(out,in,sizeof(*out),nin,idx); | |||
} | |||
static __inline__ void | |||
__attribute__((unused,always_inline)) | |||
constant_time_lookup_tw_niels ( | |||
@@ -189,6 +200,65 @@ scalarmul ( | |||
} | |||
} | |||
void | |||
scalarmul_ed ( | |||
tw_extended_a_t working, | |||
const word_t scalar[SCALAR_WORDS] | |||
) { | |||
const int WINDOW = SCALARMUL_FIXED_WINDOW_SIZE, | |||
WINDOW_MASK = (1<<WINDOW)-1, WINDOW_T_MASK = WINDOW_MASK >> 1, | |||
NTABLE = 1<<(WINDOW-1), | |||
nbits = ROUND_UP(SCALAR_BITS,WINDOW); | |||
word_t scalar2[SCALAR_WORDS]; | |||
convert_to_signed_window_form ( | |||
scalar2, scalar, SCALAR_WORDS, | |||
SCALARMUL_FIXED_WINDOW_ADJUSTMENT, SCALAR_WORDS | |||
); | |||
tw_extended_a_t | |||
tmp VECTOR_ALIGNED, | |||
multiples[NTABLE] VECTOR_ALIGNED; | |||
copy_tw_extended(tmp, working); | |||
add_tw_extended(tmp, tmp); | |||
copy_tw_extended(multiples[0], working); | |||
int i,j; | |||
for (i=1; i<NTABLE; i++) { | |||
add_tw_extended(working, tmp); | |||
copy_tw_extended(multiples[i], working); | |||
} | |||
i = nbits - WINDOW; | |||
int bits = scalar2[i/WORD_BITS] >> (i%WORD_BITS) & WINDOW_MASK, | |||
inv = (bits>>(WINDOW-1))-1; | |||
bits ^= inv; | |||
set_identity_tw_extended(working); | |||
for (; i>=0; i-=WINDOW) { | |||
if (i != nbits-WINDOW) { | |||
for (j=0; j<WINDOW; j++) { | |||
add_tw_extended(working,working); | |||
} | |||
} | |||
bits = scalar2[i/WORD_BITS] >> (i%WORD_BITS); | |||
if (i/WORD_BITS < SCALAR_WORDS-1 && i%WORD_BITS >= WORD_BITS-WINDOW) { | |||
bits ^= scalar2[i/WORD_BITS+1] << (WORD_BITS - (i%WORD_BITS)); | |||
} | |||
bits &= WINDOW_MASK; | |||
inv = (bits>>(WINDOW-1))-1; | |||
bits ^= inv; | |||
constant_time_lookup_tw_extended(tmp, (const tw_extended_a_t*)multiples, NTABLE, bits & WINDOW_T_MASK); | |||
add_sub_tw_extended(working, tmp, inv); | |||
} | |||
} | |||
void | |||
scalarmul_vlook ( | |||
tw_extensible_a_t working, | |||
@@ -267,12 +267,23 @@ int main(int argc, char **argv) { | |||
memset(&ext,0,sizeof(ext)); | |||
memset(&niels,0,sizeof(niels)); /* avoid assertions in p521 even though this isn't a valid ext or niels */ | |||
tw_extended_a_t ed; | |||
convert_tw_extensible_to_tw_extended(ed,&ext); | |||
when = now(); | |||
for (i=0; i<nbase*100; i++) { | |||
add_tw_niels_to_tw_extensible(&ext, &niels); | |||
} | |||
when = now() - when; | |||
printf("exti+niels: %5.1fns\n", when * 1e9 / i); | |||
when = now(); | |||
for (i=0; i<nbase*100; i++) { | |||
add_tw_extended(ed,ed); | |||
} | |||
when = now() - when; | |||
printf("txt + txt : %5.1fns\n", when * 1e9 / i); | |||
convert_tw_extensible_to_tw_pniels(&pniels, &ext); | |||
when = now(); | |||
@@ -347,6 +358,23 @@ int main(int argc, char **argv) { | |||
when = now() - when; | |||
printf("edwards svl: %5.1fµs\n", when * 1e6 / i); | |||
when = now(); | |||
for (i=0; i<nbase/10; i++) { | |||
scalarmul_ed(ed,sk); | |||
} | |||
when = now() - when; | |||
printf("edwards txt: %5.1fµs\n", when * 1e6 / i); | |||
field_set_ui(a,0); | |||
when = now(); | |||
for (i=0; i<nbase/10; i++) { | |||
ignore_result(decaf_deserialize_tw_extended(ed,a,-1)); | |||
scalarmul_ed(ed,sk); | |||
decaf_serialize_tw_extended(a,ed); | |||
} | |||
when = now() - when; | |||
printf("simple ECDH: %5.1fµs\n", when * 1e6 / i); | |||
when = now(); | |||
for (i=0; i<nbase/10; i++) { | |||
scalarmul(&ext,sk); | |||
@@ -134,6 +134,7 @@ add_double_test ( | |||
mask_t succ = MASK_SUCCESS; | |||
struct extensible_t exb; | |||
struct tw_extensible_t text1, text2, texta, textb; | |||
struct tw_extended_t ted1, ted2; | |||
struct tw_pniels_t pn; | |||
/* Convert to ext */ | |||
@@ -154,6 +155,25 @@ add_double_test ( | |||
convert_tw_extensible_to_tw_pniels(&pn, &text2); | |||
copy_tw_extensible(&textb, &text1); | |||
add_tw_pniels_to_tw_extensible(&textb, &pn); | |||
convert_tw_extensible_to_tw_extended(&ted1, &text1); | |||
convert_tw_extensible_to_tw_extended(&ted2, &text2); | |||
add_tw_extended(&ted1, &ted2); | |||
convert_tw_extensible_to_tw_extended(&ted2, &textb); | |||
if (~decaf_eq_tw_extended(&ted1, &ted2)) { | |||
youfail(); | |||
succ = 0; | |||
printf(" Tw extended simple compat:\n"); | |||
field_print(" x1",ted1.x); | |||
field_print(" y1",ted1.y); | |||
field_print(" z1",ted1.z); | |||
field_print(" t1",ted1.t); | |||
field_print(" x2",ted2.x); | |||
field_print(" y2",ted2.y); | |||
field_print(" z2",ted2.z); | |||
field_print(" t2",ted2.t); | |||
} | |||
succ &= fail_if_different_tw(&texta,&textb,"Addition commutativity","a+b","b+a"); | |||
@@ -161,7 +181,7 @@ add_double_test ( | |||
add_tw_pniels_to_tw_extensible(&textb, &pn); | |||
copy_tw_extensible(&texta, &text2); | |||
double_tw_extensible(&texta); | |||
succ &= fail_if_different_tw(&texta,&textb,"Doubling test","2b","b+b"); | |||
if (~succ) { | |||
@@ -307,31 +327,39 @@ int test_decaf_evil (void) { | |||
random_input[55] &= 0x7F; | |||
} | |||
field_a_t base, out_m, out_e; | |||
field_a_t base, out_m, out_e, out_ed; | |||
mask_t s_base = field_deserialize(base,random_input); | |||
affine_a_t pt_e; | |||
tw_affine_a_t pt_te; | |||
tw_extended_a_t pt_ed; | |||
// TODO: test don't allow identity | |||
mask_t s_e = decaf_deserialize_affine(pt_e,base,-1); | |||
mask_t s_te = decaf_deserialize_tw_affine(pt_te,base,-1); | |||
mask_t s_ed = decaf_deserialize_tw_extended(pt_ed,base,-1); | |||
mask_t s_m = decaf_montgomery_ladder(out_m, base, random_scalar, 448); | |||
tw_extensible_a_t work; | |||
convert_tw_affine_to_tw_extensible(work,pt_te); | |||
scalarmul(work, random_scalar); | |||
decaf_serialize_tw_extensible(out_e, work); | |||
scalarmul_ed(pt_ed, random_scalar); | |||
decaf_serialize_tw_extended(out_ed, pt_ed); | |||
if ((care_should && should != s_m) | |||
|| ~s_base || s_e != s_te || s_m != s_te || (s_te && ~field_eq(out_e,out_m)) | |||
|| ~s_base || s_e != s_te || s_m != s_te || s_ed != s_te | |||
|| (s_te && ~field_eq(out_e,out_m)) | |||
|| (s_ed && ~field_eq(out_e,out_ed)) | |||
) { | |||
youfail(); | |||
field_print(" base", base); | |||
scalar_print(" scal", random_scalar, (448+WORD_BITS-1)/WORD_BITS); | |||
field_print(" oute", out_e); | |||
field_print(" outE", out_ed); | |||
field_print(" outm", out_m); | |||
printf(" succ: m=%d, e=%d, t=%d, b=%d, should=%d[%d]\n", | |||
-(int)s_m,-(int)s_e,-(int)s_te,-(int)s_base,-(int)should,-(int)care_should | |||
printf(" succ: m=%d, e=%d, t=%d, b=%d, T=%d, should=%d[%d]\n", | |||
-(int)s_m,-(int)s_e,-(int)s_te,-(int)s_base,-(int)s_ed,-(int)should,-(int)care_should | |||
); | |||
ret = -1; | |||
fails++; | |||
@@ -452,7 +480,29 @@ int test_decaf (void) { | |||
field_print(" Y2", tw_ext2.y); | |||
fails ++; | |||
} | |||
tw_extended_a_t ed; | |||
succ = decaf_deserialize_tw_extended(ed, serf, 0); | |||
decaf_serialize_tw_extended(serf2, ed); | |||
if (~succ) { | |||
youfail(); | |||
printf("Invalid decaf ed deser:\n"); | |||
field_print(" s", serf); | |||
fails ++; | |||
} else if (~field_eq(serf, serf2)) { | |||
youfail(); | |||
printf("Fail round-trip through decaf ser:\n"); | |||
field_print(" s", serf); | |||
field_print(" x", ed->x); | |||
field_print(" y", ed->y); | |||
field_print(" z", ed->z); | |||
field_print(" t", ed->t); | |||
printf(" tw deser is %s\n", validate_tw_extensible(&tw_ext) ? "valid" : "invalid"); | |||
field_print(" S", serf2); | |||
fails ++; | |||
} | |||
word_t scalar = 1; | |||
mask_t res = decaf_montgomery_ladder(serf2,serf,&scalar,1+(i%31)); | |||
if (~res | ~field_eq(serf2,serf)) { | |||
@@ -17,7 +17,7 @@ single_scalarmul_compatibility_test ( | |||
int nbits | |||
) { | |||
struct tw_extensible_t text, work; | |||
field_a_t mont, ct, vl, vt, decaf_s, decaf_m, decaf_te; | |||
field_a_t mont, ct, vl, vt, sced, decaf_s, decaf_m, decaf_te; | |||
int ret = 0, i; | |||
mask_t succ, succm; | |||
@@ -110,11 +110,21 @@ single_scalarmul_compatibility_test ( | |||
scalarmul_vt(&work, scalar, nbits); | |||
untwist_and_double_and_serialize(vt, &work); | |||
tw_extended_a_t ed; | |||
convert_tw_extensible_to_tw_extended(ed, &text); | |||
scalarmul_ed(ed, scalar); | |||
field_copy(work.x, ed->x); | |||
field_copy(work.y, ed->y); | |||
field_copy(work.z, ed->z); | |||
field_copy(work.t, ed->t); | |||
field_set_ui(work.u, 1); | |||
untwist_and_double_and_serialize(sced, &work); | |||
/* check consistency mont vs window */ | |||
consistent &= field_eq(mont, ct); | |||
consistent &= field_eq(mont, vl); | |||
consistent &= field_eq(mont, vt); | |||
consistent &= field_eq(mont, sced); | |||
} | |||
/* check consistency mont vs combs */ | |||
@@ -163,6 +173,7 @@ single_scalarmul_compatibility_test ( | |||
field_print(" ct ", ct); | |||
field_print(" vl ", vl); | |||
field_print(" vt ", vt); | |||
field_print(" ed ", sced); | |||
} | |||
printf("decaf: succ = %d, %d\n", (int)succ_dm, (int)succ_dta); | |||