@@ -1,3 +1,8 @@ | |||||
from collections import namedtuple | |||||
comb_config = namedtuple("comb_config",["n","t","s"]) | |||||
wnaf_config = namedtuple("wnaf_config",["fixed","var"]) | |||||
field_data = { | field_data = { | ||||
"p25519" : { | "p25519" : { | ||||
"gf_desc" : "2^255 - 19", | "gf_desc" : "2^255 - 19", | ||||
@@ -22,7 +27,11 @@ curve_data = { | |||||
"scalar_bits" : 253, | "scalar_bits" : 253, | ||||
"d": -121665, | "d": -121665, | ||||
"trace": -0xa6f7cef517bce6b2c09318d2e7ae9f7a, | "trace": -0xa6f7cef517bce6b2c09318d2e7ae9f7a, | ||||
"mont_base": 9 | |||||
"mont_base": 9, | |||||
"combs":comb_config(3,5,17), | |||||
"wnaf":wnaf_config(5,3), | |||||
"window_bits":4 | |||||
}, | }, | ||||
"ed448goldilocks" : { | "ed448goldilocks" : { | ||||
"name" : "Ed448-Goldilocks", | "name" : "Ed448-Goldilocks", | ||||
@@ -31,7 +40,11 @@ curve_data = { | |||||
"scalar_bits" : 446, | "scalar_bits" : 446, | ||||
"d": -39081, | "d": -39081, | ||||
"trace": 0x10cd77058eec492d944a725bf7a4cf635c8e9c2ab721cf5b5529eec34, | "trace": 0x10cd77058eec492d944a725bf7a4cf635c8e9c2ab721cf5b5529eec34, | ||||
"mont_base": 5 | |||||
"mont_base": 5, | |||||
"combs":comb_config(5,5,18), | |||||
"wnaf":wnaf_config(5,3), | |||||
"window_bits":5 | |||||
} | } | ||||
} | } | ||||
@@ -1,50 +0,0 @@ | |||||
/** | |||||
* @file decaf_config.h | |||||
* @author Mike Hamburg | |||||
* | |||||
* @copyright | |||||
* Copyright (c) 2015 Cryptography Research, Inc. \n | |||||
* Released under the MIT License. See LICENSE.txt for license information. | |||||
* | |||||
* @brief Configuration for decaf_fast.c | |||||
*/ | |||||
#ifndef __DECAF_CONFIG_H__ | |||||
#define __DECAF_CONFIG_H__ 1 | |||||
/** | |||||
* Use the Montgomery ladder for direct scalarmul. | |||||
* | |||||
* The Montgomery ladder is faster than Edwards scalarmul, but providing | |||||
* the features Decaf supports (cofactor elimination, twist rejection) | |||||
* makes it complicated and adds code. Removing the ladder saves a few | |||||
* kilobytes at the cost of perhaps 5-10% overhead in direct scalarmul | |||||
* time. | |||||
*/ | |||||
#define DECAF_USE_MONTGOMERY_LADDER 0 /* FUTURE */ | |||||
/** The number of comb tables for fixed base scalarmul. */ | |||||
#define DECAF_COMBS_N 3 | |||||
/** The number of teeth per comb for fixed base scalarmul. */ | |||||
#define DECAF_COMBS_T 5 | |||||
/** The comb spacing fixed base scalarmul. */ | |||||
#define DECAF_COMBS_S 17 | |||||
/** Performance tuning: the width of the fixed window for scalar mul. */ | |||||
#define DECAF_WINDOW_BITS 4 | |||||
/** | |||||
* The number of bits used for the precomputed table in variable-time | |||||
* double scalarmul. | |||||
*/ | |||||
#define DECAF_WNAF_FIXED_TABLE_BITS 5 | |||||
/** | |||||
* Performance tuning: bits used for the variable table in variable-time | |||||
* double scalarmul. | |||||
*/ | |||||
#define DECAF_WNAF_VAR_TABLE_BITS 3 | |||||
#endif /* __DECAF_CONFIG_H__ */ |
@@ -1,50 +0,0 @@ | |||||
/** | |||||
* @file decaf_config.h | |||||
* @author Mike Hamburg | |||||
* | |||||
* @copyright | |||||
* Copyright (c) 2015 Cryptography Research, Inc. \n | |||||
* Released under the MIT License. See LICENSE.txt for license information. | |||||
* | |||||
* @brief Configuration for decaf_fast.c | |||||
*/ | |||||
#ifndef __DECAF_CONFIG_H__ | |||||
#define __DECAF_CONFIG_H__ 1 | |||||
/** | |||||
* Use the Montgomery ladder for direct scalarmul. | |||||
* | |||||
* The Montgomery ladder is faster than Edwards scalarmul, but providing | |||||
* the features Decaf supports (cofactor elimination, twist rejection) | |||||
* makes it complicated and adds code. Removing the ladder saves a few | |||||
* kilobytes at the cost of perhaps 5-10% overhead in direct scalarmul | |||||
* time. | |||||
*/ | |||||
#define DECAF_USE_MONTGOMERY_LADDER 1 | |||||
/** The number of comb tables for fixed base scalarmul. */ | |||||
#define DECAF_COMBS_N 5 | |||||
/** The number of teeth per comb for fixed base scalarmul. */ | |||||
#define DECAF_COMBS_T 5 | |||||
/** The comb spacing fixed base scalarmul. */ | |||||
#define DECAF_COMBS_S 18 | |||||
/** Performance tuning: the width of the fixed window for scalar mul. */ | |||||
#define DECAF_WINDOW_BITS 5 | |||||
/** | |||||
* The number of bits used for the precomputed table in variable-time | |||||
* double scalarmul. | |||||
*/ | |||||
#define DECAF_WNAF_FIXED_TABLE_BITS 5 | |||||
/** | |||||
* Performance tuning: bits used for the variable table in variable-time | |||||
* double scalarmul. | |||||
*/ | |||||
#define DECAF_WNAF_VAR_TABLE_BITS 3 | |||||
#endif /* __DECAF_CONFIG_H__ */ |
@@ -6,7 +6,6 @@ | |||||
#include "word.h" | #include "word.h" | ||||
#include "field.h" | #include "field.h" | ||||
#include "decaf_config.h" | |||||
#include <decaf.h> | #include <decaf.h> | ||||
@@ -20,19 +19,38 @@ | |||||
#define IMAGINE_TWIST $(imagine_twist) | #define IMAGINE_TWIST $(imagine_twist) | ||||
#define COFACTOR $(cofactor) | #define COFACTOR $(cofactor) | ||||
/** Comb config: number of combs, n, t, s. */ | |||||
#define COMBS_N $(combs.n) | |||||
#define COMBS_T $(combs.t) | |||||
#define COMBS_S $(combs.s) | |||||
#define DECAF_WINDOW_BITS $(window_bits) | |||||
#define DECAF_WNAF_FIXED_TABLE_BITS $(wnaf.fixed) | |||||
#define DECAF_WNAF_VAR_TABLE_BITS $(wnaf.var) | |||||
static const int EDWARDS_D = $(d); | static const int EDWARDS_D = $(d); | ||||
static const scalar_t sc_p = {{{ $(ser(q,64,"SC_LIMB")) }}}; | |||||
static const scalar_t sc_r2 = {{{ $(ser(((2**128)**((scalar_bits+63)/64))%q,64,"SC_LIMB")) }}}; | |||||
extern const scalar_t API_NS(point_scalarmul_adjustment); /* TODO: auto template these too. */ | |||||
extern const scalar_t API_NS(precomputed_scalarmul_adjustment); | |||||
static const scalar_t sc_p = {{{ | |||||
$(ser(q,64,"SC_LIMB")) | |||||
}}}, sc_r2 = {{{ | |||||
$(ser(((2**128)**((scalar_bits+63)/64))%q,64,"SC_LIMB")) | |||||
}}}, point_scalarmul_adjustment = {{{ | |||||
$(ser((2**(scalar_bits-1+window_bits - ((scalar_bits-1)%window_bits)) - 1) % q,64,"SC_LIMB")) | |||||
}}}, precomputed_scalarmul_adjustment = {{{ | |||||
$(ser((2**(combs.n*combs.t*combs.s) - 1) % q,64,"SC_LIMB")) | |||||
}}}; | |||||
static const decaf_word_t MONTGOMERY_FACTOR = (decaf_word_t)0x$("%x" % pow(-q,2**64-1,2**64))ull; | static const decaf_word_t MONTGOMERY_FACTOR = (decaf_word_t)0x$("%x" % pow(-q,2**64-1,2**64))ull; | ||||
const uint8_t API_NS(x_base_point)[SER_BYTES] /* TODO */ = { | |||||
$(ser(mont_base,8)) | |||||
}; | |||||
#if COFACTOR==8 | #if COFACTOR==8 | ||||
static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( | static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( | ||||
$(sqrt_one_minus_d) | $(sqrt_one_minus_d) | ||||
)}; | )}; | ||||
#endif | #endif | ||||
/* End of template stuff */ | |||||
#if (COFACTOR == 8) && !IMAGINE_TWIST | #if (COFACTOR == 8) && !IMAGINE_TWIST | ||||
/* FUTURE: Curve41417 doesn't have these properties. */ | /* FUTURE: Curve41417 doesn't have these properties. */ | ||||
@@ -62,7 +80,7 @@ typedef struct { niels_t n; gf z; } __attribute__((aligned(sizeof(big_register_t | |||||
pniels_s, pniels_t[1]; | pniels_s, pniels_t[1]; | ||||
/* Precomputed base */ | /* Precomputed base */ | ||||
struct precomputed_s { niels_t table [DECAF_COMBS_N<<(DECAF_COMBS_T-1)]; }; | |||||
struct precomputed_s { niels_t table [COMBS_N<<(COMBS_T-1)]; }; | |||||
extern const gf API_NS(precomputed_base_as_fe)[]; | extern const gf API_NS(precomputed_base_as_fe)[]; | ||||
const precomputed_s *API_NS(precomputed_base) = | const precomputed_s *API_NS(precomputed_base) = | ||||
@@ -916,7 +934,7 @@ void API_NS(point_scalarmul) ( | |||||
NTABLE = 1<<(WINDOW-1); | NTABLE = 1<<(WINDOW-1); | ||||
scalar_t scalar1x; | scalar_t scalar1x; | ||||
API_NS(scalar_add)(scalar1x, scalar, API_NS(point_scalarmul_adjustment)); | |||||
API_NS(scalar_add)(scalar1x, scalar, point_scalarmul_adjustment); | |||||
sc_halve(scalar1x,scalar1x,sc_p); | sc_halve(scalar1x,scalar1x,sc_p); | ||||
/* Set up a precomputed table with odd multiples of b. */ | /* Set up a precomputed table with odd multiples of b. */ | ||||
@@ -978,9 +996,9 @@ void API_NS(point_double_scalarmul) ( | |||||
NTABLE = 1<<(WINDOW-1); | NTABLE = 1<<(WINDOW-1); | ||||
scalar_t scalar1x, scalar2x; | scalar_t scalar1x, scalar2x; | ||||
API_NS(scalar_add)(scalar1x, scalarb, API_NS(point_scalarmul_adjustment)); | |||||
API_NS(scalar_add)(scalar1x, scalarb, point_scalarmul_adjustment); | |||||
sc_halve(scalar1x,scalar1x,sc_p); | sc_halve(scalar1x,scalar1x,sc_p); | ||||
API_NS(scalar_add)(scalar2x, scalarc, API_NS(point_scalarmul_adjustment)); | |||||
API_NS(scalar_add)(scalar2x, scalarc, point_scalarmul_adjustment); | |||||
sc_halve(scalar2x,scalar2x,sc_p); | sc_halve(scalar2x,scalar2x,sc_p); | ||||
/* Set up a precomputed table with odd multiples of b. */ | /* Set up a precomputed table with odd multiples of b. */ | ||||
@@ -1054,9 +1072,9 @@ void API_NS(point_dual_scalarmul) ( | |||||
NTABLE = 1<<(WINDOW-1); | NTABLE = 1<<(WINDOW-1); | ||||
scalar_t scalar1x, scalar2x; | scalar_t scalar1x, scalar2x; | ||||
API_NS(scalar_add)(scalar1x, scalar1, API_NS(point_scalarmul_adjustment)); | |||||
API_NS(scalar_add)(scalar1x, scalar1, point_scalarmul_adjustment); | |||||
sc_halve(scalar1x,scalar1x,sc_p); | sc_halve(scalar1x,scalar1x,sc_p); | ||||
API_NS(scalar_add)(scalar2x, scalar2, API_NS(point_scalarmul_adjustment)); | |||||
API_NS(scalar_add)(scalar2x, scalar2, point_scalarmul_adjustment); | |||||
sc_halve(scalar2x,scalar2x,sc_p); | sc_halve(scalar2x,scalar2x,sc_p); | ||||
/* Set up a precomputed table with odd multiples of b. */ | /* Set up a precomputed table with odd multiples of b. */ | ||||
@@ -1417,7 +1435,7 @@ void API_NS(precompute) ( | |||||
precomputed_s *table, | precomputed_s *table, | ||||
const point_t base | const point_t base | ||||
) { | ) { | ||||
const unsigned int n = DECAF_COMBS_N, t = DECAF_COMBS_T, s = DECAF_COMBS_S; | |||||
const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S; | |||||
assert(n*t*s >= SCALAR_BITS); | assert(n*t*s >= SCALAR_BITS); | ||||
point_t working, start, doubles[t-1]; | point_t working, start, doubles[t-1]; | ||||
@@ -1495,10 +1513,10 @@ void API_NS(precomputed_scalarmul) ( | |||||
) { | ) { | ||||
int i; | int i; | ||||
unsigned j,k; | unsigned j,k; | ||||
const unsigned int n = DECAF_COMBS_N, t = DECAF_COMBS_T, s = DECAF_COMBS_S; | |||||
const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S; | |||||
scalar_t scalar1x; | scalar_t scalar1x; | ||||
API_NS(scalar_add)(scalar1x, scalar, API_NS(precomputed_scalarmul_adjustment)); | |||||
API_NS(scalar_add)(scalar1x, scalar, precomputed_scalarmul_adjustment); | |||||
sc_halve(scalar1x,scalar1x,sc_p); | sc_halve(scalar1x,scalar1x,sc_p); | ||||
niels_t ni; | niels_t ni; | ||||
@@ -7,21 +7,15 @@ | |||||
#include "field.h" | #include "field.h" | ||||
#include "f_field.h" | #include "f_field.h" | ||||
#include "decaf.h" | #include "decaf.h" | ||||
#include "decaf_config.h" | |||||
#define API_NS(_id) $(c_ns)_##_id | #define API_NS(_id) $(c_ns)_##_id | ||||
#define SCALAR_BITS $(C_NS)_SCALAR_BITS | |||||
static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { | static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { | ||||
$(decaf_base) | $(decaf_base) | ||||
}; | }; | ||||
/* To satisfy linker. */ | /* To satisfy linker. */ | ||||
const gf API_NS(precomputed_base_as_fe)[1]; | 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(point_t) API_NS(point_base); | const API_NS(point_t) API_NS(point_base); | ||||
const uint8_t API_NS(x_base_point)[X_PUBLIC_BYTES] = {0}; | |||||
struct niels_s; | struct niels_s; | ||||
const gf_s *API_NS(precomputed_wnaf_as_fe); | const gf_s *API_NS(precomputed_wnaf_as_fe); | ||||
@@ -31,28 +25,6 @@ void API_NS(precompute_wnafs) ( | |||||
struct niels_s *out, | struct niels_s *out, | ||||
const API_NS(point_t) base | 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<SCALAR_BYTES; i++) { | |||||
limb |= ((uint64_t)ser[i])<<b; | |||||
b += 8; | |||||
if (b == 64 || i==SCALAR_BYTES-1) { | |||||
b = 0; | |||||
if (comma) printf(","); | |||||
comma = 1; | |||||
printf("SC_LIMB(0x%016llx)", limb); | |||||
limb = ((uint64_t)ser[i])>>(8-b); | |||||
} | |||||
} | |||||
printf("}}};\n\n"); | |||||
} | |||||
static void field_print(const gf f) { /* UNIFY */ | static void field_print(const gf f) { /* UNIFY */ | ||||
unsigned char ser[SER_BYTES]; | unsigned char ser[SER_BYTES]; | ||||
gf_serialize(ser,f); | gf_serialize(ser,f); | ||||
@@ -129,38 +101,5 @@ int main(int argc, char **argv) { | |||||
} | } | ||||
printf("\n};\n"); | printf("\n};\n"); | ||||
API_NS(scalar_t) smadj; | |||||
API_NS(scalar_copy)(smadj,API_NS(scalar_one)); | |||||
for (i=0; i<DECAF_COMBS_N*DECAF_COMBS_T*DECAF_COMBS_S; i++) { | |||||
API_NS(scalar_add)(smadj,smadj,smadj); | |||||
} | |||||
API_NS(scalar_sub)(smadj, smadj, API_NS(scalar_one)); | |||||
scalar_print("API_NS(precomputed_scalarmul_adjustment)", smadj); | |||||
API_NS(scalar_copy)(smadj,API_NS(scalar_one)); | |||||
for (i=0; i<SCALAR_BITS-1 + DECAF_WINDOW_BITS | |||||
- ((SCALAR_BITS-1) % DECAF_WINDOW_BITS); i++) { | |||||
API_NS(scalar_add)(smadj,smadj,smadj); | |||||
} | |||||
API_NS(scalar_sub)(smadj, smadj, API_NS(scalar_one)); | |||||
scalar_print("API_NS(point_scalarmul_adjustment)", smadj); | |||||
API_NS(scalar_sub)(smadj,API_NS(scalar_zero),API_NS(scalar_one)); /* get p-1 */ | |||||
/* 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<X_PUBLIC_BYTES; i++) { | |||||
printf("%s%s%d",i?",":"",(i%32==0)?"\n ":"",x_ser[i]); | |||||
} | |||||
printf("\n};\n"); | |||||
return 0; | return 0; | ||||
} | } |