From f6ec8b2fc87bdf8a2411049c93af38d68772f41b Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Fri, 29 Jan 2016 15:08:32 -0800 Subject: [PATCH] moving to a much simpler templating system --- Makefile | 68 ++++++------ src/gen_headers/curve_data.py | 4 +- src/gen_headers/curve_data_inc_c.py | 44 -------- src/gen_headers/f_field_h.py | 100 ------------------ src/gen_headers/main.py | 2 - src/gen_headers/template.py | 98 +++++++++++++++++ .../crypto.tmpl.c} | 7 +- src/per_curve/curve_data.tmpl.h | 35 ++++++ src/{decaf.c => per_curve/decaf.tmpl.c} | 12 +-- .../decaf_gen_tables.tmpl.c} | 12 +-- src/per_field/f_field.tmpl.h | 93 ++++++++++++++++ .../f_generic.tmpl.c} | 0 12 files changed, 270 insertions(+), 205 deletions(-) delete mode 100644 src/gen_headers/curve_data_inc_c.py delete mode 100644 src/gen_headers/f_field_h.py create mode 100644 src/gen_headers/template.py rename src/{decaf_crypto.c => per_curve/crypto.tmpl.c} (96%) create mode 100644 src/per_curve/curve_data.tmpl.h rename src/{decaf.c => per_curve/decaf.tmpl.c} (99%) rename src/{decaf_gen_tables.c => per_curve/decaf_gen_tables.tmpl.c} (95%) create mode 100644 src/per_field/f_field.tmpl.h rename src/{per_field.c => per_field/f_generic.tmpl.c} (100%) diff --git a/Makefile b/Makefile index 79e9c99..9d28e30 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,8 @@ MACHINE := $(shell uname -m) # The non-build/obj directories are the public interface. BUILD_ASM = build/obj BUILD_OBJ = build/obj -BUILD_C = build/obj -BUILD_H = build/obj/include +BUILD_C = build/c +BUILD_H = build/c BUILD_PY = build/obj BUILD_LIB = build/lib BUILD_INC = build/include @@ -67,7 +67,7 @@ SAGES= $(shell ls test/*.sage) BUILDPYS= $(SAGES:test/%.sage=$(BUILD_PY)/%.py) .PHONY: clean all test test_ct bench todo doc lib bat sage sagetest gen_headers -.PRECIOUS: $(BUILD_ASM)/%.s $(BUILD_C)/%.c $(BUILD_IBIN)/% +.PRECIOUS: $(BUILD_ASM)/%.s $(BUILD_C)/*/%.c $(BUILD_H)/*/%.h $(BUILD_IBIN)/% GEN_HEADERS=\ $(BUILD_INC)/decaf/decaf_255.h \ @@ -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_curve25519.o $(BUILD_OBJ)/decaf_crypto_ed448goldilocks.o # and per-field components +LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o # and per-field components BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o @@ -117,7 +117,8 @@ endif # Create all the build subdirectories $(BUILD_OBJ)/timestamp: mkdir -p $(BUILD_ASM) $(BUILD_OBJ) $(BUILD_C) $(BUILD_PY) \ - $(BUILD_LIB) $(BUILD_INC) $(BUILD_BIN) $(BUILD_IBIN) $(BUILD_H) $(BUILD_INC)/decaf + $(BUILD_LIB) $(BUILD_INC) $(BUILD_BIN) $(BUILD_IBIN) $(BUILD_H) $(BUILD_INC)/decaf \ + $(PER_OBJ_DIRS) touch $@ $(BUILD_OBJ)/%.o: $(BUILD_ASM)/%.s @@ -134,20 +135,28 @@ $(GEN_HEADERS): src/gen_headers/*.py src/public_include/decaf/* ################################################################ define define_field ARCH_FOR_$(1) ?= $(2) -COMPONENTS_OF_$(1) = $$(BUILD_OBJ)/$(1)_impl.o $$(BUILD_OBJ)/$(1)_arithmetic.o $$(BUILD_OBJ)/$(1)_per_field.o +COMPONENTS_OF_$(1) = $$(BUILD_OBJ)/$(1)/f_impl.o $$(BUILD_OBJ)/$(1)/f_arithmetic.o $$(BUILD_OBJ)/$(1)/f_generic.o +HEADERS_OF_$(1) = $(HEADERS) $$(BUILD_H)/$(1)/f_field.h LIBCOMPONENTS += $$(COMPONENTS_OF_$(1)) +PER_OBJ_DIRS += $$(BUILD_OBJ)/$(1) -$$(BUILD_ASM)/$(1)_arithmetic.s: src/$(1)/f_arithmetic.c $$(HEADERS) +$$(BUILD_C)/$(1)/%.c: src/per_field/%.tmpl.c src/gen_headers/* $(HEADERS) + python -B src/gen_headers/template.py --per=field --guard=$(1)/`basename $$@` --item=$(1) -o $$@ $$< + +$$(BUILD_H)/$(1)/%.h: src/per_field/%.tmpl.h src/gen_headers/* $(HEADERS) + python -B src/gen_headers/template.py --per=field --guard=$(1)/`basename $$@` --item=$(1) -o $$@ $$< + +$$(BUILD_ASM)/$(1)/%.s: $$(BUILD_C)/$(1)/%.c $$(HEADERS_OF_$(1)) $$(CC) $$(CFLAGS) -I src/$(1) -I src/$(1)/$$(ARCH_FOR_$(1)) -I $(BUILD_H)/$(1) \ -I $(BUILD_H)/$(1)/$$(ARCH_FOR_$(1)) -I src/include/$$(ARCH_FOR_$(1)) \ -S -c -o $$@ $$< -$$(BUILD_ASM)/$(1)_impl.s: src/$(1)/$$(ARCH_FOR_$(1))/f_impl.c $$(HEADERS) +$$(BUILD_ASM)/$(1)/%.s: src/$(1)/%.c $$(HEADERS_OF_$(1)) $$(CC) $$(CFLAGS) -I src/$(1) -I src/$(1)/$$(ARCH_FOR_$(1)) -I $(BUILD_H)/$(1) \ -I $(BUILD_H)/$(1)/$$(ARCH_FOR_$(1)) -I src/include/$$(ARCH_FOR_$(1)) \ -S -c -o $$@ $$< -$$(BUILD_ASM)/$(1)_per_field.s: src/per_field.c $$(HEADERS) +$$(BUILD_ASM)/$(1)/%.s: src/$(1)/$$(ARCH_FOR_$(1))/%.c $$(HEADERS_OF_$(1)) $$(CC) $$(CFLAGS) -I src/$(1) -I src/$(1)/$$(ARCH_FOR_$(1)) -I $(BUILD_H)/$(1) \ -I $(BUILD_H)/$(1)/$$(ARCH_FOR_$(1)) -I src/include/$$(ARCH_FOR_$(1)) \ -S -c -o $$@ $$< @@ -157,38 +166,35 @@ endef # Per-field, per-curve code: call with curve, field ################################################################ define define_curve -$$(BUILD_IBIN)/decaf_gen_tables_$(1): $$(BUILD_OBJ)/decaf_gen_tables_$(1).o \ - $$(BUILD_OBJ)/decaf_$(1).o $$(BUILD_OBJ)/utils.o \ + +LIBCOMPONENTS += $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/crypto.o $$(BUILD_OBJ)/$(1)/decaf_tables.o +PER_OBJ_DIRS += $$(BUILD_OBJ)/$(1) +HEADERS_OF_$(1) = $$(HEADERS_OF_$(2)) $$(BUILD_H)/$(1)/curve_data.h + +$$(BUILD_C)/$(1)/%.c: src/per_curve/%.tmpl.c src/gen_headers/* $$(HEADERS_OF_$(2)) + python -B src/gen_headers/template.py --per=curve --item=$(1) --guard=$(1)/`basename $$@` -o $$@ $$< + +$$(BUILD_H)/$(1)/%.h: src/per_curve/%.tmpl.h src/gen_headers/* $$(HEADERS_OF_$(2)) + python -B src/gen_headers/template.py --per=curve --item=$(1) --guard=$(1)/`basename $$@` -o $$@ $$< + +$$(BUILD_IBIN)/decaf_gen_tables_$(1): $$(BUILD_OBJ)/$(1)/decaf_gen_tables.o \ + $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/utils.o \ $$(COMPONENTS_OF_$(2)) $$(LD) $$(LDFLAGS) -o $$@ $$^ -$$(BUILD_C)/decaf_tables_$(1).c: $$(BUILD_IBIN)/decaf_gen_tables_$(1) +$$(BUILD_C)/$(1)/decaf_tables.c: $$(BUILD_IBIN)/decaf_gen_tables_$(1) ./$$< > $$@ || (rm $$@; exit 1) -$$(BUILD_ASM)/decaf_tables_$(1).s: $$(BUILD_C)/decaf_tables_$(1).c $$(HEADERS) +$$(BUILD_ASM)/$(1)/%.s: $$(BUILD_C)/$(1)/%.c $$(HEADERS_OF_$(1)) $$(CC) $$(CFLAGS) -S -c -o $$@ $$< \ -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)) + -I $(BUILD_H)/$(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) +$$(BUILD_ASM)/decaf_gen_tables_$(1).s: src/decaf_gen_tables.c $$(HEADERS_OF_$(1)) $$(CC) $$(CFLAGS) \ -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)) \ + -I $(BUILD_H)/$(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 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 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 $$@ $$< - -LIBCOMPONENTS += $$(BUILD_OBJ)/decaf_$(1).o $$(BUILD_OBJ)/decaf_tables_$(1).o endef ################################################################ @@ -303,4 +309,4 @@ microbench: $(BUILD_IBIN)/bench ./$< --micro clean: - rm -fr build $(BATNAME) + rm -fr build diff --git a/src/gen_headers/curve_data.py b/src/gen_headers/curve_data.py index a458e85..a66b1b0 100644 --- a/src/gen_headers/curve_data.py +++ b/src/gen_headers/curve_data.py @@ -14,7 +14,7 @@ field_data = { } curve_data = { - "Curve25519" : { + "curve25519" : { "iso_to" : "Curve25519", "name" : "Iso-Ed25519", "cofactor" : 8, @@ -24,7 +24,7 @@ curve_data = { "trace": -0xa6f7cef517bce6b2c09318d2e7ae9f7a, "mont_base": 9 }, - "Ed448" : { + "ed448goldilocks" : { "name" : "Ed448-Goldilocks", "cofactor" : 4, "field" : "p448", diff --git a/src/gen_headers/curve_data_inc_c.py b/src/gen_headers/curve_data_inc_c.py deleted file mode 100644 index 84dde82..0000000 --- a/src/gen_headers/curve_data_inc_c.py +++ /dev/null @@ -1,44 +0,0 @@ -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 diff --git a/src/gen_headers/f_field_h.py b/src/gen_headers/f_field_h.py deleted file mode 100644 index fa3fa5b..0000000 --- a/src/gen_headers/f_field_h.py +++ /dev/null @@ -1,100 +0,0 @@ -from gen_file import gen_file - -f_field_h = gen_file( - public = False, - per = "field", - name = "p%(gf_shortname)s/f_field.h", - doc = """@brief Field-specific code for %(gf_desc)s.""", - code = """ -#include "constant_time.h" -#include -#include - -#include "word.h" - -#define __DECAF_%(gf_shortname)s_GF_DEFINED__ 1 -#define NLIMBS (%(gf_impl_bits)d/sizeof(word_t)/8) -#define SER_BYTES ((%(gf_bits)d-1)/8 + 1) /* MAGIC: depends on if high bit known to be clear (eg p521) */ -typedef struct gf_%(gf_shortname)s_s { - word_t limb[NLIMBS]; -} __attribute__((aligned(32))) gf_%(gf_shortname)s_s, gf_%(gf_shortname)s_t[1]; - -#define GF_LIT_LIMB_BITS %(gf_lit_limb_bits)d -#define GF_BITS %(gf_bits)d -#define ZERO gf_%(gf_shortname)s_ZERO -#define ONE gf_%(gf_shortname)s_ONE -#define MODULUS gf_%(gf_shortname)s_MODULUS -#define gf gf_%(gf_shortname)s_t -#define gf_s gf_%(gf_shortname)s_s -#define gf_eq gf_%(gf_shortname)s_eq -#define gf_copy gf_%(gf_shortname)s_copy -#define gf_add gf_%(gf_shortname)s_add -#define gf_sub gf_%(gf_shortname)s_sub -#define gf_add_RAW gf_%(gf_shortname)s_add_RAW -#define gf_sub_RAW gf_%(gf_shortname)s_sub_RAW -#define gf_bias gf_%(gf_shortname)s_bias -#define gf_weak_reduce gf_%(gf_shortname)s_weak_reduce -#define gf_strong_reduce gf_%(gf_shortname)s_strong_reduce -#define gf_mul gf_%(gf_shortname)s_mul -#define gf_sqr gf_%(gf_shortname)s_sqr -#define gf_mulw gf_%(gf_shortname)s_mulw -#define gf_isr gf_%(gf_shortname)s_isr -#define gf_serialize gf_%(gf_shortname)s_serialize -#define gf_deserialize gf_%(gf_shortname)s_deserialize - -/* RFC 7748 support */ -#define X_PUBLIC_BYTES %(x_pub_bytes)d -#define X_PRIVATE_BYTES %(x_priv_bytes)d -#define X_PRIVATE_BITS %(x_priv_bits)d - -#define SQRT_MINUS_ONE P%(gf_shortname)s_SQRT_MINUS_ONE /* might not be defined */ - -#define INLINE_UNUSED __inline__ __attribute__((unused,always_inline)) - -#ifdef __cplusplus -extern "C" { -#endif - -/* 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); -static INLINE_UNUSED void gf_sub_RAW (gf out, const gf a, const gf b); -static INLINE_UNUSED void gf_bias (gf inout, int amount); -static INLINE_UNUSED void gf_weak_reduce (gf inout); - -void gf_strong_reduce (gf inout); -void gf_add (gf out, const gf a, const gf b); -void gf_sub (gf out, const gf a, const gf b); -void gf_mul (gf_s *__restrict__ out, const gf a, const gf b); -void gf_mulw (gf_s *__restrict__ out, const gf a, uint32_t b); -void gf_sqr (gf_s *__restrict__ out, const gf a); -void gf_serialize (uint8_t *serial, const gf x); -void gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0 */ -mask_t gf_eq (const gf x, const gf y); -mask_t gf_deserialize (gf x, const uint8_t serial[(GF_BITS-1)/8+1]); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#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)<" % name diff --git a/src/gen_headers/template.py b/src/gen_headers/template.py new file mode 100644 index 0000000..288a463 --- /dev/null +++ b/src/gen_headers/template.py @@ -0,0 +1,98 @@ +from textwrap import dedent + +import os +import argparse +import re + +parser = argparse.ArgumentParser(description='Generate Decaf headers and other such files.') +parser.add_argument('-o', required = True, help = "Output") +parser.add_argument('--per', required = True, help = "Files to be generated are global or per field/curve", choices=["global","field","curve"]) +parser.add_argument('--item', required = False, default = "global", help = "Which curve/field to choose") +parser.add_argument('--guard', required = False, default = None, help = "header guard") +parser.add_argument('files', metavar='file', type=str, nargs='+', help='a list of files to fill') +args = parser.parse_args() + +from curve_data import field_data,curve_data + +per_map = {"field":field_data, "curve":curve_data, "global":{"global":{}} } + +def redoc(filename,doc,author): + doc = doc.replace("\n","\n * ") + doc = dedent(""" + /** + * @file %(filename)s + * @author %(author)s + * + * @copyright + * Copyright (c) 2015-2016 Cryptography Research, Inc. \\n + * Released under the MIT License. See LICENSE.txt for license information. + * + * %(doc)s + * + * @warning This file was automatically generated in Python. + * Please do not edit it. + */""") % { "filename": filename, "doc": doc, "author" : author } + doc = doc.replace(" * \n", " *\n") + return doc[1:] + +def gen_file(public,name,doc,code,per="global",author="Mike Hamburg"): + is_header = name.endswith(".h") or name.endswith(".hxx") or name.endswith(".h++") + +def fillin(template,data): + position = 0 + ret = "" + while True: + dollars = template.find("$(",position) + if dollars is -1: return ret + template[position:] + ret += template[position:dollars] + position = dollars + 2 + parens = 1 + while parens > 0: + if template[position] == '(': parens += 1 + elif template[position] == ')': parens -= 1 + position += 1 + ret += str(eval(template[dollars+2:position-1],data)) + +author = "Mike Hamburg" # FUTURE +for name in args.files: + _,_,name_suffix = name.rpartition(".") + template0 = open(name,"r").read() + + data = per_map[args.per][args.item] + + template = template0 + + outname = args.o + guard = args.guard + if guard is None: guard = outname + header_guard = "__" + guard.replace(".","_").replace("/","_").upper() + "__" + + # Extract doxygenation + m = re.match(r"^\s*/\*\*([^*]|\*[^/])+\*/[ \t]*\n",template) + if m: + doc = re.sub("^\s*/?\*+/?[ \t]*","",m.group(),flags=re.MULTILINE) + doc = re.sub("\\s*\*/","",doc) + template = template[m.end():] + else: doc = "" + + ns_doc = dedent(doc).strip().rstrip() + ns_doc = redoc(guard, fillin(ns_doc,data), author) + ns_code = fillin(template,data) + ret = ns_doc + "\n" + + if outname.endswith(".h") or outname.endswith(".hxx"): + ns_code = dedent("""\n + #ifndef %(header_guard)s + #define %(header_guard)s 1 + %(code)s + #endif /* %(header_guard)s */ + """) % { "header_guard" : header_guard, "code": ns_code } + ret += ns_code[1:-1] + + if not os.path.exists(os.path.dirname(outname)): + os.makedirs(os.path.dirname(outname)) + with open(outname,"w") as f: + f.write(ret + "\n") + + + \ No newline at end of file diff --git a/src/decaf_crypto.c b/src/per_curve/crypto.tmpl.c similarity index 96% rename from src/decaf_crypto.c rename to src/per_curve/crypto.tmpl.c index b0e5eef..4e46d7d 100644 --- a/src/decaf_crypto.c +++ b/src/per_curve/crypto.tmpl.c @@ -1,10 +1,5 @@ /** * @cond internal - * @file decaf_crypto.c - * @copyright - * Copyright (c) 2015 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * @author Mike Hamburg * @brief Example Decaf crypto routines */ @@ -13,7 +8,7 @@ #include #define DECAF_JUST_API -#include "curve_data.inc.c" +#include "curve_data.h" #define SCALAR_BYTES ((SCALAR_BITS + 7)/8) /* TODO: canonicalize and freeze the STROBE constants in this file diff --git a/src/per_curve/curve_data.tmpl.h b/src/per_curve/curve_data.tmpl.h new file mode 100644 index 0000000..41da050 --- /dev/null +++ b/src/per_curve/curve_data.tmpl.h @@ -0,0 +1,35 @@ +#define API_NAME "$(c_ns)" +#define API_NS(_id) $(c_ns)_##_id +#define API_NS2(_pref,_id) _pref##_$(c_ns)_##_id + +#define SCALAR_BITS $(C_NS)_SCALAR_BITS + +#ifndef DECAF_JUST_API + +#define SCALAR_LIMBS $(C_NS)_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) +#define COFACTOR $(cofactor) + +static const int EDWARDS_D = $(d); + +static const scalar_t sc_p = {{{ + $(scalar_p) +}}}; + +#ifdef GEN_TABLES +/* Not exported, but used by pregen tool. */ +static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { + $(decaf_base) +}; +#endif + +#if COFACTOR==8 + static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( + $(sqrt_one_minus_d) + )}; +#endif + +#endif /* DECAF_JUST_API */ diff --git a/src/decaf.c b/src/per_curve/decaf.tmpl.c similarity index 99% rename from src/decaf.c rename to src/per_curve/decaf.tmpl.c index 844a779..f989c5f 100644 --- a/src/decaf.c +++ b/src/per_curve/decaf.tmpl.c @@ -1,12 +1,4 @@ -/* Copyright (c) 2015 Cryptography Research, Inc. - * Released under the MIT License. See LICENSE.txt for license information. - */ - -/** - * @file decaf.c - * @author Mike Hamburg - * @brief Decaf high-level functions. - */ +/** @brief Decaf high-level functions. */ #define _XOPEN_SOURCE 600 /* for posix_memalign */ #define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s */ @@ -19,7 +11,7 @@ #include /* Include the curve data here */ -#include "curve_data.inc.c" +#include "curve_data.h" #if (COFACTOR == 8) && !IMAGINE_TWIST /* FUTURE: Curve41417 doesn't have these properties. */ diff --git a/src/decaf_gen_tables.c b/src/per_curve/decaf_gen_tables.tmpl.c similarity index 95% rename from src/decaf_gen_tables.c rename to src/per_curve/decaf_gen_tables.tmpl.c index 028deb7..48ece83 100644 --- a/src/decaf_gen_tables.c +++ b/src/per_curve/decaf_gen_tables.tmpl.c @@ -1,12 +1,4 @@ -/* 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. - */ +/** @brief Decaf global constant table precomputation. */ #define _XOPEN_SOURCE 600 /* for posix_memalign */ #include @@ -18,7 +10,7 @@ #include "decaf_config.h" #define GEN_TABLES -#include "curve_data.inc.c" +#include "curve_data.h" /* To satisfy linker. */ const gf API_NS(precomputed_base_as_fe)[1]; diff --git a/src/per_field/f_field.tmpl.h b/src/per_field/f_field.tmpl.h new file mode 100644 index 0000000..4322c9a --- /dev/null +++ b/src/per_field/f_field.tmpl.h @@ -0,0 +1,93 @@ +/** @brief Field-specific code for $(gf_desc). */ + +#include "constant_time.h" +#include +#include + +#include "word.h" + +#define __DECAF_$(gf_shortname)_GF_DEFINED__ 1 +#define NLIMBS ($(gf_impl_bits/8)/sizeof(word_t)) +#define SER_BYTES $(((gf_bits-1)//8 + 1)) /* MAGIC: depends on if high bit known to be clear (eg p521) */ +typedef struct gf_$(gf_shortname)_s { + word_t limb[NLIMBS]; +} __attribute__((aligned(32))) gf_$(gf_shortname)_s, gf_$(gf_shortname)_t[1]; + +#define GF_LIT_LIMB_BITS $(gf_lit_limb_bits) +#define GF_BITS $(gf_bits) +#define ZERO gf_$(gf_shortname)_ZERO +#define ONE gf_$(gf_shortname)_ONE +#define MODULUS gf_$(gf_shortname)_MODULUS +#define gf gf_$(gf_shortname)_t +#define gf_s gf_$(gf_shortname)_s +#define gf_eq gf_$(gf_shortname)_eq +#define gf_copy gf_$(gf_shortname)_copy +#define gf_add gf_$(gf_shortname)_add +#define gf_sub gf_$(gf_shortname)_sub +#define gf_add_RAW gf_$(gf_shortname)_add_RAW +#define gf_sub_RAW gf_$(gf_shortname)_sub_RAW +#define gf_bias gf_$(gf_shortname)_bias +#define gf_weak_reduce gf_$(gf_shortname)_weak_reduce +#define gf_strong_reduce gf_$(gf_shortname)_strong_reduce +#define gf_mul gf_$(gf_shortname)_mul +#define gf_sqr gf_$(gf_shortname)_sqr +#define gf_mulw gf_$(gf_shortname)_mulw +#define gf_isr gf_$(gf_shortname)_isr +#define gf_serialize gf_$(gf_shortname)_serialize +#define gf_deserialize gf_$(gf_shortname)_deserialize + +/* RFC 7748 support */ +#define X_PUBLIC_BYTES $(x_pub_bytes) +#define X_PRIVATE_BYTES $(x_priv_bytes) +#define X_PRIVATE_BITS $(x_priv_bits) + +#define SQRT_MINUS_ONE P$(gf_shortname)_SQRT_MINUS_ONE /* might not be defined */ + +#define INLINE_UNUSED __inline__ __attribute__((unused,always_inline)) + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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); +static INLINE_UNUSED void gf_sub_RAW (gf out, const gf a, const gf b); +static INLINE_UNUSED void gf_bias (gf inout, int amount); +static INLINE_UNUSED void gf_weak_reduce (gf inout); + +void gf_strong_reduce (gf inout); +void gf_add (gf out, const gf a, const gf b); +void gf_sub (gf out, const gf a, const gf b); +void gf_mul (gf_s *__restrict__ out, const gf a, const gf b); +void gf_mulw (gf_s *__restrict__ out, const gf a, uint32_t b); +void gf_sqr (gf_s *__restrict__ out, const gf a); +void gf_serialize (uint8_t *serial, const gf x); +void gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0 */ +mask_t gf_eq (const gf x, const gf y); +mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES]); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "f_impl.h" /* Bring in the inline implementations */ + +static const gf MODULUS = {FIELD_LITERAL( + $(ser_modulus) +)}; + +#define P_MOD_8 $(p_mod_8) +#if P_MOD_8 == 5 + static const gf SQRT_MINUS_ONE = {FIELD_LITERAL( /* TODO make not static */ + $(sqrt_minus_one) + )}; +#endif + +#ifndef LIMBPERM + #define LIMBPERM(i) (i) +#endif +#define LIMB_MASK(i) (((1ull)<