#include "api.h" #include "endian.h" #include "permutations.h" #define PA_ROUNDS 12 #define PB_ROUNDS 6 #define IV \ ((uint64_t)(8 * (CRYPTO_KEYBYTES)) << 56 | \ (uint64_t)(8 * (ASCON_RATE)) << 48 | (uint64_t)(PA_ROUNDS) << 40 | \ (uint64_t)(PB_ROUNDS) << 32) int crypto_aead_encrypt(uint8_t* c, uint64_t* clen, const uint8_t* m, uint64_t mlen, const uint8_t* ad, uint64_t adlen, const uint8_t* nsec, const uint8_t* npub, const uint8_t* k) { const uint64_t K0 = U64BIG(*(uint64_t*)k); const uint64_t K1 = U64BIG(*(uint64_t*)(k + 8)); const uint64_t N0 = U64BIG(*(uint64_t*)npub); const uint64_t N1 = U64BIG(*(uint64_t*)(npub + 8)); state_t s; uint32_t i; (void)nsec; /* set ciphertext size */ *clen = mlen + CRYPTO_ABYTES; /* initialization */ s.x0 = IV; s.x1 = K0; s.x2 = K1; s.x3 = N0; s.x4 = N1; P12(); s.x3 ^= K0; s.x4 ^= K1; /* process associated data */ if (adlen) { AD(); for (i = 0; i < adlen; ++i, ++ad) s.x0 ^= SETBYTE(*ad, i); s.x0 ^= SETBYTE(0x80, adlen); P6(); } s.x4 ^= 1; /* process plaintext */ PT(); for (i = 0; i < mlen; ++i, ++m, ++c) { s.x0 ^= SETBYTE(*m, i); *c = GETBYTE(s.x0, i); } s.x0 ^= SETBYTE(0x80, mlen); /* finalization */ s.x1 ^= K0; s.x2 ^= K1; P12(); s.x3 ^= K0; s.x4 ^= K1; /* set tag */ *(uint64_t*)c = U64BIG(s.x3); *(uint64_t*)(c + 8) = U64BIG(s.x4); return 0; }