Browse Source

move everything over to more-tolerable templating

master
Michael Hamburg 9 years ago
parent
commit
d94a147194
14 changed files with 429 additions and 562 deletions
  1. +24
    -13
      Makefile
  2. +1
    -0
      src/gen_headers/curve_data.py
  3. +0
    -50
      src/gen_headers/gen_file.py
  4. +0
    -119
      src/gen_headers/main.py
  5. +1
    -1
      src/gen_headers/template.py
  6. +40
    -46
      src/per_curve/crypto.tmpl.h
  7. +38
    -44
      src/per_curve/crypto.tmpl.hxx
  8. +2
    -4
      src/per_curve/decaf.tmpl.c
  9. +176
    -184
      src/per_curve/decaf.tmpl.h
  10. +93
    -101
      src/per_curve/decaf.tmpl.hxx
  11. +18
    -0
      src/public_include/decaf.tmpl.h
  12. +16
    -0
      src/public_include/decaf.tmpl.hxx
  13. +10
    -0
      src/public_include/decaf/crypto.tmpl.h
  14. +10
    -0
      src/public_include/decaf/crypto.tmpl.hxx

+ 24
- 13
Makefile View File

@@ -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 .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)/% .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) HEADERS= Makefile $(shell find src test -name "*.h") $(BUILD_OBJ)/timestamp $(GEN_HEADERS)


# components needed by the lib # components needed by the lib
@@ -90,7 +88,6 @@ scan: clean
-enable-checker osx -enable-checker security -enable-checker unix \ -enable-checker osx -enable-checker security -enable-checker unix \
make all make all



# Internal test programs, which are not part of the final build/bin directory. # Internal test programs, which are not part of the final build/bin directory.
$(BUILD_IBIN)/test: $(BUILD_OBJ)/test_decaf.o lib $(BUILD_IBIN)/test: $(BUILD_OBJ)/test_decaf.o lib
ifeq ($(UNAME),Darwin) ifeq ($(UNAME),Darwin)
@@ -125,10 +122,15 @@ $(BUILD_OBJ)/%.o: $(BUILD_ASM)/%.s
$(ASM) $(ASFLAGS) -c -o $@ $< $(ASM) $(ASFLAGS) -c -o $@ $<


gen_headers: $(GEN_HEADERS) 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 # 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 LIBCOMPONENTS += $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/crypto.o $$(BUILD_OBJ)/$(1)/decaf_tables.o
PER_OBJ_DIRS += $$(BUILD_OBJ)/$(1) 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)) $$(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 $$@ $$< 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)) $$(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 $$@ $$< 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_IBIN)/decaf_gen_tables_$(1): $$(BUILD_OBJ)/$(1)/decaf_gen_tables.o \
$$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/utils.o \ $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/utils.o \
@@ -200,9 +211,9 @@ endef
################################################################ ################################################################
# call code above to generate curves and fields # call code above to generate curves and fields
$(eval $(call define_field,p25519,arch_x86_64)) $(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_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. # The shakesum utility is in the public bin directory.
$(BUILD_BIN)/shakesum: $(BUILD_OBJ)/shakesum.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/utils.o $(BUILD_BIN)/shakesum: $(BUILD_OBJ)/shakesum.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/utils.o


+ 1
- 0
src/gen_headers/curve_data.py View File

@@ -84,6 +84,7 @@ def ceil_log2(x):
out += 1 out += 1
return out return out


# TODO: reduce this because we can now have expressions.
for field,data in field_data.iteritems(): for field,data in field_data.iteritems():
if "modulus" not in data: if "modulus" not in data:
data["modulus"] = eval(data["gf_desc"].replace("^","**")) data["modulus"] = eval(data["gf_desc"].replace("^","**"))


+ 0
- 50
src/gen_headers/gen_file.py View File

@@ -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)

+ 0
- 119
src/gen_headers/main.py View File

@@ -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")

+ 1
- 1
src/gen_headers/template.py View File

@@ -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') parser.add_argument('files', metavar='file', type=str, nargs='+', help='a list of files to fill')
args = parser.parse_args() 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): def redoc(filename,doc,author):
doc = doc.replace("\n","\n * ") doc = doc.replace("\n","\n * ")


src/gen_headers/crypto_h.py → src/per_curve/crypto.tmpl.h View File

@@ -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> #include <decaf/strobe.h>


