Commit 5311dd58 authored by Michael Hamburg's avatar Michael Hamburg

auto-gen more field arithmetic data

parent 6aea0961
......@@ -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))
......
#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 */
#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()
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 */
""")
\ No newline at end of file
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment