diff --git a/src/decaf_fast.c b/src/decaf_fast.c index b5562eb..5190f49 100644 --- a/src/decaf_fast.c +++ b/src/decaf_fast.c @@ -257,11 +257,7 @@ void API_NS(scalar_mul) ( } /* PERF: could implement this */ -static INLINE void -sc_montsqr ( - scalar_t out, - const scalar_t a -) { +static INLINE void sc_montsqr (scalar_t out, const scalar_t a) { sc_montmul(out,a,a); } @@ -269,77 +265,60 @@ decaf_bool_t API_NS(scalar_invert) ( scalar_t out, const scalar_t a ) { -#if 0 - /* FIELD MAGIC. TODO PERF: not updated for 25519 */ - scalar_t chain[7], tmp; - sc_montmul(chain[0],a,API_NS(sc_r2)); - - unsigned int i,j; - /* Addition chain generated by a not-too-clever SAGE script. First part: compute a^(2^222-1) */ - const struct { uint8_t widx, sidx, sct, midx; } muls [] = { - {2,0,1,0}, {3,2,1,0}, {4,3,1,0}, {5,4,1,0}, /* 0x3,7,f,1f */ - {1,5,1,0}, {1,1,3,3}, {6,1,9,1}, {1,6,1,0}, {6,1,18,6}, /* a^(2^37-1) */ - {1,6,37,6}, {1,1,37,6}, {1,1,111,1} /* a^(2^222-1) */ - }; - /* Second part: sliding window */ - const struct { uint8_t sct, midx; } muls1 [] = { - {6, 5}, {4, 2}, {3, 0}, {2, 0}, {4, 0}, {8, 5}, - {2, 0}, {5, 3}, {4, 0}, {4, 0}, {5, 3}, {3, 2}, - {3, 2}, {3, 2}, {2, 0}, {3, 0}, {4, 2}, {2, 0}, - {4, 3}, {3, 2}, {2, 0}, {3, 2}, {5, 2}, {3, 2}, - {2, 0}, {3, 0}, {7, 0}, {5, 0}, {3, 2}, {3, 2}, - {4, 2}, {5, 0}, {5, 3}, {3, 0}, {2, 0}, {5, 2}, - {4, 3}, {4, 0}, {3, 2}, {7, 4}, {2, 0}, {2, 0}, - {2, 0}, {2, 0}, {3, 0}, {5, 2}, {5, 4}, {5, 2}, - {5, 0}, {2, 0}, {3, 0}, {3, 0}, {2, 0}, {2, 0}, - {2, 0}, {3, 2}, {2, 0}, {3, 2}, {5, 0}, {4, 0}, - {6, 4}, {4, 0} - }; - - for (i=0; i 0) sc_montmul(precmp[LAST],precmp[0],precmp[0]); + + int i; + for (i=1; i<=LAST; i++) { + sc_montmul(precmp[i],precmp[i-1],precmp[LAST]); } - sc_montmul(out,chain[1],API_NS(scalar_one)); - for (i=0; i=0; i--) { - sc_montsqr(b,b); - - decaf_word_t w = sc_p->limb[i/WBITS]; - if (i=-SCALAR_WINDOW_BITS; i--) { + + if (started) sc_montsqr(out,out); + + decaf_word_t w = (i>=0) ? sc_p->limb[i/WBITS] : 0; + if (i >= 0 && i= 2); w-=2; } - if (1 & w>>(i%WBITS)) { - sc_montmul(b,b,ma); + + residue = (residue<<1) | ((w>>(i%WBITS))&1); + if (residue>>SCALAR_WINDOW_BITS != 0) { + assert(trailing == 0); + trailing = residue; + residue = 0; } + + if (trailing > 0 && (trailing & (1<>(SCALAR_WINDOW_BITS+1)]); + } else { + API_NS(scalar_copy)(out,precmp[trailing>>(SCALAR_WINDOW_BITS+1)]); + started = 1; + } + trailing = 0; + } + trailing <<= 1; + } - - sc_montmul(out,b,API_NS(scalar_one)); - API_NS(scalar_destroy)(b); - API_NS(scalar_destroy)(ma); + assert(residue==0); + assert(trailing==0); + + /* Demontgomerize */ + sc_montmul(out,out,API_NS(scalar_one)); + decaf_bzero(precmp, sizeof(precmp)); return ~API_NS(scalar_eq)(out,API_NS(scalar_zero)); -#endif } void API_NS(scalar_sub) (