#ifdef __cplusplus #ifdef __cplusplus
@@ -19,48 +14,48 @@ extern "C" {
#endif #endif


/** Number of bytes for a symmetric key (expanded to full key) */ /** 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. */ /** 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. */ /** 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. */ /** 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 { typedef struct {
/** @cond internal */ /** @cond internal */
/** The symmetric key from which everything is expanded */ /** The symmetric key from which everything is expanded */
%(c_ns)s_symmetric_key_t sym;
$(c_ns)_symmetric_key_t sym;
/** The scalar x */ /** The scalar x */
%(c_ns)s_scalar_t secret_scalar;
$(c_ns)_scalar_t secret_scalar;
/** x*Base */ /** x*Base */
%(c_ns)s_public_key_t pub;
$(c_ns)_public_key_t pub;
/** @endcond */ /** @endcond */
} /** Private key structure for pointers. */ } /** Private key structure for pointers. */
%(c_ns)s_private_key_s,
$(c_ns)_private_key_s,
/** A private key (gmp array[1] style). */ /** 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. * Derive a key from its compressed form.
* @param [out] priv The derived private key. * @param [out] priv The derived private key.
* @param [in] proto The compressed or proto-key, which must be 32 random bytes. * @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; ) NONNULL2 API_VIS;


/** /**
* Destroy a private key. * 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; ) NONNULL1 API_VIS;


/** /**
@@ -68,9 +63,9 @@ void %(c_ns)s_destroy_private_key (
* @param [out] pub The extracted private key. * @param [out] pub The extracted private key.
* @param [in] priv The 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; ) NONNULL2 API_VIS;
/** /**
@@ -89,11 +84,11 @@ void %(c_ns)s_private_to_public (
* @retval DECAF_FAILURE Key exchange failed. * @retval DECAF_FAILURE Key exchange failed.
*/ */
decaf_error_t decaf_error_t
%(c_ns)s_shared_secret (
$(c_ns)_shared_secret (
uint8_t *shared, uint8_t *shared,
size_t shared_bytes, 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 int me_first
) NONNULL134 WARN_UNUSED API_VIS; ) NONNULL134 WARN_UNUSED API_VIS;
@@ -105,10 +100,10 @@ decaf_error_t
* @param [in] strobe A STROBE context with the message. * @param [in] strobe A STROBE context with the message.
*/ */
void void
%(c_ns)s_sign_strobe (
$(c_ns)_sign_strobe (
keccak_strobe_t 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; ) NONNULL3 API_VIS;


/** /**
@@ -120,9 +115,9 @@ void
* @param [in] message_len The message's length. * @param [in] message_len The message's length.
*/ */
void 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, const unsigned char *message,
size_t message_len size_t message_len
) NONNULL3 API_VIS; ) NONNULL3 API_VIS;
@@ -138,10 +133,10 @@ void
* @return DECAF_FAILURE The signature did not verify successfully. * @return DECAF_FAILURE The signature did not verify successfully.
*/ */
decaf_error_t decaf_error_t
%(c_ns)s_verify_strobe (
$(c_ns)_verify_strobe (
keccak_strobe_t 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; ) NONNULL3 API_VIS WARN_UNUSED;


/** /**
@@ -156,9 +151,9 @@ decaf_error_t
* @return DECAF_FAILURE The signature did not verify successfully. * @return DECAF_FAILURE The signature did not verify successfully.
*/ */
decaf_error_t 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, const unsigned char *message,
size_t message_len size_t message_len
) NONNULL3 API_VIS WARN_UNUSED; ) NONNULL3 API_VIS WARN_UNUSED;
@@ -166,4 +161,3 @@ decaf_error_t
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif
""")

src/gen_headers/crypto_hxx.py → src/per_curve/crypto.tmpl.hxx View File

@@ -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/shake.hxx>
#include <decaf/strobe.hxx> #include <decaf/strobe.hxx>


@@ -31,21 +26,21 @@ template <typename Group> class PublicKey;
/** A private key for crypto over some Group */ /** A private key for crypto over some Group */
template <typename Group> class PrivateKey; 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: private:
/** @cond internal */ /** @cond internal */
typedef %(c_ns)s_public_key_t Wrapped;
typedef $(c_ns)_public_key_t Wrapped;
Wrapped wrapped; Wrapped wrapped;
template<class Group> friend class PrivateKey; template<class Group> friend class PrivateKey;
/** @endcond */ /** @endcond */
public: public:
/** Underlying group */ /** Underlying group */
typedef %(cxx_ns)s Group;
typedef $(cxx_ns) Group;
/** Signature size. */ /** 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. */ /** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped); static const size_t SER_BYTES = sizeof(Wrapped);
@@ -56,7 +51,7 @@ public:
} }
/** Read a private key from a string*/ /** 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 */ /** Create but don't initialize */
inline explicit PublicKey(const NOINIT&) NOEXCEPT { } inline explicit PublicKey(const NOINIT&) NOEXCEPT { }
@@ -74,7 +69,7 @@ public:
const Block &message, const Block &message,
const FixedBlock<SIG_BYTES> &sig const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) { ) 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()); throw(CryptoException());
} }
} }
@@ -84,33 +79,33 @@ public:
Strobe &context, Strobe &context,
const FixedBlock<SIG_BYTES> &sig const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) { ) 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()); 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: private:
/** @cond internal */ /** @cond internal */
typedef %(c_ns)s_private_key_t Wrapped;
typedef $(c_ns)_private_key_t Wrapped;
Wrapped wrapped; Wrapped wrapped;
template<class Group> friend class PublicKey; template<class Group> friend class PublicKey;
/** @endcond */ /** @endcond */
public: public:
/** Underlying group */ /** Underlying group */
typedef %(cxx_ns)s Group;
typedef $(cxx_ns) Group;
/** Signature size. */ /** 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. */ /** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped); static const size_t SER_BYTES = sizeof(Wrapped);
/** Compressed size. */ /** 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 */ /** Create but don't initialize */
inline explicit PrivateKey(const NOINIT&) NOEXCEPT { } inline explicit PrivateKey(const NOINIT&) NOEXCEPT { }
@@ -122,18 +117,18 @@ public:
/** Read a private key from a string*/ /** Read a private key from a string*/
inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT { 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 */ /** Create at random */
inline explicit PrivateKey(Rng &r) NOEXCEPT { inline explicit PrivateKey(Rng &r) NOEXCEPT {
FixedArrayBuffer<SYM_BYTES> tmp(r); FixedArrayBuffer<SYM_BYTES> tmp(r);
%(c_ns)s_derive_private_key(wrapped, tmp.data());
$(c_ns)_derive_private_key(wrapped, tmp.data());
} }
/** Secure destructor */ /** Secure destructor */
inline ~PrivateKey() NOEXCEPT { inline ~PrivateKey() NOEXCEPT {
%(c_ns)s_destroy_private_key(wrapped);
$(c_ns)_destroy_private_key(wrapped);
} }
/** Serialization size. */ /** Serialization size. */
@@ -152,18 +147,18 @@ public:
} }
/** Get the public key */ /** 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 */ /** Derive a shared secret */
inline SecureBuffer sharedSecret( inline SecureBuffer sharedSecret(
const PublicKey<%(cxx_ns)s> &pub,
const PublicKey<$(cxx_ns)> &pub,
size_t bytes, size_t bytes,
bool me_first bool me_first
) const throw(CryptoException,std::bad_alloc) { ) const throw(CryptoException,std::bad_alloc) {
SecureBuffer ret(bytes); 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()); throw(CryptoException());
} }
return ret; return ret;
@@ -173,33 +168,32 @@ public:
inline decaf_error_t __attribute__((warn_unused_result)) inline decaf_error_t __attribute__((warn_unused_result))
sharedSecretNoexcept( sharedSecretNoexcept(
Buffer ret, Buffer ret,
const PublicKey<%(cxx_ns)s> &pub,
const PublicKey<$(cxx_ns)> &pub,
bool me_first bool me_first
) const NOEXCEPT { ) 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. */ /** Sign a message. */
inline SecureBuffer sign(const Block &message) const { inline SecureBuffer sign(const Block &message) const {
SecureBuffer sig(SIG_BYTES); 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; return sig;
} }


/** Sign a message. */ /** Sign a message. */
inline SecureBuffer verify(Strobe &context) const { inline SecureBuffer verify(Strobe &context) const {
SecureBuffer sig(SIG_BYTES); 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; return sig;
} }
}; };


/** @cond internal */ /** @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 */ /** @endcond */


#undef NOEXCEPT #undef NOEXCEPT
} /* namespace decaf */
""")
} /* namespace decaf */

