Commit 1a14abb4 authored by Michael Hamburg's avatar Michael Hamburg

Separate .h files for SHA/SHAKE, STROBE and sponge RNG. TODO: .hxx. Also add a lot of docs

parent 957ec6cd
...@@ -751,7 +751,7 @@ WARN_LOGFILE = ...@@ -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 = include INPUT = build/include
# 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
...@@ -1548,7 +1548,7 @@ EXTRA_SEARCH_MAPPINGS = ...@@ -1548,7 +1548,7 @@ EXTRA_SEARCH_MAPPINGS =
# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. # If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
# The default value is: YES. # The default value is: YES.
GENERATE_LATEX = YES GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
......
...@@ -243,8 +243,8 @@ $(BUILD_DOC)/timestamp: ...@@ -243,8 +243,8 @@ $(BUILD_DOC)/timestamp:
mkdir -p `dirname $@` mkdir -p `dirname $@`
touch $@ touch $@
# #
# doc: Doxyfile $(BUILD_OBJ)/timestamp $(HEADERS) src/*.c src/$(FIELD)/$(ARCH)/*.c src/$(FIELD)/$(ARCH)/*.h doc: Doxyfile $(BUILD_OBJ)/timestamp $(HEADERS)
# doxygen > /dev/null doxygen > /dev/null
# # The eBATS benchmarking script # # The eBATS benchmarking script
# bat: $(BATNAME) # bat: $(BATNAME)
......
...@@ -3,14 +3,18 @@ from gen_file import gen_file ...@@ -3,14 +3,18 @@ from gen_file import gen_file
crypto_h = gen_file( crypto_h = gen_file(
name = "decaf/crypto_%(shortname)s.h", name = "decaf/crypto_%(shortname)s.h",
doc = """ doc = """
@brief Example Decaf crypto routines. Example Decaf crypto routines.
@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
protocols will decide differently on magic numbers, formats, which items to protocols will decide differently on magic numbers, formats, which items to
hash, etc. hash, etc.
@warning Experimental! The names, parameter orders etc are likely to change. @warning Experimental! The names, parameter orders etc are likely to change.
""", code = """ """, code = """
#include <decaf/%(c_ns)s.h> #include <decaf/%(c_ns)s.h>
#include <decaf/shake.h> #include <decaf/strobe.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Number of bytes for a symmetric key (expanded to full key) */ /** Number of bytes for a symmetric key (expanded to full key) */
#define %(C_NS)s_SYMMETRIC_KEY_BYTES 32 #define %(C_NS)s_SYMMETRIC_KEY_BYTES 32
...@@ -39,13 +43,9 @@ typedef struct { ...@@ -39,13 +43,9 @@ typedef struct {
%(c_ns)s_private_key_s, %(c_ns)s_private_key_s,
/** A private key (gmp array[1] style). */ /** A private key (gmp array[1] style). */
%(c_ns)s_private_key_t[1]; %(c_ns)s_private_key_t[1];
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief Derive a key from its compressed form. * Derive a key from its compressed form.
* @param [out] priv The derived private key. * @param [out] priv The derived private key.
* @param [in] proto The compressed or proto-key, which must be 32 random bytes. * @param [in] proto The compressed or proto-key, which must be 32 random bytes.
*/ */
...@@ -55,14 +55,14 @@ void %(c_ns)s_derive_private_key ( ...@@ -55,14 +55,14 @@ void %(c_ns)s_derive_private_key (
) NONNULL2 API_VIS; ) NONNULL2 API_VIS;
/** /**
* @brief Destroy a private key. * Destroy a private key.
*/ */
void %(c_ns)s_destroy_private_key ( void %(c_ns)s_destroy_private_key (
%(c_ns)s_private_key_t priv %(c_ns)s_private_key_t priv
) NONNULL1 API_VIS; ) NONNULL1 API_VIS;
/** /**
* @brief Convert a private key to a public one. * Convert a private key to a public one.
* @param [out] pub The extracted private key. * @param [out] pub The extracted private key.
* @param [in] priv The private key. * @param [in] priv The private key.
*/ */
...@@ -72,7 +72,7 @@ void %(c_ns)s_private_to_public ( ...@@ -72,7 +72,7 @@ void %(c_ns)s_private_to_public (
) NONNULL2 API_VIS; ) NONNULL2 API_VIS;
/** /**
* @brief Compute a Diffie-Hellman shared secret. * Compute a Diffie-Hellman shared secret.
* *
* This is an example routine; real protocols would use something * This is an example routine; real protocols would use something
* protocol-specific. * protocol-specific.
...@@ -96,7 +96,7 @@ decaf_error_t ...@@ -96,7 +96,7 @@ decaf_error_t
) NONNULL134 WARN_UNUSED API_VIS; ) NONNULL134 WARN_UNUSED API_VIS;
/** /**
* @brief Sign a message from a STROBE context. * Sign a message from a STROBE context.
* *
* @param [out] sig The signature. * @param [out] sig The signature.
* @param [in] priv Your private key. * @param [in] priv Your private key.
...@@ -110,7 +110,7 @@ void ...@@ -110,7 +110,7 @@ void
) NONNULL3 API_VIS; ) NONNULL3 API_VIS;
/** /**
* @brief Sign a message. * Sign a message.
* *
* @param [out] sig The signature. * @param [out] sig The signature.
* @param [in] priv Your private key. * @param [in] priv Your private key.
...@@ -126,7 +126,7 @@ void ...@@ -126,7 +126,7 @@ void
) NONNULL3 API_VIS; ) NONNULL3 API_VIS;
/** /**
* @brief Verify a signed message from its STROBE context. * Verify a signed message from its STROBE context.
* *
* @param [in] sig The signature. * @param [in] sig The signature.
* @param [in] pub The public key. * @param [in] pub The public key.
...@@ -143,7 +143,7 @@ decaf_error_t ...@@ -143,7 +143,7 @@ decaf_error_t
) NONNULL3 API_VIS WARN_UNUSED; ) NONNULL3 API_VIS WARN_UNUSED;
/** /**
* @brief Verify a signed message. * Verify a signed message.
* *
* @param [in] sig The signature. * @param [in] sig The signature.
* @param [in] pub The public key. * @param [in] pub The public key.
......
...@@ -3,7 +3,7 @@ from gen_file import gen_file ...@@ -3,7 +3,7 @@ from gen_file import gen_file
crypto_hxx = gen_file( crypto_hxx = gen_file(
name = "decaf/crypto_%(shortname)s.hxx", name = "decaf/crypto_%(shortname)s.hxx",
doc = """ doc = """
@brief 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
protocols will decide differently on magic numbers, formats, which items to protocols will decide differently on magic numbers, formats, which items to
hash, etc. hash, etc.
...@@ -21,51 +21,56 @@ crypto_hxx = gen_file( ...@@ -21,51 +21,56 @@ crypto_hxx = gen_file(
/** @endcond */ /** @endcond */
namespace decaf { namespace decaf {
/** A public key for crypto over some Group */
template <typename Group> class PublicKey; template <typename Group> class PublicKey;
/** A private key for crypto over some Group */
template <typename Group> class PrivateKey; template <typename Group> class PrivateKey;
/** A public key for crypto over %(name)s */
template<> class PublicKey<%(cxx_ns)s> template<> class PublicKey<%(cxx_ns)s>
: public Serializable< PublicKey<%(cxx_ns)s> > { : public Serializable< PublicKey<%(cxx_ns)s> > {
private: private:
/** @cond internal */
typedef %(c_ns)s_public_key_t Wrapped; typedef %(c_ns)s_public_key_t Wrapped;
Wrapped wrapped; Wrapped wrapped;
template<class Group> friend class PrivateKey; template<class Group> friend class PrivateKey;
/** @endcond */
public: public:
/** @brief Underlying group */ /** Underlying group */
typedef %(cxx_ns)s Group; typedef %(cxx_ns)s Group;
/** @brief Signature size. */ /** Signature size. */
static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t); static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t);
/** @brief Serialization size. */ /** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped); static const size_t SER_BYTES = sizeof(Wrapped);
/* TODO: convenience types like signature? */ /* TODO: convenience types like signature? */
/** @brief Read a private key from a string*/ /** Read a private key from a string*/
inline explicit PublicKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT { inline explicit PublicKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
memcpy(wrapped,b.data(),sizeof(wrapped)); memcpy(wrapped,b.data(),sizeof(wrapped));
} }
/** @brief Read a private key from a string*/ /** Read a private key from a string*/
inline explicit PublicKey(const PrivateKey<%(cxx_ns)s> &b) NOEXCEPT; inline explicit PublicKey(const PrivateKey<%(cxx_ns)s> &b) NOEXCEPT;
/** @brief Create but don't initialize */ /** Create but don't initialize */
inline explicit PublicKey(const NOINIT&) NOEXCEPT { } inline explicit PublicKey(const NOINIT&) NOEXCEPT { }
/** @brief Serialize into a buffer. */ /** Serialize into a buffer. */
inline void serializeInto(unsigned char *x) const NOEXCEPT { inline void serializeInto(unsigned char *x) const NOEXCEPT {
memcpy(x,wrapped,sizeof(wrapped)); memcpy(x,wrapped,sizeof(wrapped));
} }
/** @brief Serialization size. */ /** Serialization size. */
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } inline size_t serSize() const NOEXCEPT { return SER_BYTES; }
/* TODO: verify_strobe */ /* TODO: verify_strobe */
/** @brief Verify a message */ /** Verify a message */
inline void verify( inline void verify(
const Block &message, const Block &message,
const FixedBlock<SIG_BYTES> &sig const FixedBlock<SIG_BYTES> &sig
...@@ -76,71 +81,73 @@ public: ...@@ -76,71 +81,73 @@ public:
} }
}; };
/** A private key for crypto over %(name)s */
template<> class PrivateKey<%(cxx_ns)s> template<> class PrivateKey<%(cxx_ns)s>
: public Serializable< PrivateKey<%(cxx_ns)s> > { : public Serializable< PrivateKey<%(cxx_ns)s> > {
private: private:
/** @cond internal */
typedef %(c_ns)s_private_key_t Wrapped; typedef %(c_ns)s_private_key_t Wrapped;
Wrapped wrapped; Wrapped wrapped;
template<class Group> friend class PublicKey; template<class Group> friend class PublicKey;
/** @endcond */
public: public:
/** @brief Underlying group */ /** Underlying group */
typedef %(cxx_ns)s Group; typedef %(cxx_ns)s Group;
/** @brief Signature size. */ /** Signature size. */
static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t); static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t);
/** @brief Serialization size. */ /** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped); static const size_t SER_BYTES = sizeof(Wrapped);
/** @brief Compressed size. */ /** Compressed size. */
static const size_t SYM_BYTES = %(C_NS)s_SYMMETRIC_KEY_BYTES; static const size_t SYM_BYTES = %(C_NS)s_SYMMETRIC_KEY_BYTES;
/** @brief Create but don't initialize */ /** Create but don't initialize */
inline explicit PrivateKey(const NOINIT&) NOEXCEPT { } inline explicit PrivateKey(const NOINIT&) NOEXCEPT { }
/** @brief Read a private key from a string*/ /** Read a private key from a string*/
inline explicit PrivateKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT { inline explicit PrivateKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
memcpy(wrapped,b.data(),sizeof(wrapped)); memcpy(wrapped,b.data(),sizeof(wrapped));
} }
/** @brief Read a private key from a string*/ /** Read a private key from a string*/
inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT { inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT {
%(c_ns)s_derive_private_key(wrapped, b.data()); %(c_ns)s_derive_private_key(wrapped, b.data());
} }
/** @brief Create at random */ /** Create at random */
inline explicit PrivateKey(Rng &r) NOEXCEPT { inline explicit PrivateKey(Rng &r) NOEXCEPT {
FixedArrayBuffer<SYM_BYTES> tmp(r); FixedArrayBuffer<SYM_BYTES> tmp(r);
%(c_ns)s_derive_private_key(wrapped, tmp.data()); %(c_ns)s_derive_private_key(wrapped, tmp.data());
} }
/** @brief Secure destructor */ /** Secure destructor */
inline ~PrivateKey() NOEXCEPT { inline ~PrivateKey() NOEXCEPT {
%(c_ns)s_destroy_private_key(wrapped); %(c_ns)s_destroy_private_key(wrapped);
} }
/** @brief Serialization size. */ /** Serialization size. */
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } inline size_t serSize() const NOEXCEPT { return SER_BYTES; }
/** @brief Serialize into a buffer. */ /** Serialize into a buffer. */
inline void serializeInto(unsigned char *x) const NOEXCEPT { inline void serializeInto(unsigned char *x) const NOEXCEPT {
memcpy(x,wrapped,sizeof(wrapped)); memcpy(x,wrapped,sizeof(wrapped));
} }
/** @brief Compressed serialize. */ /** Compressed serialize. */
inline SecureBuffer compress() const throw(std::bad_alloc) { inline SecureBuffer compress() const throw(std::bad_alloc) {
SecureBuffer ret(sizeof(wrapped->sym)); SecureBuffer ret(sizeof(wrapped->sym));
memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym)); memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym));
return ret; return ret;
} }
/** @brief Get the public key */ /** Get the public key */
inline PublicKey<%(cxx_ns)s> pub() const NOEXCEPT { inline PublicKey<%(cxx_ns)s> pub() const NOEXCEPT {
PublicKey<%(cxx_ns)s> ret(*this); return ret; PublicKey<%(cxx_ns)s> ret(*this); return ret;
} }
/** @brief Derive a shared secret */ /** Derive a shared secret */
inline SecureBuffer sharedSecret( inline SecureBuffer sharedSecret(
const PublicKey<%(cxx_ns)s> &pub, const PublicKey<%(cxx_ns)s> &pub,
size_t bytes, size_t bytes,
...@@ -153,7 +160,7 @@ public: ...@@ -153,7 +160,7 @@ public:
return ret; return ret;
} }
/** @brief Sign a message. */ /** Sign a message. */
inline SecureBuffer sign(const Block &message) const { inline SecureBuffer sign(const Block &message) const {
SecureBuffer sig(SIG_BYTES); SecureBuffer sig(SIG_BYTES);
%(c_ns)s_sign(sig.data(), wrapped, message.data(), message.size()); %(c_ns)s_sign(sig.data(), wrapped, message.data(), message.size());
......
...@@ -10,19 +10,23 @@ decaf_h = gen_file( ...@@ -10,19 +10,23 @@ decaf_h = gen_file(
extern "C" { extern "C" {
#endif #endif
/** @cond internal */
#define %(C_NS)s_LIMBS (%(gf_bits)d/DECAF_WORD_BITS) #define %(C_NS)s_LIMBS (%(gf_bits)d/DECAF_WORD_BITS)
#define %(C_NS)s_SCALAR_BITS %(scalar_bits)d
#define %(C_NS)s_SCALAR_LIMBS ((%(scalar_bits)d-1)/DECAF_WORD_BITS+1) #define %(C_NS)s_SCALAR_LIMBS ((%(scalar_bits)d-1)/DECAF_WORD_BITS+1)
/** @endcond */
/** The number of bits in a scalar */
#define %(C_NS)s_SCALAR_BITS %(scalar_bits)d
/** Galois field element internal structure */ /** @cond internal */
#ifndef __%(C_NS)s_GF_DEFINED__ #ifndef __%(C_NS)s_GF_DEFINED__
#define __%(C_NS)s_GF_DEFINED__ 1 #define __%(C_NS)s_GF_DEFINED__ 1
/** @brief Galois field element internal structure */
typedef struct gf_%(longnum)s_s { typedef struct gf_%(longnum)s_s {
/** @cond internal */
decaf_word_t limb[%(C_NS)s_LIMBS]; decaf_word_t limb[%(C_NS)s_LIMBS];
/** @endcond */
} __attribute__((aligned(32))) gf_%(longnum)s_s, gf_%(longnum)s_t[1]; } __attribute__((aligned(32))) gf_%(longnum)s_s, gf_%(longnum)s_t[1];
#endif /* __%(C_NS)s_GF_DEFINED__ */ #endif /* __%(C_NS)s_GF_DEFINED__ */
/** @endcond */
/** Number of bytes in a serialized point. */ /** Number of bytes in a serialized point. */
#define %(C_NS)s_SER_BYTES %(ser_bytes)d #define %(C_NS)s_SER_BYTES %(ser_bytes)d
...@@ -393,16 +397,17 @@ void %(c_ns)s_point_double_scalarmul ( ...@@ -393,16 +397,17 @@ void %(c_ns)s_point_double_scalarmul (
const %(c_ns)s_scalar_t scalar2 const %(c_ns)s_scalar_t scalar2
) API_VIS NONNULL5 NOINLINE; ) API_VIS NONNULL5 NOINLINE;
/* /**
* @brief Multiply one base point by two scalars: * Multiply one base point by two scalars:
*
* a1 = scalar1 * base * a1 = scalar1 * base
* a2 = scalar2 * base * a2 = scalar2 * base
* *
* Equivalent to two calls to %(c_ns)s_point_scalarmul, but may be * Equivalent to two calls to %(c_ns)s_point_scalarmul, but may be
* faster. * faster.
* *
* @param [out] a1 The first multiple * @param [out] a1 The first multiple. It may be the same as the input point.
* @param [out] a2 The second multiple * @param [out] a2 The second multiple. It may be the same as the input point.
* @param [in] base1 A point to be scaled. * @param [in] base1 A point to be scaled.
* @param [in] scalar1 A first scalar to multiply by. * @param [in] scalar1 A first scalar to multiply by.
* @param [in] scalar2 A second scalar to multiply by. * @param [in] scalar2 A second scalar to multiply by.
...@@ -410,7 +415,7 @@ void %(c_ns)s_point_double_scalarmul ( ...@@ -410,7 +415,7 @@ void %(c_ns)s_point_double_scalarmul (
void %(c_ns)s_point_dual_scalarmul ( void %(c_ns)s_point_dual_scalarmul (
%(c_ns)s_point_t a1, %(c_ns)s_point_t a1,
%(c_ns)s_point_t a2, %(c_ns)s_point_t a2,
const %(c_ns)s_point_t b, const %(c_ns)s_point_t base1,
const %(c_ns)s_scalar_t scalar1, const %(c_ns)s_scalar_t scalar1,
const %(c_ns)s_scalar_t scalar2 const %(c_ns)s_scalar_t scalar2
) API_VIS NONNULL5 NOINLINE; ) API_VIS NONNULL5 NOINLINE;
...@@ -441,7 +446,7 @@ void %(c_ns)s_base_double_scalarmul_non_secret ( ...@@ -441,7 +446,7 @@ void %(c_ns)s_base_double_scalarmul_non_secret (
* @brief Constant-time decision between two points. If pick_b * @brief Constant-time decision between two points. If pick_b
* is zero, out = a; else out = b. * is zero, out = a; else out = b.
* *
* @param [out] q The output. It may be the same as either input. * @param [out] out The output. It may be the same as either input.
* @param [in] a Any point. * @param [in] a Any point.
* @param [in] b Any point. * @param [in] b Any point.
* @param [in] pick_b If nonzero, choose point b. * @param [in] pick_b If nonzero, choose point b.
...@@ -457,7 +462,7 @@ void %(c_ns)s_point_cond_sel ( ...@@ -457,7 +462,7 @@ void %(c_ns)s_point_cond_sel (
* @brief Constant-time decision between two scalars. If pick_b * @brief Constant-time decision between two scalars. If pick_b
* is zero, out = a; else out = b. * is zero, out = a; else out = b.
* *
* @param [out] q The output. It may be the same as either input. * @param [out] out The output. It may be the same as either input.
* @param [in] a Any scalar. * @param [in] a Any scalar.
* @param [in] b Any scalar. * @param [in] b Any scalar.
* @param [in] pick_b If nonzero, choose scalar b. * @param [in] pick_b If nonzero, choose scalar b.
......
This diff is collapsed.
...@@ -34,8 +34,8 @@ crypto_h_code = "\n".join(( ...@@ -34,8 +34,8 @@ crypto_h_code = "\n".join((
)) ))
crypto_h = gen_file( crypto_h = gen_file(
name = "decaf/crypto.h", name = "decaf/crypto.h",
doc = """@brief doc = """
@brief Example Decaf crypto routines, metaheader. Example Decaf crypto routines, metaheader.
@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
protocols will decide differently on magic numbers, formats, which items to protocols will decide differently on magic numbers, formats, which items to
hash, etc. hash, etc.
...@@ -50,8 +50,8 @@ crypto_hxx_code = "\n".join(( ...@@ -50,8 +50,8 @@ crypto_hxx_code = "\n".join((
)) ))
crypto_hxx = gen_file( crypto_hxx = gen_file(
name = "decaf/crypto.hxx", name = "decaf/crypto.hxx",
doc = """@brief doc = """
@brief Example Decaf crypto routines, C++, metaheader. Example Decaf crypto routines, C++, metaheader.
@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
protocols will decide differently on magic numbers, formats, which items to protocols will decide differently on magic numbers, formats, which items to
hash, etc. hash, etc.
...@@ -67,7 +67,7 @@ root_h_code = "\n".join(( ...@@ -67,7 +67,7 @@ root_h_code = "\n".join((
decaf_root_hxx = gen_file( decaf_root_hxx = gen_file(
name = "decaf.h", name = "decaf.h",
doc = """ doc = """
@brief Master header for Decaf library. Master header for Decaf library.
The Decaf library implements cryptographic operations on a elliptic curve The Decaf library implements cryptographic operations on a elliptic curve
groups of prime order p. It accomplishes this by using a twisted Edwards groups of prime order p. It accomplishes this by using a twisted Edwards
......
...@@ -15,6 +15,10 @@ ...@@ -15,6 +15,10 @@
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/* 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__) #if defined(DOXYGEN) && !defined(__attribute__)
...@@ -43,27 +47,28 @@ ...@@ -43,27 +47,28 @@
*/ */
#if (defined(__ILP64__) || defined(__amd64__) || defined(__x86_64__) || (((__UINT_FAST32_MAX__)>>30)>>30)) \ #if (defined(__ILP64__) || defined(__amd64__) || defined(__x86_64__) || (((__UINT_FAST32_MAX__)>>30)>>30)) \
&& !defined(DECAF_FORCE_32_BIT) && !defined(DECAF_FORCE_32_BIT)
#define DECAF_WORD_BITS 64 #define DECAF_WORD_BITS 64 /**< The number of bits in a word */
typedef uint64_t decaf_word_t, decaf_bool_t; typedef uint64_t decaf_word_t; /**< Word size for internal computations */
typedef __uint128_t decaf_dword_t; typedef uint64_t decaf_bool_t; /**< "Boolean" type, will be set to all-zero or all-one (i.e. -1u) */
typedef __uint128_t decaf_dword_t; /**< Double-word size for internal computations */
#else #else
#define DECAF_WORD_BITS 32 #define DECAF_WORD_BITS 32 /**< The number of bits in a word */
typedef uint32_t decaf_word_t, decaf_bool_t; typedef uint32_t decaf_word_t; /**< Word size for internal computations */
typedef uint64_t decaf_dword_t; typedef uint32_t decaf_bool_t; /**< "Boolean" type, will be set to all-zero or all-one (i.e. -1u) */
#endif typedef uint64_t decaf_dword_t; /**< Double-word size for internal computations */
#ifdef __cplusplus
extern "C" {
#endif #endif
/** DECAF_TRUE = -1 so that DECAF_TRUE & x = x */ /** DECAF_TRUE = -1 so that DECAF_TRUE & x = x */
static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1, DECAF_FALSE = 0; static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1;
/** DECAF_FALSE = 0 so that DECAF_FALSE & x = 0 */
static const decaf_bool_t DECAF_FALSE = 0;
/* Success or failure */ /** Another boolean type used to indicate success or failure. */
// FIXME: deploy project-wide // FIXME: deploy project-wide
typedef enum { typedef enum {
DECAF_SUCCESS = -1, DECAF_SUCCESS = -1, /**< The operation succeeded. */
DECAF_FAILURE = 0 DECAF_FAILURE = 0 /**< The operation failed. */
} decaf_error_t; } decaf_error_t;
......
...@@ -48,46 +48,30 @@ public: ...@@ -48,46 +48,30 @@ public:
typedef const T& const_reference; typedef const T& const_reference;
typedef size_t size_type; typedef size_t size_type;
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
template<typename U> struct rebind { typedef SanitizingAllocator<U> other; }; template<typename U> struct rebind { typedef SanitizingAllocator<U> other; };
inline SanitizingAllocator() NOEXCEPT {} inline SanitizingAllocator() NOEXCEPT {}
inline ~SanitizingAllocator() NOEXCEPT {} inline ~SanitizingAllocator() NOEXCEPT {}
inline SanitizingAllocator(const SanitizingAllocator &) NOEXCEPT {} inline SanitizingAllocator(const SanitizingAllocator &) NOEXCEPT {}
template<typename U, size_t a> inline SanitizingAllocator(const SanitizingAllocator<U, a> &) NOEXCEPT {} template<typename U, size_t a> inline SanitizingAllocator(const SanitizingAllocator<U, a> &) NOEXCEPT {}
inline T* address(T& r) const NOEXCEPT { return &r; } inline T* address(T& r) const NOEXCEPT { return &r; }
inline const T* address(const T& r) const NOEXCEPT { return &r; } inline const T* address(const T& r) const NOEXCEPT { return &r; }
inline T* allocate ( inline T* allocate (
size_type cnt, size_type cnt,
typename std::allocator<void>::const_pointer = 0 typename std::allocator<void>::const_pointer = 0
) throw(std::bad_alloc) { ) throw(std::bad_alloc);
void *v; inline void deallocate(T* p, size_t size) NOEXCEPT;
int ret = 0;
if (alignment) ret = posix_memalign(&v, alignment, cnt * sizeof(T));
else v = malloc(cnt * sizeof(T));
if (ret || v==NULL) throw(std::bad_alloc());
return reinterpret_cast<T*>(v);
}
inline void deallocate(T* p, size_t size) NOEXCEPT {
if (p==NULL) return;
really_bzero(reinterpret_cast<void*>(p), size);
free(reinterpret_cast<void*>(p));
}
inline size_t max_size() const NOEXCEPT { return std::numeric_limits<size_t>::max() / sizeof(T); } inline size_t max_size() const NOEXCEPT { return std::numeric_limits<size_t>::max() / sizeof(T); }
inline void construct(T* p, const T& t) { new(p) T(t); } inline void construct(T* p, const T& t) { new(p) T(t); }
inline void destroy(T* p) { p->~T(); } inline void destroy(T* p) { p->~T(); }
inline bool operator==(SanitizingAllocator const&) const NOEXCEPT { return true; } inline bool operator==(SanitizingAllocator const&) const NOEXCEPT { return true; }
inline bool operator!=(SanitizingAllocator const&) const NOEXCEPT { return false; } inline bool operator!=(SanitizingAllocator const&) const NOEXCEPT { return false; }
/** @endcond */ /** @endcond */
}; };
/** A variant of std::vector which securely zerozes its state when destructed. */
typedef std::vector<unsigned char, SanitizingAllocator<unsigned char, 0> > SecureBuffer; typedef std::vector<unsigned char, SanitizingAllocator<unsigned char, 0> > SecureBuffer;
/** Constant-time compare two buffers */ /** Constant-time compare two buffers */
...@@ -170,8 +154,10 @@ public: ...@@ -170,8 +154,10 @@ public:
/** A reference to a block of data, which (when accessed through this base class) is const. */ /** A reference to a block of data, which (when accessed through this base class) is const. */
class Block { class Block {
protected: protected:
/** @cond internal */
unsigned char *data_; unsigned char *data_;
size_t size_; size_t size_;
/** @endcond */
public: public:
/** Null initialization */ /** Null initialization */
...@@ -219,13 +205,13 @@ public: ...@@ -219,13 +205,13 @@ public:
return Block(data()+off, length); return Block(data()+off, length);
} }
/* Content-wise comparison; constant-time if they are the same length. */ /** Content-wise comparison; constant-time if they are the same length. */