@@ -17,10 +17,8 @@ | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
#define NOEXCEPT noexcept | |||
#define FINAL final | |||
#else | |||
#define NOEXCEPT throw() | |||
#define FINAL | |||
#endif | |||
/** @endcond */ | |||
@@ -31,7 +29,7 @@ namespace decaf { | |||
template <typename Group> class PrivateKey; | |||
/** @brief A public key using a particular EC group */ | |||
template <typename Group> class PublicKey : public Serializable { | |||
template <typename Group> class PublicKey : public Serializable<PublicKey<Group> > { | |||
private: | |||
/** @cond internal */ | |||
friend class PrivateKey<Group>; | |||
@@ -66,17 +64,19 @@ public: | |||
} | |||
/** @brief Verify a sig. TODO: nothrow version? FIXME: doesn't check reduction of scalar! */ | |||
inline void verify_shake(const SHAKE<SHAKE_BITS> &ctx_, const FixedBlock<SIG_BYTES> &sig) throw(CryptoException) { | |||
inline bool 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); | |||
SecureBuffer challenge(ctx.output(CHALLENGE_BYTES)); | |||
FixedArrayBuffer<CHALLENGE_BYTES> challenge; | |||
ctx.output(challenge); | |||
const typename Group::Point combo = point().non_secret_combo_with_base( | |||
typename Group::Scalar(challenge), | |||
sig.slice(Group::Point::SER_BYTES, Group::Scalar::SER_BYTES) | |||
); | |||
if (combo != typename Group::Point(sig.slice(0,Group::Point::SER_BYTES))) | |||
throw CryptoException(); | |||
//if (combo != typename Group::Point(sig.slice(0,Group::Point::SER_BYTES))) | |||
// throw CryptoException(); | |||
return combo == typename Group::Point(sig.slice(0,Group::Point::SER_BYTES)); | |||
} | |||
/** @brief Sign from a message. */ | |||
@@ -87,12 +87,12 @@ public: | |||
} | |||
/** @brief Serialize into a buffer. */ | |||
inline void serializeInto(unsigned char *x) const NOEXCEPT FINAL { | |||
inline void serializeInto(unsigned char *x) const NOEXCEPT { | |||
memcpy(x,ser.data(),Group::Point::SER_BYTES); | |||
} | |||
/** @brief Serialize into a buffer. */ | |||
inline size_t serSize() const NOEXCEPT FINAL { | |||
inline size_t serSize() const NOEXCEPT { | |||
return Group::Point::SER_BYTES; | |||
} | |||
@@ -101,7 +101,7 @@ public: | |||
}; | |||
/** @brief A private key using a particular EC group */ | |||
template <typename Group> class PrivateKey : public Serializable { | |||
template <typename Group> class PrivateKey : public Serializable<PrivateKey<Group> > { | |||
public: | |||
/** Size of associated symmetric key */ | |||
static const size_t SYM_BYTES = 32; | |||
@@ -140,12 +140,12 @@ public: | |||
} | |||
/** @brief Serialize */ | |||
inline size_t serSize() const NOEXCEPT FINAL { | |||
inline size_t serSize() const NOEXCEPT { | |||
return SYM_BYTES; | |||
} | |||
/** @brief Serialize */ | |||
inline void serializeInto(unsigned char *target) const NOEXCEPT FINAL { | |||
inline void serializeInto(unsigned char *target) const NOEXCEPT { | |||
memcpy(target,sym.data(),serSize()); | |||
} | |||
@@ -38,10 +38,8 @@ | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
#define NOEXCEPT noexcept | |||
#define FINAL final | |||
#else | |||
#define NOEXCEPT throw() | |||
#define FINAL | |||
#endif | |||
/** @endcond */ | |||
@@ -68,7 +66,7 @@ class Precomputed; | |||
* Supports the usual arithmetic operations, all in constant time. | |||
* FIXME: make it clearer which init-from-buffer operations reject scalars that are too big. | |||
*/ | |||
class Scalar : public Serializable { | |||
class Scalar : public Serializable<Scalar> { | |||
private: | |||
/** @brief wrapped C type */ | |||
typedef decaf_255_scalar_t Wrapped; | |||
@@ -105,10 +103,10 @@ public: | |||
inline Scalar(const Block &buffer) NOEXCEPT { *this = buffer; } | |||
/** @brief Serializable instance */ | |||
virtual inline size_t serSize() const NOEXCEPT FINAL { return SER_BYTES; } | |||
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } | |||
/** @brief Serializable instance */ | |||
virtual inline void serializeInto(unsigned char *buffer) const NOEXCEPT FINAL { | |||
inline void serializeInto(unsigned char *buffer) const NOEXCEPT { | |||
decaf_255_scalar_encode(buffer, s); | |||
} | |||
@@ -197,7 +195,7 @@ public: | |||
/** | |||
* @brief Element of prime-order group. | |||
*/ | |||
class Point : public Serializable { | |||
class Point : public Serializable<Point> { | |||
public: | |||
typedef decaf_255_point_t Wrapped; | |||
@@ -296,10 +294,10 @@ public: | |||
} | |||
/** @brief Serializable instance */ | |||
virtual inline size_t serSize() const NOEXCEPT FINAL { return SER_BYTES; } | |||
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } | |||
/** @brief Serializable instance */ | |||
virtual inline void serializeInto(unsigned char *buffer) const NOEXCEPT FINAL { | |||
inline void serializeInto(unsigned char *buffer) const NOEXCEPT { | |||
decaf_255_point_encode(buffer, p); | |||
} | |||
@@ -544,7 +542,6 @@ inline SecureBuffer IsoEd25519::Scalar::direct_scalarmul ( | |||
/** endcond */ | |||
#undef NOEXCEPT | |||
#undef FINAL | |||
} /* namespace decaf */ | |||
#endif /* __DECAF_255_HXX__ */ |
@@ -38,10 +38,8 @@ | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
#define NOEXCEPT noexcept | |||
#define FINAL final | |||
#else | |||
#define NOEXCEPT throw() | |||
#define FINAL | |||
#endif | |||
/** @endcond */ | |||
@@ -67,7 +65,7 @@ class Precomputed; | |||
* @brief A scalar modulo the curve order. | |||
* Supports the usual arithmetic operations, all in constant time. | |||
*/ | |||
class Scalar : public Serializable { | |||
class Scalar : public Serializable<Scalar> { | |||
private: | |||
/** @brief wrapped C type */ | |||
typedef decaf_448_scalar_t Wrapped; | |||
@@ -136,10 +134,10 @@ public: | |||
} | |||
/** @brief Serializable instance */ | |||
virtual inline size_t serSize() const NOEXCEPT FINAL { return SER_BYTES; } | |||
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } | |||
/** @brief Serializable instance */ | |||
virtual inline void serializeInto(unsigned char *buffer) const NOEXCEPT FINAL { | |||
inline void serializeInto(unsigned char *buffer) const NOEXCEPT { | |||
decaf_448_scalar_encode(buffer, s); | |||
} | |||
@@ -201,7 +199,7 @@ public: | |||
/** | |||
* @brief Element of prime-order group. | |||
*/ | |||
class Point : public Serializable { | |||
class Point : public Serializable<Point> { | |||
public: | |||
/** @brief Size of a serialized element */ | |||
static const size_t SER_BYTES = DECAF_448_SER_BYTES; | |||
@@ -307,10 +305,10 @@ public: | |||
} | |||
/** @brief Serializable instance */ | |||
virtual inline size_t serSize() const NOEXCEPT FINAL { return SER_BYTES; } | |||
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } | |||
/** @brief Serializable instance */ | |||
virtual inline void serializeInto(unsigned char *buffer) const NOEXCEPT FINAL { | |||
inline void serializeInto(unsigned char *buffer) const NOEXCEPT { | |||
decaf_448_point_encode(buffer, p); | |||
} | |||
@@ -544,7 +542,6 @@ public: | |||
}; /* struct Decaf448 */ | |||
#undef NOEXCEPT | |||
#undef FINAL | |||
} /* namespace decaf */ | |||
#endif /* __DECAF_448_HXX__ */ |
@@ -98,13 +98,15 @@ inline bool memeq(const std::vector<T,U> &a, const std::vector<V,W> &b) { | |||
} | |||
/** Base class of objects which support serialization */ | |||
class Serializable { | |||
template<class Base> class Serializable { | |||
public: | |||
/** @brief Return the number of bytes needed to serialize this object */ | |||
virtual inline size_t serSize() const NOEXCEPT = 0; | |||
inline size_t serSize() const NOEXCEPT { return static_cast<const Base*>(this)->serSize(); } | |||
/** @brief Serialize this object into a buffer */ | |||
virtual inline void serializeInto(unsigned char *buf) const NOEXCEPT = 0; | |||
inline void serializeInto(unsigned char *buf) const NOEXCEPT { | |||
static_cast<const Base*>(this)->serializeInto(buf); | |||
} | |||
/** @brief Serialize this object into a SecureBuffer and return it */ | |||
inline SecureBuffer serialize() const throw(std::bad_alloc) { | |||
@@ -73,12 +73,6 @@ public: | |||
*/ | |||
inline void output(Buffer b) { sha3_output(sp,b.data(),b.size()); } | |||
/** | |||
* @brief Output bytes from the sponge. | |||
* @todo make this throw exceptions. | |||
*/ | |||
inline void output(Buffer &b) { sha3_output(sp,b.data(),b.size()); } | |||
/** @brief Output bytes from the sponge. */ | |||
inline SecureBuffer output(size_t len) { | |||
SecureBuffer buffer(len); | |||
@@ -214,8 +208,8 @@ public: | |||
if (!strobe_key(sp, data.data(), data.size(), more)) throw ProtocolException(); | |||
} | |||
inline void key ( | |||
const Serializable &data, bool more = false | |||
template<class T> inline void key ( | |||
const Serializable<T> &data, bool more = false | |||
) throw(ProtocolException) { | |||
key(data.serialize(), more); | |||
} | |||
@@ -229,7 +223,7 @@ public: | |||
throw(ProtocolException()); | |||
} | |||
inline void send_plaintext(const Serializable &data, bool more = false) throw(ProtocolException) { | |||
template<class T> inline void send_plaintext(const Serializable<T> &data, bool more = false) throw(ProtocolException) { | |||
send_plaintext(data.serialize(), more); | |||
} | |||
@@ -239,7 +233,7 @@ public: | |||
throw(ProtocolException()); | |||
} | |||
inline void recv_plaintext(const Serializable &data, bool more = false) throw(ProtocolException) { | |||
template<class T> inline void recv_plaintext(const Serializable<T> &data, bool more = false) throw(ProtocolException) { | |||
recv_plaintext(data.serialize(), more); | |||
} | |||
@@ -248,7 +242,7 @@ public: | |||
throw(ProtocolException()); | |||
} | |||
inline void ad(const Serializable &data, bool more = false) throw(ProtocolException) { | |||
template<class T> inline void ad(const Serializable<T> &data, bool more = false) throw(ProtocolException) { | |||
ad(data.serialize(), more); | |||
} | |||
@@ -264,7 +258,7 @@ public: | |||
SecureBuffer out(data.size()); encrypt_no_auth(out, data, more); return out; | |||
} | |||
inline SecureBuffer encrypt_no_auth(const Serializable &data, bool more = false | |||
template<class T> inline SecureBuffer encrypt_no_auth(const Serializable<T> &data, bool more = false | |||
) throw(ProtocolException) { | |||
return encrypt_no_auth(data.serialize(), more); | |||
} | |||
@@ -281,7 +275,7 @@ public: | |||
SecureBuffer out(data.size()); decrypt_no_auth(out, data, more); return out; | |||
} | |||
inline SecureBuffer decrypt_no_auth(const Serializable &data, bool more = false | |||
template<class T> inline SecureBuffer decrypt_no_auth(const Serializable<T> &data, bool more = false | |||
) throw(ProtocolException) { | |||
return decrypt_no_auth(data.serialize(),more); | |||
} | |||
@@ -311,8 +305,8 @@ public: | |||
SecureBuffer out(data.size() + auth); encrypt(out, data, auth); return out; | |||
} | |||
inline SecureBuffer encrypt ( | |||
const Serializable &data, uint8_t auth = 8 | |||
template<class T> inline SecureBuffer encrypt ( | |||
const Serializable<T> &data, uint8_t auth = 8 | |||
) throw(LengthException,ProtocolException,std::bad_alloc ){ | |||
return encrypt(data.serialize(), auth); | |||
} | |||
@@ -325,8 +319,8 @@ public: | |||
verify_auth(data.slice(out.size(),bytes)); | |||
} | |||
inline SecureBuffer decrypt ( | |||
const Serializable &data, uint8_t auth = 8 | |||
template<class T> inline SecureBuffer decrypt ( | |||
const Serializable<T> &data, uint8_t auth = 8 | |||
) throw(LengthException,ProtocolException,CryptoException, std::bad_alloc ){ | |||
return decrypt(data.serialize(), auth); | |||
} | |||
@@ -497,8 +497,8 @@ static void strobe_forget ( | |||
if (sponge->params->rate < len + sponge->params->position) { | |||
dokeccak(sponge); | |||
} | |||
memset(sponge->state->b, 0, len); | |||
sponge->params->position = len; | |||
memset(&sponge->state->b[sponge->params->position], 0, len); | |||
sponge->params->position += len; | |||
} | |||
} | |||
@@ -286,7 +286,7 @@ static void macro() { | |||
PublicKey<Group> p1((NOINIT())), p2((NOINIT())); | |||
PrivateKey<Group> s1((NOINIT())), s2((NOINIT())); | |||
SecureBuffer message = rng.read(12), sig; | |||
SecureBuffer message = rng.read(5), sig; | |||
for (Benchmark b("Create private key",1); b.iter(); ) { | |||
s1 = PrivateKey<Group>(rng); | |||
@@ -299,7 +299,7 @@ static void macro() { | |||
p1 = s1.pub(); | |||
for (Benchmark b("Verify",1); b.iter(); ) { | |||
message = rng.read(12); | |||
rng.read(Buffer(message)); | |||
try { p1.verify(message, sig); } catch (CryptoException) {} | |||
} | |||
@@ -354,6 +354,7 @@ static void micro() { | |||
for (Benchmark b("Point double scalarmul"); b.iter(); ) { Point::double_scalarmul(p,s,q,t); } | |||
for (Benchmark b("Point precmp scalarmul"); b.iter(); ) { pBase * s; } | |||
for (Benchmark b("Point double scalarmul_v"); b.iter(); ) { | |||
s = Scalar(rng); | |||
t = Scalar(rng); | |||
p.non_secret_combo_with_base(s,t); | |||
} | |||
@@ -362,6 +363,7 @@ static void micro() { | |||
}; /* template <typename group> struct Benches */ | |||
int main(int argc, char **argv) { | |||
bool micro = false; | |||
if (argc >= 2 && !strcmp(argv[1], "--micro")) | |||
micro = true; | |||
@@ -379,9 +381,8 @@ int main(int argc, char **argv) { | |||
size_t lmessage = sizeof(umessage); | |||
SpongeRng rng(Block("micro-benchmarks")); | |||
if (micro) { | |||
SpongeRng rng(Block("micro-benchmarks")); | |||
printf("\nMicro-benchmarks:\n"); | |||
SHAKE<128> shake1; | |||
SHAKE<256> shake2; | |||
@@ -435,8 +436,9 @@ int main(int argc, char **argv) { | |||
for (Benchmark b("Verify"); b.iter(); ) { | |||
decaf_bool_t ret = decaf_255_verify(sig1,p1,umessage,lmessage); | |||
umessage[0]++; | |||
umessage[1]^=umessage[0]; | |||
rng.read(Buffer(umessage,lmessage)); | |||
// umessage[0]++; | |||
// umessage[1]^=umessage[0]; | |||
ignore_result(ret); | |||
} | |||