crypto_aead/0040777000000000000000000000000012725250271010311 5ustar00crypto_aead/acorn128v2/0040777000000000000000000000000012725250046012116 5ustar00crypto_aead/acorn128v2/opt/0040777000000000000000000000000012725250076012723 5ustar00crypto_aead/acorn128v2/opt/api.h0100777000000000000000000000020612326476726013654 0ustar00#define CRYPTO_KEYBYTES 16 #define CRYPTO_NSECBYTES 0 #define CRYPTO_NPUBBYTES 16 #define CRYPTO_ABYTES 16 #define CRYPTO_NOOVERLAP 1 crypto_aead/acorn128v2/opt/crypto_aead.h0100777000000000000000000000102212324363330015352 0ustar00int 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 ); int crypto_aead_decrypt( unsigned char *m,unsigned long long *outputmlen, 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 ); crypto_aead/acorn128v2/opt/encrypt.c0100777000000000000000000004076212725247467014576 0ustar00/* This is the optimized implementation of ACORN-128. In the implementation, we store the 293-bit register into 7 64-bit registers: 293-bit register R: r292 r291 r290 r289 r288 r287 r286 r285 ...... r5 r4 r3 r2 r1 r0 state[0]: r60 r59 r58 r57 ...... r2 r1 r0 (61 bits) (lsb: r0) state[1]: r106 r105 r104 r103 ...... r63 r62 r61 (46 bits) (lsb: r61) state[2]: r153 r152 r151 r150 ...... r109 r108 r107 (47 bits) (lsb: r107) state[3]: r192 r191 r190 r189 ...... r156 r155 r154 (39 bits) (lsb: r154) state[4]: r229 r228 r227 r226 ...... r195 r194 r193 (37 bits) (lsb: r193) state[5]: r288 r287 r286 r285 ...... r232 r231 r230 (59 bits) (lsb: r230) state[6]: r292 r291 r290 r289 (4 bits) (lsb: r289) */ #include #include #include "crypto_aead.h" #define maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) //#define ch32(x,y,z) ( ((x) & (y)) | ( ((x) ^ 0xffffffff) & (z)) ) #define ch32(x,y,z) ( ((x) & (y)) ^ ((~x) & (z)) ) //encrypt 32 bit void encrypt_32bits(unsigned long long *state, unsigned int plaintextword, unsigned int *ciphertextword, unsigned int *ks, unsigned int ca, unsigned int cb) { unsigned long long f; unsigned long long word_244, word_23, word_160, word_111, word_66, word_196, word_0, word_107, word_230; unsigned long long word_12,word_154,word_235,word_61,word_193; word_235 = state[5] >> 5; word_196 = state[4] >> 3; word_160 = state[3] >> 6; word_111 = state[2] >> 4; word_66 = state[1] >> 5; word_23 = state[0] >> 23; word_244 = state[5] >> 14; word_12 = state[0] >> 12; //update using those 6 LFSRs state[6] ^= (state[5] ^ word_235) & 0xffffffff; state[5] ^= (state[4] ^ word_196) & 0xffffffff; state[4] ^= (state[3] ^ word_160) & 0xffffffff; state[3] ^= (state[2] ^ word_111) & 0xffffffff; state[2] ^= (state[1] ^ word_66) & 0xffffffff; state[1] ^= (state[0] ^ word_23) & 0xffffffff; /* word_0 = state[0]; word_107 = state[2]; word_230 = state[5]; word_154 = state[3]; word_61 = state[1]; word_193 = state[4]; */ //compute keystream *ks = word_12 ^ state[3] ^ maj(word_235, state[1], state[4]); //f = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ (ca & state[196]) ^ (cb & (*ks)); f = state[0] ^ (state[2] ^ 0xffffffff) ^ maj(word_244, word_23, word_160) ^ ch32(state[5], word_111, word_66) ^ (word_196 & ca) ^ (cb & *ks); *ciphertextword = plaintextword ^ *ks; f = (f ^ plaintextword) & 0xffffffff; state[6] = state[6] ^ (f << 4); //shift by 32 bits state[0] = (state[0] >> 32) | ((state[1] & 0xffffffff) << 29); //32-(64-61) = 29 state[1] = (state[1] >> 32) | ((state[2] & 0xffffffff) << 14); //32-(64-46) = 14 state[2] = (state[2] >> 32) | ((state[3] & 0xffffffff) << 15); //32-(64-47) = 15 state[3] = (state[3] >> 32) | ((state[4] & 0xffffffff) << 7); //32-(64-39) = 7 state[4] = (state[4] >> 32) | ((state[5] & 0xffffffff) << 5); //32-(64-37) = 5 state[5] = (state[5] >> 32) | ((state[6] & 0xffffffff) << 27); //32-(64-59) = 27 state[6] = state[6] >> 32; //perform encryption return; } // encrypt 8 bits // it is used if the length of associated data is not multiple of 32 bits; // it is also used if the length of plaintext is not multiple of 32 bits; void encrypt_8bits(unsigned long long *state, unsigned int plaintextword, unsigned int *ciphertextword, unsigned int *ks, unsigned int ca, unsigned int cb) { unsigned long long f; unsigned long long word_244, word_23, word_160, word_111, word_66, word_196, word_0, word_107, word_230; unsigned long long word_12,word_154,word_235,word_61,word_193; //f = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ (ca & state[196]) ^ (cb & (*ks)); word_12 = state[0] >> 12; word_235 = state[5] >> 5; word_244 = state[5] >> 14; word_23 = state[0] >> 23; word_160 = state[3] >> 6; word_111 = state[2] >> 4; word_66 = state[1] >> 5; word_196 = state[4] >> 3; state[6] ^= (state[5] ^ word_235) & 0xff; state[5] ^= (state[4] ^ word_196) & 0xff; state[4] ^= (state[3] ^ word_160) & 0xff; state[3] ^= (state[2] ^ word_111) & 0xff; state[2] ^= (state[1] ^ word_66) & 0xff; state[1] ^= (state[0] ^ word_23) & 0xff; *ks = word_12 ^ state[3] ^ maj(word_235, state[1], state[4]); *ks &= 0xff; //f = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ state[196]; f = state[0] ^ (state[2] ^ 0xffffffff) ^ maj(word_244, word_23, word_160) ^ ch32(state[5], word_111, word_66) ^ (word_196 & ca) ^ (cb & *ks); f = (f ^ plaintextword) & 0xff; state[6] = state[6] ^ (f << 4); state[0] = (state[0] >> 8) | ((state[1] & 0xff) << (29+24)); //32-(64-61) = 29 state[1] = (state[1] >> 8) | ((state[2] & 0xff) << (14+24)); //32-(64-46) = 14 state[2] = (state[2] >> 8) | ((state[3] & 0xff) << (15+24)); //32-(64-47) = 15 state[3] = (state[3] >> 8) | ((state[4] & 0xff) << (7+24)); //32-(64-39) = 7 state[4] = (state[4] >> 8) | ((state[5] & 0xff) << (5+24)); //32-(64-37) = 5 state[5] = (state[5] >> 8) | ((state[6] & 0xff) << (27+24)); //32-(64-59) = 27 state[6] = state[6] >> 8; *ciphertextword = plaintextword ^ *ks; return; } //decrypt 32 bit void decrypt_32bits(unsigned long long *state, unsigned int *plaintextword, unsigned int ciphertextword, unsigned int *ks, unsigned int ca, unsigned int cb) { unsigned long long f; unsigned long long word_244, word_23, word_160, word_111, word_66, word_196, word_0, word_107, word_230; unsigned long long word_12,word_154,word_235,word_61,word_193; //f = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ (ca & state[196]) ^ (cb & (*ks)); word_12 = state[0] >> 12; word_235 = state[5] >> 5; word_244 = state[5] >> 14; word_23 = state[0] >> 23; word_160 = state[3] >> 6; word_111 = state[2] >> 4; word_66 = state[1] >> 5; word_196 = state[4] >> 3; state[6] ^= (state[5] ^ word_235) & 0xffffffff; state[5] ^= (state[4] ^ word_196) & 0xffffffff; state[4] ^= (state[3] ^ word_160) & 0xffffffff; state[3] ^= (state[2] ^ word_111) & 0xffffffff; state[2] ^= (state[1] ^ word_66) & 0xffffffff; state[1] ^= (state[0] ^ word_23) & 0xffffffff; /* word_0 = state[0]; word_107 = state[2]; word_230 = state[5]; word_154 = state[3]; word_61 = state[1]; word_193 = state[4]; */ *ks = word_12 ^ state[3] ^ maj(word_235, state[1], state[4]); //f = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ state[196]; f = state[0] ^ (state[2] ^ 0xffffffff) ^ maj(word_244, word_23, word_160) ^ ch32(state[5], word_111, word_66) ^ (word_196 & ca) ^ (cb & *ks); *plaintextword = ciphertextword ^ *ks; f = (f ^ *plaintextword) & 0xffffffff; state[6] = state[6] ^ (f << 4); state[0] = (state[0] >> 32) | ((state[1] & 0xffffffff) << 29); //32-(64-61) = 29 state[1] = (state[1] >> 32) | ((state[2] & 0xffffffff) << 14); //32-(64-46) = 14 state[2] = (state[2] >> 32) | ((state[3] & 0xffffffff) << 15); //32-(64-47) = 15 state[3] = (state[3] >> 32) | ((state[4] & 0xffffffff) << 7); //32-(64-39) = 7 state[4] = (state[4] >> 32) | ((state[5] & 0xffffffff) << 5); //32-(64-37) = 5 state[5] = (state[5] >> 32) | ((state[6] & 0xffffffff) << 27); //32-(64-59) = 27 state[6] = state[6] >> 32; return; } void decrypt_8bits(unsigned long long *state, unsigned int *plaintextword, unsigned int ciphertextword, unsigned int *ks, unsigned int ca, unsigned int cb) { unsigned long long f; unsigned long long word_244, word_23, word_160, word_111, word_66, word_196, word_0, word_107, word_230; unsigned long long word_12,word_154,word_235,word_61,word_193; //f = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ (ca & state[196]) ^ (cb & (*ks)); word_12 = state[0] >> 12; word_235 = state[5] >> 5; word_244 = state[5] >> 14; word_23 = state[0] >> 23; word_160 = state[3] >> 6; word_111 = state[2] >> 4; word_66 = state[1] >> 5; word_196 = state[4] >> 3; state[6] ^= (state[5] ^ word_235) & 0xff; state[5] ^= (state[4] ^ word_196) & 0xff; state[4] ^= (state[3] ^ word_160) & 0xff; state[3] ^= (state[2] ^ word_111) & 0xff; state[2] ^= (state[1] ^ word_66) & 0xff; state[1] ^= (state[0] ^ word_23) & 0xff; word_0 = state[0]; word_107 = state[2]; word_230 = state[5]; word_154 = state[3]; word_61 = state[1]; word_193 = state[4]; *ks = word_12 ^ state[3] ^ maj(word_235, state[1], state[4]); *ks &= 0xff; //f = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ state[196]; f = state[0] ^ (state[2] ^ 0xffffffff) ^ maj(word_244, word_23, word_160) ^ ch32(state[5], word_111, word_66) ^ (word_196 & ca) ^ (cb & *ks); *plaintextword = ciphertextword ^ *ks; f = (f ^ *plaintextword) & 0xff; state[6] = state[6] ^ (f << 4); state[0] = (state[0] >> 8) | ((state[1] & 0xff) << (29+24)); //32-(64-61) = 29 state[1] = (state[1] >> 8) | ((state[2] & 0xff) << (14+24)); //32-(64-46) = 14 state[2] = (state[2] >> 8) | ((state[3] & 0xff) << (15+24)); //32-(64-47) = 15 state[3] = (state[3] >> 8) | ((state[4] & 0xff) << (7+24)); //32-(64-39) = 7 state[4] = (state[4] >> 8) | ((state[5] & 0xff) << (5+24)); //32-(64-37) = 5 state[5] = (state[5] >> 8) | ((state[6] & 0xff) << (27+24)); //32-(64-59) = 27 state[6] = state[6] >> 8; return; } // The initialization state of ACORN /* The input to initialization is the 128-bit key; 128-bit IV;*/ void acorn128_initialization_32bitversion(const unsigned char *key, const unsigned char *iv, unsigned long long *state) { int i, j; unsigned int m; unsigned int ks=0, tem=0; //initialize the state to 0 for (j = 0; j <= 6; j++) state[j] = 0; //run the cipher for 1792 steps for (j = 0; j <= 3; j++) { encrypt_32bits(state, ((unsigned int*)key)[j], &tem, &ks, 0xffffffff, 0xffffffff); } for (j = 4; j <= 7; j++) { encrypt_32bits(state, ((unsigned int*)iv)[j-4], &tem, &ks, 0xffffffff, 0xffffffff); } for (j = 8; j <= 8; j++) { encrypt_32bits(state, ((unsigned int*)key)[j&3] ^ 1, &tem, &ks, 0xffffffff, 0xffffffff); } for (j = 9; j <= 55; j++) { encrypt_32bits(state, ((unsigned int*)key)[j&3], &tem, &ks, 0xffffffff, 0xffffffff); } } //the finalization state of acorn void acorn128_tag_generation_32bits_version(unsigned long long msglen, unsigned long long adlen, unsigned char maclen, unsigned char *mac, unsigned long long *state) { int i; unsigned int plaintextword = 0; unsigned int ciphertextword = 0; unsigned int ksword = 0; for (i = 0; i < 768/32; i++) { encrypt_32bits(state, plaintextword, &ciphertextword, &ksword, 0xffffffff, 0xffffffff); if ( i >= (768/32 - 4) ) { ((unsigned int*)mac)[i-(768/32-4)] = ksword; } } } //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 long i; unsigned char mac[16]; unsigned int plaintextword, ciphertextword, ksword; unsigned long long state[7]; unsigned int ca, cb; //initialization stage acorn128_initialization_32bitversion(k, npub, state); //process the associated data ca = 0xffffffff; cb = 0xffffffff; for (i = 0; i < adlen/4; i = i+1) { encrypt_32bits(state, ((unsigned int*)ad)[i], &ciphertextword, &ksword, ca, cb); } // if adlen is not a multiple of 4, we process the remaining bytes for (i = adlen & 0xfffffffffffffffcULL; i < adlen; i++) { ca = 0xff; cb = 0xff; plaintextword = ad[i]; encrypt_8bits(state, plaintextword, &ciphertextword, &ksword, ca, cb); } //256bits padding after the associated data for (i = 0; i < 256/32; i++) { if (i == 0) plaintextword = 0x1; else plaintextword = 0; if ( i < 128/32) ca = 0xffffffff; else ca = 0; cb = 0xffffffff; encrypt_32bits(state, plaintextword, &ciphertextword, &ksword, ca, cb); } //process the plaintext ca = 0xffffffff; cb = 0; for (i = 0; i < mlen/4; i=i+1) { encrypt_32bits(state, ((unsigned int*)m)[i], &(((unsigned int*)c)[i]), &ksword, ca, cb); //&c[i], &ksword, ca, cb); } //if mlen is not a multiple of 32 bits, we process the remaining bytes. for (i = mlen & 0xfffffffffffffffcULL; i < mlen; i++) { ca = 0xff; cb = 0x0; plaintextword = m[i]; encrypt_8bits(state, plaintextword, &ciphertextword, &ksword, ca, cb); c[i] = ciphertextword; } //256 bits padding after the plaintext for (i = 0; i < 256/32; i++) { if ( i == 0 ) plaintextword = 0x1; else plaintextword = 0; if ( i < 128/32) ca = 0xffffffff; else ca = 0; cb = 0; encrypt_32bits(state, plaintextword, &ciphertextword, &ksword, ca, cb); } //finalization stage, we assume that the tag length is a multiple of bytes acorn128_tag_generation_32bits_version(mlen, adlen, 16, mac, state); *clen = mlen + 16; memcpy(c+mlen, mac, 16); return 0; } //decrypt a message 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 tag[16],check=0; unsigned int plaintextword, ciphertextword, ksword; unsigned long long state[7]; unsigned int ca, cb; //initialization stage acorn128_initialization_32bitversion(k, npub, state); //process the associated data ca = 0xffffffff; cb = 0xffffffff; for (i = 0; i < adlen/4; i = i+1) { encrypt_32bits(state, ((unsigned int*)ad)[i], &ciphertextword, &ksword, ca, cb); } for (i = adlen & 0xfffffffffffffffcULL; i < adlen; i++) { ca = 0xff; cb = 0xff; plaintextword = ad[i]; encrypt_8bits(state, plaintextword, &ciphertextword, &ksword, ca, cb); } //256bits padding after the associated data for (i = 0; i < 256/32; i++) { if (i == 0) plaintextword = 0x1; else plaintextword = 0; if ( i < 128/32) ca = 0xffffffff; else ca = 0; cb = 0xffffffff; encrypt_32bits(state, plaintextword, &ciphertextword, &ksword, ca, cb); } //process the plaintext ca = 0xffffffff; cb = 0; *mlen = clen - 16; for (i = 0; i < *mlen/4; i=i+1) { decrypt_32bits(state, &(((unsigned int*)m)[i]), ((unsigned int*)c)[i], &ksword, ca, cb); //&c[i], &ksword, ca, cb); } for (i = *mlen & 0xfffffffffffffffcULL; i < *mlen; i++) { ca = 0xff; cb = 0x0; ciphertextword = c[i]; decrypt_8bits(state, &plaintextword, ciphertextword, &ksword, ca, cb); m[i] = plaintextword; } //256 bits padding after the plaintext for (i = 0; i < 256/32; i++) { if ( i == 0 ) plaintextword = 0x1; else plaintextword = 0; if ( i < 128/32) ca = 0xffffffff; else ca = 0; cb = 0; encrypt_32bits(state, plaintextword, &ciphertextword, &ksword, ca, cb); } //finalization stage, we assume that the tag length is a multiple of bytes acorn128_tag_generation_32bits_version(*mlen, adlen, 16, tag, state); for (i = 0; i < 16; i++) check |= (tag[i] ^ c[clen - 16 + i]); if (check == 0) return 0; else return -1; } crypto_aead/acorn128v2/ref/0040777000000000000000000000000012725250113012665 5ustar00crypto_aead/acorn128v2/ref/api.h0100777000000000000000000000020612434611611013606 0ustar00#define CRYPTO_KEYBYTES 16 #define CRYPTO_NSECBYTES 0 #define CRYPTO_NPUBBYTES 16 #define CRYPTO_ABYTES 16 #define CRYPTO_NOOVERLAP 1 crypto_aead/acorn128v2/ref/crypto_aead.h0100777000000000000000000000102212324363330015324 0ustar00int 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 ); int crypto_aead_decrypt( unsigned char *m,unsigned long long *outputmlen, 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 ); crypto_aead/acorn128v2/ref/encrypt.c0100777000000000000000000002173112725017044014525 0ustar00#include #include #include "crypto_aead.h" #define maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) #define ch(x,y,z) ( ((x) & (y)) ^ ( ((x) ^ 1) & (z)) ) unsigned char KSG128(unsigned char *state) { return ( state[12] ^ state[154] ^ maj(state[235], state[61], state[193]) ); } unsigned char FBK128(unsigned char *state, unsigned char *ks, unsigned char ca, unsigned char cb) { unsigned char f; *ks = KSG128(state); f = state[0] ^ (state[107] ^ 1) ^ maj(state[244], state[23], state[160]) ^ ch(state[230], state[111], state[66]) ^ (ca & state[196]) ^ (cb & (*ks)); return f; } //encrypt one bit void Encrypt_StateUpdate128_1bit(unsigned char *state, unsigned char plaintextbit, unsigned char *ciphertextbit, unsigned char *ks, unsigned char ca, unsigned char cb) { unsigned int j; unsigned char f; state[289] ^= state[235] ^ state[230]; state[230] ^= state[196] ^ state[193]; state[193] ^= state[160] ^ state[154]; state[154] ^= state[111] ^ state[107]; state[107] ^= state[66] ^ state[61]; state[61] ^= state[23] ^ state[0]; f = FBK128(state, ks, ca, cb); for (j = 0; j <= 291; j++) state[j] = state[j+1]; state[292] = f ^ plaintextbit; *ciphertextbit = *ks ^ plaintextbit; } //decrypt one bit void Decrypt_StateUpdate128_1bit(unsigned char *state, unsigned char *plaintextbit, unsigned char ciphertextbit, unsigned char *ks, unsigned char ca, unsigned char cb) { unsigned int j; unsigned char f; state[289] ^= state[235] ^ state[230]; state[230] ^= state[196] ^ state[193]; state[193] ^= state[160] ^ state[154]; state[154] ^= state[111] ^ state[107]; state[107] ^= state[66] ^ state[61]; state[61] ^= state[23] ^ state[0]; f = FBK128(state, ks, ca, cb); for (j = 0; j <= 291; j++) state[j] = state[j+1]; *plaintextbit = *ks ^ ciphertextbit; state[292] = f ^ *plaintextbit; } // encrypt one byte void acorn128_enc_onebyte(unsigned char *state, unsigned char plaintextbyte, unsigned char *ciphertextbyte, unsigned char *ksbyte, unsigned char cabyte, unsigned char cbbyte) { unsigned char i,t[4]; unsigned char plaintextbit,ciphertextbit,kstem,ca,cb; *ciphertextbyte = 0; kstem = 0; *ksbyte = 0; for (i = 0; i < 8; i++) { ca = (cabyte >> i) & 1; cb = (cbbyte >> i) & 1; plaintextbit = (plaintextbyte >> i) & 1; Encrypt_StateUpdate128_1bit(state, plaintextbit, &ciphertextbit, &kstem, ca, cb); *ciphertextbyte |= (ciphertextbit << i); *ksbyte |= (kstem << i); } } // decrypt one byte void acorn128_dec_onebyte(unsigned char *state, unsigned char *plaintextbyte, unsigned char ciphertextbyte, unsigned char *ksbyte, unsigned char cabyte, unsigned char cbbyte) { unsigned char i; unsigned char plaintextbit,ciphertextbit, ks,ca,cb; *plaintextbyte = 0; for (i = 0; i < 8; i++) { ca = (cabyte >> i) & 1; cb = (cbbyte >> i) & 1; ciphertextbit = (ciphertextbyte >> i) & 1; Decrypt_StateUpdate128_1bit(state, &plaintextbit, ciphertextbit, &ks, ca, cb); *plaintextbyte |= (plaintextbit << i); } } //The initialization state of ACORN /*The input to initialization is the 128-bit key; 128-bit IV;*/ void acorn128_initialization(const unsigned char *key, const unsigned char *iv, unsigned char *state) { int i,j; unsigned char m[293], ks, tem; //initialize the state to 0 for (j = 0; j <= 292; j++) state[j] = 0; //set the value of m for (j = 0; j <= 15; j++) m[j] = key[j]; for (j = 16; j <= 31; j++) m[j] = iv[j - 16]; for (j = 32; j <= 223; j++) m[j] = key[j & 0xf]; m[32] ^= 1; //run the cipher for 1792 steps for (i = 0; i < 224; i++) { acorn128_enc_onebyte(state, m[i], &tem, &ks, 0xff, 0xff); } } //the finalization state of acorn void acorn128_tag_generation(unsigned long long msglen, unsigned long long adlen, unsigned char maclen, unsigned char *mac, unsigned char *state) { int i; unsigned char plaintextbyte = 0; unsigned char ciphertextbyte = 0; unsigned char ksbyte = 0; for (i = 0; i < 768/8; i++) { acorn128_enc_onebyte(state, plaintextbyte, &ciphertextbyte, &ksbyte, 0xff, 0xff); if ( i >= (768/8 - 16) ) {mac[i-(768/8-16)] = ksbyte; } } } //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 long i; unsigned char plaintextbyte, ciphertextbyte, ksbyte, mac[16]; unsigned char state[293]; unsigned char ca, cb; //initialization stage acorn128_initialization(k, npub, state); //process the associated data for (i = 0; i < adlen; i++) { acorn128_enc_onebyte(state, ad[i], &ciphertextbyte, &ksbyte, 0xff, 0xff); } for (i = 0; i < 256/8; i++) { if ( i == 0 ) plaintextbyte = 0x1; else plaintextbyte = 0; if ( i < 128/8) ca = 0xff; else ca = 0; cb = 0xff; acorn128_enc_onebyte(state, plaintextbyte, &ciphertextbyte, &ksbyte, ca, cb); } //process the plaintext for (i = 0; i < mlen; i++) { acorn128_enc_onebyte(state, m[i], &(c[i]), &ksbyte, 0xff, 0 ); } for (i = 0; i < 256/8; i++) { if (i == 0) plaintextbyte = 0x1; else plaintextbyte = 0; if ( i < 128/8) ca = 0xff; else ca = 0; cb = 0; acorn128_enc_onebyte(state, plaintextbyte, &ciphertextbyte, &ksbyte, ca, cb); } //finalization stage, we assume that the tag length is a multiple of bytes acorn128_tag_generation(mlen, adlen, 16, mac, state); *clen = mlen + 16; memcpy(c+mlen, mac, 16); return 0; } 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 plaintextbyte, ciphertextbyte, ksbyte; unsigned char state[293]; unsigned char tag[16]; unsigned char check = 0; unsigned char ca, cb; if (clen < 16) return -1; //initialization stage acorn128_initialization(k, npub, state); //process the associated data for (i = 0; i < adlen; i++) { acorn128_enc_onebyte(state, ad[i], &ciphertextbyte, &ksbyte, 0xff, 0xff); } for (i = 0; i < 256/8; i++) { if ( i == 0 ) plaintextbyte = 0x1; else plaintextbyte = 0; if ( i < 128/8) ca = 0xff; else ca = 0; cb = 0xff; acorn128_enc_onebyte(state, plaintextbyte, &ciphertextbyte, &ksbyte, ca, cb); } //process the ciphertext *mlen = clen - 16; for (i = 0; i < *mlen; i++) { acorn128_dec_onebyte(state, &m[i], c[i], &ksbyte, 0xff, 0); } for (i = 0; i < 256/8; i++) { if ( i == 0 ) plaintextbyte = 0x1; else plaintextbyte = 0; if ( i < 128/8) ca = 0xff; else ca = 0; cb = 0; acorn128_enc_onebyte(state, plaintextbyte, &ciphertextbyte, &ksbyte, ca, cb); } //finalization stage, we assume that the tag length is a multiple of bytes acorn128_tag_generation(*mlen, adlen, 16, tag, state); for (i = 0; i < 16; i++) check |= (tag[i] ^ c[clen - 16 + i]); if (check == 0) return 0; else return -1; } /* int main() { unsigned char t,state[500]; unsigned long long s[500]; int i,j ; unsigned char plaintext[4096]; unsigned char ad[4096]; unsigned char ciphertext[4096]; unsigned char key[16]; unsigned char iv[16]; unsigned char mac[16]; unsigned long long msglen, adlen, clen; // msg, adlen, clen in bytes. unsigned char maclen = 16; unsigned int success; msglen = 1003; adlen = 1003; for (i = 0; i < 16; i++) key[i] = 0; for (i = 0; i < 16; i++) iv[i] = 0; key[0] = 1; for (i = 0; i < 4096; i++) plaintext[i] = i%256; for (i = 0; i < 4096; i++) ciphertext[i] = 0; for (i = 0; i < 4096; i++) ad[i] = i%7; crypto_aead_encrypt(ciphertext,&clen,plaintext,msglen,ad,adlen,0,iv,key); for( i = 0; i < msglen; i++) plaintext[i] = 0; t = crypto_aead_decrypt(plaintext,&msglen,0,ciphertext,clen,ad,adlen,iv,key); for( i = 0; i < msglen; i++) printf("%2x", plaintext[i]); printf("\n\n%d", t); printf("\n\nThe tag is: "); for( i = 0; i < 16; i++) printf("%2x", ciphertext[msglen+i]); } */