Browse Source

make doc now mostly works

master
Michael Hamburg 7 years ago
parent
commit
c227424384
28 changed files with 460 additions and 376 deletions
  1. +2
    -2
      Doxyfile
  2. +4
    -2
      Makefile
  3. +0
    -6
      src/GENERATED/c/curve25519/eddsa.c
  4. +0
    -6
      src/GENERATED/c/ed448goldilocks/eddsa.c
  5. +2
    -0
      src/GENERATED/include/decaf.hxx
  6. +3
    -2
      src/GENERATED/include/decaf/common.h
  7. +8
    -1
      src/GENERATED/include/decaf/ed255.h
  8. +58
    -45
      src/GENERATED/include/decaf/ed255.hxx
  9. +8
    -1
      src/GENERATED/include/decaf/ed448.h
  10. +58
    -45
      src/GENERATED/include/decaf/ed448.hxx
  11. +9
    -1
      src/GENERATED/include/decaf/eddsa.hxx
  12. +30
    -26
      src/GENERATED/include/decaf/point_255.h
  13. +31
    -41
      src/GENERATED/include/decaf/point_255.hxx
  14. +30
    -26
      src/GENERATED/include/decaf/point_448.h
  15. +30
    -41
      src/GENERATED/include/decaf/point_448.hxx
  16. +21
    -3
      src/GENERATED/include/decaf/sha512.h
  17. +1
    -1
      src/GENERATED/include/decaf/sha512.hxx
  18. +1
    -3
      src/GENERATED/include/decaf/spongerng.hxx
  19. +8
    -1
      src/per_curve/eddsa.tmpl.h
  20. +58
    -45
      src/per_curve/eddsa.tmpl.hxx
  21. +30
    -26
      src/per_curve/point.tmpl.h
  22. +31
    -42
      src/per_curve/point.tmpl.hxx
  23. +2
    -0
      src/public_include/decaf.tmpl.hxx
  24. +3
    -2
      src/public_include/decaf/common.h
  25. +9
    -1
      src/public_include/decaf/eddsa.tmpl.hxx
  26. +21
    -3
      src/public_include/decaf/sha512.h
  27. +1
    -1
      src/public_include/decaf/sha512.hxx
  28. +1
    -3
      src/public_include/decaf/spongerng.hxx

+ 2
- 2
Doxyfile View File

@@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places. # title of most generated pages and in a few other places.
# The default value is: My Project. # 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 # 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 # could be handy for archiving the generated documentation or if some version
@@ -751,7 +751,7 @@ WARN_LOGFILE =
# spaces. # spaces.
# Note: If this tag is empty the current directory is searched. # 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 # 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 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses


+ 4
- 2
Makefile View File

@@ -17,6 +17,8 @@ BUILD_INC = src/GENERATED/include
BUILD_BIN = build/bin BUILD_BIN = build/bin
BUILD_IBIN = build/obj/bin BUILD_IBIN = build/obj/bin


DOXYGEN ?= doxygen

ifeq ($(UNAME),Darwin) ifeq ($(UNAME),Darwin)
CC = clang CC = clang
CXX = clang++ CXX = clang++
@@ -300,8 +302,8 @@ $(BUILD_DOC)/timestamp:
mkdir -p `dirname $@` mkdir -p `dirname $@`
touch $@ 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_static: $(GEN_CODE)
gen_code: gen_code_static $(GEN_CODE_P2) gen_code: gen_code_static $(GEN_CODE_P2)


+ 0
- 6
src/GENERATED/c/curve25519/eddsa.c View File

