]> git.codecow.com Git - Monocypher.git/commitdiff
fused self containted tests together
authorLoup Vaillant <loup@loup-vaillant.fr>
Sun, 23 Jul 2017 15:26:10 +0000 (17:26 +0200)
committerLoup Vaillant <loup@loup-vaillant.fr>
Sun, 23 Jul 2017 15:26:10 +0000 (17:26 +0200)
.gitignore
makefile
test.sh
tests/self.c [moved from tests/properties.c with 51% similarity]
tests/sodium.c
tests/vectors.c [deleted file]

index f160ef631788119752bab2336ae10f953755c60b..b5cbdcaddc4b6c0879ce5ccf68d6275c3e78e35f 100644 (file)
@@ -7,8 +7,7 @@
 *.profdata
 bin/*
 formal-analysis/*
-properties
-vectors
+self
 sodium
 donna
 speed
index bcdd9f85bb262401440d95a11a18308e407fa583..1ca8bbdd98b178d7ef4e516fffe4dedfb34a1b75 100644 (file)
--- a/makefile
+++ b/makefile
@@ -24,15 +24,14 @@ CFLAGS= -I src -pedantic -Wall -Wextra -O3 -march=native
 # disable implicit rules
 .SUFFIXES:
 
-all: vectors properties sodium donna
+all: self sodium donna
 
 clean:
        rm -rf bin formal-analysis
        rm -f src/*.gch src/rename_*
-       rm -f vectors properties sodium donna speed
+       rm -f self sodium donna speed
 
-TEST_DEPS=tests/vectors.c bin/monocypher.o bin/sha512.o
-PROP_DEPS=tests/properties.c bin/classic_monocypher.o bin/sha512.o
+TEST_DEPS=tests/self.c bin/monocypher.o bin/sha512.o
 GEN_HEADERS=bin/argon2i.h      \
             bin/blake2b.h      \
             bin/blake2b_easy.h \
@@ -46,8 +45,8 @@ GEN_HEADERS=bin/argon2i.h      \
             bin/x25519.h       \
             bin/x_chacha20.h
 
-# Test suite based on test vectors
-vectors: $(TEST_DEPS) $(GEN_HEADERS)
+# self containted test suite (vectors and properties)
+self: $(TEST_DEPS) $(GEN_HEADERS)
        $(CC) $(CFLAGS) -I bin -o $@ $(TEST_DEPS)
 
 bin/vector: tests/vector_to_header.c
@@ -58,10 +57,6 @@ bin/%.h: tests/vectors/% bin/vector
        @echo generate $@
        @bin/vector $$(basename $<) <$< >$@
 
-# Property based tests (consistency)
-properties: $(PROP_DEPS) $(GEN_HEADERS)
-       $(CC) $(CFLAGS) -I bin -o $@ $(PROP_DEPS)
-
 # Test suite based on comparison with libsodium
 C_SODIUM_FLAGS=$$(pkg-config --cflags libsodium)
 LD_SODIUM_FLAGS=$$(pkg-config --libs libsodium)
@@ -117,7 +112,7 @@ rename_%.h: %.h
 formal-analysis: $(GEN_HEADERS)                    \
          src/monocypher.c src/monocypher.h \
          src/sha512.c src/sha512.h         \
-         tests/vectors.c
+         tests/self.c
        @echo "copy sources to formal-analysis directory for analysis (frama-c or TIS)"
        @mkdir -p formal-analysis
        @cp $^ formal-analysis
diff --git a/test.sh b/test.sh
index 91f9220318036d27a9e65ca0069095a58d7c2886..a2a61065a5d5d30f2441596402b91f14861d3a0a 100755 (executable)
--- a/test.sh
+++ b/test.sh
@@ -2,44 +2,37 @@
 
 echo
 echo "Build"
-echo "-----"
-make vectors properties sodium donna
+echo "====="
+make self sodium donna
 
 echo
-echo "Tests against vectors"
-echo "---------------------"
-./vectors
+echo "Self contained tests"
+echo "===================="
+./self
 retval_test=$?
 
-echo
-echo "Random self-consistency tests"
-echo "-----------------------------"
-./properties
-retval_prop=$?
-
 echo
 echo "Random comparison tests with libsodium"
-echo "--------------------------------------"
+echo "======================================"
 ./sodium
 retval_sodium=$?
 
 echo
 echo "Random comparison tests with ed25519-donna)"
-echo "-------------------------------------------"
+echo "==========================================="
 ./donna
 retval_donna=$?
 
 echo
 if [ "$retval_test"   -ne 0 ] ||\
-   [ "$retval_prop"   -ne 0 ] ||\
    [ "$retval_sodium" -ne 0 ] ||\
    [ "$retval_donna"  -ne 0 ]
 then
     echo "TESTS FAILED.  VERIFY IMPLEMENTATION.  REPORT BUG"
     echo "DO. NOT. USE."
 else
-    echo "-------------------"
-    echo "-- All tests OK! --"
-    echo "-------------------"
+    echo "==================="
+    echo "== All tests OK! =="
+    echo "==================="
     echo ""
 fi
similarity index 51%
rename from tests/properties.c
rename to tests/self.c
index eed3a4af196f21824790124ca851ee40eda9c87f..75df5bca184152acfe6b5055bdaccc1a21b2b186 100644 (file)
 #include "monocypher.h"
 #include "sha512.h"
 
+#include "chacha20.h"
+#include "argon2i.h"
+#include "blake2b.h"
+#include "blake2b_easy.h"
+#include "ed25519_key.h"
+#include "ed25519_sign.h"
+#include "h_chacha20.h"
+#include "key_exchange.h"
+#include "poly1305.h"
+#include "v_sha512.h"
+#include "x25519.h"
+#include "x_chacha20.h"
+
 #define FOR(i, start, end) for (size_t (i) = (start); (i) < (end); (i)++)
+typedef  int8_t   i8;
 typedef uint8_t   u8;
 typedef uint32_t u32;
 typedef  int32_t i32;
 typedef  int64_t i64;
 typedef uint64_t u64;
 
+/////////////////
+/// Utilities ///
+/////////////////
+
+static void* alloc(size_t size)
+{
+    void *buf = malloc(size);
+    if (buf == NULL) {
+        fprintf(stderr, "Allocation failed\n");
+        exit(1);
+    }
+    return buf;
+}
+
+typedef struct {
+    u8     *buf;
+    size_t  size;
+} vector;
+
+static int test(void (*f)(const vector[], vector*),
+                const char *name, size_t nb_inputs,
+                size_t nb_vectors, u8 **vectors, size_t *sizes)
+{
+    int     status   = 0;
+    int     nb_tests = 0;
+    size_t  idx      = 0;
+    vector *in;
+    in = (vector*)alloc(nb_vectors * sizeof(vector));
+    while (idx < nb_vectors) {
+        size_t out_size = sizes[idx + nb_inputs];
+        vector out;
+        out.buf  = (u8*)alloc(out_size);
+        out.size = out_size;
+        FOR (i, 0, nb_inputs) {
+            in[i].buf  = vectors[idx+i];
+            in[i].size = sizes  [idx+i];
+        }
+        f(in, &out);
+        vector expected;
+        expected.buf  = vectors[idx+nb_inputs];
+        expected.size = sizes  [idx+nb_inputs];
+        status |= out.size - expected.size;
+        status |= crypto_memcmp(out.buf, expected.buf, out.size);
+        free(out.buf);
+        idx += nb_inputs + 1;
+        nb_tests++;
+    }
+    free(in);
+    printf("%s %3d tests: %s\n",
+           status != 0 ? "FAILED" : "OK", nb_tests, name);
+    return status;
+}
+
+#define TEST(name, nb_inputs) test(name, #name, nb_inputs, \
+                                   nb_##name##_vectors,    \
+                                   name##_vectors,         \
+                                   name##_sizes)
+
+////////////////////////
+/// The tests proper ///
+////////////////////////
+static void chacha20(const vector in[], vector *out)
+{
+    const vector *key   = in;
+    const vector *nonce = in + 1;
+    crypto_chacha_ctx ctx;
+    crypto_chacha20_init  (&ctx, key->buf, nonce->buf);
+    crypto_chacha20_stream(&ctx, out->buf, out->size);
+}
+
+static void h_chacha20(const vector in[], vector *out)
+{
+    const vector *key   = in;
+    const vector *input = in + 1;
+    crypto_chacha20_H(out->buf, key->buf, input->buf);
+}
+
+static void x_chacha20(const vector in[], vector *out)
+{
+    const vector *key   = in;
+    const vector *nonce = in + 1;
+    crypto_chacha_ctx ctx;
+    crypto_chacha20_x_init(&ctx, key->buf, nonce->buf);
+    crypto_chacha20_stream(&ctx, out->buf, out->size);
+}
+
+static void blake2b(const vector in[], vector *out)
+{
+    const vector *msg = in;
+    const vector *key = in + 1;
+    crypto_blake2b_general(out->buf, out->size,
+                           key->buf, key->size,
+                           msg->buf, msg->size);
+}
+
+static void blake2b_easy(const vector in[], vector *out)
+{
+    crypto_blake2b(out->buf, in->buf, in->size);
+}
+
+static void poly1305(const vector in[], vector *out)
+{
+    const vector *key = in;
+    const vector *msg = in + 1;
+    crypto_poly1305_auth(out->buf, msg->buf, msg->size, key->buf);
+}
+
+static void argon2i(const vector in[], vector *out)
+{
+    u32 nb_blocks = 0;
+    u32 nb_iterations = 0;
+    FOR (i, 0, in[0].size) {nb_blocks     <<= 8; nb_blocks     += in[0].buf[i];}
+    FOR (i, 0, in[1].size) {nb_iterations <<= 8; nb_iterations += in[1].buf[i];}
+    const vector *password      = in + 2;
+    const vector *salt          = in + 3;
+    const vector *key           = in + 4;
+    const vector *ad            = in + 5;
+    void         *work_area     = alloc(nb_blocks * 1024);
+    crypto_argon2i(out->buf, out->size,
+                   work_area, nb_blocks, nb_iterations,
+                   password->buf, password->size,
+                   salt    ->buf, salt    ->size,
+                   key     ->buf, key     ->size,
+                   ad      ->buf, ad      ->size);
+    free(work_area);
+}
+
+static void x25519(const vector in[], vector *out)
+{
+    const vector *scalar = in;
+    const vector *point  = in + 1;
+    int report   = crypto_x25519(out->buf, scalar->buf, point->buf);
+    int not_zero = crypto_zerocmp(out->buf, out->size);
+    if ( not_zero &&  report)  printf("FAILURE: x25519 false all_zero report\n");
+    if (!not_zero && !report)  printf("FAILURE: x25519 failed to report zero\n");
+}
+
+static void iterate_x25519(u8 k[32], u8 u[32])
+{
+    u8 tmp[32];
+    crypto_x25519(tmp , k, u);
+    memcpy(u, k  , 32);
+    memcpy(k, tmp, 32);
+}
+
+static int test_x25519()
+{
+    u8 _1   [32] = {0x42, 0x2c, 0x8e, 0x7a, 0x62, 0x27, 0xd7, 0xbc,
+                    0xa1, 0x35, 0x0b, 0x3e, 0x2b, 0xb7, 0x27, 0x9f,
+                    0x78, 0x97, 0xb8, 0x7b, 0xb6, 0x85, 0x4b, 0x78,
+                    0x3c, 0x60, 0xe8, 0x03, 0x11, 0xae, 0x30, 0x79};
+    u8 k[32] = {9};
+    u8 u[32] = {9};
+
+    crypto_x25519_public_key(k, u);
+    int status = crypto_memcmp(k, _1, 32);
+    printf("%s: x25519 1\n", status != 0 ? "FAILED" : "OK");
+
+    u8 _1k  [32] = {0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55,
+                    0x28, 0x00, 0xef, 0x56, 0x6f, 0x2f, 0x4d, 0x3c,
+                    0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60, 0xe3, 0x87,
+                    0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51};
+    FOR (i, 1, 1000) { iterate_x25519(k, u); }
+    status |= crypto_memcmp(k, _1k, 32);
+    printf("%s: x25519 1K\n", status != 0 ? "FAILED" : "OK");
+
+    // too long; didn't run
+    //u8 _100k[32] = {0x7c, 0x39, 0x11, 0xe0, 0xab, 0x25, 0x86, 0xfd,
+    //                0x86, 0x44, 0x97, 0x29, 0x7e, 0x57, 0x5e, 0x6f,
+    //                0x3b, 0xc6, 0x01, 0xc0, 0x88, 0x3c, 0x30, 0xdf,
+    //                0x5f, 0x4d, 0xd2, 0xd2, 0x4f, 0x66, 0x54, 0x24};
+    //FOR (i, 1000, 1000000) { iterate_x25519(k, u); }
+    //status |= crypto_memcmp(k, _100k, 32);
+    //printf("%s: x25519 1M\n", status != 0 ? "FAILED" : "OK");
+    return status;
+}
+
+static void v_sha512(const vector in[], vector *out)
+{
+    crypto_sha512(out->buf, in->buf, in->size);
+}
+
+static void ed25519_key(const vector in[], vector *out)
+{
+    crypto_sign_public_key(out->buf, in->buf);
+}
+
+static void ed25519_sign(const vector in[], vector *out)
+{
+    const vector *secret_k = in;
+    const vector *public_k = in + 1;
+    const vector *msg      = in + 2;
+    u8            out2[64];
+
+    // Sign with cached public key, then by reconstructing the key
+    crypto_sign(out->buf, secret_k->buf, public_k->buf, msg->buf, msg->size);
+    crypto_sign(out2    , secret_k->buf, 0            , msg->buf, msg->size);
+    // Compare signatures (must be the same)
+    if (crypto_memcmp(out->buf, out2, out->size)) {
+        printf("FAILURE: reconstructing public key"
+               " yields different signature\n");
+    }
+
+    // test successful signature verification
+    if (crypto_check(out->buf, public_k->buf, msg->buf, msg->size)) {
+        printf("FAILURE: signature check failed to recognise signature\n");
+    }
+    // test forgery rejections
+    u8 fake_signature1[64];
+    u8 fake_signature2[64];
+    FOR (i, 0, 64) {
+        fake_signature1[i] = out->buf[i] + 1;
+        fake_signature2[i] = out->buf[i] + 1;
+    }
+    if (!crypto_check(fake_signature1, public_k->buf, msg->buf, msg->size) ||
+        !crypto_check(fake_signature2, public_k->buf, msg->buf, msg->size)) {
+        printf("FAILURE: signature check failed to reject forgery\n");
+    }
+}
+
+static void key_exchange(const vector in[], vector *out)
+{
+    const vector *secret_key = in;
+    const vector *public_key = in + 1;
+    crypto_key_exchange(out->buf, secret_key->buf, public_key->buf);
+}
+
+
+
+//////////////////////////////
+/// Self consistency tests ///
+//////////////////////////////
 // Deterministic "random" number generator, so we can make "random", yet
 // reproducible tests.  To change the random stream, change the seed.
-void p_random(u8 *stream, size_t size)
+static void p_random(u8 *stream, size_t size)
 {
     static crypto_chacha_ctx ctx;
     static int is_init = 0;
@@ -27,7 +273,7 @@ void p_random(u8 *stream, size_t size)
 }
 
 // Random 64 bit number
-u64 rand64()
+static u64 rand64()
 {
     u8  tmp;
     u64 result = 0;
@@ -39,9 +285,11 @@ u64 rand64()
     return result;
 }
 
+
+
 // Tests that encrypting in chunks yields the same result than
 // encrypting all at once.
-static int chacha20()
+static int p_chacha20()
 {
     static const size_t block_size = 64;             // Chacha Block size
     static const size_t input_size = block_size * 4; // total input size
@@ -79,7 +327,7 @@ static int chacha20()
     return status;
 }
 
-static int chacha20_set_ctr()
+static int p_chacha20_set_ctr()
 {
     static const size_t nb_blocks   = 10;
     static const size_t block_size  = 64;
@@ -122,7 +370,7 @@ static int chacha20_set_ctr()
 
 // Tests that authenticating bit by bit yields the same mac than
 // authenticating all at once
-static int poly1305()
+static int p_poly1305()
 {
     static const size_t block_size = 16;             // poly1305 block size
     static const size_t input_size = block_size * 4; // total input size
@@ -162,7 +410,7 @@ static int poly1305()
 // at once.  Note: I figured we didn't need to test keyed mode, or
 // different hash sizes, again.  This test sticks to the simplified
 // interface.
-static int blake2b()
+static int p_blake2b()
 {
     static const size_t block_size = 128;            // Blake2b block size
     static const size_t input_size = block_size * 4; // total input size
@@ -199,7 +447,7 @@ static int blake2b()
 
 // Tests that hashing bit by bit yields the same hash than hashing all
 // at once. (for sha512)
-static int sha512()
+static int p_sha512()
 {
     static const size_t block_size = 128;            // Blake2b block size
     static const size_t input_size = block_size * 4; // total input size
@@ -234,7 +482,7 @@ static int sha512()
     return status;
 }
 
-static int aead()
+static int p_aead()
 {
     int status = 0;
     FOR (i, 0, 1000) {
@@ -273,11 +521,30 @@ static int aead()
 int main(void)
 {
     int status = 0;
-    status |= chacha20();
-    status |= chacha20_set_ctr();
-    status |= poly1305();
-    status |= blake2b();
-    status |= sha512();
-    status |= aead();
+    printf("\nTest against vectors");
+    printf("\n--------------------\n");
+    status |= TEST(chacha20    , 2);
+    status |= TEST(h_chacha20  , 2);
+    status |= TEST(x_chacha20  , 2);
+    status |= TEST(blake2b     , 2);
+    status |= TEST(blake2b_easy, 1);
+    status |= TEST(poly1305    , 2);
+    status |= TEST(argon2i     , 6);
+    status |= TEST(x25519      , 2);
+    status |= TEST(key_exchange, 2);
+    status |= TEST(v_sha512    , 1);
+    status |= TEST(ed25519_key , 1);
+    status |= TEST(ed25519_sign, 3);
+    status |= test_x25519();
+
+    printf("\nProperty based tests tests");
+    printf("\n--------------------------\n");
+    status |= p_chacha20();
+    status |= p_chacha20_set_ctr();
+    status |= p_poly1305();
+    status |= p_blake2b();
+    status |= p_sha512();
+    status |= p_aead();
+
     return status;
 }
index ce377ff0abede06e95dd68a0cfe362f2d0ceedbd..38834977852b2f0d5f308232b8653be74c354641 100644 (file)
@@ -110,7 +110,7 @@ static int blake2b(void)
 static int argon2i(void)
 {
     u8 work_area[1024*1024], password[16], salt[crypto_pwhash_SALTBYTES],
-        mono[32], sodium[32];
+        mono[32], sodium[32]; // check output sizes > 64
     int status = 0;
     FOR (nb_blocks, 8, 1024) {
         p_random(password, 16);
diff --git a/tests/vectors.c b/tests/vectors.c
deleted file mode 100644 (file)
index a45e0f0..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "monocypher.h"
-#include "sha512.h"
-
-#include "chacha20.h"
-#include "argon2i.h"
-#include "blake2b.h"
-#include "blake2b_easy.h"
-#include "ed25519_key.h"
-#include "ed25519_sign.h"
-#include "h_chacha20.h"
-#include "key_exchange.h"
-#include "poly1305.h"
-#include "v_sha512.h"
-#include "x25519.h"
-#include "x_chacha20.h"
-
-#define FOR(i, start, end) for (size_t (i) = (start); (i) < (end); (i)++)
-typedef  int8_t   i8;
-typedef uint8_t   u8;
-typedef uint32_t u32;
-typedef  int32_t i32;
-typedef  int64_t i64;
-typedef uint64_t u64;
-
-/////////////////
-/// Utilities ///
-/////////////////
-
-static void* alloc(size_t size)
-{
-    void *buf = malloc(size);
-    if (buf == NULL) {
-        fprintf(stderr, "Allocation failed\n");
-        exit(1);
-    }
-    return buf;
-}
-
-typedef struct {
-    u8     *buf;
-    size_t  size;
-} vector;
-
-static int test(void (*f)(const vector[], vector*),
-                const char *name, size_t nb_inputs,
-                size_t nb_vectors, u8 **vectors, size_t *sizes)
-{
-    int     status   = 0;
-    int     nb_tests = 0;
-    size_t  idx      = 0;
-    vector *in;
-    in = (vector*)alloc(nb_vectors * sizeof(vector));
-    while (idx < nb_vectors) {
-        size_t out_size = sizes[idx + nb_inputs];
-        vector out;
-        out.buf  = (u8*)alloc(out_size);
-        out.size = out_size;
-        FOR (i, 0, nb_inputs) {
-            in[i].buf  = vectors[idx+i];
-            in[i].size = sizes  [idx+i];
-        }
-        f(in, &out);
-        vector expected;
-        expected.buf  = vectors[idx+nb_inputs];
-        expected.size = sizes  [idx+nb_inputs];
-        status |= out.size - expected.size;
-        status |= crypto_memcmp(out.buf, expected.buf, out.size);
-        free(out.buf);
-        idx += nb_inputs + 1;
-        nb_tests++;
-    }
-    free(in);
-    printf("%s %3d tests: %s\n",
-           status != 0 ? "FAILED" : "OK", nb_tests, name);
-    return status;
-}
-
-#define TEST(name, nb_inputs) test(name, #name, nb_inputs, \
-                                   nb_##name##_vectors,    \
-                                   name##_vectors,         \
-                                   name##_sizes)
-
-////////////////////////
-/// The tests proper ///
-////////////////////////
-static void chacha20(const vector in[], vector *out)
-{
-    const vector *key   = in;
-    const vector *nonce = in + 1;
-    crypto_chacha_ctx ctx;
-    crypto_chacha20_init  (&ctx, key->buf, nonce->buf);
-    crypto_chacha20_stream(&ctx, out->buf, out->size);
-}
-
-static void h_chacha20(const vector in[], vector *out)
-{
-    const vector *key   = in;
-    const vector *input = in + 1;
-    crypto_chacha20_H(out->buf, key->buf, input->buf);
-}
-
-static void x_chacha20(const vector in[], vector *out)
-{
-    const vector *key   = in;
-    const vector *nonce = in + 1;
-    crypto_chacha_ctx ctx;
-    crypto_chacha20_x_init(&ctx, key->buf, nonce->buf);
-    crypto_chacha20_stream(&ctx, out->buf, out->size);
-}
-
-static void blake2b(const vector in[], vector *out)
-{
-    const vector *msg = in;
-    const vector *key = in + 1;
-    crypto_blake2b_general(out->buf, out->size,
-                           key->buf, key->size,
-                           msg->buf, msg->size);
-}
-
-static void blake2b_easy(const vector in[], vector *out)
-{
-    crypto_blake2b(out->buf, in->buf, in->size);
-}
-
-static void poly1305(const vector in[], vector *out)
-{
-    const vector *key = in;
-    const vector *msg = in + 1;
-    crypto_poly1305_auth(out->buf, msg->buf, msg->size, key->buf);
-}
-
-static void argon2i(const vector in[], vector *out)
-{
-    u32 nb_blocks = 0;
-    u32 nb_iterations = 0;
-    FOR (i, 0, in[0].size) {nb_blocks     <<= 8; nb_blocks     += in[0].buf[i];}
-    FOR (i, 0, in[1].size) {nb_iterations <<= 8; nb_iterations += in[1].buf[i];}
-    const vector *password      = in + 2;
-    const vector *salt          = in + 3;
-    const vector *key           = in + 4;
-    const vector *ad            = in + 5;
-    void         *work_area     = alloc(nb_blocks * 1024);
-    crypto_argon2i(out->buf, out->size,
-                   work_area, nb_blocks, nb_iterations,
-                   password->buf, password->size,
-                   salt    ->buf, salt    ->size,
-                   key     ->buf, key     ->size,
-                   ad      ->buf, ad      ->size);
-    free(work_area);
-}
-
-static void x25519(const vector in[], vector *out)
-{
-    const vector *scalar = in;
-    const vector *point  = in + 1;
-    int report   = crypto_x25519(out->buf, scalar->buf, point->buf);
-    int not_zero = crypto_zerocmp(out->buf, out->size);
-    if ( not_zero &&  report)  printf("FAILURE: x25519 false all_zero report\n");
-    if (!not_zero && !report)  printf("FAILURE: x25519 failed to report zero\n");
-}
-
-static void iterate_x25519(u8 k[32], u8 u[32])
-{
-    u8 tmp[32];
-    crypto_x25519(tmp , k, u);
-    memcpy(u, k  , 32);
-    memcpy(k, tmp, 32);
-}
-
-static int test_x25519()
-{
-    u8 _1   [32] = {0x42, 0x2c, 0x8e, 0x7a, 0x62, 0x27, 0xd7, 0xbc,
-                    0xa1, 0x35, 0x0b, 0x3e, 0x2b, 0xb7, 0x27, 0x9f,
-                    0x78, 0x97, 0xb8, 0x7b, 0xb6, 0x85, 0x4b, 0x78,
-                    0x3c, 0x60, 0xe8, 0x03, 0x11, 0xae, 0x30, 0x79};
-    u8 k[32] = {9};
-    u8 u[32] = {9};
-
-    crypto_x25519_public_key(k, u);
-    int status = crypto_memcmp(k, _1, 32);
-    printf("%s: x25519 1\n", status != 0 ? "FAILED" : "OK");
-
-    u8 _1k  [32] = {0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55,
-                    0x28, 0x00, 0xef, 0x56, 0x6f, 0x2f, 0x4d, 0x3c,
-                    0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60, 0xe3, 0x87,
-                    0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51};
-    FOR (i, 1, 1000) { iterate_x25519(k, u); }
-    status |= crypto_memcmp(k, _1k, 32);
-    printf("%s: x25519 1K\n", status != 0 ? "FAILED" : "OK");
-
-    // too long; didn't run
-    //u8 _100k[32] = {0x7c, 0x39, 0x11, 0xe0, 0xab, 0x25, 0x86, 0xfd,
-    //                0x86, 0x44, 0x97, 0x29, 0x7e, 0x57, 0x5e, 0x6f,
-    //                0x3b, 0xc6, 0x01, 0xc0, 0x88, 0x3c, 0x30, 0xdf,
-    //                0x5f, 0x4d, 0xd2, 0xd2, 0x4f, 0x66, 0x54, 0x24};
-    //FOR (i, 1000, 1000000) { iterate_x25519(k, u); }
-    //status |= crypto_memcmp(k, _100k, 32);
-    //printf("%s: x25519 1M\n", status != 0 ? "FAILED" : "OK");
-    return status;
-}
-
-static void v_sha512(const vector in[], vector *out)
-{
-    crypto_sha512(out->buf, in->buf, in->size);
-}
-
-static void ed25519_key(const vector in[], vector *out)
-{
-    crypto_sign_public_key(out->buf, in->buf);
-}
-
-static void ed25519_sign(const vector in[], vector *out)
-{
-    const vector *secret_k = in;
-    const vector *public_k = in + 1;
-    const vector *msg      = in + 2;
-    u8            out2[64];
-
-    // Sign with cached public key, then by reconstructing the key
-    crypto_sign(out->buf, secret_k->buf, public_k->buf, msg->buf, msg->size);
-    crypto_sign(out2    , secret_k->buf, 0            , msg->buf, msg->size);
-    // Compare signatures (must be the same)
-    if (crypto_memcmp(out->buf, out2, out->size)) {
-        printf("FAILURE: reconstructing public key"
-               " yields different signature\n");
-    }
-
-    // test successful signature verification
-    if (crypto_check(out->buf, public_k->buf, msg->buf, msg->size)) {
-        printf("FAILURE: signature check failed to recognise signature\n");
-    }
-    // test forgery rejections
-    u8 fake_signature1[64];
-    u8 fake_signature2[64];
-    FOR (i, 0, 64) {
-        fake_signature1[i] = out->buf[i] + 1;
-        fake_signature2[i] = out->buf[i] + 1;
-    }
-    if (!crypto_check(fake_signature1, public_k->buf, msg->buf, msg->size) ||
-        !crypto_check(fake_signature2, public_k->buf, msg->buf, msg->size)) {
-        printf("FAILURE: signature check failed to reject forgery\n");
-    }
-}
-
-static void key_exchange(const vector in[], vector *out)
-{
-    const vector *secret_key = in;
-    const vector *public_key = in + 1;
-    crypto_key_exchange(out->buf, secret_key->buf, public_key->buf);
-}
-
-int main(void)
-{
-    int status = 0;
-    status |= TEST(chacha20    , 2);
-    status |= TEST(h_chacha20  , 2);
-    status |= TEST(x_chacha20  , 2);
-    status |= TEST(blake2b     , 2);
-    status |= TEST(blake2b_easy, 1);
-    status |= TEST(poly1305    , 2);
-    status |= TEST(argon2i     , 6);
-    status |= TEST(x25519      , 2);
-    status |= TEST(key_exchange, 2);
-    status |= TEST(v_sha512    , 1);
-    status |= TEST(ed25519_key , 1);
-    status |= TEST(ed25519_sign, 3);
-    status |= test_x25519();
-    return status;
-}