test_ct.cxx 4.01 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
/**
 * @file test_decaf.cxx
 * @author Mike Hamburg
 *
 * @copyright
 *   Copyright (c) 2015 Cryptography Research, Inc.  \n
 *   Released under the MIT License.  See LICENSE.txt for license information.
 *
 * @brief C++ tests, because that's easier.
 */

#include <decaf.hxx>
13
#include <decaf/spongerng.hxx>
14 15 16
#include <decaf/crypto.h>
#include <decaf/crypto.hxx>
#include <stdio.h>
17
#include <valgrind/memcheck.h>
18 19

using namespace decaf;
20
using namespace decaf::TOY;
21

22
static const long NTESTS = 10;
23

24
const char *undef_str = "Valgrind thinks this string is undefined.";
25 26
const Block undef_block(undef_str);

27
static inline void ignore_result(decaf_error_t x) {
28 29 30
    (void)x;
}

31 32 33 34 35 36 37
template<typename Group> struct Tests {

typedef typename Group::Scalar Scalar;
typedef typename Group::Point Point;
typedef typename Group::Precomputed Precomputed;

static void test_arithmetic() {
38
    SpongeRng rng(Block("test_arithmetic"),SpongeRng::DETERMINISTIC);
39
    rng.stir(undef_block);
40 41
    
    Scalar x(rng),y(rng),z;
42
    uint8_t ser[Group::Scalar::SER_BYTES];
43 44 45 46 47
        
    for (int i=0; i<NTESTS; i++) {
        (void)(x+y);
        (void)(x-y);
        (void)(x*y);
48
        ignore_result(x.inverse_noexcept(y));
49 50
        (void)(x==y);
        (void)(z=y);
51
        x.serialize_into(ser);
52 53 54 55 56
        x = y;
    }
}

static void test_elligator() {
57
    SpongeRng rng(Block("test_elligator"),SpongeRng::DETERMINISTIC);
58
    rng.stir(undef_block);
59 60
    
    FixedArrayBuffer<Group::Point::HASH_BYTES> inv;
61 62
        
    for (int i=0; i<NTESTS; i++) {
63 64
        Point x(rng), y(rng,false);
        
65
        ignore_result((x+y).invert_elligator(inv,i));
66 67 68 69
    }
}

static void test_ec() {
70
    SpongeRng rng(Block("test_ec"),SpongeRng::DETERMINISTIC);
71 72 73
    rng.stir(undef_block);

    uint8_t ser[Group::Point::SER_BYTES];
74 75 76 77

    for (int i=0; i<NTESTS; i++) {
        Scalar y(rng),z(rng);
        Point p(rng),q(rng),r;
78

79
        p.serialize_into(ser);
80
        ignore_result(p.decode(FixedBlock<Group::Point::SER_BYTES>(ser)));
81 82 83 84 85 86 87
        (void)(p*y);
        (void)(p+q);
        (void)(p-q);
        (void)(-p);
        (void)(p.times_two());
        (void)(p==q);
        (void)(p.debugging_torque());
88
        /* (void)(p.non_secret_combo_with_base(y,z)); */ /* Should fail */
89 90
        (void)(Precomputed(p)*y);
        p.dual_scalarmul(q,r,y,z);
91
        Group::Point::double_scalarmul(p,y,q,z);
92 93 94 95
        
    }
}

96 97 98 99 100 101 102 103
static void test_cfrg() {
    SpongeRng rng(Block("test_cfrg"),SpongeRng::DETERMINISTIC);
    rng.stir(undef_block);
    
    for (int i=0; i<NTESTS; i++) {
        FixedArrayBuffer<Group::DhLadder::PUBLIC_BYTES> pub(rng);
        FixedArrayBuffer<Group::DhLadder::PRIVATE_BYTES> priv(rng);
        
Michael Hamburg's avatar
Michael Hamburg committed
104
        Group::DhLadder::derive_public_key(priv);
105
        ignore_result(Group::DhLadder::shared_secret_noexcept(pub,pub,priv));
106 107
    }
}
108

109 110 111 112 113
/* 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

114
static void test_crypto() {
115
    SpongeRng rng(Block("test_crypto"),SpongeRng::DETERMINISTIC);
116
    rng.stir(undef_block);
117 118 119 120 121 122

#if DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT
    SpongeRng defrng(Block("test_crypto_defined"));
#endif
    
    FixedArrayBuffer<Group::Point::SER_BYTES> shared;
123 124 125 126
    
    for (int i=0; i<NTESTS; i++) {
        PrivateKey<Group> sk1(rng);
        SecureBuffer sig = sk1.sign(undef_block);
127 128 129

#if DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT
        PrivateKey<Group> sk2(defrng);
130
        ignore_result(sk1.shared_secret_noexcept(shared,sk2.pub(),i&1));
131 132
#else
        PrivateKey<Group> sk3(rng);
133
        ignore_result(sk1.shared_secret_noexcept(shared,sk3.pub(),i&1));
134
#endif
135
    }
136 137
}

138 139 140 141 142 143 144 145 146 147 148
static void run() {
    printf("Testing %s:\n",Group::name());
    test_arithmetic();
    test_elligator();
    test_ec();
    test_cfrg();
    test_crypto();
    printf("\n");
}

}; /* template<GroupId GROUP> struct Tests */
149 150 151 152

int main(int argc, char **argv) {
    (void) argc; (void) argv;
    VALGRIND_MAKE_MEM_UNDEFINED(undef_str, strlen(undef_str));
153
    run_for_all_curves<Tests>();    
154
    return 0;
155
}