Skip to content

Commit

Permalink
Faster AEGIS-128L incremental APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
jedisct1 committed Nov 13, 2024
1 parent b3e69d0 commit bc73ebf
Showing 1 changed file with 73 additions and 27 deletions.
100 changes: 73 additions & 27 deletions src/aegis128l/aegis128l_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,18 +293,21 @@ decrypt_unauthenticated(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t
}
}

typedef aes_block_t aegis_blocks[8];

typedef struct _aegis128l_state {
aes_block_t state[8];
uint8_t buf[RATE];
uint64_t adlen;
uint64_t mlen;
size_t pos;
aegis_blocks blocks;
uint8_t buf[RATE];
uint64_t adlen;
uint64_t mlen;
size_t pos;
} _aegis128l_state;

static void
state_init(aegis128l_state *st_, const uint8_t *ad, size_t adlen, const uint8_t *npub,
const uint8_t *k)
{
aegis_blocks blocks;
_aegis128l_state *const st =
(_aegis128l_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
Expand All @@ -314,28 +317,35 @@ state_init(aegis128l_state *st_, const uint8_t *ad, size_t adlen, const uint8_t
st->mlen = 0;
st->pos = 0;

aegis128l_init(k, npub, st->state);
memcpy(blocks, st->blocks, sizeof blocks);

aegis128l_init(k, npub, blocks);
for (i = 0; i + RATE <= adlen; i += RATE) {
aegis128l_absorb(ad + i, st->state);
aegis128l_absorb(ad + i, blocks);
}
if (adlen % RATE) {
memset(st->buf, 0, RATE);
memcpy(st->buf, ad + i, adlen % RATE);
aegis128l_absorb(st->buf, st->state);
aegis128l_absorb(st->buf, blocks);
}
st->adlen = adlen;

memcpy(st->blocks, blocks, sizeof blocks);
}

static int
state_encrypt_update(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written,
const uint8_t *m, size_t mlen)
{
aegis_blocks blocks;
_aegis128l_state *const st =
(_aegis128l_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
size_t i = 0;
size_t left;

memcpy(blocks, st->blocks, sizeof blocks);

*written = 0;
st->mlen += mlen;
if (st->pos != 0) {
Expand All @@ -354,7 +364,7 @@ state_encrypt_update(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *
return -1;
}
clen_max -= RATE;
aegis128l_enc(c, st->buf, st->state);
aegis128l_enc(c, st->buf, blocks);
*written += RATE;
c += RATE;
st->pos = 0;
Expand All @@ -367,27 +377,33 @@ state_encrypt_update(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *
return -1;
}
for (i = 0; i + RATE <= mlen; i += RATE) {
aegis128l_enc(c + i, m + i, st->state);
aegis128l_enc(c + i, m + i, blocks);
}
*written += i;
left = mlen % RATE;
if (left != 0) {
memcpy(st->buf, m + i, left);
st->pos = left;
}

memcpy(st->blocks, blocks, sizeof blocks);

return 0;
}

static int
state_encrypt_detached_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written,
uint8_t *mac, size_t maclen)
{
aegis_blocks blocks;
_aegis128l_state *const st =
(_aegis128l_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
CRYPTO_ALIGN(ALIGNMENT) uint8_t src[RATE];
CRYPTO_ALIGN(ALIGNMENT) uint8_t dst[RATE];

memcpy(blocks, st->blocks, sizeof blocks);

*written = 0;
if (clen_max < st->pos) {
errno = ERANGE;
Expand All @@ -396,26 +412,31 @@ state_encrypt_detached_final(aegis128l_state *st_, uint8_t *c, size_t clen_max,
if (st->pos != 0) {
memset(src, 0, sizeof src);
memcpy(src, st->buf, st->pos);
aegis128l_enc(dst, src, st->state);
aegis128l_enc(dst, src, blocks);
memcpy(c, dst, st->pos);
}
aegis128l_mac(mac, maclen, st->adlen, st->mlen, st->state);
aegis128l_mac(mac, maclen, st->adlen, st->mlen, blocks);

*written = st->pos;

memcpy(st->blocks, blocks, sizeof blocks);

return 0;
}

static int
state_encrypt_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *written,
size_t maclen)
{
aegis_blocks blocks;
_aegis128l_state *const st =
(_aegis128l_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
CRYPTO_ALIGN(ALIGNMENT) uint8_t src[RATE];
CRYPTO_ALIGN(ALIGNMENT) uint8_t dst[RATE];

memcpy(blocks, st->blocks, sizeof blocks);

*written = 0;
if (clen_max < st->pos + maclen) {
errno = ERANGE;
Expand All @@ -424,27 +445,32 @@ state_encrypt_final(aegis128l_state *st_, uint8_t *c, size_t clen_max, size_t *w
if (st->pos != 0) {
memset(src, 0, sizeof src);
memcpy(src, st->buf, st->pos);
aegis128l_enc(dst, src, st->state);
aegis128l_enc(dst, src, blocks);
memcpy(c, dst, st->pos);
}
aegis128l_mac(c + st->pos, maclen, st->adlen, st->mlen, st->state);
aegis128l_mac(c + st->pos, maclen, st->adlen, st->mlen, blocks);

*written = st->pos + maclen;

memcpy(st->blocks, blocks, sizeof blocks);

return 0;
}

static int
state_decrypt_detached_update(aegis128l_state *st_, uint8_t *m, size_t mlen_max, size_t *written,
const uint8_t *c, size_t clen)
{
aegis_blocks blocks;
_aegis128l_state *const st =
(_aegis128l_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
CRYPTO_ALIGN(ALIGNMENT) uint8_t dst[RATE];
size_t i = 0;
size_t left;

memcpy(blocks, st->blocks, sizeof blocks);

*written = 0;
st->mlen += clen;

Expand All @@ -468,10 +494,10 @@ state_decrypt_detached_update(aegis128l_state *st_, uint8_t *m, size_t mlen_max,
return -1;
}
mlen_max -= RATE;
aegis128l_dec(m, st->buf, st->state);
aegis128l_dec(m, st->buf, blocks);
m += RATE;
} else {
aegis128l_dec(dst, st->buf, st->state);
aegis128l_dec(dst, st->buf, blocks);
}
*written += RATE;
}
Expand All @@ -481,11 +507,11 @@ state_decrypt_detached_update(aegis128l_state *st_, uint8_t *m, size_t mlen_max,
return -1;
}
for (i = 0; i + RATE <= clen; i += RATE) {
aegis128l_dec(m + i, c + i, st->state);
aegis128l_dec(m + i, c + i, blocks);
}
} else {
for (i = 0; i + RATE <= clen; i += RATE) {
aegis128l_dec(dst, c + i, st->state);
aegis128l_dec(dst, c + i, blocks);
}
}
*written += i;
Expand All @@ -494,33 +520,39 @@ state_decrypt_detached_update(aegis128l_state *st_, uint8_t *m, size_t mlen_max,
memcpy(st->buf, c + i, left);
st->pos = left;
}

memcpy(st->blocks, blocks, sizeof blocks);

return 0;
}

static int
state_decrypt_detached_final(aegis128l_state *st_, uint8_t *m, size_t mlen_max, size_t *written,
const uint8_t *mac, size_t maclen)
{
aegis_blocks blocks;
CRYPTO_ALIGN(16) uint8_t computed_mac[32];
CRYPTO_ALIGN(ALIGNMENT) uint8_t dst[RATE];
_aegis128l_state *const st =
(_aegis128l_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
int ret;

memcpy(blocks, st->blocks, sizeof blocks);

*written = 0;
if (st->pos != 0) {
if (m != NULL) {
if (mlen_max < st->pos) {
errno = ERANGE;
return -1;
}
aegis128l_declast(m, st->buf, st->pos, st->state);
aegis128l_declast(m, st->buf, st->pos, blocks);
} else {
aegis128l_declast(dst, st->buf, st->pos, st->state);
aegis128l_declast(dst, st->buf, st->pos, blocks);
}
}
aegis128l_mac(computed_mac, maclen, st->adlen, st->mlen, st->state);
aegis128l_mac(computed_mac, maclen, st->adlen, st->mlen, blocks);
ret = -1;
if (maclen == 16) {
ret = aegis_verify_16(computed_mac, mac);
Expand All @@ -532,18 +564,24 @@ state_decrypt_detached_final(aegis128l_state *st_, uint8_t *m, size_t mlen_max,
} else {
memset(m, 0, st->pos);
}

memcpy(st->blocks, blocks, sizeof blocks);

return ret;
}

static int
state_mac_update(aegis128l_state *st_, const uint8_t *ad, size_t adlen)
{
aegis_blocks blocks;
_aegis128l_state *const st =
(_aegis128l_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
size_t i;
size_t left;

memcpy(blocks, st->blocks, sizeof blocks);

left = st->adlen % RATE;
st->adlen += adlen;
if (left != 0) {
Expand All @@ -552,7 +590,7 @@ state_mac_update(aegis128l_state *st_, const uint8_t *ad, size_t adlen)
return 0;
}
memcpy(st->buf + left, ad, RATE - left);
aegis128l_absorb(st->buf, st->state);
aegis128l_absorb(st->buf, blocks);
ad += RATE - left;
adlen -= RATE - left;
}
Expand All @@ -565,33 +603,41 @@ state_mac_update(aegis128l_state *st_, const uint8_t *ad, size_t adlen)
msg3 = AES_BLOCK_LOAD(ad + i + AES_BLOCK_LENGTH * 3);
COMPILER_ASSERT(AES_BLOCK_LENGTH * 4 == RATE * 2);

aegis128l_update(st->state, msg0, msg1);
aegis128l_update(st->state, msg2, msg3);
aegis128l_update(blocks, msg0, msg1);
aegis128l_update(blocks, msg2, msg3);
}
for (; i + RATE <= adlen; i += RATE) {
aegis128l_absorb(ad + i, st->state);
aegis128l_absorb(ad + i, blocks);
}
if (i < adlen) {
memset(st->buf, 0, RATE);
memcpy(st->buf, ad + i, adlen - i);
}

memcpy(st->blocks, blocks, sizeof blocks);

return 0;
}

static int
state_mac_final(aegis128l_state *st_, uint8_t *mac, size_t maclen)
{
aegis_blocks blocks;
_aegis128l_state *const st =
(_aegis128l_state *) ((((uintptr_t) &st_->opaque) + (ALIGNMENT - 1)) &
~(uintptr_t) (ALIGNMENT - 1));
size_t left;

memcpy(blocks, st->blocks, sizeof blocks);

left = st->adlen % RATE;
if (left != 0) {
memset(st->buf + left, 0, RATE - left);
aegis128l_absorb(st->buf, st->state);
aegis128l_absorb(st->buf, blocks);
}
aegis128l_mac(mac, maclen, st->adlen, 0, st->state);
aegis128l_mac(mac, maclen, st->adlen, 0, blocks);

memcpy(st->blocks, blocks, sizeof blocks);

return 0;
}
Expand Down

0 comments on commit bc73ebf

Please sign in to comment.