diff --git a/Makefile b/Makefile index 4431fb6..bb5589e 100644 --- a/Makefile +++ b/Makefile @@ -179,7 +179,7 @@ doc/timestamp: touch $@ doc: Doxyfile doc/timestamp include/*.h src/*.c src/include/*.h src/$(FIELD)/$(ARCH)/*.c src/$(FIELD)/$(ARCH)/*.h - doxygen + doxygen > /dev/null bat: $(BATNAME) diff --git a/include/decaf.h b/include/decaf.h index f13bd30..4a2991e 100644 --- a/include/decaf.h +++ b/include/decaf.h @@ -51,28 +51,30 @@ typedef uint64_t decaf_word_t, decaf_bool_t; #define DECAF_WORD_BITS 32 typedef uint32_t decaf_word_t, decaf_bool_t; #endif -/** @endcond */ #define DECAF_448_LIMBS (512/DECAF_WORD_BITS) #define DECAF_448_SCALAR_BITS 446 #define DECAF_448_SCALAR_LIMBS (448/DECAF_WORD_BITS) +/** Galois field element internal structure */ +typedef struct gf_s { + decaf_word_t limb[DECAF_448_LIMBS]; +} __attribute__((aligned(32))) gf_s, gf[1]; +/** @endcond */ + /** Number of bytes in a serialized point. */ #define DECAF_448_SER_BYTES 56 /** Number of bytes in a serialized scalar. */ #define DECAF_448_SCALAR_BYTES 56 -/** Galois field element internal structure */ -typedef struct gf_s { - decaf_word_t limb[DECAF_448_LIMBS]; -} __attribute__((aligned(32))) gf_s, gf[1]; - /** Twisted Edwards (-1,d-1) extended homogeneous coordinates */ -typedef struct decaf_448_point_s { gf x,y,z,t; } decaf_448_point_t[1]; +typedef struct decaf_448_point_s { /**@cond internal*/gf x,y,z,t;/**@endcond*/ } decaf_448_point_t[1]; /** Precomputed table based on a point. Can be trivial implementation. */ struct decaf_448_precomputed_s; + +/** Precomputed table based on a point. Can be trivial implementation. */ typedef struct decaf_448_precomputed_s decaf_448_precomputed_s; /** Size and alignment of precomputed point tables. */ @@ -80,7 +82,9 @@ extern const size_t sizeof_decaf_448_precomputed_s API_VIS, alignof_decaf_448_pr /** Scalar is stored packed, because we don't need the speed. */ typedef struct decaf_448_scalar_s { + /** @cond internal */ decaf_word_t limb[DECAF_448_SCALAR_LIMBS]; + /** @endcond */ } decaf_448_scalar_t[1]; /** DECAF_TRUE = -1 so that DECAF_TRUE & x = x */ @@ -129,7 +133,7 @@ extern "C" { * and has been reduced modulo that modulus. */ decaf_bool_t decaf_448_scalar_decode ( - decaf_448_scalar_t s, + decaf_448_scalar_t out, const unsigned char ser[DECAF_448_SCALAR_BYTES] ) API_VIS WARN_UNUSED NONNULL2 NOINLINE; @@ -142,7 +146,7 @@ decaf_bool_t decaf_448_scalar_decode ( * @param [out] out Deserialized form. */ void decaf_448_scalar_decode_long ( - decaf_448_scalar_t s, + decaf_448_scalar_t out, const unsigned char *ser, size_t ser_len ) API_VIS NONNULL2 NOINLINE; @@ -223,7 +227,6 @@ decaf_bool_t decaf_448_scalar_invert ( * @param [in] a A scalar. * @param [out] out Will become a copy of a. */ - /* PERF: make this memcpy */ static inline void NONNULL2 decaf_448_scalar_copy ( decaf_448_scalar_t out, const decaf_448_scalar_t a @@ -235,11 +238,12 @@ static inline void NONNULL2 decaf_448_scalar_copy ( * @brief Set a scalar to an integer. * @param [in] a An integer. * @param [out] out Will become equal to a. + * @todo Make inline? */ -void decaf_448_scalar_set ( +void decaf_448_scalar_set API_VIS NONNULL1 ( decaf_448_scalar_t out, - decaf_word_t w -) API_VIS NONNULL1; + decaf_word_t a +); /** * @brief Encode a point as a sequence of bytes. @@ -261,6 +265,7 @@ void decaf_448_point_encode ( * * @param [out] pt The decoded point. * @param [in] ser The serialized version of the point. + * @param [in] allow_identity DECAF_TRUE if the identity is a legal input. * @retval DECAF_SUCCESS The decoding succeeded. * @retval DECAF_FAILURE The decoding didn't succeed, because * ser does not represent a point. @@ -318,7 +323,7 @@ void decaf_448_point_add ( * @brief Double a point. Equivalent to * decaf_448_point_add(two_a,a,a), but potentially faster. * - * @param [out] sum The sum a+a. + * @param [out] two_a The sum a+a. * @param [in] a A point. */ void decaf_448_point_double ( @@ -416,7 +421,7 @@ void decaf_448_precompute ( * @param [in] base The point to be scaled. * @param [in] scalar The scalar to multiply by. * - * @TODO: precomputed dsmul? const or variable time? + * @todo precomputed dsmul? const or variable time? */ void decaf_448_precomputed_scalarmul ( decaf_448_point_t scaled, @@ -431,12 +436,11 @@ void decaf_448_precomputed_scalarmul ( * Equivalent to two calls to decaf_448_point_scalarmul, but may be * faster. * - * @param [out] scaled The scaled point base*scalar + * @param [out] combo The linear combination scalar1*base1 + scalar2*base2. * @param [in] base1 A first point to be scaled. * @param [in] scalar1 A first scalar to multiply by. * @param [in] base2 A second point to be scaled. * @param [in] scalar2 A second scalar to multiply by. - * @fixme This function isn't tested! */ void decaf_448_point_double_scalarmul ( decaf_448_point_t combo, @@ -453,7 +457,7 @@ void decaf_448_point_double_scalarmul ( * Otherwise equivalent to decaf_448_point_double_scalarmul, but may be * faster. * - * @param [out] scaled The scaled point base*scalar + * @param [out] combo The linear combination scalar1*base + scalar2*base2. * @param [in] scalar1 A first scalar to multiply by. * @param [in] base2 A second point to be scaled. * @param [in] scalar2 A second scalar to multiply by. @@ -471,7 +475,7 @@ void decaf_448_base_double_scalarmul_non_secret ( /** * @brief Test that a point is valid, for debugging purposes. * - * @param [in] point The number to test. + * @param [in] toTest The number to test. * @retval DECAF_TRUE The point is valid. * @retval DECAF_FALSE The point is invalid. */ diff --git a/include/decaf.hxx b/include/decaf.hxx index 3765692..c06b42f 100644 --- a/include/decaf.hxx +++ b/include/decaf.hxx @@ -22,7 +22,8 @@ #ifndef __DECAF_448_HXX__ #define __DECAF_448_HXX__ 1 -#define _XOPEN_SOURCE 600 /* for posix_memalign */ +/** This code uses posix_memalign. */ +#define _XOPEN_SOURCE 600 #include #include /* for memcpy */ @@ -34,6 +35,7 @@ /* TODO: This is incomplete */ /* TODO: attribute nonnull */ +/** @cond internal */ #if __cplusplus >= 201103L #define NOEXCEPT noexcept #define EXPLICIT_CON explicit @@ -43,6 +45,7 @@ #define EXPLICIT_CON #define GET_DATA(str) ((const unsigned char *)((str).data())) #endif +/** @endcond */ namespace decaf { @@ -82,6 +85,7 @@ class Scalar { public: /** @brief access to the underlying scalar object */ decaf_448_scalar_t s; + /** @brief Set to an unsigned word */ inline Scalar(const decaf_word_t w=0) NOEXCEPT { *this = w; } @@ -123,7 +127,7 @@ public: /** Destructor securely erases the scalar. */ inline ~Scalar() NOEXCEPT { decaf_448_scalar_destroy(s); } - /** @briefAssign from arbitrary-length little-endian byte sequence in C++ string. */ + /** @brief Assign from arbitrary-length little-endian byte sequence in C++ string. */ inline Scalar &operator=(const std::string &str) NOEXCEPT { decaf_448_scalar_decode_long(s,GET_DATA(str),str.length()); return *this; } @@ -158,20 +162,26 @@ public: decaf_448_scalar_encode(buffer, s); } - /* Arithmetic */ + /** Add. */ inline Scalar operator+ (const Scalar &q) const NOEXCEPT { Scalar r; decaf_448_scalar_add(r.s,s,q.s); return r; } + + /** Add to this. */ inline Scalar operator+=(const Scalar &q) NOEXCEPT { decaf_448_scalar_add(s,s,q.s); return *this; } + + /** Subtract. */ inline Scalar operator- (const Scalar &q) const NOEXCEPT { Scalar r; decaf_448_scalar_sub(r.s,s,q.s); return r; } + + /** Subtract from this. */ inline Scalar operator-=(const Scalar &q) NOEXCEPT { decaf_448_scalar_sub(s,s,q.s); return *this; } + + /** Multiply */ inline Scalar operator* (const Scalar &q) const NOEXCEPT { Scalar r; decaf_448_scalar_mul(r.s,s,q.s); return r; } - inline Scalar operator*=(const Scalar &q) NOEXCEPT { decaf_448_scalar_mul(s,s,q.s); return *this; } - inline Scalar operator- () const NOEXCEPT { Scalar r; decaf_448_scalar_sub(r.s,decaf_448_scalar_zero,s); return r; } - /** @brief Compare in constant time */ - inline bool operator!=(const Scalar &q) const NOEXCEPT { return ! decaf_448_scalar_eq(s,q.s); } + /** Multiply into this. */ + inline Scalar operator*=(const Scalar &q) NOEXCEPT { decaf_448_scalar_mul(s,s,q.s); return *this; } - /** @brief Compare in constant time */ - inline bool operator==(const Scalar &q) const NOEXCEPT { return !!decaf_448_scalar_eq(s,q.s); } + /** Negate */ + inline Scalar operator- () const NOEXCEPT { Scalar r; decaf_448_scalar_sub(r.s,decaf_448_scalar_zero,s); return r; } /** @brief Invert with Fermat's Little Theorem (slow!). If *this == 0, return 0. */ inline Scalar inverse() const NOEXCEPT { Scalar r; decaf_448_scalar_invert(r.s,s); return r; } @@ -182,6 +192,12 @@ public: /** @brief Divide by inverting q. If q == 0, return 0. */ inline Scalar operator/=(const Scalar &q) NOEXCEPT { decaf_448_scalar_mul(s,s,q.inverse().s); return *this; } + /** @brief Compare in constant time */ + inline bool operator!=(const Scalar &q) const NOEXCEPT { return ! decaf_448_scalar_eq(s,q.s); } + + /** @brief Compare in constant time */ + inline bool operator==(const Scalar &q) const NOEXCEPT { return !!decaf_448_scalar_eq(s,q.s); } + /** @brief Scalarmul with scalar on left. */ inline Point operator* (const Point &q) const NOEXCEPT { return q * (*this); } @@ -194,6 +210,7 @@ public: */ class Point { public: + /** The c-level object. */ decaf_448_point_t p; /** @brief Constructor sets to identity by default. */ @@ -491,6 +508,8 @@ public: }; /* struct decaf<448> */ #undef NOEXCEPT +#undef EXPLICIT_CON +#undef GET_DATA } /* namespace decaf */ #endif /* __DECAF_448_HXX__ */ diff --git a/include/decaf_crypto.h b/include/decaf_crypto.h index a86bfc7..d63b38c 100644 --- a/include/decaf_crypto.h +++ b/include/decaf_crypto.h @@ -14,7 +14,9 @@ #include "decaf.h" #include "shake.h" +/** Number of bytes for a symmetric key (expanded to full key) */ #define DECAF_448_SYMMETRIC_KEY_BYTES 32 + /** @cond internal */ #define API_VIS __attribute__((visibility("default"))) __attribute__((noinline)) // TODO: synergize with decaf.h #define WARN_UNUSED __attribute__((warn_unused_result)) @@ -34,12 +36,23 @@ typedef unsigned char decaf_448_public_key_t[DECAF_448_SER_BYTES]; /** A signature. */ typedef unsigned char decaf_448_signature_t[DECAF_448_SER_BYTES + DECAF_448_SCALAR_BYTES]; -/** A private key. */ typedef struct { + /** @cond intetrnal */ + /** The symmetric key from which everything is expanded */ decaf_448_symmetric_key_t sym; + + /** The scalar x */ decaf_448_scalar_t secret_scalar; + + /** x*Base */ decaf_448_public_key_t pub; -} decaf_448_private_key_t[1]; + /** @endcond */ +} + /** Private key structure for pointers. */ + decaf_448_private_key_s, + + /** A private key (gmp array[1] style). */ + decaf_448_private_key_t[1]; #ifdef __cplusplus extern "C" { @@ -47,7 +60,7 @@ extern "C" { /** * @brief Derive a key from its compressed form. - * @param [out] privkey 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. */ void decaf_448_derive_private_key ( diff --git a/include/shake.h b/include/shake.h index 056988f..443882e 100644 --- a/include/shake.h +++ b/include/shake.h @@ -16,13 +16,18 @@ #include /* TODO: unify with other headers (maybe all into one??); add nonnull attributes */ +/** @cond internal */ #define API_VIS __attribute__((visibility("default"))) #define WARN_UNUSED __attribute__((warn_unused_result)) +/** @endcond */ /* TODO: different containing structs for each primitive? */ #ifndef INTERNAL_SPONGE_STRUCT + /** Sponge container object for the various primitives. */ typedef struct keccak_sponge_s { + /** @cond internal */ uint64_t opaque[26]; + /** @endcond */ } keccak_sponge_t[1]; struct kparams_s; #endif @@ -59,7 +64,7 @@ void sha3_update ( * sha3 output can be called more times. * * @param [inout] sponge The context. - * @param [out] in The output data. + * @param [out] out The output data. * @param [in] len The requested output data length in bytes. */ void sha3_output ( @@ -94,6 +99,7 @@ void sponge_hash ( /* TODO: expand/doxygenate individual SHAKE/SHA3 instances? */ +/** @cond internal */ #define DECSHAKE(n) \ extern const struct kparams_s SHAKE##n##_params_s API_VIS; \ static inline void shake##n##_init(keccak_sponge_t sponge) { \ @@ -131,6 +137,7 @@ void sponge_hash ( static inline void sha3_##n##_destroy( keccak_sponge_t sponge ) { \ sponge_destroy(sponge); \ } +/** @endcond */ DECSHAKE(128) DECSHAKE(256) @@ -203,7 +210,7 @@ int spongerng_init_from_dev_urandom ( * * @param [inout] sponge The sponge object. * @param [out] out The output buffer. - * @param [in] out The output buffer's length. + * @param [in] len The output buffer's length. */ void spongerng_next ( keccak_sponge_t sponge,