Split extension functions away
This commit is contained in:
parent
d06fff489d
commit
78621356ec
86
c_src/enacl_ext.c
Normal file
86
c_src/enacl_ext.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include <sodium.h>
|
||||
|
||||
#include <erl_nif.h>
|
||||
|
||||
#include "enacl.h"
|
||||
#include "enacl_ext.h"
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
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 enacl_error_tuple(env, "alloc_failed");
|
||||
}
|
||||
|
||||
crypto_block(out.data, in.data, key.data);
|
||||
|
||||
return enif_make_binary(env, &out);
|
||||
}
|
9
c_src/enacl_ext.h
Normal file
9
c_src/enacl_ext.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef ENACL_EXT_H
|
||||
#define ENACL_EXT_H
|
||||
|
||||
#include <erl_nif.h>
|
||||
|
||||
ERL_NIF_TERM enif_scramble_block_16(ErlNifEnv *env, int argc,
|
||||
ERL_NIF_TERM const argv[]);
|
||||
|
||||
#endif
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "aead.h"
|
||||
#include "enacl.h"
|
||||
#include "enacl_ext.h"
|
||||
#include "generichash.h"
|
||||
#include "hash.h"
|
||||
#include "kx.h"
|
||||
@ -121,11 +122,12 @@ enacl_crypto_curve25519_scalarmult(ErlNifEnv *env, int argc,
|
||||
|
||||
do {
|
||||
if (!enif_alloc_binary(crypto_scalarmult_curve25519_BYTES, &output)) {
|
||||
result = enacl_error_tuple(env, "alloc_failed");
|
||||
result = enacl_internal_error(env);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (crypto_scalarmult_curve25519(output.data, secret.data, bp) < 0) {
|
||||
if (crypto_scalarmult_curve25519(output.data, secret.data, bp) != 0) {
|
||||
enif_release_binary(&output);
|
||||
result = enacl_error_tuple(env, "scalarmult_curve25519_failed");
|
||||
continue;
|
||||
}
|
||||
@ -151,11 +153,12 @@ enacl_crypto_curve25519_scalarmult_base(ErlNifEnv *env, int argc,
|
||||
|
||||
do {
|
||||
if (!enif_alloc_binary(crypto_scalarmult_curve25519_BYTES, &output)) {
|
||||
result = enacl_error_tuple(env, "alloc_failed");
|
||||
result = enacl_internal_error(env);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (crypto_scalarmult_curve25519_base(output.data, secret.data) < 0) {
|
||||
if (crypto_scalarmult_curve25519_base(output.data, secret.data) != 0) {
|
||||
enif_release_binary(&output);
|
||||
result = enacl_error_tuple(env, "scalarmult_curve25519_base_failed");
|
||||
continue;
|
||||
}
|
||||
@ -166,86 +169,6 @@ enacl_crypto_curve25519_scalarmult_base(ErlNifEnv *env, int argc,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Various other helper functions */
|
||||
static 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;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
static 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 enacl_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, enacl_crypto_box_NONCEBYTES},
|
||||
|
Loading…
x
Reference in New Issue
Block a user