From cf26bc48cf5ac9986f7173e4b7897c096aa407d6 Mon Sep 17 00:00:00 2001 From: Mike Hamburg Date: Sat, 28 Mar 2015 15:55:54 -0700 Subject: [PATCH] fix a 32-bit cleanness issue in decaf_fast; allow NOINIT constructors in hxx --- include/decaf.hxx | 71 ++++++++++++++++++++++++++++++++++----------- src/decaf_fast.c | 10 ++++--- test/test_decaf.cxx | 11 +++++-- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/include/decaf.hxx b/include/decaf.hxx index 16978f8..380d345 100644 --- a/include/decaf.hxx +++ b/include/decaf.hxx @@ -60,6 +60,9 @@ void really_bzero(void *data, size_t size); */ template struct decaf; +/** @brief Passed to constructors to avoid (conservative) initialization */ +static const class NOINIT { public: NOINIT(){} } NI; + /** * @brief Ed448-Goldilocks/Decaf instantiation of group. */ @@ -86,6 +89,9 @@ public: /** @brief access to the underlying scalar object */ decaf_448_scalar_t s; + /** @brief Don't initialize. */ + inline Scalar(const NOINIT &) {} + /** @brief Set to an unsigned word */ inline Scalar(const decaf_word_t w) NOEXCEPT { *this = w; } @@ -163,31 +169,31 @@ public: } /** Add. */ - inline Scalar operator+ (const Scalar &q) const NOEXCEPT { Scalar r; decaf_448_scalar_add(r.s,s,q.s); return r; } + inline Scalar operator+ (const Scalar &q) const NOEXCEPT { Scalar r(NI); 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; } + inline Scalar operator- (const Scalar &q) const NOEXCEPT { Scalar r(NI); 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) const NOEXCEPT { Scalar r(NI); decaf_448_scalar_mul(r.s,s,q.s); return r; } /** Multiply into this. */ inline Scalar &operator*=(const Scalar &q) NOEXCEPT { decaf_448_scalar_mul(s,s,q.s); return *this; } /** Negate */ - inline Scalar operator- () const NOEXCEPT { Scalar r; decaf_448_scalar_sub(r.s,decaf_448_scalar_zero,s); return r; } + inline Scalar operator- () const NOEXCEPT { Scalar r(NI); 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; } /** @brief Divide by inverting q. If q == 0, return 0. */ - inline Scalar operator/ (const Scalar &q) const NOEXCEPT { Scalar r; decaf_448_scalar_mul(r.s,s,q.inverse().s); return r; } + inline Scalar operator/ (const Scalar &q) const NOEXCEPT { Scalar r(NI); decaf_448_scalar_mul(r.s,s,q.inverse().s); return r; } /** @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; } @@ -203,6 +209,34 @@ public: /** @brief Scalarmul-precomputed with scalar on left. */ inline Point operator* (const Precomputed &q) const NOEXCEPT { return q * (*this); } + + /** @brief Direct scalar multiplication. + * @todo Fix up bools. + */ + inline decaf_bool_t direct_scalarmul( + unsigned char out[DECAF_448_SER_BYTES], + const unsigned char in[DECAF_448_SER_BYTES], + decaf_bool_t allow_identity=DECAF_FALSE, + decaf_bool_t short_circuit=DECAF_TRUE + ) const NOEXCEPT { + return decaf_448_direct_scalarmul(out, in, s, allow_identity, short_circuit); + } + + /** @brief Direct scalar multiplication. + * @todo Fix up bools. + */ + inline std::string direct_scalarmul( + const std::string in, + decaf_bool_t allow_identity=DECAF_FALSE, + decaf_bool_t short_circuit=DECAF_TRUE + ) const NOEXCEPT { + unsigned char out[DECAF_448_SER_BYTES]; + if (decaf_448_direct_scalarmul(out, GET_DATA(in), s, allow_identity, short_circuit)) { + return std::string((char *)out,sizeof(out)); + } else { + return ""; + } + } }; /** @@ -213,6 +247,9 @@ public: /** The c-level object. */ decaf_448_point_t p; + /** @brief Don't initialize. */ + inline Point(const NOINIT &) {} + /** @brief Constructor sets to identity by default. */ inline Point(const decaf_448_point_t &q = decaf_448_point_identity) { decaf_448_point_copy(p,q); } @@ -280,7 +317,7 @@ public: * The all-zero buffer maps to the identity, as does the buffer {1,0...} */ static inline Point from_hash_nonuniform ( const unsigned char buffer[DECAF_448_SER_BYTES] ) NOEXCEPT { - Point p; decaf_448_point_from_hash_nonuniform(p.p,buffer); return p; + Point p(NI); decaf_448_point_from_hash_nonuniform(p.p,buffer); return p; } /** @@ -291,7 +328,7 @@ public: static inline Point from_hash_nonuniform ( const std::string &s ) NOEXCEPT { std::string t = s; if (t.size() < DECAF_448_SER_BYTES) t.insert(t.size(),DECAF_448_SER_BYTES-t.size(),0); - Point p; decaf_448_point_from_hash_nonuniform(p.p,GET_DATA(t)); return p; + Point p(NI); decaf_448_point_from_hash_nonuniform(p.p,GET_DATA(t)); return p; } @@ -300,7 +337,7 @@ public: * The all-zero buffer maps to the identity, as does the buffer {1,0...}. */ static inline Point from_hash ( const unsigned char buffer[2*DECAF_448_SER_BYTES] ) NOEXCEPT { - Point p; decaf_448_point_from_hash_uniform(p.p,buffer); return p; + Point p(NI); decaf_448_point_from_hash_uniform(p.p,buffer); return p; } /** @@ -313,7 +350,7 @@ public: std::string t = s; if (t.size() <= DECAF_448_SER_BYTES) return from_hash_nonuniform(s); if (t.size() < 2*DECAF_448_SER_BYTES) t.insert(t.size(),2*DECAF_448_SER_BYTES-t.size(),0); - Point p; decaf_448_point_from_hash_uniform(p.p,GET_DATA(t)); return p; + Point p(NI); decaf_448_point_from_hash_uniform(p.p,GET_DATA(t)); return p; } /** @@ -333,22 +370,22 @@ public: } /** @brief Point add. */ - inline Point operator+ (const Point &q) const NOEXCEPT { Point r; decaf_448_point_add(r.p,p,q.p); return r; } + inline Point operator+ (const Point &q) const NOEXCEPT { Point r(NI); decaf_448_point_add(r.p,p,q.p); return r; } /** @brief Point add. */ inline Point &operator+=(const Point &q) NOEXCEPT { decaf_448_point_add(p,p,q.p); return *this; } /** @brief Point subtract. */ - inline Point operator- (const Point &q) const NOEXCEPT { Point r; decaf_448_point_sub(r.p,p,q.p); return r; } + inline Point operator- (const Point &q) const NOEXCEPT { Point r(NI); decaf_448_point_sub(r.p,p,q.p); return r; } /** @brief Point subtract. */ inline Point &operator-=(const Point &q) NOEXCEPT { decaf_448_point_sub(p,p,q.p); return *this; } /** @brief Point negate. */ - inline Point operator- () const NOEXCEPT { Point r; decaf_448_point_negate(r.p,p); return r; } + inline Point operator- () const NOEXCEPT { Point r(NI); decaf_448_point_negate(r.p,p); return r; } /** @brief Double the point out of place. */ - inline Point times_two () const NOEXCEPT { Point r; decaf_448_point_double(r.p,p); return r; } + inline Point times_two () const NOEXCEPT { Point r(NI); decaf_448_point_double(r.p,p); return r; } /** @brief Double the point in place. */ inline Point &double_in_place() NOEXCEPT { decaf_448_point_double(p,p); return *this; } @@ -360,7 +397,7 @@ public: inline bool operator==(const Point &q) const NOEXCEPT { return !!decaf_448_point_eq(p,q.p); } /** @brief Scalar multiply. */ - inline Point operator* (const Scalar &s) const NOEXCEPT { Point r; decaf_448_point_scalarmul(r.p,p,s.s); return r; } + inline Point operator* (const Scalar &s) const NOEXCEPT { Point r(NI); decaf_448_point_scalarmul(r.p,p,s.s); return r; } /** @brief Scalar multiply in place. */ inline Point &operator*=(const Scalar &s) NOEXCEPT { decaf_448_point_scalarmul(p,p,s.s); return *this; } @@ -375,7 +412,7 @@ public: static inline Point double_scalarmul ( const Point &q, const Scalar &qs, const Point &r, const Scalar &rs ) NOEXCEPT { - Point p; decaf_448_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p; + Point p(NI); decaf_448_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p; } /** @@ -385,7 +422,7 @@ public: static inline Point double_scalarmul ( const Scalar &qs, const Point &q, const Scalar &rs, const Point &r ) NOEXCEPT { - Point p; decaf_448_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p; + Point p(NI); decaf_448_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p; } /** @@ -394,7 +431,7 @@ public: * it doesn't). */ inline Point non_secret_combo_with_base(const Scalar &s, const Scalar &s_base) { - Point r; decaf_448_base_double_scalarmul_non_secret(r.p,s_base.s,p,s.s); return r; + Point r(NI); decaf_448_base_double_scalarmul_non_secret(r.p,s_base.s,p,s.s); return r; } /** @brief Return the base point */ diff --git a/src/decaf_fast.c b/src/decaf_fast.c index 42d25d9..6b5ab89 100644 --- a/src/decaf_fast.c +++ b/src/decaf_fast.c @@ -164,6 +164,7 @@ siv gf_sub_nr ( gf_s *__restrict__ c, const gf a, const gf b ) { ANALYZE_THIS_ROUTINE_CAREFULLY; //TODO field_sub_nr((field_t *)c, (const field_t *)a, (const field_t *)b); gf_bias(c, 2); + if (WBITS==32) field_weak_reduce((field_t*) c); // HACK FIXME } /** Subtract mod p. Bias by amt but don't reduce. */ @@ -171,6 +172,7 @@ siv gf_sub_nr_x ( gf c, const gf a, const gf b, int amt ) { ANALYZE_THIS_ROUTINE_CAREFULLY; //TODO field_sub_nr((field_t *)c, (const field_t *)a, (const field_t *)b); gf_bias(c, amt); + if (WBITS==32) field_weak_reduce((field_t*) c); // HACK FIXME } /** Add mod p. Don't reduce. */ @@ -663,7 +665,7 @@ void decaf_bzero ( #else const size_t sw = sizeof(decaf_word_t); volatile uint8_t *destroy = (volatile uint8_t *)s; - for (; size && ((decaf_word_t)destroy)%sw; size--, destroy++) + for (; size && ((uintptr_t)destroy)%sw; size--, destroy++) *destroy = 0; for (; size >= sw; size -= sw, destroy += sw) *(volatile decaf_word_t *)destroy = 0; @@ -845,9 +847,9 @@ extern const decaf_448_scalar_t decaf_448_point_scalarmul_adjustment; siv constant_time_lookup_xx ( void *__restrict__ out_, const void *table_, - word_t elem_bytes, - word_t n_table, - word_t idx + decaf_word_t elem_bytes, + decaf_word_t n_table, + decaf_word_t idx ) { big_register_t big_one = br_set_to_mask(1), big_i = br_set_to_mask(idx); big_register_t *out = (big_register_t *)out_; diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index fcdd43c..8ed6f4d 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -91,13 +91,17 @@ static bool point_check( const Point &R, const Scalar &x, const Scalar &y, - const Point &r, const Point &l, + const Point &r, const char *name ) { if (l == r) return true; test.fail(); printf(" %s", name); + if (!decaf_448_point_valid(p.p)) printf(" p invalid\n"); + if (!decaf_448_point_valid(q.p)) printf(" q invalid\n"); + if (!decaf_448_point_valid(r.p)) printf(" r invalid\n"); + if (!decaf_448_point_valid(l.p)) printf(" l invalid\n"); print("x", x); print("y", y); print("p", p); @@ -190,8 +194,9 @@ static void test_ec() { +Point::from_hash_nonuniform(&buffer[DECAF_448_SCALAR_BYTES]), "unih = hash+add" ); - - // TODO: test hash_u(x+x) == hash_nu(x) + hash_nu(x)??? + + + point_check(test,p,q,r,x,0,Point(x.direct_scalarmul(p)),x*p,"direct mul"); } }