|
|
@@ -12,8 +12,10 @@ |
|
|
|
#include <decaf.hxx> |
|
|
|
#include <decaf/shake.hxx> |
|
|
|
#include <decaf/crypto.h> |
|
|
|
#include <decaf/crypto.hxx> |
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
using namespace decaf; |
|
|
|
|
|
|
|
static bool passing = true; |
|
|
|
static const long NTESTS = 10000; |
|
|
@@ -49,7 +51,7 @@ typedef typename Group::Precomputed Precomputed; |
|
|
|
|
|
|
|
static void print(const char *name, const Scalar &x) { |
|
|
|
unsigned char buffer[Scalar::SER_BYTES]; |
|
|
|
x.encode(decaf::FixedBuffer<Scalar::SER_BYTES>(buffer)); |
|
|
|
x.encode(FixedBuffer<Scalar::SER_BYTES>(buffer)); |
|
|
|
printf(" %s = 0x", name); |
|
|
|
for (int i=sizeof(buffer)-1; i>=0; i--) { |
|
|
|
printf("%02x", buffer[i]); |
|
|
@@ -57,7 +59,7 @@ static void print(const char *name, const Scalar &x) { |
|
|
|
printf("\n"); |
|
|
|
} |
|
|
|
|
|
|
|
static void hexprint(const char *name, const decaf::SecureBuffer &buffer) { |
|
|
|
static void hexprint(const char *name, const SecureBuffer &buffer) { |
|
|
|
printf(" %s = 0x", name); |
|
|
|
for (int i=buffer.size()-1; i>=0; i--) { |
|
|
|
printf("%02x", buffer[i]); |
|
|
@@ -66,7 +68,7 @@ static void hexprint(const char *name, const decaf::SecureBuffer &buffer) { |
|
|
|
} |
|
|
|
|
|
|
|
static void print(const char *name, const Point &x) { |
|
|
|
decaf::StackBuffer<Point::SER_BYTES> buffer; |
|
|
|
FixedArrayBuffer<Point::SER_BYTES> buffer; |
|
|
|
x.encode(buffer); |
|
|
|
printf(" %s = 0x", name); |
|
|
|
for (int i=Point::SER_BYTES-1; i>=0; i--) { |
|
|
@@ -126,7 +128,7 @@ static bool point_check( |
|
|
|
} |
|
|
|
|
|
|
|
static void test_arithmetic() { |
|
|
|
decaf::SpongeRng rng(decaf::Block("test_arithmetic")); |
|
|
|
SpongeRng rng(Block("test_arithmetic")); |
|
|
|
|
|
|
|
Test test("Arithmetic"); |
|
|
|
Scalar x(0),y(0),z(0); |
|
|
@@ -161,18 +163,18 @@ static void test_arithmetic() { |
|
|
|
} |
|
|
|
|
|
|
|
static void test_elligator() { |
|
|
|
decaf::SpongeRng rng(decaf::Block("test_elligator")); |
|
|
|
SpongeRng rng(Block("test_elligator")); |
|
|
|
Test test("Elligator"); |
|
|
|
|
|
|
|
const int NHINTS = Group::REMOVED_COFACTOR * 2; |
|
|
|
decaf::SecureBuffer *alts[NHINTS]; |
|
|
|
SecureBuffer *alts[NHINTS]; |
|
|
|
bool successes[NHINTS]; |
|
|
|
decaf::SecureBuffer *alts2[NHINTS]; |
|
|
|
SecureBuffer *alts2[NHINTS]; |
|
|
|
bool successes2[NHINTS]; |
|
|
|
|
|
|
|
for (int i=0; i<NTESTS/10 && (test.passing_now || i < 100); i++) { |
|
|
|
size_t len = (i % (2*Point::HASH_BYTES + 3)); |
|
|
|
decaf::SecureBuffer b1(len); |
|
|
|
SecureBuffer b1(len); |
|
|
|
if (i!=Point::HASH_BYTES) rng.read(b1); /* special test case */ |
|
|
|
if (i==1) b1[0] = 1; /* special case test */ |
|
|
|
if (len >= Point::HASH_BYTES) b1[Point::HASH_BYTES-1] &= 0x7F; // FIXME MAGIC |
|
|
@@ -184,8 +186,8 @@ static void test_elligator() { |
|
|
|
|
|
|
|
bool good = false; |
|
|
|
for (int j=0; j<NHINTS; j++) { |
|
|
|
alts[j] = new decaf::SecureBuffer(len); |
|
|
|
alts2[j] = new decaf::SecureBuffer(len); |
|
|
|
alts[j] = new SecureBuffer(len); |
|
|
|
alts2[j] = new SecureBuffer(len); |
|
|
|
|
|
|
|
if (len > Point::HASH_BYTES) |
|
|
|
memcpy(&(*alts[j])[Point::HASH_BYTES], &b1[Point::HASH_BYTES], len-Point::HASH_BYTES); |
|
|
@@ -263,7 +265,7 @@ static void test_elligator() { |
|
|
|
} |
|
|
|
|
|
|
|
static void test_ec() { |
|
|
|
decaf::SpongeRng rng(decaf::Block("test_ec")); |
|
|
|
SpongeRng rng(Block("test_ec")); |
|
|
|
|
|
|
|
Test test("EC"); |
|
|
|
|
|
|
@@ -278,13 +280,13 @@ static void test_ec() { |
|
|
|
Point p(rng); |
|
|
|
Point q(rng); |
|
|
|
|
|
|
|
decaf::SecureBuffer buffer(2*Point::HASH_BYTES); |
|
|
|
SecureBuffer buffer(2*Point::HASH_BYTES); |
|
|
|
rng.read(buffer); |
|
|
|
Point r = Point::from_hash(buffer); |
|
|
|
|
|
|
|
point_check(test,p,q,r,0,0,p,Point((decaf::SecureBuffer)p),"round-trip"); |
|
|
|
point_check(test,p,q,r,0,0,p,Point((SecureBuffer)p),"round-trip"); |
|
|
|
Point pp = p.debugging_torque().debugging_pscale(rng); |
|
|
|
if (decaf::SecureBuffer(pp) != decaf::SecureBuffer(p)) { |
|
|
|
if (SecureBuffer(pp) != SecureBuffer(p)) { |
|
|
|
test.fail(); |
|
|
|
printf("Fail torque seq test\n"); |
|
|
|
} |
|
|
@@ -306,16 +308,30 @@ static void test_ec() { |
|
|
|
"unih = hash+add" |
|
|
|
); |
|
|
|
|
|
|
|
point_check(test,p,q,r,x,0,Point(x.direct_scalarmul(decaf::SecureBuffer(p))),x*p,"direct mul"); |
|
|
|
point_check(test,p,q,r,x,0,Point(x.direct_scalarmul(SecureBuffer(p))),x*p,"direct mul"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}; // template<decaf::GroupId GROUP> |
|
|
|
static void test_crypto() { |
|
|
|
Test test("Sample crypto"); |
|
|
|
SpongeRng rng(Block("test_decaf_crypto")); |
|
|
|
|
|
|
|
for (int i=0; i<NTESTS && test.passing_now; i++) { |
|
|
|
PrivateKey<Group> priv1(rng), priv2(rng); |
|
|
|
PublicKey<Group> pub1(priv1), pub2(priv2); |
|
|
|
|
|
|
|
SecureBuffer message(rng, i); |
|
|
|
FixedArrayBuffer<PublicKey<Group>::SIG_BYTES> sig(priv1.sign(message)); |
|
|
|
pub1.verify(message, sig); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}; // template<GroupId GROUP> |
|
|
|
|
|
|
|
// FIXME cross-field |
|
|
|
static void test_decaf() { |
|
|
|
Test test("Sample crypto"); |
|
|
|
decaf::SpongeRng rng(decaf::Block("test_decaf")); |
|
|
|
SpongeRng rng(Block("test_decaf")); |
|
|
|
|
|
|
|
decaf_255_symmetric_key_t proto1,proto2; |
|
|
|
decaf_255_private_key_t s1,s2; |
|
|
@@ -325,8 +341,8 @@ static void test_decaf() { |
|
|
|
const char *message = "Hello, world!"; |
|
|
|
|
|
|
|
for (int i=0; i<NTESTS && test.passing_now; i++) { |
|
|
|
rng.read(decaf::TmpBuffer(proto1,sizeof(proto1))); |
|
|
|
rng.read(decaf::TmpBuffer(proto2,sizeof(proto2))); |
|
|
|
rng.read(TmpBuffer(proto1,sizeof(proto1))); |
|
|
|
rng.read(TmpBuffer(proto2,sizeof(proto2))); |
|
|
|
decaf_255_derive_private_key(s1,proto1); |
|
|
|
decaf_255_private_to_public(p1,s1); |
|
|
|
decaf_255_derive_private_key(s2,proto2); |
|
|
@@ -350,17 +366,19 @@ static void test_decaf() { |
|
|
|
int main(int argc, char **argv) { |
|
|
|
(void) argc; (void) argv; |
|
|
|
|
|
|
|
printf("Testing %s:\n", decaf::IsoEd25519::name()); |
|
|
|
Tests<decaf::IsoEd25519>::test_arithmetic(); |
|
|
|
Tests<decaf::IsoEd25519>::test_elligator(); |
|
|
|
Tests<decaf::IsoEd25519>::test_ec(); |
|
|
|
printf("Testing %s:\n",IsoEd25519::name()); |
|
|
|
Tests<IsoEd25519>::test_arithmetic(); |
|
|
|
Tests<IsoEd25519>::test_elligator(); |
|
|
|
Tests<IsoEd25519>::test_ec(); |
|
|
|
Tests<IsoEd25519>::test_crypto(); |
|
|
|
test_decaf(); |
|
|
|
|
|
|
|
printf("\n"); |
|
|
|
printf("Testing %s:\n", decaf::Ed448Goldilocks::name()); |
|
|
|
Tests<decaf::Ed448Goldilocks>::test_arithmetic(); |
|
|
|
Tests<decaf::Ed448Goldilocks>::test_elligator(); |
|
|
|
Tests<decaf::Ed448Goldilocks>::test_ec(); |
|
|
|
printf("Testing %s:\n", Ed448Goldilocks::name()); |
|
|
|
Tests<Ed448Goldilocks>::test_arithmetic(); |
|
|
|
Tests<Ed448Goldilocks>::test_elligator(); |
|
|
|
Tests<Ed448Goldilocks>::test_ec(); |
|
|
|
Tests<Ed448Goldilocks>::test_crypto(); |
|
|
|
|
|
|
|
if (passing) printf("Passed all tests.\n"); |
|
|
|
|
|
|
|