.Xr crypto_wipe 3monocypher ,
.Xr intro 3monocypher
.Sh STANDARDS
-These functions implement the XChacha20 (encryption) and Poly1305
-(MAC) primitives.
-Chacha20 and Poly1305 are described in RFC 7539.
+These functions implement RFC 7539, with XChacha20 instead of Chacha20.
XChacha20 derives from Chacha20 the same way XSalsa20 derives from
Salsa20, and benefits from the same security reduction (proven secure
as long as Chacha20 itself is secure).
-.Sh IMPLEMENTATION DETAILS
+.Pp
.Fn crypto_aead_lock
-and
-.Fn crypto_aead_unlock
-do not authenticate the length themselves to make them compatible with
-.Fn crypto_lock
-and
-.Fn crypto_unlock
-when the size of the additional data is zero.
-This also simplifies the implementation.
+is equivalent to the following:
+.Bd -literal -offset indent
+void crypto_aead_lock(uint8_t mac[16], uint8_t *cipher_text,
+ const uint8_t key[32],
+ const uint8_t nonce[24],
+ const uint8_t *ad , size_t ad_size,
+ const uint8_t *plain_text, size_t text_size)
+{
+ u8 auth_key[64]; /* only the first 32 bytes are used */
+ crypto_chacha_ctx ctx_e;
+ crypto_chacha20_x_init (&ctx_e, key, nonce);
+ crypto_chacha20_stream (&ctx_e, auth_key, 64);
+ crypto_chacha20_encrypt(&ctx_e, cipher_text,
+ plain_text, text_size);
+
+ static const u8 zero [15] = {0};
+ u8 sizes[16];
+ size_t ad_zero = -ad_size & 15;
+ size_t text_zero = -text_size & 15;
+ store64_le(sizes , ad_size);
+ store64_le(sizes + 8, text_size);
+
+ crypto_poly1305_ctx ctx;
+ crypto_poly1305_init (&ctx, auth_key);
+ crypto_poly1305_update(&ctx, ad , ad_size);
+ crypto_poly1305_update(&ctx, zero , ad_zero);
+ crypto_poly1305_update(&ctx, cipher_text, text_size);
+ crypto_poly1305_update(&ctx, zero , text_zero);
+ crypto_poly1305_update(&ctx, sizes , 16);
+ crypto_poly1305_final (&ctx, mac);
+}
+.Ed
.Pp
-This rarely causes problems in practice, because most of the time, the
-length of the additional data is either fixed or self-contained, and
-thus outside of attacker control.
+(Real code would also wipe the relevant buffers.)
.Os
.Sh NAME
.Nm crypto_lock_init ,
-.Nm crypto_lock_aead_auth ,
+.Nm crypto_lock_auth_ad ,
+.Nm crypto_lock_auth_message ,
.Nm crypto_lock_update ,
.Nm crypto_lock_final ,
.Nm crypto_unlock_init ,
-.Nm crypto_unlock_aead_auth ,
+.Nm crypto_unlock_auth_ad ,
+.Nm crypto_unlock_auth_message ,
.Nm crypto_unlock_update ,
-.Nm crypto_unlock_final ,
-.Nm crypto_lock_auth ,
-.Nm crypto_lock_encrypt
+.Nm crypto_unlock_final
.Nd incremental authenticated encryption with additional data
.Sh SYNOPSIS
.In monocypher.h
.Fa "const uint8_t nonce[24]"
.Fc
.Ft void
-.Fo crypto_lock_aead_auth
+.Fo crypto_lock_auth_ad
.Fa "crypto_lock_ctx *ctx"
.Fa "const uint8_t *ad"
.Fa "size_t ad_size"
.Fc
.Ft void
+.Fo crypto_lock_auth_message
+.Fa "crypto_lock_ctx *ctx"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fc
+.Ft void
.Fo crypto_lock_update
.Fa "crypto_lock_ctx *ctx"
.Fa "uint8_t *cipher_text"
.Fa "const uint8_t nonce[24]"
.Fc
.Ft void
-.Fo crypto_unlock_aead_auth
+.Fo crypto_unlock_auth_ad
.Fa "crypto_unlock_ctx *ctx"
.Fa "const uint8_t *ad"
.Fa "size_t ad_size"
.Fc
.Ft void
+.Fo crypto_unlock_auth_message
+.Fa "crypto_unlock_ctx *ctx"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fc
+.Ft void
.Fo crypto_unlock_update
.Fa "crypto_unlock_ctx *ctx"
.Fa "uint8_t *plain_text"
.Fa "crypto_unlock_ctx *ctx"
.Fa "const uint8_t mac[16]"
.Fc
-.Ft void
-.Fo crypto_lock_auth
-.Fa "crypto_lock_ctx *ctx"
-.Fa "const uint8_t *ad"
-.Fa "size_t ad_size"
-.Fc
-.Ft void
-.Fo crypto_lock_encrypt
-.Fa "crypto_lock_ctx *ctx"
-.Fa "uint8_t *cipher_text"
-.Fa "const uint8_t *plain_text"
-.Fa "size_t text_size"
-.Fc
.Sh DESCRIPTION
These functions are variants of
.Xr crypto_lock 3monocypher ,
.Fn crypto_lock_init .
.It
Authenticate additional data, if any, with
-.Fn crypto_lock_aead_auth .
+.Fn crypto_lock_auth_ad .
.It
Encrypt and authenticate some data with
.Fn crypto_lock_update .
.Fn crypto_unlock_init .
.It
Verify additional data, if any, with
-.Fn crypto_unlock_aead_auth .
+.Fn crypto_unlock_auth_ad .
.It
Decrypt and verify some data with
.Fn crypto_unlock_update .
Verify the MAC with
.Fn crypto_unlock_final .
.El
-.Pp
-.Fn crypto_lock_encrypt
-encrypts or decrypts data
-.Em without authenticating it .
-It is meant as a building block.
-Used with
-.Fn crypto_lock_auth ,
-it enables various AEAD constructions.
-Most users do not need either of them.
-Prefer
-.Fn crypto_lock_update
-and
-.Fn crypto_unlock_update
-instead.
.Sh RETURN VALUES
.Fn crypto_lock_init ,
.Fn crypto_unlock_init ,
-.Fn crypto_lock_auth ,
-.Fn crypto_lock_encrypt ,
-.Fn crypto_lock_aead_auth ,
-.Fn crypto_unlock_aead_auth ,
+.Fn crypto_lock_auth_ad ,
+.Fn crypto_unlock_auth_ad ,
+.Fn crypto_lock_auth_message ,
+.Fn crypto_unlock_auth_message ,
.Fn crypto_lock_update ,
.Fn crypto_unlock_update ,
and
/* Authenticate additional data */
for (size_t i = 0; i < 500; i += 100) {
- crypto_lock_aead_auth(&ctx, ad + i, 100);
+ crypto_lock_auth_ad(&ctx, ad + i, 100);
}
/* Encrypt message */
/* Verify additional data */
for (size_t i = 0; i < 500; i += 100) {
- crypto_unlock_aead_auth(&ctx, ad + i, 100);
+ crypto_unlock_auth_ad(&ctx, ad + i, 100);
}
/* Decrypt message */
crypto_wipe(plain_text, 500);
.Ed
.Pp
+To authenticate the above without decrypting it:
+.Bd -literal -offset indent
+const uint8_t key [ 32]; /* Session key */
+const uint8_t nonce [ 32]; /* Unique per session key */
+const uint8_t mac [ 16]; /* Transmitted MAC */
+const uint8_t ad [500]; /* Optional additional data */
+const uint8_t cipher_text[500]; /* Encrypted message */
+
+/* Set up initial context */
+crypto_unlock_ctx ctx;
+crypto_unlock_init(&ctx, key, nonce);
+/* Wipe the key if it is no longer needed */
+crypto_wipe(key, 32);
+
+/* Verify additional data */
+for (size_t i = 0; i < 500; i += 100) {
+ crypto_unlock_auth_ad(&ctx, ad + i, 100);
+}
+
+/* Verify message */
+for (size_t i = 0; i < 500; i += 100) {
+ crypto_unlock_auth_message(&ctx, cipher_text + i, 100);
+}
+
+/* Check the MAC */
+if (crypto_unlock_final(&ctx, mac)) {
+ /* Corrupted message */
+} else {
+ /* Genuine message */
+}
+.Ed
+.Pp
In-place encryption without additional data:
.Bd -literal -offset indent
const uint8_t key [ 32]; /* Session key */
.Xr crypto_wipe 3monocypher ,
.Xr intro 3monocypher
.Sh STANDARDS
-These functions implement the XChacha20 (encryption) and Poly1305
-(MAC) primitives.
-Chacha20 and Poly1305 are described in RFC 7539.
+These functions implement RFC 7539, with XChacha20 instead of Chacha20.
XChacha20 derives from Chacha20 the same way XSalsa20 derives from
Salsa20, and benefits from the same security reduction (proven secure
as long as Chacha20 itself is secure).
is an alias to
.Fn crypto_lock_init .
.It
-.Fn crypto_lock_aead_auth
+.Fn crypto_lock_auth_ad
and
-.Fn crypto_unlock_aead_auth
+.Fn crypto_unlock_auth_ad
are aliases to
.Fn crypto_lock_auth .
.El
interface at identifying corrupted messages.
This is because the incremental interface works in a single pass and has
to interleave decryption and verification.
-Users who expect a high corruption rate may want to avoid it.
+Users who expect a high corruption rate may want to perform a first
+pass with
+.Fn crypto_unlock_auth_message
+before decrypting the message.
.Xr crypto_check_update 3monocypher ,
.Xr crypto_key_exchange 3monocypher ,
.Xr crypto_lock 3monocypher ,
-.Xr crypto_lock_auth 3monocypher ,
-.Xr crypto_lock_encrypt 3monocypher ,
+.Xr crypto_lock_auth_ad 3monocypher ,
+.Xr crypto_lock_auth_message 3monocypher ,
.Xr crypto_lock_final 3monocypher ,
.Xr crypto_lock_init 3monocypher ,
.Xr crypto_lock_update 3monocypher ,
.Xr crypto_sign_public_key 3monocypher ,
.Xr crypto_sign_update 3monocypher ,
.Xr crypto_unlock 3monocypher ,
-.Xr crypto_unlock_update 3monocypher ,
+.Xr crypto_unlock_auth_ad 3monocypher ,
+.Xr crypto_unlock_auth_message 3monocypher ,
.Xr crypto_unlock_final 3monocypher ,
+.Xr crypto_unlock_init 3monocypher ,
+.Xr crypto_unlock_update 3monocypher ,
.Xr crypto_verify16 3monocypher ,
.Xr crypto_verify32 3monocypher ,
.Xr crypto_verify64 3monocypher ,
////////////////////////////////
/// Authenticated encryption ///
////////////////////////////////
+static void lock_ad_padding(crypto_lock_ctx *ctx)
+{
+ static const u8 zero[15] = {0};
+ if (ctx->ad_phase) {
+ ctx->ad_phase = 0;
+ crypto_poly1305_update(&(ctx->poly), zero, -ctx->ad_size & 15);
+ }
+}
+
void crypto_lock_init(crypto_lock_ctx *ctx, const u8 key[32], const u8 nonce[24])
{
- u8 auth_key[32];
+ u8 auth_key[64]; // "Wasting" the whole Chacha block is faster
+ ctx->ad_phase = 1;
+ ctx->ad_size = 0;
+ ctx->message_size = 0;
crypto_chacha20_x_init(&(ctx->chacha), key, nonce);
- crypto_chacha20_stream(&(ctx->chacha), auth_key, 32);
+ crypto_chacha20_stream(&(ctx->chacha), auth_key, 64);
crypto_poly1305_init (&(ctx->poly ), auth_key);
WIPE_BUFFER(auth_key);
}
-void crypto_lock_encrypt(crypto_lock_ctx *ctx, u8 *cipher_text,
- const u8 *plain_text, size_t text_size)
+void crypto_lock_auth_ad(crypto_lock_ctx *ctx, const u8 *msg, size_t msg_size)
{
- crypto_chacha20_encrypt(&(ctx->chacha), cipher_text, plain_text, text_size);
+ crypto_poly1305_update(&(ctx->poly), msg, msg_size);
+ ctx->ad_size += msg_size;
}
-void crypto_lock_auth(crypto_lock_ctx *ctx, const u8 *msg, size_t msg_size)
+void crypto_lock_auth_message(crypto_lock_ctx *ctx,
+ const u8 *cipher_text, size_t text_size)
{
- crypto_poly1305_update(&(ctx->poly), msg, msg_size);
+ lock_ad_padding(ctx);
+ ctx->message_size += text_size;
+ crypto_poly1305_update(&(ctx->poly), cipher_text, text_size);
}
void crypto_lock_update(crypto_lock_ctx *ctx, u8 *cipher_text,
const u8 *plain_text, size_t text_size)
{
- crypto_lock_encrypt(ctx, cipher_text, plain_text, text_size);
- crypto_lock_auth (ctx, cipher_text, text_size);
+ crypto_chacha20_encrypt(&(ctx->chacha), cipher_text, plain_text, text_size);
+ crypto_lock_auth_message(ctx, cipher_text, text_size);
}
void crypto_lock_final(crypto_lock_ctx *ctx, u8 mac[16])
{
- crypto_poly1305_final(&(ctx->poly), mac);
+ lock_ad_padding(ctx);
+ static const u8 zero[15] = {0};
+ u8 sizes[16];
+ store64_le(sizes + 0, ctx->ad_size);
+ store64_le(sizes + 8, ctx->message_size);
+ crypto_poly1305_update(&(ctx->poly), zero, -ctx->message_size & 15);
+ crypto_poly1305_update(&(ctx->poly), sizes, 16);
+ crypto_poly1305_final (&(ctx->poly), mac);
WIPE_CTX(ctx);
}
void crypto_unlock_update(crypto_lock_ctx *ctx, u8 *plain_text,
const u8 *cipher_text, size_t text_size)
{
- crypto_lock_auth (ctx, cipher_text, text_size);
- crypto_lock_encrypt(ctx, plain_text, cipher_text, text_size);
+ crypto_unlock_auth_message(ctx, cipher_text, text_size);
+ crypto_chacha20_encrypt(&(ctx->chacha), plain_text, cipher_text, text_size);
}
int crypto_unlock_final(crypto_lock_ctx *ctx, const u8 mac[16])
const u8 *plain_text, size_t text_size)
{
crypto_lock_ctx ctx;
- crypto_lock_init (&ctx, key, nonce);
- // authenticate additional data first, to allow overlapping buffers
- crypto_lock_auth (&ctx, ad, ad_size);
- crypto_lock_update(&ctx, cipher_text, plain_text, text_size);
- crypto_lock_final (&ctx, mac);
+ crypto_lock_init (&ctx, key, nonce);
+ crypto_lock_auth_ad(&ctx, ad, ad_size);
+ crypto_lock_update (&ctx, cipher_text, plain_text, text_size);
+ crypto_lock_final (&ctx, mac);
}
int crypto_aead_unlock(u8 *plain_text,
const u8 *ad , size_t ad_size,
const u8 *cipher_text, size_t text_size)
{
- crypto_lock_ctx ctx;
- crypto_lock_init(&ctx, key, nonce);
- crypto_lock_auth(&ctx, ad, ad_size);
- crypto_lock_auth(&ctx, cipher_text, text_size);
+ crypto_unlock_ctx ctx;
+ crypto_unlock_init (&ctx, key, nonce);
+ crypto_unlock_auth_ad (&ctx, ad, ad_size);
+ crypto_unlock_auth_message(&ctx, cipher_text, text_size);
crypto_chacha_ctx chacha_ctx = ctx.chacha; // avoid the wiping...
if (crypto_unlock_final(&ctx, mac)) { // ...that occurs here
WIPE_CTX(&chacha_ctx);
typedef struct {
crypto_chacha_ctx chacha;
crypto_poly1305_ctx poly;
+ uint64_t ad_size;
+ uint64_t message_size;
+ int ad_phase;
} crypto_lock_ctx;
#define crypto_unlock_ctx crypto_lock_ctx
void crypto_lock_init(crypto_lock_ctx *ctx,
const uint8_t key[32],
const uint8_t nonce[24]);
-#define crypto_lock_aead_auth crypto_lock_auth
+void crypto_lock_auth_ad(crypto_lock_ctx *ctx,
+ const uint8_t *message,
+ size_t message_size);
+void crypto_lock_auth_message(crypto_lock_ctx *ctx,
+ const uint8_t *cipher_text, size_t text_size);
void crypto_lock_update(crypto_lock_ctx *ctx,
uint8_t *cipher_text,
const uint8_t *plain_text,
void crypto_lock_final(crypto_lock_ctx *ctx, uint8_t mac[16]);
// Incremental interface (decryption)
-#define crypto_unlock_init crypto_lock_init
-#define crypto_unlock_aead_auth crypto_lock_auth
+#define crypto_unlock_init crypto_lock_init
+#define crypto_unlock_auth_ad crypto_lock_auth_ad
+#define crypto_unlock_auth_message crypto_lock_auth_message
void crypto_unlock_update(crypto_lock_ctx *ctx,
uint8_t *plain_text,
const uint8_t *cipher_text,
const uint8_t your_secret_key [32],
const uint8_t their_public_key [32]);
-
-// Building block for authenticated encryption
-// -------------------------------------------
-void crypto_lock_encrypt(crypto_lock_ctx *ctx,
- uint8_t *cipher_text,
- const uint8_t *plain_text,
- size_t text_size);
-void crypto_lock_auth(crypto_lock_ctx *ctx,
- const uint8_t *message,
- size_t message_size);
-
#endif // MONOCYPHER_H
--- /dev/null
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t text_size, size_t ad_size)
+{
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+ RANDOM_INPUT(ad , 32); // ad size <= 32
+ RANDOM_INPUT(text , 128); // text_size <= 128
+ u8 out[16 + 128]; // text_size <= 128
+
+ crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
+ out + 16, out, 0, text, text_size, ad, ad_size, 0, nonce, key);
+
+ print_vector(key , 32);
+ print_vector(nonce , 24);
+ print_vector(ad , ad_size);
+ print_vector(text , text_size);
+ print_vector(out , text_size + 16);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ // regular tests
+ FOR (text_size, 0, 128) { test(text_size, 0); }
+ FOR (text_size, 0, 128) { test(text_size, 4); }
+ FOR ( ad_size, 0, 32) { test(0, ad_size); }
+ FOR ( ad_size, 0, 32) { test(16, ad_size); }
+ return 0;
+}
.PHONY: all clean
-VEC = chacha20.vec xchacha20.vec poly1305.vec blake2b.vec \
- sha512.vec argon2i.vec edDSA.vec x25519.vec
+VEC = chacha20.vec xchacha20.vec aead_ietf.vec poly1305.vec blake2b.vec \
+ sha512.vec argon2i.vec edDSA.vec x25519.vec
VEC2 = $(patsubst %.vec, %.all.vec, $(VEC)) key_exchange.all.vec
HEADERS = $(patsubst %.all.vec, %.h.vec, $(VEC2))
VECTORS = ../vectors.h
poly1305.all.vec : poly1305.vec ../vectors/poly1305
x25519.all.vec : x25519.vec ../vectors/x25519
xchacha20.all.vec : xchacha20.vec
+aead_ietf.all.vec : aead_ietf.vec
blake2b.all.vec : blake2b.vec
sha512.all.vec : sha512.vec
argon2i.all.vec : argon2i.vec
crypto_poly1305(out->buf, msg->buf, msg->size, key->buf);
}
+static void aead_ietf(const vector in[], vector *out)
+{
+ const vector *key = in;
+ const vector *nonce = in + 1;
+ const vector *ad = in + 2;
+ const vector *text = in + 3;
+ crypto_aead_lock(out ->buf, out->buf + 16, key->buf, nonce->buf,
+ ad->buf, ad->size, text->buf, text->size);
+}
+
+
static void blake2b(const vector in[], vector *out)
{
const vector *msg = in;
crypto_aead_lock(mac1, cipher1, key, nonce,
ad, ad_size, plain, text_size);
crypto_lock_ctx ctx;
- crypto_lock_init (&ctx, key, nonce);
- crypto_lock_aead_auth(&ctx, ad1, ad_size1); // just to show ad also have
- crypto_lock_aead_auth(&ctx, ad2, ad_size2); // an incremental interface
- crypto_lock_update (&ctx, cipher2 , plain1, text_size1);
- crypto_lock_update (&ctx, cipher2 + text_size1, plain2, text_size2);
- crypto_lock_final (&ctx, mac2);
+ crypto_lock_init (&ctx, key, nonce);
+ crypto_lock_auth_ad(&ctx, ad1, ad_size1); // just to show ad also have
+ crypto_lock_auth_ad(&ctx, ad2, ad_size2); // an incremental interface
+ crypto_lock_update (&ctx, cipher2 , plain1, text_size1);
+ crypto_lock_update (&ctx, cipher2 + text_size1, plain2, text_size2);
+ crypto_lock_final (&ctx, mac2);
status |= memcmp(mac1 , mac2 , 16 );
status |= memcmp(cipher1, cipher2, text_size);
u8 re_plain2[256];
status |= crypto_aead_unlock(re_plain1, key, nonce, mac1,
ad, ad_size, cipher1, text_size);
- crypto_unlock_init (&ctx, key, nonce);
- crypto_unlock_aead_auth(&ctx, ad, ad_size);
- crypto_unlock_update (&ctx, re_plain2, cipher2, text_size);
+ crypto_unlock_init (&ctx, key, nonce);
+ crypto_unlock_auth_ad(&ctx, ad, ad_size);
+ crypto_unlock_update (&ctx, re_plain2, cipher2, text_size);
status |= crypto_unlock_final(&ctx, mac2);
status |= memcmp(mac1 , mac2 , 16 );
status |= memcmp(plain, re_plain1, text_size);
status |= memcmp(plain, re_plain2, text_size);
// Test authentication without decryption
- crypto_lock_init (&ctx, key, nonce);
- crypto_lock_aead_auth(&ctx, ad , ad_size );
- crypto_lock_aead_auth(&ctx, cipher2, text_size);
+ crypto_unlock_init (&ctx, key, nonce);
+ crypto_unlock_auth_ad (&ctx, ad , ad_size );
+ crypto_unlock_auth_message(&ctx, cipher2, text_size);
status |= crypto_unlock_final(&ctx, mac2);
// The same, except we're supposed to reject forgeries
if (text_size > 0) {
cipher2[0]++; // forgery attempt
- crypto_lock_init (&ctx, key, nonce);
- crypto_lock_aead_auth(&ctx, ad , ad_size );
- crypto_lock_aead_auth(&ctx, cipher2, text_size);
+ crypto_unlock_init (&ctx, key, nonce);
+ crypto_unlock_auth_ad (&ctx, ad , ad_size );
+ crypto_unlock_auth_message(&ctx, cipher2, text_size);
status |= !crypto_unlock_final(&ctx, mac2);
}
}
return status;
}
+// Only additionnal data
+static int p_auth()
+{
+ int status = 0;
+ FOR (i, 0, 128) {
+ u8 key [ 32]; p_random(key , 32);
+ u8 nonce [ 24]; p_random(nonce , 24);
+ u8 ad [128]; p_random(ad , i);
+ u8 mac1[16];
+ u8 mac2[16];
+ // roundtrip
+ {
+ crypto_lock_ctx ctx;
+ crypto_lock_init (&ctx, key, nonce);
+ crypto_lock_auth_ad(&ctx, ad, i);
+ crypto_lock_final (&ctx, mac1);
+ crypto_aead_lock(mac2, 0, key, nonce, ad, i, 0, 0);
+ status |= memcmp(mac1, mac2, 16);
+ }
+ {
+ crypto_unlock_ctx ctx;
+ crypto_unlock_init (&ctx, key, nonce);
+ crypto_unlock_auth_ad(&ctx, ad, i);
+ status |= crypto_unlock_final(&ctx, mac1);
+ status |= crypto_aead_unlock(0, key, nonce, mac1, ad, i, 0, 0);
+ }
+ }
+ printf("%s: aead (authentication)\n", status != 0 ? "FAILED" : "OK");
+ return status;
+}
+
int main(void)
{
int status = 0;
status |= TEST(chacha20 , 4);
status |= TEST(xchacha20 , 4);
status |= TEST(poly1305 , 2);
+ status |= TEST(aead_ietf , 4);
status |= TEST(blake2b , 2);
status |= TEST(sha512 , 1);
status |= TEST(argon2i , 4);
status |= p_eddsa_overlap();
status |= p_aead();
status |= p_lock_incremental();
+ status |= p_auth();
printf("\n%s\n\n", status != 0 ? "SOME TESTS FAILED" : "All tests OK!");
return status;