return crypto_unlock_aead(plain_text, key, nonce, mac, 0, 0,
cipher_text, text_size);
}
-
-///////////////////////
-/// Secure channels ///
-///////////////////////
-static void copy32(u8 out[32], const u8 in[32]){FOR (i, 0, 32){out[i] = in[i];}}
-static void xor32 (u8 out[32], const u8 in[32]){FOR (i, 0, 32){out[i]^= in[i];}}
-
-static void kex_update_key(crypto_kex_ctx *ctx,
- const u8 secret_key[32],
- const u8 public_key[32])
-{
- static const u8 one[16] = {1};
-
- // Extract
- u8 shared_secret[32];
- crypto_x25519(shared_secret, secret_key, public_key);
- crypto_chacha20_H(shared_secret , shared_secret , zero);
- crypto_chacha20_H(ctx->chaining_key, ctx->chaining_key, one );
- xor32(ctx->chaining_key, shared_secret);
-
- // Expand (directly from chaining key)
- crypto_chacha_ctx chacha_ctx;
- crypto_chacha20_init (&chacha_ctx, ctx->chaining_key, one);
- crypto_chacha20_stream(&chacha_ctx, ctx->derived_keys, 64);
-
- // Clean up
- WIPE_BUFFER(shared_secret);
- WIPE_CTX(&chacha_ctx);
-}
-
-static void kex_auth(crypto_kex_ctx *ctx, u8 mac[16])
-{
- crypto_poly1305(mac, ctx->transcript, ctx->transcript_size,
- ctx->derived_keys);
-}
-
-static int kex_verify(crypto_kex_ctx *ctx, const u8 mac[16])
-{
- u8 real_mac[16];
- kex_auth(ctx, real_mac);
- int mismatch = crypto_verify16(real_mac, mac);
- if (mismatch) { WIPE_CTX(ctx); }
- WIPE_BUFFER(real_mac);
- return mismatch;
-}
-
-static void kex_send(crypto_kex_ctx *ctx, u8 msg[32], const u8 src[32])
-{
- // Send message, encrypted if we have a key
- copy32(msg, src);
- xor32(msg, ctx->derived_keys + 32);
- // Record sent message
- copy32(ctx->transcript + ctx->transcript_size, msg);
- ctx->transcript_size += 32;
-}
-
-static void kex_receive(crypto_kex_ctx *ctx, u8 dest[32], const u8 msg[32])
-{
- // Record incoming message
- copy32(ctx->transcript + ctx->transcript_size, msg);
- ctx->transcript_size += 32;
- // Receive message, decrypted it if we have a key
- copy32(dest, msg);
- xor32(dest, ctx->derived_keys + 32);
-}
-
-static void kex_init(crypto_kex_ctx *ctx,
- const u8 local_sk[32],
- const u8 local_pk[32])
-{
- if (local_pk == 0) crypto_x25519_public_key(ctx->local_pk, local_sk);
- else copy32 (ctx->local_pk, local_pk);
- copy32(ctx->chaining_key , zero );
- copy32(ctx->derived_keys + 32, zero ); // first encryption key is zero
- copy32(ctx->local_sk , local_sk);
- ctx->transcript_size = 0;
-}
-
-static void kex_seed(crypto_kex_ctx *ctx, u8 random_seed[32])
-{
- copy32(ctx->local_ske , random_seed);
- crypto_wipe(random_seed, 32); // auto wipe seed to avoid reuse
- crypto_x25519_public_key(ctx->local_pke, ctx->local_ske);
-}
-
-
-///////////
-/// XK1 ///
-///////////
-static const u8 xk1_ck0[32] = "Monokex XK1";
-void crypto_kex_xk1_init_client(crypto_kex_client_ctx *client_ctx,
- u8 random_seed[32],
- const u8 client_sk [32],
- const u8 client_pk [32],
- const u8 server_pk [32])
-{
- crypto_kex_ctx *ctx = &(client_ctx->ctx);
- kex_init (ctx, client_sk, client_pk);
- kex_seed (ctx, random_seed);
- kex_receive(ctx, ctx->remote_pk, server_pk);
- copy32(ctx->chaining_key, xk1_ck0);
-}
-
-void crypto_kex_xk1_init_server(crypto_kex_server_ctx *server_ctx,
- u8 random_seed[32],
- const u8 server_sk [32],
- const u8 server_pk [32])
-{
- crypto_kex_ctx *ctx = &(server_ctx->ctx);
- kex_init (ctx, server_sk, server_pk);
- kex_seed (ctx, random_seed);
- kex_receive(ctx, ctx->local_pk, ctx->local_pk);
- copy32(ctx->chaining_key, xk1_ck0);
-}
-
-void crypto_kex_xk1_1(crypto_kex_client_ctx *client_ctx,
- u8 msg1[32])
-{
- crypto_kex_ctx *ctx = &(client_ctx->ctx);
- kex_send (ctx, msg1 , ctx->local_pke ); // -> IE
-}
-
-void crypto_kex_xk1_2(crypto_kex_server_ctx *server_ctx,
- u8 msg2[48],
- const u8 msg1[32])
-{
- crypto_kex_ctx *ctx = &(server_ctx->ctx);
- kex_receive (ctx, ctx->remote_pke, msg1 ); // -> IE
- kex_send (ctx, msg2 , ctx->local_pke ); // <- RE
- kex_update_key(ctx, ctx->local_ske , ctx->remote_pke); // ee
- kex_update_key(ctx, ctx->local_sk , ctx->remote_pke); // es
- kex_auth (ctx, msg2 + 32); // auth
-}
-
-int crypto_kex_xk1_3(crypto_kex_client_ctx *client_ctx,
- u8 session_key[32],
- u8 msg3 [48],
- const u8 msg2 [48])
-{
- crypto_kex_ctx *ctx = &(client_ctx->ctx);
- kex_receive (ctx, ctx->remote_pke, msg2 ); // <- RE
- kex_update_key(ctx, ctx->local_ske , ctx->remote_pke); // ee
- kex_update_key(ctx, ctx->local_ske , ctx->remote_pk ); // es
- if (kex_verify(ctx, msg2 + 32)) { return -1; } // verify
- kex_send (ctx, msg3 , ctx->local_pk ); // -> IS
- kex_update_key(ctx, ctx->local_sk , ctx->remote_pke); // se
- kex_auth (ctx, msg3 + 32); // auth
- copy32(session_key, ctx->derived_keys + 32);
- WIPE_CTX(ctx);
- return 0;
-}
-
-int crypto_kex_xk1_4(crypto_kex_server_ctx *server_ctx,
- u8 session_key[32],
- u8 client_pk [32],
- const u8 msg3 [48])
-{
- crypto_kex_ctx *ctx = &(server_ctx->ctx);
- kex_receive (ctx, ctx->remote_pk , msg3 ); // -> IS
- kex_update_key(ctx, ctx->local_ske , ctx->remote_pk ); // se
- if (kex_verify(ctx, msg3 + 32)) { return -1; } // verify
- copy32(client_pk , ctx->remote_pk);
- copy32(session_key, ctx->derived_keys + 32);
- WIPE_CTX(ctx);
- return 0;
-}
-
-/////////
-/// X ///
-/////////
-static const u8 x_ck0[32] = "Monokex X";
-void crypto_kex_x_init_client(crypto_kex_client_ctx *client_ctx,
- u8 random_seed[32],
- const u8 client_sk [32],
- const u8 client_pk [32],
- const u8 server_pk [32])
-{
- crypto_kex_ctx *ctx = &(client_ctx->ctx);
- kex_init (ctx, client_sk, client_pk);
- kex_seed (ctx, random_seed);
- kex_receive(ctx, ctx->remote_pk, server_pk);
- copy32(ctx->chaining_key, x_ck0);
-}
-
-void crypto_kex_x_init_server(crypto_kex_server_ctx *server_ctx,
- const u8 server_sk [32],
- const u8 server_pk [32])
-{
- crypto_kex_ctx *ctx = &(server_ctx->ctx);
- kex_init (ctx, server_sk, server_pk);
- kex_receive(ctx, ctx->local_pk, ctx->local_pk);
- copy32(ctx->chaining_key, x_ck0);
-}
-
-void crypto_kex_x_1(crypto_kex_client_ctx *client_ctx,
- u8 session_key[32],
- u8 msg1 [80])
-{
- crypto_kex_ctx *ctx = &(client_ctx->ctx);
- kex_send (ctx, msg1 , ctx->local_pke ); // -> IE
- kex_update_key(ctx, ctx->local_ske , ctx->remote_pk ); // es
- kex_send (ctx, msg1 + 32 , ctx->local_pk ); // -> IS
- kex_update_key(ctx, ctx->local_sk , ctx->remote_pk ); // ss
- kex_auth (ctx, msg1 + 64); // auth
- copy32(session_key, ctx->derived_keys + 32);
- WIPE_CTX(ctx);
-}
-
-int crypto_kex_x_2(crypto_kex_server_ctx *server_ctx,
- u8 session_key[32],
- u8 client_pk [32],
- const u8 msg1 [80])
-{
- crypto_kex_ctx *ctx = &(server_ctx->ctx);
- kex_receive (ctx, ctx->remote_pke, msg1 ); // -> IE
- kex_update_key(ctx, ctx->local_sk , ctx->remote_pke); // es
- kex_receive (ctx, ctx->remote_pk , msg1 + 32 ); // -> IS
- kex_update_key(ctx, ctx->local_sk , ctx->remote_pk ); // ss
- if (kex_verify(ctx, msg1 + 64)) { return -1; } // verify
- copy32(client_pk , ctx->remote_pk);
- copy32(session_key, ctx->derived_keys + 32);
- WIPE_CTX(ctx);
- return 0;
-}
-
uint8_t pk [32];
} crypto_check_ctx;
-// Secure channels (Monokex)
-typedef struct {
- uint8_t transcript [128];
- uint8_t chaining_key[32];
- uint8_t derived_keys[64];
- uint8_t local_sk [32];
- uint8_t local_pk [32];
- uint8_t local_ske [32];
- uint8_t local_pke [32];
- uint8_t remote_pk [32];
- uint8_t remote_pke [32];
- size_t transcript_size;
-} crypto_kex_ctx;
-typedef struct { crypto_kex_ctx ctx; } crypto_kex_client_ctx;
-typedef struct { crypto_kex_ctx ctx; } crypto_kex_server_ctx;
-
////////////////////////////
/// High level interface ///
////////////////////////////
int crypto_check_final (crypto_check_ctx *ctx);
-// Secure channel (interactive)
-// ----------------------------
-void crypto_kex_xk1_init_client(crypto_kex_client_ctx *client_ctx,
- uint8_t random_seed[32],
- const uint8_t client_sk [32],
- const uint8_t client_pk [32],
- const uint8_t server_pk [32]);
-void crypto_kex_xk1_init_server(crypto_kex_server_ctx *server_ctx,
- uint8_t random_seed[32],
- const uint8_t server_sk [32],
- const uint8_t server_pk [32]);
-void crypto_kex_xk1_1(crypto_kex_client_ctx *client_ctx,
- uint8_t msg1[32]);
-void crypto_kex_xk1_2(crypto_kex_server_ctx *server_ctx,
- uint8_t msg2[48],
- const uint8_t msg1[32]);
-int crypto_kex_xk1_3(crypto_kex_client_ctx *client_ctx,
- uint8_t session_key[32],
- uint8_t msg3 [48],
- const uint8_t msg2 [48]);
-int crypto_kex_xk1_4(crypto_kex_server_ctx *server_ctx,
- uint8_t session_key[32],
- uint8_t client_pk [32],
- const uint8_t msg3 [48]);
-
-// Secure channel (one way)
-// ------------------------
-void crypto_kex_x_init_client(crypto_kex_client_ctx *client_ctx,
- uint8_t random_seed[32],
- const uint8_t client_sk [32],
- const uint8_t client_pk [32],
- const uint8_t server_pk [32]);
-void crypto_kex_x_init_server(crypto_kex_server_ctx *server_ctx,
- const uint8_t server_sk [32],
- const uint8_t server_pk [32]);
-void crypto_kex_x_1(crypto_kex_client_ctx *client_ctx,
- uint8_t session_key[32],
- uint8_t msg1 [80]);
-int crypto_kex_x_2(crypto_kex_server_ctx *server_ctx,
- uint8_t session_key[32],
- uint8_t client_pk [32],
- const uint8_t msg1 [80]);
-
-
-
////////////////////////////
/// Low level primitives ///
////////////////////////////
VEC = chacha20 hchacha20 xchacha20 aead_ietf poly1305 \
blake2b sha512 argon2i \
edDSA edDSA_pk ed_25519 ed_25519_check \
- x25519 x25519_pk key_exchange \
- monokex_xk1 monokex_x
+ x25519 x25519_pk key_exchange
+# monokex_xk1 monokex_x
VEC2 = $(patsubst %, %.all.vec, $(VEC))
HEADERS = $(patsubst %, %.h.vec , $(VEC))
VECTORS = ../vectors.h
-#include <sodium.h>
-#include "utils.h"
-
-static const uint8_t zero[32] = {0};
-static const uint8_t one [16] = {1};
-
-static void crypto_chacha20_H(uint8_t out[32],
- const uint8_t key[32],
- const uint8_t in [16])
-{
- crypto_core_hchacha20(out, in, key, 0);
-}
-int crypto_x25519(uint8_t shared[32],
- const uint8_t sk [32],
- const uint8_t pk [32])
-{
- return crypto_scalarmult(shared, sk, pk);
-}
-#define crypto_x25519_public_key crypto_scalarmult_base
-#define crypto_poly1305_ctx crypto_onetimeauth_state
-#define crypto_poly1305_init crypto_onetimeauth_init
-#define crypto_poly1305_update crypto_onetimeauth_update
-#define crypto_poly1305_final crypto_onetimeauth_final
-
-static void xor(uint8_t out[32], const uint8_t a[32], const uint8_t b[32])
-{
- for (unsigned i = 0; i < 32; i++) {
- out[i] = a[i] ^ b[i];
- }
-}
-
-static void copy(uint8_t out[32], const uint8_t in[32])
-{
- for (unsigned i = 0; i < 32; i++) {
- out[i] = in[i];
- }
-}
-
-static void chacha_block(uint8_t out[64],
- const uint8_t key[32],
- const uint8_t nonce[16])
-{
- static const uint8_t in[64] = {0};
- crypto_stream_chacha20_xor_ic(out, in, 64, nonce, 0, key);
-}
-
-typedef struct {
- // Key pairs
- uint8_t is[32]; uint8_t IS[32];
- uint8_t ie[32]; uint8_t IE[32];
- uint8_t rs[32]; uint8_t RS[32];
-
- // Shared secrets
- uint8_t es[32];
- uint8_t ss[32];
-
- // Symmetric Keys
- uint8_t CK1[32];
- uint8_t CK2[32];
- uint8_t AK2[32];
- uint8_t EK1[32];
- uint8_t EK2[32];
-
- // Messages
- uint8_t msg1[80];
-} test_vectors_x;
-
-static void vectors_x_fill(test_vectors_x *v,
- const uint8_t client_sk [32],
- const uint8_t server_sk [32],
- const uint8_t client_seed[32])
-{
- // Private keys
- copy(v->is, client_sk );
- copy(v->ie, client_seed);
- copy(v->rs, server_sk );
-
- // Public keys
- crypto_x25519_public_key(v->IS, v->is);
- crypto_x25519_public_key(v->IE, v->ie);
- crypto_x25519_public_key(v->RS, v->rs);
-
- // Exchanges
- crypto_x25519(v->es, v->ie, v->RS);
- crypto_x25519(v->ss, v->is, v->RS);
-
- // Keys
- uint8_t tmp1[32];
- uint8_t tmp2[32];
- uint8_t CK0 [32] = "Monokex X";
- crypto_chacha20_H(tmp1, v->es , zero);
- crypto_chacha20_H(tmp2, CK0 , one );
- xor(v->CK1, tmp1, tmp2);
- crypto_chacha20_H(tmp1, v->ss , zero);
- crypto_chacha20_H(tmp2, v->CK1, one );
- xor(v->CK2, tmp1, tmp2);
- uint8_t tmp[64];
- chacha_block(tmp, v->CK1, one);
- copy(v->EK1, tmp + 32);
- chacha_block(tmp, v->CK2, one);
- copy(v->AK2, tmp );
- copy(v->EK2, tmp + 32);
-
- // Messages
- crypto_poly1305_ctx ctx;
- uint8_t XIS[32];
- xor(XIS, v->IS, v->EK1);
- copy(v->msg1 , v->IE);
- copy(v->msg1 + 32, XIS );
- crypto_poly1305_init (&ctx, v->AK2);
- crypto_poly1305_update(&ctx, v->RS, 32);
- crypto_poly1305_update(&ctx, v->IE, 32);
- crypto_poly1305_update(&ctx, XIS , 32);
- crypto_poly1305_final (&ctx, v->msg1 + 64);
-}
+// TODO: add Monokex (X patern)
int main(void)
{
- FOR(i, 0, 5) {
- RANDOM_INPUT(client_sk , 32);
- RANDOM_INPUT(server_sk , 32);
- RANDOM_INPUT(client_seed, 32);
- RANDOM_INPUT(server_seed, 32);
- test_vectors_x v;
- vectors_x_fill(&v, client_sk, server_sk, client_seed);
-
- print_vector(v.is , 32);
- print_vector(v.ie , 32);
- print_vector(v.rs , 32);
- print_vector(v.IS , 32);
- print_vector(v.RS , 32);
- print_vector(v.msg1, 80);
- print_vector(v.EK2 , 32);
- }
return 0;
}
-#include <sodium.h>
-#include "utils.h"
-
-static const uint8_t zero[32] = {0};
-static const uint8_t one [16] = {1};
-
-static void crypto_chacha20_H(uint8_t out[32],
- const uint8_t key[32],
- const uint8_t in [16])
-{
- crypto_core_hchacha20(out, in, key, 0);
-}
-int crypto_x25519(uint8_t shared[32],
- const uint8_t sk [32],
- const uint8_t pk [32])
-{
- return crypto_scalarmult(shared, sk, pk);
-}
-#define crypto_x25519_public_key crypto_scalarmult_base
-#define crypto_poly1305_ctx crypto_onetimeauth_state
-#define crypto_poly1305_init crypto_onetimeauth_init
-#define crypto_poly1305_update crypto_onetimeauth_update
-#define crypto_poly1305_final crypto_onetimeauth_final
-
-static void xor(uint8_t out[32], const uint8_t a[32], const uint8_t b[32])
-{
- for (unsigned i = 0; i < 32; i++) {
- out[i] = a[i] ^ b[i];
- }
-}
-
-static void copy(uint8_t out[32], const uint8_t in[32])
-{
- for (unsigned i = 0; i < 32; i++) {
- out[i] = in[i];
- }
-}
-
-static void chacha_block(uint8_t out[64],
- const uint8_t key[32],
- const uint8_t nonce[16])
-{
- static const uint8_t in[64] = {0};
- crypto_stream_chacha20_xor_ic(out, in, 64, nonce, 0, key);
-}
-
-typedef struct {
- // Key pairs
- uint8_t is[32]; uint8_t IS[32];
- uint8_t ie[32]; uint8_t IE[32];
- uint8_t rs[32]; uint8_t RS[32];
- uint8_t re[32]; uint8_t RE[32];
-
- // Shared secrets
- uint8_t ee[32];
- uint8_t es[32];
- uint8_t se[32];
-
- // Symmetric keys
- uint8_t CK1[32];
- uint8_t CK2[32];
- uint8_t CK3[32];
- uint8_t AK2[32];
- uint8_t AK3[32];
- uint8_t EK2[32];
- uint8_t EK3[32];
-
- // Messages
- uint8_t msg1[32];
- uint8_t msg2[48];
- uint8_t msg3[48];
-} test_vectors_xk1;
-
-static void vectors_xk1_fill(test_vectors_xk1 *v,
- const uint8_t client_sk [32],
- const uint8_t server_sk [32],
- const uint8_t client_seed[32],
- const uint8_t server_seed[32])
-{
- // Private keys
- copy(v->is, client_sk );
- copy(v->ie, client_seed);
- copy(v->rs, server_sk );
- copy(v->re, server_seed);
-
- // Public keys
- crypto_x25519_public_key(v->IS, v->is);
- crypto_x25519_public_key(v->IE, v->ie);
- crypto_x25519_public_key(v->RS, v->rs);
- crypto_x25519_public_key(v->RE, v->re);
-
- // Shared secrets
- crypto_x25519(v->ee, v->ie, v->RE);
- crypto_x25519(v->es, v->ie, v->RS);
- crypto_x25519(v->se, v->is, v->RE);
-
- // Keys
- uint8_t tmp1[32];
- uint8_t tmp2[32];
- uint8_t CK0 [32] = "Monokex XK1";
- crypto_chacha20_H(tmp1, v->ee , zero);
- crypto_chacha20_H(tmp2, CK0 , one );
- xor(v->CK1, tmp1, tmp2);
- crypto_chacha20_H(tmp1, v->es , zero);
- crypto_chacha20_H(tmp2, v->CK1, one );
- xor(v->CK2, tmp1, tmp2);
- crypto_chacha20_H(tmp1, v->se , zero);
- crypto_chacha20_H(tmp2, v->CK2, one );
- xor(v->CK3, tmp1, tmp2);
- uint8_t tmp[64];
- chacha_block(tmp, v->CK2, one);
- copy(v->AK2, tmp );
- copy(v->EK2, tmp + 32);
- chacha_block(tmp, v->CK3, one);
- copy(v->AK3, tmp );
- copy(v->EK3, tmp + 32);
-
- // Messages
- crypto_poly1305_ctx ctx;
- uint8_t XIS[32];
- xor(XIS, v->IS, v->EK2);
- copy(v->msg1, v->IE);
- copy(v->msg2, v->RE);
- crypto_poly1305_init (&ctx, v->AK2);
- crypto_poly1305_update(&ctx, v->RS, 32);
- crypto_poly1305_update(&ctx, v->IE, 32);
- crypto_poly1305_update(&ctx, v->RE, 32);
- crypto_poly1305_final (&ctx, v->msg2 + 32);
- copy(v->msg3, XIS);
- crypto_poly1305_init (&ctx, v->AK3);
- crypto_poly1305_update(&ctx, v->RS, 32);
- crypto_poly1305_update(&ctx, v->IE, 32);
- crypto_poly1305_update(&ctx, v->RE, 32);
- crypto_poly1305_update(&ctx, XIS , 32);
- crypto_poly1305_final (&ctx, v->msg3 + 32);
-}
+// TODO: add Monokex (X patern)
int main(void)
{
- FOR(i, 0, 5) {
- RANDOM_INPUT(client_sk , 32);
- RANDOM_INPUT(server_sk , 32);
- RANDOM_INPUT(client_seed, 32);
- RANDOM_INPUT(server_seed, 32);
- test_vectors_xk1 v;
- vectors_xk1_fill(&v, client_sk, server_sk, client_seed, server_seed);
-
- print_vector(v.is , 32);
- print_vector(v.ie , 32);
- print_vector(v.rs , 32);
- print_vector(v.re , 32);
- print_vector(v.IS , 32);
- print_vector(v.RS , 32);
- print_vector(v.msg1, 32);
- print_vector(v.msg2, 48);
- print_vector(v.msg3, 48);
- print_vector(v.EK3 , 32);
- }
return 0;
}
TIMING_END;
}
-static void get_interactive_session(u8 msg1[32], u8 msg2[48], u8 msg3[48],
- u8 client_pk[32], u8 server_pk[32],
- const u8 client_sk [32],
- const u8 server_sk [32],
- const u8 client_seed[32],
- const u8 server_seed[32])
-{
- crypto_key_exchange_public_key(client_pk, client_sk);
- crypto_key_exchange_public_key(server_pk, server_sk);
-
- u8 c_seed[32];
- u8 s_seed[32];
- FOR (i, 0, 32) {
- c_seed[i] = client_seed[i];
- s_seed[i] = server_seed[i];
- }
- crypto_kex_client_ctx client_ctx;
- crypto_kex_xk1_init_client(&client_ctx, c_seed, client_sk, client_pk,
- server_pk);
- crypto_kex_server_ctx server_ctx;
- crypto_kex_xk1_init_server(&server_ctx, s_seed, server_sk, server_pk);
-
- crypto_kex_xk1_1(&client_ctx, msg1);
- crypto_kex_xk1_2(&server_ctx, msg2, msg1);
-
- u8 client_session_key[32];
- if (crypto_kex_xk1_3(&client_ctx, client_session_key,
- msg3, msg2)) {
- fprintf(stderr, "Cannot confirm\n");
- return;
- }
-
- u8 server_session_key[32];
- u8 remote_pk [32]; // same as client_pk
- if (crypto_kex_xk1_4(&server_ctx, server_session_key, remote_pk,
- msg3)) {
- fprintf(stderr, "Cannot accept\n");
- return;
- }
-
- if (crypto_verify32(client_session_key, server_session_key)) {
- fprintf(stderr, "Different session keys\n");
- return;
- }
- if (crypto_verify32(remote_pk, client_pk)) {
- fprintf(stderr, "Server got the wrong client public key\n");
- return;
- }
-}
-
-
-static u64 interactive_client(void)
-{
- RANDOM_INPUT(client_sk, 32);
- RANDOM_INPUT(server_sk, 32);
- RANDOM_INPUT(client_seed, 32);
- RANDOM_INPUT(server_seed, 32);
- u8 msg1[32]; u8 msg2[48]; u8 msg3[48];
- u8 client_pk[32]; u8 server_pk[32];
- get_interactive_session(msg1, msg2, msg3,
- client_pk , server_pk,
- client_sk , server_sk,
- client_seed, server_seed);
- TIMING_START {
- u8 session_key[32];
- crypto_kex_client_ctx client_ctx;
- u8 seed[32];
- FOR (i, 0, 32) {
- seed[i] = client_seed[i];
- }
- crypto_kex_xk1_init_client(&client_ctx, seed, client_sk, client_pk,
- server_pk);
- crypto_kex_xk1_1(&client_ctx, msg1);
- if (crypto_kex_xk1_3(&client_ctx, session_key,
- msg3, msg2)) {
- fprintf(stderr, "Cannot confirm\n");
- return 1;
- }
- }
- TIMING_END;
-}
-
-static u64 interactive_server(void)
-{
- RANDOM_INPUT(client_sk, 32);
- RANDOM_INPUT(server_sk, 32);
- RANDOM_INPUT(client_seed, 32);
- RANDOM_INPUT(server_seed, 32);
- u8 msg1[32]; u8 msg2[48]; u8 msg3[48];
- u8 client_pk[32]; u8 server_pk[32];
- get_interactive_session(msg1, msg2, msg3,
- client_pk , server_pk,
- client_sk , server_sk,
- client_seed, server_seed);
- TIMING_START {
- u8 session_key[32];
- u8 remote_pk [32]; // same as client_pk
- crypto_kex_server_ctx server_ctx;
- u8 seed[32];
- FOR (i, 0, 32) {
- seed[i] = server_seed[i];
- }
- crypto_kex_xk1_init_server(&server_ctx, seed, server_sk, server_pk);
- crypto_kex_xk1_2(&server_ctx, msg2, msg1);
- if (crypto_kex_xk1_4(&server_ctx, session_key, remote_pk,
- msg3)) {
- fprintf(stderr, "Cannot accept\n");
- return 1;
- }
- }
- TIMING_END;
-}
-
-static void get_one_way_session(u8 msg[80], u8 client_pk[32], u8 server_pk[32],
- const u8 client_sk [32],
- const u8 server_sk [32],
- const u8 client_seed[32])
-{
- crypto_key_exchange_public_key(client_pk, client_sk);
- crypto_key_exchange_public_key(server_pk, server_sk);
-
- u8 c_seed[32];
- FOR (i, 0, 32) {
- c_seed[i] = client_seed[i];
- }
-
- crypto_kex_client_ctx client_ctx;
- crypto_kex_x_init_client(&client_ctx, c_seed, client_sk, client_pk,
- server_pk);
- crypto_kex_server_ctx server_ctx;
- crypto_kex_x_init_server(&server_ctx, server_sk, server_pk);
-
- u8 client_session_key[32];
- crypto_kex_x_1(&client_ctx, client_session_key, msg);
-
- u8 server_session_key[32];
- u8 remote_pk [32]; // same as client_pk
- if (crypto_kex_x_2(&server_ctx, server_session_key, remote_pk, msg)) {
- fprintf(stderr, "Cannot receive\n");
- return;
- }
-
- if (crypto_verify32(client_session_key, server_session_key)) {
- fprintf(stderr, "Different session keys\n");
- return;
- }
- if (crypto_verify32(remote_pk, client_pk)) {
- fprintf(stderr, "Server got the wrong client public key\n");
- return;
- }
-}
-
-static u64 one_way_client(void)
-{
- RANDOM_INPUT(client_sk, 32);
- RANDOM_INPUT(server_sk, 32);
- RANDOM_INPUT(client_seed, 32);
- u8 msg[80]; u8 client_pk[32]; u8 server_pk[32];
- get_one_way_session(msg,
- client_pk, server_pk,
- client_sk, server_sk,
- client_seed);
- TIMING_START {
- u8 session_key[32];
- u8 seed[32];
- FOR (i, 0, 32) {
- seed[i] = client_seed[i];
- }
- crypto_kex_client_ctx client_ctx;
- crypto_kex_x_init_client(&client_ctx, seed, client_sk, client_pk,
- server_pk);
- crypto_kex_x_1(&client_ctx, session_key, msg);
- }
- TIMING_END;
-}
-
-static u64 one_way_server(void)
-{
- RANDOM_INPUT(client_sk, 32);
- RANDOM_INPUT(server_sk, 32);
- RANDOM_INPUT(client_seed, 32);
- u8 msg[80]; u8 client_pk[32]; u8 server_pk[32];
- get_one_way_session(msg,
- client_pk, server_pk,
- client_sk, server_sk,
- client_seed);
- TIMING_START {
- u8 session_key[32];
- u8 remote_pk [32]; // same as client_pk
- crypto_kex_server_ctx server_ctx;
- crypto_kex_x_init_server(&server_ctx, server_sk, server_pk);
- if (crypto_kex_x_2(&server_ctx, session_key, remote_pk, msg)) {
- fprintf(stderr, "Cannot receive\n");
- return 1;
- }
- }
- TIMING_END;
-}
-
int main()
{
print("Chacha20 ",chacha20() *MUL ,"megabytes per second");
print("x25519 ",x25519() ,"exchanges per second");
print("EdDSA(sign) ",edDSA_sign() ,"signatures per second");
print("EdDSA(check) ",edDSA_check() ,"checks per second");
- print("Monokex XK1 (client)",interactive_client(),"handshakes per second");
- print("Monokex XK1 (server)",interactive_server(),"handshakes per second");
- print("Monokex X (client)",one_way_client() ,"handshakes per second");
- print("Monokex X (server)",one_way_server() ,"handshakes per second");
printf("\n");
return 0;
}
}
#endif
-static void monokex_xk1(const vector in[], vector *out)
-{
- const vector *is = in;
- const vector *ie = in + 1;
- const vector *rs = in + 2;
- const vector *re = in + 3;
- const vector *IS = in + 4;
- const vector *RS = in + 5;
- const vector *msg1 = in + 6;
- const vector *msg2 = in + 7;
- const vector *msg3 = in + 8;
- crypto_kex_client_ctx client;
- crypto_kex_server_ctx server;
- u8 client_seed[32]; memcpy(client_seed, ie->buf, ie->size);
- u8 server_seed[32]; memcpy(server_seed, re->buf, re->size);
- crypto_kex_xk1_init_client(&client, client_seed, is->buf, IS->buf, RS->buf);
- crypto_kex_xk1_init_server(&server, server_seed, rs->buf, RS->buf);
- u8 m1 [32];
- u8 m2 [48];
- u8 m3 [48];
- u8 client_key[32];
- u8 remote_pk [32];
- crypto_kex_xk1_1(&client, m1);
- crypto_kex_xk1_2(&server, m2, m1);
- if (crypto_kex_xk1_3(&client, client_key, m3, m2)) {
- fprintf(stderr, "FAILURE: crypto_kex_xk1_3\n");
- return;
- }
- if (crypto_kex_xk1_4(&server, out->buf, remote_pk, m3)) {
- fprintf(stderr, "FAILURE: crypto_kex_xk1_4\n");
- return;
- }
-#define COMPARE(local, vector) \
- do { \
- if (memcmp(local, vector->buf, vector->size)) { \
- fprintf(stderr, "FAILURE: "#vector"\n"); \
- return; \
- } \
- } while (0)
- COMPARE(m1 , msg1);
- COMPARE(m2 , msg2);
- COMPARE(m3 , msg3);
- COMPARE(remote_pk , IS );
- COMPARE(client_key, out );
-}
-
-static void monokex_x(const vector in[], vector *out)
-{
- const vector *is = in;
- const vector *ie = in + 1;
- const vector *rs = in + 2;
- const vector *IS = in + 3;
- const vector *RS = in + 4;
- const vector *msg1 = in + 5;
- crypto_kex_client_ctx client;
- crypto_kex_server_ctx server;
- u8 seed[32]; memcpy(seed, ie->buf, ie->size);
- crypto_kex_x_init_client(&client, seed, is->buf, IS->buf, RS->buf);
- crypto_kex_x_init_server(&server, rs->buf, RS->buf);
- u8 m1 [80];
- u8 client_key[32];
- u8 remote_pk [32];
- crypto_kex_x_1(&client, client_key, m1);
- if (crypto_kex_x_2(&server, out->buf, remote_pk, m1)) {
- fprintf(stderr, "FAILURE: crypto_kex_x_2\n");
- return;
- }
- COMPARE(m1 , msg1);
- COMPARE(remote_pk , IS );
- COMPARE(client_key, out );
-}
static void iterate_x25519(u8 k[32], u8 u[32])
{
u8 tmp[32];
return status;
}
-static int p_monokex_xk1()
-{
- int status = 0;
- RANDOM_INPUT(is, 32);
- RANDOM_INPUT(ie, 32);
- RANDOM_INPUT(rs, 32);
- RANDOM_INPUT(re, 32);
- u8 IS[32]; crypto_x25519_public_key(IS, is);
- u8 RS[32]; crypto_x25519_public_key(RS, rs);
-
- crypto_kex_client_ctx client1, client2;
- crypto_kex_server_ctx server1, server2;
- u8 client_seed1[32]; memcpy(client_seed1, ie, 32);
- u8 client_seed2[32]; memcpy(client_seed2, ie, 32);
- u8 server_seed1[32]; memcpy(server_seed1, re, 32);
- u8 server_seed2[32]; memcpy(server_seed2, re, 32);
-
- // Test the same thing, with and without the local pk
- // (the API is supposed to reconstruct it)
- crypto_kex_xk1_init_client(&client1, client_seed1, is, IS, RS);
- crypto_kex_xk1_init_client(&client2, client_seed2, is, 0, RS);
- crypto_kex_xk1_init_server(&server1, server_seed1, rs, RS);
- crypto_kex_xk1_init_server(&server2, server_seed2, rs, 0);
- u8 msg11 [32]; u8 msg12 [32];
- u8 msg21 [48]; u8 msg22 [48];
- u8 msg31 [48]; u8 msg32 [48];
- u8 client_key1[32]; u8 client_key2[32];
- u8 server_key1[32]; u8 server_key2[32];
- u8 remote_pk1 [32]; u8 remote_pk2 [32];
- crypto_kex_xk1_1(&client1, msg11);
- crypto_kex_xk1_1(&client2, msg12);
- crypto_kex_xk1_2(&server1, msg21, msg11);
- crypto_kex_xk1_2(&server2, msg22, msg12);
- crypto_kex_client_ctx client_save = client1;
- crypto_kex_server_ctx server_save = server1;
- // make sure everything is accepted as it should be
- status |= crypto_kex_xk1_3(&client1, client_key1, msg31, msg21);
- status |= crypto_kex_xk1_3(&client2, client_key2, msg32, msg22);
- status |= crypto_kex_xk1_4(&server1, server_key1, remote_pk1, msg31);
- status |= crypto_kex_xk1_4(&server2, server_key2, remote_pk2, msg32);
- // Make sure we get the same result whether we gave the local pk or not
- status |= memcmp(msg11 , msg12 , 32);
- status |= memcmp(msg21 , msg22 , 48);
- status |= memcmp(msg31 , msg32 , 48);
- status |= memcmp(client_key1, client_key2, 32);
- status |= memcmp(remote_pk1 , remote_pk2 , 32);
- // make sure wrong messages are rejected as they should be.
- msg21[1]++;
- status |= !crypto_kex_xk1_3(&client_save, client_key1, msg31, msg21);
- msg32[1]++;
- status |= !crypto_kex_xk1_4(&server_save, server_key2, remote_pk2, msg32);
-
- printf("%s: monokex_xk1\n", status != 0 ? "FAILED" : "OK");
- return status;
-}
-
-static int p_monokex_x()
-{
- int status = 0;
- RANDOM_INPUT(is, 32);
- RANDOM_INPUT(ie, 32);
- RANDOM_INPUT(rs, 32);
- u8 IS[32]; crypto_x25519_public_key(IS, is);
- u8 RS[32]; crypto_x25519_public_key(RS, rs);
-
- crypto_kex_client_ctx client1, client2;
- crypto_kex_server_ctx server1, server2;
- u8 seed1[32]; memcpy(seed1, ie, 32);
- u8 seed2[32]; memcpy(seed2, ie, 32);
- crypto_kex_x_init_client(&client1, seed1, is, IS, RS);
- crypto_kex_x_init_client(&client2, seed2, is, 0, RS);
- crypto_kex_x_init_server(&server1, rs, RS);
- crypto_kex_x_init_server(&server2, rs, 0);
- u8 msg11 [80]; u8 msg12 [80];
- u8 client_key1[32]; u8 client_key2[32];
- u8 server_key1[32]; u8 server_key2[32];
- u8 remote_pk1 [32]; u8 remote_pk2 [32];
- crypto_kex_x_1(&client1, client_key1, msg11);
- crypto_kex_x_1(&client2, client_key2, msg12);
- crypto_kex_server_ctx server_save = server1;
- // make sure everything is accepted as it should be
- status |= crypto_kex_x_2(&server1, server_key1, remote_pk1, msg11);
- status |= crypto_kex_x_2(&server2, server_key2, remote_pk2, msg12);
- // Make sure we get the same result whether we gave the local pk or not
- status |= memcmp(msg11 , msg12 , 80);
- status |= memcmp(client_key1, client_key2, 32);
- status |= memcmp(remote_pk1 , remote_pk2 , 32);
- // make sure wrong messages are rejected as they should be.
- msg11[1]++;
- status |= !crypto_kex_x_2(&server_save, server_key1, remote_pk1, msg11);
-
- printf("%s: monokex_x\n", status != 0 ? "FAILED" : "OK");
- return status;
-}
-
int main(int argc, char *argv[])
{
if (argc > 1) {
status |= TEST(edDSA , 3);
status |= TEST(edDSA_pk , 1);
#endif
- status |= TEST(monokex_xk1 , 9);
- status |= TEST(monokex_x , 6);
status |= test_x25519();
printf("\nProperty based tests");
status |= p_aead();
status |= p_lock_incremental();
status |= p_auth();
- status |= p_monokex_xk1();
- status |= p_monokex_x();
printf("\n%s\n\n", status != 0 ? "SOME TESTS FAILED" : "All tests OK!");
return status;
}