diff --git a/Makefile b/Makefile index cfb1e7e..9898e4e 100644 --- a/Makefile +++ b/Makefile @@ -69,12 +69,10 @@ 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_H)/*/%.h $(BUILD_IBIN)/% -GEN_HEADERS=\ - $(BUILD_INC)/decaf/decaf_255.h \ - $(BUILD_INC)/decaf/decaf_448.h \ - $(BUILD_INC)/decaf/decaf_255.hxx \ - $(BUILD_INC)/decaf/decaf_448.hxx \ - $( src/public_include/decaf/* : src/public_include = $(BUILD_INC) ) +HEADER_SRCS= $(shell find src/public_include -name "*.h*") +GEN_HEADERS_0= $(HEADER_SRCS:src/public_include/%=$(BUILD_INC)/%) +GEN_HEADERS_1= $(GEN_HEADERS_0:%.tmpl.h=%.h) +GEN_HEADERS= $(GEN_HEADERS_1:%.tmpl.hxx=%.hxx) HEADERS= Makefile $(shell find src test -name "*.h") $(BUILD_OBJ)/timestamp $(GEN_HEADERS) # components needed by the lib @@ -90,7 +88,6 @@ scan: clean -enable-checker osx -enable-checker security -enable-checker unix \ make all - # Internal test programs, which are not part of the final build/bin directory. $(BUILD_IBIN)/test: $(BUILD_OBJ)/test_decaf.o lib ifeq ($(UNAME),Darwin) @@ -125,10 +122,15 @@ $(BUILD_OBJ)/%.o: $(BUILD_ASM)/%.s $(ASM) $(ASFLAGS) -c -o $@ $< gen_headers: $(GEN_HEADERS) + +$(BUILD_INC)/%: src/public_include/% $(BUILD_OBJ)/timestamp + cp -f $< $@ + +$(BUILD_INC)/%.h: src/public_include/%.tmpl.h src/gen_headers/* + python -B src/gen_headers/template.py --per=global --guard=$(@:$(BUILD_INC)/%=%) -o $@ $< -$(GEN_HEADERS): src/gen_headers/*.py src/public_include/decaf/* - python -B src/gen_headers/main.py --hpre=$(BUILD_INC) --ihpre=$(BUILD_H) --cpre=$(BUILD_C) - cp src/public_include/decaf/* $(BUILD_INC)/decaf/ +$(BUILD_INC)/%.hxx: src/public_include/%.tmpl.hxx src/gen_headers/* + python -B src/gen_headers/template.py --per=global --guard=$(@:$(BUILD_INC)/%=%) -o $@ $< ################################################################ # Per-field code: call with field, arch @@ -169,13 +171,22 @@ define define_curve 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)) +GLOBAL_HEADERS_OF_$(1) = $(BUILD_INC)/decaf/decaf_$(3).h $(BUILD_INC)/decaf/decaf_$(3).hxx \ + $(BUILD_INC)/decaf/crypto_$(3).h $(BUILD_INC)/decaf/crypto_$(3).hxx +HEADERS_OF_$(1) = $$(HEADERS_OF_$(2)) $$(GLOBAL_HEADERS_OF_$(1)) +HEADERS += $$(GLOBAL_HEADERS_OF_$(1)) $$(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_INC)/decaf/decaf_$(3).%: src/per_curve/decaf.tmpl.% src/gen_headers/* $$(HEADERS_OF_$(2)) + python -B src/gen_headers/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$< + +$$(BUILD_INC)/decaf/crypto_$(3).%: src/per_curve/crypto.tmpl.% src/gen_headers/* $$(HEADERS_OF_$(2)) + python -B src/gen_headers/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$< $$(BUILD_IBIN)/decaf_gen_tables_$(1): $$(BUILD_OBJ)/$(1)/decaf_gen_tables.o \ $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/utils.o \ @@ -200,9 +211,9 @@ endef ################################################################ # call code above to generate curves and fields $(eval $(call define_field,p25519,arch_x86_64)) -$(eval $(call define_curve,curve25519,p25519)) +$(eval $(call define_curve,curve25519,p25519,255)) $(eval $(call define_field,p448,arch_x86_64)) -$(eval $(call define_curve,ed448goldilocks,p448)) +$(eval $(call define_curve,ed448goldilocks,p448,448)) # The shakesum utility is in the public bin directory. $(BUILD_BIN)/shakesum: $(BUILD_OBJ)/shakesum.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/utils.o diff --git a/src/gen_headers/curve_data.py b/src/gen_headers/curve_data.py index d9f26ec..17813b1 100644 --- a/src/gen_headers/curve_data.py +++ b/src/gen_headers/curve_data.py @@ -84,6 +84,7 @@ def ceil_log2(x): out += 1 return out +# TODO: reduce this because we can now have expressions. for field,data in field_data.iteritems(): if "modulus" not in data: data["modulus"] = eval(data["gf_desc"].replace("^","**")) diff --git a/src/gen_headers/gen_file.py b/src/gen_headers/gen_file.py deleted file mode 100644 index ea4b5b3..0000000 --- a/src/gen_headers/gen_file.py +++ /dev/null @@ -1,50 +0,0 @@ -from curve_data import curve_data, field_data -from textwrap import dedent - -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:] - -gend_files = {} - -per_map = {"field":field_data, "curve":curve_data, "global":{"global":{}} } - -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++") - - for curve,data in per_map[per].iteritems(): - ns_name = name % data - - _,_,name_base = ns_name.rpartition("/") - header_guard = "__" + ns_name.replace(".","_").replace("/","_").upper() + "__" - - ns_doc = dedent(doc).strip().rstrip() - ns_doc = redoc(ns_name, ns_doc % data, author) - ns_code = code % data - ret = ns_doc + "\n" - - if is_header: - 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] - - gend_files[ns_name] = (public,ret) diff --git a/src/gen_headers/main.py b/src/gen_headers/main.py deleted file mode 100644 index 288041b..0000000 --- a/src/gen_headers/main.py +++ /dev/null @@ -1,119 +0,0 @@ -from gen_file import gen_file,gend_files - -import os -import argparse -import re - -parser = argparse.ArgumentParser(description='Generate Decaf headers and other such files.') -parser.add_argument('--hpre', required = True, help = "Where to put the public header files") -parser.add_argument('--ihpre', required = True, help = "Where to put the internal header files") -parser.add_argument('--cpre', required = True, help = "Where to put the C/C++ implementation files") -args = parser.parse_args() - -prefixes = { (True,"h") : args.hpre, (True,"hxx") : args.hpre, (False,"c") : args.cpre, (False,"h") : args.ihpre } - -from decaf_hxx import decaf_hxx -from decaf_h import decaf_h -from crypto_h import crypto_h -from crypto_hxx import crypto_hxx -from curve_data import curve_data - -root_hxx_code = "\n".join(( - "#include <%s>" % name - for name in sorted(gend_files) - if re.match("^decaf/decaf_\d+.hxx$",name) -)) -root_hxx_code += """ - -namespace decaf { - template class Run> - void run_for_all_curves() { -""" -root_hxx_code += "\n".join(( - " Run<%s>::run();" % cd["cxx_ns"] - for cd in sorted(curve_data.values(), key=lambda x:x["c_ns"]) -)) -root_hxx_code += """ - } -} -""" -decaf_root_hxx = gen_file( - public = True, - per = "global", - name = "decaf.hxx", - doc = """@brief Decaf curve metaheader.""", - code = "\n"+root_hxx_code+"\n" -) - -crypto_h_code = "\n".join(( - "#include <%s>" % name - for name in sorted(gend_files) - if re.match("^decaf/crypto_\d+.h$",name) -)) -crypto_h = gen_file( - public = True, - per = "global", - name = "decaf/crypto.h", - doc = """ - Example Decaf crypto routines, metaheader. - @warning These are merely examples, though they ought to be secure. But real - protocols will decide differently on magic numbers, formats, which items to - hash, etc. - """, - code = "\n"+crypto_h_code+"\n" -) - -crypto_hxx_code = "\n".join(( - "#include <%s>" % name - for name in sorted(gend_files) - if re.match("^decaf/crypto_\d+.hxx$",name) -)) -crypto_hxx = gen_file( - public = True, - per = "global", - name = "decaf/crypto.hxx", - doc = """ - Example Decaf crypto routines, C++, metaheader. - @warning These are merely examples, though they ought to be secure. But real - protocols will decide differently on magic numbers, formats, which items to - hash, etc. - """, - code = "\n"+crypto_hxx_code+"\n" -) - -root_h_code = "\n".join(( - "#include <%s>" % name - for name in sorted(gend_files) - if re.match("^decaf/decaf_\d+.h$",name) -)) -decaf_root_hxx = gen_file( - public = True, - per = "global", - name = "decaf.h", - doc = """ - Master header for Decaf library. - - The Decaf library implements cryptographic operations on a elliptic curve - groups of prime order p. It accomplishes this by using a twisted Edwards - curve (isogenous to Ed448-Goldilocks or Ed25519) and wiping out the cofactor. - - The formulas are all complete and have no special cases. However, some - functions can fail. For example, decoding functions can fail because not - every string is the encoding of a valid group element. - - The formulas contain no data-dependent branches, timing or memory accesses, - except for decaf_XXX_base_double_scalarmul_non_secret. - """, - code = "\n"+root_h_code+"\n" -) - - -for name,(public,code) in gend_files.iteritems(): - _,_,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)) - with open(prefix + "/" + name,"w") as f: - f.write(code + "\n") - - \ No newline at end of file diff --git a/src/gen_headers/template.py b/src/gen_headers/template.py index ba56cc8..0f9e380 100644 --- a/src/gen_headers/template.py +++ b/src/gen_headers/template.py @@ -13,7 +13,7 @@ parser.add_argument('--guard', required = False, default = None, help = "header parser.add_argument('files', metavar='file', type=str, nargs='+', help='a list of files to fill') args = parser.parse_args() -per_map = {"field":field_data, "curve":curve_data, "global":{"global":{}} } +per_map = {"field":field_data, "curve":curve_data, "global":{"global":{"field":field_data,"curve":curve_data} }} def redoc(filename,doc,author): doc = doc.replace("\n","\n * ") diff --git a/src/gen_headers/crypto_h.py b/src/per_curve/crypto.tmpl.h similarity index 63% rename from src/gen_headers/crypto_h.py rename to src/per_curve/crypto.tmpl.h index 8d5df60..39cab3e 100644 --- a/src/gen_headers/crypto_h.py +++ b/src/per_curve/crypto.tmpl.h @@ -1,17 +1,12 @@ -from gen_file import gen_file +/** + * Example Decaf crypto routines. + * @warning These are merely examples, though they ought to be secure. But real + * protocols will decide differently on magic numbers, formats, which items to + * hash, etc. + * @warning Experimental! The names, parameter orders etc are likely to change. + */ -crypto_h = gen_file( - public = True, - per = "curve", - name = "decaf/crypto_%(shortname)s.h", - doc = """ - Example Decaf crypto routines. - @warning These are merely examples, though they ought to be secure. But real - protocols will decide differently on magic numbers, formats, which items to - hash, etc. - @warning Experimental! The names, parameter orders etc are likely to change. - """, code = """ -#include +#include #include #ifdef __cplusplus @@ -19,48 +14,48 @@ extern "C" { #endif /** Number of bytes for a symmetric key (expanded to full key) */ -#define %(C_NS)s_SYMMETRIC_KEY_BYTES 32 +#define $(C_NS)_SYMMETRIC_KEY_BYTES 32 /** A symmetric key, the compressed point of a private key. */ -typedef unsigned char %(c_ns)s_symmetric_key_t[%(C_NS)s_SYMMETRIC_KEY_BYTES]; +typedef unsigned char $(c_ns)_symmetric_key_t[$(C_NS)_SYMMETRIC_KEY_BYTES]; /** An encoded public key. */ -typedef unsigned char %(c_ns)s_public_key_t[%(C_NS)s_SER_BYTES]; +typedef unsigned char $(c_ns)_public_key_t[$(C_NS)_SER_BYTES]; /** A signature. */ -typedef unsigned char %(c_ns)s_signature_t[%(C_NS)s_SER_BYTES + %(C_NS)s_SCALAR_BYTES]; +typedef unsigned char $(c_ns)_signature_t[$(C_NS)_SER_BYTES + $(C_NS)_SCALAR_BYTES]; typedef struct { /** @cond internal */ /** The symmetric key from which everything is expanded */ - %(c_ns)s_symmetric_key_t sym; + $(c_ns)_symmetric_key_t sym; /** The scalar x */ - %(c_ns)s_scalar_t secret_scalar; + $(c_ns)_scalar_t secret_scalar; /** x*Base */ - %(c_ns)s_public_key_t pub; + $(c_ns)_public_key_t pub; /** @endcond */ } /** Private key structure for pointers. */ - %(c_ns)s_private_key_s, + $(c_ns)_private_key_s, /** A private key (gmp array[1] style). */ - %(c_ns)s_private_key_t[1]; + $(c_ns)_private_key_t[1]; /** * Derive a key from its compressed form. * @param [out] priv The derived private key. * @param [in] proto The compressed or proto-key, which must be 32 random bytes. */ -void %(c_ns)s_derive_private_key ( - %(c_ns)s_private_key_t priv, - const %(c_ns)s_symmetric_key_t proto +void $(c_ns)_derive_private_key ( + $(c_ns)_private_key_t priv, + const $(c_ns)_symmetric_key_t proto ) NONNULL2 API_VIS; /** * Destroy a private key. */ -void %(c_ns)s_destroy_private_key ( - %(c_ns)s_private_key_t priv +void $(c_ns)_destroy_private_key ( + $(c_ns)_private_key_t priv ) NONNULL1 API_VIS; /** @@ -68,9 +63,9 @@ void %(c_ns)s_destroy_private_key ( * @param [out] pub The extracted private key. * @param [in] priv The private key. */ -void %(c_ns)s_private_to_public ( - %(c_ns)s_public_key_t pub, - const %(c_ns)s_private_key_t priv +void $(c_ns)_private_to_public ( + $(c_ns)_public_key_t pub, + const $(c_ns)_private_key_t priv ) NONNULL2 API_VIS; /** @@ -89,11 +84,11 @@ void %(c_ns)s_private_to_public ( * @retval DECAF_FAILURE Key exchange failed. */ decaf_error_t -%(c_ns)s_shared_secret ( +$(c_ns)_shared_secret ( uint8_t *shared, size_t shared_bytes, - const %(c_ns)s_private_key_t my_privkey, - const %(c_ns)s_public_key_t your_pubkey, + const $(c_ns)_private_key_t my_privkey, + const $(c_ns)_public_key_t your_pubkey, int me_first ) NONNULL134 WARN_UNUSED API_VIS; @@ -105,10 +100,10 @@ decaf_error_t * @param [in] strobe A STROBE context with the message. */ void -%(c_ns)s_sign_strobe ( +$(c_ns)_sign_strobe ( keccak_strobe_t strobe, - %(c_ns)s_signature_t sig, - const %(c_ns)s_private_key_t priv + $(c_ns)_signature_t sig, + const $(c_ns)_private_key_t priv ) NONNULL3 API_VIS; /** @@ -120,9 +115,9 @@ void * @param [in] message_len The message's length. */ void -%(c_ns)s_sign ( - %(c_ns)s_signature_t sig, - const %(c_ns)s_private_key_t priv, +$(c_ns)_sign ( + $(c_ns)_signature_t sig, + const $(c_ns)_private_key_t priv, const unsigned char *message, size_t message_len ) NONNULL3 API_VIS; @@ -138,10 +133,10 @@ void * @return DECAF_FAILURE The signature did not verify successfully. */ decaf_error_t -%(c_ns)s_verify_strobe ( +$(c_ns)_verify_strobe ( keccak_strobe_t strobe, - const %(c_ns)s_signature_t sig, - const %(c_ns)s_public_key_t pub + const $(c_ns)_signature_t sig, + const $(c_ns)_public_key_t pub ) NONNULL3 API_VIS WARN_UNUSED; /** @@ -156,9 +151,9 @@ decaf_error_t * @return DECAF_FAILURE The signature did not verify successfully. */ decaf_error_t -%(c_ns)s_verify ( - const %(c_ns)s_signature_t sig, - const %(c_ns)s_public_key_t pub, +$(c_ns)_verify ( + const $(c_ns)_signature_t sig, + const $(c_ns)_public_key_t pub, const unsigned char *message, size_t message_len ) NONNULL3 API_VIS WARN_UNUSED; @@ -166,4 +161,3 @@ decaf_error_t #ifdef __cplusplus } /* extern "C" */ #endif -""") diff --git a/src/gen_headers/crypto_hxx.py b/src/per_curve/crypto.tmpl.hxx similarity index 63% rename from src/gen_headers/crypto_hxx.py rename to src/per_curve/crypto.tmpl.hxx index 7a0bf21..bc37c23 100644 --- a/src/gen_headers/crypto_hxx.py +++ b/src/per_curve/crypto.tmpl.hxx @@ -1,17 +1,12 @@ -from gen_file import gen_file +/* + * Example Decaf cyrpto routines, C++ wrapper. + * @warning These are merely examples, though they ought to be secure. But real + * protocols will decide differently on magic numbers, formats, which items to + * hash, etc. + * @warning Experimental! The names, parameter orders etc are likely to change. + */ -crypto_hxx = gen_file( - public = True, - per = "curve", - name = "decaf/crypto_%(shortname)s.hxx", - doc = """ - Example Decaf cyrpto routines, C++ wrapper. - @warning These are merely examples, though they ought to be secure. But real - protocols will decide differently on magic numbers, formats, which items to - hash, etc. - @warning Experimental! The names, parameter orders etc are likely to change. - """, code = """ -#include +#include #include #include @@ -31,21 +26,21 @@ template class PublicKey; /** A private key for crypto over some Group */ template class PrivateKey; -/** A public key for crypto over %(name)s */ -template<> class PublicKey<%(cxx_ns)s> - : public Serializable< PublicKey<%(cxx_ns)s> > { +/** A public key for crypto over $(name) */ +template<> class PublicKey<$(cxx_ns)> + : public Serializable< PublicKey<$(cxx_ns)> > { private: /** @cond internal */ - typedef %(c_ns)s_public_key_t Wrapped; + typedef $(c_ns)_public_key_t Wrapped; Wrapped wrapped; template friend class PrivateKey; /** @endcond */ public: /** Underlying group */ - typedef %(cxx_ns)s Group; + typedef $(cxx_ns) Group; /** Signature size. */ - static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t); + static const size_t SIG_BYTES = sizeof($(c_ns)_signature_t); /** Serialization size. */ static const size_t SER_BYTES = sizeof(Wrapped); @@ -56,7 +51,7 @@ public: } /** Read a private key from a string*/ - inline explicit PublicKey(const PrivateKey<%(cxx_ns)s> &b) NOEXCEPT; + inline explicit PublicKey(const PrivateKey<$(cxx_ns)> &b) NOEXCEPT; /** Create but don't initialize */ inline explicit PublicKey(const NOINIT&) NOEXCEPT { } @@ -74,7 +69,7 @@ public: const Block &message, const FixedBlock &sig ) const throw(CryptoException) { - if (DECAF_SUCCESS != %(c_ns)s_verify(sig.data(),wrapped,message.data(),message.size())) { + if (DECAF_SUCCESS != $(c_ns)_verify(sig.data(),wrapped,message.data(),message.size())) { throw(CryptoException()); } } @@ -84,33 +79,33 @@ public: Strobe &context, const FixedBlock &sig ) const throw(CryptoException) { - if (DECAF_SUCCESS != %(c_ns)s_verify_strobe(context.wrapped,sig.data(),wrapped)) { + if (DECAF_SUCCESS != $(c_ns)_verify_strobe(context.wrapped,sig.data(),wrapped)) { throw(CryptoException()); } } }; -/** A private key for crypto over %(name)s */ -template<> class PrivateKey<%(cxx_ns)s> - : public Serializable< PrivateKey<%(cxx_ns)s> > { +/** A private key for crypto over $(name) */ +template<> class PrivateKey<$(cxx_ns)> + : public Serializable< PrivateKey<$(cxx_ns)> > { private: /** @cond internal */ - typedef %(c_ns)s_private_key_t Wrapped; + typedef $(c_ns)_private_key_t Wrapped; Wrapped wrapped; template friend class PublicKey; /** @endcond */ public: /** Underlying group */ - typedef %(cxx_ns)s Group; + typedef $(cxx_ns) Group; /** Signature size. */ - static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t); + static const size_t SIG_BYTES = sizeof($(c_ns)_signature_t); /** Serialization size. */ static const size_t SER_BYTES = sizeof(Wrapped); /** Compressed size. */ - static const size_t SYM_BYTES = %(C_NS)s_SYMMETRIC_KEY_BYTES; + static const size_t SYM_BYTES = $(C_NS)_SYMMETRIC_KEY_BYTES; /** Create but don't initialize */ inline explicit PrivateKey(const NOINIT&) NOEXCEPT { } @@ -122,18 +117,18 @@ public: /** Read a private key from a string*/ inline explicit PrivateKey(const FixedBlock &b) NOEXCEPT { - %(c_ns)s_derive_private_key(wrapped, b.data()); + $(c_ns)_derive_private_key(wrapped, b.data()); } /** Create at random */ inline explicit PrivateKey(Rng &r) NOEXCEPT { FixedArrayBuffer tmp(r); - %(c_ns)s_derive_private_key(wrapped, tmp.data()); + $(c_ns)_derive_private_key(wrapped, tmp.data()); } /** Secure destructor */ inline ~PrivateKey() NOEXCEPT { - %(c_ns)s_destroy_private_key(wrapped); + $(c_ns)_destroy_private_key(wrapped); } /** Serialization size. */ @@ -152,18 +147,18 @@ public: } /** Get the public key */ - inline PublicKey<%(cxx_ns)s> pub() const NOEXCEPT { - PublicKey<%(cxx_ns)s> ret(*this); return ret; + inline PublicKey<$(cxx_ns)> pub() const NOEXCEPT { + PublicKey<$(cxx_ns)> ret(*this); return ret; } /** Derive a shared secret */ inline SecureBuffer sharedSecret( - const PublicKey<%(cxx_ns)s> &pub, + const PublicKey<$(cxx_ns)> &pub, size_t bytes, bool me_first ) const throw(CryptoException,std::bad_alloc) { SecureBuffer ret(bytes); - if (DECAF_SUCCESS != %(c_ns)s_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) { + if (DECAF_SUCCESS != $(c_ns)_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) { throw(CryptoException()); } return ret; @@ -173,33 +168,32 @@ public: inline decaf_error_t __attribute__((warn_unused_result)) sharedSecretNoexcept( Buffer ret, - const PublicKey<%(cxx_ns)s> &pub, + const PublicKey<$(cxx_ns)> &pub, bool me_first ) const NOEXCEPT { - return %(c_ns)s_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first); + return $(c_ns)_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first); } /** Sign a message. */ inline SecureBuffer sign(const Block &message) const { SecureBuffer sig(SIG_BYTES); - %(c_ns)s_sign(sig.data(), wrapped, message.data(), message.size()); + $(c_ns)_sign(sig.data(), wrapped, message.data(), message.size()); return sig; } /** Sign a message. */ inline SecureBuffer verify(Strobe &context) const { SecureBuffer sig(SIG_BYTES); - %(c_ns)s_sign_strobe(context.wrapped, sig.data(), wrapped); + $(c_ns)_sign_strobe(context.wrapped, sig.data(), wrapped); return sig; } }; /** @cond internal */ -PublicKey<%(cxx_ns)s>::PublicKey(const PrivateKey<%(cxx_ns)s> &b) NOEXCEPT { - %(c_ns)s_private_to_public(wrapped,b.wrapped); +PublicKey<$(cxx_ns)>::PublicKey(const PrivateKey<$(cxx_ns)> &b) NOEXCEPT { + $(c_ns)_private_to_public(wrapped,b.wrapped); } /** @endcond */ #undef NOEXCEPT -} /* namespace decaf */ -""") \ No newline at end of file +} /* namespace decaf */ \ No newline at end of file diff --git a/src/per_curve/decaf.tmpl.c b/src/per_curve/decaf.tmpl.c index c123d94..dee9531 100644 --- a/src/per_curve/decaf.tmpl.c +++ b/src/per_curve/decaf.tmpl.c @@ -19,7 +19,7 @@ #define IMAGINE_TWIST $(imagine_twist) #define COFACTOR $(cofactor) -/** Comb config: number of combs, n, t, s. */ +/* Comb config: number of combs, n, t, s. */ #define COMBS_N $(combs.n) #define COMBS_T $(combs.t) #define COMBS_S $(combs.s) @@ -39,9 +39,7 @@ static const scalar_t sc_p = {{{ }}}; 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)) -}; +const uint8_t API_NS(x_base_point)[SER_BYTES] = { $(ser(mont_base,8)) }; #if COFACTOR==8 static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( diff --git a/src/gen_headers/decaf_h.py b/src/per_curve/decaf.tmpl.h similarity index 66% rename from src/gen_headers/decaf_h.py rename to src/per_curve/decaf.tmpl.h index ceddec0..fdf1dae 100644 --- a/src/gen_headers/decaf_h.py +++ b/src/per_curve/decaf.tmpl.h @@ -1,11 +1,5 @@ -from gen_file import gen_file - -decaf_h = gen_file( - public = True, - per = "curve", - name = "decaf/%(c_ns)s.h", - doc = """@brief A group of prime order p, based on %(iso_to)s.""", - code = """ +/** @brief A group of prime order p, based on $(iso_to). */ + #include #ifdef __cplusplus @@ -13,78 +7,78 @@ extern "C" { #endif /** @cond internal */ -#define %(C_NS)s_SCALAR_LIMBS ((%(scalar_bits)d-1)/DECAF_WORD_BITS+1) +#define $(C_NS)_SCALAR_LIMBS (($(scalar_bits)-1)/DECAF_WORD_BITS+1) /** @endcond */ /** The number of bits in a scalar */ -#define %(C_NS)s_SCALAR_BITS %(scalar_bits)d +#define $(C_NS)_SCALAR_BITS $(scalar_bits) /** @cond internal */ -#ifndef __DECAF_%(gf_shortname)s_GF_DEFINED__ -#define __DECAF_%(gf_shortname)s_GF_DEFINED__ 1 +#ifndef __DECAF_$(gf_shortname)_GF_DEFINED__ +#define __DECAF_$(gf_shortname)_GF_DEFINED__ 1 /** @brief Galois field element internal structure */ -typedef struct gf_%(gf_shortname)s_s { - decaf_word_t limb[%(gf_impl_bits)d/DECAF_WORD_BITS]; -} __attribute__((aligned(32))) gf_%(gf_shortname)s_s, gf_%(gf_shortname)s_t[1]; -#endif /* __DECAF_%(gf_shortname)s_GF_DEFINED__ */ +typedef struct gf_$(gf_shortname)_s { + decaf_word_t limb[$(gf_impl_bits)/DECAF_WORD_BITS]; +} __attribute__((aligned(32))) gf_$(gf_shortname)_s, gf_$(gf_shortname)_t[1]; +#endif /* __DECAF_$(gf_shortname)_GF_DEFINED__ */ /** @endcond */ /** Number of bytes in a serialized point. */ -#define %(C_NS)s_SER_BYTES %(ser_bytes)d +#define $(C_NS)_SER_BYTES $(ser_bytes) /** Number of bytes in a serialized scalar. */ -#define %(C_NS)s_SCALAR_BYTES %(scalar_ser_bytes)d +#define $(C_NS)_SCALAR_BYTES $(scalar_ser_bytes) -/** Number of bytes in an x%(gf_shortname)s public key */ -#define X%(gf_shortname)s_PUBLIC_BYTES %(x_pub_bytes)d +/** Number of bytes in an x$(gf_shortname) public key */ +#define X$(gf_shortname)_PUBLIC_BYTES $(x_pub_bytes) -/** Number of bytes in an x%(gf_shortname)s private key */ -#define X%(gf_shortname)s_PRIVATE_BYTES %(x_priv_bytes)d +/** Number of bytes in an x$(gf_shortname) private key */ +#define X$(gf_shortname)_PRIVATE_BYTES $(x_priv_bytes) /** Twisted Edwards extended homogeneous coordinates */ -typedef struct %(c_ns)s_point_s { +typedef struct $(c_ns)_point_s { /** @cond internal */ - gf_%(gf_shortname)s_t x,y,z,t; + gf_$(gf_shortname)_t x,y,z,t; /** @endcond */ -} %(c_ns)s_point_t[1]; +} $(c_ns)_point_t[1]; /** Precomputed table based on a point. Can be trivial implementation. */ -struct %(c_ns)s_precomputed_s; +struct $(c_ns)_precomputed_s; /** Precomputed table based on a point. Can be trivial implementation. */ -typedef struct %(c_ns)s_precomputed_s %(c_ns)s_precomputed_s; +typedef struct $(c_ns)_precomputed_s $(c_ns)_precomputed_s; /** Size and alignment of precomputed point tables. */ -extern const size_t %(c_ns)s_sizeof_precomputed_s API_VIS, %(c_ns)s_alignof_precomputed_s API_VIS; +extern const size_t $(c_ns)_sizeof_precomputed_s API_VIS, $(c_ns)_alignof_precomputed_s API_VIS; /** Scalar is stored packed, because we don't need the speed. */ -typedef struct %(c_ns)s_scalar_s { +typedef struct $(c_ns)_scalar_s { /** @cond internal */ - decaf_word_t limb[%(C_NS)s_SCALAR_LIMBS]; + decaf_word_t limb[$(C_NS)_SCALAR_LIMBS]; /** @endcond */ -} %(c_ns)s_scalar_t[1]; +} $(c_ns)_scalar_t[1]; /** A scalar equal to 1. */ -extern const %(c_ns)s_scalar_t %(c_ns)s_scalar_one API_VIS; +extern const $(c_ns)_scalar_t $(c_ns)_scalar_one API_VIS; /** A scalar equal to 0. */ -extern const %(c_ns)s_scalar_t %(c_ns)s_scalar_zero API_VIS; +extern const $(c_ns)_scalar_t $(c_ns)_scalar_zero API_VIS; /** The identity point on the curve. */ -extern const %(c_ns)s_point_t %(c_ns)s_point_identity API_VIS; +extern const $(c_ns)_point_t $(c_ns)_point_identity API_VIS; /** An arbitrarily chosen base point on the curve. * @warning TODO: this is subject to change. It is currently - * the preimage of the X%(gf_shortname)s base point. Sometime - * soon, we will merge and finalize support for X%(gf_shortname)s - * and Ed%(gf_shortname)s integration. This might make some + * the preimage of the X$(gf_shortname) base point. Sometime + * soon, we will merge and finalize support for X$(gf_shortname) + * and Ed$(gf_shortname) integration. This might make some * multiple of the current basepoint (eg twice it, or the cofactor * times it) more convenient API-wise, and trigger a changeover. */ -extern const %(c_ns)s_point_t %(c_ns)s_point_base API_VIS; +extern const $(c_ns)_point_t $(c_ns)_point_base API_VIS; /** Precomputed table for the base point on the curve. */ -extern const struct %(c_ns)s_precomputed_s *%(c_ns)s_precomputed_base API_VIS; +extern const struct $(c_ns)_precomputed_s *$(c_ns)_precomputed_base API_VIS; /** * @brief Read a scalar from wire format or from bytes. @@ -96,9 +90,9 @@ extern const struct %(c_ns)s_precomputed_s *%(c_ns)s_precomputed_base API_VIS; * @retval DECAF_FAILURE The scalar was greater than the modulus, * and has been reduced modulo that modulus. */ -decaf_error_t %(c_ns)s_scalar_decode ( - %(c_ns)s_scalar_t out, - const unsigned char ser[%(C_NS)s_SCALAR_BYTES] +decaf_error_t $(c_ns)_scalar_decode ( + $(c_ns)_scalar_t out, + const unsigned char ser[$(C_NS)_SCALAR_BYTES] ) API_VIS WARN_UNUSED NONNULL2 NOINLINE; /** @@ -109,8 +103,8 @@ decaf_error_t %(c_ns)s_scalar_decode ( * @param [in] ser_len Length of serialized form. * @param [out] out Deserialized form. */ -void %(c_ns)s_scalar_decode_long ( - %(c_ns)s_scalar_t out, +void $(c_ns)_scalar_decode_long ( + $(c_ns)_scalar_t out, const unsigned char *ser, size_t ser_len ) API_VIS NONNULL2 NOINLINE; @@ -121,9 +115,9 @@ void %(c_ns)s_scalar_decode_long ( * @param [out] ser Serialized form of a scalar. * @param [in] s Deserialized scalar. */ -void %(c_ns)s_scalar_encode ( - unsigned char ser[%(C_NS)s_SCALAR_BYTES], - const %(c_ns)s_scalar_t s +void $(c_ns)_scalar_encode ( + unsigned char ser[$(C_NS)_SCALAR_BYTES], + const $(c_ns)_scalar_t s ) API_VIS NONNULL2 NOINLINE NOINLINE; /** @@ -132,10 +126,10 @@ void %(c_ns)s_scalar_encode ( * @param [in] b Another scalar. * @param [out] out a+b. */ -void %(c_ns)s_scalar_add ( - %(c_ns)s_scalar_t out, - const %(c_ns)s_scalar_t a, - const %(c_ns)s_scalar_t b +void $(c_ns)_scalar_add ( + $(c_ns)_scalar_t out, + const $(c_ns)_scalar_t a, + const $(c_ns)_scalar_t b ) API_VIS NONNULL3 NOINLINE; /** @@ -145,9 +139,9 @@ void %(c_ns)s_scalar_add ( * @retval DECAF_TRUE The scalars are equal. * @retval DECAF_FALSE The scalars are not equal. */ -decaf_bool_t %(c_ns)s_scalar_eq ( - const %(c_ns)s_scalar_t a, - const %(c_ns)s_scalar_t b +decaf_bool_t $(c_ns)_scalar_eq ( + const $(c_ns)_scalar_t a, + const $(c_ns)_scalar_t b ) API_VIS WARN_UNUSED NONNULL2 NOINLINE; /** @@ -156,10 +150,10 @@ decaf_bool_t %(c_ns)s_scalar_eq ( * @param [in] b Another scalar. * @param [out] out a-b. */ -void %(c_ns)s_scalar_sub ( - %(c_ns)s_scalar_t out, - const %(c_ns)s_scalar_t a, - const %(c_ns)s_scalar_t b +void $(c_ns)_scalar_sub ( + $(c_ns)_scalar_t out, + const $(c_ns)_scalar_t a, + const $(c_ns)_scalar_t b ) API_VIS NONNULL3 NOINLINE; /** @@ -168,10 +162,10 @@ void %(c_ns)s_scalar_sub ( * @param [in] b Another scalar. * @param [out] out a*b. */ -void %(c_ns)s_scalar_mul ( - %(c_ns)s_scalar_t out, - const %(c_ns)s_scalar_t a, - const %(c_ns)s_scalar_t b +void $(c_ns)_scalar_mul ( + $(c_ns)_scalar_t out, + const $(c_ns)_scalar_t a, + const $(c_ns)_scalar_t b ) API_VIS NONNULL3 NOINLINE; /** @@ -180,9 +174,9 @@ void %(c_ns)s_scalar_mul ( * @param [out] out 1/a. * @return DECAF_SUCCESS The input is nonzero. */ -decaf_error_t %(c_ns)s_scalar_invert ( - %(c_ns)s_scalar_t out, - const %(c_ns)s_scalar_t a +decaf_error_t $(c_ns)_scalar_invert ( + $(c_ns)_scalar_t out, + const $(c_ns)_scalar_t a ) API_VIS WARN_UNUSED NONNULL2 NOINLINE; /** @@ -191,9 +185,9 @@ decaf_error_t %(c_ns)s_scalar_invert ( * @param [in] a A scalar. * @param [out] out Will become a copy of a. */ -static inline void NONNULL2 %(c_ns)s_scalar_copy ( - %(c_ns)s_scalar_t out, - const %(c_ns)s_scalar_t a +static inline void NONNULL2 $(c_ns)_scalar_copy ( + $(c_ns)_scalar_t out, + const $(c_ns)_scalar_t a ) { *out = *a; } @@ -203,8 +197,8 @@ static inline void NONNULL2 %(c_ns)s_scalar_copy ( * @param [in] a An integer. * @param [out] out Will become equal to a. */ -void %(c_ns)s_scalar_set_unsigned ( - %(c_ns)s_scalar_t out, +void $(c_ns)_scalar_set_unsigned ( + $(c_ns)_scalar_t out, uint64_t a ) API_VIS NONNULL1; @@ -214,9 +208,9 @@ void %(c_ns)s_scalar_set_unsigned ( * @param [out] ser The byte representation of the point. * @param [in] pt The point to encode. */ -void %(c_ns)s_point_encode ( - uint8_t ser[%(C_NS)s_SER_BYTES], - const %(c_ns)s_point_t pt +void $(c_ns)_point_encode ( + uint8_t ser[$(C_NS)_SER_BYTES], + const $(c_ns)_point_t pt ) API_VIS NONNULL2 NOINLINE; /** @@ -233,9 +227,9 @@ void %(c_ns)s_point_encode ( * @retval DECAF_FAILURE The decoding didn't succeed, because * ser does not represent a point. */ -decaf_error_t %(c_ns)s_point_decode ( - %(c_ns)s_point_t pt, - const uint8_t ser[%(C_NS)s_SER_BYTES], +decaf_error_t $(c_ns)_point_decode ( + $(c_ns)_point_t pt, + const uint8_t ser[$(C_NS)_SER_BYTES], decaf_bool_t allow_identity ) API_VIS WARN_UNUSED NONNULL2 NOINLINE; @@ -246,9 +240,9 @@ decaf_error_t %(c_ns)s_point_decode ( * @param [out] a A copy of the point. * @param [in] b Any point. */ -static inline void NONNULL2 %(c_ns)s_point_copy ( - %(c_ns)s_point_t a, - const %(c_ns)s_point_t b +static inline void NONNULL2 $(c_ns)_point_copy ( + $(c_ns)_point_t a, + const $(c_ns)_point_t b ) { *a=*b; } @@ -262,9 +256,9 @@ static inline void NONNULL2 %(c_ns)s_point_copy ( * @retval DECAF_TRUE The points are equal. * @retval DECAF_FALSE The points are not equal. */ -decaf_bool_t %(c_ns)s_point_eq ( - const %(c_ns)s_point_t a, - const %(c_ns)s_point_t b +decaf_bool_t $(c_ns)_point_eq ( + const $(c_ns)_point_t a, + const $(c_ns)_point_t b ) API_VIS WARN_UNUSED NONNULL2 NOINLINE; /** @@ -276,22 +270,22 @@ decaf_bool_t %(c_ns)s_point_eq ( * @param [in] a An addend. * @param [in] b An addend. */ -void %(c_ns)s_point_add ( - %(c_ns)s_point_t sum, - const %(c_ns)s_point_t a, - const %(c_ns)s_point_t b +void $(c_ns)_point_add ( + $(c_ns)_point_t sum, + const $(c_ns)_point_t a, + const $(c_ns)_point_t b ) API_VIS NONNULL3; /** * @brief Double a point. Equivalent to - * %(c_ns)s_point_add(two_a,a,a), but potentially faster. + * $(c_ns)_point_add(two_a,a,a), but potentially faster. * * @param [out] two_a The sum a+a. * @param [in] a A point. */ -void %(c_ns)s_point_double ( - %(c_ns)s_point_t two_a, - const %(c_ns)s_point_t a +void $(c_ns)_point_double ( + $(c_ns)_point_t two_a, + const $(c_ns)_point_t a ) API_VIS NONNULL2; /** @@ -303,10 +297,10 @@ void %(c_ns)s_point_double ( * @param [in] a The minuend. * @param [in] b The subtrahend. */ -void %(c_ns)s_point_sub ( - %(c_ns)s_point_t diff, - const %(c_ns)s_point_t a, - const %(c_ns)s_point_t b +void $(c_ns)_point_sub ( + $(c_ns)_point_t diff, + const $(c_ns)_point_t a, + const $(c_ns)_point_t b ) API_VIS NONNULL3; /** @@ -316,9 +310,9 @@ void %(c_ns)s_point_sub ( * @param [out] nega The negated input point * @param [in] a The input point. */ -void %(c_ns)s_point_negate ( - %(c_ns)s_point_t nega, - const %(c_ns)s_point_t a +void $(c_ns)_point_negate ( + $(c_ns)_point_t nega, + const $(c_ns)_point_t a ) API_VIS NONNULL2; /** @@ -328,10 +322,10 @@ void %(c_ns)s_point_negate ( * @param [in] base The point to be scaled. * @param [in] scalar The scalar to multiply by. */ -void %(c_ns)s_point_scalarmul ( - %(c_ns)s_point_t scaled, - const %(c_ns)s_point_t base, - const %(c_ns)s_scalar_t scalar +void $(c_ns)_point_scalarmul ( + $(c_ns)_point_t scaled, + const $(c_ns)_point_t base, + const $(c_ns)_scalar_t scalar ) API_VIS NONNULL3 NOINLINE; /** @@ -351,10 +345,10 @@ void %(c_ns)s_point_scalarmul ( * @retval DECAF_FAILURE The scalarmul didn't succeed, because * base does not represent a point. */ -decaf_error_t %(c_ns)s_direct_scalarmul ( - uint8_t scaled[%(C_NS)s_SER_BYTES], - const uint8_t base[%(C_NS)s_SER_BYTES], - const %(c_ns)s_scalar_t scalar, +decaf_error_t $(c_ns)_direct_scalarmul ( + uint8_t scaled[$(C_NS)_SER_BYTES], + const uint8_t base[$(C_NS)_SER_BYTES], + const $(c_ns)_scalar_t scalar, decaf_bool_t allow_identity, decaf_bool_t short_circuit ) API_VIS NONNULL3 WARN_UNUSED NOINLINE; @@ -371,14 +365,14 @@ decaf_error_t %(c_ns)s_direct_scalarmul ( * @retval DECAF_FAILURE The scalarmul didn't succeed, because the base * point is in a small subgroup. */ -decaf_error_t %(c_ns)s_x_direct_scalarmul ( /* TODO: rename? */ - uint8_t out[X%(gf_shortname)s_PUBLIC_BYTES], - const uint8_t base[X%(gf_shortname)s_PUBLIC_BYTES], - const uint8_t scalar[X%(gf_shortname)s_PRIVATE_BYTES] +decaf_error_t $(c_ns)_x_direct_scalarmul ( /* TODO: rename? */ + uint8_t out[X$(gf_shortname)_PUBLIC_BYTES], + const uint8_t base[X$(gf_shortname)_PUBLIC_BYTES], + const uint8_t scalar[X$(gf_shortname)_PRIVATE_BYTES] ) API_VIS NONNULL3 WARN_UNUSED NOINLINE; -/** The base point for X%(gf_shortname)s Diffie-Hellman */ -extern const uint8_t %(c_ns)s_x_base_point[X%(gf_shortname)s_PUBLIC_BYTES] API_VIS; +/** The base point for X$(gf_shortname) Diffie-Hellman */ +extern const uint8_t $(c_ns)_x_base_point[X$(gf_shortname)_PUBLIC_BYTES] API_VIS; /** * @brief RFC 7748 Diffie-Hellman base point scalarmul. This function uses @@ -387,9 +381,9 @@ extern const uint8_t %(c_ns)s_x_base_point[X%(gf_shortname)s_PUBLIC_BYTES] API_V * @param [out] scaled The scaled point base*scalar * @param [in] scalar The scalar to multiply by. */ -void %(c_ns)s_x_base_scalarmul ( - uint8_t out[X%(gf_shortname)s_PUBLIC_BYTES], - const uint8_t scalar[X%(gf_shortname)s_PRIVATE_BYTES] +void $(c_ns)_x_base_scalarmul ( + uint8_t out[X$(gf_shortname)_PUBLIC_BYTES], + const uint8_t scalar[X$(gf_shortname)_PRIVATE_BYTES] ) API_VIS NONNULL2 NOINLINE; /** @@ -401,9 +395,9 @@ void %(c_ns)s_x_base_scalarmul ( * @param [out] a A precomputed table of multiples of the point. * @param [in] b Any point. */ -void %(c_ns)s_precompute ( - %(c_ns)s_precomputed_s *a, - const %(c_ns)s_point_t b +void $(c_ns)_precompute ( + $(c_ns)_precomputed_s *a, + const $(c_ns)_point_t b ) API_VIS NONNULL2 NOINLINE; /** @@ -411,23 +405,23 @@ void %(c_ns)s_precompute ( * scaled = scalar*base. * Some implementations do not include precomputed points; for * those implementations, this function is the same as - * %(c_ns)s_point_scalarmul + * $(c_ns)_point_scalarmul * * @param [out] scaled The scaled point base*scalar * @param [in] base The point to be scaled. * @param [in] scalar The scalar to multiply by. */ -void %(c_ns)s_precomputed_scalarmul ( - %(c_ns)s_point_t scaled, - const %(c_ns)s_precomputed_s *base, - const %(c_ns)s_scalar_t scalar +void $(c_ns)_precomputed_scalarmul ( + $(c_ns)_point_t scaled, + const $(c_ns)_precomputed_s *base, + const $(c_ns)_scalar_t scalar ) API_VIS NONNULL3 NOINLINE; /** * @brief Multiply two base points by two scalars: * scaled = scalar1*base1 + scalar2*base2. * - * Equivalent to two calls to %(c_ns)s_point_scalarmul, but may be + * Equivalent to two calls to $(c_ns)_point_scalarmul, but may be * faster. * * @param [out] combo The linear combination scalar1*base1 + scalar2*base2. @@ -436,12 +430,12 @@ void %(c_ns)s_precomputed_scalarmul ( * @param [in] base2 A second point to be scaled. * @param [in] scalar2 A second scalar to multiply by. */ -void %(c_ns)s_point_double_scalarmul ( - %(c_ns)s_point_t combo, - const %(c_ns)s_point_t base1, - const %(c_ns)s_scalar_t scalar1, - const %(c_ns)s_point_t base2, - const %(c_ns)s_scalar_t scalar2 +void $(c_ns)_point_double_scalarmul ( + $(c_ns)_point_t combo, + const $(c_ns)_point_t base1, + const $(c_ns)_scalar_t scalar1, + const $(c_ns)_point_t base2, + const $(c_ns)_scalar_t scalar2 ) API_VIS NONNULL5 NOINLINE; /** @@ -450,7 +444,7 @@ void %(c_ns)s_point_double_scalarmul ( * a1 = scalar1 * base * a2 = scalar2 * base * - * Equivalent to two calls to %(c_ns)s_point_scalarmul, but may be + * Equivalent to two calls to $(c_ns)_point_scalarmul, but may be * faster. * * @param [out] a1 The first multiple. It may be the same as the input point. @@ -459,19 +453,19 @@ void %(c_ns)s_point_double_scalarmul ( * @param [in] scalar1 A first scalar to multiply by. * @param [in] scalar2 A second scalar to multiply by. */ -void %(c_ns)s_point_dual_scalarmul ( - %(c_ns)s_point_t a1, - %(c_ns)s_point_t a2, - const %(c_ns)s_point_t base1, - const %(c_ns)s_scalar_t scalar1, - const %(c_ns)s_scalar_t scalar2 +void $(c_ns)_point_dual_scalarmul ( + $(c_ns)_point_t a1, + $(c_ns)_point_t a2, + const $(c_ns)_point_t base1, + const $(c_ns)_scalar_t scalar1, + const $(c_ns)_scalar_t scalar2 ) API_VIS NONNULL5 NOINLINE; /** * @brief Multiply two base points by two scalars: - * scaled = scalar1*%(c_ns)s_point_base + scalar2*base2. + * scaled = scalar1*$(c_ns)_point_base + scalar2*base2. * - * Otherwise equivalent to %(c_ns)s_point_double_scalarmul, but may be + * Otherwise equivalent to $(c_ns)_point_double_scalarmul, but may be * faster at the expense of being variable time. * * @param [out] combo The linear combination scalar1*base + scalar2*base2. @@ -482,11 +476,11 @@ void %(c_ns)s_point_dual_scalarmul ( * @warning: This function takes variable time, and may leak the scalars * used. It is designed for signature verification. */ -void %(c_ns)s_base_double_scalarmul_non_secret ( - %(c_ns)s_point_t combo, - const %(c_ns)s_scalar_t scalar1, - const %(c_ns)s_point_t base2, - const %(c_ns)s_scalar_t scalar2 +void $(c_ns)_base_double_scalarmul_non_secret ( + $(c_ns)_point_t combo, + const $(c_ns)_scalar_t scalar1, + const $(c_ns)_point_t base2, + const $(c_ns)_scalar_t scalar2 ) API_VIS NONNULL4 NOINLINE; /** @@ -498,10 +492,10 @@ void %(c_ns)s_base_double_scalarmul_non_secret ( * @param [in] b Any point. * @param [in] pick_b If nonzero, choose point b. */ -void %(c_ns)s_point_cond_sel ( - %(c_ns)s_point_t out, - const %(c_ns)s_point_t a, - const %(c_ns)s_point_t b, +void $(c_ns)_point_cond_sel ( + $(c_ns)_point_t out, + const $(c_ns)_point_t a, + const $(c_ns)_point_t b, decaf_word_t pick_b ) API_VIS NONNULL3 NOINLINE; @@ -514,10 +508,10 @@ void %(c_ns)s_point_cond_sel ( * @param [in] b Any scalar. * @param [in] pick_b If nonzero, choose scalar b. */ -void %(c_ns)s_scalar_cond_sel ( - %(c_ns)s_scalar_t out, - const %(c_ns)s_scalar_t a, - const %(c_ns)s_scalar_t b, +void $(c_ns)_scalar_cond_sel ( + $(c_ns)_scalar_t out, + const $(c_ns)_scalar_t a, + const $(c_ns)_scalar_t b, decaf_word_t pick_b ) API_VIS NONNULL3 NOINLINE; @@ -528,8 +522,8 @@ void %(c_ns)s_scalar_cond_sel ( * @retval DECAF_TRUE The point is valid. * @retval DECAF_FALSE The point is invalid. */ -decaf_bool_t %(c_ns)s_point_valid ( - const %(c_ns)s_point_t toTest +decaf_bool_t $(c_ns)_point_valid ( + const $(c_ns)_point_t toTest ) API_VIS WARN_UNUSED NONNULL1 NOINLINE; /** @@ -539,9 +533,9 @@ decaf_bool_t %(c_ns)s_point_valid ( * @param [out] q The point to torque. * @param [in] p The point to torque. */ -void %(c_ns)s_point_debugging_torque ( - %(c_ns)s_point_t q, - const %(c_ns)s_point_t p +void $(c_ns)_point_debugging_torque ( + $(c_ns)_point_t q, + const $(c_ns)_point_t p ) API_VIS NONNULL2 NOINLINE; /** @@ -553,10 +547,10 @@ void %(c_ns)s_point_debugging_torque ( * @param [in] p The point to scale. * @param [in] factor Serialized GF factor to scale. */ -void %(c_ns)s_point_debugging_pscale ( - %(c_ns)s_point_t q, - const %(c_ns)s_point_t p, - const unsigned char factor[%(C_NS)s_SER_BYTES] +void $(c_ns)_point_debugging_pscale ( + $(c_ns)_point_t q, + const $(c_ns)_point_t p, + const unsigned char factor[$(C_NS)_SER_BYTES] ) API_VIS NONNULL2 NOINLINE; /** @@ -564,7 +558,7 @@ void %(c_ns)s_point_debugging_pscale ( * * Call this function with the output of a hash to make a hash to the curve. * - * This function runs Elligator2 on the %(c_ns)s Jacobi quartic model. It then + * This function runs Elligator2 on the $(c_ns) Jacobi quartic model. It then * uses the isogeny to put the result in twisted Edwards form. As a result, * it is safe (cannot produce points of order 4), and would be compatible with * hypothetical other implementations of Decaf using a Montgomery or untwisted @@ -588,29 +582,29 @@ void %(c_ns)s_point_debugging_pscale ( * @param [out] pt The data hashed to the curve. */ void -%(c_ns)s_point_from_hash_nonuniform ( - %(c_ns)s_point_t pt, - const unsigned char hashed_data[%(C_NS)s_SER_BYTES] +$(c_ns)_point_from_hash_nonuniform ( + $(c_ns)_point_t pt, + const unsigned char hashed_data[$(C_NS)_SER_BYTES] ) API_VIS NONNULL2 NOINLINE; /** * @brief Indifferentiable hash function encoding to curve. * - * Equivalent to calling %(c_ns)s_point_from_hash_nonuniform twice and adding. + * Equivalent to calling $(c_ns)_point_from_hash_nonuniform twice and adding. * * @param [in] hashed_data Output of some hash function. * @param [out] pt The data hashed to the curve. */ -void %(c_ns)s_point_from_hash_uniform ( - %(c_ns)s_point_t pt, - const unsigned char hashed_data[2*%(C_NS)s_SER_BYTES] +void $(c_ns)_point_from_hash_uniform ( + $(c_ns)_point_t pt, + const unsigned char hashed_data[2*$(C_NS)_SER_BYTES] ) API_VIS NONNULL2 NOINLINE; /** * @brief Inverse of elligator-like hash to curve. * * This function writes to the buffer, to make it so that - * %(c_ns)s_point_from_hash_nonuniform(buffer) = pt if + * $(c_ns)_point_from_hash_nonuniform(buffer) = pt if * possible. Since there may be multiple preimages, the * "which" parameter chooses between them. To ensure uniform * inverse sampling, this function succeeds or fails @@ -625,9 +619,9 @@ void %(c_ns)s_point_from_hash_uniform ( * @retval DECAF_FAILURE The inverse failed. */ decaf_error_t -%(c_ns)s_invert_elligator_nonuniform ( - unsigned char recovered_hash[%(C_NS)s_SER_BYTES], - const %(c_ns)s_point_t pt, +$(c_ns)_invert_elligator_nonuniform ( + unsigned char recovered_hash[$(C_NS)_SER_BYTES], + const $(c_ns)_point_t pt, uint16_t which ) API_VIS NONNULL2 NOINLINE WARN_UNUSED; @@ -635,7 +629,7 @@ decaf_error_t * @brief Inverse of elligator-like hash to curve. * * This function writes to the buffer, to make it so that - * %(c_ns)s_point_from_hash_uniform(buffer) = pt if + * $(c_ns)_point_from_hash_uniform(buffer) = pt if * possible. Since there may be multiple preimages, the * "which" parameter chooses between them. To ensure uniform * inverse sampling, this function succeeds or fails @@ -650,36 +644,34 @@ decaf_error_t * @retval DECAF_FAILURE The inverse failed. */ decaf_error_t -%(c_ns)s_invert_elligator_uniform ( - unsigned char recovered_hash[2*%(C_NS)s_SER_BYTES], - const %(c_ns)s_point_t pt, +$(c_ns)_invert_elligator_uniform ( + unsigned char recovered_hash[2*$(C_NS)_SER_BYTES], + const $(c_ns)_point_t pt, uint16_t which ) API_VIS NONNULL2 NOINLINE WARN_UNUSED; /** * @brief Overwrite scalar with zeros. */ -void %(c_ns)s_scalar_destroy ( - %(c_ns)s_scalar_t scalar +void $(c_ns)_scalar_destroy ( + $(c_ns)_scalar_t scalar ) NONNULL1 API_VIS; /** * @brief Overwrite point with zeros. * @todo Use this internally. */ -void %(c_ns)s_point_destroy ( - %(c_ns)s_point_t point +void $(c_ns)_point_destroy ( + $(c_ns)_point_t point ) NONNULL1 API_VIS; /** * @brief Overwrite precomputed table with zeros. */ -void %(c_ns)s_precomputed_destroy ( - %(c_ns)s_precomputed_s *pre +void $(c_ns)_precomputed_destroy ( + $(c_ns)_precomputed_s *pre ) NONNULL1 API_VIS; #ifdef __cplusplus } /* extern "C" */ #endif -""" -) diff --git a/src/gen_headers/decaf_hxx.py b/src/per_curve/decaf.tmpl.hxx similarity index 75% rename from src/gen_headers/decaf_hxx.py rename to src/per_curve/decaf.tmpl.hxx index 94a91e3..c4cc01b 100644 --- a/src/gen_headers/decaf_hxx.py +++ b/src/per_curve/decaf.tmpl.hxx @@ -1,23 +1,18 @@ -from gen_file import gen_file - -decaf_hxx = gen_file( - public = True, - per = "curve", - name = "decaf/%(c_ns)s.hxx", - doc = """ - A group of prime order p, C++ wrapper. - - The Decaf library implements cryptographic operations on a an elliptic curve - group of prime order p. It accomplishes this by using a twisted Edwards - curve (isogenous to %(iso_to)s) and wiping out the cofactor. - - The formulas are all complete and have no special cases, except that - %(c_ns)s_decode can fail because not every sequence of bytes is a valid group - element. - - The formulas contain no data-dependent branches, timing or memory accesses, - except for %(c_ns)s_base_double_scalarmul_non_secret. - """, code = """ +/** + * A group of prime order p, C++ wrapper. + * + * The Decaf library implements cryptographic operations on a an elliptic curve + * group of prime order p. It accomplishes this by using a twisted Edwards + * curve (isogenous to $(iso_to)) and wiping out the cofactor. + * + * The formulas are all complete and have no special cases, except that + * $(c_ns)_decode can fail because not every sequence of bytes is a valid group + * element. + * + * The formulas contain no data-dependent branches, timing or memory accesses, + * except for $(c_ns)_base_double_scalarmul_non_secret. + */ + /** This code uses posix_memalign. */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 @@ -25,7 +20,7 @@ decaf_hxx = gen_file( #include #include /* for memcpy */ -#include +#include #include #include #include @@ -42,18 +37,18 @@ decaf_hxx = gen_file( namespace decaf { /** - * %(iso_to)s/Decaf instantiation of group. + * $(iso_to)/Decaf instantiation of group. */ -struct %(cxx_ns)s { +struct $(cxx_ns) { /** The name of the curve */ -static inline const char *name() { return "%(name)s"; } +static inline const char *name() { return "$(name)"; } /** The curve's cofactor (removed, but useful for testing) */ -static const int REMOVED_COFACTOR = %(cofactor)d; +static const int REMOVED_COFACTOR = $(cofactor); /** Residue class of field modulus: p == this mod 2*(this-1) */ -static const int FIELD_MODULUS_TYPE = %(modulus_type)d; +static const int FIELD_MODULUS_TYPE = $(modulus_type); /** @cond internal */ class Point; @@ -67,10 +62,10 @@ class Precomputed; class Scalar : public Serializable { public: /** wrapped C type */ - typedef %(c_ns)s_scalar_t Wrapped; + typedef $(c_ns)_scalar_t Wrapped; /** Size of a serialized element */ - static const size_t SER_BYTES = %(C_NS)s_SCALAR_BYTES; + static const size_t SER_BYTES = $(C_NS)_SCALAR_BYTES; /** access to the underlying scalar object */ Wrapped s; @@ -99,7 +94,7 @@ public: } /** Construct from decaf_scalar_t object. */ - inline Scalar(const Wrapped &t = %(c_ns)s_scalar_zero) NOEXCEPT { %(c_ns)s_scalar_copy(s,t); } + inline Scalar(const Wrapped &t = $(c_ns)_scalar_zero) NOEXCEPT { $(c_ns)_scalar_copy(s,t); } /** Copy constructor. */ inline Scalar(const Scalar &x) NOEXCEPT { *this = x; } @@ -112,20 +107,20 @@ public: /** Serializable instance */ inline void serialize_into(unsigned char *buffer) const NOEXCEPT { - %(c_ns)s_scalar_encode(buffer, s); + $(c_ns)_scalar_encode(buffer, s); } /** Assignment. */ - inline Scalar& operator=(const Scalar &x) NOEXCEPT { %(c_ns)s_scalar_copy(s,x.s); return *this; } + inline Scalar& operator=(const Scalar &x) NOEXCEPT { $(c_ns)_scalar_copy(s,x.s); return *this; } /** Assign from unsigned 64-bit integer. */ - inline Scalar& operator=(uint64_t w) NOEXCEPT { %(c_ns)s_scalar_set_unsigned(s,w); return *this; } + inline Scalar& operator=(uint64_t w) NOEXCEPT { $(c_ns)_scalar_set_unsigned(s,w); return *this; } /** Assign from signed int. */ inline Scalar& operator=(int64_t w) NOEXCEPT { Scalar t(-(uint64_t)INT_MIN); - %(c_ns)s_scalar_set_unsigned(s,(uint64_t)w - (uint64_t)INT_MIN); + $(c_ns)_scalar_set_unsigned(s,(uint64_t)w - (uint64_t)INT_MIN); *this -= t; return *this; } @@ -137,11 +132,11 @@ public: inline Scalar& operator=(int w) NOEXCEPT { return *this = (int64_t)w; } /** Destructor securely zeorizes the scalar. */ - inline ~Scalar() NOEXCEPT { %(c_ns)s_scalar_destroy(s); } + inline ~Scalar() NOEXCEPT { $(c_ns)_scalar_destroy(s); } /** Assign from arbitrary-length little-endian byte sequence in a Block. */ inline Scalar &operator=(const Block &bl) NOEXCEPT { - %(c_ns)s_scalar_decode_long(s,bl.data(),bl.size()); return *this; + $(c_ns)_scalar_decode_long(s,bl.data(),bl.size()); return *this; } /** @@ -151,35 +146,35 @@ public: static inline decaf_error_t WARN_UNUSED decode ( Scalar &sc, const FixedBlock buffer ) NOEXCEPT { - return %(c_ns)s_scalar_decode(sc.s,buffer.data()); + return $(c_ns)_scalar_decode(sc.s,buffer.data()); } /** Add. */ - inline Scalar operator+ (const Scalar &q) const NOEXCEPT { Scalar r((NOINIT())); %(c_ns)s_scalar_add(r.s,s,q.s); return r; } + inline Scalar operator+ (const Scalar &q) const NOEXCEPT { Scalar r((NOINIT())); $(c_ns)_scalar_add(r.s,s,q.s); return r; } /** Add to this. */ - inline Scalar &operator+=(const Scalar &q) NOEXCEPT { %(c_ns)s_scalar_add(s,s,q.s); return *this; } + inline Scalar &operator+=(const Scalar &q) NOEXCEPT { $(c_ns)_scalar_add(s,s,q.s); return *this; } /** Subtract. */ - inline Scalar operator- (const Scalar &q) const NOEXCEPT { Scalar r((NOINIT())); %(c_ns)s_scalar_sub(r.s,s,q.s); return r; } + inline Scalar operator- (const Scalar &q) const NOEXCEPT { Scalar r((NOINIT())); $(c_ns)_scalar_sub(r.s,s,q.s); return r; } /** Subtract from this. */ - inline Scalar &operator-=(const Scalar &q) NOEXCEPT { %(c_ns)s_scalar_sub(s,s,q.s); return *this; } + inline Scalar &operator-=(const Scalar &q) NOEXCEPT { $(c_ns)_scalar_sub(s,s,q.s); return *this; } /** Multiply */ - inline Scalar operator* (const Scalar &q) const NOEXCEPT { Scalar r((NOINIT())); %(c_ns)s_scalar_mul(r.s,s,q.s); return r; } + inline Scalar operator* (const Scalar &q) const NOEXCEPT { Scalar r((NOINIT())); $(c_ns)_scalar_mul(r.s,s,q.s); return r; } /** Multiply into this. */ - inline Scalar &operator*=(const Scalar &q) NOEXCEPT { %(c_ns)s_scalar_mul(s,s,q.s); return *this; } + inline Scalar &operator*=(const Scalar &q) NOEXCEPT { $(c_ns)_scalar_mul(s,s,q.s); return *this; } /** Negate */ - inline Scalar operator- () const NOEXCEPT { Scalar r((NOINIT())); %(c_ns)s_scalar_sub(r.s,%(c_ns)s_scalar_zero,s); return r; } + inline Scalar operator- () const NOEXCEPT { Scalar r((NOINIT())); $(c_ns)_scalar_sub(r.s,$(c_ns)_scalar_zero,s); return r; } /** Invert with Fermat's Little Theorem (slow!). If *this == 0, * throw CryptoException. */ inline Scalar inverse() const throw(CryptoException) { Scalar r; - if (DECAF_SUCCESS != %(c_ns)s_scalar_invert(r.s,s)) { + if (DECAF_SUCCESS != $(c_ns)_scalar_invert(r.s,s)) { throw CryptoException(); } return r; @@ -189,7 +184,7 @@ public: * and return DECAF_FAILURE. */ inline decaf_error_t WARN_UNUSED inverse_noexcept(Scalar &r) const NOEXCEPT { - return %(c_ns)s_scalar_invert(r.s,s); + return $(c_ns)_scalar_invert(r.s,s); } /** Divide by inverting q. If q == 0, return 0. */ @@ -202,7 +197,7 @@ public: inline bool operator!=(const Scalar &q) const NOEXCEPT { return !(*this == q); } /** Compare in constant time */ - inline bool operator==(const Scalar &q) const NOEXCEPT { return !!%(c_ns)s_scalar_eq(s,q.s); } + inline bool operator==(const Scalar &q) const NOEXCEPT { return !!$(c_ns)_scalar_eq(s,q.s); } /** Scalarmul with scalar on left. */ inline Point operator* (const Point &q) const NOEXCEPT { return q * (*this); } @@ -224,10 +219,10 @@ public: class Point : public Serializable { public: /** wrapped C type */ - typedef %(c_ns)s_point_t Wrapped; + typedef $(c_ns)_point_t Wrapped; /** Size of a serialized element */ - static const size_t SER_BYTES = %(C_NS)s_SER_BYTES; + static const size_t SER_BYTES = $(C_NS)_SER_BYTES; /** Bytes required for hash */ static const size_t HASH_BYTES = SER_BYTES; @@ -244,16 +239,16 @@ public: /** @endcond */ /** Constructor sets to identity by default. */ - inline Point(const Wrapped &q = %(c_ns)s_point_identity) NOEXCEPT { %(c_ns)s_point_copy(p,q); } + inline Point(const Wrapped &q = $(c_ns)_point_identity) NOEXCEPT { $(c_ns)_point_copy(p,q); } /** Copy constructor. */ inline Point(const Point &q) NOEXCEPT { *this = q; } /** Assignment. */ - inline Point& operator=(const Point &q) NOEXCEPT { %(c_ns)s_point_copy(p,q.p); return *this; } + inline Point& operator=(const Point &q) NOEXCEPT { $(c_ns)_point_copy(p,q.p); return *this; } /** Destructor securely zeorizes the point. */ - inline ~Point() NOEXCEPT { %(c_ns)s_point_destroy(p); } + inline ~Point() NOEXCEPT { $(c_ns)_point_destroy(p); } /** Construct from RNG */ inline explicit Point(Rng &rng, bool uniform = true) NOEXCEPT { @@ -291,7 +286,7 @@ public: static inline decaf_error_t WARN_UNUSED decode ( Point &p, const FixedBlock &buffer, decaf_bool_t allow_identity=DECAF_TRUE ) NOEXCEPT { - return %(c_ns)s_point_decode(p.p,buffer.data(),allow_identity); + return $(c_ns)_point_decode(p.p,buffer.data(),allow_identity); } /** @@ -314,15 +309,15 @@ public: if (s.size() < HASH_BYTES) { SecureBuffer b(HASH_BYTES); memcpy(b.data(), s.data(), s.size()); - %(c_ns)s_point_from_hash_nonuniform(p,b.data()); + $(c_ns)_point_from_hash_nonuniform(p,b.data()); } else if (s.size() == HASH_BYTES) { - %(c_ns)s_point_from_hash_nonuniform(p,s.data()); + $(c_ns)_point_from_hash_nonuniform(p,s.data()); } else if (s.size() < 2*HASH_BYTES) { SecureBuffer b(2*HASH_BYTES); memcpy(b.data(), s.data(), s.size()); - %(c_ns)s_point_from_hash_uniform(p,b.data()); + $(c_ns)_point_from_hash_uniform(p,b.data()); } else { - %(c_ns)s_point_from_hash_uniform(p,s.data()); + $(c_ns)_point_from_hash_uniform(p,s.data()); } } @@ -331,7 +326,7 @@ public: */ inline operator SecureBuffer() const { SecureBuffer buffer(SER_BYTES); - %(c_ns)s_point_encode(buffer.data(), p); + $(c_ns)_point_encode(buffer.data(), p); return buffer; } @@ -340,41 +335,41 @@ public: /** Serializable instance */ inline void serialize_into(unsigned char *buffer) const NOEXCEPT { - %(c_ns)s_point_encode(buffer, p); + $(c_ns)_point_encode(buffer, p); } /** Point add. */ - inline Point operator+ (const Point &q) const NOEXCEPT { Point r((NOINIT())); %(c_ns)s_point_add(r.p,p,q.p); return r; } + inline Point operator+ (const Point &q) const NOEXCEPT { Point r((NOINIT())); $(c_ns)_point_add(r.p,p,q.p); return r; } /** Point add. */ - inline Point &operator+=(const Point &q) NOEXCEPT { %(c_ns)s_point_add(p,p,q.p); return *this; } + inline Point &operator+=(const Point &q) NOEXCEPT { $(c_ns)_point_add(p,p,q.p); return *this; } /** Point subtract. */ - inline Point operator- (const Point &q) const NOEXCEPT { Point r((NOINIT())); %(c_ns)s_point_sub(r.p,p,q.p); return r; } + inline Point operator- (const Point &q) const NOEXCEPT { Point r((NOINIT())); $(c_ns)_point_sub(r.p,p,q.p); return r; } /** Point subtract. */ - inline Point &operator-=(const Point &q) NOEXCEPT { %(c_ns)s_point_sub(p,p,q.p); return *this; } + inline Point &operator-=(const Point &q) NOEXCEPT { $(c_ns)_point_sub(p,p,q.p); return *this; } /** Point negate. */ - inline Point operator- () const NOEXCEPT { Point r((NOINIT())); %(c_ns)s_point_negate(r.p,p); return r; } + inline Point operator- () const NOEXCEPT { Point r((NOINIT())); $(c_ns)_point_negate(r.p,p); return r; } /** Double the point out of place. */ - inline Point times_two () const NOEXCEPT { Point r((NOINIT())); %(c_ns)s_point_double(r.p,p); return r; } + inline Point times_two () const NOEXCEPT { Point r((NOINIT())); $(c_ns)_point_double(r.p,p); return r; } /** Double the point in place. */ - inline Point &double_in_place() NOEXCEPT { %(c_ns)s_point_double(p,p); return *this; } + inline Point &double_in_place() NOEXCEPT { $(c_ns)_point_double(p,p); return *this; } /** Constant-time compare. */ - inline bool operator!=(const Point &q) const NOEXCEPT { return ! %(c_ns)s_point_eq(p,q.p); } + inline bool operator!=(const Point &q) const NOEXCEPT { return ! $(c_ns)_point_eq(p,q.p); } /** Constant-time compare. */ - inline bool operator==(const Point &q) const NOEXCEPT { return !!%(c_ns)s_point_eq(p,q.p); } + inline bool operator==(const Point &q) const NOEXCEPT { return !!$(c_ns)_point_eq(p,q.p); } /** Scalar multiply. */ - inline Point operator* (const Scalar &s) const NOEXCEPT { Point r((NOINIT())); %(c_ns)s_point_scalarmul(r.p,p,s.s); return r; } + inline Point operator* (const Scalar &s) const NOEXCEPT { Point r((NOINIT())); $(c_ns)_point_scalarmul(r.p,p,s.s); return r; } /** Scalar multiply in place. */ - inline Point &operator*=(const Scalar &s) NOEXCEPT { %(c_ns)s_point_scalarmul(p,p,s.s); return *this; } + inline Point &operator*=(const Scalar &s) NOEXCEPT { $(c_ns)_point_scalarmul(p,p,s.s); return *this; } /** Multiply by s.inverse(). If s=0, maps to the identity. */ inline Point operator/ (const Scalar &s) const throw(CryptoException) { return (*this) * s.inverse(); } @@ -383,20 +378,20 @@ public: inline Point &operator/=(const Scalar &s) throw(CryptoException) { return (*this) *= s.inverse(); } /** Validate / sanity check */ - inline bool validate() const NOEXCEPT { return %(c_ns)s_point_valid(p); } + inline bool validate() const NOEXCEPT { return $(c_ns)_point_valid(p); } /** Double-scalar multiply, equivalent to q*qs + r*rs but faster. */ static inline Point double_scalarmul ( const Point &q, const Scalar &qs, const Point &r, const Scalar &rs ) NOEXCEPT { - Point p((NOINIT())); %(c_ns)s_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p; + Point p((NOINIT())); $(c_ns)_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p; } /** Dual-scalar multiply, equivalent to this*r1, this*r2 but faster. */ inline void dual_scalarmul ( Point &q1, Point &q2, const Scalar &r1, const Scalar &r2 ) const NOEXCEPT { - %(c_ns)s_point_dual_scalarmul(q1.p,q2.p,p,r1.s,r2.s); + $(c_ns)_point_dual_scalarmul(q1.p,q2.p,p,r1.s,r2.s); } /** @@ -415,20 +410,20 @@ public: * it doesn't). */ inline Point non_secret_combo_with_base(const Scalar &s, const Scalar &s_base) NOEXCEPT { - Point r((NOINIT())); %(c_ns)s_base_double_scalarmul_non_secret(r.p,s_base.s,p,s.s); return r; + Point r((NOINIT())); $(c_ns)_base_double_scalarmul_non_secret(r.p,s_base.s,p,s.s); return r; } /** Return a point equal to *this, whose internal data is rotated by a torsion element. */ inline Point debugging_torque() const NOEXCEPT { Point q; - %(c_ns)s_point_debugging_torque(q.p,p); + $(c_ns)_point_debugging_torque(q.p,p); return q; } /** Return a point equal to *this, whose internal data has a modified representation. */ inline Point debugging_pscale(const FixedBlock factor) const NOEXCEPT { Point q; - %(c_ns)s_point_debugging_pscale(q.p,p,factor.data()); + $(c_ns)_point_debugging_pscale(q.p,p,factor.data()); return q; } @@ -450,9 +445,9 @@ public: memcpy(buf2,buf.data(),(buf.size() > 2*HASH_BYTES) ? 2*HASH_BYTES : buf.size()); decaf_bool_t ret; if (buf.size() > HASH_BYTES) { - ret = decaf_successful(%(c_ns)s_invert_elligator_uniform(buf2, p, hint)); + ret = decaf_successful($(c_ns)_invert_elligator_uniform(buf2, p, hint)); } else { - ret = decaf_successful(%(c_ns)s_invert_elligator_nonuniform(buf2, p, hint)); + ret = decaf_successful($(c_ns)_invert_elligator_nonuniform(buf2, p, hint)); } if (buf.size() < HASH_BYTES) { ret &= decaf_memeq(&buf2[buf.size()], &buf2[HASH_BYTES], HASH_BYTES - buf.size()); @@ -477,10 +472,10 @@ public: } /** Return the base point */ - static inline const Point base() NOEXCEPT { return Point(%(c_ns)s_point_base); } + static inline const Point base() NOEXCEPT { return Point($(c_ns)_point_base); } /** Return the identity point */ - static inline const Point identity() NOEXCEPT { return Point(%(c_ns)s_point_identity); } + static inline const Point identity() NOEXCEPT { return Point($(c_ns)_point_identity); } }; /** @@ -491,7 +486,7 @@ public: */ /** @cond internal */ -typedef %(c_ns)s_precomputed_s Precomputed_U; +typedef $(c_ns)_precomputed_s Precomputed_U; /** @endcond */ class Precomputed /** @cond internal */ @@ -543,7 +538,7 @@ public: */ inline Precomputed &operator=(const Point &it) throw(std::bad_alloc) { alloc(); - %(c_ns)s_precompute(ours.mine,it.p); + $(c_ns)_precompute(ours.mine,it.p); return *this; } @@ -560,7 +555,7 @@ public: : OwnedOrUnowned() { *this = it; } /** Fixed base scalarmul. */ - inline Point operator* (const Scalar &s) const NOEXCEPT { Point r; %(c_ns)s_precomputed_scalarmul(r.p,get(),s.s); return r; } + inline Point operator* (const Scalar &s) const NOEXCEPT { Point r; $(c_ns)_precomputed_scalarmul(r.p,get(),s.s); return r; } /** Multiply by s.inverse(). If s=0, maps to the identity. */ inline Point operator/ (const Scalar &s) const throw(CryptoException) { return (*this) * s.inverse(); } @@ -571,23 +566,23 @@ public: public: /** @cond internal */ friend class OwnedOrUnowned; - static inline size_t size() NOEXCEPT { return %(c_ns)s_sizeof_precomputed_s; } - static inline size_t alignment() NOEXCEPT { return %(c_ns)s_alignof_precomputed_s; } - static inline const Precomputed_U * defaultValue() NOEXCEPT { return %(c_ns)s_precomputed_base; } + static inline size_t size() NOEXCEPT { return $(c_ns)_sizeof_precomputed_s; } + static inline size_t alignment() NOEXCEPT { return $(c_ns)_alignof_precomputed_s; } + static inline const Precomputed_U * defaultValue() NOEXCEPT { return $(c_ns)_precomputed_base; } /** @endcond */ }; struct DhLadder { public: - /** Bytes in an X%(gf_shortname)s public key. */ - static const size_t PUBLIC_BYTES = X%(gf_shortname)s_PUBLIC_BYTES; + /** Bytes in an X$(gf_shortname) public key. */ + static const size_t PUBLIC_BYTES = X$(gf_shortname)_PUBLIC_BYTES; - /** Bytes in an X%(gf_shortname)s private key. */ - static const size_t PRIVATE_BYTES = X%(gf_shortname)s_PRIVATE_BYTES; + /** Bytes in an X$(gf_shortname) private key. */ + static const size_t PRIVATE_BYTES = X$(gf_shortname)_PRIVATE_BYTES; /** Base point for a scalar multiplication. */ static const FixedBlock base_point() NOEXCEPT { - return FixedBlock(%(c_ns)s_x_base_point); + return FixedBlock($(c_ns)_x_base_point); } /** Generate and return a shared secret with public key. */ @@ -596,7 +591,7 @@ public: const FixedBlock &scalar ) throw(std::bad_alloc,CryptoException) { SecureBuffer out(PUBLIC_BYTES); - if (DECAF_SUCCESS != %(c_ns)s_x_direct_scalarmul(out.data(), pk.data(), scalar.data())) { + if (DECAF_SUCCESS != $(c_ns)_x_direct_scalarmul(out.data(), pk.data(), scalar.data())) { throw CryptoException(); } return out; @@ -609,7 +604,7 @@ public: const FixedBlock &pk, const FixedBlock &scalar ) NOEXCEPT { - return %(c_ns)s_x_direct_scalarmul(out.data(), pk.data(), scalar.data()); + return $(c_ns)_x_direct_scalarmul(out.data(), pk.data(), scalar.data()); } /** Generate and return a public key; equivalent to shared_secret(base_point(),scalar) @@ -619,7 +614,7 @@ public: const FixedBlock &scalar ) throw(std::bad_alloc) { SecureBuffer out(PUBLIC_BYTES); - %(c_ns)s_x_base_scalarmul(out.data(), scalar.data()); + $(c_ns)_x_base_scalarmul(out.data(), scalar.data()); return out; } @@ -631,21 +626,21 @@ public: FixedBuffer &out, const FixedBlock &scalar ) NOEXCEPT { - %(c_ns)s_x_base_scalarmul(out.data(), scalar.data()); + $(c_ns)_x_base_scalarmul(out.data(), scalar.data()); } }; -}; /* struct %(cxx_ns)s */ +}; /* struct $(cxx_ns) */ /** @cond internal */ -inline SecureBuffer %(cxx_ns)s::Scalar::direct_scalarmul ( +inline SecureBuffer $(cxx_ns)::Scalar::direct_scalarmul ( const Block &in, decaf_bool_t allow_identity, decaf_bool_t short_circuit ) const throw(CryptoException) { - SecureBuffer out(%(cxx_ns)s::Point::SER_BYTES); + SecureBuffer out($(cxx_ns)::Point::SER_BYTES); if (DECAF_SUCCESS != - %(c_ns)s_direct_scalarmul(out.data(), in.data(), s, allow_identity, short_circuit) + $(c_ns)_direct_scalarmul(out.data(), in.data(), s, allow_identity, short_circuit) ) { throw CryptoException(); } @@ -655,6 +650,3 @@ inline SecureBuffer %(cxx_ns)s::Scalar::direct_scalarmul ( #undef NOEXCEPT } /* namespace decaf */ -""" -) - diff --git a/src/public_include/decaf.tmpl.h b/src/public_include/decaf.tmpl.h new file mode 100644 index 0000000..c4c1fe2 --- /dev/null +++ b/src/public_include/decaf.tmpl.h @@ -0,0 +1,18 @@ +/** + * Master header for Decaf library. + * + * The Decaf library implements cryptographic operations on a elliptic curve + * groups of prime order p. It accomplishes this by using a twisted Edwards + * curve (isogenous to Ed448-Goldilocks or Ed25519) and wiping out the cofactor. + * + * The formulas are all complete and have no special cases. However, some + * functions can fail. For example, decoding functions can fail because not + * every string is the encoding of a valid group element. + * + * The formulas contain no data-dependent branches, timing or memory accesses, + * except for decaf_XXX_base_double_scalarmul_non_secret. + */ + +$("\n".join([ + "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) +])) diff --git a/src/public_include/decaf.tmpl.hxx b/src/public_include/decaf.tmpl.hxx new file mode 100644 index 0000000..2da5246 --- /dev/null +++ b/src/public_include/decaf.tmpl.hxx @@ -0,0 +1,16 @@ +/** Master header for Decaf library, C++ version. */ + +$("\n".join([ + "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) +])) + +namespace decaf { + template class Run> + void run_for_all_curves() { +$("\n".join([ +" Run<%s>::run();" % cd["cxx_ns"] +for cd in sorted(curve.values(), key=lambda x:x["c_ns"]) +]) +) + } +} diff --git a/src/public_include/decaf/crypto.tmpl.h b/src/public_include/decaf/crypto.tmpl.h new file mode 100644 index 0000000..dec7617 --- /dev/null +++ b/src/public_include/decaf/crypto.tmpl.h @@ -0,0 +1,10 @@ +/** + * Example Decaf crypto routines, metaheader. + * @warning These are merely examples, though they ought to be secure. But real + * protocols will decide differently on magic numbers, formats, which items to + * hash, etc. + */ + +$("\n".join([ + "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) +])) diff --git a/src/public_include/decaf/crypto.tmpl.hxx b/src/public_include/decaf/crypto.tmpl.hxx new file mode 100644 index 0000000..be98c6f --- /dev/null +++ b/src/public_include/decaf/crypto.tmpl.hxx @@ -0,0 +1,10 @@ +/** + * Example Decaf crypto routines, C++ metaheader. + * @warning These are merely examples, though they ought to be secure. But real + * protocols will decide differently on magic numbers, formats, which items to + * hash, etc. + */ + +$("\n".join([ + "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) +]))