EQC Test improvements

* Generalize binary generation because it is used again and again.
* Use generalized binary generation in the hash functions since they are much faster as generators.
This commit is contained in:
Jesper Louis Andersen
2014-12-13 02:00:52 +01:00
parent b109ff7834
commit 5fec48c091
4 changed files with 128 additions and 26 deletions
+78 -1
View File
@@ -578,6 +578,81 @@ ERL_NIF_TERM enif_randombytes(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[
return enif_make_binary(env, &result);
}
/* Various other helper functions */
void uint64_pack(unsigned char *y, ErlNifUInt64 x)
{
*y++ = x; x >>= 8;
*y++ = x; x >>= 8;
*y++ = x; x >>= 8;
*y++ = x; x >>= 8;
*y++ = x; x >>= 8;
*y++ = x; x >>= 8;
*y++ = x; x >>= 8;
*y++ = x; x >>= 8;
}
ErlNifUInt64
uint64_unpack(const unsigned char *x)
{
ErlNifUInt64 result;
result = x[7];
result <<= 8; result |= x[6];
result <<= 8; result |= x[5];
result <<= 8; result |= x[4];
result <<= 8; result |= x[3];
result <<= 8; result |= x[2];
result <<= 8; result |= x[1];
result <<= 8; result |= x[0];
return result;
}
int
crypto_block(unsigned char *out, const unsigned char *in, const unsigned char *k)
{
ErlNifUInt64 v0 = uint64_unpack(in + 0);
ErlNifUInt64 v1 = uint64_unpack(in + 8);
ErlNifUInt64 k0 = uint64_unpack(k + 0);
ErlNifUInt64 k1 = uint64_unpack(k + 8);
ErlNifUInt64 k2 = uint64_unpack(k + 16);
ErlNifUInt64 k3 = uint64_unpack(k + 24);
ErlNifUInt64 sum = 0;
ErlNifUInt64 delta = 0x9e3779b97f4a7c15;
int i;
for (i = 0;i < 32;++i) {
sum += delta;
v0 += ((v1<<7) + k0) ^ (v1 + sum) ^ ((v1>>12) + k1);
v1 += ((v0<<16) + k2) ^ (v0 + sum) ^ ((v0>>8) + k3);
}
uint64_pack(out + 0,v0);
uint64_pack(out + 8,v1);
return 0;
}
static
ERL_NIF_TERM enif_scramble_block_16(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[])
{
ErlNifBinary in, out, key;
if (
(argc != 2) ||
(!enif_inspect_binary(env, argv[0], &in)) ||
(!enif_inspect_binary(env, argv[1], &key)) ||
(in.size != 16) || (key.size != 32)) {
return enif_make_badarg(env);
}
if (!enif_alloc_binary(in.size, &out)) {
return nacl_error_tuple(env, "alloc_failed");
}
crypto_block(out.data, in.data, key.data);
return enif_make_binary(env, &out);
}
/* Tie the knot to the Erlang world */
static ErlNifFunc nif_funcs[] = {
{"crypto_box_NONCEBYTES", 0, enif_crypto_box_NONCEBYTES},
@@ -635,7 +710,9 @@ static ErlNifFunc nif_funcs[] = {
{"crypto_verify_32", 2, enif_crypto_verify_32},
{"randombytes_b", 1, enif_randombytes},
{"randombytes", 1, enif_randombytes, ERL_NIF_DIRTY_JOB_CPU_BOUND}
{"randombytes", 1, enif_randombytes, ERL_NIF_DIRTY_JOB_CPU_BOUND},
{"scramble_block_16", 2, enif_scramble_block_16}
};