int crypto_aead_decrypt( unsigned char *m,unsigned long long *mlen, unsigned char *nsec, const unsigned char *c,unsigned long long clen, const unsigned char *ad,unsigned long long adlen, const unsigned char *npub, const unsigned char *k ) { unsigned long long i; unsigned char plaintextblock[16], ciphertextblock[16]; unsigned char tag[16]; unsigned char check = 0; __m128i aegis128_state[5]; if (clen < 16) return -1; aegis128_initialization(k, npub, aegis128_state); //process the associated data for (i = 0; (i+16) <= adlen; i += 16) { aegis128_enc_aut_step(ad+i, ciphertextblock, aegis128_state); } //deal with the partial block of associated data //in this program, we assume that the message length is multiple of bytes. if ( (adlen & 0xf) != 0 ) { memset(plaintextblock, 0, 16); memcpy(plaintextblock, ad+i, adlen & 0xf); aegis128_enc_aut_step(plaintextblock, ciphertextblock, aegis128_state); } //decrypt the ciphertext *mlen = clen - 16; for (i = 0; (i+16) <= *mlen; i += 16) { aegis128_dec_aut_step(m+i, c+i, aegis128_state); } // Deal with the partial block // In this program, we assume that the message length is multiple of bytes. if ( (*mlen & 0xf) != 0 ) { memset(ciphertextblock, 0, 16); memcpy(ciphertextblock, c+i, *mlen & 0xf); aegis128_dec_aut_step(plaintextblock, ciphertextblock, aegis128_state); memcpy(m+i, plaintextblock, *mlen & 0xf); //need to modify the state here (because in the last block, keystream is wrongly used to update the state) memset(plaintextblock, 0, *mlen & 0xf); aegis128_state[0] = _mm_xor_si128( aegis128_state[0], _mm_load_si128((__m128i*)plaintextblock) ) ; } //we assume that the tag length is multiple of bytes aegis128_tag_generation(*mlen, adlen, 16, tag, aegis128_state); //verification for (i = 0; i < 16; i++) check |= (tag[i] ^ c[i+*mlen]); if (check == 0) return 0; else return -1; }
//encrypt a message. int crypto_aead_encrypt( unsigned char *c,unsigned long long *clen, const unsigned char *m,unsigned long long mlen, const unsigned char *ad,unsigned long long adlen, const unsigned char *nsec, const unsigned char *npub, const unsigned char *k ) { unsigned long i; unsigned char plaintextblock[16], ciphertextblock[16], mac[16]; unsigned char aegis128_state[80]; //initialization stage aegis128_initialization(k, npub, aegis128_state); //process the associated data for (i = 0; (i+16) <= adlen; i += 16) { aegis128_enc_aut_step(ad+i, ciphertextblock, aegis128_state); } //deal with the partial block of associated data //in this program, we assume that the message length is multiple of bytes. if ( (adlen & 0xf) != 0 ) { memset(plaintextblock, 0, 16); memcpy(plaintextblock, ad+i, adlen & 0xf); aegis128_enc_aut_step(plaintextblock, ciphertextblock, aegis128_state); } //encrypt the plaintext for (i = 0; (i+16) <= mlen; i += 16) { aegis128_enc_aut_step(m+i, c+i, aegis128_state); } // Deal with the partial block // In this program, we assume that the message length is multiple of bytes. if ( (mlen & 0xf) != 0 ) { memset(plaintextblock, 0, 16); memcpy(plaintextblock, m+i, mlen & 0xf); aegis128_enc_aut_step(plaintextblock, ciphertextblock, aegis128_state); memcpy(c+i,ciphertextblock, mlen & 0xf); } //finalization stage, we assume that the tag length is a multiple of bytes aegis128_tag_generation(mlen, adlen, 16, mac, aegis128_state); *clen = mlen + 16; memcpy(c+mlen, mac, 16); return 0; }