mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
test_crypto: add equix and hashx tests
This adds test vectors for the Equi-X proof of work algorithm and the Hash-X function it's based on. The overall Equi-X test takes about 10 seconds to run on my machine, so it's in test_crypto_slow. The hashx test still covers both the compiled and interpreted versions of the hash function. There aren't any official test vectors for Equi-X or for its particular configuration of Hash-X, so I made some up based on the current implementation. Signed-off-by: Micah Elizabeth Scott <beth@torproject.org>
This commit is contained in:
parent
92f83347f7
commit
ffa8531fe0
@ -1,6 +1,11 @@
|
|||||||
|
|
||||||
AM_CPPFLAGS += -I$(srcdir)/src/ext -Isrc/ext
|
AM_CPPFLAGS += -I$(srcdir)/src/ext -Isrc/ext
|
||||||
|
|
||||||
|
# TODO: put this with other equix/hashx ext defs when those happen,
|
||||||
|
# and also add it to the autoconf config header. For now this is here
|
||||||
|
# just for test_crypto's benefit.
|
||||||
|
AM_CPPFLAGS += -DHASHX_SIZE=8
|
||||||
|
|
||||||
EXTRA_DIST += src/ext/ext.md
|
EXTRA_DIST += src/ext/ext.md
|
||||||
|
|
||||||
EXTHEADERS = \
|
EXTHEADERS = \
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "test/test.h"
|
#include "test/test.h"
|
||||||
#include "lib/crypt_ops/aes.h"
|
#include "lib/crypt_ops/aes.h"
|
||||||
#include "siphash.h"
|
#include "siphash.h"
|
||||||
|
#include "ext/equix/hashx/include/hashx.h"
|
||||||
#include "lib/crypt_ops/crypto_curve25519.h"
|
#include "lib/crypt_ops/crypto_curve25519.h"
|
||||||
#include "lib/crypt_ops/crypto_dh.h"
|
#include "lib/crypt_ops/crypto_dh.h"
|
||||||
#include "lib/crypt_ops/crypto_ed25519.h"
|
#include "lib/crypt_ops/crypto_ed25519.h"
|
||||||
@ -2957,6 +2958,76 @@ test_crypto_blake2b(void *arg)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_crypto_hashx(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
/* Specifically test the embedded instance of HashX inside Equi-X.
|
||||||
|
* It uses a non-default setting of HASHX_SIZE=8 */
|
||||||
|
static const struct {
|
||||||
|
const char *seed_literal;
|
||||||
|
uint64_t hash_input;
|
||||||
|
const char *out_hex;
|
||||||
|
} vectors[] = {
|
||||||
|
{ "", 0, "466cc2021c268560" },
|
||||||
|
{ "a", 0, "b2a110ee695c475c" },
|
||||||
|
{ "ab", 0, "57c77f7e0d2c1727" },
|
||||||
|
{ "abc", 0, "ef560991338086d1" },
|
||||||
|
{ "", 999, "304068b62bc4874e" },
|
||||||
|
{ "a", 999, "c8b66a8eb4bba304" },
|
||||||
|
{ "ab", 999, "26c1f7031f0b3645" },
|
||||||
|
{ "abc", 999, "de84f9d286b39ab5" },
|
||||||
|
{ "abc", UINT64_MAX, "f756c266a3cb3b5a" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
hashx_type type;
|
||||||
|
} variations[] = {
|
||||||
|
{ HASHX_INTERPRETED },
|
||||||
|
#if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)
|
||||||
|
{ HASHX_COMPILED },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned num_vectors = sizeof vectors / sizeof vectors[0];
|
||||||
|
const unsigned num_variations = sizeof variations / sizeof variations[0];
|
||||||
|
|
||||||
|
for (unsigned vec_i = 0; vec_i < num_vectors; vec_i++) {
|
||||||
|
const char *seed_literal = vectors[vec_i].seed_literal;
|
||||||
|
const uint64_t hash_input = vectors[vec_i].hash_input;
|
||||||
|
const char *out_hex = vectors[vec_i].out_hex;
|
||||||
|
const size_t seed_len = strlen(seed_literal);
|
||||||
|
const size_t out_hex_len = strlen(out_hex);
|
||||||
|
|
||||||
|
int retval = -1;
|
||||||
|
uint8_t out_expected[HASHX_SIZE] = { 0 };
|
||||||
|
tt_int_op(out_hex_len, OP_EQ, 2 * HASHX_SIZE);
|
||||||
|
retval = base16_decode((char*)out_expected, HASHX_SIZE,
|
||||||
|
out_hex, out_hex_len);
|
||||||
|
tt_int_op(retval, OP_EQ, HASHX_SIZE);
|
||||||
|
|
||||||
|
for (unsigned vari_i = 0; vari_i < num_variations; vari_i++) {
|
||||||
|
uint8_t out_actual[HASHX_SIZE] = { 0 };
|
||||||
|
|
||||||
|
hashx_ctx *ctx = hashx_alloc(variations[vari_i].type);
|
||||||
|
tt_ptr_op(ctx, OP_NE, NULL);
|
||||||
|
tt_ptr_op(ctx, OP_NE, HASHX_NOTSUPP);
|
||||||
|
retval = hashx_make(ctx, seed_literal, seed_len);
|
||||||
|
tt_int_op(retval, OP_EQ, 1);
|
||||||
|
|
||||||
|
memset(out_actual, 0xa5, sizeof out_actual);
|
||||||
|
hashx_exec(ctx, hash_input, out_actual);
|
||||||
|
tt_mem_op(out_actual, OP_EQ, out_expected, sizeof out_actual);
|
||||||
|
|
||||||
|
hashx_free(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
/* We want the likelihood that the random buffer exhibits any regular pattern
|
/* We want the likelihood that the random buffer exhibits any regular pattern
|
||||||
* to be far less than the memory bit error rate in the int return value.
|
* to be far less than the memory bit error rate in the int return value.
|
||||||
* Using 2048 bits provides a failure rate of 1/(3 * 10^616), and we call
|
* Using 2048 bits provides a failure rate of 1/(3 * 10^616), and we call
|
||||||
@ -3187,6 +3258,7 @@ struct testcase_t crypto_tests[] = {
|
|||||||
{ "ed25519_storage", test_crypto_ed25519_storage, 0, NULL, NULL },
|
{ "ed25519_storage", test_crypto_ed25519_storage, 0, NULL, NULL },
|
||||||
{ "siphash", test_crypto_siphash, 0, NULL, NULL },
|
{ "siphash", test_crypto_siphash, 0, NULL, NULL },
|
||||||
{ "blake2b", test_crypto_blake2b, 0, NULL, NULL },
|
{ "blake2b", test_crypto_blake2b, 0, NULL, NULL },
|
||||||
|
{ "hashx", test_crypto_hashx, 0, NULL, NULL },
|
||||||
{ "failure_modes", test_crypto_failure_modes, TT_FORK, NULL, NULL },
|
{ "failure_modes", test_crypto_failure_modes, TT_FORK, NULL, NULL },
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define CRYPTO_S2K_PRIVATE
|
#define CRYPTO_S2K_PRIVATE
|
||||||
#include "core/or/or.h"
|
#include "core/or/or.h"
|
||||||
#include "test/test.h"
|
#include "test/test.h"
|
||||||
|
#include "ext/equix/include/equix.h"
|
||||||
#include "lib/crypt_ops/crypto_curve25519.h"
|
#include "lib/crypt_ops/crypto_curve25519.h"
|
||||||
#include "lib/crypt_ops/crypto_ed25519.h"
|
#include "lib/crypt_ops/crypto_ed25519.h"
|
||||||
#include "lib/crypt_ops/crypto_s2k.h"
|
#include "lib/crypt_ops/crypto_s2k.h"
|
||||||
@ -584,6 +585,138 @@ test_crypto_ed25519_fuzz_donna(void *arg)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_crypto_equix(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char *challenge_literal;
|
||||||
|
size_t num_solutions;
|
||||||
|
equix_solution solutions[EQUIX_MAX_SOLS];
|
||||||
|
} vectors[] = {
|
||||||
|
{ "zzz", 1, {
|
||||||
|
{{ 0xae21, 0xd392, 0x3215, 0xdd9c, 0x2f08, 0x93df, 0x232c, 0xe5dc }},
|
||||||
|
}},
|
||||||
|
{ "rrr", 1, {
|
||||||
|
{{ 0x0873, 0x57a8, 0x73e0, 0x912e, 0x1ca8, 0xad96, 0x9abd, 0xd7de }},
|
||||||
|
}},
|
||||||
|
{ "qqq", 0, {{{ 0 }}} },
|
||||||
|
{ "0123456789", 0, {{{ 0 }}} },
|
||||||
|
{ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0, {{{ 0 }}} },
|
||||||
|
{ "", 3, {
|
||||||
|
{{ 0x0098, 0x3a4d, 0xc489, 0xcfba, 0x7ef3, 0xa498, 0xa00f, 0xec20 }},
|
||||||
|
{{ 0x78d8, 0x8611, 0xa4df, 0xec19, 0x0927, 0xa729, 0x842f, 0xf771 }},
|
||||||
|
{{ 0x54b5, 0xcc11, 0x1593, 0xe624, 0x9357, 0xb339, 0xb138, 0xed99 }},
|
||||||
|
}},
|
||||||
|
{ "a", 3, {
|
||||||
|
{{ 0x4b38, 0x8c81, 0x9255, 0xad99, 0x5ce7, 0xeb3e, 0xc635, 0xee38 }},
|
||||||
|
{{ 0x3f9e, 0x659b, 0x9ae6, 0xb891, 0x63ae, 0x777c, 0x06ca, 0xc593 }},
|
||||||
|
{{ 0x2227, 0xa173, 0x365a, 0xb47d, 0x1bb2, 0xa077, 0x0d5e, 0xf25f }},
|
||||||
|
}},
|
||||||
|
{ "abc", 2, {
|
||||||
|
{{ 0x371f, 0x8865, 0x8189, 0xfbc3, 0x26df, 0xe4c0, 0xab39, 0xfe5a }},
|
||||||
|
{{ 0x2101, 0xb88f, 0xc525, 0xccb3, 0x5785, 0xa41e, 0x4fba, 0xed18 }},
|
||||||
|
}},
|
||||||
|
{ "abce", 4, {
|
||||||
|
{{ 0x4fca, 0x72eb, 0x101f, 0xafab, 0x1add, 0x2d71, 0x75a3, 0xc978 }},
|
||||||
|
{{ 0x17f1, 0x7aa6, 0x23e3, 0xab00, 0x7e2f, 0x917e, 0x16da, 0xda9e }},
|
||||||
|
{{ 0x70ee, 0x7757, 0x8a54, 0xbd2b, 0x90e4, 0xe31e, 0x2085, 0xe47e }},
|
||||||
|
{{ 0x62c5, 0x86d1, 0x5752, 0xe1f0, 0x12da, 0x8f33, 0x7336, 0xf161 }},
|
||||||
|
}},
|
||||||
|
{ "01234567890123456789", 5, {
|
||||||
|
{{ 0x4803, 0x6775, 0xc5c9, 0xd1b0, 0x1bc3, 0xe4f6, 0x4027, 0xf5ad }},
|
||||||
|
{{ 0x5a8a, 0x9542, 0xef99, 0xf0b9, 0x4905, 0x4e29, 0x2da5, 0xfbd5 }},
|
||||||
|
{{ 0x4c79, 0xc935, 0x2bcb, 0xcd0f, 0x0362, 0x9fa9, 0xa62e, 0xf83a }},
|
||||||
|
{{ 0x5878, 0x6edf, 0x1e00, 0xf5e3, 0x43de, 0x9212, 0xd01e, 0xfd11 }},
|
||||||
|
{{ 0x0b69, 0x2d17, 0x01be, 0x6cb4, 0x0fba, 0x4a9e, 0x8d75, 0xa50f }},
|
||||||
|
}},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
equix_ctx_flags flags;
|
||||||
|
equix_result expected;
|
||||||
|
} variations[] = {
|
||||||
|
{0, EQUIX_OK},
|
||||||
|
{0, EQUIX_ORDER},
|
||||||
|
{0, EQUIX_PARTIAL_SUM},
|
||||||
|
#if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)
|
||||||
|
{EQUIX_CTX_COMPILE, EQUIX_OK},
|
||||||
|
{EQUIX_CTX_COMPILE, EQUIX_ORDER},
|
||||||
|
{EQUIX_CTX_COMPILE, EQUIX_PARTIAL_SUM},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned num_vectors = sizeof vectors / sizeof vectors[0];
|
||||||
|
const unsigned num_variations = sizeof variations / sizeof variations[0];
|
||||||
|
|
||||||
|
for (unsigned vec_i = 0; vec_i < num_vectors; vec_i++) {
|
||||||
|
const char *challenge_literal = vectors[vec_i].challenge_literal;
|
||||||
|
const size_t challenge_len = strlen(challenge_literal);
|
||||||
|
|
||||||
|
const size_t num_sols = vectors[vec_i].num_solutions;
|
||||||
|
const equix_solution *sols_expected = vectors[vec_i].solutions;
|
||||||
|
|
||||||
|
for (unsigned vari_i = 0; vari_i < num_variations; vari_i++) {
|
||||||
|
const equix_ctx_flags flags = variations[vari_i].flags;
|
||||||
|
const equix_result expected = variations[vari_i].expected;
|
||||||
|
|
||||||
|
equix_solution sols_actual[EQUIX_MAX_SOLS];
|
||||||
|
equix_ctx *solve_ctx = NULL, *verify_ctx = NULL;
|
||||||
|
|
||||||
|
solve_ctx = equix_alloc(EQUIX_CTX_SOLVE | flags);
|
||||||
|
tt_ptr_op(solve_ctx, OP_NE, NULL);
|
||||||
|
tt_ptr_op(solve_ctx, OP_NE, EQUIX_NOTSUPP);
|
||||||
|
|
||||||
|
/* Solve phase: Make sure the test vector matches */
|
||||||
|
memset(sols_actual, 0xa5, sizeof sols_actual);
|
||||||
|
int retval = equix_solve(solve_ctx, challenge_literal,
|
||||||
|
challenge_len, sols_actual);
|
||||||
|
tt_int_op(retval, OP_EQ, num_sols);
|
||||||
|
tt_mem_op(sols_actual, OP_EQ, sols_expected,
|
||||||
|
num_sols * sizeof(equix_solution));
|
||||||
|
|
||||||
|
verify_ctx = equix_alloc(EQUIX_CTX_VERIFY | flags);
|
||||||
|
tt_ptr_op(verify_ctx, OP_NE, NULL);
|
||||||
|
tt_ptr_op(verify_ctx, OP_NE, EQUIX_NOTSUPP);
|
||||||
|
|
||||||
|
/* Use each solution for positive and negative tests of verify */
|
||||||
|
for (size_t sol_i = 0; sol_i < num_sols; sol_i++) {
|
||||||
|
equix_result result;
|
||||||
|
equix_idx tmp_idx;
|
||||||
|
equix_solution *sol = &sols_actual[sol_i];
|
||||||
|
|
||||||
|
switch (expected) {
|
||||||
|
case EQUIX_ORDER:
|
||||||
|
/* Swap two otherwise valid indices, to trigger an order error */
|
||||||
|
tmp_idx = sol->idx[0];
|
||||||
|
sol->idx[0] = sol->idx[1];
|
||||||
|
sol->idx[1] = tmp_idx;
|
||||||
|
break;
|
||||||
|
case EQUIX_FINAL_SUM:
|
||||||
|
case EQUIX_PARTIAL_SUM:
|
||||||
|
/* Most changes to the solution will cause a partial sum error */
|
||||||
|
sol->idx[0]++;
|
||||||
|
break;
|
||||||
|
case EQUIX_OK:
|
||||||
|
case EQUIX_CHALLENGE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = equix_verify(verify_ctx, challenge_literal,
|
||||||
|
challenge_len, sol);
|
||||||
|
tt_int_op(expected, OP_EQ, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
equix_free(solve_ctx);
|
||||||
|
equix_free(verify_ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef COCCI
|
#ifndef COCCI
|
||||||
#define CRYPTO_LEGACY(name) \
|
#define CRYPTO_LEGACY(name) \
|
||||||
{ #name, test_crypto_ ## name , 0, NULL, NULL }
|
{ #name, test_crypto_ ## name , 0, NULL, NULL }
|
||||||
@ -619,5 +752,6 @@ struct testcase_t slow_crypto_tests[] = {
|
|||||||
{ "pbkdf2_vectors", test_crypto_pbkdf2_vectors, 0, NULL, NULL },
|
{ "pbkdf2_vectors", test_crypto_pbkdf2_vectors, 0, NULL, NULL },
|
||||||
{ "pwbox", test_crypto_pwbox, 0, NULL, NULL },
|
{ "pwbox", test_crypto_pwbox, 0, NULL, NULL },
|
||||||
ED25519_TEST(fuzz_donna, TT_FORK),
|
ED25519_TEST(fuzz_donna, TT_FORK),
|
||||||
|
{ "equix", test_crypto_equix, 0, NULL, NULL },
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user