+ 2
- 4
src/per_curve/decaf.tmpl.c View File

@@ -19,7 +19,7 @@
#define IMAGINE_TWIST $(imagine_twist) #define IMAGINE_TWIST $(imagine_twist)
#define COFACTOR $(cofactor) #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_N $(combs.n)
#define COMBS_T $(combs.t) #define COMBS_T $(combs.t)
#define COMBS_S $(combs.s) #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; 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 #if COFACTOR==8
static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL(


src/gen_headers/decaf_h.py → src/per_curve/decaf.tmpl.h View File

@@ -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> #include <decaf/common.h>


#ifdef __cplusplus #ifdef __cplusplus
@@ -13,78 +7,78 @@ extern "C" {
#endif #endif


/** @cond internal */ /** @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 */ /** @endcond */


/** The number of bits in a scalar */ /** 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 */ /** @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 */ /** @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 */ /** @endcond */


/** Number of bytes in a serialized point. */ /** 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. */ /** 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 */ /** Twisted Edwards extended homogeneous coordinates */
typedef struct %(c_ns)s_point_s {
typedef struct $(c_ns)_point_s {
/** @cond internal */ /** @cond internal */
gf_%(gf_shortname)s_t x,y,z,t;
gf_$(gf_shortname)_t x,y,z,t;
/** @endcond */ /** @endcond */
} %(c_ns)s_point_t[1];
} $(c_ns)_point_t[1];


/** Precomputed table based on a point. Can be trivial implementation. */ /** 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. */ /** 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. */ /** 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. */ /** 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 */ /** @cond internal */
decaf_word_t limb[%(C_NS)s_SCALAR_LIMBS];
decaf_word_t limb[$(C_NS)_SCALAR_LIMBS];
/** @endcond */ /** @endcond */
} %(c_ns)s_scalar_t[1];
} $(c_ns)_scalar_t[1];


