| @@ -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 | |||
| @@ -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("^","**")) | |||
| @@ -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) | |||
| @@ -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 <template<typename Group> 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") | |||
| @@ -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 * ") | |||
| @@ -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 <decaf/%(c_ns)s.h> | |||
| #include <decaf/$(c_ns).h> | |||
| #include <decaf/strobe.h> | |||
| #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 | |||
| """) | |||
| @@ -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 <decaf.hxx> | |||
| #include <decaf/decaf_$(gf_bits).hxx> | |||
| #include <decaf/shake.hxx> | |||
| #include <decaf/strobe.hxx> | |||
| @@ -31,21 +26,21 @@ template <typename Group> class PublicKey; | |||
| /** A private key for crypto over some Group */ | |||
| template <typename Group> 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<class Group> 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_BYTES> &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_BYTES> &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<class Group> 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<SYM_BYTES> &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<SYM_BYTES> 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 */ | |||
| """) | |||
| } /* namespace decaf */ | |||
| @@ -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( | |||
| @@ -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 <decaf/common.h> | |||
| #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 | |||
| """ | |||
| ) | |||
| @@ -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 <stdlib.h> | |||
| #include <string.h> /* for memcpy */ | |||
| #include <decaf.h> | |||
| #include <decaf/decaf_$(gf_bits).h> | |||
| #include <decaf/secure_buffer.hxx> | |||
| #include <string> | |||
| #include <sys/types.h> | |||
| @@ -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<Scalar> { | |||
| 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<SER_BYTES> 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<Point> { | |||
| 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<SER_BYTES> &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<SER_BYTES> 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<Precomputed,Precomputed_U>() { *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<Precomputed,Precomputed_U>; | |||
| 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<PUBLIC_BYTES> base_point() NOEXCEPT { | |||
| return FixedBlock<PUBLIC_BYTES>(%(c_ns)s_x_base_point); | |||
| return FixedBlock<PUBLIC_BYTES>($(c_ns)_x_base_point); | |||
| } | |||
| /** Generate and return a shared secret with public key. */ | |||
| @@ -596,7 +591,7 @@ public: | |||
| const FixedBlock<PRIVATE_BYTES> &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<PUBLIC_BYTES> &pk, | |||
| const FixedBlock<PRIVATE_BYTES> &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<PRIVATE_BYTES> &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<PUBLIC_BYTES> &out, | |||
| const FixedBlock<PRIVATE_BYTES> &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 */ | |||
| """ | |||
| ) | |||
| @@ -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 <decaf/decaf_%s.h>" % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) | |||
| ])) | |||
| @@ -0,0 +1,16 @@ | |||
| /** Master header for Decaf library, C++ version. */ | |||
| $("\n".join([ | |||
| "#include <decaf/decaf_%s.hxx>" % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) | |||
| ])) | |||
| namespace decaf { | |||
| template <template<typename Group> 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"]) | |||
| ]) | |||
| ) | |||
| } | |||
| } | |||
| @@ -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 <decaf/crypto_%s.h>" % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) | |||
| ])) | |||
| @@ -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 <decaf/crypto_%s.hxx>" % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) | |||
| ])) | |||