Browse Source

beginning to separate errors from bools. not there yet though

master
Michael Hamburg 10 years ago
parent
commit
a1f5348e18
12 changed files with 109 additions and 82 deletions
  1. +13
    -12
      src/decaf_crypto.c
  2. +17
    -15
      src/decaf_fast.c
  3. +1
    -1
      src/decaf_gen_tables.c
  4. +0
    -1
      src/include/word.h
  5. +22
    -3
      src/public_include/decaf/common.h
  6. +9
    -3
      src/public_include/decaf/crypto.h
  7. +6
    -5
      src/public_include/decaf/crypto.hxx
  8. +6
    -6
      src/public_include/decaf/decaf_255.h
  9. +12
    -12
      src/public_include/decaf/decaf_255.hxx
  10. +6
    -6
      src/public_include/decaf/decaf_448.h
  11. +12
    -13
      src/public_include/decaf/decaf_448.hxx
  12. +5
    -5
      test/test_decaf.cxx

+ 13
- 12
src/decaf_crypto.c View File

@@ -51,7 +51,7 @@ void decaf_255_private_to_public (
memcpy(pub, priv->pub, sizeof(decaf_255_public_key_t));
}

decaf_bool_t
decaf_error_t
decaf_255_shared_secret (
uint8_t *shared,
size_t shared_bytes,
@@ -92,15 +92,16 @@ decaf_255_shared_secret (
}
shake256_update(sponge, ss_ser, sizeof(ss_ser));
decaf_bool_t ret = decaf_255_direct_scalarmul(ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, DECAF_TRUE);
decaf_error_t ret = decaf_255_direct_scalarmul(ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, DECAF_TRUE);
decaf_bool_t good = decaf_successful(ret);
/* If invalid, then replace ... */
for (i=0; i<sizeof(ss_ser); i++) {
ss_ser[i] &= ret;
ss_ser[i] &= good;
if (i < sizeof(my_privkey->sym)) {
ss_ser[i] |= my_privkey->sym[i] & ~ret;
ss_ser[i] |= my_privkey->sym[i] & ~good;
} else if (i - sizeof(my_privkey->sym) < strlen(nope)) {
ss_ser[i] |= nope[i-sizeof(my_privkey->sym)] & ~ret;
ss_ser[i] |= nope[i-sizeof(my_privkey->sym)] & ~good;
}
}

@@ -159,7 +160,7 @@ decaf_255_sign_shake (
decaf_bzero(encoded,sizeof(encoded));
}

decaf_bool_t
decaf_error_t
decaf_255_verify_shake (
const decaf_255_signature_t sig,
const decaf_255_public_key_t pub,
@@ -181,9 +182,9 @@ decaf_255_verify_shake (
decaf_255_scalar_decode_long(challenge, overkill, sizeof(overkill));

/* Decode points. */
ret = decaf_255_point_decode(point, sig, DECAF_TRUE);
ret &= decaf_255_point_decode(pubpoint, pub, DECAF_FALSE);
ret &= decaf_255_scalar_decode(response, &sig[DECAF_255_SER_BYTES]);
ret = decaf_successful(decaf_255_point_decode(point, sig, DECAF_TRUE));
ret &= decaf_successful(decaf_255_point_decode(pubpoint, pub, DECAF_FALSE));
ret &= decaf_successful(decaf_255_scalar_decode(response, &sig[DECAF_255_SER_BYTES]));

decaf_255_base_double_scalarmul_non_secret (
pubpoint, response, pubpoint, challenge
@@ -191,7 +192,7 @@ decaf_255_verify_shake (

ret &= decaf_255_point_eq(pubpoint, point);
return ret;
return decaf_succeed_if(ret);
}

void
@@ -208,7 +209,7 @@ decaf_255_sign (
shake256_destroy(ctx);
}

decaf_bool_t
decaf_error_t
decaf_255_verify (
const decaf_255_signature_t sig,
const decaf_255_public_key_t pub,
@@ -218,7 +219,7 @@ decaf_255_verify (
shake256_ctx_t ctx;
shake256_init(ctx);
shake256_update(ctx, message, message_len);
decaf_bool_t ret = decaf_255_verify_shake(sig, pub, ctx);
decaf_error_t ret = decaf_255_verify_shake(sig, pub, ctx);
shake256_destroy(ctx);
return ret;
}

+ 17
- 15
src/decaf_fast.c View File

@@ -261,7 +261,7 @@ static INLINE void sc_montsqr (scalar_t out, const scalar_t a) {
sc_montmul(out,a,a);
}

decaf_bool_t API_NS(scalar_invert) (
decaf_error_t API_NS(scalar_invert) (
scalar_t out,
const scalar_t a
) {
@@ -318,7 +318,7 @@ decaf_bool_t API_NS(scalar_invert) (
/* Demontgomerize */
sc_montmul(out,out,API_NS(scalar_one));
decaf_bzero(precmp, sizeof(precmp));
return ~API_NS(scalar_eq)(out,API_NS(scalar_zero));
return decaf_succeed_if(~API_NS(scalar_eq)(out,API_NS(scalar_zero)));
}

void API_NS(scalar_sub) (
@@ -510,13 +510,14 @@ static decaf_bool_t gf_deser(gf s, const unsigned char ser[SER_BYTES]) {
return gf_deserialize((gf_s *)s, ser);
}

decaf_bool_t API_NS(point_decode) (
decaf_error_t API_NS(point_decode) (
point_t p,
const unsigned char ser[SER_BYTES],
decaf_bool_t allow_identity
) {
gf s, a, b, c, d, e, f;
decaf_bool_t succ = gf_deser(s, ser), zero = gf_eq(s, ZERO);
allow_identity = ~word_is_zero(allow_identity);
succ &= allow_identity | ~zero;
succ &= ~hibit(s);
gf_sqr ( a, s );
@@ -566,7 +567,7 @@ decaf_bool_t API_NS(point_decode) (
assert(API_NS(point_valid)(p) | ~succ);
return succ;
return decaf_succeed_if(succ);
}

#if IMAGINE_TWIST
@@ -700,7 +701,7 @@ scalar_decode_short (
}
}

decaf_bool_t API_NS(scalar_decode)(
decaf_error_t API_NS(scalar_decode)(
scalar_t s,
const unsigned char ser[SER_BYTES]
) {
@@ -710,10 +711,11 @@ decaf_bool_t API_NS(scalar_decode)(
for (i=0; i<SCALAR_LIMBS; i++) {
accum = (accum + s->limb[i] - sc_p->limb[i]) >> WBITS;
}
/* Here accum == 0 or -1 */
API_NS(scalar_mul)(s,s,API_NS(scalar_one)); /* ham-handed reduce */
return accum;
return decaf_succeed_if(accum);
}

void API_NS(scalar_destroy) (
@@ -1170,7 +1172,7 @@ void API_NS(point_from_hash_nonuniform) (
assert(API_NS(point_valid)(p));
}

decaf_bool_t
decaf_error_t
API_NS(invert_elligator_nonuniform) (
unsigned char recovered_hash[SER_BYTES],
const point_t p,
@@ -1218,7 +1220,7 @@ API_NS(invert_elligator_nonuniform) (
gf_encode(recovered_hash, b);
/* TODO: deal with overflow flag */
return succ;
return decaf_succeed_if(succ);
}

void API_NS(point_from_hash_uniform) (
@@ -1231,7 +1233,7 @@ void API_NS(point_from_hash_uniform) (
API_NS(point_add)(pt,pt,pt2);
}

decaf_bool_t
decaf_error_t
API_NS(invert_elligator_uniform) (
unsigned char partial_hash[2*SER_BYTES],
const point_t p,
@@ -1481,7 +1483,7 @@ void API_NS(point_cond_sel) (
const point_t b,
decaf_bool_t pick_b
) {
pick_b = ~(((decaf_dword_t)pick_b - 1) >> WBITS);
pick_b = ~word_is_zero(pick_b);
constant_time_select(out,b,a,sizeof(point_t),pick_b);
}

@@ -1491,12 +1493,12 @@ void API_NS(scalar_cond_sel) (
const scalar_t b,
decaf_bool_t pick_b
) {
pick_b = ~(((decaf_dword_t)pick_b - 1) >> WBITS);
pick_b = ~word_is_zero(pick_b);
constant_time_select(out,b,a,sizeof(scalar_t),pick_b);
}

/* TODO: restore Curve25519 Montgomery ladder? */
decaf_bool_t API_NS(direct_scalarmul) (
decaf_error_t API_NS(direct_scalarmul) (
uint8_t scaled[SER_BYTES],
const uint8_t base[SER_BYTES],
const scalar_t scalar,
@@ -1504,13 +1506,13 @@ decaf_bool_t API_NS(direct_scalarmul) (
decaf_bool_t short_circuit
) {
point_t basep;
decaf_bool_t succ = API_NS(point_decode)(basep, base, allow_identity);
if (short_circuit & ~succ) return succ;
decaf_bool_t succ = decaf_successful(API_NS(point_decode)(basep, base, allow_identity));
if (short_circuit && ~succ) return DECAF_FAILURE;
API_NS(point_cond_sel)(basep, API_NS(point_base), basep, succ);
API_NS(point_scalarmul)(basep, basep, scalar);
API_NS(point_encode)(scaled, basep);
API_NS(point_destroy)(basep);
return succ;
return decaf_succeed_if(succ);
}

/**


+ 1
- 1
src/decaf_gen_tables.c View File

@@ -75,7 +75,7 @@ int main(int argc, char **argv) {
API_NS(point_t) real_point_base;
int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0);
if (!ret) return 1;
if (ret != DECAF_SUCCESS) return 1;
API_NS(precomputed_s) *pre;
ret = posix_memalign((void**)&pre, API_NS2(alignof,precomputed_s), API_NS2(sizeof,precomputed_s));


+ 0
- 1
src/include/word.h View File

@@ -73,7 +73,6 @@
#define UNUSED __attribute__((unused))
#define INLINE __inline__ __attribute__((always_inline))


#ifdef __ARM_NEON__
typedef uint32x4_t vecmask_t;
#elif __clang__


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

@@ -51,9 +51,28 @@ extern "C" {
/** DECAF_TRUE = -1 so that DECAF_TRUE & x = x */
static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1, DECAF_FALSE = 0;

/** NB Success is -1, failure is 0. */
static const decaf_bool_t DECAF_SUCCESS = -(decaf_bool_t)1 /*DECAF_TRUE*/,
DECAF_FAILURE = 0 /*DECAF_FALSE*/;
/* Success or failure */
// FIXME: deploy project-wide
typedef enum {
DECAF_SUCCESS = -1,
DECAF_FAILURE = 0
} decaf_error_t;


/** Return success if x is true */
static __inline__ __attribute__((unused,always_inline))
decaf_error_t
decaf_succeed_if(decaf_bool_t x) {
return (decaf_error_t)x;
}

/** Return DECAF_TRUE iff x == DECAF_SUCCESS */
static __inline__ __attribute__((unused,always_inline))
decaf_bool_t
decaf_successful(decaf_error_t e) {
decaf_dword_t w = ((decaf_word_t)e) ^ ((decaf_word_t)DECAF_SUCCESS);
return (w-1)>>DECAF_WORD_BITS;
}
/**
* @brief Overwrite data with zeros. Uses memset_s if available.


+ 9
- 3
src/public_include/decaf/crypto.h View File

@@ -103,7 +103,7 @@ void decaf_255_private_to_public (
* @warning This is a pretty silly shared secret computation
* and will almost definitely change in the future.
*/
decaf_bool_t
decaf_error_t
decaf_255_shared_secret (
uint8_t *shared,
size_t shared_bytes,
@@ -147,8 +147,11 @@ decaf_255_sign (
* @param [in] sig The signature.
* @param [in] pub The public key.
* @param [in] shake A SHAKE256 context with the message.
*
* @return DECAF_SUCCESS The signature verified successfully.
* @return DECAF_FAILURE The signature did not verify successfully.
*/
decaf_bool_t
decaf_error_t
decaf_255_verify_shake (
const decaf_255_signature_t sig,
const decaf_255_public_key_t pub,
@@ -162,8 +165,11 @@ decaf_255_verify_shake (
* @param [in] pub The public key.
* @param [in] message The message.
* @param [in] message_len The message's length.
*
* @return DECAF_SUCCESS The signature verified successfully.
* @return DECAF_FAILURE The signature did not verify successfully.
*/
decaf_bool_t
decaf_error_t
decaf_255_verify (
const decaf_255_signature_t sig,
const decaf_255_public_key_t pub,


+ 6
- 5
src/public_include/decaf/crypto.hxx View File

@@ -64,14 +64,14 @@ public:
}
/** @brief Verify a sig. TODO: nothrow version? */
inline bool verify_shake(const SHAKE<SHAKE_BITS> &ctx_, const FixedBlock<SIG_BYTES> &sig) throw(CryptoException) {
inline void verify_shake(const SHAKE<SHAKE_BITS> &ctx_, const FixedBlock<SIG_BYTES> &sig) throw(CryptoException) {
SHAKE<SHAKE_BITS> ctx(ctx_);
ctx << ser << sig.slice(0,Group::Point::SER_BYTES);
FixedArrayBuffer<CHALLENGE_BYTES> challenge;
ctx.output(challenge);
typename Group::Scalar response;
decaf_bool_t scalar_OK = Group::Scalar::decode(
decaf_error_t scalar_OK = Group::Scalar::decode(
response,
sig.slice(Group::Point::SER_BYTES, Group::Scalar::SER_BYTES)
);
@@ -79,9 +79,10 @@ public:
const typename Group::Point combo = point().non_secret_combo_with_base(
typename Group::Scalar(challenge), response
);
//if (combo != typename Group::Point(sig.slice(0,Group::Point::SER_BYTES)))
// throw CryptoException();
return scalar_OK & (combo == typename Group::Point(sig.slice(0,Group::Point::SER_BYTES)));
if (!decaf_successful(scalar_OK)
|| combo != typename Group::Point(sig.slice(0,Group::Point::SER_BYTES)))
throw CryptoException();
//return scalar_OK & (combo == typename Group::Point(sig.slice(0,Group::Point::SER_BYTES)));
}
/** @brief Sign from a message. */


+ 6
- 6
src/public_include/decaf/decaf_255.h View File

@@ -80,7 +80,7 @@ extern const struct decaf_255_precomputed_s *decaf_255_precomputed_base API_VIS;
* @retval DECAF_FAILURE The scalar was greater than the modulus,
* and has been reduced modulo that modulus.
*/
decaf_bool_t decaf_255_scalar_decode (
decaf_error_t decaf_255_scalar_decode (
decaf_255_scalar_t out,
const unsigned char ser[DECAF_255_SCALAR_BYTES]
) API_VIS WARN_UNUSED NONNULL2 NOINLINE;
@@ -164,7 +164,7 @@ void decaf_255_scalar_mul (
* @param [out] out 1/a.
* @return DECAF_SUCCESS The input is nonzero.
*/
decaf_bool_t decaf_255_scalar_invert (
decaf_error_t decaf_255_scalar_invert (
decaf_255_scalar_t out,
const decaf_255_scalar_t a
) API_VIS WARN_UNUSED NONNULL2 NOINLINE;
@@ -217,7 +217,7 @@ void decaf_255_point_encode (
* @retval DECAF_FAILURE The decoding didn't succeed, because
* ser does not represent a point.
*/
decaf_bool_t decaf_255_point_decode (
decaf_error_t decaf_255_point_decode (
decaf_255_point_t pt,
const uint8_t ser[DECAF_255_SER_BYTES],
decaf_bool_t allow_identity
@@ -335,7 +335,7 @@ void decaf_255_point_scalarmul (
* @retval DECAF_FAILURE The scalarmul didn't succeed, because
* base does not represent a point.
*/
decaf_bool_t decaf_255_direct_scalarmul (
decaf_error_t decaf_255_direct_scalarmul (
uint8_t scaled[DECAF_255_SER_BYTES],
const uint8_t base[DECAF_255_SER_BYTES],
const decaf_255_scalar_t scalar,
@@ -552,7 +552,7 @@ void decaf_255_point_from_hash_uniform (
* @retval DECAF_SUCCESS The inverse succeeded.
* @retval DECAF_FAILURE The inverse failed.
*/
decaf_bool_t
decaf_error_t
decaf_255_invert_elligator_nonuniform (
unsigned char recovered_hash[DECAF_255_SER_BYTES],
const decaf_255_point_t pt,
@@ -577,7 +577,7 @@ decaf_255_invert_elligator_nonuniform (
* @retval DECAF_SUCCESS The inverse succeeded.
* @retval DECAF_FAILURE The inverse failed.
*/
decaf_bool_t
decaf_error_t
decaf_255_invert_elligator_uniform (
unsigned char recovered_hash[2*DECAF_255_SER_BYTES],
const decaf_255_point_t pt,


+ 12
- 12
src/public_include/decaf/decaf_255.hxx View File

@@ -139,7 +139,7 @@ public:
* @brief Decode from correct-length little-endian byte sequence.
* @return DECAF_FAILURE if the scalar is greater than or equal to the group order q.
*/
static inline decaf_bool_t __attribute__((warn_unused_result)) decode (
static inline decaf_error_t __attribute__((warn_unused_result)) decode (
Scalar &sc, const FixedBlock<SER_BYTES> buffer
) NOEXCEPT {
return decaf_255_scalar_decode(sc.s,buffer.data());
@@ -268,7 +268,7 @@ public:
* @return DECAF_FAILURE the string was the wrong length, or wasn't the encoding of a point,
* or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined.
*/
static inline decaf_bool_t __attribute__((warn_unused_result)) decode (
static inline decaf_error_t __attribute__((warn_unused_result)) decode (
Point &p, const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE
) NOEXCEPT {
return decaf_255_point_decode(p.p,buffer.data(),allow_identity);
@@ -354,7 +354,7 @@ public:
inline Point &operator/=(const Scalar &s) throw(CryptoException) { return (*this) *= s.inverse(); }
/** @brief Validate / sanity check */
inline bool validate() const NOEXCEPT { return DECAF_SUCCESS == decaf_255_point_valid(p); }
inline bool validate() const NOEXCEPT { return decaf_255_point_valid(p); }
/** @brief Double-scalar multiply, equivalent to q*qs + r*rs but faster. */
static inline Point double_scalarmul (
@@ -398,10 +398,10 @@ public:
}
/**
* Modify buffer so that Point::from_hash(Buffer) == *this, and return true;
* or leave buf unmodified and return false.
* Modify buffer so that Point::from_hash(Buffer) == *this, and return DECAF_SUCCESS;
* or leave buf unmodified and return DECAF_FAILURE.
*/
inline bool invert_elligator (
inline decaf_error_t invert_elligator (
Buffer buf, uint16_t hint
) const NOEXCEPT {
unsigned char buf2[2*HASH_BYTES];
@@ -409,30 +409,30 @@ public:
memcpy(buf2,buf.data(),(buf.size() > 2*HASH_BYTES) ? 2*HASH_BYTES : buf.size());
decaf_bool_t ret;
if (buf.size() > HASH_BYTES) {
ret = decaf_255_invert_elligator_uniform(buf2, p, hint);
ret = decaf_successful(decaf_255_invert_elligator_uniform(buf2, p, hint));
} else {
ret = decaf_255_invert_elligator_nonuniform(buf2, p, hint);
ret = decaf_successful(decaf_255_invert_elligator_nonuniform(buf2, p, hint));
}
if (buf.size() < HASH_BYTES) {
ret &= decaf_memeq(&buf2[buf.size()], &buf2[HASH_BYTES], HASH_BYTES - buf.size());
}
if (DECAF_SUCCESS == ret) {
if (ret) {
/* TODO: make this constant time?? */
memcpy(buf.data(),buf2,(buf.size() < HASH_BYTES) ? buf.size() : HASH_BYTES);
}
decaf_bzero(buf2,sizeof(buf2));
return DECAF_SUCCESS == ret;
return decaf_succeed_if(ret);
}
/** @brief Steganographically encode this */
inline SecureBuffer steg_encode(Rng &rng, size_t size=STEG_BYTES) const throw(std::bad_alloc, LengthException) {
if (size <= HASH_BYTES + 4 || size > 2*HASH_BYTES) throw LengthException();
SecureBuffer out(STEG_BYTES);
bool done;
decaf_error_t done;
do {
rng.read(Buffer(out).slice(HASH_BYTES-1,STEG_BYTES-HASH_BYTES+1));
done = invert_elligator(out, out[HASH_BYTES-1]);
} while (!done);
} while (!decaf_successful(done));
return out;
}


+ 6
- 6
src/public_include/decaf/decaf_448.h View File

@@ -80,7 +80,7 @@ extern const struct decaf_448_precomputed_s *decaf_448_precomputed_base API_VIS;
* @retval DECAF_FAILURE The scalar was greater than the modulus,
* and has been reduced modulo that modulus.
*/
decaf_bool_t decaf_448_scalar_decode (
decaf_error_t decaf_448_scalar_decode (
decaf_448_scalar_t out,
const unsigned char ser[DECAF_448_SCALAR_BYTES]
) API_VIS WARN_UNUSED NONNULL2 NOINLINE;
@@ -164,7 +164,7 @@ void decaf_448_scalar_mul (
* @param [out] out 1/a.
* @return DECAF_TRUE The input is nonzero.
*/
decaf_bool_t decaf_448_scalar_invert (
decaf_error_t decaf_448_scalar_invert (
decaf_448_scalar_t out,
const decaf_448_scalar_t a
) API_VIS WARN_UNUSED NONNULL2 NOINLINE;
@@ -217,7 +217,7 @@ void decaf_448_point_encode (
* @retval DECAF_FAILURE The decoding didn't succeed, because
* ser does not represent a point.
*/
decaf_bool_t decaf_448_point_decode (
decaf_error_t decaf_448_point_decode (
decaf_448_point_t pt,
const uint8_t ser[DECAF_448_SER_BYTES],
decaf_bool_t allow_identity
@@ -335,7 +335,7 @@ void decaf_448_point_scalarmul (
* @retval DECAF_FAILURE The scalarmul didn't succeed, because
* base does not represent a point.
*/
decaf_bool_t decaf_448_direct_scalarmul (
decaf_error_t decaf_448_direct_scalarmul (
uint8_t scaled[DECAF_448_SER_BYTES],
const uint8_t base[DECAF_448_SER_BYTES],
const decaf_448_scalar_t scalar,
@@ -552,7 +552,7 @@ void decaf_448_point_from_hash_uniform (
* @retval DECAF_SUCCESS The inverse succeeded.
* @retval DECAF_FAILURE The inverse failed.
*/
decaf_bool_t
decaf_error_t
decaf_448_invert_elligator_nonuniform (
unsigned char recovered_hash[DECAF_448_SER_BYTES],
const decaf_448_point_t pt,
@@ -577,7 +577,7 @@ decaf_448_invert_elligator_nonuniform (
* @retval DECAF_SUCCESS The inverse succeeded.
* @retval DECAF_FAILURE The inverse failed.
*/
decaf_bool_t
decaf_error_t
decaf_448_invert_elligator_uniform (
unsigned char recovered_hash[2*DECAF_448_SER_BYTES],
const decaf_448_point_t pt,


+ 12
- 13
src/public_include/decaf/decaf_448.hxx View File

@@ -130,7 +130,7 @@ public:
* @brief Decode from correct-length little-endian byte sequence.
* @return DECAF_FAILURE if the scalar is greater than or equal to the group order q.
*/
static inline decaf_bool_t __attribute__((warn_unused_result)) decode (
static inline decaf_error_t __attribute__((warn_unused_result)) decode (
Scalar &sc, const FixedBlock<SER_BYTES> buffer
) NOEXCEPT {
return decaf_448_scalar_decode(sc.s,buffer.data());
@@ -271,7 +271,7 @@ public:
* @return DECAF_FAILURE the string was the wrong length, or wasn't the encoding of a point,
* or was the identity and allow_identity was DECAF_FALSE. Contents of the buffer are undefined.
*/
static inline decaf_bool_t __attribute__((warn_unused_result)) decode (
static inline decaf_error_t __attribute__((warn_unused_result)) decode (
Point &p, const FixedBlock<SER_BYTES> &buffer, decaf_bool_t allow_identity=DECAF_TRUE
) NOEXCEPT {
return decaf_448_point_decode(p.p,buffer.data(),allow_identity);
@@ -366,7 +366,7 @@ public:
inline Point &operator/=(const Scalar &s) throw(CryptoException) { return (*this) *= s.inverse(); }
/** @brief Validate / sanity check */
inline bool validate() const NOEXCEPT { return DECAF_SUCCESS == decaf_448_point_valid(p); }
inline bool validate() const NOEXCEPT { return decaf_448_point_valid(p); }
/** @brief Double-scalar multiply, equivalent to q*qs + r*rs but faster. */
static inline Point double_scalarmul (
@@ -415,10 +415,10 @@ public:
}
/**
* Modify buffer so that Point::from_hash(Buffer) == *this, and return true;
* or leave buf unmodified and return false.
* Modify buffer so that Point::from_hash(Buffer) == *this, and return DECAF_SUCCESS;
* or leave buf unmodified and return DECAF_FAILURE.
*/
inline bool invert_elligator (
inline decaf_error_t invert_elligator (
Buffer buf, uint16_t hint
) const NOEXCEPT {
unsigned char buf2[2*HASH_BYTES];
@@ -426,30 +426,29 @@ public:
memcpy(buf2,buf.data(),(buf.size() > 2*HASH_BYTES) ? 2*HASH_BYTES : buf.size());
decaf_bool_t ret;
if (buf.size() > HASH_BYTES) {
ret = decaf_448_invert_elligator_uniform(buf2, p, hint);
ret = decaf_successful(decaf_448_invert_elligator_uniform(buf2, p, hint));
} else {
ret = decaf_448_invert_elligator_nonuniform(buf2, p, hint);
ret = decaf_successful(decaf_448_invert_elligator_nonuniform(buf2, p, hint));
}
if (buf.size() < HASH_BYTES) {
// FIXME: this &= will fail if success becomes 0
ret &= decaf_memeq(&buf2[buf.size()], &buf2[HASH_BYTES], HASH_BYTES - buf.size());
}
if (DECAF_SUCCESS == ret) {
if (ret) {
/* TODO: make this constant time?? */
memcpy(buf.data(),buf2,(buf.size() < HASH_BYTES) ? buf.size() : HASH_BYTES);
}
decaf_bzero(buf2,sizeof(buf2));
return (ret == DECAF_SUCCESS);
return decaf_succeed_if(ret);
}
/** @brief Steganographically encode this */
inline SecureBuffer steg_encode(Rng &rng) const throw(std::bad_alloc) {
SecureBuffer out(STEG_BYTES);
bool done;
decaf_error_t done;
do {
rng.read(Buffer(out).slice(HASH_BYTES-1,STEG_BYTES-HASH_BYTES+1));
done = invert_elligator(out, out[HASH_BYTES-1]);
} while (!done);
} while (!decaf_successful(done));
return out;
}


+ 5
- 5
test/test_decaf.cxx View File

@@ -201,8 +201,8 @@ static void test_elligator() {
if (len > Point::HASH_BYTES)
memcpy(&(*alts2[j])[Point::HASH_BYTES], &b1[Point::HASH_BYTES], len-Point::HASH_BYTES);
successes[j] = s.invert_elligator(*alts[j], j);
successes2[j] = ss.invert_elligator(*alts2[j],j);
successes[j] = decaf_successful( s.invert_elligator(*alts[j], j));
successes2[j] = decaf_successful(ss.invert_elligator(*alts2[j],j));
if (successes[j] != successes2[j]
|| (successes[j] && successes2[j] && *alts[j] != *alts2[j])
@@ -353,17 +353,17 @@ static void test_decaf() {
decaf_255_private_to_public(p1,s1);
decaf_255_derive_private_key(s2,proto2);
decaf_255_private_to_public(p2,s2);
if (!decaf_255_shared_secret (shared1,sizeof(shared1),s1,p2)) {
if (DECAF_SUCCESS != decaf_255_shared_secret (shared1,sizeof(shared1),s1,p2)) {
test.fail(); printf("Fail ss12\n");
}
if (!decaf_255_shared_secret (shared2,sizeof(shared2),s2,p1)) {
if (DECAF_SUCCESS != decaf_255_shared_secret (shared2,sizeof(shared2),s2,p1)) {
test.fail(); printf("Fail ss21\n");
}
if (memcmp(shared1,shared2,sizeof(shared1))) {
test.fail(); printf("Fail ss21 == ss12\n");
}
decaf_255_sign (sig,s1,(const unsigned char *)message,strlen(message));
if (!decaf_255_verify (sig,p1,(const unsigned char *)message,strlen(message))) {
if (DECAF_SUCCESS != decaf_255_verify (sig,p1,(const unsigned char *)message,strlen(message))) {
test.fail(); printf("Fail sig ver\n");
}
}


Loading…
Cancel
Save