/* Copyright (c) 2015 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ /** * @file decaf_precompute.c * @author Mike Hamburg * @brief Decaf global constant table precomputation. */ #define _XOPEN_SOURCE 600 /* for posix_memalign */ #include #include #include "field.h" #include "f_field.h" #include "decaf.h" #include "decaf_config.h" #define GEN_TABLES #include "curve_data.inc.c" /* To satisfy linker. */ const gf API_NS(precomputed_base_as_fe)[1]; 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(sc_r2) = {{{0}}}; const decaf_word_t API_NS(MONTGOMERY_FACTOR) = 0; const API_NS(point_t) API_NS(point_base); const uint8_t API_NS(x_base_point)[X_PUBLIC_BYTES] = {0}; struct niels_s; const gf_s *API_NS(precomputed_wnaf_as_fe); extern const size_t API_NS2(sizeof,precomputed_wnafs); void API_NS(precompute_wnafs) ( struct niels_s *out, const API_NS(point_t) base ); static void scalar_print(const char *name, const API_NS(scalar_t) sc) { /* UNIFY */ printf("const API_NS(scalar_t) %s = {{{\n", name); const int SCALAR_BYTES = (SCALAR_BITS + 7) / 8; unsigned char ser[SCALAR_BYTES]; API_NS(scalar_encode)(ser,sc); int b=0, i, comma=0; unsigned long long limb = 0; for (i=0; i>(8-b); } } printf("}}};\n\n"); } static void field_print(const gf f) { /* UNIFY */ unsigned char ser[SER_BYTES]; gf_serialize(ser,f); int b=0, i, comma=0; unsigned long long limb = 0; printf("{FIELD_LITERAL("); for (i=0; i= GF_LIT_LIMB_BITS || i == SER_BYTES-1) { limb &= (1ull<>(8-b); } } printf(")}"); assert(b<8); } int main(int argc, char **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 != DECAF_SUCCESS) return 1; API_NS(precomputed_s) *pre; ret = posix_memalign((void**)&pre, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_s)); if (ret || !pre) return 1; API_NS(precompute)(pre, real_point_base); struct niels_s *preWnaf; ret = posix_memalign((void**)&preWnaf, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_wnafs)); if (ret || !preWnaf) return 1; API_NS(precompute_wnafs)(preWnaf, real_point_base); const gf_s *output; unsigned i; printf("/** @warning: this file was automatically generated. */\n"); printf("#include \"field.h\"\n\n"); printf("#include \n\n"); printf("#define API_NS(_id) %s_##_id\n", API_NAME); printf("#define API_NS2(_pref,_id) _pref##_%s_##_id\n", API_NAME); output = (const gf_s *)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(gf)) { if (i) printf(",\n "); field_print(output++); } printf("\n}};\n"); output = (const gf_s *)pre; printf("const gf API_NS(precomputed_base_as_fe)[%d]\n", (int)(API_NS2(sizeof,precomputed_s) / sizeof(gf))); printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS2(alignof,precomputed_s)); for (i=0; i < API_NS2(sizeof,precomputed_s); i+=sizeof(gf)) { if (i) printf(",\n "); field_print(output++); } printf("\n};\n"); output = (const gf_s *)preWnaf; printf("const gf API_NS(precomputed_wnaf_as_fe)[%d]\n", (int)(API_NS2(sizeof,precomputed_wnafs) / sizeof(gf))); printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS2(alignof,precomputed_s)); for (i=0; i < API_NS2(sizeof,precomputed_wnafs); i+=sizeof(gf)) { if (i) printf(",\n "); field_print(output++); } printf("\n};\n"); API_NS(scalar_t) smadj; API_NS(scalar_copy)(smadj,API_NS(scalar_one)); for (i=0; ilimb[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 API_NS(MONTGOMERY_FACTOR) = (decaf_word_t)0x%016llxull;\n\n", w); /* Generate the Montgomery ladder version of the base point */ gf base1,base2; ret = gf_deserialize(base1,base_point_ser_for_pregen); if (ret != DECAF_SUCCESS) return 1; gf_sqr(base2,base1); uint8_t x_ser[X_PUBLIC_BYTES] = {0}; gf_serialize(x_ser, base2); printf("const uint8_t API_NS(x_base_point)[%d] = {", X_PUBLIC_BYTES); for (i=0; i