@@ -829,7 +829,6 @@ decaf_bool_t decaf_448_direct_scalarmul ( | |||||
gf s0, x0, xa, za, xd, zd, xs, zs; | gf s0, x0, xa, za, xd, zd, xs, zs; | ||||
decaf_bool_t succ = gf_deser ( s0, base ); | decaf_bool_t succ = gf_deser ( s0, base ); | ||||
succ &= allow_identity |~ gf_eq( s0, ZERO); | succ &= allow_identity |~ gf_eq( s0, ZERO); | ||||
succ &= ~hibit(s0); | |||||
gf_sqr ( xa, s0 ); | gf_sqr ( xa, s0 ); | ||||
gf_cpy ( x0, xa ); | gf_cpy ( x0, xa ); | ||||
@@ -874,16 +873,10 @@ decaf_bool_t decaf_448_direct_scalarmul ( | |||||
output_zero = gf_eq(xz_d, ZERO); | output_zero = gf_eq(xz_d, ZERO); | ||||
cond_sel(xz_d, xz_d, ONE, output_zero); /* make xz_d always nonzero */ | cond_sel(xz_d, xz_d, ONE, output_zero); /* make xz_d always nonzero */ | ||||
zcase = output_zero | gf_eq(xz_a, ZERO); | zcase = output_zero | gf_eq(xz_a, ZERO); | ||||
za_zero = gf_eq(za, ZERO); | za_zero = gf_eq(za, ZERO); | ||||
cond_sel(zs,zs,s0,zcase); /* zs, but s0 in zcase */ | |||||
cond_sel(L3,xd,zd,za_zero); | |||||
cond_sel(xs,xs,L3,zcase); /* xs, but zq or qq in zcase */ | |||||
/* Curve test in zcase */ | /* Curve test in zcase */ | ||||
gf_cpy(L0,x0); | |||||
gf_add(L0,L0,ONE); | |||||
gf_add(L0,x0,ONE); | |||||
gf_sqr(L1,L0); | gf_sqr(L1,L0); | ||||
gf_mlw(L0,x0,-4*EDWARDS_D); | gf_mlw(L0,x0,-4*EDWARDS_D); | ||||
gf_add(L1,L1,L0); | gf_add(L1,L1,L0); | ||||
@@ -914,18 +907,26 @@ decaf_bool_t decaf_448_direct_scalarmul ( | |||||
gf_mul(L2, L1, den); /* L2 = y0 / x0 */ | gf_mul(L2, L1, den); /* L2 = y0 / x0 */ | ||||
gf_mul(L1, L0, den); /* L1 = yO / xO */ | gf_mul(L1, L0, den); /* L1 = yO / xO */ | ||||
sflip = hibit(L1) ^ hibit(L2) ^ za_zero; | sflip = hibit(L1) ^ hibit(L2) ^ za_zero; | ||||
cond_sel(L0, xd, zd, sflip); /* L0 = "times" */ | |||||
cond_swap(xd, zd, sflip); /* L0 = "times" */ | |||||
/* OK, done with y-coordinates */ | /* OK, done with y-coordinates */ | ||||
/* OK, now correct for swappage */ | |||||
gf_add(den,den,den); | gf_add(den,den,den); | ||||
/* OK, now correct for swappage, if last was flip, or in zcase */ | |||||
/* Possibly den = (den*s0)^2 * xa * za */ | |||||
gf_mul(L1,den,s0); | gf_mul(L1,den,s0); | ||||
gf_sqr(L2,L1); | gf_sqr(L2,L1); | ||||
gf_mul(L3,L2,xz_a); | gf_mul(L3,L2,xz_a); | ||||
cond_sel(den,L1,L3,pflip|zcase); | cond_sel(den,L1,L3,pflip|zcase); | ||||
/* compute the output */ | |||||
gf_mul(L1,L0,den); | |||||
/* zs*xs, but s0*(xd or zd) in zcase */ | |||||
cond_sel(zs,zs,s0,zcase); | |||||
cond_sel(xs,xs,xd,zcase); | |||||
/* compute the output xd*den*xs*zs or | |||||
* den*xd^2*s0 = (oden*s0*xd)^2 * xa * za * s0 | |||||
* in zcase */ | |||||
gf_mul(L1,xd,den); | |||||
gf_mul(L0,xs,zs); | gf_mul(L0,xs,zs); | ||||
gf_mul(out,L0,L1); | gf_mul(out,L0,L1); | ||||
@@ -353,6 +353,9 @@ int test_decaf_evil (void) { | |||||
mask_t s_ed = decaf_deserialize_tw_extended(pt_ed,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); | mask_t s_m = decaf_montgomery_ladder(out_m, base, random_scalar, 448); | ||||
uint8_t ser_di[56]; | |||||
mask_t s_di = decaf_448_direct_scalarmul(ser_di,random_input,(struct decaf_448_scalar_s *)random_scalar,-1,-1); | |||||
tw_extensible_a_t work; | tw_extensible_a_t work; | ||||
convert_tw_affine_to_tw_extensible(work,pt_te); | convert_tw_affine_to_tw_extensible(work,pt_te); | ||||
scalarmul(work, random_scalar); | scalarmul(work, random_scalar); | ||||
@@ -391,10 +394,11 @@ int test_decaf_evil (void) { | |||||
eq_pos = decaf_448_point_eq(m,decaf_448_point_identity); | eq_pos = decaf_448_point_eq(m,decaf_448_point_identity); | ||||
if ((care_should && should != s_m) | if ((care_should && should != s_m) | ||||
|| ~s_base || s_e != s_te || s_m != s_te || s_ed != s_te | |||||
|| ~s_base || s_e != s_te || s_m != s_te || s_ed != s_te || s_di != s_te | |||||
|| (s_te && ~field_eq(out_e,out_m)) | || (s_te && ~field_eq(out_e,out_m)) | ||||
|| (s_ed && ~field_eq(out_e,out_ed)) | || (s_ed && ~field_eq(out_e,out_ed)) | ||||
|| memcmp(ser_de, ser_ed, 56) | || memcmp(ser_de, ser_ed, 56) | ||||
|| (s_te && memcmp(ser_di, ser_ed, 56)) | |||||
|| (s_e & ~succ_dec) | || (s_e & ~succ_dec) | ||||
|| (s_e & ~decaf_448_point_eq(pt_dec, pt_dec2) | || (s_e & ~decaf_448_point_eq(pt_dec, pt_dec2) | ||||
|| (s_e & ~decaf_448_point_valid(pt_dec)) | || (s_e & ~decaf_448_point_valid(pt_dec)) | ||||
@@ -409,8 +413,8 @@ int test_decaf_evil (void) { | |||||
field_print(" oute", out_e); | field_print(" oute", out_e); | ||||
field_print(" outE", out_ed); | field_print(" outE", out_ed); | ||||
field_print(" outm", out_m); | field_print(" outm", out_m); | ||||
printf(" succ: m=%d, e=%d, t=%d, b=%d, T=%d, D=%d, nur=%d, e+=%d, e-=%d, should=%d[%d]\n", | |||||
-(int)s_m,-(int)s_e,-(int)s_te,-(int)s_base,-(int)s_ed,-(int)succ_dec, | |||||
printf(" succ: m=%d, e=%d, t=%d, di=%d, b=%d, T=%d, D=%d, nur=%d, e+=%d, e-=%d, should=%d[%d]\n", | |||||
-(int)s_m,-(int)s_e,-(int)s_te,-(int)s_di,-(int)s_base,-(int)s_ed,-(int)succ_dec, | |||||
-(int)succ_nur, -(int)eq_neg, -(int)eq_pos, | -(int)succ_nur, -(int)eq_neg, -(int)eq_pos, | ||||
-(int)should,-(int)care_should | -(int)should,-(int)care_should | ||||
); | ); | ||||