@@ -78,7 +78,7 @@ GEN_HEADERS=\ | |||
HEADERS= Makefile $(shell find src test -name "*.h") $(BUILD_OBJ)/timestamp $(GEN_HEADERS) | |||
# components needed by the lib | |||
LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/decaf_crypto_ed25519.o $(BUILD_OBJ)/decaf_crypto_ed448goldilocks.o # and per-field components | |||
LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/decaf_crypto_curve25519.o $(BUILD_OBJ)/decaf_crypto_ed448goldilocks.o # and per-field components | |||
BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o | |||
@@ -167,24 +167,24 @@ $$(BUILD_C)/decaf_tables_$(1).c: $$(BUILD_IBIN)/decaf_gen_tables_$(1) | |||
$$(BUILD_ASM)/decaf_tables_$(1).s: $$(BUILD_C)/decaf_tables_$(1).c $$(HEADERS) | |||
$$(CC) $$(CFLAGS) -S -c -o $$@ $$< \ | |||
-I src/curve_$(1)/ -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) -I src/include/$$(ARCH_FOR_$(2)) \ | |||
-I build/obj/curve_$(1)/ -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) -I src/include/$$(ARCH_FOR_$(2)) \ | |||
-I $(BUILD_H)/curve_$(1) -I $(BUILD_H)/$(2) -I $(BUILD_H)/$(2)/$$(ARCH_FOR_$(2)) | |||
$$(BUILD_ASM)/decaf_gen_tables_$(1).s: src/decaf_gen_tables.c $$(HEADERS) | |||
$$(CC) $$(CFLAGS) \ | |||
-I src/curve_$(1) -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) -I src/include/$$(ARCH_FOR_$(2)) \ | |||
-I build/obj/curve_$(1) -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) -I src/include/$$(ARCH_FOR_$(2)) \ | |||
-I $(BUILD_H)/curve_$(1) -I $(BUILD_H)/$(2) -I $(BUILD_H)/$(2)/$$(ARCH_FOR_$(2)) \ | |||
-S -c -o $$@ $$< | |||
$$(BUILD_ASM)/decaf_$(1).s: src/decaf.c $$(HEADERS) | |||
$$(CC) $$(CFLAGS) \ | |||
-I src/curve_$(1)/ -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) -I src/include/$$(ARCH_FOR_$(2)) \ | |||
-I build/obj/curve_$(1)/ -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) -I src/include/$$(ARCH_FOR_$(2)) \ | |||
-I $(BUILD_H)/curve_$(1) -I $(BUILD_H)/$(2) -I $(BUILD_H)/$(2)/$$(ARCH_FOR_$(2)) \ | |||
-S -c -o $$@ $$< | |||
$$(BUILD_ASM)/decaf_crypto_$(1).s: src/decaf_crypto.c $$(HEADERS) | |||
$$(CC) $$(CFLAGS) \ | |||
-I src/curve_$(1)/ -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) -I src/include/$$(ARCH_FOR_$(2)) \ | |||
-I build/obj/curve_$(1)/ -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) -I src/include/$$(ARCH_FOR_$(2)) \ | |||
-I $(BUILD_H)/curve_$(1) -I $(BUILD_H)/$(2) -I $(BUILD_H)/$(2)/$$(ARCH_FOR_$(2)) \ | |||
-S -c -o $$@ $$< | |||
@@ -194,7 +194,7 @@ endef | |||
################################################################ | |||
# call code above to generate curves and fields | |||
$(eval $(call define_field,p25519,arch_x86_64)) | |||
$(eval $(call define_curve,ed25519,p25519)) | |||
$(eval $(call define_curve,curve25519,p25519)) | |||
$(eval $(call define_field,p448,arch_x86_64)) | |||
$(eval $(call define_curve,ed448goldilocks,p448)) | |||
@@ -1,40 +0,0 @@ | |||
#define API_NAME "decaf_255" | |||
#define API_NS(_id) decaf_255_##_id | |||
#define API_NS2(_pref,_id) _pref##_decaf_255_##_id | |||
#define SCALAR_LIMBS DECAF_255_SCALAR_LIMBS | |||
#define SCALAR_BITS DECAF_255_SCALAR_BITS | |||
#define scalar_t decaf_255_scalar_t | |||
#define point_t decaf_255_point_t | |||
#define precomputed_s decaf_255_precomputed_s | |||
#define IMAGINE_TWIST 1 | |||
#define P_MOD_8 5 | |||
#define COFACTOR 8 | |||
#ifndef DECAF_JUST_API | |||
static const int EDWARDS_D = -121665; | |||
static const scalar_t sc_p = {{{ | |||
SC_LIMB(0x5812631a5cf5d3ed), | |||
SC_LIMB(0x14def9dea2f79cd6), | |||
SC_LIMB(0), | |||
SC_LIMB(0x1000000000000000) | |||
}}}; | |||
#ifdef GEN_TABLES | |||
/* sqrt(9) = 3 from the curve spec. Not exported, but used by pregen tool. */ | |||
static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { | |||
3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |||
}; | |||
#endif | |||
static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( | |||
0x6db8831bbddec, | |||
0x38d7b56c9c165, | |||
0x016b221394bdc, | |||
0x7540f7816214a, | |||
0x0a0d85b4032b1 | |||
)}; | |||
#endif /* DECAF_JUST_API */ |
@@ -1,34 +0,0 @@ | |||
#define API_NAME "decaf_448" | |||
#define API_NS(_id) decaf_448_##_id | |||
#define API_NS2(_pref,_id) _pref##_decaf_448_##_id | |||
#define SCALAR_LIMBS DECAF_448_SCALAR_LIMBS | |||
#define SCALAR_BITS DECAF_448_SCALAR_BITS | |||
#define scalar_t decaf_448_scalar_t | |||
#define point_t decaf_448_point_t | |||
#define precomputed_s decaf_448_precomputed_s | |||
#define IMAGINE_TWIST 0 | |||
#define P_MOD_8 7 | |||
#define COFACTOR 4 | |||
#ifndef DECAF_JUST_API | |||
static const int EDWARDS_D = -39081; | |||
static const scalar_t sc_p = {{{ | |||
SC_LIMB(0x2378c292ab5844f3), | |||
SC_LIMB(0x216cc2728dc58f55), | |||
SC_LIMB(0xc44edb49aed63690), | |||
SC_LIMB(0xffffffff7cca23e9), | |||
SC_LIMB(0xffffffffffffffff), | |||
SC_LIMB(0xffffffffffffffff), | |||
SC_LIMB(0x3fffffffffffffff) | |||
}}}; | |||
#ifdef GEN_TABLES | |||
/* sqrt(5) = 2phi-1 from the curve spec. Not exported, but used by pregen tool. */ | |||
static 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 | |||
}; | |||
#endif | |||
#endif /* DECAF_JUST_API */ |
@@ -19,16 +19,50 @@ curve_data = { | |||
"name" : "Iso-Ed25519", | |||
"cofactor" : 8, | |||
"field" : "p25519", | |||
"scalar_bits" : 253 | |||
"scalar_bits" : 253, | |||
"d": -121665, | |||
"trace": -0xa6f7cef517bce6b2c09318d2e7ae9f7a, | |||
"mont_base": 9 | |||
}, | |||
"Ed448" : { | |||
"name" : "Ed448-Goldilocks", | |||
"cofactor" : 4, | |||
"field" : "p448", | |||
"scalar_bits" : 446 | |||
"scalar_bits" : 446, | |||
"d": -39081, | |||
"trace": 0x10cd77058eec492d944a725bf7a4cf635c8e9c2ab721cf5b5529eec34, | |||
"mont_base": 5 | |||
} | |||
} | |||
def ser(x,bits,paren=None): | |||
out = "" | |||
mask = 2**bits - 1 | |||
first = True | |||
while x > 0 or first: | |||
desc = "0x%0*x" % ((bits+3)//4,x&mask) | |||
if paren is not None: | |||
desc = "%s(%s)" % (paren,desc) | |||
if not first: out += ", " | |||
out += desc | |||
x = x >> bits | |||
first = False | |||
return out | |||
def msqrt(x,p,hi_bit_clear = True): | |||
if p % 4 == 3: ret = pow(x,(p+1)//4,p) | |||
elif p % 8 == 5: | |||
for u in xrange(1,1000): | |||
if pow(u,(p-1)//2,p) != 1: break | |||
u = pow(u,(p-1)//4,p) | |||
ret = pow(x,(p+3)//8,p) | |||
if pow(ret,2,p) != (x % p): ret = (ret * u) % p | |||
else: raise Exception("sqrt only for 3-mod-4 or 5-mod-8") | |||
if (ret**2-x) % p != 0: raise Exception("No sqrt") | |||
if hi_bit_clear and ret > p//2: ret = p-ret | |||
return ret | |||
def ceil_log2(x): | |||
out = 0 | |||
cmp = 1 | |||
@@ -38,9 +72,10 @@ def ceil_log2(x): | |||
return out | |||
for field,data in field_data.iteritems(): | |||
if "modulus" not in data: | |||
data["modulus"] = eval(data["gf_desc"].replace("^","**")) | |||
data["p_mod_8"] = data["modulus"] % 8 | |||
if "gf_bits" not in data: | |||
data["gf_bits"] = ceil_log2(data["modulus"]) | |||
@@ -52,41 +87,52 @@ for field,data in field_data.iteritems(): | |||
data["x_priv_bytes"] = (data["gf_bits"]-1)//8 + 1 | |||
if "x_priv_bits" not in data: | |||
data["x_priv_bits"] = ceil_log2(data["modulus"]*0.99) | |||
data["x_priv_bits"] = ceil_log2(data["modulus"]*0.99) # not per curve at least in 7748 | |||
data["ser_modulus"] = ser(data["modulus"], data["gf_lit_limb_bits"]) | |||
if data["modulus"] % 4 == 1: data["sqrt_minus_one"] = ser(msqrt(-1,data["modulus"]), data["gf_lit_limb_bits"]) | |||
else: data["sqrt_minus_one"] = "/* NONE */" | |||
for curve,data in curve_data.iteritems(): | |||
for key in field_data[data["field"]]: | |||
if key not in data: | |||
data[key] = field_data[data["field"]][key] | |||
if "iso_to" not in data: | |||
data["iso_to"] = data["name"] | |||
if "cxx_ns" not in data: | |||
data["cxx_ns"] = data["name"].replace("-","") | |||
if "modulus_type" not in data: | |||
mod = data["modulus"] | |||
ptwo = 2 | |||
while mod % ptwo == 1: | |||
ptwo *= 2 | |||
data["modulus_type"] = mod % ptwo | |||
if "c_filename" not in data: | |||
data["c_filename"] = data["iso_to"].replace("-","").lower() | |||
mod = data["modulus"] | |||
ptwo = 2 | |||
while mod % ptwo == 1: | |||
ptwo *= 2 | |||
data["modulus_type"] = mod % ptwo | |||
if "imagine_twist" not in data: | |||
if data["modulus_type"] == 3: data["imagine_twist"] = 0 | |||
else: data["imagine_twist"] = 1 | |||
data["q"] = (data["modulus"]+1-data["trace"]) // data["cofactor"] | |||
data["bits"] = ceil_log2(data["modulus"]) | |||
data["decaf_base"] = ser(msqrt(data["mont_base"],data["modulus"]),8) | |||
data["scalar_p"] = ser(data["q"],64,"SC_LIMB") | |||
if "bits" not in data: | |||
data["bits"] = ceil_log2(data["modulus"]) | |||
if data["cofactor"] > 4: data["sqrt_one_minus_d"] = ser(msqrt(1-data["d"],data["modulus"]),data["gf_lit_limb_bits"]) | |||
else: data["sqrt_one_minus_d"] = "/* NONE */" | |||
if "shortname" not in data: | |||
data["shortname"] = str(data["bits"]) | |||
if "c_ns" not in data: | |||
data["c_ns"] = "decaf_" + data["shortname"] | |||
data["C_NS"] = data["c_ns"].upper() | |||
if "ser_bytes" not in data: | |||
data["ser_bytes"] = (data["bits"]-2)//8 + 1 | |||
if "scalar_ser_bytes" not in data: | |||
data["scalar_ser_bytes"] = (data["scalar_bits"]-1)//8 + 1 | |||
data["ser_bytes"] = (data["bits"]-2)//8 + 1 # TODO: split for decaf vs non-decaf | |||
data["scalar_ser_bytes"] = (data["scalar_bits"]-1)//8 + 1 | |||
if "C_NS" not in data: | |||
data["C_NS"] = data["c_ns"].upper() | |||
@@ -0,0 +1,44 @@ | |||
from gen_file import gen_file | |||
curve_data_inc_c = gen_file( | |||
public = False, | |||
per = "curve", | |||
name = "curve_%(c_filename)s/curve_data.inc.c", | |||
doc = """@brief Curve data for %(name)s.""", | |||
code = """ | |||
#define API_NAME "%(c_ns)s" | |||
#define API_NS(_id) %(c_ns)s_##_id | |||
#define API_NS2(_pref,_id) _pref##_%(c_ns)s_##_id | |||
#define SCALAR_BITS %(C_NS)s_SCALAR_BITS | |||
#ifndef DECAF_JUST_API | |||
#define SCALAR_LIMBS %(C_NS)s_SCALAR_LIMBS | |||
#define scalar_t API_NS(scalar_t) | |||
#define point_t API_NS(point_t) | |||
#define precomputed_s API_NS(precomputed_s) | |||
#define IMAGINE_TWIST %(imagine_twist)d | |||
#define COFACTOR %(cofactor)d | |||
static const int EDWARDS_D = %(d)d; | |||
static const scalar_t sc_p = {{{ | |||
%(scalar_p)s | |||
}}}; | |||
#ifdef GEN_TABLES | |||
/* Not exported, but used by pregen tool. */ | |||
static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { | |||
%(decaf_base)s | |||
}; | |||
#endif | |||
#if COFACTOR==8 | |||
static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( | |||
%(sqrt_one_minus_d)s | |||
)}; | |||
#endif | |||
#endif /* DECAF_JUST_API */ | |||
""") |
@@ -55,8 +55,6 @@ typedef struct gf_%(gf_shortname)s_s { | |||
extern "C" { | |||
#endif | |||
const gf MODULUS, ZERO, ONE; | |||
/* Defined below in f_impl.h */ | |||
static INLINE_UNUSED void gf_copy (gf out, const gf a) { *out = *a; } | |||
static INLINE_UNUSED void gf_add_RAW (gf out, const gf a, const gf b); | |||
@@ -82,8 +80,21 @@ mask_t gf_deserialize (gf x, const uint8_t serial[(GF_BITS-1)/8+1]); | |||
#include "f_impl.h" /* Bring in the inline implementations */ | |||
static const gf MODULUS = {FIELD_LITERAL( | |||
%(ser_modulus)s | |||
)}; | |||
#define P_MOD_8 %(p_mod_8)d | |||
#if P_MOD_8 == 5 | |||
static const gf SQRT_MINUS_ONE = {FIELD_LITERAL( /* TODO make not static */ | |||
%(sqrt_minus_one)s | |||
)}; | |||
#endif | |||
#ifndef LIMBPERM | |||
#define LIMBPERM(i) (i) | |||
#endif | |||
#define LIMB_MASK(i) (((1ull)<<LIMB_PLACE_VALUE(i))-1) | |||
static const gf ZERO = {{{0}}}, ONE = {{{ [LIMBPERM(0)] = 1 }}}; | |||
""") |
@@ -18,6 +18,7 @@ from crypto_h import crypto_h | |||
from crypto_hxx import crypto_hxx | |||
from f_field_h import f_field_h | |||
from curve_data import curve_data | |||
from curve_data_inc_c import curve_data_inc_c | |||
root_hxx_code = "\n".join(( | |||
"#include <%s>" % name | |||
@@ -110,7 +111,7 @@ decaf_root_hxx = gen_file( | |||
for name,(public,code) in gend_files.iteritems(): | |||
_,_,name_suffix = name.partition(".") | |||
_,_,name_suffix = name.rpartition(".") | |||
prefix = prefixes[(public,name_suffix)] | |||
if not os.path.exists(os.path.dirname(prefix + "/" + name)): | |||
os.makedirs(os.path.dirname(prefix + "/" + name)) | |||
@@ -11,18 +11,6 @@ | |||
#include "field.h" | |||
#include "constant_time.h" | |||
const gf SQRT_MINUS_ONE = {FIELD_LITERAL( | |||
0x61b274a0ea0b0, | |||
0x0d5a5fc8f189d, | |||
0x7ef5e9cbd0c60, | |||
0x78595a6804c9e, | |||
0x2b8324804fc1d | |||
)}; | |||
const gf MODULUS = {FIELD_LITERAL( | |||
0x7ffffffffffed, 0x7ffffffffffff, 0x7ffffffffffff, 0x7ffffffffffff, 0x7ffffffffffff | |||
)}; | |||
/* Guarantee: a^2 x = 0 if x = 0; else a^2 x = 1 or SQRT_MINUS_ONE; */ | |||
void gf_isr (gf a, const gf x) { | |||
gf st[3], tmp1, tmp2; | |||
@@ -10,39 +10,34 @@ | |||
#include "field.h" | |||
const gf MODULUS = {FIELD_LITERAL( | |||
0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, | |||
0xfffffffffffffe, 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff | |||
)}; | |||
void | |||
gf_isr ( | |||
gf a, | |||
const gf x | |||
) { | |||
gf L0, L1, L2; | |||
gf_sqr ( L1, x ); | |||
gf_mul ( L2, x, L1 ); | |||
gf_sqr ( L1, L2 ); | |||
gf_mul ( L2, x, L1 ); | |||
gf_sqrn ( L1, L2, 3 ); | |||
gf_mul ( L0, L2, L1 ); | |||
gf_sqrn ( L1, L0, 3 ); | |||
gf_mul ( L0, L2, L1 ); | |||
gf_sqrn ( L2, L0, 9 ); | |||
gf_mul ( L1, L0, L2 ); | |||
gf_sqr ( L0, L1 ); | |||
gf_mul ( L2, x, L0 ); | |||
gf_sqrn ( L0, L2, 18 ); | |||
gf_mul ( L2, L1, L0 ); | |||
gf_sqrn ( L0, L2, 37 ); | |||
gf_mul ( L1, L2, L0 ); | |||
gf_sqrn ( L0, L1, 37 ); | |||
gf_mul ( L1, L2, L0 ); | |||
gf_sqrn ( L0, L1, 111 ); | |||
gf_mul ( L2, L1, L0 ); | |||
gf_sqr ( L0, L2 ); | |||
gf_mul ( L1, x, L0 ); | |||
gf_sqrn ( L0, L1, 223 ); | |||
gf_mul ( a, L2, L0 ); | |||
gf_sqr (L1, x ); | |||
gf_mul (L2, x, L1 ); | |||
gf_sqr (L1, L2 ); | |||
gf_mul (L2, x, L1 ); | |||
gf_sqrn (L1, L2, 3 ); | |||
gf_mul (L0, L2, L1 ); | |||
gf_sqrn (L1, L0, 3 ); | |||
gf_mul (L0, L2, L1 ); | |||
gf_sqrn (L2, L0, 9 ); | |||
gf_mul (L1, L0, L2 ); | |||
gf_sqr (L0, L1 ); | |||
gf_mul (L2, x, L0 ); | |||
gf_sqrn (L0, L2, 18 ); | |||
gf_mul (L2, L1, L0 ); | |||
gf_sqrn (L0, L2, 37 ); | |||
gf_mul (L1, L2, L0 ); | |||
gf_sqrn (L0, L1, 37 ); | |||
gf_mul (L1, L2, L0 ); | |||
gf_sqrn (L0, L1, 111 ); | |||
gf_mul (L2, L1, L0 ); | |||
gf_sqr (L0, L2 ); | |||
gf_mul (L1, x, L0 ); | |||
gf_sqrn (L0, L1, 223 ); | |||
gf_mul ( a, L2, L0 ); | |||
} |
@@ -10,8 +10,6 @@ | |||
#include "field.h" | |||
const gf ZERO = {{{0}}}, ONE = {{{ [LIMBPERM(0)] = 1 }}}; | |||
/** Serialize to wire format. */ | |||
void gf_serialize (uint8_t serial[SER_BYTES], const gf x) { | |||
gf red; | |||