diff --git a/src/decaf_crypto.c b/src/decaf_crypto.c index 3a74ce0..b0e5eef 100644 --- a/src/decaf_crypto.c +++ b/src/decaf_crypto.c @@ -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); diff --git a/src/gen_headers/crypto_hxx.py b/src/gen_headers/crypto_hxx.py index 18fe75c..269b3e8 100644 --- a/src/gen_headers/crypto_hxx.py +++ b/src/gen_headers/crypto_hxx.py @@ -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 { diff --git a/src/gen_headers/decaf_hxx.py b/src/gen_headers/decaf_hxx.py index 22704c1..bea045d 100644 --- a/src/gen_headers/decaf_hxx.py +++ b/src/gen_headers/decaf_hxx.py @@ -88,7 +88,7 @@ public: /** Construct from RNG */ inline explicit Scalar(Rng &rng) NOEXCEPT { - FixedArrayBuffer sb(rng); + FixedArrayBuffer 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 inv; for (int i=0; i shared; for (int i=0; i sk1(rng); - PrivateKey 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 sk2(defrng); + (void)sk1.sharedSecretNoexcept(shared,sk2.pub(),i&1); +#else + PrivateKey sk3(rng); + (void)sk1.sharedSecretNoexcept(shared,sk3.pub(),i&1); +#endif } }