@@ -3,7 +3,7 @@ from gen_file import gen_file | |||
crypto_h = gen_file( | |||
name = "decaf/crypto_%(shortname)s.h", | |||
doc = """ | |||
@brief Example Decaf cyrpto routines. | |||
@brief Example Decaf crypto routines. | |||
@warning These are merely examples, though they ought to be secure. But real | |||
protocols will decide differently on magic numbers, formats, which items to | |||
hash, etc. | |||
@@ -25,7 +25,7 @@ typedef unsigned char %(c_ns)s_public_key_t[%(C_NS)s_SER_BYTES]; | |||
typedef unsigned char %(c_ns)s_signature_t[%(C_NS)s_SER_BYTES + %(C_NS)s_SCALAR_BYTES]; | |||
typedef struct { | |||
/** @cond intetrnal */ | |||
/** @cond internal */ | |||
/** The symmetric key from which everything is expanded */ | |||
%(c_ns)s_symmetric_key_t sym; | |||
@@ -0,0 +1,172 @@ | |||
from gen_file import gen_file | |||
crypto_hxx = gen_file( | |||
name = "decaf/crypto_%(shortname)s.hxx", | |||
doc = """ | |||
@brief Example Decaf cyrpto routines, C++ wrapper. | |||
@warning These are merely examples, though they ought to be secure. But real | |||
protocols will decide differently on magic numbers, formats, which items to | |||
hash, etc. | |||
@warning Experimental! The names, parameter orders etc are likely to change. | |||
""", code = """ | |||
#include <decaf.hxx> | |||
#include <decaf/shake.hxx> | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
#define NOEXCEPT noexcept | |||
#else | |||
#define NOEXCEPT throw() | |||
#endif | |||
/** @endcond */ | |||
namespace decaf { | |||
template <typename Group> class PublicKey; | |||
template <typename Group> class PrivateKey; | |||
template<> class PublicKey<%(cxx_ns)s> | |||
: public Serializable< PublicKey<%(cxx_ns)s> > { | |||
private: | |||
typedef %(c_ns)s_public_key_t Wrapped; | |||
Wrapped wrapped; | |||
template<class Group> friend class PrivateKey; | |||
public: | |||
/** @brief Underlying group */ | |||
typedef %(cxx_ns)s Group; | |||
/** @brief Signature size. */ | |||
static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t); | |||
/** @brief Serialization size. */ | |||
static const size_t SER_BYTES = sizeof(Wrapped); | |||
/* TODO: convenience types like signature? */ | |||
/** @brief Read a private key from a string*/ | |||
inline explicit PublicKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT { | |||
memcpy(wrapped,b.data(),sizeof(wrapped)); | |||
} | |||
/** @brief Read a private key from a string*/ | |||
inline explicit PublicKey(const PrivateKey<%(cxx_ns)s> &b) NOEXCEPT; | |||
/** @brief Create but don't initialize */ | |||
inline explicit PublicKey(const NOINIT&) NOEXCEPT { } | |||
/** @brief Serialize into a buffer. */ | |||
inline void serializeInto(unsigned char *x) const NOEXCEPT { | |||
memcpy(x,wrapped,sizeof(wrapped)); | |||
} | |||
/** @brief Serialization size. */ | |||
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } | |||
/* TODO: verify_strobe? */ | |||
/** @brief Verify a message */ | |||
inline void verify( | |||
const Block &message, | |||
const FixedBlock<SIG_BYTES> &sig | |||
) const throw(CryptoException) { | |||
if (DECAF_SUCCESS != %(c_ns)s_verify(sig.data(),wrapped,message.data(),message.size())) { | |||
throw(CryptoException()); | |||
} | |||
} | |||
}; | |||
template<> class PrivateKey<%(cxx_ns)s> | |||
: public Serializable< PrivateKey<%(cxx_ns)s> > { | |||
private: | |||
typedef %(c_ns)s_private_key_t Wrapped; | |||
Wrapped wrapped; | |||
template<class Group> friend class PublicKey; | |||
public: | |||
/** @brief Underlying group */ | |||
typedef %(cxx_ns)s Group; | |||
/** @brief Signature size. */ | |||
static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t); | |||
/** @brief Serialization size. */ | |||
static const size_t SER_BYTES = sizeof(Wrapped); | |||
/** @brief Compressed size. */ | |||
static const size_t SYM_BYTES = %(C_NS)s_SYMMETRIC_KEY_BYTES; | |||
/** @brief Create but don't initialize */ | |||
inline explicit PrivateKey(const NOINIT&) NOEXCEPT { } | |||
/** @brief Read a private key from a string*/ | |||
inline explicit PrivateKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT { | |||
memcpy(wrapped,b.data(),sizeof(wrapped)); | |||
} | |||
/** @brief Read a private key from a string*/ | |||
inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT { | |||
%(c_ns)s_derive_private_key(wrapped, b.data()); | |||
} | |||
/** @brief Create at random */ | |||
inline explicit PrivateKey(Rng &r) NOEXCEPT { | |||
FixedArrayBuffer<SYM_BYTES> tmp(r); | |||
%(c_ns)s_derive_private_key(wrapped, tmp.data()); | |||
} | |||
/** @brief Secure destructor */ | |||
inline ~PrivateKey() NOEXCEPT { | |||
%(c_ns)s_destroy_private_key(wrapped); | |||
} | |||
/** @brief Serialization size. */ | |||
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } | |||
/** @brief Serialize into a buffer. */ | |||
inline void serializeInto(unsigned char *x) const NOEXCEPT { | |||
memcpy(x,wrapped,sizeof(wrapped)); | |||
} | |||
/** @brief Compressed serialize. */ | |||
inline SecureBuffer compress() const throw(std::bad_alloc) { | |||
SecureBuffer ret(sizeof(wrapped->sym)); | |||
memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym)); | |||
return ret; | |||
} | |||
/** @brief Get the public key */ | |||
inline PublicKey<%(cxx_ns)s> pub() const NOEXCEPT { | |||
PublicKey<%(cxx_ns)s> ret(*this); return ret; | |||
} | |||
/** @brief Derive a shared secret */ | |||
inline SecureBuffer sharedSecret( | |||
const PublicKey<%(cxx_ns)s> &pub, | |||
size_t bytes, | |||
bool me_first | |||
) const throw(CryptoException,std::bad_alloc) { | |||
SecureBuffer ret(bytes); | |||
if (DECAF_SUCCESS != %(c_ns)s_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) { | |||
throw(CryptoException()); | |||
} | |||
return ret; | |||
} | |||
/** @brief Sign a message. */ | |||
inline SecureBuffer sign(const Block &message) const { | |||
SecureBuffer sig(SIG_BYTES); | |||
%(c_ns)s_sign(sig.data(), wrapped, message.data(), message.size()); | |||
return sig; | |||
} | |||
}; | |||
/** @cond internal */ | |||
PublicKey<%(cxx_ns)s>::PublicKey(const PrivateKey<%(cxx_ns)s> &b) NOEXCEPT { | |||
%(c_ns)s_private_to_public(wrapped,b.wrapped); | |||
} | |||
/** @endcond */ | |||
#undef NOEXCEPT | |||
} /* namespace decaf */ | |||
""") |
@@ -14,6 +14,7 @@ prefixes = { "h" : args.hpre, "hxx" : args.hpre, "c" : args.cpre } | |||
from decaf_hxx import decaf_hxx | |||
from decaf_h import decaf_h | |||
from crypto_h import crypto_h | |||
from crypto_hxx import crypto_hxx | |||
root_hxx_code = "\n".join(( | |||
"#include <%s>" % name | |||
@@ -34,7 +35,7 @@ crypto_h_code = "\n".join(( | |||
crypto_h = gen_file( | |||
name = "decaf/crypto.h", | |||
doc = """@brief | |||
@brief Example Decaf cyrpto routines, metaheader. | |||
@brief Example Decaf crypto routines, metaheader. | |||
@warning These are merely examples, though they ought to be secure. But real | |||
protocols will decide differently on magic numbers, formats, which items to | |||
hash, etc. | |||
@@ -42,6 +43,22 @@ crypto_h = gen_file( | |||
code = "\n"+crypto_h_code+"\n" | |||
) | |||
crypto_hxx_code = "\n".join(( | |||
"#include <%s>" % name | |||
for name in sorted(gend_files) | |||
if re.match("^decaf/crypto_\d+.hxx$",name) | |||
)) | |||
crypto_hxx = gen_file( | |||
name = "decaf/crypto.hxx", | |||
doc = """@brief | |||
@brief Example Decaf crypto routines, C++, metaheader. | |||
@warning These are merely examples, though they ought to be secure. But real | |||
protocols will decide differently on magic numbers, formats, which items to | |||
hash, etc. | |||
""", | |||
code = "\n"+crypto_hxx_code+"\n" | |||
) | |||
root_h_code = "\n".join(( | |||
"#include <%s>" % name | |||
for name in sorted(gend_files) | |||
@@ -1,216 +0,0 @@ | |||
/** | |||
* @file decaf/crypto.hxx | |||
* @author Mike Hamburg | |||
* | |||
* @copyright | |||
* Copyright (c) 2015 Cryptography Research, Inc. \n | |||
* Released under the MIT License. See LICENSE.txt for license information. | |||
* | |||
* @brief Example cryptography using Decaf. | |||
* @warning FIXME: this is out of sync with crypto_*.h | |||
*/ | |||
#ifndef __DECAF_CRYPTO_HXX__ | |||
#define __DECAF_CRYPTO_HXX__ 1 | |||
#include <decaf.hxx> | |||
#include <decaf/shake.hxx> | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
#define NOEXCEPT noexcept | |||
#else | |||
#define NOEXCEPT throw() | |||
#endif | |||
/** @endcond */ | |||
/* TODO: decide on copy vs reference */ | |||
namespace decaf { | |||
template <typename Group> class PrivateKey; | |||
/** @brief A public key using a particular EC group */ | |||
template <typename Group> class PublicKey : public Serializable<PublicKey<Group> > { | |||
private: | |||
/** @cond internal */ | |||
friend class PrivateKey<Group>; | |||
static const size_t CHALLENGE_BYTES = Group::Scalar::SER_BYTES; | |||
//const typename Group::Point p; | |||
FixedArrayBuffer<Group::Point::SER_BYTES> ser; | |||
/** @endcond */ | |||
public: | |||
/** Create without init */ | |||
PublicKey(NOINIT) : ser(NOINIT()) {} | |||
/** SHAKE instance size for sigs etc */ | |||
static const size_t SHAKE_BITS = 256; | |||
/** Size of a signature */ | |||
static const size_t SIG_BYTES = Group::Point::SER_BYTES + Group::Scalar::SER_BYTES; | |||
/** @brief Set the public key to a point */ | |||
inline explicit PublicKey(const typename Group::Point &p) NOEXCEPT : ser(p.serialize()) {} | |||
/** @brief Get the private key for a given public key */ | |||
inline explicit PublicKey(const PrivateKey<Group> &priv) NOEXCEPT; | |||
/** @brief Read a private key from a string*/ | |||
inline explicit PublicKey(const FixedBlock<Group::Point::SER_BYTES> &b) NOEXCEPT : ser(b) {} | |||
/** @brief Return the corresponding EC point */ | |||
inline typename Group::Point point() const throw(CryptoException) { | |||
return typename Group::Point(ser); | |||
} | |||
/** @brief Verify a sig. TODO: nothrow version? */ | |||
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_error_t scalar_OK = Group::Scalar::decode( | |||
response, | |||
sig.slice(Group::Point::SER_BYTES, Group::Scalar::SER_BYTES) | |||
); | |||
const typename Group::Point combo = point().non_secret_combo_with_base( | |||
typename Group::Scalar(challenge), response | |||
); | |||
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. */ | |||
inline void verify(const Block &message, const FixedBlock<SIG_BYTES> &sig) throw(CryptoException) { | |||
SHAKE<SHAKE_BITS> ctx; | |||
ctx << message; | |||
verify_shake(ctx,sig); | |||
} | |||
/** @brief Serialize into a buffer. */ | |||
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 { | |||
return Group::Point::SER_BYTES; | |||
} | |||
/** @brief Copy operator */ | |||
inline PublicKey &operator=(const PublicKey &x) NOEXCEPT { ser = x.ser; return *this; } | |||
}; | |||
/** @brief A private key using a particular EC group */ | |||
template <typename Group> class PrivateKey : public Serializable<PrivateKey<Group> > { | |||
public: | |||
/** Size of associated symmetric key */ | |||
static const size_t SYM_BYTES = 32; | |||
/** SHAKE instance size for sigs etc */ | |||
static const size_t SHAKE_BITS = PublicKey<Group>::SHAKE_BITS; | |||
private: | |||
/** @cond internal */ | |||
static const size_t SCALAR_HASH_BYTES = Group::Scalar::SER_BYTES + 8; | |||
friend class PublicKey<Group>; | |||
FixedArrayBuffer<SYM_BYTES> sym; | |||
typename Group::Scalar scalar; | |||
PublicKey<Group> pub_; | |||
/** @endcond */ | |||
public: | |||
/** @brief Don't initialize */ | |||
inline PrivateKey(const NOINIT &ni) NOEXCEPT : sym(ni), scalar(ni), pub_(ni) {} | |||
/** @brief Construct at random */ | |||
inline PrivateKey(Rng &r) : | |||
sym(r), | |||
scalar(SHAKE<SHAKE_BITS>::hash(sym, SCALAR_HASH_BYTES)), | |||
pub_((Group::Precomputed::base() * scalar).serialize()) {} | |||
/** @brief Construct from buffer */ | |||
inline PrivateKey(const FixedBlock<SYM_BYTES> &sym_) : | |||
sym(sym_), | |||
scalar(SHAKE<SHAKE_BITS>::hash(sym, SCALAR_HASH_BYTES)), | |||
pub_(SecureBuffer(Group::Precomputed::Base * scalar)) {} | |||
/** @brief Compressed representation */ | |||
inline const FixedBlock<SYM_BYTES> &ser_compressed() const NOEXCEPT { | |||
return sym; | |||
} | |||
/** @brief Serialize */ | |||
inline size_t serSize() const NOEXCEPT { | |||
return SYM_BYTES; | |||
} | |||
/** @brief Serialize */ | |||
inline void serializeInto(unsigned char *target) const NOEXCEPT { | |||
memcpy(target,sym.data(),serSize()); | |||
} | |||
/** @brief Uncompressed representation */ | |||
inline SecureBuffer ser_uncompressed() const throw(std::bad_alloc) { | |||
SecureBuffer b(SYM_BYTES + Group::Scalar::SER_BYTES + Group::Point::SER_BYTES); | |||
Buffer(b).slice(0,SYM_BYTES).assign(sym); | |||
Buffer(b).slice(SYM_BYTES,Group::Scalar::SER_BYTES).assign(scalar); | |||
Buffer(b).slice(SYM_BYTES+Group::Scalar::SER_BYTES,Group::Point::SER_BYTES).assign(pub_.ser); | |||
return b; | |||
} | |||
/** @brief Sign from a SHAKE context. TODO: double check random oracle eval of this; destructive version? */ | |||
inline SecureBuffer sign_shake(const SHAKE<SHAKE_BITS> &ctx_) throw(std::bad_alloc) { | |||
SHAKE<SHAKE_BITS> ctx(ctx_); | |||
ctx << sym << "decaf_255_sign_shake"; | |||
typename Group::Scalar nonce(ctx.output(SCALAR_HASH_BYTES)); | |||
SecureBuffer g_nonce = (Group::Precomputed::base() * nonce).serialize(); | |||
ctx = ctx_; | |||
ctx << pub_.ser << g_nonce; | |||
SecureBuffer challenge(ctx.output(PublicKey<Group>::CHALLENGE_BYTES)); | |||
SecureBuffer response((nonce - scalar * typename Group::Scalar(challenge)).serialize()); | |||
SecureBuffer ret(PublicKey<Group>::SIG_BYTES); | |||
Buffer(ret).slice(0,Group::Point::SER_BYTES).assign(g_nonce); | |||
Buffer(ret).slice(Group::Point::SER_BYTES, Group::Scalar::SER_BYTES).assign(response); | |||
return ret; | |||
} | |||
/** @brief Sign from a message. */ | |||
inline SecureBuffer sign(const Block &message) { | |||
SHAKE<SHAKE_BITS> ctx; | |||
ctx << message; | |||
return sign_shake(ctx); | |||
} | |||
/** @brief Get the corresponding public key */ | |||
inline const PublicKey<Group> &pub() const { return pub_; } | |||
/** @brief Copy operator */ | |||
inline PrivateKey &operator=(const PrivateKey &x) NOEXCEPT { | |||
sym = x.sym; | |||
scalar = x.scalar; | |||
pub_ = x.pub_; | |||
return *this; | |||
} | |||
}; | |||
/** @cond internal */ | |||
template <typename Group> | |||
inline PublicKey<Group>::PublicKey( | |||
const PrivateKey<Group> &priv | |||
) NOEXCEPT : ser(priv.pub_.ser){} | |||
/** @endcond */ | |||
#undef NOEXCEPT | |||
} /* namespace decaf */ | |||
#endif /* __DECAF_CRYPTO_HXX__ */ | |||
@@ -376,14 +376,6 @@ int main(int argc, char **argv) { | |||
if (argc >= 2 && !strcmp(argv[1], "--micro")) | |||
micro = true; | |||
decaf_255_symmetric_key_t r1,r2; | |||
memset(r1,1,sizeof(r1)); | |||
memset(r2,2,sizeof(r2)); | |||
unsigned char umessage[] = {1,2,3,4,5}; | |||
size_t lmessage = sizeof(umessage); | |||
SpongeRng rng(Block("micro-benchmarks")); | |||
if (micro) { | |||
printf("\nMicro-benchmarks:\n"); | |||
@@ -417,76 +409,10 @@ int main(int argc, char **argv) { | |||
Benches<Ed448Goldilocks>::micro(); | |||
} | |||
{ | |||
decaf_255_public_key_t p1,p2; | |||
decaf_255_private_key_t s1,s2; | |||
decaf_255_signature_t sig1; | |||
unsigned char ss[32]; | |||
printf("\nMacro-benchmarks for IsoEd25519:\n"); | |||
for (Benchmark b("Keygen"); b.iter(); ) { | |||
decaf_255_derive_private_key(s1,r1); | |||
} | |||
decaf_255_private_to_public(p1,s1); | |||
decaf_255_derive_private_key(s2,r2); | |||
decaf_255_private_to_public(p2,s2); | |||
for (Benchmark b("Shared secret"); b.iter(); ) { | |||
decaf_bool_t ret = decaf_255_shared_secret(ss,sizeof(ss),s1,p2,1); | |||
ignore_result(ret); | |||
assert(ret); | |||
} | |||
for (Benchmark b("Sign"); b.iter(); ) { | |||
decaf_255_sign(sig1,s1,umessage,lmessage); | |||
} | |||
for (Benchmark b("Verify"); b.iter(); ) { | |||
decaf_bool_t ret = decaf_255_verify(sig1,p1,umessage,lmessage); | |||
rng.read(Buffer(umessage,lmessage)); | |||
// umessage[0]++; | |||
// umessage[1]^=umessage[0]; | |||
ignore_result(ret); | |||
} | |||
} | |||
{ | |||
decaf_448_public_key_t p1,p2; | |||
decaf_448_private_key_t s1,s2; | |||
decaf_448_signature_t sig1; | |||
unsigned char ss[32]; | |||
printf("\nMacro-benchmarks for Ed448-Goldilocks:\n"); | |||
for (Benchmark b("Keygen"); b.iter(); ) { | |||
decaf_448_derive_private_key(s1,r1); | |||
} | |||
decaf_448_private_to_public(p1,s1); | |||
decaf_448_derive_private_key(s2,r2); | |||
decaf_448_private_to_public(p2,s2); | |||
for (Benchmark b("Shared secret"); b.iter(); ) { | |||
decaf_bool_t ret = decaf_448_shared_secret(ss,sizeof(ss),s1,p2,1); | |||
ignore_result(ret); | |||
assert(ret); | |||
} | |||
for (Benchmark b("Sign"); b.iter(); ) { | |||
decaf_448_sign(sig1,s1,umessage,lmessage); | |||
} | |||
for (Benchmark b("Verify"); b.iter(); ) { | |||
decaf_bool_t ret = decaf_448_verify(sig1,p1,umessage,lmessage); | |||
rng.read(Buffer(umessage,lmessage)); | |||
// umessage[0]++; | |||
// umessage[1]^=umessage[0]; | |||
ignore_result(ret); | |||
} | |||
} | |||
Benches<IsoEd25519>::macro(); | |||
Benches<Ed448Goldilocks>::macro(); | |||
printf("\n"); | |||
Benchmark::calib(); | |||
@@ -11,8 +11,7 @@ | |||
#include <decaf.hxx> | |||
#include <decaf/shake.hxx> | |||
#include <decaf/crypto_255.h> | |||
#include <decaf/crypto_448.h> | |||
#include <decaf/crypto.h> | |||
#include <decaf/crypto.hxx> | |||
#include <stdio.h> | |||
@@ -342,75 +341,6 @@ static void test_crypto() { | |||
}; // template<GroupId GROUP> | |||
static void test_decaf_255() { | |||
Test test("Sample crypto"); | |||
SpongeRng rng(Block("test_decaf")); | |||
decaf_255_symmetric_key_t proto1,proto2; | |||
decaf_255_private_key_t s1,s2; | |||
decaf_255_public_key_t p1,p2; | |||
decaf_255_signature_t sig; | |||
unsigned char shared1[1234],shared2[1234]; | |||
const char *message = "Hello, world!"; | |||
for (int i=0; i<NTESTS && test.passing_now; i++) { | |||
rng.read(Buffer(proto1,sizeof(proto1))); | |||
rng.read(Buffer(proto2,sizeof(proto2))); | |||
decaf_255_derive_private_key(s1,proto1); | |||
decaf_255_private_to_public(p1,s1); | |||
decaf_255_derive_private_key(s2,proto2); | |||
decaf_255_private_to_public(p2,s2); | |||
if (DECAF_SUCCESS != decaf_255_shared_secret (shared1,sizeof(shared1),s1,p2,0)) { | |||
test.fail(); printf("Fail ss12\n"); | |||
} | |||
if (DECAF_SUCCESS != decaf_255_shared_secret (shared2,sizeof(shared2),s2,p1,1)) { | |||
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_SUCCESS != decaf_255_verify (sig,p1,(const unsigned char *)message,strlen(message))) { | |||
test.fail(); printf("Fail sig ver\n"); | |||
} | |||
} | |||
} | |||
/* TODO: don't copy-paste */ | |||
static void test_decaf_448() { | |||
Test test("Sample crypto"); | |||
SpongeRng rng(Block("test_decaf")); | |||
decaf_448_symmetric_key_t proto1,proto2; | |||
decaf_448_private_key_t s1,s2; | |||
decaf_448_public_key_t p1,p2; | |||
decaf_448_signature_t sig; | |||
unsigned char shared1[1234],shared2[1234]; | |||
const char *message = "Hello, world!"; | |||
for (int i=0; i<NTESTS && test.passing_now; i++) { | |||
rng.read(Buffer(proto1,sizeof(proto1))); | |||
rng.read(Buffer(proto2,sizeof(proto2))); | |||
decaf_448_derive_private_key(s1,proto1); | |||
decaf_448_private_to_public(p1,s1); | |||
decaf_448_derive_private_key(s2,proto2); | |||
decaf_448_private_to_public(p2,s2); | |||
if (DECAF_SUCCESS != decaf_448_shared_secret (shared1,sizeof(shared1),s1,p2,0)) { | |||
test.fail(); printf("Fail ss12\n"); | |||
} | |||
if (DECAF_SUCCESS != decaf_448_shared_secret (shared2,sizeof(shared2),s2,p1,1)) { | |||
test.fail(); printf("Fail ss21\n"); | |||
} | |||
if (memcmp(shared1,shared2,sizeof(shared1))) { | |||
test.fail(); printf("Fail ss21 == ss12\n"); | |||
} | |||
decaf_448_sign (sig,s1,(const unsigned char *)message,strlen(message)); | |||
if (DECAF_SUCCESS != decaf_448_verify (sig,p1,(const unsigned char *)message,strlen(message))) { | |||
test.fail(); printf("Fail sig ver\n"); | |||
} | |||
} | |||
} | |||
int main(int argc, char **argv) { | |||
(void) argc; (void) argv; | |||
@@ -419,7 +349,6 @@ int main(int argc, char **argv) { | |||
Tests<IsoEd25519>::test_elligator(); | |||
Tests<IsoEd25519>::test_ec(); | |||
Tests<IsoEd25519>::test_crypto(); | |||
test_decaf_255(); | |||
printf("\n"); | |||
printf("Testing %s:\n", Ed448Goldilocks::name()); | |||
@@ -427,7 +356,6 @@ int main(int argc, char **argv) { | |||
Tests<Ed448Goldilocks>::test_elligator(); | |||
Tests<Ed448Goldilocks>::test_ec(); | |||
Tests<Ed448Goldilocks>::test_crypto(); | |||
test_decaf_448(); | |||
if (passing) printf("Passed all tests.\n"); | |||