@@ -61,6 +61,14 @@ void API_NS(private_to_public) ( | |||
memcpy(pub, priv->pub, sizeof(API_NS(public_key_t))); | |||
} | |||
/* Performance vs consttime tuning. | |||
* Specifying true here might give better DOS resistance in certain corner | |||
* cases. Specifying false gives a tighter result in test_ct. | |||
*/ | |||
#ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT | |||
#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE | |||
#endif | |||
decaf_error_t | |||
API_NS(shared_secret) ( | |||
uint8_t *shared, | |||
@@ -82,7 +90,8 @@ API_NS(shared_secret) ( | |||
strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t))); | |||
} | |||
decaf_error_t ret = API_NS(direct_scalarmul)( | |||
ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, DECAF_TRUE | |||
ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, | |||
DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT | |||
); | |||
strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY); | |||
@@ -161,6 +161,16 @@ public: | |||
} | |||
return ret; | |||
} | |||
/** Derive a shared secret */ | |||
inline decaf_error_t __attribute__((warn_unused_result)) | |||
sharedSecretNoexcept( | |||
Buffer ret, | |||
const PublicKey<%(cxx_ns)s> &pub, | |||
bool me_first | |||
) const NOEXCEPT { | |||
return %(c_ns)s_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first); | |||
} | |||
/** Sign a message. */ | |||
inline SecureBuffer sign(const Block &message) const { | |||
@@ -88,7 +88,7 @@ public: | |||
/** Construct from RNG */ | |||
inline explicit Scalar(Rng &rng) NOEXCEPT { | |||
FixedArrayBuffer<SER_BYTES> sb(rng); | |||
FixedArrayBuffer<SER_BYTES + 16> sb(rng); | |||
*this = sb; | |||
} | |||
@@ -445,9 +445,8 @@ public: | |||
if (buf.size() < HASH_BYTES) { | |||
ret &= decaf_memeq(&buf2[buf.size()], &buf2[HASH_BYTES], HASH_BYTES - buf.size()); | |||
} | |||
if (ret) { | |||
/* TODO: make this constant time?? */ | |||
memcpy(buf.data(),buf2,(buf.size() < HASH_BYTES) ? buf.size() : HASH_BYTES); | |||
for (size_t i=0; i<buf.size() && i<HASH_BYTES; i++) { | |||
buf[i] = (buf[i] & ~ret) | (buf2[i] &ret); | |||
} | |||
decaf_bzero(buf2,sizeof(buf2)); | |||
return decaf_succeed_if(ret); | |||
@@ -55,11 +55,13 @@ static void test_arithmetic() { | |||
static void test_elligator() { | |||
SpongeRng rng(Block("test_elligator")); | |||
rng.stir(undef_block); | |||
FixedArrayBuffer<Group::Point::HASH_BYTES> inv; | |||
for (int i=0; i<NTESTS; i++) { | |||
Point x(rng); | |||
(void)x; | |||
/* TODO: uniform, nonuniform... */ | |||
Point x(rng), y(rng,false); | |||
ignore((x+y).invert_elligator(inv,i)); | |||
} | |||
} | |||
@@ -82,7 +84,7 @@ static void test_ec() { | |||
(void)(p.times_two()); | |||
(void)(p==q); | |||
(void)(p.debugging_torque()); | |||
//(void)(p.non_secret_combo_with_base(y,z)); // Should fail | |||
/* (void)(p.non_secret_combo_with_base(y,z)); */ /* Should fail */ | |||
(void)(Precomputed(p)*y); | |||
p.dual_scalarmul(q,r,y,z); | |||
Group::Point::double_scalarmul(p,y,q,z); | |||
@@ -90,17 +92,32 @@ static void test_ec() { | |||
} | |||
} | |||
/* Specify the same value as you did when compiling decaf_crypto.c */ | |||
#ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT | |||
#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE | |||
#endif | |||
static void test_crypto() { | |||
SpongeRng rng(Block("test_crypto")); | |||
rng.stir(undef_block); | |||
#if DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT | |||
SpongeRng defrng(Block("test_crypto_defined")); | |||
#endif | |||
FixedArrayBuffer<Group::Point::SER_BYTES> shared; | |||
for (int i=0; i<NTESTS; i++) { | |||
PrivateKey<Group> sk1(rng); | |||
PrivateKey<Group> sk2(rng); | |||
SecureBuffer sig = sk1.sign(undef_block); | |||
//sk.pub().verify(undef_block,sig); would fail. FUTURE: ct version of this? | |||
/* TODO: shared_secret nothrow? have to test shared_secret... */ | |||
#if DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT | |||
PrivateKey<Group> sk2(defrng); | |||
(void)sk1.sharedSecretNoexcept(shared,sk2.pub(),i&1); | |||
#else | |||
PrivateKey<Group> sk3(rng); | |||
(void)sk1.sharedSecretNoexcept(shared,sk3.pub(),i&1); | |||
#endif | |||
} | |||
} | |||