pull/1/head
Jeff Becker 6 years ago
parent afd6530049
commit 212165500d
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -52,19 +52,21 @@ all: build
format:
$(FORMAT) -style=Google -i $(HDRS) $(SRCS)
build: $(EXE)
build: shared $(EXE)
test: $(TEST_OBJ_CPP) $(TEST_OBJ_C)
shared: $(SHARED_LIB)
$(TEST_SRC): $(STATIC_LIB)
$(TEST_OBJ_CPP): $(TEST_SRC_CPP)
$(REPO)/test/%.cpp.bin: $(REPO)/test/%.cpp
$(CXX) $(REQUIRED_CXXFLAGS) $< -o $<.bin $(TEST_LDFLAGS)
mv $<.bin $<.test
$<.test
$(TEST_OBJ_C): $(TEST_SRC_C)
$(REPO)/test/%.c.bin: $(REPO)/test/%.c
$(CC) $(REQUIRED_CFLAGS) $< -o $<.bin $(TEST_LDFLAGS)
mv $<.bin $<.test
$<.test

@ -8,41 +8,53 @@ extern "C" {
#endif
#define PUBKEYSIZE 32
#define SECKEYSIZE 32
#define SECKEYSIZE 64
#define NOUNCESIZE 24
#define SHAREDKEYSIZE 32
#define HASHSIZE 64
#define HMACSECSIZE 32
#define SIGSIZE 64
#define TUNNOUNCESIZE 32
#define HMACSIZE 64
typedef uint8_t llarp_pubkey_t[PUBKEYSIZE];
typedef uint8_t llarp_seckey_t[SECKEYSIZE];
typedef uint8_t llarp_nounce_t[NOUNCESIZE];
typedef uint8_t llarp_sharedkey_t[SHAREDKEYSIZE];
typedef uint8_t llarp_hash_t[HASHSIZE];
typedef uint8_t llarp_hmac_t[HMACSIZE];
typedef uint8_t llarp_hmacsec_t[HMACSECSIZE];
typedef uint8_t llarp_sig_t[SIGSIZE];
typedef uint8_t llarp_tunnel_nounce_t[TUNNOUNCESIZE];
struct llarp_keypair {
llarp_pubkey_t pub;
llarp_seckey_t sec;
};
static inline uint8_t * llarp_seckey_topublic(llarp_seckey_t k)
{
return k + 32;
}
typedef bool (*llarp_dh_func)(llarp_sharedkey_t *, llarp_pubkey_t,
llarp_tunnel_nounce_t, llarp_seckey_t);
typedef bool (*llarp_sym_cipher_func)(llarp_buffer_t, llarp_sharedkey_t, llarp_nounce_t);
typedef bool (*llarp_hash_func)(llarp_hash_t *, llarp_buffer_t);
typedef bool (*llarp_hmac_func)(llarp_hmac_t *, llarp_buffer_t, llarp_hmacsec_t);
typedef bool (*llarp_sign_func)(llarp_sig_t *, llarp_seckey_t, llarp_buffer_t);
typedef bool (*llarp_verify_func)(llarp_pubkey_t, llarp_buffer_t, llarp_sig_t);
struct llarp_crypto {
bool (*xchacha20)(llarp_buffer_t, llarp_sharedkey_t, llarp_nounce_t);
llarp_sym_cipher_func xchacha20;
llarp_dh_func dh_client;
llarp_dh_func dh_server;
bool (*hash)(llarp_hash_t *, llarp_buffer_t);
bool (*hmac)(llarp_hash_t *, llarp_buffer_t, llarp_hmacsec_t);
bool (*sign)(llarp_sig_t *, llarp_seckey_t, llarp_buffer_t);
bool (*verify)(llarp_pubkey_t, llarp_buffer_t, llarp_sig_t);
llarp_hash_func hash;
llarp_hmac_func hmac;
llarp_sign_func sign;
llarp_verify_func verify;
void (*randomize)(llarp_buffer_t);
void (*keygen)(struct llarp_keypair *);
void (*randbytes)(void *, size_t);
void (*keygen)(llarp_seckey_t *);
};
void llarp_crypto_libsodium_init(struct llarp_crypto *c);

@ -10,33 +10,56 @@ extern "C" {
struct llarp_async_dh;
struct llarp_async_dh *llarp_async_dh_new(struct llarp_crypto *crypto,
struct llarp_ev_loop *ev,
struct llarp_threadpool *tp);
struct llarp_async_dh *llarp_async_dh_new(
llarp_seckey_t ourkey,
struct llarp_crypto *crypto,
struct llarp_ev_loop *ev,
struct llarp_threadpool *tp);
void llarp_async_dh_free(struct llarp_async_dh **dh);
struct llarp_dh_result;
typedef void (*llarp_dh_complete_hook)(struct llarp_dh_result *);
struct llarp_dh_internal;
struct llarp_dh_result {
struct llarp_dh_internal *impl;
llarp_sharedkey_t result;
llarp_sharedkey_t sharedkey;
void *user;
llarp_dh_complete_hook hook;
};
void llarp_async_client_dh(struct llarp_async_dh *dh, llarp_seckey_t ourkey,
void llarp_async_client_dh(struct llarp_async_dh *dh,
llarp_pubkey_t theirkey,
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user);
void llarp_async_server_dh(struct llarp_async_dh *dh, llarp_seckey_t ourkey,
void llarp_async_server_dh(struct llarp_async_dh *dh,
llarp_pubkey_t theirkey,
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user);
struct llarp_async_cipher;
struct llarp_cipher_result;
typedef void (*llarp_cipher_complete_hook)(struct llarp_cipher_result*);
struct llarp_cipher_result
{
llarp_buffer_t buff;
void * user;
llarp_cipher_complete_hook hook;
};
struct llarp_async_cipher * llarp_async_cipher_new(
llarp_sharedkey_t key,
struct llarp_crypto *crypto,
struct llarp_ev_loop *ev,
struct llarp_threadpool *tp);
void llarp_async_cipher_free(struct llarp_async_cipher ** c);
void llarp_async_cipher_queue_op(struct llarp_async_cipher * c, llarp_buffer_t * buff, llarp_nounce_t n, llarp_cipher_complete_hook h, void * user);
#ifdef __cplusplus
}
#endif

@ -7,19 +7,20 @@ struct llarp_async_dh {
llarp_dh_func server;
struct llarp_threadpool *tp;
struct llarp_ev_caller *caller;
llarp_seckey_t ourkey;
};
struct llarp_dh_internal {
llarp_dh_func func;
llarp_pubkey_t theirkey;
llarp_seckey_t ourkey;
uint8_t * ourkey;
llarp_tunnel_nounce_t nounce;
struct llarp_dh_result result;
llarp_dh_func func;
};
static void llarp_crypto_dh_work(void *user) {
struct llarp_dh_internal *impl = (struct llarp_dh_internal *)user;
impl->func(&impl->result.result, impl->theirkey, impl->nounce, impl->ourkey);
impl->func(&impl->result.sharedkey, impl->theirkey, impl->nounce, impl->ourkey);
}
static void llarp_crypto_dh_result(struct llarp_ev_async_call *call) {
@ -29,15 +30,14 @@ static void llarp_crypto_dh_result(struct llarp_ev_async_call *call) {
}
static void llarp_async_dh_exec(struct llarp_async_dh *dh, llarp_dh_func func,
llarp_seckey_t ourkey, llarp_pubkey_t theirkey,
llarp_pubkey_t theirkey,
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
struct llarp_dh_internal *impl =
llarp_g_mem.alloc(sizeof(struct llarp_dh_internal), 16);
llarp_g_mem.alloc(sizeof(struct llarp_dh_internal), 32);
memcpy(impl->theirkey, theirkey, sizeof(llarp_pubkey_t));
memcpy(impl->ourkey, ourkey, sizeof(llarp_seckey_t));
memcpy(impl->nounce, nounce, sizeof(llarp_tunnel_nounce_t));
impl->result.impl = impl;
impl->ourkey = dh->ourkey;
impl->result.user = user;
impl->result.hook = result;
impl->func = func;
@ -48,27 +48,30 @@ static void llarp_async_dh_exec(struct llarp_async_dh *dh, llarp_dh_func func,
llarp_threadpool_queue_job(dh->tp, job);
}
void llarp_async_client_dh(struct llarp_async_dh *dh, llarp_seckey_t ourkey,
void llarp_async_client_dh(struct llarp_async_dh *dh,
llarp_pubkey_t theirkey,
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
llarp_async_dh_exec(dh, dh->client, ourkey, theirkey, nounce, result, user);
llarp_async_dh_exec(dh, dh->client, theirkey, nounce, result, user);
}
void llarp_async_server_dh(struct llarp_async_dh *dh, llarp_seckey_t ourkey,
void llarp_async_server_dh(struct llarp_async_dh *dh,
llarp_pubkey_t theirkey,
llarp_tunnel_nounce_t nounce,
llarp_dh_complete_hook result, void *user) {
llarp_async_dh_exec(dh, dh->server, ourkey, theirkey, nounce, result, user);
llarp_async_dh_exec(dh, dh->server, theirkey, nounce, result, user);
}
struct llarp_async_dh *llarp_async_dh_new(struct llarp_crypto *crypto,
struct llarp_ev_loop *ev,
struct llarp_threadpool *tp) {
struct llarp_async_dh *llarp_async_dh_new(
llarp_seckey_t ourkey,
struct llarp_crypto *crypto,
struct llarp_ev_loop *ev,
struct llarp_threadpool *tp) {
struct llarp_async_dh *dh =
llarp_g_mem.alloc(sizeof(struct llarp_async_dh), 16);
dh->client = crypto->dh_client;
dh->server = crypto->dh_server;
memcpy(dh->ourkey, ourkey, sizeof(llarp_seckey_t));
dh->tp = tp;
dh->caller = llarp_ev_prepare_async(ev, &llarp_crypto_dh_result);
return dh;
@ -81,3 +84,71 @@ void llarp_async_dh_free(struct llarp_async_dh **dh) {
*dh = NULL;
}
}
struct llarp_async_cipher_internal
{
uint8_t * key;
llarp_nounce_t nounce;
struct llarp_cipher_result result;
llarp_sym_cipher_func func;
};
struct llarp_async_cipher
{
llarp_sharedkey_t key;
struct llarp_threadpool *tp;
struct llarp_ev_caller *caller;
llarp_sym_cipher_func func;
};
static void llarp_crypto_cipher_result(struct llarp_ev_async_call * job)
{
struct llarp_async_cipher_internal * impl = (struct llarp_async_cipher_internal *) job->user;
impl->result.hook(&impl->result);
llarp_g_mem.free(impl);
}
static void llarp_crypto_cipher_work(void * work)
{
struct llarp_async_cipher_internal * impl = (struct llarp_async_cipher_internal *) work;
impl->func(impl->result.buff, impl->key, impl->nounce);
}
void llarp_async_cipher_queue_op(struct llarp_async_cipher * c, llarp_buffer_t * buff, llarp_nounce_t n, llarp_cipher_complete_hook h, void * user)
{
struct llarp_async_cipher_internal * impl = llarp_g_mem.alloc(sizeof(struct llarp_async_cipher_internal), 16);
impl->key = c->key;
memcpy(impl->nounce, n, sizeof(llarp_nounce_t));
impl->result.user = user;
impl->result.buff.base = buff->base;
impl->result.buff.sz = buff->sz;
impl->result.hook = h;
impl->func = c->func;
struct llarp_thread_job job = {.caller = c->caller,
.data = impl,
.user = impl,
.work = &llarp_crypto_cipher_work};
llarp_threadpool_queue_job(c->tp, job);
}
struct llarp_async_cipher * llarp_async_cipher_new(llarp_sharedkey_t key,
struct llarp_crypto * crypto,
struct llarp_ev_loop * ev,
struct llarp_threadpool *tp)
{
struct llarp_async_cipher * cipher = llarp_g_mem.alloc(sizeof(struct llarp_async_cipher), 16);
cipher->func = crypto->xchacha20;
cipher->tp = tp;
cipher->caller = llarp_ev_prepare_async(ev, &llarp_crypto_cipher_result);
memcpy(cipher->key, key, sizeof(llarp_sharedkey_t));
return cipher;
}
void llarp_async_cipher_free(struct llarp_async_cipher **c) {
if (*c) {
llarp_ev_caller_stop((*c)->caller);
llarp_g_mem.free(*c);
*c = NULL;
}
}

@ -73,10 +73,15 @@ static void randomize(llarp_buffer_t buff) {
randombytes((unsigned char *)buff.base, buff.sz);
}
static void keygen(struct llarp_keypair *keys) {
randombytes(keys->sec, sizeof(llarp_seckey_t));
unsigned char sk[64];
crypto_sign_seed_keypair(keys->pub, sk, keys->sec);
static inline void randbytes(void * ptr, size_t sz)
{
randombytes((unsigned char*)ptr, sz);
}
static void keygen(llarp_seckey_t *keys) {
unsigned char seed[32];
uint8_t * pk = llarp_seckey_topublic(*keys);
crypto_sign_seed_keypair(pk, *keys, seed);
}
} // namespace sodium
} // namespace llarp
@ -92,6 +97,7 @@ void llarp_crypto_libsodium_init(struct llarp_crypto *c) {
c->sign = llarp::sodium::sign;
c->verify = llarp::sodium::verify;
c->randomize = llarp::sodium::randomize;
c->randbytes = llarp::sodium::randbytes;
c->keygen = llarp::sodium::keygen;
}
}

@ -34,6 +34,7 @@ struct llarp_ev_caller {
auto &front = pending.front();
front->work(front);
pending.pop();
delete front;
}
}

@ -0,0 +1,83 @@
#include <llarp/crypto_async.h>
#include <llarp/mem.h>
#include <stdio.h>
struct bench_main {
size_t completed;
size_t num;
size_t jobs;
struct llarp_ev_loop *ev;
struct llarp_async_cipher *cipher;
struct llarp_crypto crypto;
};
static void handle_cipher_complete(struct llarp_cipher_result *res) {
struct bench_main *m = (struct bench_main *)res->user;
size_t sz = m->jobs;
m->completed++;
size_t left = m->num - m->completed;
if (m->completed % 10000 == 0) printf("completed %ld and %ld left\n", m->completed, left);
if (m->completed == m->num)
{
llarp_ev_loop_stop(m->ev);
}
else if(m->completed % sz == 0)
{
llarp_nounce_t nounce;
while(sz--)
{
m->crypto.randbytes(nounce, sizeof(llarp_nounce_t));
llarp_async_cipher_queue_op(m->cipher, &res->buff, nounce,
handle_cipher_complete, m);
}
}
}
int main(int argc, char *argv[]) {
struct bench_main b_main;
struct llarp_threadpool *tp;
llarp_mem_jemalloc();
llarp_crypto_libsodium_init(&b_main.crypto);
llarp_ev_loop_alloc(&b_main.ev);
tp = llarp_init_threadpool(8);
b_main.num = 10000000;
b_main.jobs = 10000;
b_main.completed = 0;
llarp_sharedkey_t key;
b_main.crypto.randbytes(key, sizeof(llarp_sharedkey_t));
b_main.cipher = llarp_async_cipher_new(key, &b_main.crypto, b_main.ev, tp);
llarp_threadpool_start(tp);
llarp_nounce_t nounce;
llarp_buffer_t n_buff;
n_buff.base = nounce;
n_buff.cur = n_buff.base;
n_buff.sz = sizeof(llarp_nounce_t);
size_t sz = b_main.jobs;
printf("starting %ld jobs\n", sz);
/* do work here */
while (sz--) {
llarp_buffer_t * msg = llarp_g_mem.alloc(sizeof(llarp_buffer_t), 8);
msg->base = llarp_g_mem.alloc(1024, 1024);
msg->sz = 1024;
msg->cur = msg->base;
b_main.crypto.randomize(*msg);
b_main.crypto.randbytes(nounce, sizeof(llarp_nounce_t));
llarp_async_cipher_queue_op(b_main.cipher, msg, nounce,
handle_cipher_complete, &b_main);
}
llarp_ev_loop_run(b_main.ev);
llarp_threadpool_join(tp);
llarp_async_cipher_free(&b_main.cipher);
llarp_ev_loop_free(&b_main.ev);
llarp_free_threadpool(&tp);
printf("did %ld of %ld work\n", b_main.completed, b_main.num);
return 0;
}

@ -12,10 +12,11 @@ struct dh_bench_main {
static void handle_dh_complete(struct llarp_dh_result *res) {
struct dh_bench_main *m = (struct dh_bench_main *)res->user;
m->completed++;
if (m->completed % 1000 == 0) printf("completed %ld\n", m->completed);
if (m->completed == m->num) {
printf("we done\n");
if (m->completed % 10000 == 0) printf("completed %ld\n", m->completed);
if (m->completed == m->num)
{
llarp_ev_loop_stop(m->ev);
}
}
@ -30,29 +31,32 @@ int main(int argc, char *argv[]) {
llarp_ev_loop_alloc(&dh_main.ev);
tp = llarp_init_threadpool(8);
dh_main.dh = llarp_async_dh_new(&crypto, dh_main.ev, tp);
llarp_threadpool_start(tp);
dh_main.num = 1000000;
dh_main.num = 100000;
dh_main.completed = 0;
struct llarp_keypair ourkey;
struct llarp_keypair theirkey;
llarp_seckey_t ourkey;
llarp_seckey_t theirkey;
crypto.keygen(&ourkey);
crypto.keygen(&theirkey);
dh_main.dh = llarp_async_dh_new(ourkey, &crypto, dh_main.ev, tp);
llarp_threadpool_start(tp);
llarp_tunnel_nounce_t nounce;
llarp_buffer_t n_buff;
n_buff.base = nounce;
n_buff.cur = n_buff.base;
n_buff.sz = sizeof(llarp_tunnel_nounce_t);
uint8_t * theirpubkey = llarp_seckey_topublic(theirkey);
size_t sz = dh_main.num;
printf("starting %ld dh jobs\n", sz);
/* do work here */
while (sz--) {
crypto.randomize(n_buff);
llarp_async_client_dh(dh_main.dh, ourkey.sec, theirkey.pub, nounce,
llarp_async_client_dh(dh_main.dh, theirpubkey, nounce,
handle_dh_complete, &dh_main);
}
printf("started %ld dh jobs\n", dh_main.num);

Loading…
Cancel
Save