Browse Source

fix a 32-bit cleanness issue in decaf_fast; allow NOINIT constructors in hxx

master
Mike Hamburg 9 years ago
parent
commit
cf26bc48cf
3 changed files with 68 additions and 24 deletions
  1. +54
    -17
      include/decaf.hxx
  2. +6
    -4
      src/decaf_fast.c
  3. +8
    -3
      test/test_decaf.cxx

+ 54
- 17
include/decaf.hxx View File

@@ -60,6 +60,9 @@ void really_bzero(void *data, size_t size);
*/
template<unsigned int bits = 448> 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 */


+ 6
- 4
src/decaf_fast.c View File

@@ -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_;


+ 8
- 3
test/test_decaf.cxx View File

@@ -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");
}
}



Loading…
Cancel
Save