Current section
Files
Jump to
Current section
Files
c_src/ntrukem_nif.c
#include "api.h"
#include "ntrukem.h"
#include "tools.c"
#include <stdio.h>
#include <string.h>
#include "erl_nif.h"
static ERL_NIF_TERM
generate_keypair(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary pk_bin, sk_bin;
if (argc != 0)
{
return enif_make_badarg(env);
}
unsigned char *pk, *sk;
pk = xmalloc(NTRU_PUBLICKEYBYTES);
sk = xmalloc(NTRU_SECRETKEYBYTES);
memset(pk, 0, NTRU_PUBLICKEYBYTES);
memset(sk, 0, NTRU_SECRETKEYBYTES);
crypto_kem_keypair(pk, sk);
if (enif_alloc_binary(NTRU_PUBLICKEYBYTES, &pk_bin))
{
memcpy(pk_bin.data, pk, NTRU_PUBLICKEYBYTES);
if (enif_alloc_binary(NTRU_SECRETKEYBYTES, &sk_bin))
{
memcpy(sk_bin.data, sk, NTRU_SECRETKEYBYTES);
xfree(pk);
xfree(sk);
return enif_make_tuple3(env, enif_make_atom(env, "ok"), enif_make_binary(env, &pk_bin), enif_make_binary(env, &sk_bin));
}
}
xfree(pk);
xfree(sk);
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "mem_alloc"));
}
static ERL_NIF_TERM
derive_keypair(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pk_bin, sk_bin, seed_bin;
if (argc != 1 ||
!enif_inspect_binary(env, argv[0], &seed_bin))
{
return enif_make_badarg(env);
}
unsigned char *pk, *sk;
pk = xmalloc(NTRU_PUBLICKEYBYTES);
sk = xmalloc(NTRU_SECRETKEYBYTES);
memset(pk, 0, NTRU_PUBLICKEYBYTES);
memset(sk, 0, NTRU_SECRETKEYBYTES);
crypto_kem_keypair_from_seed(pk, sk, seed_bin.data, seed_bin.size);
if (enif_alloc_binary(NTRU_PUBLICKEYBYTES, &pk_bin))
{
memcpy(pk_bin.data, pk, NTRU_PUBLICKEYBYTES);
if (enif_alloc_binary(NTRU_SECRETKEYBYTES, &sk_bin))
{
memcpy(sk_bin.data, sk, NTRU_SECRETKEYBYTES);
xfree(pk);
xfree(sk);
return enif_make_tuple3(env, enif_make_atom(env, "ok"), enif_make_binary(env, &pk_bin), enif_make_binary(env, &sk_bin));
}
}
xfree(pk);
xfree(sk);
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, "mem_alloc"));
}
static ERL_NIF_TERM
encapsulate(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary pk_bin, key_bin, cipher_bin;
if (argc != 1 ||
!enif_inspect_binary(env, argv[0], &pk_bin))
{
return enif_make_badarg(env);
}
unsigned char *key, *cipher;
key = xmalloc(NTRU_SHAREDKEYBYTES);
cipher = xmalloc(NTRU_CIPHERTEXTBYTES);
memset(key, 0, NTRU_SHAREDKEYBYTES);
memset(cipher, 0, NTRU_CIPHERTEXTBYTES);
crypto_kem_enc(cipher, key, pk_bin.data);
if (enif_alloc_binary(NTRU_CIPHERTEXTBYTES, &cipher_bin))
{
memcpy(cipher_bin.data, cipher, NTRU_CIPHERTEXTBYTES);
if (enif_alloc_binary(NTRU_SHAREDKEYBYTES, &key_bin))
{
memcpy(key_bin.data, key, NTRU_SHAREDKEYBYTES);
xfree(key);
xfree(cipher);
return enif_make_tuple3(env, enif_make_atom(env, "ok"), enif_make_binary(env, &cipher_bin), enif_make_binary(env, &key_bin));
}
}
xfree(key);
xfree(cipher);
return enif_make_atom(env, "error");
}
static ERL_NIF_TERM
decapsulate(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary sk_bin, key_bin, cipher_bin;
if (argc != 2 ||
!enif_inspect_binary(env, argv[0], &sk_bin) ||
!enif_inspect_binary(env, argv[1], &cipher_bin))
{
return enif_make_badarg(env);
}
unsigned char *key;
key = xmalloc(NTRU_SHAREDKEYBYTES);
memset(key, 0, NTRU_SHAREDKEYBYTES);
int r = crypto_kem_dec(key, cipher_bin.data, sk_bin.data);
if (r != 0)
{
return enif_make_atom(env, "error");
}
if (enif_alloc_binary(NTRU_SHAREDKEYBYTES, &key_bin))
{
memcpy(key_bin.data, key, NTRU_SHAREDKEYBYTES);
xfree(key);
return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_binary(env, &key_bin));
}
xfree(key);
return enif_make_atom(env, "error");
}
static ErlNifFunc nif_funcs[] = {
{"generate_keypair", 0, generate_keypair},
{"derive_keypair", 1, derive_keypair},
{"encapsulate", 1, encapsulate},
{"decapsulate", 2, decapsulate},
};
ERL_NIF_INIT(Elixir.NtruKem, nif_funcs, NULL, NULL, NULL, NULL)