/** A scalar equal to 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. */ /** 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. */ /** 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. /** An arbitrarily chosen base point on the curve.
* @warning TODO: this is subject to change. It is currently * @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 * multiple of the current basepoint (eg twice it, or the cofactor
* times it) more convenient API-wise, and trigger a changeover. * 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. */ /** 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. * @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, * @retval DECAF_FAILURE The scalar was greater than the modulus,
* and has been reduced modulo that 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; ) 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 [in] ser_len Length of serialized form.
* @param [out] out Deserialized 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, const unsigned char *ser,
size_t ser_len size_t ser_len
) API_VIS NONNULL2 NOINLINE; ) API_VIS NONNULL2 NOINLINE;
@@ -121,9 +115,9 @@ void %(c_ns)s_scalar_decode_long (
* @param [out] ser Serialized form of a scalar. * @param [out] ser Serialized form of a scalar.
* @param [in] s Deserialized 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; ) API_VIS NONNULL2 NOINLINE NOINLINE;
/** /**
@@ -132,10 +126,10 @@ void %(c_ns)s_scalar_encode (
* @param [in] b Another scalar. * @param [in] b Another scalar.
* @param [out] out a+b. * @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; ) API_VIS NONNULL3 NOINLINE;


/** /**
@@ -145,9 +139,9 @@ void %(c_ns)s_scalar_add (
* @retval DECAF_TRUE The scalars are equal. * @retval DECAF_TRUE The scalars are equal.
* @retval DECAF_FALSE The scalars are not 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; ) API_VIS WARN_UNUSED NONNULL2 NOINLINE;


/** /**
@@ -156,10 +150,10 @@ decaf_bool_t %(c_ns)s_scalar_eq (
* @param [in] b Another scalar. * @param [in] b Another scalar.
* @param [out] out a-b. * @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; ) API_VIS NONNULL3 NOINLINE;


/** /**
@@ -168,10 +162,10 @@ void %(c_ns)s_scalar_sub (
* @param [in] b Another scalar. * @param [in] b Another scalar.
* @param [out] out a*b. * @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; ) API_VIS NONNULL3 NOINLINE;


/** /**
@@ -180,9 +174,9 @@ void %(c_ns)s_scalar_mul (
* @param [out] out 1/a. * @param [out] out 1/a.
* @return DECAF_SUCCESS The input is nonzero. * @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; ) API_VIS WARN_UNUSED NONNULL2 NOINLINE;


/** /**
@@ -191,9 +185,9 @@ decaf_error_t %(c_ns)s_scalar_invert (
* @param [in] a A scalar. * @param [in] a A scalar.
* @param [out] out Will become a copy of a. * @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; *out = *a;
} }
@@ -203,8 +197,8 @@ static inline void NONNULL2 %(c_ns)s_scalar_copy (
* @param [in] a An integer. * @param [in] a An integer.
* @param [out] out Will become equal to a. * @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 uint64_t a
) API_VIS NONNULL1; ) API_VIS NONNULL1;


@@ -214,9 +208,9 @@ void %(c_ns)s_scalar_set_unsigned (
* @param [out] ser The byte representation of the point. * @param [out] ser The byte representation of the point.
* @param [in] pt The point to encode. * @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; ) API_VIS NONNULL2 NOINLINE;


/** /**
@@ -233,9 +227,9 @@ void %(c_ns)s_point_encode (
* @retval DECAF_FAILURE The decoding didn't succeed, because * @retval DECAF_FAILURE The decoding didn't succeed, because
* ser does not represent a point. * 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 decaf_bool_t allow_identity
) API_VIS WARN_UNUSED NONNULL2 NOINLINE; ) 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 [out] a A copy of the point.
* @param [in] b Any 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; *a=*b;
} }
@@ -262,9 +256,9 @@ static inline void NONNULL2 %(c_ns)s_point_copy (
* @retval DECAF_TRUE The points are equal. * @retval DECAF_TRUE The points are equal.
* @retval DECAF_FALSE The points are not 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; ) 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] a An addend.
* @param [in] b 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; ) API_VIS NONNULL3;


/** /**
* @brief Double a point. Equivalent to * @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 [out] two_a The sum a+a.
* @param [in] a A point. * @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; ) API_VIS NONNULL2;


/** /**
@@ -303,10 +297,10 @@ void %(c_ns)s_point_double (
* @param [in] a The minuend. * @param [in] a The minuend.
* @param [in] b The subtrahend. * @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; ) API_VIS NONNULL3;
/** /**
@@ -316,9 +310,9 @@ void %(c_ns)s_point_sub (
* @param [out] nega The negated input point * @param [out] nega The negated input point
* @param [in] a The 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; ) API_VIS NONNULL2;


/** /**
@@ -328,10 +322,10 @@ void %(c_ns)s_point_negate (
* @param [in] base The point to be scaled. * @param [in] base The point to be scaled.
* @param [in] scalar The scalar to multiply by. * @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; ) API_VIS NONNULL3 NOINLINE;


/** /**
@@ -351,10 +345,10 @@ void %(c_ns)s_point_scalarmul (
* @retval DECAF_FAILURE The scalarmul didn't succeed, because * @retval DECAF_FAILURE The scalarmul didn't succeed, because
* base does not represent a point. * 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 allow_identity,
decaf_bool_t short_circuit decaf_bool_t short_circuit
) API_VIS NONNULL3 WARN_UNUSED NOINLINE; ) 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 * @retval DECAF_FAILURE The scalarmul didn't succeed, because the base
* point is in a small subgroup. * 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; ) 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 * @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 [out] scaled The scaled point base*scalar
* @param [in] scalar The scalar to multiply by. * @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; ) 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 [out] a A precomputed table of multiples of the point.
* @param [in] b Any 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; ) API_VIS NONNULL2 NOINLINE;


/** /**
@@ -411,23 +405,23 @@ void %(c_ns)s_precompute (
* scaled = scalar*base. * scaled = scalar*base.
* Some implementations do not include precomputed points; for * Some implementations do not include precomputed points; for
* those implementations, this function is the same as * 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 [out] scaled The scaled point base*scalar
* @param [in] base The point to be scaled. * @param [in] base The point to be scaled.
* @param [in] scalar The scalar to multiply by. * @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; ) API_VIS NONNULL3 NOINLINE;


/** /**
* @brief Multiply two base points by two scalars: * @brief Multiply two base points by two scalars:
* scaled = scalar1*base1 + scalar2*base2. * 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. * faster.
* *
* @param [out] combo The linear combination scalar1*base1 + scalar2*base2. * @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] base2 A second point to be scaled.
* @param [in] scalar2 A second scalar to multiply by. * @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; ) API_VIS NONNULL5 NOINLINE;
/** /**
@@ -450,7 +444,7 @@ void %(c_ns)s_point_double_scalarmul (
* a1 = scalar1 * base * a1 = scalar1 * base
* a2 = scalar2 * 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. * faster.
* *
* @param [out] a1 The first multiple. It may be the same as the input point. * @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] scalar1 A first scalar to multiply by.
* @param [in] scalar2 A second 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; ) API_VIS NONNULL5 NOINLINE;


/** /**
* @brief Multiply two base points by two scalars: * @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. * faster at the expense of being variable time.
* *
* @param [out] combo The linear combination scalar1*base + scalar2*base2. * @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 * @warning: This function takes variable time, and may leak the scalars
* used. It is designed for signature verification. * 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; ) API_VIS NONNULL4 NOINLINE;


/** /**
@@ -498,10 +492,10 @@ void %(c_ns)s_base_double_scalarmul_non_secret (
* @param [in] b Any point. * @param [in] b Any point.
* @param [in] pick_b If nonzero, choose point b. * @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 decaf_word_t pick_b
) API_VIS NONNULL3 NOINLINE; ) API_VIS NONNULL3 NOINLINE;


@@ -514,10 +508,10 @@ void %(c_ns)s_point_cond_sel (
* @param [in] b Any scalar. * @param [in] b Any scalar.
* @param [in] pick_b If nonzero, choose scalar b. * @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 decaf_word_t pick_b
) API_VIS NONNULL3 NOINLINE; ) API_VIS NONNULL3 NOINLINE;


@@ -528,8 +522,8 @@ void %(c_ns)s_scalar_cond_sel (
* @retval DECAF_TRUE The point is valid. * @retval DECAF_TRUE The point is valid.
* @retval DECAF_FALSE The point is invalid. * @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; ) 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 [out] q The point to torque.
* @param [in] p 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; ) API_VIS NONNULL2 NOINLINE;


/** /**
@@ -553,10 +547,10 @@ void %(c_ns)s_point_debugging_torque (
* @param [in] p The point to scale. * @param [in] p The point to scale.
* @param [in] factor Serialized GF factor 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; ) 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. * 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, * 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 * it is safe (cannot produce points of order 4), and would be compatible with
* hypothetical other implementations of Decaf using a Montgomery or untwisted * 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. * @param [out] pt The data hashed to the curve.
*/ */
void 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; ) API_VIS NONNULL2 NOINLINE;


