| @@ -250,19 +250,37 @@ static decaf_word_t hibit(const gf x) { | |||||
| return -(y->limb[0]&1); | return -(y->limb[0]&1); | ||||
| } | } | ||||
| /* a = use_c ? c : b */ | |||||
| sv decaf_448_cond_sel ( | |||||
| decaf_448_point_t a, | |||||
| static inline decaf_word_t | |||||
| word_is_zero(decaf_word_t x) { | |||||
| return ((decaf_dword_t)x - 1)>>WBITS; | |||||
| } | |||||
| void decaf_448_point_cond_sel ( | |||||
| decaf_448_point_t out, | |||||
| const decaf_448_point_t a, | |||||
| const decaf_448_point_t b, | const decaf_448_point_t b, | ||||
| const decaf_448_point_t c, | |||||
| decaf_bool_t use_c | |||||
| decaf_bool_t pick_b | |||||
| ) { | ) { | ||||
| pick_b = ~word_is_zero(pick_b); | |||||
| cond_sel(a->x, b->x, c->x, use_c); | cond_sel(a->x, b->x, c->x, use_c); | ||||
| cond_sel(a->y, b->y, c->y, use_c); | cond_sel(a->y, b->y, c->y, use_c); | ||||
| cond_sel(a->z, b->z, c->z, use_c); | cond_sel(a->z, b->z, c->z, use_c); | ||||
| cond_sel(a->t, b->t, c->t, use_c); | cond_sel(a->t, b->t, c->t, use_c); | ||||
| } | } | ||||
| void decaf_448_scalar_cond_sel ( | |||||
| decaf_448_scalar_t out, | |||||
| const decaf_448_scalar_t a, | |||||
| const decaf_448_scalar_t b, | |||||
| decaf_bool_t pick_b | |||||
| ) { | |||||
| pick_b = ~word_is_zero(pick_b); | |||||
| int i; | |||||
| for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) { | |||||
| out->limb[i] = (a->limb[i] & ~pick_b) | (b->limb[i] & pick_b); | |||||
| } | |||||
| } | |||||
| /** {extra,accum} - sub +? p | /** {extra,accum} - sub +? p | ||||
| * Must have extra <= 1 | * Must have extra <= 1 | ||||
| */ | */ | ||||
| @@ -659,15 +677,19 @@ void decaf_448_point_scalarmul ( | |||||
| int i; | int i; | ||||
| for (i=DECAF_448_SCALAR_BITS &~ 1; i>0; i-=2) { | for (i=DECAF_448_SCALAR_BITS &~ 1; i>0; i-=2) { | ||||
| decaf_word_t bits = scalar->limb[i/WBITS]>>(i%WBITS); | decaf_word_t bits = scalar->limb[i/WBITS]>>(i%WBITS); | ||||
| decaf_448_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1); | |||||
| decaf_448_point_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1); | |||||
| decaf_448_point_double(w,w); | decaf_448_point_double(w,w); | ||||
| decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1); | decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1); | ||||
| decaf_448_point_double(w,w); | decaf_448_point_double(w,w); | ||||
| } | } | ||||
| decaf_448_point_add_sub(w,w,b,((scalar->limb[0]>>1)&1)-1); | decaf_448_point_add_sub(w,w,b,((scalar->limb[0]>>1)&1)-1); | ||||
| /* low bit is special because fo signed window */ | /* low bit is special because fo signed window */ | ||||
| decaf_448_cond_sel(tmp,b,decaf_448_point_identity,-(scalar->limb[0]&1)); | |||||
| decaf_448_point_cond_sel(tmp,b,decaf_448_point_identity,-(scalar->limb[0]&1)); | |||||
| decaf_448_point_sub(a,w,tmp); | decaf_448_point_sub(a,w,tmp); | ||||
| decaf_448_point_destroy(w); | |||||
| decaf_448_point_destroy(b3); | |||||
| decaf_448_point_destroy(tmp); | |||||
| } | } | ||||
| void decaf_448_point_double_scalarmul ( | void decaf_448_point_double_scalarmul ( | ||||
| @@ -693,20 +715,41 @@ void decaf_448_point_double_scalarmul ( | |||||
| for (i=DECAF_448_SCALAR_BITS &~ 1; i>0; i-=2) { | for (i=DECAF_448_SCALAR_BITS &~ 1; i>0; i-=2) { | ||||
| decaf_448_point_double(w,w); | decaf_448_point_double(w,w); | ||||
| decaf_word_t bits = scalarb->limb[i/WBITS]>>(i%WBITS); | decaf_word_t bits = scalarb->limb[i/WBITS]>>(i%WBITS); | ||||
| decaf_448_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1); | |||||
| decaf_448_point_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1); | |||||
| decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1); | decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1); | ||||
| bits = scalarc->limb[i/WBITS]>>(i%WBITS); | bits = scalarc->limb[i/WBITS]>>(i%WBITS); | ||||
| decaf_448_cond_sel(tmp,c,c3,((bits^(bits>>1))&1)-1); | |||||
| decaf_448_point_cond_sel(tmp,c,c3,((bits^(bits>>1))&1)-1); | |||||
| decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1); | decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1); | ||||
| decaf_448_point_double(w,w); | decaf_448_point_double(w,w); | ||||
| } | } | ||||
| decaf_448_point_add_sub(w,w,b,((scalarb->limb[0]>>1)&1)-1); | decaf_448_point_add_sub(w,w,b,((scalarb->limb[0]>>1)&1)-1); | ||||
| decaf_448_point_add_sub(w,w,c,((scalarc->limb[0]>>1)&1)-1); | decaf_448_point_add_sub(w,w,c,((scalarc->limb[0]>>1)&1)-1); | ||||
| /* low bit is special because of signed window */ | /* low bit is special because of signed window */ | ||||
| decaf_448_cond_sel(tmp,b,decaf_448_point_identity,-(scalarb->limb[0]&1)); | |||||
| decaf_448_point_cond_sel(tmp,b,decaf_448_point_identity,-(scalarb->limb[0]&1)); | |||||
| decaf_448_point_sub(w,w,tmp); | decaf_448_point_sub(w,w,tmp); | ||||
| decaf_448_cond_sel(tmp,c,decaf_448_point_identity,-(scalarc->limb[0]&1)); | |||||
| decaf_448_point_cond_sel(tmp,c,decaf_448_point_identity,-(scalarc->limb[0]&1)); | |||||
| decaf_448_point_sub(a,w,tmp); | decaf_448_point_sub(a,w,tmp); | ||||
| decaf_448_point_destroy(w); | |||||
| decaf_448_point_destroy(b3); | |||||
| decaf_448_point_destroy(c3); | |||||
| decaf_448_point_destroy(tmp); | |||||
| } | |||||
| void decaf_448_point_dual_scalarmul ( | |||||
| decaf_448_point_t a1, | |||||
| decaf_448_point_t a2, | |||||
| const decaf_448_point_t b, | |||||
| const decaf_448_scalar_t scalar1, | |||||
| const decaf_448_scalar_t scalar2 | |||||
| ) { | |||||
| /* Temporary point in case a1 aliases b */ | |||||
| decaf_448_point_t a1tmp; | |||||
| decaf_448_point_scalarmul(a1tmp, b, scalar1); | |||||
| decaf_448_point_scalarmul(a2, b, scalar2); | |||||
| decaf_448_point_copy(a1, a1tmp); | |||||
| decaf_448_point_destroy(a1tmp); | |||||
| } | } | ||||
| decaf_bool_t decaf_448_point_eq ( const decaf_448_point_t p, const decaf_448_point_t q ) { | decaf_bool_t decaf_448_point_eq ( const decaf_448_point_t p, const decaf_448_point_t q ) { | ||||
| @@ -946,6 +989,7 @@ decaf_bool_t decaf_448_direct_scalarmul ( | |||||
| if (short_circuit & ~succ) return succ; | if (short_circuit & ~succ) return succ; | ||||
| decaf_448_point_scalarmul(basep, basep, scalar); | decaf_448_point_scalarmul(basep, basep, scalar); | ||||
| decaf_448_point_encode(scaled, basep); | decaf_448_point_encode(scaled, basep); | ||||
| decaf_448_point_destroy(basep); | |||||
| return succ; | return succ; | ||||
| } | } | ||||