@@ -38,12 +38,6 @@ const uint8_t NO_CONTEXT_POINTS_HERE = 0;
const uint8_t * const DECAF_ED25519_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE; const uint8_t * const DECAF_ED25519_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
#endif #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 ( static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES] uint8_t secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES]
) { ) {


+ 0
- 6
src/GENERATED/c/ed448goldilocks/eddsa.c View File

@@ -38,12 +38,6 @@ const uint8_t NO_CONTEXT_POINTS_HERE = 0;
const uint8_t * const DECAF_ED448_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE; const uint8_t * const DECAF_ED448_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
#endif #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 ( static void clamp (
uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES] uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES]
) { ) {


+ 2
- 0
src/GENERATED/include/decaf.hxx View File

@@ -18,7 +18,9 @@
#include <decaf/point_255.hxx> #include <decaf/point_255.hxx>
#include <decaf/point_448.hxx> #include <decaf/point_448.hxx>


/** Namespace for all C++ decaf objects. */
namespace decaf { namespace decaf {
/** Given a template with a "run" function, run it for all curves */
template <template<typename Group> class Run> template <template<typename Group> class Run>
void run_for_all_curves() { void run_for_all_curves() {
Run<Ristretto>::run(); Run<Ristretto>::run();


+ 3
- 2
src/GENERATED/include/decaf/common.h View File

@@ -21,8 +21,9 @@ extern "C" {


/* Goldilocks' build flags default to hidden and stripping executables. */ /* Goldilocks' build flags default to hidden and stripping executables. */
/** @cond internal */ /** @cond internal */
#if defined(DOXYGEN) && !defined(__attribute__)
#define __attribute__((x))
#if DOXYGEN || defined(__attribute__)
#define __attribute__(x)
#define NOINLINE
#endif #endif
#define DECAF_API_VIS __attribute__((visibility("default"))) #define DECAF_API_VIS __attribute__((visibility("default")))
#define DECAF_NOINLINE __attribute__((noinline)) #define DECAF_NOINLINE __attribute__((noinline))


+ 8
- 1
src/GENERATED/include/decaf/ed255.h View File

@@ -36,10 +36,17 @@ extern "C" {
#define DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS 1 #define DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS 1
extern const uint8_t * const DECAF_ED25519_NO_CONTEXT DECAF_API_VIS; 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 #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 #define decaf_ed25519_prehash_ctx_t decaf_sha512_ctx_t
/** Prehash update. */
#define decaf_ed25519_prehash_update decaf_sha512_update #define decaf_ed25519_prehash_update decaf_sha512_update
/** Prehash destroy. */
#define decaf_ed25519_prehash_destroy decaf_sha512_destroy #define decaf_ed25519_prehash_destroy decaf_sha512_destroy


/** EdDSA encoding ratio. */ /** EdDSA encoding ratio. */


+ 58
- 45
src/GENERATED/include/decaf/ed255.hxx View File

@@ -14,7 +14,6 @@


#ifndef __DECAF_ED255_HXX__ #ifndef __DECAF_ED255_HXX__
#define __DECAF_ED255_HXX__ 1 #define __DECAF_ED255_HXX__ 1

/* /*
* Example Decaf cyrpto routines, C++ wrapper. * Example Decaf cyrpto routines, C++ wrapper.
* @warning These are merely examples, though they ought to be secure. But real * @warning These are merely examples, though they ought to be secure. But real
@@ -38,6 +37,7 @@
#endif #endif
/** @endcond */ /** @endcond */


/** Namespace for all libdecaf C++ objects. */
namespace decaf { namespace decaf {


/** A public key for crypto over some Group */ /** A public key for crypto over some Group */
@@ -55,7 +55,14 @@ typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh;
typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh; typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh;
/** @endcond */ /** @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 #if DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS
static inline const Block NO_CONTEXT() { return Block(DECAF_ED25519_NO_CONTEXT,0); } static inline const Block NO_CONTEXT() { return Block(DECAF_ED25519_NO_CONTEXT,0); }
#else #else
@@ -65,6 +72,7 @@ static inline const Block NO_CONTEXT() { return Block(NULL,0); }
/** Prehash context for EdDSA. */ /** Prehash context for EdDSA. */
class Prehash : public SHA512 { class Prehash : public SHA512 {
private: private:
/** @cond internal */
typedef SHA512 Super; typedef SHA512 Super;
SecureBuffer context_; SecureBuffer context_;
template<class T, Prehashed Ph> friend class Signing; template<class T, Prehashed Ph> friend class Signing;
@@ -79,6 +87,7 @@ private:


decaf_ed25519_prehash_init((decaf_sha512_ctx_s *)wrapped); decaf_ed25519_prehash_init((decaf_sha512_ctx_s *)wrapped);
} }
/** @endcond */
public: public:
/** Number of output bytes in prehash */ /** Number of output bytes in prehash */
@@ -108,35 +117,10 @@ public:
} }
}; };


/** Signing (i.e. private) key class template */
template<class CRTP, Prehashed ph> class Signing; template<class CRTP, Prehashed ph> class Signing;


template<class CRTP> class Signing<CRTP,PREHASHED> {
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 CRTP> class Signing<CRTP,PURE> { template<class CRTP> class Signing<CRTP,PURE> {
public: public:
/** /**
@@ -169,12 +153,42 @@ public:
} }
}; };


/** Signing (i.e. private) key class, prehashed version */
template<class CRTP> class Signing<CRTP,PREHASHED> {
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 class PrivateKeyBase
: public Serializable<PrivateKeyBase> : public Serializable<PrivateKeyBase>
, public Signing<PrivateKeyBase,PURE> , public Signing<PrivateKeyBase,PURE>
, public Signing<PrivateKeyBase,PREHASHED> { , public Signing<PrivateKeyBase,PREHASHED> {
public: public:
typedef class PublicKeyBase MyPublicKey;
/** Type of public key corresponding to this private key */
typedef class PublicKeyBase PublicKey;
private: private:
/** @cond internal */ /** @cond internal */
friend class PublicKeyBase; friend class PublicKeyBase;
@@ -243,14 +257,13 @@ public:
} }
/** Return the corresponding public key */ /** 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; return pub;
} }
}; /* class PrivateKey */ }; /* class PrivateKey */




/** Verification (i.e. public) EdDSA key, PureEdDSA version. */
template<class CRTP> class Verification<CRTP,PURE> { template<class CRTP> class Verification<CRTP,PURE> {
public: public:
/** Verify a signature, returning DECAF_FAILURE if verification fails */ /** Verify a signature, returning DECAF_FAILURE if verification fails */
@@ -296,10 +309,10 @@ public:
} }
}; };


/** Verification (i.e. public) EdDSA key, prehashed version. */
template<class CRTP> class Verification<CRTP,PREHASHED> { template<class CRTP> class Verification<CRTP,PREHASHED> {
public: 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 ( inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept (
const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
const Prehash &ph const Prehash &ph
@@ -312,8 +325,8 @@ public:
ph.context_.size() 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 ( inline void verify_prehashed (
const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
const Prehash &ph 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 ( inline void verify_with_prehash (
const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
const Block &message, const Block &message,
@@ -341,24 +354,25 @@ public:
} }
}; };


/** EdDSA Public key base class. */
class PublicKeyBase class PublicKeyBase
: public Serializable<PublicKeyBase> : public Serializable<PublicKeyBase>
, public Verification<PublicKeyBase,PURE> , public Verification<PublicKeyBase,PURE>
, public Verification<PublicKeyBase,PREHASHED> { , public Verification<PublicKeyBase,PREHASHED> {
public: public:
typedef class PrivateKeyBase MyPrivateKey;
/** Private key corresponding to this type of public key */
typedef class PrivateKeyBase PrivateKey;
private: private:
/** @cond internal */ /** @cond internal */
friend class PrivateKeyBase; friend class PrivateKeyBase;
friend class Verification<PublicKey,PURE>; friend class Verification<PublicKey,PURE>;
friend class Verification<PublicKey,PREHASHED>; friend class Verification<PublicKey,PREHASHED>;
/** @endcond */


private: private:
/** The pre-expansion form of the signature */ /** The pre-expansion form of the signature */
FixedArrayBuffer<DECAF_EDDSA_25519_PUBLIC_BYTES> pub_; FixedArrayBuffer<DECAF_EDDSA_25519_PUBLIC_BYTES> pub_;
/** @endcond */
public: public:
/* PERF FUTURE: Pre-cached decoding? Precomputed table?? */ /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
@@ -372,7 +386,6 @@ public:
/** Serialization size. */ /** Serialization size. */
static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES; static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES;
/** Create but don't initialize */ /** Create but don't initialize */
inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { } inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { }
@@ -383,7 +396,7 @@ public:
inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; } inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; }
/** Copy constructor */ /** 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 */ /** Assignment from string */
inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
@@ -397,7 +410,7 @@ public:
} }


/** Assignment from private key */ /** Assignment from private key */
inline PublicKey &operator=(const MyPrivateKey &p) DECAF_NOEXCEPT {
inline PublicKey &operator=(const PrivateKey &p) DECAF_NOEXCEPT {
return *this = p.pub_; return *this = p.pub_;
} }




+ 8
- 1
src/GENERATED/include/decaf/ed448.h View File

@@ -35,10 +35,17 @@ extern "C" {
/** Does EdDSA support non-contextual signatures? */ /** Does EdDSA support non-contextual signatures? */
#define DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS 0 #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 #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 #define decaf_ed448_prehash_ctx_t decaf_shake256_ctx_t
/** Prehash update. */
#define decaf_ed448_prehash_update decaf_shake256_update #define decaf_ed448_prehash_update decaf_shake256_update
/** Prehash destroy. */
#define decaf_ed448_prehash_destroy decaf_shake256_destroy #define decaf_ed448_prehash_destroy decaf_shake256_destroy


/** EdDSA encoding ratio. */ /** EdDSA encoding ratio. */


+ 58
- 45
src/GENERATED/include/decaf/ed448.hxx View File

@@ -14,7 +14,6 @@


#ifndef __DECAF_ED448_HXX__ #ifndef __DECAF_ED448_HXX__
#define __DECAF_ED448_HXX__ 1 #define __DECAF_ED448_HXX__ 1

/* /*
* Example Decaf cyrpto routines, C++ wrapper. * Example Decaf cyrpto routines, C++ wrapper.
* @warning These are merely examples, though they ought to be secure. But real * @warning These are merely examples, though they ought to be secure. But real
@@ -38,6 +37,7 @@
#endif #endif
/** @endcond */ /** @endcond */


/** Namespace for all libdecaf C++ objects. */
namespace decaf { namespace decaf {


/** A public key for crypto over some Group */ /** A public key for crypto over some Group */
@@ -55,7 +55,14 @@ typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh;
typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh; typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh;
/** @endcond */ /** @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 #if DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS
static inline const Block NO_CONTEXT() { return Block(DECAF_ED448_NO_CONTEXT,0); } static inline const Block NO_CONTEXT() { return Block(DECAF_ED448_NO_CONTEXT,0); }
#else #else
@@ -65,6 +72,7 @@ static inline const Block NO_CONTEXT() { return Block(NULL,0); }
/** Prehash context for EdDSA. */ /** Prehash context for EdDSA. */
class Prehash : public SHAKE<256> { class Prehash : public SHAKE<256> {
private: private:
/** @cond internal */
typedef SHAKE<256> Super; typedef SHAKE<256> Super;
SecureBuffer context_; SecureBuffer context_;
template<class T, Prehashed Ph> friend class Signing; template<class T, Prehashed Ph> friend class Signing;
@@ -79,6 +87,7 @@ private:


decaf_ed448_prehash_init((decaf_shake256_ctx_s *)wrapped); decaf_ed448_prehash_init((decaf_shake256_ctx_s *)wrapped);
} }
/** @endcond */
public: public:
/** Number of output bytes in prehash */ /** Number of output bytes in prehash */
@@ -108,35 +117,10 @@ public:
} }
}; };


/** Signing (i.e. private) key class template */
template<class CRTP, Prehashed ph> class Signing; template<class CRTP, Prehashed ph> class Signing;


template<class CRTP> class Signing<CRTP,PREHASHED> {
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 CRTP> class Signing<CRTP,PURE> { template<class CRTP> class Signing<CRTP,PURE> {
public: public:
/** /**
@@ -169,12 +153,42 @@ public:
} }
}; };


/** Signing (i.e. private) key class, prehashed version */
template<class CRTP> class Signing<CRTP,PREHASHED> {
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 class PrivateKeyBase
: public Serializable<PrivateKeyBase> : public Serializable<PrivateKeyBase>
, public Signing<PrivateKeyBase,PURE> , public Signing<PrivateKeyBase,PURE>
, public Signing<PrivateKeyBase,PREHASHED> { , public Signing<PrivateKeyBase,PREHASHED> {
public: public:
typedef class PublicKeyBase MyPublicKey;
/** Type of public key corresponding to this private key */
typedef class PublicKeyBase PublicKey;
private: private:
/** @cond internal */ /** @cond internal */
friend class PublicKeyBase; friend class PublicKeyBase;
@@ -243,14 +257,13 @@ public:
} }
/** Return the corresponding public key */ /** 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; return pub;
} }
}; /* class PrivateKey */ }; /* class PrivateKey */




/** Verification (i.e. public) EdDSA key, PureEdDSA version. */
template<class CRTP> class Verification<CRTP,PURE> { template<class CRTP> class Verification<CRTP,PURE> {
public: public:
/** Verify a signature, returning DECAF_FAILURE if verification fails */ /** Verify a signature, returning DECAF_FAILURE if verification fails */
@@ -296,10 +309,10 @@ public:
} }
}; };


/** Verification (i.e. public) EdDSA key, prehashed version. */
template<class CRTP> class Verification<CRTP,PREHASHED> { template<class CRTP> class Verification<CRTP,PREHASHED> {
public: 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 ( inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept (
const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig,
const Prehash &ph const Prehash &ph
@@ -312,8 +325,8 @@ public:
ph.context_.size() 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 ( inline void verify_prehashed (
const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig,
const Prehash &ph 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 ( inline void verify_with_prehash (
const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_448_SIGNATURE_BYTES> &sig,
const Block &message, const Block &message,
@@ -341,24 +354,25 @@ public:
} }
}; };


/** EdDSA Public key base class. */
class PublicKeyBase class PublicKeyBase
: public Serializable<PublicKeyBase> : public Serializable<PublicKeyBase>
, public Verification<PublicKeyBase,PURE> , public Verification<PublicKeyBase,PURE>
, public Verification<PublicKeyBase,PREHASHED> { , public Verification<PublicKeyBase,PREHASHED> {
public: public:
typedef class PrivateKeyBase MyPrivateKey;
/** Private key corresponding to this type of public key */
typedef class PrivateKeyBase PrivateKey;
private: private:
/** @cond internal */ /** @cond internal */
friend class PrivateKeyBase; friend class PrivateKeyBase;
friend class Verification<PublicKey,PURE>; friend class Verification<PublicKey,PURE>;
friend class Verification<PublicKey,PREHASHED>; friend class Verification<PublicKey,PREHASHED>;
/** @endcond */


private: private:
/** The pre-expansion form of the signature */ /** The pre-expansion form of the signature */
FixedArrayBuffer<DECAF_EDDSA_448_PUBLIC_BYTES> pub_; FixedArrayBuffer<DECAF_EDDSA_448_PUBLIC_BYTES> pub_;
/** @endcond */
public: public:
/* PERF FUTURE: Pre-cached decoding? Precomputed table?? */ /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
@@ -372,7 +386,6 @@ public:
/** Serialization size. */ /** Serialization size. */
static const size_t SER_BYTES = DECAF_EDDSA_448_PRIVATE_BYTES; static const size_t SER_BYTES = DECAF_EDDSA_448_PRIVATE_BYTES;
/** Create but don't initialize */ /** Create but don't initialize */
inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { } inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { }
@@ -383,7 +396,7 @@ public:
inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; } inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; }
/** Copy constructor */ /** 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 */ /** Assignment from string */
inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
@@ -397,7 +410,7 @@ public:
} }


/** Assignment from private key */ /** Assignment from private key */
inline PublicKey &operator=(const MyPrivateKey &p) DECAF_NOEXCEPT {
inline PublicKey &operator=(const PrivateKey &p) DECAF_NOEXCEPT {
return *this = p.pub_; return *this = p.pub_;
} }




+ 9
- 1
src/GENERATED/include/decaf/eddsa.hxx View File

@@ -15,7 +15,15 @@
#ifndef __DECAF_EDDSA_HXX__ #ifndef __DECAF_EDDSA_HXX__
#define __DECAF_EDDSA_HXX__ 1 #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 <decaf/ed255.hxx> #include <decaf/ed255.hxx>
#include <decaf/ed448.hxx> #include <decaf/ed448.hxx>




+ 30
- 26
src/GENERATED/include/decaf/point_255.h View File

@@ -64,10 +64,10 @@ typedef struct gf_25519_s {
/** Number of bytes in an x25519 private key */ /** Number of bytes in an x25519 private key */
#define DECAF_X25519_PRIVATE_BYTES 32 #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 { typedef struct decaf_255_point_s {
/** @cond internal */ /** @cond internal */
gf_25519_t x,y,z,t;
gf_25519_t x,y,z,t; /* Twisted extended homogeneous coordinates */
/** @endcond */ /** @endcond */
} decaf_255_point_t[1]; } 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. */ /** 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; 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 { typedef struct decaf_255_scalar_s {
/** @cond internal */ /** @cond internal */
decaf_word_t limb[DECAF_255_SCALAR_LIMBS]; decaf_word_t limb[DECAF_255_SCALAR_LIMBS];
/** @endcond */ /** @endcond */
} decaf_255_scalar_t[1]; } 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; 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; 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; 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; 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; 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; ) 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_SUCCESS The scalarmul succeeded.
* @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 decaf_x25519 ( 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 base[DECAF_X25519_PUBLIC_BYTES],
const uint8_t scalar[DECAF_X25519_PRIVATE_BYTES] const uint8_t scalar[DECAF_X25519_PRIVATE_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; ) 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; ) DECAF_API_VIS DECAF_NONNULL;


/** The base point for X25519 Diffie-Hellman */ /** 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 * @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. * @deprecated Renamed to decaf_x25519_derive_public_key.
* I have no particular timeline for removing this name. * 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 ( void decaf_x25519_generate_key (
uint8_t out[DECAF_X25519_PUBLIC_BYTES], 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, * Does exactly the same thing as decaf_x25519_generate_key,
* but has a better name. * 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 ( void decaf_x25519_derive_public_key (
uint8_t out[DECAF_X25519_PUBLIC_BYTES], uint8_t out[DECAF_X25519_PUBLIC_BYTES],
@@ -737,22 +743,20 @@ decaf_255_invert_elligator_uniform (
uint32_t which uint32_t which
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED; ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED;


/**
* @brief Overwrite scalar with zeros.
*/
/** Securely erase a scalar. */
void decaf_255_scalar_destroy ( void decaf_255_scalar_destroy (
decaf_255_scalar_t scalar decaf_255_scalar_t scalar
) DECAF_NONNULL DECAF_API_VIS; ) 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 ( void decaf_255_point_destroy (
decaf_255_point_t point decaf_255_point_t point
) DECAF_NONNULL DECAF_API_VIS; ) 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 ( void decaf_255_precomputed_destroy (
decaf_255_precomputed_s *pre decaf_255_precomputed_s *pre


+ 31
- 41
src/GENERATED/include/decaf/point_255.hxx View File

@@ -6,18 +6,17 @@
* Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Copyright (c) 2015-2016 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information. * 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 * 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. * 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. * @warning This file was automatically generated in Python.
* Please do not edit it. * Please do not edit it.
@@ -187,8 +186,9 @@ public:
/** Negate */ /** Negate */
inline Scalar operator- () const DECAF_NOEXCEPT { Scalar r((NOINIT())); decaf_255_scalar_sub(r.s,decaf_255_scalar_zero,s); return r; } 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)*/ { inline Scalar inverse() const /*throw(CryptoException)*/ {
Scalar r; Scalar r;
if (DECAF_SUCCESS != decaf_255_scalar_invert(r.s,s)) { if (DECAF_SUCCESS != decaf_255_scalar_invert(r.s,s)) {
@@ -204,10 +204,10 @@ public:
return decaf_255_scalar_invert(r.s,s); 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(); } 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(); } inline Scalar &operator/=(const Scalar &q) /*throw(CryptoException)*/ { return *this *= q.inverse(); }


/** Return half this scalar. Much faster than /2. */ /** Return half this scalar. Much faster than /2. */
@@ -225,7 +225,9 @@ public:
/** Scalarmul-precomputed with scalar on left. */ /** Scalarmul-precomputed with scalar on left. */
inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } 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 ( inline SecureBuffer direct_scalarmul (
const FixedBlock<SER_BYTES> &in, const FixedBlock<SER_BYTES> &in,
decaf_bool_t allow_identity=DECAF_FALSE, decaf_bool_t allow_identity=DECAF_FALSE,
@@ -241,12 +243,10 @@ public:
) const DECAF_NOEXCEPT; ) const DECAF_NOEXCEPT;
}; };


/**
* Element of prime-order group.
*/
/** Element of prime-order elliptic curve group. */
class Point : public Serializable<Point> { class Point : public Serializable<Point> {
public: public:
/** wrapped C type */
/** Wrapped C type */
typedef decaf_255_point_t Wrapped; typedef decaf_255_point_t Wrapped;
/** Size of a serialized element */ /** Size of a serialized element */
@@ -270,17 +270,8 @@ public:
/** Ratio due to ladder decoding */ /** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X25519_ENCODE_RATIO; 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; 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, * @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. * or was the identity and allow_identity was DECAF_FALSE.
*/ */
inline explicit Point(const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE)
inline explicit Point(const FixedBlock<SER_BYTES> &buffer, bool allow_identity=true)
/*throw(CryptoException)*/ { /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode(buffer,allow_identity)) {
if (DECAF_SUCCESS != decode(buffer,allow_identity ? DECAF_TRUE : DECAF_FALSE)) {
throw CryptoException(); throw CryptoException();
} }
} }
@@ -341,9 +332,9 @@ public:
* or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined. * or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined.
*/ */
inline decaf_error_t DECAF_WARN_UNUSED decode ( inline decaf_error_t DECAF_WARN_UNUSED decode (
const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE
const FixedBlock<SER_BYTES> &buffer, bool allow_identity=true
) DECAF_NOEXCEPT { ) 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. */ /** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
inline void mul_by_ratio_and_encode_like_ladder(FixedBuffer<LADDER_BYTES> &out) const {
decaf_255_point_mul_by_ratio_and_encode_like_x25519(out.data(),p); 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 { inline operator SecureBuffer() const {
SecureBuffer buffer(SER_BYTES); SecureBuffer buffer(SER_BYTES);
decaf_255_point_encode(buffer.data(), p); decaf_255_point_encode(buffer.data(), p);
@@ -583,10 +570,10 @@ public:
return out; 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); } 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); } static inline const Point identity() DECAF_NOEXCEPT { return Point(decaf_255_point_identity); }
}; };


@@ -684,6 +671,7 @@ public:
/** @endcond */ /** @endcond */
}; };


/** X-only Diffie-Hellman ladder functions */
struct DhLadder { struct DhLadder {
public: public:
/** Bytes in an X25519 public key. */ /** Bytes in an X25519 public key. */
@@ -758,7 +746,8 @@ public:
* equivalent to shared_secret(base_point(),scalar) but possibly faster. * equivalent to shared_secret(base_point(),scalar) but possibly faster.
* @deprecated Renamed to derive_public_key_noexcept. * @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 ( generate_key_noexcept (
FixedBuffer<PUBLIC_BYTES> &out, FixedBuffer<PUBLIC_BYTES> &out,
const FixedBlock<PRIVATE_BYTES> &scalar const FixedBlock<PRIVATE_BYTES> &scalar
@@ -794,6 +783,7 @@ inline decaf_error_t Ristretto::Scalar::direct_scalarmul_noexcept (
} }
/** @endcond */ /** @endcond */


/** Alternative name for Ristretto, for backwards compatibility */
typedef Ristretto IsoEd25519; typedef Ristretto IsoEd25519;






+ 30
- 26
src/GENERATED/include/decaf/point_448.h View File

@@ -64,10 +64,10 @@ typedef struct gf_448_s {
/** Number of bytes in an x448 private key */ /** Number of bytes in an x448 private key */
#define DECAF_X448_PRIVATE_BYTES 56 #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 { typedef struct decaf_448_point_s {
/** @cond internal */ /** @cond internal */
gf_448_t x,y,z,t;
gf_448_t x,y,z,t; /* Twisted extended homogeneous coordinates */
/** @endcond */ /** @endcond */
} decaf_448_point_t[1]; } 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. */ /** 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; 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 { typedef struct decaf_448_scalar_s {
/** @cond internal */ /** @cond internal */
decaf_word_t limb[DECAF_448_SCALAR_LIMBS]; decaf_word_t limb[DECAF_448_SCALAR_LIMBS];
/** @endcond */ /** @endcond */
} decaf_448_scalar_t[1]; } 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; 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; 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; 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; 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; 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; ) 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_SUCCESS The scalarmul succeeded.
* @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 decaf_x448 ( 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 base[DECAF_X448_PUBLIC_BYTES],
const uint8_t scalar[DECAF_X448_PRIVATE_BYTES] const uint8_t scalar[DECAF_X448_PRIVATE_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; ) 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; ) DECAF_API_VIS DECAF_NONNULL;


/** The base point for X448 Diffie-Hellman */ /** 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 * @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. * @deprecated Renamed to decaf_x448_derive_public_key.
* I have no particular timeline for removing this name. * 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 ( void decaf_x448_generate_key (
uint8_t out[DECAF_X448_PUBLIC_BYTES], 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, * Does exactly the same thing as decaf_x448_generate_key,
* but has a better name. * 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 ( void decaf_x448_derive_public_key (
uint8_t out[DECAF_X448_PUBLIC_BYTES], uint8_t out[DECAF_X448_PUBLIC_BYTES],
@@ -737,22 +743,20 @@ decaf_448_invert_elligator_uniform (
uint32_t which uint32_t which
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED; ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED;


/**
* @brief Overwrite scalar with zeros.
*/
/** Securely erase a scalar. */
void decaf_448_scalar_destroy ( void decaf_448_scalar_destroy (
decaf_448_scalar_t scalar decaf_448_scalar_t scalar
) DECAF_NONNULL DECAF_API_VIS; ) 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 ( void decaf_448_point_destroy (
decaf_448_point_t point decaf_448_point_t point
) DECAF_NONNULL DECAF_API_VIS; ) 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 ( void decaf_448_precomputed_destroy (
decaf_448_precomputed_s *pre decaf_448_precomputed_s *pre


+ 30
- 41
src/GENERATED/include/decaf/point_448.hxx View File

@@ -6,18 +6,17 @@
* Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Copyright (c) 2015-2016 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information. * 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 * 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. * 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. * @warning This file was automatically generated in Python.
* Please do not edit it. * Please do not edit it.
@@ -187,8 +186,9 @@ public:
/** Negate */ /** Negate */
inline Scalar operator- () const DECAF_NOEXCEPT { Scalar r((NOINIT())); decaf_448_scalar_sub(r.s,decaf_448_scalar_zero,s); return r; } 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)*/ { inline Scalar inverse() const /*throw(CryptoException)*/ {
Scalar r; Scalar r;
if (DECAF_SUCCESS != decaf_448_scalar_invert(r.s,s)) { if (DECAF_SUCCESS != decaf_448_scalar_invert(r.s,s)) {
@@ -204,10 +204,10 @@ public:
return decaf_448_scalar_invert(r.s,s); 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(); } 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(); } inline Scalar &operator/=(const Scalar &q) /*throw(CryptoException)*/ { return *this *= q.inverse(); }


/** Return half this scalar. Much faster than /2. */ /** Return half this scalar. Much faster than /2. */
@@ -225,7 +225,9 @@ public:
/** Scalarmul-precomputed with scalar on left. */ /** Scalarmul-precomputed with scalar on left. */
inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } 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 ( inline SecureBuffer direct_scalarmul (
const FixedBlock<SER_BYTES> &in, const FixedBlock<SER_BYTES> &in,
decaf_bool_t allow_identity=DECAF_FALSE, decaf_bool_t allow_identity=DECAF_FALSE,
@@ -241,12 +243,10 @@ public:
) const DECAF_NOEXCEPT; ) const DECAF_NOEXCEPT;
}; };


/**
* Element of prime-order group.
*/
/** Element of prime-order elliptic curve group. */
class Point : public Serializable<Point> { class Point : public Serializable<Point> {
public: public:
/** wrapped C type */
/** Wrapped C type */
typedef decaf_448_point_t Wrapped; typedef decaf_448_point_t Wrapped;
/** Size of a serialized element */ /** Size of a serialized element */
@@ -270,17 +270,8 @@ public:
/** Ratio due to ladder decoding */ /** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X448_ENCODE_RATIO; 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; 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, * @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. * or was the identity and allow_identity was DECAF_FALSE.
*/ */
inline explicit Point(const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE)
inline explicit Point(const FixedBlock<SER_BYTES> &buffer, bool allow_identity=true)
/*throw(CryptoException)*/ { /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode(buffer,allow_identity)) {
if (DECAF_SUCCESS != decode(buffer,allow_identity ? DECAF_TRUE : DECAF_FALSE)) {
throw CryptoException(); throw CryptoException();
} }
} }
@@ -341,9 +332,9 @@ public:
* or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined. * or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined.
*/ */
inline decaf_error_t DECAF_WARN_UNUSED decode ( inline decaf_error_t DECAF_WARN_UNUSED decode (
const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE
const FixedBlock<SER_BYTES> &buffer, bool allow_identity=true
) DECAF_NOEXCEPT { ) 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. */ /** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
inline void mul_by_ratio_and_encode_like_ladder(FixedBuffer<LADDER_BYTES> &out) const {
decaf_448_point_mul_by_ratio_and_encode_like_x448(out.data(),p); 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 { inline operator SecureBuffer() const {
SecureBuffer buffer(SER_BYTES); SecureBuffer buffer(SER_BYTES);
decaf_448_point_encode(buffer.data(), p); decaf_448_point_encode(buffer.data(), p);
@@ -583,10 +570,10 @@ public:
return out; 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); } 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); } static inline const Point identity() DECAF_NOEXCEPT { return Point(decaf_448_point_identity); }
}; };


@@ -684,6 +671,7 @@ public:
/** @endcond */ /** @endcond */
}; };


/** X-only Diffie-Hellman ladder functions */
struct DhLadder { struct DhLadder {
public: public:
/** Bytes in an X448 public key. */ /** Bytes in an X448 public key. */
@@ -758,7 +746,8 @@ public:
* equivalent to shared_secret(base_point(),scalar) but possibly faster. * equivalent to shared_secret(base_point(),scalar) but possibly faster.
* @deprecated Renamed to derive_public_key_noexcept. * @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 ( generate_key_noexcept (
FixedBuffer<PUBLIC_BYTES> &out, FixedBuffer<PUBLIC_BYTES> &out,
const FixedBlock<PRIVATE_BYTES> &scalar const FixedBlock<PRIVATE_BYTES> &scalar


+ 21
- 3
src/GENERATED/include/decaf/sha512.h View File

@@ -18,21 +18,39 @@
extern "C" { extern "C" {
#endif #endif
/** Hash context for SHA-512 */
typedef struct decaf_sha512_ctx_s { typedef struct decaf_sha512_ctx_s {
/** @cond internal */
uint64_t state[8]; uint64_t state[8];
uint8_t block[128]; uint8_t block[128];
uint64_t bytes_processed; uint64_t bytes_processed;
/* @endcond */
} decaf_sha512_ctx_s, decaf_sha512_ctx_t[1]; } 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_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) { static inline void decaf_sha512_destroy(decaf_sha512_ctx_t ctx) {
decaf_bzero(ctx,sizeof(*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( static inline void decaf_sha512_hash(
uint8_t *output, uint8_t *output,
size_t output_len, size_t output_len,


+ 1
- 1
src/GENERATED/include/decaf/sha512.hxx View File

@@ -31,9 +31,9 @@ protected:
/** @cond internal */ /** @cond internal */
/** The C-wrapper sponge state */ /** The C-wrapper sponge state */
decaf_sha512_ctx_t wrapped; decaf_sha512_ctx_t wrapped;
/** @endcond */


public: public:
/** Number of bytes ouf output */ /** Number of bytes ouf output */
static const size_t OUTPUT_BYTES = 64; static const size_t OUTPUT_BYTES = 64;


+ 1
- 3
src/GENERATED/include/decaf/spongerng.hxx View File

@@ -1,7 +1,5 @@


/** /**
* @file decaf/strobe.hxx
* @file decaf/spongerng.hxx
* @copyright * @copyright
* Based on CC0 code by David Leon Gil, 2015 \n * Based on CC0 code by David Leon Gil, 2015 \n
* Copyright (c) 2015 Cryptography Research, Inc. \n * Copyright (c) 2015 Cryptography Research, Inc. \n


+ 8
- 1
src/per_curve/eddsa.tmpl.h View File

@@ -20,10 +20,17 @@ extern "C" {
/** Does EdDSA support non-contextual signatures? */ /** Does EdDSA support non-contextual signatures? */
#define DECAF_EDDSA_$(gf_shortname)_SUPPORTS_CONTEXTLESS_SIGS $(eddsa_no_context) #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 "") $("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 #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 #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 #define decaf_ed$(gf_shortname)_prehash_update decaf_$(eddsa_hash)_update
/** Prehash destroy. */
#define decaf_ed$(gf_shortname)_prehash_destroy decaf_$(eddsa_hash)_destroy #define decaf_ed$(gf_shortname)_prehash_destroy decaf_$(eddsa_hash)_destroy


/** EdDSA encoding ratio. */ /** EdDSA encoding ratio. */


+ 58
- 45
src/per_curve/eddsa.tmpl.hxx View File

@@ -1,4 +1,3 @@

/* /*
* Example Decaf cyrpto routines, C++ wrapper. * Example Decaf cyrpto routines, C++ wrapper.
* @warning These are merely examples, though they ought to be secure. But real * @warning These are merely examples, though they ought to be secure. But real
@@ -22,6 +21,7 @@
#endif #endif
/** @endcond */ /** @endcond */


/** Namespace for all libdecaf C++ objects. */
namespace decaf { namespace decaf {


/** A public key for crypto over some Group */ /** A public key for crypto over some Group */
@@ -39,7 +39,14 @@ typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh;
typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh; typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh;
/** @endcond */ /** @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 #if DECAF_EDDSA_$(gf_shortname)_SUPPORTS_CONTEXTLESS_SIGS
static inline const Block NO_CONTEXT() { return Block(DECAF_ED$(gf_shortname)_NO_CONTEXT,0); } static inline const Block NO_CONTEXT() { return Block(DECAF_ED$(gf_shortname)_NO_CONTEXT,0); }
#else #else
@@ -49,6 +56,7 @@ static inline const Block NO_CONTEXT() { return Block(NULL,0); }
/** Prehash context for EdDSA. */ /** Prehash context for EdDSA. */
class Prehash : public $(re.sub(r"SHAKE(\d+)",r"SHAKE<\1>", eddsa_hash.upper())) { class Prehash : public $(re.sub(r"SHAKE(\d+)",r"SHAKE<\1>", eddsa_hash.upper())) {
private: private:
/** @cond internal */
typedef $(re.sub(r"SHAKE(\d+)",r"SHAKE<\1>", eddsa_hash.upper())) Super; typedef $(re.sub(r"SHAKE(\d+)",r"SHAKE<\1>", eddsa_hash.upper())) Super;
SecureBuffer context_; SecureBuffer context_;
template<class T, Prehashed Ph> friend class Signing; template<class T, Prehashed Ph> friend class Signing;
@@ -63,6 +71,7 @@ private:


decaf_ed$(gf_shortname)_prehash_init((decaf_$(eddsa_hash)_ctx_s *)wrapped); decaf_ed$(gf_shortname)_prehash_init((decaf_$(eddsa_hash)_ctx_s *)wrapped);
} }
/** @endcond */
public: public:
/** Number of output bytes in prehash */ /** Number of output bytes in prehash */
@@ -92,35 +101,10 @@ public:
} }
}; };


/** Signing (i.e. private) key class template */
template<class CRTP, Prehashed ph> class Signing; template<class CRTP, Prehashed ph> class Signing;


template<class CRTP> class Signing<CRTP,PREHASHED> {
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 CRTP> class Signing<CRTP,PURE> { template<class CRTP> class Signing<CRTP,PURE> {
public: public:
/** /**
@@ -153,12 +137,42 @@ public:
} }
}; };


/** Signing (i.e. private) key class, prehashed version */
template<class CRTP> class Signing<CRTP,PREHASHED> {
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 class PrivateKeyBase
: public Serializable<PrivateKeyBase> : public Serializable<PrivateKeyBase>
, public Signing<PrivateKeyBase,PURE> , public Signing<PrivateKeyBase,PURE>
, public Signing<PrivateKeyBase,PREHASHED> { , public Signing<PrivateKeyBase,PREHASHED> {
public: public:
typedef class PublicKeyBase MyPublicKey;
/** Type of public key corresponding to this private key */
typedef class PublicKeyBase PublicKey;
private: private:
/** @cond internal */ /** @cond internal */
friend class PublicKeyBase; friend class PublicKeyBase;
@@ -227,14 +241,13 @@ public:
} }
/** Return the corresponding public key */ /** 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; return pub;
} }
}; /* class PrivateKey */ }; /* class PrivateKey */




/** Verification (i.e. public) EdDSA key, PureEdDSA version. */
template<class CRTP> class Verification<CRTP,PURE> { template<class CRTP> class Verification<CRTP,PURE> {
public: public:
/** Verify a signature, returning DECAF_FAILURE if verification fails */ /** Verify a signature, returning DECAF_FAILURE if verification fails */
@@ -280,10 +293,10 @@ public:
} }
}; };


/** Verification (i.e. public) EdDSA key, prehashed version. */
template<class CRTP> class Verification<CRTP,PREHASHED> { template<class CRTP> class Verification<CRTP,PREHASHED> {
public: 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 ( inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept (
const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig,
const Prehash &ph const Prehash &ph
@@ -296,8 +309,8 @@ public:
ph.context_.size() 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 ( inline void verify_prehashed (
const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig,
const Prehash &ph 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 ( inline void verify_with_prehash (
const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig, const FixedBlock<DECAF_EDDSA_$(gf_shortname)_SIGNATURE_BYTES> &sig,
const Block &message, const Block &message,
@@ -325,24 +338,25 @@ public:
} }
}; };


/** EdDSA Public key base class. */
class PublicKeyBase class PublicKeyBase
: public Serializable<PublicKeyBase> : public Serializable<PublicKeyBase>
, public Verification<PublicKeyBase,PURE> , public Verification<PublicKeyBase,PURE>
, public Verification<PublicKeyBase,PREHASHED> { , public Verification<PublicKeyBase,PREHASHED> {
public: public:
typedef class PrivateKeyBase MyPrivateKey;
/** Private key corresponding to this type of public key */
typedef class PrivateKeyBase PrivateKey;
private: private:
/** @cond internal */ /** @cond internal */
friend class PrivateKeyBase; friend class PrivateKeyBase;
friend class Verification<PublicKey,PURE>; friend class Verification<PublicKey,PURE>;
friend class Verification<PublicKey,PREHASHED>; friend class Verification<PublicKey,PREHASHED>;
/** @endcond */


private: private:
/** The pre-expansion form of the signature */ /** The pre-expansion form of the signature */
FixedArrayBuffer<DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES> pub_; FixedArrayBuffer<DECAF_EDDSA_$(gf_shortname)_PUBLIC_BYTES> pub_;
/** @endcond */
public: public:
/* PERF FUTURE: Pre-cached decoding? Precomputed table?? */ /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
@@ -356,7 +370,6 @@ public:
/** Serialization size. */ /** Serialization size. */
static const size_t SER_BYTES = DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES; static const size_t SER_BYTES = DECAF_EDDSA_$(gf_shortname)_PRIVATE_BYTES;
/** Create but don't initialize */ /** Create but don't initialize */
inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { } inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { }
@@ -367,7 +380,7 @@ public:
inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; } inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; }
/** Copy constructor */ /** 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 */ /** Assignment from string */
inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
@@ -381,7 +394,7 @@ public:
} }


/** Assignment from private key */ /** Assignment from private key */
inline PublicKey &operator=(const MyPrivateKey &p) DECAF_NOEXCEPT {
inline PublicKey &operator=(const PrivateKey &p) DECAF_NOEXCEPT {
return *this = p.pub_; return *this = p.pub_;
} }




+ 30
- 26
src/per_curve/point.tmpl.h View File

@@ -49,10 +49,10 @@ typedef struct gf_$(gf_shortname)_s {
/** Number of bytes in an x$(gf_shortname) private key */ /** Number of bytes in an x$(gf_shortname) private key */
#define DECAF_X$(gf_shortname)_PRIVATE_BYTES $((gf_bits-1)//8 + 1) #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 { typedef struct $(c_ns)_point_s {
/** @cond internal */ /** @cond internal */
gf_$(gf_shortname)_t x,y,z,t;
gf_$(gf_shortname)_t x,y,z,t; /* Twisted extended homogeneous coordinates */
/** @endcond */ /** @endcond */
} $(c_ns)_point_t[1]; } $(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. */ /** 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; 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 { typedef struct $(c_ns)_scalar_s {
/** @cond internal */ /** @cond internal */
decaf_word_t limb[$(C_NS)_SCALAR_LIMBS]; decaf_word_t limb[$(C_NS)_SCALAR_LIMBS];
/** @endcond */ /** @endcond */
} $(c_ns)_scalar_t[1]; } $(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; 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; 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; 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; 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; 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; ) 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_SUCCESS The scalarmul succeeded.
* @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 decaf_x$(gf_shortname) ( 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 base[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
const uint8_t scalar[DECAF_X$(gf_shortname)_PRIVATE_BYTES] const uint8_t scalar[DECAF_X$(gf_shortname)_PRIVATE_BYTES]
) DECAF_API_VIS DECAF_NONNULL DECAF_WARN_UNUSED DECAF_NOINLINE; ) 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; ) DECAF_API_VIS DECAF_NONNULL;


/** The base point for X$(gf_shortname) Diffie-Hellman */ /** 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 * @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. * @deprecated Renamed to decaf_x$(gf_shortname)_derive_public_key.
* I have no particular timeline for removing this name. * 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 ( void decaf_x$(gf_shortname)_generate_key (
uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES], 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, * Does exactly the same thing as decaf_x$(gf_shortname)_generate_key,
* but has a better name. * 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 ( void decaf_x$(gf_shortname)_derive_public_key (
uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES], uint8_t out[DECAF_X$(gf_shortname)_PUBLIC_BYTES],
@@ -722,22 +728,20 @@ $(c_ns)_invert_elligator_uniform (
uint32_t which uint32_t which
) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED; ) DECAF_API_VIS DECAF_NONNULL DECAF_NOINLINE DECAF_WARN_UNUSED;


/**
* @brief Overwrite scalar with zeros.
*/
/** Securely erase a scalar. */
void $(c_ns)_scalar_destroy ( void $(c_ns)_scalar_destroy (
$(c_ns)_scalar_t scalar $(c_ns)_scalar_t scalar
) DECAF_NONNULL DECAF_API_VIS; ) 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 ( void $(c_ns)_point_destroy (
$(c_ns)_point_t point $(c_ns)_point_t point
) DECAF_NONNULL DECAF_API_VIS; ) 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 ( void $(c_ns)_precomputed_destroy (
$(c_ns)_precomputed_s *pre $(c_ns)_precomputed_s *pre


+ 31
- 42
src/per_curve/point.tmpl.hxx View File

@@ -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 * 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. * 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. */ /** This code uses posix_memalign. */
@@ -174,8 +173,9 @@ public:
/** Negate */ /** Negate */
inline Scalar operator- () const DECAF_NOEXCEPT { Scalar r((NOINIT())); $(c_ns)_scalar_sub(r.s,$(c_ns)_scalar_zero,s); return r; } 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)*/ { inline Scalar inverse() const /*throw(CryptoException)*/ {
Scalar r; Scalar r;
if (DECAF_SUCCESS != $(c_ns)_scalar_invert(r.s,s)) { if (DECAF_SUCCESS != $(c_ns)_scalar_invert(r.s,s)) {
@@ -191,10 +191,10 @@ public:
return $(c_ns)_scalar_invert(r.s,s); 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(); } 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(); } inline Scalar &operator/=(const Scalar &q) /*throw(CryptoException)*/ { return *this *= q.inverse(); }


/** Return half this scalar. Much faster than /2. */ /** Return half this scalar. Much faster than /2. */
@@ -212,7 +212,9 @@ public:
/** Scalarmul-precomputed with scalar on left. */ /** Scalarmul-precomputed with scalar on left. */
inline Point operator* (const Precomputed &q) const DECAF_NOEXCEPT { return q * (*this); } 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 ( inline SecureBuffer direct_scalarmul (
const FixedBlock<SER_BYTES> &in, const FixedBlock<SER_BYTES> &in,
decaf_bool_t allow_identity=DECAF_FALSE, decaf_bool_t allow_identity=DECAF_FALSE,
@@ -228,12 +230,10 @@ public:
) const DECAF_NOEXCEPT; ) const DECAF_NOEXCEPT;
}; };


/**
* Element of prime-order group.
*/
/** Element of prime-order elliptic curve group. */
class Point : public Serializable<Point> { class Point : public Serializable<Point> {
public: public:
/** wrapped C type */
/** Wrapped C type */
typedef $(c_ns)_point_t Wrapped; typedef $(c_ns)_point_t Wrapped;
/** Size of a serialized element */ /** Size of a serialized element */
@@ -257,17 +257,8 @@ public:
/** Ratio due to ladder decoding */ /** Ratio due to ladder decoding */
static const int LADDER_ENCODE_RATIO = DECAF_X$(gf_shortname)_ENCODE_RATIO; 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; 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, * @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. * or was the identity and allow_identity was DECAF_FALSE.
*/ */
inline explicit Point(const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE)
inline explicit Point(const FixedBlock<SER_BYTES> &buffer, bool allow_identity=true)
/*throw(CryptoException)*/ { /*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode(buffer,allow_identity)) {
if (DECAF_SUCCESS != decode(buffer,allow_identity ? DECAF_TRUE : DECAF_FALSE)) {
throw CryptoException(); throw CryptoException();
} }
} }
@@ -328,9 +319,9 @@ public:
* or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined. * or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined.
*/ */
inline decaf_error_t DECAF_WARN_UNUSED decode ( inline decaf_error_t DECAF_WARN_UNUSED decode (
const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE
const FixedBlock<SER_BYTES> &buffer, bool allow_identity=true
) DECAF_NOEXCEPT { ) 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. */ /** Multiply by LADDER_ENCODE_RATIO and encode like X25519/X448. */
inline void mul_by_ratio_and_encode_like_ladder(
FixedBuffer<LADDER_BYTES> &out
) const {
inline void mul_by_ratio_and_encode_like_ladder(FixedBuffer<LADDER_BYTES> &out) const {
$(c_ns)_point_mul_by_ratio_and_encode_like_x$(gf_shortname)(out.data(),p); $(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 { inline operator SecureBuffer() const {
SecureBuffer buffer(SER_BYTES); SecureBuffer buffer(SER_BYTES);
$(c_ns)_point_encode(buffer.data(), p); $(c_ns)_point_encode(buffer.data(), p);
@@ -570,10 +557,10 @@ public:
return out; 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); } 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); } static inline const Point identity() DECAF_NOEXCEPT { return Point($(c_ns)_point_identity); }
}; };


@@ -671,6 +658,7 @@ public:
/** @endcond */ /** @endcond */
}; };


/** X-only Diffie-Hellman ladder functions */
struct DhLadder { struct DhLadder {
public: public:
/** Bytes in an X$(gf_shortname) public key. */ /** Bytes in an X$(gf_shortname) public key. */
@@ -745,7 +733,8 @@ public:
* equivalent to shared_secret(base_point(),scalar) but possibly faster. * equivalent to shared_secret(base_point(),scalar) but possibly faster.
* @deprecated Renamed to derive_public_key_noexcept. * @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 ( generate_key_noexcept (
FixedBuffer<PUBLIC_BYTES> &out, FixedBuffer<PUBLIC_BYTES> &out,
const FixedBlock<PRIVATE_BYTES> &scalar const FixedBlock<PRIVATE_BYTES> &scalar
@@ -781,7 +770,7 @@ inline decaf_error_t $(cxx_ns)::Scalar::direct_scalarmul_noexcept (
} }
/** @endcond */ /** @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 #undef DECAF_NOEXCEPT
} /* namespace decaf */ } /* namespace decaf */

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

@@ -4,7 +4,9 @@ $("\n".join([
"#include <decaf/point_%s.hxx>" % g for g in sorted([c["bits"] for _,c in curve.items()]) "#include <decaf/point_%s.hxx>" % g for g in sorted([c["bits"] for _,c in curve.items()])
])) ]))


/** Namespace for all C++ decaf objects. */
namespace decaf { namespace decaf {
/** Given a template with a "run" function, run it for all curves */
template <template<typename Group> class Run> template <template<typename Group> class Run>
void run_for_all_curves() { void run_for_all_curves() {
$("\n".join([ $("\n".join([


+ 3
- 2
src/public_include/decaf/common.h View File

@@ -21,8 +21,9 @@ extern "C" {


/* Goldilocks' build flags default to hidden and stripping executables. */ /* Goldilocks' build flags default to hidden and stripping executables. */
/** @cond internal */ /** @cond internal */
#if defined(DOXYGEN) && !defined(__attribute__)
#define __attribute__((x))
#if DOXYGEN || defined(__attribute__)
#define __attribute__(x)
#define NOINLINE
#endif #endif
#define DECAF_API_VIS __attribute__((visibility("default"))) #define DECAF_API_VIS __attribute__((visibility("default")))
#define DECAF_NOINLINE __attribute__((noinline)) #define DECAF_NOINLINE __attribute__((noinline))


+ 9
- 1
src/public_include/decaf/eddsa.tmpl.hxx View File

@@ -2,7 +2,15 @@
* EdDSA crypto routines, metaheader. * 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([ $("\n".join([
"#include <decaf/ed%s.hxx>" % g for g in sorted([c["bits"] for _,c in curve.items()]) "#include <decaf/ed%s.hxx>" % g for g in sorted([c["bits"] for _,c in curve.items()])
])) ]))

+ 21
- 3
src/public_include/decaf/sha512.h View File

@@ -18,21 +18,39 @@
extern "C" { extern "C" {
#endif #endif
/** Hash context for SHA-512 */
typedef struct decaf_sha512_ctx_s { typedef struct decaf_sha512_ctx_s {
/** @cond internal */
uint64_t state[8]; uint64_t state[8];
uint8_t block[128]; uint8_t block[128];
uint64_t bytes_processed; uint64_t bytes_processed;
/* @endcond */
} decaf_sha512_ctx_s, decaf_sha512_ctx_t[1]; } 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_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) { static inline void decaf_sha512_destroy(decaf_sha512_ctx_t ctx) {
decaf_bzero(ctx,sizeof(*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( static inline void decaf_sha512_hash(
uint8_t *output, uint8_t *output,
size_t output_len, size_t output_len,


+ 1
- 1
src/public_include/decaf/sha512.hxx View File

@@ -31,9 +31,9 @@ protected:
/** @cond internal */ /** @cond internal */
/** The C-wrapper sponge state */ /** The C-wrapper sponge state */
decaf_sha512_ctx_t wrapped; decaf_sha512_ctx_t wrapped;
/** @endcond */


public: public:
/** Number of bytes ouf output */ /** Number of bytes ouf output */
static const size_t OUTPUT_BYTES = 64; static const size_t OUTPUT_BYTES = 64;


+ 1
- 3
src/public_include/decaf/spongerng.hxx View File

@@ -1,7 +1,5 @@


/** /**
* @file decaf/strobe.hxx
* @file decaf/spongerng.hxx
* @copyright * @copyright
* Based on CC0 code by David Leon Gil, 2015 \n * Based on CC0 code by David Leon Gil, 2015 \n
* Copyright (c) 2015 Cryptography Research, Inc. \n * Copyright (c) 2015 Cryptography Research, Inc. \n


Loading…
Cancel
Save