/** /**
* @brief Indifferentiable hash function encoding to curve. * @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 [in] hashed_data Output of some hash function.
* @param [out] pt The data hashed to the curve. * @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; ) API_VIS NONNULL2 NOINLINE;


/** /**
* @brief Inverse of elligator-like hash to curve. * @brief Inverse of elligator-like hash to curve.
* *
* This function writes to the buffer, to make it so that * 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 * possible. Since there may be multiple preimages, the
* "which" parameter chooses between them. To ensure uniform * "which" parameter chooses between them. To ensure uniform
* inverse sampling, this function succeeds or fails * 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. * @retval DECAF_FAILURE The inverse failed.
*/ */
decaf_error_t 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 uint16_t which
) API_VIS NONNULL2 NOINLINE WARN_UNUSED; ) API_VIS NONNULL2 NOINLINE WARN_UNUSED;


@@ -635,7 +629,7 @@ decaf_error_t
* @brief Inverse of elligator-like hash to curve. * @brief Inverse of elligator-like hash to curve.
* *
* This function writes to the buffer, to make it so that * 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 * possible. Since there may be multiple preimages, the
* "which" parameter chooses between them. To ensure uniform * "which" parameter chooses between them. To ensure uniform
* inverse sampling, this function succeeds or fails * inverse sampling, this function succeeds or fails
@@ -650,36 +644,34 @@ decaf_error_t
* @retval DECAF_FAILURE The inverse failed. * @retval DECAF_FAILURE The inverse failed.
*/ */
decaf_error_t 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 uint16_t which
) API_VIS NONNULL2 NOINLINE WARN_UNUSED; ) API_VIS NONNULL2 NOINLINE WARN_UNUSED;


