@@ -67,24 +67,20 @@ static const decaf_448_scalar_t decaf_448_scalar_r2 = {{{ | |||||
static const decaf_word_t DECAF_MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull); | static const decaf_word_t DECAF_MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull); | ||||
/** base = twist of Goldilocks base point (~,19). */ | |||||
#define FIELD_LITERAL(a,b,c,d,e,f,g,h) {{LIMB(a),LIMB(b),LIMB(c),LIMB(d),LIMB(e),LIMB(f),LIMB(g),LIMB(h)}} | |||||
const decaf_448_point_t decaf_448_point_base = {{ | const decaf_448_point_t decaf_448_point_base = {{ | ||||
{{{ LIMB(0xb39a2d57e08c7b),LIMB(0xb38639c75ff281), | |||||
LIMB(0x2ec981082b3288),LIMB(0x99fe8607e5237c), | |||||
LIMB(0x0e33fbb1fadd1f),LIMB(0xe714f67055eb4a), | |||||
LIMB(0xc9ae06d64067dd),LIMB(0xf7be45054760fa) }}}, | |||||
{{{ LIMB(0xbd8715f551617f),LIMB(0x8c17fbeca8f5fc), | |||||
LIMB(0xaae0eec209c06f),LIMB(0xce41ad80cbe6b8), | |||||
LIMB(0xdf360b5c828c00),LIMB(0xaf25b6bbb40e3b), | |||||
LIMB(0x8ed37f0ce4ed31),LIMB(0x72a1c3214557b9) }}}, | |||||
{{{ 1 }}}, | |||||
{{{ LIMB(0x97ca9c8ed8bde9),LIMB(0xf0b780da83304c), | |||||
LIMB(0x0d79c0a7729a69),LIMB(0xc18d3f24aebc1c), | |||||
LIMB(0x1fbb5389b3fda5),LIMB(0xbb24f674635948), | |||||
LIMB(0x723a55709a3983),LIMB(0xe1c0107a823dd4) }}} | |||||
{FIELD_LITERAL(0x00fffffffffffffe,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff, | |||||
0x0000000000000003,0x0000000000000000,0x0000000000000000,0x0000000000000000)}, | |||||
{FIELD_LITERAL(0x0081e6d37f752992,0x003078ead1c28721,0x00135cfd2394666c,0x0041149c50506061, | |||||
0x0031d30e4f5490b3,0x00902014990dc141,0x0052341b04c1e328,0x0014237853c10a1b)}, | |||||
{FIELD_LITERAL(0x00fffffffffffffb,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff, | |||||
0x00fffffffffffffe,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff)}, | |||||
{FIELD_LITERAL(0x008f205b70660415,0x00881c60cfd3824f,0x00377a638d08500d,0x008c66d5d4672615, | |||||
0x00e52fa558e08e13,0x0087770ae1b6983d,0x004388f55a0aa7ff,0x00b4d9a785cf1a91)} | |||||
}}; | }}; | ||||
struct decaf_448_precomputed_s { decaf_448_point_t p[1]; }; | struct decaf_448_precomputed_s { decaf_448_point_t p[1]; }; | ||||
/* FIXME: restore */ | /* FIXME: restore */ | ||||
@@ -56,50 +56,17 @@ static const scalar_t sc_p = {{{ | |||||
SC_LIMB(0xffffffffffffffff), | SC_LIMB(0xffffffffffffffff), | ||||
SC_LIMB(0x3fffffffffffffff) | SC_LIMB(0x3fffffffffffffff) | ||||
}}}; | }}}; | ||||
const scalar_t API_NS(scalar_one) = {{{1}}}, API_NS(scalar_zero) = {{{0}}}; | |||||
static const scalar_t sc_r2 = {{{ | |||||
SC_LIMB(0xe3539257049b9b60), | |||||
SC_LIMB(0x7af32c4bc1b195d9), | |||||
SC_LIMB(0x0d66de2388ea1859), | |||||
SC_LIMB(0xae17cf725ee4d838), | |||||
SC_LIMB(0x1a9cc14ba3c47c44), | |||||
SC_LIMB(0x2052bcb7e4d070af), | |||||
SC_LIMB(0x3402a939f823b729) | |||||
}}}; | |||||
const scalar_t API_NS(scalar_one) = {{{1}}}, API_NS(scalar_zero) = {{{0}}}; | |||||
extern const scalar_t sc_r2; | |||||
extern const decaf_word_t MONTGOMERY_FACTOR; | |||||
static const scalar_t sc_r1 = {{{ | |||||
SC_LIMB(0x721cf5b5529eec34), | |||||
SC_LIMB(0x7a4cf635c8e9c2ab), | |||||
SC_LIMB(0xeec492d944a725bf), | |||||
SC_LIMB(0x000000020cd77058), | |||||
SC_LIMB(0), | |||||
SC_LIMB(0), | |||||
SC_LIMB(0) | |||||
}}}; | |||||
/* sqrt(5) = 2phi-1 from the curve spec. Not exported, but used by pregen tool. */ | |||||
const unsigned char base_point_ser_for_pregen[SER_BYTES] = { | |||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1 | |||||
}; | |||||
static const decaf_word_t MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull); | |||||
/** base = twist of Goldilocks base point (~,19). */ | |||||
const point_t API_NS(point_base) = {{ | |||||
{ FIELD_LITERAL( | |||||
0xb39a2d57e08c7b,0xb38639c75ff281, | |||||
0x2ec981082b3288,0x99fe8607e5237c, | |||||
0x0e33fbb1fadd1f,0xe714f67055eb4a, | |||||
0xc9ae06d64067dd,0xf7be45054760fa )}, | |||||
{ FIELD_LITERAL( | |||||
0xbd8715f551617f,0x8c17fbeca8f5fc, | |||||
0xaae0eec209c06f,0xce41ad80cbe6b8, | |||||
0xdf360b5c828c00,0xaf25b6bbb40e3b, | |||||
0x8ed37f0ce4ed31,0x72a1c3214557b9 )}, | |||||
{{{ 1 }}}, | |||||
{ FIELD_LITERAL( | |||||
0x97ca9c8ed8bde9,0xf0b780da83304c, | |||||
0x0d79c0a7729a69,0xc18d3f24aebc1c, | |||||
0x1fbb5389b3fda5,0xbb24f674635948, | |||||
0x723a55709a3983,0xe1c0107a823dd4 )} | |||||
}}; | |||||
extern const point_t API_NS(point_base); | |||||
/* Projective Niels coordinates */ | /* Projective Niels coordinates */ | ||||
typedef struct { gf a, b, c; } niels_s, niels_t[1]; | typedef struct { gf a, b, c; } niels_s, niels_t[1]; | ||||
@@ -651,7 +618,7 @@ decaf_bool_t API_NS(scalar_decode)( | |||||
accum = (accum + s->limb[i] - sc_p->limb[i]) >> WBITS; | accum = (accum + s->limb[i] - sc_p->limb[i]) >> WBITS; | ||||
} | } | ||||
sc_montmul(s,s,sc_r1); /* ham-handed reduce */ | |||||
API_NS(scalar_mul)(s,s,API_NS(scalar_one)); /* ham-handed reduce */ | |||||
return accum; | return accum; | ||||
} | } | ||||
@@ -706,7 +673,7 @@ void API_NS(scalar_decode_long)( | |||||
if (ser_len == sizeof(scalar_t)) { | if (ser_len == sizeof(scalar_t)) { | ||||
assert(i==0); | assert(i==0); | ||||
/* ham-handed reduce */ | /* ham-handed reduce */ | ||||
sc_montmul(s,t1,sc_r1); | |||||
API_NS(scalar_mul)(s,t1,API_NS(scalar_one)); | |||||
API_NS(scalar_destroy)(t1); | API_NS(scalar_destroy)(t1); | ||||
return; | return; | ||||
} | } | ||||
@@ -22,6 +22,11 @@ | |||||
const field_t API_NS(precomputed_base_as_fe)[1]; | const field_t API_NS(precomputed_base_as_fe)[1]; | ||||
const API_NS(scalar_t) API_NS(precomputed_scalarmul_adjustment); | const API_NS(scalar_t) API_NS(precomputed_scalarmul_adjustment); | ||||
const API_NS(scalar_t) API_NS(point_scalarmul_adjustment); | const API_NS(scalar_t) API_NS(point_scalarmul_adjustment); | ||||
const API_NS(scalar_t) sc_r2 = {{{0}}}; | |||||
const decaf_word_t MONTGOMERY_FACTOR = 0; | |||||
const unsigned char base_point_ser_for_pregen[DECAF_448_SER_BYTES]; | |||||
const API_NS(point_t) API_NS(point_base); | |||||
struct niels_s; | struct niels_s; | ||||
const field_t *API_NS(precomputed_wnaf_as_fe); | const field_t *API_NS(precomputed_wnaf_as_fe); | ||||
@@ -32,6 +37,7 @@ void API_NS(precompute_wnafs) ( | |||||
const API_NS(point_t) base | const API_NS(point_t) base | ||||
); | ); | ||||
/* TODO: use SC_LIMB? */ | |||||
static void scalar_print(const char *name, const API_NS(scalar_t) sc) { | static void scalar_print(const char *name, const API_NS(scalar_t) sc) { | ||||
printf("const API_NS(scalar_t) %s = {{{\n", name); | printf("const API_NS(scalar_t) %s = {{{\n", name); | ||||
unsigned i; | unsigned i; | ||||
@@ -68,17 +74,21 @@ static void field_print(const field_t *f) { | |||||
int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||
(void)argc; (void)argv; | (void)argc; (void)argv; | ||||
API_NS(point_t) real_point_base; | |||||
int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0); | |||||
if (!ret) return 1; | |||||
API_NS(precomputed_s) *pre; | API_NS(precomputed_s) *pre; | ||||
int ret = posix_memalign((void**)&pre, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_s)); | |||||
ret = posix_memalign((void**)&pre, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_s)); | |||||
if (ret || !pre) return 1; | if (ret || !pre) return 1; | ||||
API_NS(precompute)(pre, API_NS(point_base)); | |||||
API_NS(precompute)(pre, real_point_base); | |||||
struct niels_s *preWnaf; | struct niels_s *preWnaf; | ||||
ret = posix_memalign((void**)&preWnaf, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_wnafs)); | ret = posix_memalign((void**)&preWnaf, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_wnafs)); | ||||
if (ret || !preWnaf) return 1; | if (ret || !preWnaf) return 1; | ||||
API_NS(precompute_wnafs)(preWnaf, API_NS(point_base)); | |||||
API_NS(precompute_wnafs)(preWnaf, real_point_base); | |||||
const field_t *output = (const field_t *)pre; | |||||
const field_t *output; | |||||
unsigned i; | unsigned i; | ||||
printf("/** @warning: this file was automatically generated. */\n"); | printf("/** @warning: this file was automatically generated. */\n"); | ||||
@@ -86,6 +96,18 @@ int main(int argc, char **argv) { | |||||
printf("#include \"decaf.h\"\n\n"); | printf("#include \"decaf.h\"\n\n"); | ||||
printf("#define API_NS(_id) decaf_448_##_id\n"); | printf("#define API_NS(_id) decaf_448_##_id\n"); | ||||
printf("#define API_NS2(_pref,_id) _pref##_decaf_448_##_id\n"); | printf("#define API_NS2(_pref,_id) _pref##_decaf_448_##_id\n"); | ||||
output = (const field_t *)real_point_base; | |||||
printf("const API_NS(point_t) API_NS(point_base) = {{\n"); | |||||
for (i=0; i < sizeof(API_NS(point_t)); i+=sizeof(field_t)) { | |||||
if (i) printf(",\n "); | |||||
printf("{"); | |||||
field_print(output++); | |||||
printf("}"); | |||||
} | |||||
printf("\n}};\n"); | |||||
output = (const field_t *)pre; | |||||
printf("const field_t API_NS(precomputed_base_as_fe)[%d]\n", | printf("const field_t API_NS(precomputed_base_as_fe)[%d]\n", | ||||
(int)(API_NS2(sizeof,precomputed_s) / sizeof(field_t))); | (int)(API_NS2(sizeof,precomputed_s) / sizeof(field_t))); | ||||
printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS2(alignof,precomputed_s)); | printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS2(alignof,precomputed_s)); | ||||
@@ -123,5 +145,22 @@ int main(int argc, char **argv) { | |||||
API_NS(scalar_sub)(smadj, smadj, API_NS(scalar_one)); | API_NS(scalar_sub)(smadj, smadj, API_NS(scalar_one)); | ||||
scalar_print("API_NS(point_scalarmul_adjustment)", smadj); | scalar_print("API_NS(point_scalarmul_adjustment)", smadj); | ||||
API_NS(scalar_copy)(smadj,API_NS(scalar_one)); | |||||
for (i=0; i<sizeof(API_NS(scalar_t))*8*2; i++) { | |||||
API_NS(scalar_add)(smadj,smadj,smadj); | |||||
} | |||||
scalar_print("sc_r2", smadj); | |||||
API_NS(scalar_sub)(smadj,API_NS(scalar_zero),API_NS(scalar_one)); /* HACK */ | |||||
unsigned long long w = 1, plo = smadj->limb[0]+1; | |||||
#if DECAF_WORD_BITS == 32 | |||||
plo |= ((unsigned long long)smadj->limb[1]) << 32; | |||||
#endif | |||||
for (i=0; i<6; i++) { | |||||
w *= w*plo + 2; | |||||
} | |||||
printf("const decaf_word_t MONTGOMERY_FACTOR = (decaf_word_t)0x%016llxull;\n\n", w); | |||||
return 0; | return 0; | ||||
} | } |