From c2274243840d7235445efa22856caa5f7d9b4e9c Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Mon, 16 Oct 2017 16:34:30 -0700 Subject: [PATCH] make doc now mostly works --- Doxyfile | 4 +- Makefile | 6 +- src/GENERATED/c/curve25519/eddsa.c | 6 -- src/GENERATED/c/ed448goldilocks/eddsa.c | 6 -- src/GENERATED/include/decaf.hxx | 2 + src/GENERATED/include/decaf/common.h | 5 +- src/GENERATED/include/decaf/ed255.h | 9 +- src/GENERATED/include/decaf/ed255.hxx | 103 ++++++++++++---------- src/GENERATED/include/decaf/ed448.h | 9 +- src/GENERATED/include/decaf/ed448.hxx | 103 ++++++++++++---------- src/GENERATED/include/decaf/eddsa.hxx | 10 ++- src/GENERATED/include/decaf/point_255.h | 56 ++++++------ src/GENERATED/include/decaf/point_255.hxx | 72 +++++++-------- src/GENERATED/include/decaf/point_448.h | 56 ++++++------ src/GENERATED/include/decaf/point_448.hxx | 71 +++++++-------- src/GENERATED/include/decaf/sha512.h | 24 ++++- src/GENERATED/include/decaf/sha512.hxx | 2 +- src/GENERATED/include/decaf/spongerng.hxx | 4 +- src/per_curve/eddsa.tmpl.h | 9 +- src/per_curve/eddsa.tmpl.hxx | 103 ++++++++++++---------- src/per_curve/point.tmpl.h | 56 ++++++------ src/per_curve/point.tmpl.hxx | 73 +++++++-------- src/public_include/decaf.tmpl.hxx | 2 + src/public_include/decaf/common.h | 5 +- src/public_include/decaf/eddsa.tmpl.hxx | 10 ++- src/public_include/decaf/sha512.h | 24 ++++- src/public_include/decaf/sha512.hxx | 2 +- src/public_include/decaf/spongerng.hxx | 4 +- 28 files changed, 460 insertions(+), 376 deletions(-) diff --git a/Doxyfile b/Doxyfile index a86e46d..0265e0c 100644 --- a/Doxyfile +++ b/Doxyfile @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "Ed448-Goldilocks" +PROJECT_NAME = "libdecaf" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -751,7 +751,7 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = build/include +INPUT = src/GENERATED/include src/GENERATED/include/decaf # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/Makefile b/Makefile index c04154d..bb27775 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,8 @@ BUILD_INC = src/GENERATED/include BUILD_BIN = build/bin BUILD_IBIN = build/obj/bin +DOXYGEN ?= doxygen + ifeq ($(UNAME),Darwin) CC = clang CXX = clang++ @@ -300,8 +302,8 @@ $(BUILD_DOC)/timestamp: mkdir -p `dirname $@` touch $@ # -doc: Doxyfile $(BUILD_OBJ)/timestamp $(HEADERS) - doxygen > /dev/null +doc: Doxyfile $(BUILD_OBJ)/timestamp gen_code_static + $(DOXYGEN) > /dev/null gen_code_static: $(GEN_CODE) gen_code: gen_code_static $(GEN_CODE_P2) diff --git a/src/GENERATED/c/curve25519/eddsa.c b/src/GENERATED/c/curve25519/eddsa.c index 9d361b9..bf7b764 100644 --- a/src/GENERATED/c/curve25519/eddsa.c +++ b/src/GENERATED/c/curve25519/eddsa.c @@ -38,12 +38,6 @@ const uint8_t NO_CONTEXT_POINTS_HERE = 0; const uint8_t * const DECAF_ED25519_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE; #endif -/* EDDSA_BASE_POINT_RATIO = 1 or 2 - * Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d, - * its base point is twice ours. - */ -#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) /* TODO: remove */ - static void clamp ( uint8_t secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES] ) { diff --git a/src/GENERATED/c/ed448goldilocks/eddsa.c b/src/GENERATED/c/ed448goldilocks/eddsa.c index f6c1836..cedb38c 100644 --- a/src/GENERATED/c/ed448goldilocks/eddsa.c +++ b/src/GENERATED/c/ed448goldilocks/eddsa.c @@ -38,12 +38,6 @@ const uint8_t NO_CONTEXT_POINTS_HERE = 0; const uint8_t * const DECAF_ED448_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE; #endif -/* EDDSA_BASE_POINT_RATIO = 1 or 2 - * Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d, - * its base point is twice ours. - */ -#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) /* TODO: remove */ - static void clamp ( uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES] ) { diff --git a/src/GENERATED/include/decaf.hxx b/src/GENERATED/include/decaf.hxx index 2712aa8..3ef7c08 100644 --- a/src/GENERATED/include/decaf.hxx +++ b/src/GENERATED/include/decaf.hxx @@ -18,7 +18,9 @@ #include #include +/** Namespace for all C++ decaf objects. */ namespace decaf { + /** Given a template with a "run" function, run it for all curves */ template class Run> void run_for_all_curves() { Run::run(); diff --git a/src/GENERATED/include/decaf/common.h b/src/GENERATED/include/decaf/common.h index 64719ad..f891a0a 100644 --- a/src/GENERATED/include/decaf/common.h +++ b/src/GENERATED/include/decaf/common.h @@ -21,8 +21,9 @@ extern "C" { /* Goldilocks' build flags default to hidden and stripping executables. */ /** @cond internal */ -#if defined(DOXYGEN) && !defined(__attribute__) -#define __attribute__((x)) +#if DOXYGEN || defined(__attribute__) +#define __attribute__(x) +#define NOINLINE #endif #define DECAF_API_VIS __attribute__((visibility("default"))) #define DECAF_NOINLINE __attribute__((noinline)) diff --git a/src/GENERATED/include/decaf/ed255.h b/src/GENERATED/include/decaf/ed255.h index 4e5cb0b..0811f96 100644 --- a/src/GENERATED/include/decaf/ed255.h +++ b/src/GENERATED/include/decaf/ed255.h @@ -36,10 +36,17 @@ extern "C" { #define DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS 1 extern const uint8_t * const DECAF_ED25519_NO_CONTEXT DECAF_API_VIS; -/** Prehash context renaming macros. */ + +/** Prehash context (raw), because each EdDSA instance has a different prehash. */ #define decaf_ed25519_prehash_ctx_s decaf_sha512_ctx_s + +/** Prehash context, array[1] form. */ #define decaf_ed25519_prehash_ctx_t decaf_sha512_ctx_t + +/** Prehash update. */ #define decaf_ed25519_prehash_update decaf_sha512_update + +/** Prehash destroy. */ #define decaf_ed25519_prehash_destroy decaf_sha512_destroy /** EdDSA encoding ratio. */ diff --git a/src/GENERATED/include/decaf/ed255.hxx b/src/GENERATED/include/decaf/ed255.hxx index 07099cb..b74bfc1 100644 --- a/src/GENERATED/include/decaf/ed255.hxx +++ b/src/GENERATED/include/decaf/ed255.hxx @@ -14,7 +14,6 @@ #ifndef __DECAF_ED255_HXX__ #define __DECAF_ED255_HXX__ 1 - /* * Example Decaf cyrpto routines, C++ wrapper. * @warning These are merely examples, though they ought to be secure. But real @@ -38,6 +37,7 @@ #endif /** @endcond */ +/** Namespace for all libdecaf C++ objects. */ namespace decaf { /** A public key for crypto over some Group */ @@ -55,7 +55,14 @@ typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh; typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh; /** @endcond */ - +/** + * Signatures support a "context" block, which allows you to domain separate them if + * (for some reason) it's annoying to domain separate the message itself. The default + * is no context. For Ed25519, the spec defining contexts is an extension, and the + * default is not to use that extension. This makes "no context" different from + * the empty string. For Ed448, contexts are built-in and mandatory, so "no context" + * is the same as the empty string. + */ #if DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS static inline const Block NO_CONTEXT() { return Block(DECAF_ED25519_NO_CONTEXT,0); } #else @@ -65,6 +72,7 @@ static inline const Block NO_CONTEXT() { return Block(NULL,0); } /** Prehash context for EdDSA. */ class Prehash : public SHA512 { private: + /** @cond internal */ typedef SHA512 Super; SecureBuffer context_; template friend class Signing; @@ -79,6 +87,7 @@ private: decaf_ed25519_prehash_init((decaf_sha512_ctx_s *)wrapped); } + /** @endcond */ public: /** Number of output bytes in prehash */ @@ -108,35 +117,10 @@ public: } }; +/** Signing (i.e. private) key class template */ template class Signing; -template class Signing { -public: - /* Sign a prehash context, and reset the context */ - inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ { - SecureBuffer out(CRTP::SIG_BYTES); - decaf_ed25519_sign_prehash ( - out.data(), - ((const CRTP*)this)->priv_.data(), - ((const CRTP*)this)->pub_.data(), - (const decaf_ed25519_prehash_ctx_s*)ph.wrapped, - ph.context_.data(), - ph.context_.size() - ); - return out; - } - - /* Sign a message using the prehasher */ - inline SecureBuffer sign_with_prehash ( - const Block &message, - const Block &context = NO_CONTEXT() - ) const /*throw(LengthException,CryptoException)*/ { - Prehash ph(context); - ph += message; - return sign_prehashed(ph); - } -}; - +/** Signing (i.e. private) key class, PureEdDSA version */ template class Signing { public: /** @@ -169,12 +153,42 @@ public: } }; +/** Signing (i.e. private) key class, prehashed version */ +template class Signing { +public: + /** Sign a prehash context, and reset the context */ + inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ { + SecureBuffer out(CRTP::SIG_BYTES); + decaf_ed25519_sign_prehash ( + out.data(), + ((const CRTP*)this)->priv_.data(), + ((const CRTP*)this)->pub_.data(), + (const decaf_ed25519_prehash_ctx_s*)ph.wrapped, + ph.context_.data(), + ph.context_.size() + ); + return out; + } + + /** Sign a message using the prehasher */ + inline SecureBuffer sign_with_prehash ( + const Block &message, + const Block &context = NO_CONTEXT() + ) const /*throw(LengthException,CryptoException)*/ { + Prehash ph(context); + ph += message; + return sign_prehashed(ph); + } +}; + +/** Signing (i.e. private) key base class */ class PrivateKeyBase : public Serializable , public Signing , public Signing { public: - typedef class PublicKeyBase MyPublicKey; + /** Type of public key corresponding to this private key */ + typedef class PublicKeyBase PublicKey; private: /** @cond internal */ friend class PublicKeyBase; @@ -243,14 +257,13 @@ public: } /** Return the corresponding public key */ - inline MyPublicKey pub() const DECAF_NOEXCEPT { - MyPublicKey pub(*this); + inline PublicKey pub() const DECAF_NOEXCEPT { + PublicKey pub(*this); return pub; } }; /* class PrivateKey */ - - +/** Verification (i.e. public) EdDSA key, PureEdDSA version. */ template class Verification { public: /** Verify a signature, returning DECAF_FAILURE if verification fails */ @@ -296,10 +309,10 @@ public: } }; - +/** Verification (i.e. public) EdDSA key, prehashed version. */ template class Verification { public: - /* Verify a prehash context. */ + /** Verify that a signature is valid for a given prehashed message, given the context. */ inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept ( const FixedBlock &sig, const Prehash &ph @@ -312,8 +325,8 @@ public: ph.context_.size() ); } - - /* Verify a prehash context. */ + + /** Verify that a signature is valid for a given prehashed message, given the context. */ inline void verify_prehashed ( const FixedBlock &sig, const Prehash &ph @@ -329,7 +342,7 @@ public: } } - /* Verify a message using the prehasher */ + /** Hash and verify a message, using the prehashed verification mode. */ inline void verify_with_prehash ( const FixedBlock &sig, const Block &message, @@ -341,24 +354,25 @@ public: } }; - +/** EdDSA Public key base class. */ class PublicKeyBase : public Serializable , public Verification , public Verification { public: - typedef class PrivateKeyBase MyPrivateKey; + /** Private key corresponding to this type of public key */ + typedef class PrivateKeyBase PrivateKey; private: /** @cond internal */ friend class PrivateKeyBase; friend class Verification; friend class Verification; -/** @endcond */ private: /** The pre-expansion form of the signature */ FixedArrayBuffer pub_; +/** @endcond */ public: /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */ @@ -372,7 +386,6 @@ public: /** Serialization size. */ static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES; - /** Create but don't initialize */ inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { } @@ -383,7 +396,7 @@ public: inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; } /** Copy constructor */ - inline explicit PublicKeyBase(const MyPrivateKey &k) DECAF_NOEXCEPT { *this = k; } + inline explicit PublicKeyBase(const PrivateKey &k) DECAF_NOEXCEPT { *this = k; } /** Assignment from string */ inline PublicKey &operator=(const FixedBlock &b) DECAF_NOEXCEPT { @@ -397,7 +410,7 @@ public: } /** Assignment from private key */ - inline PublicKey &operator=(const MyPrivateKey &p) DECAF_NOEXCEPT { + inline PublicKey &operator=(const PrivateKey &p) DECAF_NOEXCEPT { return *this = p.pub_; } diff --git a/src/GENERATED/include/decaf/ed448.h b/src/GENERATED/include/decaf/ed448.h index eeed619..6d08685 100644 --- a/src/GENERATED/include/decaf/ed448.h +++ b/src/GENERATED/include/decaf/ed448.h @@ -35,10 +35,17 @@ extern "C" { /** Does EdDSA support non-contextual signatures? */ #define DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS 0 -/** Prehash context renaming macros. */ + +/** Prehash context (raw), because each EdDSA instance has a different prehash. */ #define decaf_ed448_prehash_ctx_s decaf_shake256_ctx_s + +/** Prehash context, array[1] form. */ #define decaf_ed448_prehash_ctx_t decaf_shake256_ctx_t + +/** Prehash update. */ #define decaf_ed448_prehash_update decaf_shake256_update + +/** Prehash destroy. */ #define decaf_ed448_prehash_destroy decaf_shake256_destroy /** EdDSA encoding ratio. */ diff --git a/src/GENERATED/include/decaf/ed448.hxx b/src/GENERATED/include/decaf/ed448.hxx index 6ad6031..b1c4ea5 100644 --- a/src/GENERATED/include/decaf/ed448.hxx +++ b/src/GENERATED/include/decaf/ed448.hxx @@ -14,7 +14,6 @@ #ifndef __DECAF_ED448_HXX__ #define __DECAF_ED448_HXX__ 1 - /* * Example Decaf cyrpto routines, C++ wrapper. * @warning These are merely examples, though they ought to be secure. But real @@ -38,6 +37,7 @@ #endif /** @endcond */ +/** Namespace for all libdecaf C++ objects. */ namespace decaf { /** A public key for crypto over some Group */ @@ -55,7 +55,14 @@ typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh; typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh; /** @endcond */ - +/** + * Signatures support a "context" block, which allows you to domain separate them if + * (for some reason) it's annoying to domain separate the message itself. The default + * is no context. For Ed25519, the spec defining contexts is an extension, and the + * default is not to use that extension. This makes "no context" different from + * the empty string. For Ed448, contexts are built-in and mandatory, so "no context" + * is the same as the empty string. + */ #if DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS static inline const Block NO_CONTEXT() { return Block(DECAF_ED448_NO_CONTEXT,0); } #else @@ -65,6 +72,7 @@ static inline const Block NO_CONTEXT() { return Block(NULL,0); } /** Prehash context for EdDSA. */ class Prehash : public SHAKE<256> { private: + /** @cond internal */ typedef SHAKE<256> Super; SecureBuffer context_; template friend class Signing; @@ -79,6 +87,7 @@ private: decaf_ed448_prehash_init((decaf_shake256_ctx_s *)wrapped); } + /** @endcond */ public: /** Number of output bytes in prehash */ @@ -108,35 +117,10 @@ public: } }; +/** Signing (i.e. private) key class template */ template class Signing; -template class Signing { -public: - /* Sign a prehash context, and reset the context */ - inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ { - SecureBuffer out(CRTP::SIG_BYTES); - decaf_ed448_sign_prehash ( - out.data(), - ((const CRTP*)this)->priv_.data(), - ((const CRTP*)this)->pub_.data(), - (const decaf_ed448_prehash_ctx_s*)ph.wrapped, - ph.context_.data(), - ph.context_.size() - ); - return out; - } - - /* Sign a message using the prehasher */ - inline SecureBuffer sign_with_prehash ( - const Block &message, - const Block &context = NO_CONTEXT() - ) const /*throw(LengthException,CryptoException)*/ { - Prehash ph(context); - ph += message; - return sign_prehashed(ph); - } -}; - +/** Signing (i.e. private) key class, PureEdDSA version */ template class Signing { public: /** @@ -169,12 +153,42 @@ public: } }; +/** Signing (i.e. private) key class, prehashed version */ +template class Signing { +public: + /** Sign a prehash context, and reset the context */ + inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ { + SecureBuffer out(CRTP::SIG_BYTES); + decaf_ed448_sign_prehash ( + out.data(), + ((const CRTP*)this)->priv_.data(), + ((const CRTP*)this)->pub_.data(), + (const decaf_ed448_prehash_ctx_s*)ph.wrapped, + ph.context_.data(), + ph.context_.size() + ); + return out; + } + + /** Sign a message using the prehasher */ + inline SecureBuffer sign_with_prehash ( + const Block &message, + const Block &context = NO_CONTEXT() + ) const /*throw(LengthException,CryptoException)*/ { + Prehash ph(context); + ph += message; + return sign_prehashed(ph); + } +}; + +/** Signing (i.e. private) key base class */ class PrivateKeyBase : public Serializable , public Signing , public Signing { public: - typedef class PublicKeyBase MyPublicKey; + /** Type of public key corresponding to this private key */ + typedef class PublicKeyBase PublicKey; private: /** @cond internal */ friend class PublicKeyBase; @@ -243,14 +257,13 @@ public: } /** Return the corresponding public key */ - inline MyPublicKey pub() const DECAF_NOEXCEPT { - MyPublicKey pub(*this); + inline PublicKey pub() const DECAF_NOEXCEPT { + PublicKey pub(*this); return pub; } }; /* class PrivateKey */ - - +/** Verification (i.e. public) EdDSA key, PureEdDSA version. */ template class Verification { public: /** Verify a signature, returning DECAF_FAILURE if verification fails */ @@ -296,10 +309,10 @@ public: } }; - +/** Verification (i.e. public) EdDSA key, prehashed version. */ template class Verification { public: - /* Verify a prehash context. */ + /** Verify that a signature is valid for a given prehashed message, given the context. */ inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept ( const FixedBlock &sig, const Prehash &ph @@ -312,8 +325,8 @@ public: ph.context_.size() ); } - - /* Verify a prehash context. */ + + /** Verify that a signature is valid for a given prehashed message, given the context. */ inline void verify_prehashed ( const FixedBlock &sig, const Prehash &ph @@ -329,7 +342,7 @@ public: } } - /* Verify a message using the prehasher */ + /** Hash and verify a message, using the prehashed verification mode. */ inline void verify_with_prehash ( const FixedBlock &sig, const Block &message, @@ -341,24 +354,25 @@ public: } }; - +/** EdDSA Public key base class. */ class PublicKeyBase : public Serializable , public Verification , public Verification { public: - typedef class PrivateKeyBase MyPrivateKey; + /** Private key corresponding to this type of public key */ + typedef class PrivateKeyBase PrivateKey; private: /** @cond internal */ friend class PrivateKeyBase; friend class Verification; friend class Verification; -/** @endcond */ private: /** The pre-expansion form of the signature */ FixedArrayBuffer pub_; +/** @endcond */ public: /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */ @@ -372,7 +386,6 @@ public: /** Serialization size. */ static const size_t SER_BYTES = DECAF_EDDSA_448_PRIVATE_BYTES; - /** Create but don't initialize */ inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { } @@ -383,7 +396,7 @@ public: inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; } /** Copy constructor */ - inline explicit PublicKeyBase(const MyPrivateKey &k) DECAF_NOEXCEPT { *this = k; } + inline explicit PublicKeyBase(const PrivateKey &k) DECAF_NOEXCEPT { *this = k; } /** Assignment from string */ inline PublicKey &operator=(const FixedBlock &b) DECAF_NOEXCEPT { @@ -397,7 +410,7 @@ public: } /** Assignment from private key */ - inline PublicKey &operator=(const MyPrivateKey &p) DECAF_NOEXCEPT { + inline PublicKey &operator=(const PrivateKey &p) DECAF_NOEXCEPT { return *this = p.pub_; } diff --git a/src/GENERATED/include/decaf/eddsa.hxx b/src/GENERATED/include/decaf/eddsa.hxx index 7a30ce7..867c5d2 100644 --- a/src/GENERATED/include/decaf/eddsa.hxx +++ b/src/GENERATED/include/decaf/eddsa.hxx @@ -15,7 +15,15 @@ #ifndef __DECAF_EDDSA_HXX__ #define __DECAF_EDDSA_HXX__ 1 -namespace decaf { enum Prehashed { PURE, PREHASHED }; } +/** Namespace for all libdecaf C++ objects. */ +namespace decaf { + /** How signatures handle hashing. */ + enum Prehashed { + PURE, /**< Sign the message itself. This can't be done in one pass. */ + PREHASHED /**< Sign the hash of the message. */ + }; +} + #include #include diff --git a/src/GENERATED/include/decaf/point_255.h b/src/GENERATED/include/decaf/point_255.h index 94e30a5..58ec3f8 100644 --- a/src/GENERATED/include/decaf/point_255.h +++ b/src/GENERATED/include/decaf/point_255.h @@ -64,10 +64,10 @@ typedef struct gf_25519_s { /** Number of bytes in an x25519 private key */ #define DECAF_X25519_PRIVATE_BYTES 32 -/** Twisted Edwards extended homogeneous coordinates */ +/** Representation of a point on the elliptic curve. */ typedef struct decaf_255_point_s { /** @cond internal */ - gf_25519_t x,y,z,t; + gf_25519_t x,y,z,t; /* Twisted extended homogeneous coordinates */ /** @endcond */ } decaf_255_point_t[1]; @@ -80,26 +80,26 @@ typedef struct decaf_255_precomputed_s decaf_255_precomputed_s; /** Size and alignment of precomputed point tables. */ extern const size_t decaf_255_sizeof_precomputed_s DECAF_API_VIS, decaf_255_alignof_precomputed_s DECAF_API_VIS; -/** Scalar is stored packed, because we don't need the speed. */ +/** Representation of an element of the scalar field. */ typedef struct decaf_255_scalar_s { /** @cond internal */ decaf_word_t limb[DECAF_255_SCALAR_LIMBS]; /** @endcond */ } decaf_255_scalar_t[1]; -/** A scalar equal to 1. */ +/** The scalar 1. */ extern const decaf_255_scalar_t decaf_255_scalar_one DECAF_API_VIS; -/** A scalar equal to 0. */ +/** The scalar 0. */ extern const decaf_255_scalar_t decaf_255_scalar_zero DECAF_API_VIS; -/** The identity point on the curve. */ +/** The identity (zero) point on the curve. */ extern const decaf_255_point_t decaf_255_point_identity DECAF_API_VIS; -/** An arbitrarily chosen base point on the curve. */ +/** An arbitrarily-chosen base point on the curve. */ extern const decaf_255_point_t decaf_255_point_base DECAF_API_VIS; -/** Precomputed table for the base point on the curve. */ +/** Precomputed table of multiples of the base point on the curve. */ extern const struct decaf_255_precomputed_s *decaf_255_precomputed_base DECAF_API_VIS; /** @@ -386,19 +386,19 @@ decaf_error_t decaf_255_direct_scalarmul ( ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; /** - * @brief RFC 7748 Diffie-Hellman scalarmul. This function uses a different - * (non-Decaf) encoding. + * @brief RFC 7748 Diffie-Hellman scalarmul, used to compute shared secrets. + * This function uses a different (non-Decaf) encoding. * - * @param [out] scaled The scaled point base*scalar - * @param [in] base The point to be scaled. - * @param [in] scalar The scalar to multiply by. + * @param [out] shared The shared secret base*scalar + * @param [in] base The other party's public key, used as the base of the scalarmul. + * @param [in] scalar The private scalar to multiply by. * * @retval DECAF_SUCCESS The scalarmul succeeded. * @retval DECAF_FAILURE The scalarmul didn't succeed, because the base * point is in a small subgroup. */ decaf_error_t decaf_x25519 ( - uint8_t out[DECAF_X25519_PUBLIC_BYTES], + uint8_t shared[DECAF_X25519_PUBLIC_BYTES], const uint8_t base[DECAF_X25519_PUBLIC_BYTES], const uint8_t scalar[DECAF_X25519_PRIVATE_BYTES] ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; @@ -429,7 +429,13 @@ void decaf_255_point_mul_by_ratio_and_encode_like_x25519 ( ) DECAF_API_VIS DECAF_NONNULL; /** The base point for X25519 Diffie-Hellman */ -extern const uint8_t decaf_x25519_base_point[DECAF_X25519_PUBLIC_BYTES] DECAF_API_VIS; +extern const uint8_t + decaf_x25519_base_point[DECAF_X25519_PUBLIC_BYTES] +#ifndef DOXYGEN + /* For some reason Doxygen chokes on this despite the defense in common.h... */ + DECAF_API_VIS +#endif +; /** * @brief RFC 7748 Diffie-Hellman base point scalarmul. This function uses @@ -438,8 +444,8 @@ extern const uint8_t decaf_x25519_base_point[DECAF_X25519_PUBLIC_BYTES] DECAF_AP * @deprecated Renamed to decaf_x25519_derive_public_key. * I have no particular timeline for removing this name. * - * @param [out] scaled The scaled point base*scalar - * @param [in] scalar The scalar to multiply by. + * @param [out] out The public key base*scalar. + * @param [in] scalar The private scalar. */ void decaf_x25519_generate_key ( uint8_t out[DECAF_X25519_PUBLIC_BYTES], @@ -453,8 +459,8 @@ void decaf_x25519_generate_key ( * Does exactly the same thing as decaf_x25519_generate_key, * but has a better name. * - * @param [out] scaled The scaled point base*scalar - * @param [in] scalar The scalar to multiply by. + * @param [out] out The public key base*scalar + * @param [in] scalar The private scalar. */ void decaf_x25519_derive_public_key ( uint8_t out[DECAF_X25519_PUBLIC_BYTES], @@ -737,22 +743,20 @@ decaf_255_invert_elligator_uniform ( uint32_t which ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED; -/** - * @brief Overwrite scalar with zeros. - */ +/** Securely erase a scalar. */ void decaf_255_scalar_destroy ( decaf_255_scalar_t scalar ) DECAF_NONNULL DECAF_API_VIS; -/** - * @brief Overwrite point with zeros. +/** Securely erase a point by overwriting it with zeros. + * @warning This causes the point object to become invalid. */ void decaf_255_point_destroy ( decaf_255_point_t point ) DECAF_NONNULL DECAF_API_VIS; -/** - * @brief Overwrite precomputed table with zeros. +/** Securely erase a precomputed table by overwriting it with zeros. + * @warning This causes the table object to become invalid. */ void decaf_255_precomputed_destroy ( decaf_255_precomputed_s *pre diff --git a/src/GENERATED/include/decaf/point_255.hxx b/src/GENERATED/include/decaf/point_255.hxx index f359944..905a8bc 100644 --- a/src/GENERATED/include/decaf/point_255.hxx +++ b/src/GENERATED/include/decaf/point_255.hxx @@ -6,18 +6,17 @@ * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * - * A group of prime order p, C++ wrapper. + * A group of prime order, 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 + * group of prime order. It accomplishes this by using a twisted Edwards * curve (isogenous to Curve25519) and wiping out the cofactor. * - * The formulas are all complete and have no special cases, except that - * decaf_255_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 decaf_255_base_double_scalarmul_non_secret. + * Most of the functions in this file run in constant time, can't fail + * except for ubiquitous reasons like memory exhaustion, and contain no + * data-dependend branches, timing or memory accesses. There are some + * exceptions, which should be noted. Typically, decoding functions can + * fail. * * @warning This file was automatically generated in Python. * Please do not edit it. @@ -187,8 +186,9 @@ public: /** Negate */ inline Scalar operator- () const DECAF_NOEXCEPT { Scalar r((NOINIT())); decaf_255_scalar_sub(r.s,decaf_255_scalar_zero,s); return r; } - /** Invert with Fermat's Little Theorem (slow!). If *this == 0, - * throw CryptoException. */ + /** Return 1/this. + * @throw CryptoException if this is 0. + */ inline Scalar inverse() const /*throw(CryptoException)*/ { Scalar r; if (DECAF_SUCCESS != decaf_255_scalar_invert(r.s,s)) { @@ -204,10 +204,10 @@ public: return decaf_255_scalar_invert(r.s,s); } - /** Divide by inverting q. If q == 0, return 0. */ + /** Return this/q. @throw CryptoException if q == 0. */ inline Scalar operator/ (const Scalar &q) const /*throw(CryptoException)*/ { return *this * q.inverse(); } - /** Divide by inverting q. If q == 0, return 0. */ + /** Set this to this/q. @throw CryptoException if q == 0. */ inline Scalar &operator/=(const Scalar &q) /*throw(CryptoException)*/ { return *this *= q.inverse(); } /** Return half this scalar. Much faster than /2. */ @@ -225,7 +225,9 @@ public: /** Scalarmul-precomputed with scalar on left. */ inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } - /** Direct scalar multiplication. */ + /** Direct scalar multiplication. + * @throw CryptoException if the input didn't decode. + */ inline SecureBuffer direct_scalarmul ( const FixedBlock &in, decaf_bool_t allow_identity=DECAF_FALSE, @@ -241,12 +243,10 @@ public: ) const DECAF_NOEXCEPT; }; -/** - * Element of prime-order group. - */ +/** Element of prime-order elliptic curve group. */ class Point : public Serializable { public: - /** wrapped C type */ + /** Wrapped C type */ typedef decaf_255_point_t Wrapped; /** Size of a serialized element */ @@ -270,17 +270,8 @@ public: /** Ratio due to ladder decoding */ static const int LADDER_ENCODE_RATIO = DECAF_X25519_ENCODE_RATIO; - /** - * Size of a stegged element. - * - * FUTURE: You can use HASH_BYTES * 3/2 (or more likely much less, eg HASH_BYTES + 8) - * with a random oracle hash function, by hash-expanding everything past the first - * HASH_BYTES of the element. However, since the internal C invert_elligator is not - * tied to a hash function, I didn't want to tie the C++ wrapper to a hash function - * either. But it might be a good idea to do this in the future, either with STROBE - * or something else. - * - * Then again, calling invert_elligator at all is super niche, so maybe who cares? + /** Size of a steganographically-encoded curve element. If the point is random, the encoding + * should look statistically close to a uniformly-random sequnece of STEG_BYTES bytes. */ static const size_t STEG_BYTES = HASH_BYTES * 2; @@ -325,9 +316,9 @@ public: * @throw CryptoException the string was the wrong length, or wasn't the encoding of a point, * or was the identity and allow_identity was DECAF_FALSE. */ - inline explicit Point(const FixedBlock &buffer, decaf_bool_t allow_identity=DECAF_TRUE) + inline explicit Point(const FixedBlock &buffer, bool allow_identity=true) /*throw(CryptoException)*/ { - if (DECAF_SUCCESS != decode(buffer,allow_identity)) { + if (DECAF_SUCCESS != decode(buffer,allow_identity ? DECAF_TRUE : DECAF_FALSE)) { throw CryptoException(); } } @@ -341,9 +332,9 @@ public: * or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined. */ inline decaf_error_t DECAF_WARN_UNUSED decode ( - const FixedBlock &buffer, decaf_bool_t allow_identity=DECAF_TRUE + const FixedBlock &buffer, bool allow_identity=true ) DECAF_NOEXCEPT { - return decaf_255_point_decode(p,buffer.data(),allow_identity); + return decaf_255_point_decode(p,buffer.data(),allow_identity ? DECAF_TRUE : DECAF_FALSE); } /** @@ -393,9 +384,7 @@ public: } /** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */ - inline void mul_by_ratio_and_encode_like_ladder( - FixedBuffer &out - ) const { + inline void mul_by_ratio_and_encode_like_ladder(FixedBuffer &out) const { decaf_255_point_mul_by_ratio_and_encode_like_x25519(out.data(),p); } @@ -431,9 +420,7 @@ public: } } - /** - * Encode to string. The identity encodes to the all-zero string. - */ + /** Encode to string. The identity encodes to the all-zero string. */ inline operator SecureBuffer() const { SecureBuffer buffer(SER_BYTES); decaf_255_point_encode(buffer.data(), p); @@ -583,10 +570,10 @@ public: return out; } - /** Return the base point */ + /** Return the base point of the curve. */ static inline const Point base() DECAF_NOEXCEPT { return Point(decaf_255_point_base); } - /** Return the identity point */ + /** Return the identity point of the curve. */ static inline const Point identity() DECAF_NOEXCEPT { return Point(decaf_255_point_identity); } }; @@ -684,6 +671,7 @@ public: /** @endcond */ }; +/** X-only Diffie-Hellman ladder functions */ struct DhLadder { public: /** Bytes in an X25519 public key. */ @@ -758,7 +746,8 @@ public: * equivalent to shared_secret(base_point(),scalar) but possibly faster. * @deprecated Renamed to derive_public_key_noexcept. */ - static inline void DECAF_DEPRECATED("Renamed to derive_public_key_noexcept") + static inline void + DECAF_DEPRECATED("Renamed to derive_public_key_noexcept") generate_key_noexcept ( FixedBuffer &out, const FixedBlock &scalar @@ -794,6 +783,7 @@ inline decaf_error_t Ristretto::Scalar::direct_scalarmul_noexcept ( } /** @endcond */ +/** Alternative name for Ristretto, for backwards compatibility */ typedef Ristretto IsoEd25519; diff --git a/src/GENERATED/include/decaf/point_448.h b/src/GENERATED/include/decaf/point_448.h index bc1cb43..0562f23 100644 --- a/src/GENERATED/include/decaf/point_448.h +++ b/src/GENERATED/include/decaf/point_448.h @@ -64,10 +64,10 @@ typedef struct gf_448_s { /** Number of bytes in an x448 private key */ #define DECAF_X448_PRIVATE_BYTES 56 -/** Twisted Edwards extended homogeneous coordinates */ +/** Representation of a point on the elliptic curve. */ typedef struct decaf_448_point_s { /** @cond internal */ - gf_448_t x,y,z,t; + gf_448_t x,y,z,t; /* Twisted extended homogeneous coordinates */ /** @endcond */ } decaf_448_point_t[1]; @@ -80,26 +80,26 @@ typedef struct decaf_448_precomputed_s decaf_448_precomputed_s; /** Size and alignment of precomputed point tables. */ extern const size_t decaf_448_sizeof_precomputed_s DECAF_API_VIS, decaf_448_alignof_precomputed_s DECAF_API_VIS; -/** Scalar is stored packed, because we don't need the speed. */ +/** Representation of an element of the scalar field. */ typedef struct decaf_448_scalar_s { /** @cond internal */ decaf_word_t limb[DECAF_448_SCALAR_LIMBS]; /** @endcond */ } decaf_448_scalar_t[1]; -/** A scalar equal to 1. */ +/** The scalar 1. */ extern const decaf_448_scalar_t decaf_448_scalar_one DECAF_API_VIS; -/** A scalar equal to 0. */ +/** The scalar 0. */ extern const decaf_448_scalar_t decaf_448_scalar_zero DECAF_API_VIS; -/** The identity point on the curve. */ +/** The identity (zero) point on the curve. */ extern const decaf_448_point_t decaf_448_point_identity DECAF_API_VIS; -/** An arbitrarily chosen base point on the curve. */ +/** An arbitrarily-chosen base point on the curve. */ extern const decaf_448_point_t decaf_448_point_base DECAF_API_VIS; -/** Precomputed table for the base point on the curve. */ +/** Precomputed table of multiples of the base point on the curve. */ extern const struct decaf_448_precomputed_s *decaf_448_precomputed_base DECAF_API_VIS; /** @@ -386,19 +386,19 @@ decaf_error_t decaf_448_direct_scalarmul ( ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; /** - * @brief RFC 7748 Diffie-Hellman scalarmul. This function uses a different - * (non-Decaf) encoding. + * @brief RFC 7748 Diffie-Hellman scalarmul, used to compute shared secrets. + * This function uses a different (non-Decaf) encoding. * - * @param [out] scaled The scaled point base*scalar - * @param [in] base The point to be scaled. - * @param [in] scalar The scalar to multiply by. + * @param [out] shared The shared secret base*scalar + * @param [in] base The other party's public key, used as the base of the scalarmul. + * @param [in] scalar The private scalar to multiply by. * * @retval DECAF_SUCCESS The scalarmul succeeded. * @retval DECAF_FAILURE The scalarmul didn't succeed, because the base * point is in a small subgroup. */ decaf_error_t decaf_x448 ( - uint8_t out[DECAF_X448_PUBLIC_BYTES], + uint8_t shared[DECAF_X448_PUBLIC_BYTES], const uint8_t base[DECAF_X448_PUBLIC_BYTES], const uint8_t scalar[DECAF_X448_PRIVATE_BYTES] ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; @@ -429,7 +429,13 @@ void decaf_448_point_mul_by_ratio_and_encode_like_x448 ( ) DECAF_API_VIS DECAF_NONNULL; /** The base point for X448 Diffie-Hellman */ -extern const uint8_t decaf_x448_base_point[DECAF_X448_PUBLIC_BYTES] DECAF_API_VIS; +extern const uint8_t + decaf_x448_base_point[DECAF_X448_PUBLIC_BYTES] +#ifndef DOXYGEN + /* For some reason Doxygen chokes on this despite the defense in common.h... */ + DECAF_API_VIS +#endif +; /** * @brief RFC 7748 Diffie-Hellman base point scalarmul. This function uses @@ -438,8 +444,8 @@ extern const uint8_t decaf_x448_base_point[DECAF_X448_PUBLIC_BYTES] DECAF_API_VI * @deprecated Renamed to decaf_x448_derive_public_key. * I have no particular timeline for removing this name. * - * @param [out] scaled The scaled point base*scalar - * @param [in] scalar The scalar to multiply by. + * @param [out] out The public key base*scalar. + * @param [in] scalar The private scalar. */ void decaf_x448_generate_key ( uint8_t out[DECAF_X448_PUBLIC_BYTES], @@ -453,8 +459,8 @@ void decaf_x448_generate_key ( * Does exactly the same thing as decaf_x448_generate_key, * but has a better name. * - * @param [out] scaled The scaled point base*scalar - * @param [in] scalar The scalar to multiply by. + * @param [out] out The public key base*scalar + * @param [in] scalar The private scalar. */ void decaf_x448_derive_public_key ( uint8_t out[DECAF_X448_PUBLIC_BYTES], @@ -737,22 +743,20 @@ decaf_448_invert_elligator_uniform ( uint32_t which ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED; -/** - * @brief Overwrite scalar with zeros. - */ +/** Securely erase a scalar. */ void decaf_448_scalar_destroy ( decaf_448_scalar_t scalar ) DECAF_NONNULL DECAF_API_VIS; -/** - * @brief Overwrite point with zeros. +/** Securely erase a point by overwriting it with zeros. + * @warning This causes the point object to become invalid. */ void decaf_448_point_destroy ( decaf_448_point_t point ) DECAF_NONNULL DECAF_API_VIS; -/** - * @brief Overwrite precomputed table with zeros. +/** Securely erase a precomputed table by overwriting it with zeros. + * @warning This causes the table object to become invalid. */ void decaf_448_precomputed_destroy ( decaf_448_precomputed_s *pre diff --git a/src/GENERATED/include/decaf/point_448.hxx b/src/GENERATED/include/decaf/point_448.hxx index 3718778..a39ca2a 100644 --- a/src/GENERATED/include/decaf/point_448.hxx +++ b/src/GENERATED/include/decaf/point_448.hxx @@ -6,18 +6,17 @@ * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * - * A group of prime order p, C++ wrapper. + * A group of prime order, 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 + * group of prime order. It accomplishes this by using a twisted Edwards * curve (isogenous to Ed448-Goldilocks) and wiping out the cofactor. * - * The formulas are all complete and have no special cases, except that - * decaf_448_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 decaf_448_base_double_scalarmul_non_secret. + * Most of the functions in this file run in constant time, can't fail + * except for ubiquitous reasons like memory exhaustion, and contain no + * data-dependend branches, timing or memory accesses. There are some + * exceptions, which should be noted. Typically, decoding functions can + * fail. * * @warning This file was automatically generated in Python. * Please do not edit it. @@ -187,8 +186,9 @@ public: /** Negate */ inline Scalar operator- () const DECAF_NOEXCEPT { Scalar r((NOINIT())); decaf_448_scalar_sub(r.s,decaf_448_scalar_zero,s); return r; } - /** Invert with Fermat's Little Theorem (slow!). If *this == 0, - * throw CryptoException. */ + /** Return 1/this. + * @throw CryptoException if this is 0. + */ inline Scalar inverse() const /*throw(CryptoException)*/ { Scalar r; if (DECAF_SUCCESS != decaf_448_scalar_invert(r.s,s)) { @@ -204,10 +204,10 @@ public: return decaf_448_scalar_invert(r.s,s); } - /** Divide by inverting q. If q == 0, return 0. */ + /** Return this/q. @throw CryptoException if q == 0. */ inline Scalar operator/ (const Scalar &q) const /*throw(CryptoException)*/ { return *this * q.inverse(); } - /** Divide by inverting q. If q == 0, return 0. */ + /** Set this to this/q. @throw CryptoException if q == 0. */ inline Scalar &operator/=(const Scalar &q) /*throw(CryptoException)*/ { return *this *= q.inverse(); } /** Return half this scalar. Much faster than /2. */ @@ -225,7 +225,9 @@ public: /** Scalarmul-precomputed with scalar on left. */ inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } - /** Direct scalar multiplication. */ + /** Direct scalar multiplication. + * @throw CryptoException if the input didn't decode. + */ inline SecureBuffer direct_scalarmul ( const FixedBlock &in, decaf_bool_t allow_identity=DECAF_FALSE, @@ -241,12 +243,10 @@ public: ) const DECAF_NOEXCEPT; }; -/** - * Element of prime-order group. - */ +/** Element of prime-order elliptic curve group. */ class Point : public Serializable { public: - /** wrapped C type */ + /** Wrapped C type */ typedef decaf_448_point_t Wrapped; /** Size of a serialized element */ @@ -270,17 +270,8 @@ public: /** Ratio due to ladder decoding */ static const int LADDER_ENCODE_RATIO = DECAF_X448_ENCODE_RATIO; - /** - * Size of a stegged element. - * - * FUTURE: You can use HASH_BYTES * 3/2 (or more likely much less, eg HASH_BYTES + 8) - * with a random oracle hash function, by hash-expanding everything past the first - * HASH_BYTES of the element. However, since the internal C invert_elligator is not - * tied to a hash function, I didn't want to tie the C++ wrapper to a hash function - * either. But it might be a good idea to do this in the future, either with STROBE - * or something else. - * - * Then again, calling invert_elligator at all is super niche, so maybe who cares? + /** Size of a steganographically-encoded curve element. If the point is random, the encoding + * should look statistically close to a uniformly-random sequnece of STEG_BYTES bytes. */ static const size_t STEG_BYTES = HASH_BYTES * 2; @@ -325,9 +316,9 @@ public: * @throw CryptoException the string was the wrong length, or wasn't the encoding of a point, * or was the identity and allow_identity was DECAF_FALSE. */ - inline explicit Point(const FixedBlock &buffer, decaf_bool_t allow_identity=DECAF_TRUE) + inline explicit Point(const FixedBlock &buffer, bool allow_identity=true) /*throw(CryptoException)*/ { - if (DECAF_SUCCESS != decode(buffer,allow_identity)) { + if (DECAF_SUCCESS != decode(buffer,allow_identity ? DECAF_TRUE : DECAF_FALSE)) { throw CryptoException(); } } @@ -341,9 +332,9 @@ public: * or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined. */ inline decaf_error_t DECAF_WARN_UNUSED decode ( - const FixedBlock &buffer, decaf_bool_t allow_identity=DECAF_TRUE + const FixedBlock &buffer, bool allow_identity=true ) DECAF_NOEXCEPT { - return decaf_448_point_decode(p,buffer.data(),allow_identity); + return decaf_448_point_decode(p,buffer.data(),allow_identity ? DECAF_TRUE : DECAF_FALSE); } /** @@ -393,9 +384,7 @@ public: } /** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */ - inline void mul_by_ratio_and_encode_like_ladder( - FixedBuffer &out - ) const { + inline void mul_by_ratio_and_encode_like_ladder(FixedBuffer &out) const { decaf_448_point_mul_by_ratio_and_encode_like_x448(out.data(),p); } @@ -431,9 +420,7 @@ public: } } - /** - * Encode to string. The identity encodes to the all-zero string. - */ + /** Encode to string. The identity encodes to the all-zero string. */ inline operator SecureBuffer() const { SecureBuffer buffer(SER_BYTES); decaf_448_point_encode(buffer.data(), p); @@ -583,10 +570,10 @@ public: return out; } - /** Return the base point */ + /** Return the base point of the curve. */ static inline const Point base() DECAF_NOEXCEPT { return Point(decaf_448_point_base); } - /** Return the identity point */ + /** Return the identity point of the curve. */ static inline const Point identity() DECAF_NOEXCEPT { return Point(decaf_448_point_identity); } }; @@ -684,6 +671,7 @@ public: /** @endcond */ }; +/** X-only Diffie-Hellman ladder functions */ struct DhLadder { public: /** Bytes in an X448 public key. */ @@ -758,7 +746,8 @@ public: * equivalent to shared_secret(base_point(),scalar) but possibly faster. * @deprecated Renamed to derive_public_key_noexcept. */ - static inline void DECAF_DEPRECATED("Renamed to derive_public_key_noexcept") + static inline void + DECAF_DEPRECATED("Renamed to derive_public_key_noexcept") generate_key_noexcept ( FixedBuffer &out, const FixedBlock &scalar diff --git a/src/GENERATED/include/decaf/sha512.h b/src/GENERATED/include/decaf/sha512.h index 3c8ec70..ab810b4 100644 --- a/src/GENERATED/include/decaf/sha512.h +++ b/src/GENERATED/include/decaf/sha512.h @@ -18,21 +18,39 @@ extern "C" { #endif - +/** Hash context for SHA-512 */ typedef struct decaf_sha512_ctx_s { + /** @cond internal */ uint64_t state[8]; uint8_t block[128]; uint64_t bytes_processed; + /* @endcond */ } decaf_sha512_ctx_s, decaf_sha512_ctx_t[1]; +/** Initialize a SHA-512 context. */ void decaf_sha512_init(decaf_sha512_ctx_t ctx) DECAF_NONNULL DECAF_API_VIS; -void decaf_sha512_update(decaf_sha512_ctx_t ctx, const uint8_t *message, size_t length) DECAF_NONNULL DECAF_API_VIS; -void decaf_sha512_final(decaf_sha512_ctx_t ctx, uint8_t *out, size_t length) DECAF_NONNULL DECAF_API_VIS; +/** Update context by hashing part of a message. */ +void decaf_sha512_update(decaf_sha512_ctx_t ctx, const uint8_t *message, size_t message_len) DECAF_NONNULL DECAF_API_VIS; + +/** Finalize context and write out hash. + * @param [inout] ctx The context. Will be destroyed and re-initialized on return. + * @param [out] output Place to store the output hash. + * @param [in] output_len Length in bytes of the output hash. Must between 0 and 64, inclusive. + */ +void decaf_sha512_final(decaf_sha512_ctx_t ctx, uint8_t *output, size_t output_len) DECAF_NONNULL DECAF_API_VIS; + +/** Securely destroy a SHA512 context. */ static inline void decaf_sha512_destroy(decaf_sha512_ctx_t ctx) { decaf_bzero(ctx,sizeof(*ctx)); } +/** Hash a message. + * @param [out] output Place to store the output hash. + * @param [in] output_len Length in bytes of the output hash. Must between 0 and 64, inclusive. + * @param [in] message A message to hash. + * @param [in] message_len Length in bytes of the input message. + */ static inline void decaf_sha512_hash( uint8_t *output, size_t output_len, diff --git a/src/GENERATED/include/decaf/sha512.hxx b/src/GENERATED/include/decaf/sha512.hxx index e63c051..32e86a3 100644 --- a/src/GENERATED/include/decaf/sha512.hxx +++ b/src/GENERATED/include/decaf/sha512.hxx @@ -31,9 +31,9 @@ protected: /** @cond internal */ /** The C-wrapper sponge state */ decaf_sha512_ctx_t wrapped; + /** @endcond */ public: - /** Number of bytes ouf output */ static const size_t OUTPUT_BYTES = 64; diff --git a/src/GENERATED/include/decaf/spongerng.hxx b/src/GENERATED/include/decaf/spongerng.hxx index 0f1e054..e299e13 100644 --- a/src/GENERATED/include/decaf/spongerng.hxx +++ b/src/GENERATED/include/decaf/spongerng.hxx @@ -1,7 +1,5 @@ - - /** - * @file decaf/strobe.hxx + * @file decaf/spongerng.hxx * @copyright * Based on CC0 code by David Leon Gil, 2015 \n * Copyright (c) 2015 Cryptography Research, Inc. \n diff --git a/src/per_curve/eddsa.tmpl.h b/src/per_curve/eddsa.tmpl.h index b83b0fe..4530adc 100644 --- a/src/per_curve/eddsa.tmpl.h +++ b/src/per_curve/eddsa.tmpl.h @@ -20,10 +20,17 @@ extern "C" { /** Does EdDSA support non-contextual signatures? */ #define DECAF_EDDSA_$(gf_shortname)_SUPPORTS_CONTEXTLESS_SIGS $(eddsa_no_context) $("extern const uint8_t * const DECAF_ED" + gf_shortname + "_NO_CONTEXT DECAF_API_VIS;\n" if eddsa_no_context else "") -/** Prehash context renaming macros. */ + +/** Prehash context (raw), because each EdDSA instance has a different prehash. */ #define decaf_ed$(gf_shortname)_prehash_ctx_s decaf_$(eddsa_hash)_ctx_s + +/** Prehash context, array[1] form. */ #define decaf_ed$(gf_shortname)_prehash_ctx_t decaf_$(eddsa_hash)_ctx_t + +/** Prehash update. */ #define decaf_ed$(gf_shortname)_prehash_update decaf_$(eddsa_hash)_update + +/** Prehash destroy. */ #define decaf_ed$(gf_shortname)_prehash_destroy decaf_$(eddsa_hash)_destroy /** EdDSA encoding ratio. */ diff --git a/src/per_curve/eddsa.tmpl.hxx b/src/per_curve/eddsa.tmpl.hxx index ae562e4..997c653 100644 --- a/src/per_curve/eddsa.tmpl.hxx +++ b/src/per_curve/eddsa.tmpl.hxx @@ -1,4 +1,3 @@ - /* * Example Decaf cyrpto routines, C++ wrapper. * @warning These are merely examples, though they ought to be secure. But real @@ -22,6 +21,7 @@ #endif /** @endcond */ +/** Namespace for all libdecaf C++ objects. */ namespace decaf { /** A public key for crypto over some Group */ @@ -39,7 +39,14 @@ typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh; typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh; /** @endcond */ - +/** + * Signatures support a "context" block, which allows you to domain separate them if + * (for some reason) it's annoying to domain separate the message itself. The default + * is no context. For Ed25519, the spec defining contexts is an extension, and the + * default is not to use that extension. This makes "no context" different from + * the empty string. For Ed448, contexts are built-in and mandatory, so "no context" + * is the same as the empty string. + */ #if DECAF_EDDSA_$(gf_shortname)_SUPPORTS_CONTEXTLESS_SIGS static inline const Block NO_CONTEXT() { return Block(DECAF_ED$(gf_shortname)_NO_CONTEXT,0); } #else @@ -49,6 +56,7 @@ static inline const Block NO_CONTEXT() { return Block(NULL,0); } /** Prehash context for EdDSA. */ class Prehash : public $(re.sub(r"SHAKE(\d+)",r"SHAKE<\1>", eddsa_hash.upper())) { private: + /** @cond internal */ typedef $(re.sub(r"SHAKE(\d+)",r"SHAKE<\1>", eddsa_hash.upper())) Super; SecureBuffer context_; template friend class Signing; @@ -63,6 +71,7 @@ private: decaf_ed$(gf_shortname)_prehash_init((decaf_$(eddsa_hash)_ctx_s *)wrapped); } + /** @endcond */ public: /** Number of output bytes in prehash */ @@ -92,35 +101,10 @@ public: } }; +/** Signing (i.e. private) key class template */ template class Signing; -template class Signing { -public: - /* Sign a prehash context, and reset the context */ - inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ { - SecureBuffer out(CRTP::SIG_BYTES); - decaf_ed$(gf_shortname)_sign_prehash ( - out.data(), - ((const CRTP*)this)->priv_.data(), - ((const CRTP*)this)->pub_.data(), - (const decaf_ed$(gf_shortname)_prehash_ctx_s*)ph.wrapped, - ph.context_.data(), - ph.context_.size() - ); - return out; - } - - /* Sign a message using the prehasher */ - inline SecureBuffer sign_with_prehash ( - const Block &message, - const Block &context = NO_CONTEXT() - ) const /*throw(LengthException,CryptoException)*/ { - Prehash ph(context); - ph += message; - return sign_prehashed(ph); - } -}; - +/** Signing (i.e. private) key class, PureEdDSA version */ template class Signing { public: /** @@ -153,12 +137,42 @@ public: } }; +/** Signing (i.e. private) key class, prehashed version */ +template class Signing { +public: + /** Sign a prehash context, and reset the context */ + inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ { + SecureBuffer out(CRTP::SIG_BYTES); + decaf_ed$(gf_shortname)_sign_prehash ( + out.data(), + ((const CRTP*)this)->priv_.data(), + ((const CRTP*)this)->pub_.data(), + (const decaf_ed$(gf_shortname)_prehash_ctx_s*)ph.wrapped, + ph.context_.data(), + ph.context_.size() + ); + return out; + } + + /** Sign a message using the prehasher */ + inline SecureBuffer sign_with_prehash ( + const Block &message, + const Block &context = NO_CONTEXT() + ) const /*throw(LengthException,CryptoException)*/ { + Prehash ph(context); + ph += message; + return sign_prehashed(ph); + } +}; + +/** Signing (i.e. private) key base class */ class PrivateKeyBase : public Serializable , public Signing , public Signing { public: - typedef class PublicKeyBase MyPublicKey; + /** Type of public key corresponding to this private key */ + typedef class PublicKeyBase PublicKey; private: /** @cond internal */ friend class PublicKeyBase; @@ -227,14 +241,13 @@ public: } /** Return the corresponding public key */ - inline MyPublicKey pub() const DECAF_NOEXCEPT { - MyPublicKey pub(*this); + inline PublicKey pub() const DECAF_NOEXCEPT { + PublicKey pub(*this); return pub; } }; /* class PrivateKey */ - - +/** Verification (i.e. public) EdDSA key, PureEdDSA version. */ template class Verification { public: /** Verify a signature, returning DECAF_FAILURE if verification fails */ @@ -280,10 +293,10 @@ public: } }; - +/** Verification (i.e. public) EdDSA key, prehashed version. */ template class Verification { public: - /* Verify a prehash context. */ + /** Verify that a signature is valid for a given prehashed message, given the context. */ inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept ( const FixedBlock &sig, const Prehash &ph @@ -296,8 +309,8 @@ public: ph.context_.size() ); } - - /* Verify a prehash context. */ + + /** Verify that a signature is valid for a given prehashed message, given the context. */ inline void verify_prehashed ( const FixedBlock &sig, const Prehash &ph @@ -313,7 +326,7 @@ public: } } - /* Verify a message using the prehasher */ + /** Hash and verify a message, using the prehashed verification mode. */ inline void verify_with_prehash ( const FixedBlock &sig, const Block &message, @@ -325,24 +338,25 @@ public: } }; - +/** EdDSA Public key base class. */ class PublicKeyBase : public Serializable , public Verification , public Verification { public: - typedef class PrivateKeyBase MyPrivateKey; + /** Private key corresponding to this type of public key */ + typedef class PrivateKeyBase PrivateKey; private: /** @cond internal */ friend class PrivateKeyBase; friend class Verification; friend class Verification; -/** @endcond */ private: /** The pre-expansion form of the signature */ FixedArrayBuffer pub_; +/** @endcond */ public: /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */ @@ -356,7 +370,6 @@ public: /** Serialization size. */ static const size_t SER_BYTES = DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES; - /** Create but don't initialize */ inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { } @@ -367,7 +380,7 @@ public: inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; } /** Copy constructor */ - inline explicit PublicKeyBase(const MyPrivateKey &k) DECAF_NOEXCEPT { *this = k; } + inline explicit PublicKeyBase(const PrivateKey &k) DECAF_NOEXCEPT { *this = k; } /** Assignment from string */ inline PublicKey &operator=(const FixedBlock &b) DECAF_NOEXCEPT { @@ -381,7 +394,7 @@ public: } /** Assignment from private key */ - inline PublicKey &operator=(const MyPrivateKey &p) DECAF_NOEXCEPT { + inline PublicKey &operator=(const PrivateKey &p) DECAF_NOEXCEPT { return *this = p.pub_; } diff --git a/src/per_curve/point.tmpl.h b/src/per_curve/point.tmpl.h index a297c75..fc785a9 100644 --- a/src/per_curve/point.tmpl.h +++ b/src/per_curve/point.tmpl.h @@ -49,10 +49,10 @@ typedef struct gf_$(gf_shortname)_s { /** Number of bytes in an x$(gf_shortname) private key */ #define DECAF_X$(gf_shortname)_PRIVATE_BYTES $((gf_bits-1)//8 + 1) -/** Twisted Edwards extended homogeneous coordinates */ +/** Representation of a point on the elliptic curve. */ typedef struct $(c_ns)_point_s { /** @cond internal */ - gf_$(gf_shortname)_t x,y,z,t; + gf_$(gf_shortname)_t x,y,z,t; /* Twisted extended homogeneous coordinates */ /** @endcond */ } $(c_ns)_point_t[1]; @@ -65,26 +65,26 @@ typedef struct $(c_ns)_precomputed_s $(c_ns)_precomputed_s; /** Size and alignment of precomputed point tables. */ extern const size_t $(c_ns)_sizeof_precomputed_s DECAF_API_VIS, $(c_ns)_alignof_precomputed_s DECAF_API_VIS; -/** Scalar is stored packed, because we don't need the speed. */ +/** Representation of an element of the scalar field. */ typedef struct $(c_ns)_scalar_s { /** @cond internal */ decaf_word_t limb[$(C_NS)_SCALAR_LIMBS]; /** @endcond */ } $(c_ns)_scalar_t[1]; -/** A scalar equal to 1. */ +/** The scalar 1. */ extern const $(c_ns)_scalar_t $(c_ns)_scalar_one DECAF_API_VIS; -/** A scalar equal to 0. */ +/** The scalar 0. */ extern const $(c_ns)_scalar_t $(c_ns)_scalar_zero DECAF_API_VIS; -/** The identity point on the curve. */ +/** The identity (zero) point on the curve. */ extern const $(c_ns)_point_t $(c_ns)_point_identity DECAF_API_VIS; -/** An arbitrarily chosen base point on the curve. */ +/** An arbitrarily-chosen base point on the curve. */ extern const $(c_ns)_point_t $(c_ns)_point_base DECAF_API_VIS; -/** Precomputed table for the base point on the curve. */ +/** Precomputed table of multiples of the base point on the curve. */ extern const struct $(c_ns)_precomputed_s *$(c_ns)_precomputed_base DECAF_API_VIS; /** @@ -371,19 +371,19 @@ decaf_error_t $(c_ns)_direct_scalarmul ( ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; /** - * @brief RFC 7748 Diffie-Hellman scalarmul. This function uses a different - * (non-Decaf) encoding. + * @brief RFC 7748 Diffie-Hellman scalarmul, used to compute shared secrets. + * This function uses a different (non-Decaf) encoding. * - * @param [out] scaled The scaled point base*scalar - * @param [in] base The point to be scaled. - * @param [in] scalar The scalar to multiply by. + * @param [out] shared The shared secret base*scalar + * @param [in] base The other party's public key, used as the base of the scalarmul. + * @param [in] scalar The private scalar to multiply by. * * @retval DECAF_SUCCESS The scalarmul succeeded. * @retval DECAF_FAILURE The scalarmul didn't succeed, because the base * point is in a small subgroup. */ decaf_error_t decaf_x$(gf_shortname) ( - uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES], + uint8_t shared[DECAF_X$(gf_shortname)_PUBLIC_BYTES], const uint8_t base[DECAF_X$(gf_shortname)_PUBLIC_BYTES], const uint8_t scalar[DECAF_X$(gf_shortname)_PRIVATE_BYTES] ) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; @@ -414,7 +414,13 @@ void $(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname) ( ) DECAF_API_VIS DECAF_NONNULL; /** The base point for X$(gf_shortname) Diffie-Hellman */ -extern const uint8_t decaf_x$(gf_shortname)_base_point[DECAF_X$(gf_shortname)_PUBLIC_BYTES] DECAF_API_VIS; +extern const uint8_t + decaf_x$(gf_shortname)_base_point[DECAF_X$(gf_shortname)_PUBLIC_BYTES] +#ifndef DOXYGEN + /* For some reason Doxygen chokes on this despite the defense in common.h... */ + DECAF_API_VIS +#endif +; /** * @brief RFC 7748 Diffie-Hellman base point scalarmul. This function uses @@ -423,8 +429,8 @@ extern const uint8_t decaf_x$(gf_shortname)_base_point[DECAF_X$(gf_shortname)_PU * @deprecated Renamed to decaf_x$(gf_shortname)_derive_public_key. * I have no particular timeline for removing this name. * - * @param [out] scaled The scaled point base*scalar - * @param [in] scalar The scalar to multiply by. + * @param [out] out The public key base*scalar. + * @param [in] scalar The private scalar. */ void decaf_x$(gf_shortname)_generate_key ( uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES], @@ -438,8 +444,8 @@ void decaf_x$(gf_shortname)_generate_key ( * Does exactly the same thing as decaf_x$(gf_shortname)_generate_key, * but has a better name. * - * @param [out] scaled The scaled point base*scalar - * @param [in] scalar The scalar to multiply by. + * @param [out] out The public key base*scalar + * @param [in] scalar The private scalar. */ void decaf_x$(gf_shortname)_derive_public_key ( uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES], @@ -722,22 +728,20 @@ $(c_ns)_invert_elligator_uniform ( uint32_t which ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED; -/** - * @brief Overwrite scalar with zeros. - */ +/** Securely erase a scalar. */ void $(c_ns)_scalar_destroy ( $(c_ns)_scalar_t scalar ) DECAF_NONNULL DECAF_API_VIS; -/** - * @brief Overwrite point with zeros. +/** Securely erase a point by overwriting it with zeros. + * @warning This causes the point object to become invalid. */ void $(c_ns)_point_destroy ( $(c_ns)_point_t point ) DECAF_NONNULL DECAF_API_VIS; -/** - * @brief Overwrite precomputed table with zeros. +/** Securely erase a precomputed table by overwriting it with zeros. + * @warning This causes the table object to become invalid. */ void $(c_ns)_precomputed_destroy ( $(c_ns)_precomputed_s *pre diff --git a/src/per_curve/point.tmpl.hxx b/src/per_curve/point.tmpl.hxx index 5405871..d481777 100644 --- a/src/per_curve/point.tmpl.hxx +++ b/src/per_curve/point.tmpl.hxx @@ -1,16 +1,15 @@ /** - * A group of prime order p, C++ wrapper. + * A group of prime order, 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 + * group of prime order. 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. + * Most of the functions in this file run in constant time, can't fail + * except for ubiquitous reasons like memory exhaustion, and contain no + * data-dependend branches, timing or memory accesses. There are some + * exceptions, which should be noted. Typically, decoding functions can + * fail. */ /** This code uses posix_memalign. */ @@ -174,8 +173,9 @@ public: /** Negate */ inline Scalar operator- () const DECAF_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. */ + /** Return 1/this. + * @throw CryptoException if this is 0. + */ inline Scalar inverse() const /*throw(CryptoException)*/ { Scalar r; if (DECAF_SUCCESS != $(c_ns)_scalar_invert(r.s,s)) { @@ -191,10 +191,10 @@ public: return $(c_ns)_scalar_invert(r.s,s); } - /** Divide by inverting q. If q == 0, return 0. */ + /** Return this/q. @throw CryptoException if q == 0. */ inline Scalar operator/ (const Scalar &q) const /*throw(CryptoException)*/ { return *this * q.inverse(); } - /** Divide by inverting q. If q == 0, return 0. */ + /** Set this to this/q. @throw CryptoException if q == 0. */ inline Scalar &operator/=(const Scalar &q) /*throw(CryptoException)*/ { return *this *= q.inverse(); } /** Return half this scalar. Much faster than /2. */ @@ -212,7 +212,9 @@ public: /** Scalarmul-precomputed with scalar on left. */ inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } - /** Direct scalar multiplication. */ + /** Direct scalar multiplication. + * @throw CryptoException if the input didn't decode. + */ inline SecureBuffer direct_scalarmul ( const FixedBlock &in, decaf_bool_t allow_identity=DECAF_FALSE, @@ -228,12 +230,10 @@ public: ) const DECAF_NOEXCEPT; }; -/** - * Element of prime-order group. - */ +/** Element of prime-order elliptic curve group. */ class Point : public Serializable { public: - /** wrapped C type */ + /** Wrapped C type */ typedef $(c_ns)_point_t Wrapped; /** Size of a serialized element */ @@ -257,17 +257,8 @@ public: /** Ratio due to ladder decoding */ static const int LADDER_ENCODE_RATIO = DECAF_X$(gf_shortname)_ENCODE_RATIO; - /** - * Size of a stegged element. - * - * FUTURE: You can use HASH_BYTES * 3/2 (or more likely much less, eg HASH_BYTES + 8) - * with a random oracle hash function, by hash-expanding everything past the first - * HASH_BYTES of the element. However, since the internal C invert_elligator is not - * tied to a hash function, I didn't want to tie the C++ wrapper to a hash function - * either. But it might be a good idea to do this in the future, either with STROBE - * or something else. - * - * Then again, calling invert_elligator at all is super niche, so maybe who cares? + /** Size of a steganographically-encoded curve element. If the point is random, the encoding + * should look statistically close to a uniformly-random sequnece of STEG_BYTES bytes. */ static const size_t STEG_BYTES = HASH_BYTES * 2; @@ -312,9 +303,9 @@ public: * @throw CryptoException the string was the wrong length, or wasn't the encoding of a point, * or was the identity and allow_identity was DECAF_FALSE. */ - inline explicit Point(const FixedBlock &buffer, decaf_bool_t allow_identity=DECAF_TRUE) + inline explicit Point(const FixedBlock &buffer, bool allow_identity=true) /*throw(CryptoException)*/ { - if (DECAF_SUCCESS != decode(buffer,allow_identity)) { + if (DECAF_SUCCESS != decode(buffer,allow_identity ? DECAF_TRUE : DECAF_FALSE)) { throw CryptoException(); } } @@ -328,9 +319,9 @@ public: * or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined. */ inline decaf_error_t DECAF_WARN_UNUSED decode ( - const FixedBlock &buffer, decaf_bool_t allow_identity=DECAF_TRUE + const FixedBlock &buffer, bool allow_identity=true ) DECAF_NOEXCEPT { - return $(c_ns)_point_decode(p,buffer.data(),allow_identity); + return $(c_ns)_point_decode(p,buffer.data(),allow_identity ? DECAF_TRUE : DECAF_FALSE); } /** @@ -380,9 +371,7 @@ public: } /** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */ - inline void mul_by_ratio_and_encode_like_ladder( - FixedBuffer &out - ) const { + inline void mul_by_ratio_and_encode_like_ladder(FixedBuffer &out) const { $(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname)(out.data(),p); } @@ -418,9 +407,7 @@ public: } } - /** - * Encode to string. The identity encodes to the all-zero string. - */ + /** Encode to string. The identity encodes to the all-zero string. */ inline operator SecureBuffer() const { SecureBuffer buffer(SER_BYTES); $(c_ns)_point_encode(buffer.data(), p); @@ -570,10 +557,10 @@ public: return out; } - /** Return the base point */ + /** Return the base point of the curve. */ static inline const Point base() DECAF_NOEXCEPT { return Point($(c_ns)_point_base); } - /** Return the identity point */ + /** Return the identity point of the curve. */ static inline const Point identity() DECAF_NOEXCEPT { return Point($(c_ns)_point_identity); } }; @@ -671,6 +658,7 @@ public: /** @endcond */ }; +/** X-only Diffie-Hellman ladder functions */ struct DhLadder { public: /** Bytes in an X$(gf_shortname) public key. */ @@ -745,7 +733,8 @@ public: * equivalent to shared_secret(base_point(),scalar) but possibly faster. * @deprecated Renamed to derive_public_key_noexcept. */ - static inline void DECAF_DEPRECATED("Renamed to derive_public_key_noexcept") + static inline void + DECAF_DEPRECATED("Renamed to derive_public_key_noexcept") generate_key_noexcept ( FixedBuffer &out, const FixedBlock &scalar @@ -781,7 +770,7 @@ inline decaf_error_t $(cxx_ns)::Scalar::direct_scalarmul_noexcept ( } /** @endcond */ -$("typedef %s %s;\n" % (cxx_ns,altname) if altname else "") +$("/** Alternative name for %s, for backwards compatibility */\ntypedef %s %s;\n" % (cxx_ns,cxx_ns,altname) if altname else "") #undef DECAF_NOEXCEPT } /* namespace decaf */ diff --git a/src/public_include/decaf.tmpl.hxx b/src/public_include/decaf.tmpl.hxx index 21ea394..1d349ec 100644 --- a/src/public_include/decaf.tmpl.hxx +++ b/src/public_include/decaf.tmpl.hxx @@ -4,7 +4,9 @@ $("\n".join([ "#include " % g for g in sorted([c["bits"] for _,c in curve.items()]) ])) +/** Namespace for all C++ decaf objects. */ namespace decaf { + /** Given a template with a "run" function, run it for all curves */ template class Run> void run_for_all_curves() { $("\n".join([ diff --git a/src/public_include/decaf/common.h b/src/public_include/decaf/common.h index 64719ad..f891a0a 100644 --- a/src/public_include/decaf/common.h +++ b/src/public_include/decaf/common.h @@ -21,8 +21,9 @@ extern "C" { /* Goldilocks' build flags default to hidden and stripping executables. */ /** @cond internal */ -#if defined(DOXYGEN) && !defined(__attribute__) -#define __attribute__((x)) +#if DOXYGEN || defined(__attribute__) +#define __attribute__(x) +#define NOINLINE #endif #define DECAF_API_VIS __attribute__((visibility("default"))) #define DECAF_NOINLINE __attribute__((noinline)) diff --git a/src/public_include/decaf/eddsa.tmpl.hxx b/src/public_include/decaf/eddsa.tmpl.hxx index 5d772f9..a379313 100644 --- a/src/public_include/decaf/eddsa.tmpl.hxx +++ b/src/public_include/decaf/eddsa.tmpl.hxx @@ -2,7 +2,15 @@ * EdDSA crypto routines, metaheader. */ -namespace decaf { enum Prehashed { PURE, PREHASHED }; } +/** Namespace for all libdecaf C++ objects. */ +namespace decaf { + /** How signatures handle hashing. */ + enum Prehashed { + PURE, /**< Sign the message itself. This can't be done in one pass. */ + PREHASHED /**< Sign the hash of the message. */ + }; +} + $("\n".join([ "#include " % g for g in sorted([c["bits"] for _,c in curve.items()]) ])) diff --git a/src/public_include/decaf/sha512.h b/src/public_include/decaf/sha512.h index 3c8ec70..ab810b4 100644 --- a/src/public_include/decaf/sha512.h +++ b/src/public_include/decaf/sha512.h @@ -18,21 +18,39 @@ extern "C" { #endif - +/** Hash context for SHA-512 */ typedef struct decaf_sha512_ctx_s { + /** @cond internal */ uint64_t state[8]; uint8_t block[128]; uint64_t bytes_processed; + /* @endcond */ } decaf_sha512_ctx_s, decaf_sha512_ctx_t[1]; +/** Initialize a SHA-512 context. */ void decaf_sha512_init(decaf_sha512_ctx_t ctx) DECAF_NONNULL DECAF_API_VIS; -void decaf_sha512_update(decaf_sha512_ctx_t ctx, const uint8_t *message, size_t length) DECAF_NONNULL DECAF_API_VIS; -void decaf_sha512_final(decaf_sha512_ctx_t ctx, uint8_t *out, size_t length) DECAF_NONNULL DECAF_API_VIS; +/** Update context by hashing part of a message. */ +void decaf_sha512_update(decaf_sha512_ctx_t ctx, const uint8_t *message, size_t message_len) DECAF_NONNULL DECAF_API_VIS; + +/** Finalize context and write out hash. + * @param [inout] ctx The context. Will be destroyed and re-initialized on return. + * @param [out] output Place to store the output hash. + * @param [in] output_len Length in bytes of the output hash. Must between 0 and 64, inclusive. + */ +void decaf_sha512_final(decaf_sha512_ctx_t ctx, uint8_t *output, size_t output_len) DECAF_NONNULL DECAF_API_VIS; + +/** Securely destroy a SHA512 context. */ static inline void decaf_sha512_destroy(decaf_sha512_ctx_t ctx) { decaf_bzero(ctx,sizeof(*ctx)); } +/** Hash a message. + * @param [out] output Place to store the output hash. + * @param [in] output_len Length in bytes of the output hash. Must between 0 and 64, inclusive. + * @param [in] message A message to hash. + * @param [in] message_len Length in bytes of the input message. + */ static inline void decaf_sha512_hash( uint8_t *output, size_t output_len, diff --git a/src/public_include/decaf/sha512.hxx b/src/public_include/decaf/sha512.hxx index e63c051..32e86a3 100644 --- a/src/public_include/decaf/sha512.hxx +++ b/src/public_include/decaf/sha512.hxx @@ -31,9 +31,9 @@ protected: /** @cond internal */ /** The C-wrapper sponge state */ decaf_sha512_ctx_t wrapped; + /** @endcond */ public: - /** Number of bytes ouf output */ static const size_t OUTPUT_BYTES = 64; diff --git a/src/public_include/decaf/spongerng.hxx b/src/public_include/decaf/spongerng.hxx index 0f1e054..e299e13 100644 --- a/src/public_include/decaf/spongerng.hxx +++ b/src/public_include/decaf/spongerng.hxx @@ -1,7 +1,5 @@ - - /** - * @file decaf/strobe.hxx + * @file decaf/spongerng.hxx * @copyright * Based on CC0 code by David Leon Gil, 2015 \n * Copyright (c) 2015 Cryptography Research, Inc. \n