/** /**
* @brief Overwrite scalar with zeros. * @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; ) NONNULL1 API_VIS;


/** /**
* @brief Overwrite point with zeros. * @brief Overwrite point with zeros.
* @todo Use this internally. * @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; ) NONNULL1 API_VIS;


/** /**
* @brief Overwrite precomputed table with zeros. * @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; ) NONNULL1 API_VIS;


#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif
"""
)

src/gen_headers/decaf_hxx.py → src/per_curve/decaf.tmpl.hxx View File

@@ -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. */ /** This code uses posix_memalign. */
#ifndef _XOPEN_SOURCE #ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600 #define _XOPEN_SOURCE 600
@@ -25,7 +20,7 @@ decaf_hxx = gen_file(
#include <stdlib.h> #include <stdlib.h>
#include <string.h> /* for memcpy */ #include <string.h> /* for memcpy */


#include <decaf.h>
#include <decaf/decaf_$(gf_bits).h>
#include <decaf/secure_buffer.hxx> #include <decaf/secure_buffer.hxx>
#include <string> #include <string>
#include <sys/types.h> #include <sys/types.h>
@@ -42,18 +37,18 @@ decaf_hxx = gen_file(
namespace decaf { 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 */ /** 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) */ /** 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) */ /** 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 */ /** @cond internal */
class Point; class Point;
@@ -67,10 +62,10 @@ class Precomputed;
class Scalar : public Serializable<Scalar> { class Scalar : public Serializable<Scalar> {
public: public:
/** wrapped C type */ /** wrapped C type */
typedef %(c_ns)s_scalar_t Wrapped;
typedef $(c_ns)_scalar_t Wrapped;
/** Size of a serialized element */ /** 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 */ /** access to the underlying scalar object */
Wrapped s; Wrapped s;
@@ -99,7 +94,7 @@ public:
} }


/** Construct from decaf_scalar_t object. */ /** 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. */ /** Copy constructor. */
inline Scalar(const Scalar &x) NOEXCEPT { *this = x; } inline Scalar(const Scalar &x) NOEXCEPT { *this = x; }
@@ -112,20 +107,20 @@ public:


/** Serializable instance */ /** Serializable instance */
inline void serialize_into(unsigned char *buffer) const NOEXCEPT { inline void serialize_into(unsigned char *buffer) const NOEXCEPT {
%(c_ns)s_scalar_encode(buffer, s);
$(c_ns)_scalar_encode(buffer, s);
} }


/** Assignment. */ /** 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. */ /** 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. */ /** Assign from signed int. */
inline Scalar& operator=(int64_t w) NOEXCEPT { inline Scalar& operator=(int64_t w) NOEXCEPT {
Scalar t(-(uint64_t)INT_MIN); 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; *this -= t;
return *this; return *this;
} }
@@ -137,11 +132,11 @@ public:
inline Scalar& operator=(int w) NOEXCEPT { return *this = (int64_t)w; } inline Scalar& operator=(int w) NOEXCEPT { return *this = (int64_t)w; }


/** Destructor securely zeorizes the scalar. */ /** 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. */ /** Assign from arbitrary-length little-endian byte sequence in a Block. */
inline Scalar &operator=(const Block &bl) NOEXCEPT { 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 ( static inline decaf_error_t WARN_UNUSED decode (
Scalar &sc, const FixedBlock<SER_BYTES> buffer Scalar &sc, const FixedBlock<SER_BYTES> buffer
) NOEXCEPT { ) NOEXCEPT {
return %(c_ns)s_scalar_decode(sc.s,buffer.data());
return $(c_ns)_scalar_decode(sc.s,buffer.data());
} }


/** Add. */ /** 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. */ /** 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. */ /** 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. */ /** 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 */ /** 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. */ /** 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 */ /** 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, /** Invert with Fermat's Little Theorem (slow!). If *this == 0,
* throw CryptoException. */ * throw CryptoException. */
inline Scalar inverse() const throw(CryptoException) { inline Scalar inverse() const throw(CryptoException) {
Scalar r; 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(); throw CryptoException();
} }
return r; return r;
@@ -189,7 +184,7 @@ public:
* and return DECAF_FAILURE. */ * and return DECAF_FAILURE. */
inline decaf_error_t WARN_UNUSED inline decaf_error_t WARN_UNUSED
inverse_noexcept(Scalar &r) const NOEXCEPT { 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. */ /** 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); } inline bool operator!=(const Scalar &q) const NOEXCEPT { return !(*this == q); }


/** Compare in constant time */ /** 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. */ /** Scalarmul with scalar on left. */
inline Point operator* (const Point &q) const NOEXCEPT { return q * (*this); } inline Point operator* (const Point &q) const NOEXCEPT { return q * (*this); }
@@ -224,10 +219,10 @@ public:
class Point : public Serializable<Point> { class Point : public Serializable<Point> {
public: public:
/** wrapped C type */ /** wrapped C type */
typedef %(c_ns)s_point_t Wrapped;
typedef $(c_ns)_point_t Wrapped;
/** Size of a serialized element */ /** 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 */ /** Bytes required for hash */
static const size_t HASH_BYTES = SER_BYTES; static const size_t HASH_BYTES = SER_BYTES;
@@ -244,16 +239,16 @@ public:
/** @endcond */ /** @endcond */


/** Constructor sets to identity by default. */ /** 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. */ /** Copy constructor. */
inline Point(const Point &q) NOEXCEPT { *this = q; } inline Point(const Point &q) NOEXCEPT { *this = q; }


/** Assignment. */ /** 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. */ /** 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 */ /** Construct from RNG */
inline explicit Point(Rng &rng, bool uniform = true) NOEXCEPT { inline explicit Point(Rng &rng, bool uniform = true) NOEXCEPT {
@@ -291,7 +286,7 @@ public:
static inline decaf_error_t WARN_UNUSED decode ( static inline decaf_error_t WARN_UNUSED decode (
Point &p, const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE Point &p, const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE
) NOEXCEPT { ) 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) { if (s.size() < HASH_BYTES) {
SecureBuffer b(HASH_BYTES); SecureBuffer b(HASH_BYTES);
memcpy(b.data(), s.data(), s.size()); 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) { } 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) { } else if (s.size() < 2*HASH_BYTES) {
SecureBuffer b(2*HASH_BYTES); SecureBuffer b(2*HASH_BYTES);
memcpy(b.data(), s.data(), s.size()); 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 { } 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 { inline operator SecureBuffer() const {
SecureBuffer buffer(SER_BYTES); SecureBuffer buffer(SER_BYTES);
%(c_ns)s_point_encode(buffer.data(), p);
$(c_ns)_point_encode(buffer.data(), p);
return buffer; return buffer;
} }


@@ -340,41 +335,41 @@ public:


/** Serializable instance */ /** Serializable instance */
inline void serialize_into(unsigned char *buffer) const NOEXCEPT { inline void serialize_into(unsigned char *buffer) const NOEXCEPT {
%(c_ns)s_point_encode(buffer, p);
$(c_ns)_point_encode(buffer, p);
} }


/** Point add. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** 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. */ /** Multiply by s.inverse(). If s=0, maps to the identity. */
inline Point operator/ (const Scalar &s) const throw(CryptoException) { return (*this) * s.inverse(); } 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(); } inline Point &operator/=(const Scalar &s) throw(CryptoException) { return (*this) *= s.inverse(); }


/** Validate / sanity check */ /** 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. */ /** Double-scalar multiply, equivalent to q*qs + r*rs but faster. */
static inline Point double_scalarmul ( static inline Point double_scalarmul (
const Point &q, const Scalar &qs, const Point &r, const Scalar &rs const Point &q, const Scalar &qs, const Point &r, const Scalar &rs
) NOEXCEPT { ) 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. */ /** Dual-scalar multiply, equivalent to this*r1, this*r2 but faster. */
inline void dual_scalarmul ( inline void dual_scalarmul (
Point &q1, Point &q2, const Scalar &r1, const Scalar &r2 Point &q1, Point &q2, const Scalar &r1, const Scalar &r2
) const NOEXCEPT { ) 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). * it doesn't).
*/ */
inline Point non_secret_combo_with_base(const Scalar &s, const Scalar &s_base) NOEXCEPT { 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. */ /** Return a point equal to *this, whose internal data is rotated by a torsion element. */
inline Point debugging_torque() const NOEXCEPT { inline Point debugging_torque() const NOEXCEPT {
Point q; Point q;
%(c_ns)s_point_debugging_torque(q.p,p);
$(c_ns)_point_debugging_torque(q.p,p);
return q; return q;
} }


/** Return a point equal to *this, whose internal data has a modified representation. */ /** Return a point equal to *this, whose internal data has a modified representation. */
inline Point debugging_pscale(const FixedBlock<SER_BYTES> factor) const NOEXCEPT { inline Point debugging_pscale(const FixedBlock<SER_BYTES> factor) const NOEXCEPT {
Point q; 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; return q;
} }


@@ -450,9 +445,9 @@ public:
memcpy(buf2,buf.data(),(buf.size() > 2*HASH_BYTES) ? 2*HASH_BYTES : buf.size()); memcpy(buf2,buf.data(),(buf.size() > 2*HASH_BYTES) ? 2*HASH_BYTES : buf.size());
decaf_bool_t ret; decaf_bool_t ret;
if (buf.size() > HASH_BYTES) { 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 { } 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) { if (buf.size() < HASH_BYTES) {
ret &= decaf_memeq(&buf2[buf.size()], &buf2[HASH_BYTES], HASH_BYTES - buf.size()); ret &= decaf_memeq(&buf2[buf.size()], &buf2[HASH_BYTES], HASH_BYTES - buf.size());
@@ -477,10 +472,10 @@ public:
} }


/** Return the base point */ /** 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 */ /** 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 */ /** @cond internal */
typedef %(c_ns)s_precomputed_s Precomputed_U;
typedef $(c_ns)_precomputed_s Precomputed_U;
/** @endcond */ /** @endcond */
class Precomputed class Precomputed
/** @cond internal */ /** @cond internal */
@@ -543,7 +538,7 @@ public:
*/ */
inline Precomputed &operator=(const Point &it) throw(std::bad_alloc) { inline Precomputed &operator=(const Point &it) throw(std::bad_alloc) {
alloc(); alloc();
%(c_ns)s_precompute(ours.mine,it.p);
$(c_ns)_precompute(ours.mine,it.p);
return *this; return *this;
} }


@@ -560,7 +555,7 @@ public:
: OwnedOrUnowned<Precomputed,Precomputed_U>() { *this = it; } : OwnedOrUnowned<Precomputed,Precomputed_U>() { *this = it; }


/** Fixed base scalarmul. */ /** 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. */ /** Multiply by s.inverse(). If s=0, maps to the identity. */
inline Point operator/ (const Scalar &s) const throw(CryptoException) { return (*this) * s.inverse(); } inline Point operator/ (const Scalar &s) const throw(CryptoException) { return (*this) * s.inverse(); }
@@ -571,23 +566,23 @@ public:
public: public:
/** @cond internal */ /** @cond internal */
friend class OwnedOrUnowned<Precomputed,Precomputed_U>; 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 */ /** @endcond */
}; };


struct DhLadder { struct DhLadder {
public: 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. */ /** Base point for a scalar multiplication. */
static const FixedBlock<PUBLIC_BYTES> base_point() NOEXCEPT { 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. */ /** Generate and return a shared secret with public key. */
@@ -596,7 +591,7 @@ public:
const FixedBlock<PRIVATE_BYTES> &scalar const FixedBlock<PRIVATE_BYTES> &scalar
) throw(std::bad_alloc,CryptoException) { ) throw(std::bad_alloc,CryptoException) {
SecureBuffer out(PUBLIC_BYTES); 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(); throw CryptoException();
} }
return out; return out;
@@ -609,7 +604,7 @@ public:
const FixedBlock<PUBLIC_BYTES> &pk, const FixedBlock<PUBLIC_BYTES> &pk,
const FixedBlock<PRIVATE_BYTES> &scalar const FixedBlock<PRIVATE_BYTES> &scalar
) NOEXCEPT { ) 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) /** Generate and return a public key; equivalent to shared_secret(base_point(),scalar)
@@ -619,7 +614,7 @@ public:
const FixedBlock<PRIVATE_BYTES> &scalar const FixedBlock<PRIVATE_BYTES> &scalar
) throw(std::bad_alloc) { ) throw(std::bad_alloc) {
SecureBuffer out(PUBLIC_BYTES); 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; return out;
} }


@@ -631,21 +626,21 @@ public:
FixedBuffer<PUBLIC_BYTES> &out, FixedBuffer<PUBLIC_BYTES> &out,
const FixedBlock<PRIVATE_BYTES> &scalar const FixedBlock<PRIVATE_BYTES> &scalar
) NOEXCEPT { ) 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 */ /** @cond internal */
inline SecureBuffer %(cxx_ns)s::Scalar::direct_scalarmul (
inline SecureBuffer $(cxx_ns)::Scalar::direct_scalarmul (
const Block &in, const Block &in,
decaf_bool_t allow_identity, decaf_bool_t allow_identity,
decaf_bool_t short_circuit decaf_bool_t short_circuit
) const throw(CryptoException) { ) const throw(CryptoException) {
SecureBuffer out(%(cxx_ns)s::Point::SER_BYTES);
SecureBuffer out($(cxx_ns)::Point::SER_BYTES);
if (DECAF_SUCCESS != 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(); throw CryptoException();
} }
@@ -655,6 +650,3 @@ inline SecureBuffer %(cxx_ns)s::Scalar::direct_scalarmul (


#undef NOEXCEPT #undef NOEXCEPT
} /* namespace decaf */ } /* namespace decaf */
"""
)


+ 18
- 0
src/public_include/decaf.tmpl.h View File

@@ -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()])
]))

+ 16
- 0
src/public_include/decaf.tmpl.hxx View File

@@ -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"])
])
)
}
}

+ 10
- 0
src/public_include/decaf/crypto.tmpl.h View File

@@ -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()])
]))

+ 10
- 0
src/public_include/decaf/crypto.tmpl.hxx View File

@@ -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()])
]))

Loading…
Cancel
Save