Commit 017a9cea by Hongjun Wu Committed by Sebastian Renner

tinyjambu with for loop

parent 109ff80f
/* /*
TinyJAMBU-128: 128-bit key, 96-bit IV TinyJAMBU-128: 128-bit key, 96-bit IV
Optimized implementation Optimized implementation
The state consists of four 32-bit registers The state consists of four 32-bit registers
state[3] || state[2] || state[1] || state[0] state[3] || state[2] || state[1] || state[0]
Implemented by: Hongjun Wu Implemented by: Hongjun Wu
*/ */
#include <string.h>
#include <stdio.h>
#include "crypto_aead.h" #include "crypto_aead.h"
#define FrameBitsIV 0x10 #define FrameBitsIV 0x10
#define FrameBitsAD 0x30 #define FrameBitsAD 0x30
#define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext #define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext
...@@ -22,36 +21,36 @@ ...@@ -22,36 +21,36 @@
/*optimized state update function*/ /*optimized state update function*/
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps) void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
{ {
unsigned int i; unsigned int i;
unsigned int t1, t2, t3, t4; unsigned int t1, t2, t3, t4;
//in each iteration, we compute 128 rounds of the state update function. //in each iteration, we compute 128 rounds of the state update function.
for (i = 0; i < (number_of_steps >> 5); i = i+4) for (i = 0; i < (number_of_steps >> 5); i = i+4)
{ {
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15 t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6 t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21 t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27 t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
state[0] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[0]; state[0] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[0];
t1 = (state[2] >> 15) | (state[3] << 17); t1 = (state[2] >> 15) | (state[3] << 17);
t2 = (state[3] >> 6) | (state[0] << 26); t2 = (state[3] >> 6) | (state[0] << 26);
t3 = (state[3] >> 21) | (state[0] << 11); t3 = (state[3] >> 21) | (state[0] << 11);
t4 = (state[3] >> 27) | (state[0] << 5); t4 = (state[3] >> 27) | (state[0] << 5);
state[1] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[1]; state[1] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[1];
t1 = (state[3] >> 15) | (state[0] << 17); t1 = (state[3] >> 15) | (state[0] << 17);
t2 = (state[0] >> 6) | (state[1] << 26); t2 = (state[0] >> 6) | (state[1] << 26);
t3 = (state[0] >> 21) | (state[1] << 11); t3 = (state[0] >> 21) | (state[1] << 11);
t4 = (state[0] >> 27) | (state[1] << 5); t4 = (state[0] >> 27) | (state[1] << 5);
state[2] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[2]; state[2] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[2];
t1 = (state[0] >> 15) | (state[1] << 17); t1 = (state[0] >> 15) | (state[1] << 17);
t2 = (state[1] >> 6) | (state[2] << 26); t2 = (state[1] >> 6) | (state[2] << 26);
t3 = (state[1] >> 21) | (state[2] << 11); t3 = (state[1] >> 21) | (state[2] << 11);
t4 = (state[1] >> 27) | (state[2] << 5); t4 = (state[1] >> 27) | (state[2] << 5);
state[3] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[3]; state[3] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[3];
} }
} }
// The initialization // The initialization
...@@ -61,41 +60,41 @@ void initialization(const unsigned char *key, const unsigned char *iv, unsigned ...@@ -61,41 +60,41 @@ void initialization(const unsigned char *key, const unsigned char *iv, unsigned
int i; int i;
//initialize the state as 0 //initialize the state as 0
for (i = 0; i < 4; i++) state[i] = 0; for (i = 0; i < 4; i++) state[i] = 0;
//update the state with the key //update the state with the key
state_update(state, key, NROUND2); state_update(state, key, NROUND2);
//introduce IV into the state //introduce IV into the state
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
state[1] ^= FrameBitsIV; state[1] ^= FrameBitsIV;
state_update(state, key, NROUND1); state_update(state, key, NROUND1);
state[3] ^= ((unsigned int*)iv)[i]; state[3] ^= ((unsigned int*)iv)[i];
} }
} }
//process the associated data //process the associated data
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state) void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
{ {
unsigned long long i; unsigned long long i;
unsigned int j; unsigned int j;
for (i = 0; i < (adlen >> 2); i++) for (i = 0; i < (adlen >> 2); i++)
{ {
state[1] ^= FrameBitsAD; state[1] ^= FrameBitsAD;
state_update(state, k, NROUND1); state_update(state, k, NROUND1);
state[3] ^= ((unsigned int*)ad)[i]; state[3] ^= ((unsigned int*)ad)[i];
} }
// if adlen is not a multiple of 4, we process the remaining bytes // if adlen is not a multiple of 4, we process the remaining bytes
if ((adlen & 3) > 0) if ((adlen & 3) > 0)
{ {
state[1] ^= FrameBitsAD; state[1] ^= FrameBitsAD;
state_update(state, k, NROUND1); state_update(state, k, NROUND1);
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j]; for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
state[1] ^= adlen & 3; state[1] ^= adlen & 3;
} }
} }
//encrypt plaintext //encrypt plaintext
...@@ -108,51 +107,51 @@ int crypto_aead_encrypt( ...@@ -108,51 +107,51 @@ int crypto_aead_encrypt(
const unsigned char *k const unsigned char *k
) )
{ {
unsigned long long i; unsigned long long i;
unsigned int j; unsigned int j;
unsigned char mac[8]; unsigned char mac[8];
unsigned int state[4]; unsigned int state[4];
//initialization stage //initialization stage
initialization(k, npub, state); initialization(k, npub, state);
//process the associated data //process the associated data
process_ad(k, ad, adlen, state); process_ad(k, ad, adlen, state);
//process the plaintext //process the plaintext
for (i = 0; i < (mlen >> 2); i++) for (i = 0; i < (mlen >> 2); i++)
{ {
state[1] ^= FrameBitsPC; state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
state[3] ^= ((unsigned int*)m)[i]; state[3] ^= ((unsigned int*)m)[i];
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i]; ((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
} }
// if mlen is not a multiple of 4, we process the remaining bytes // if mlen is not a multiple of 4, we process the remaining bytes
if ((mlen & 3) > 0) if ((mlen & 3) > 0)
{ {
state[1] ^= FrameBitsPC; state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
for (j = 0; j < (mlen & 3); j++) for (j = 0; j < (mlen & 3); j++)
{ {
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j]; ((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j]; c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
} }
state[1] ^= mlen & 3; state[1] ^= mlen & 3;
} }
//finalization stage, we assume that the tag length is 8 bytes //finalization stage, we assume that the tag length is 8 bytes
state[1] ^= FrameBitsFinalization; state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
((unsigned int*)mac)[0] = state[2]; ((unsigned int*)mac)[0] = state[2];
state[1] ^= FrameBitsFinalization; state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND1); state_update(state, k, NROUND1);
((unsigned int*)mac)[1] = state[2]; ((unsigned int*)mac)[1] = state[2];
*clen = mlen + 8; *clen = mlen + 8;
memcpy(c + mlen, mac, 8); for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
return 0; return 0;
} }
//decrypt a message //decrypt a message
...@@ -165,52 +164,52 @@ int crypto_aead_decrypt( ...@@ -165,52 +164,52 @@ int crypto_aead_decrypt(
const unsigned char *k const unsigned char *k
) )
{ {
unsigned long long i; unsigned long long i;
unsigned int j, check = 0; unsigned int j, check = 0;
unsigned char mac[8]; unsigned char mac[8];
unsigned int state[4]; unsigned int state[4];
*mlen = clen - 8; *mlen = clen - 8;
//initialization stage //initialization stage
initialization(k, npub, state); initialization(k, npub, state);
//process the associated data //process the associated data
process_ad(k, ad, adlen, state); process_ad(k, ad, adlen, state);
//process the ciphertext //process the ciphertext
for (i = 0; i < (*mlen >> 2); i++) for (i = 0; i < (*mlen >> 2); i++)
{ {
state[1] ^= FrameBitsPC; state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i]; ((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
state[3] ^= ((unsigned int*)m)[i]; state[3] ^= ((unsigned int*)m)[i];
} }
// if mlen is not a multiple of 4, we process the remaining bytes // if mlen is not a multiple of 4, we process the remaining bytes
if ((*mlen & 3) > 0) if ((*mlen & 3) > 0)
{ {
state[1] ^= FrameBitsPC; state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
for (j = 0; j < (*mlen & 3); j++) for (j = 0; j < (*mlen & 3); j++)
{ {
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j]; m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j]; ((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
} }
state[1] ^= *mlen & 3; state[1] ^= *mlen & 3;
} }
//finalization stage, we assume that the tag length is 8 bytes //finalization stage, we assume that the tag length is 8 bytes
state[1] ^= FrameBitsFinalization; state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
((unsigned int*)mac)[0] = state[2]; ((unsigned int*)mac)[0] = state[2];
state[1] ^= FrameBitsFinalization; state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND1); state_update(state, k, NROUND1);
((unsigned int*)mac)[1] = state[2]; ((unsigned int*)mac)[1] = state[2];
//verification of the authentication tag //verification of the authentication tag
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); } for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
if (check == 0) return 0; if (check == 0) return 0;
else return -1; else return -1;
} }
/* /*
TinyJAMBU-128: 128-bit key, 96-bit IV TinyJAMBU-128: 128-bit key, 96-bit IV
Reference implementation for 32-bit CPU Reference implementation for 32-bit CPU
The state consists of four 32-bit registers The state consists of four 32-bit registers
state[3] || state[2] || state[1] || state[0] state[3] || state[2] || state[1] || state[0]
Implemented by: Hongjun Wu Implemented by: Hongjun Wu
*/ */
#include <string.h>
#include <stdio.h>
#include "crypto_aead.h" #include "crypto_aead.h"
#define FrameBitsIV 0x10 #define FrameBitsIV 0x10
...@@ -22,19 +20,19 @@ ...@@ -22,19 +20,19 @@
/*no-optimized date update function*/ /*no-optimized date update function*/
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps) void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
{ {
unsigned int i; unsigned int i;
unsigned int t1, t2, t3, t4, feedback; unsigned int t1, t2, t3, t4, feedback;
for (i = 0; i < (number_of_steps >> 5); i++) for (i = 0; i < (number_of_steps >> 5); i++)
{ {
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15 t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6 t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21 t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27 t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
feedback = state[0] ^ t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[i & 3]; feedback = state[0] ^ t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[i & 3];
// shift 32 bit positions // shift 32 bit positions
state[0] = state[1]; state[1] = state[2]; state[2] = state[3]; state[0] = state[1]; state[1] = state[2]; state[2] = state[3];
state[3] = feedback ; state[3] = feedback ;
} }
} }
// The initialization // The initialization
...@@ -44,41 +42,41 @@ void initialization(const unsigned char *key, const unsigned char *iv, unsigned ...@@ -44,41 +42,41 @@ void initialization(const unsigned char *key, const unsigned char *iv, unsigned
int i; int i;
//initialize the state as 0 //initialize the state as 0
for (i = 0; i < 4; i++) state[i] = 0; for (i = 0; i < 4; i++) state[i] = 0;
//update the state with the key //update the state with the key
state_update(state, key, NROUND2); state_update(state, key, NROUND2);
//introduce IV into the state //introduce IV into the state
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
state[1] ^= FrameBitsIV; state[1] ^= FrameBitsIV;
state_update(state, key, NROUND1); state_update(state, key, NROUND1);
state[3] ^= ((unsigned int*)iv)[i]; state[3] ^= ((unsigned int*)iv)[i];
} }
} }
//process the associated data //process the associated data
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state) void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
{ {
unsigned long long i; unsigned long long i;
unsigned int j; unsigned int j;
for (i = 0; i < (adlen >> 2); i++)
{
state[1] ^= FrameBitsAD;
state_update(state, k, NROUND1);
state[3] ^= ((unsigned int*)ad)[i];
}
for (i = 0; i < (adlen >> 2); i++) // if adlen is not a multiple of 4, we process the remaining bytes
{ if ((adlen & 3) > 0)
state[1] ^= FrameBitsAD; {
state_update(state, k, NROUND1); state[1] ^= FrameBitsAD;
state[3] ^= ((unsigned int*)ad)[i]; state_update(state, k, NROUND1);
} for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
state[1] ^= adlen & 3;
// if adlen is not a multiple of 4, we process the remaining bytes }
if ((adlen & 3) > 0)
{
state[1] ^= FrameBitsAD;
state_update(state, k, NROUND1);
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
state[1] ^= adlen & 3;
}
} }
//encrypt plaintext //encrypt plaintext
...@@ -91,51 +89,51 @@ int crypto_aead_encrypt( ...@@ -91,51 +89,51 @@ int crypto_aead_encrypt(
const unsigned char *k const unsigned char *k
) )
{ {
unsigned long long i; unsigned long long i;
unsigned int j; unsigned int j;
unsigned char mac[8]; unsigned char mac[8];
unsigned int state[4]; unsigned int state[4];
//initialization stage //initialization stage
initialization(k, npub, state); initialization(k, npub, state);
//process the associated data //process the associated data
process_ad(k, ad, adlen, state); process_ad(k, ad, adlen, state);
//process the plaintext //process the plaintext
for (i = 0; i < (mlen >> 2); i++) for (i = 0; i < (mlen >> 2); i++)
{ {
state[1] ^= FrameBitsPC; state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
state[3] ^= ((unsigned int*)m)[i]; state[3] ^= ((unsigned int*)m)[i];
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i]; ((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
} }
// if mlen is not a multiple of 4, we process the remaining bytes // if mlen is not a multiple of 4, we process the remaining bytes
if ((mlen & 3) > 0) if ((mlen & 3) > 0)
{ {
state[1] ^= FrameBitsPC; state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
for (j = 0; j < (mlen & 3); j++) for (j = 0; j < (mlen & 3); j++)
{ {
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j]; ((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j]; c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
} }
state[1] ^= mlen & 3; state[1] ^= mlen & 3;
} }
//finalization stage, we assume that the tag length is 8 bytes //finalization stage, we assume that the tag length is 8 bytes
state[1] ^= FrameBitsFinalization; state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
((unsigned int*)mac)[0] = state[2]; ((unsigned int*)mac)[0] = state[2];
state[1] ^= FrameBitsFinalization; state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND1); state_update(state, k, NROUND1);
((unsigned int*)mac)[1] = state[2]; ((unsigned int*)mac)[1] = state[2];
*clen = mlen + 8; *clen = mlen + 8;
memcpy(c + mlen, mac, 8); for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
return 0; return 0;
} }
//decrypt a message //decrypt a message
...@@ -148,51 +146,51 @@ int crypto_aead_decrypt( ...@@ -148,51 +146,51 @@ int crypto_aead_decrypt(
const unsigned char *k const unsigned char *k
) )
{ {
unsigned long long i; unsigned long long i;
unsigned int j, check = 0; unsigned int j, check = 0;
unsigned char mac[8]; unsigned char mac[8];
unsigned int state[4]; unsigned int state[4];
*mlen = clen - 8; *mlen = clen - 8;
//initialization stage //initialization stage
initialization(k, npub, state); initialization(k, npub, state);
//process the associated data //process the associated data
process_ad(k, ad, adlen, state); process_ad(k, ad, adlen, state);
//process the ciphertext //process the ciphertext
for (i = 0; i < (*mlen >> 2); i++) for (i = 0; i < (*mlen >> 2); i++)
{ {
state[1] ^= FrameBitsPC; state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i]; ((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
state[3] ^= ((unsigned int*)m)[i]; state[3] ^= ((unsigned int*)m)[i];
} }
// if mlen is not a multiple of 4, we process the remaining bytes // if mlen is not a multiple of 4, we process the remaining bytes
if ((*mlen & 3) > 0) if ((*mlen & 3) > 0)
{ {
state[1] ^= FrameBitsPC; state[1] ^= FrameBitsPC;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
for (j = 0; j < (*mlen & 3); j++) for (j = 0; j < (*mlen & 3); j++)
{ {
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j]; m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j]; ((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
} }
state[1] ^= *mlen & 3; state[1] ^= *mlen & 3;
} }
//finalization stage, we assume that the tag length is 8 bytes //finalization stage, we assume that the tag length is 8 bytes
state[1] ^= FrameBitsFinalization; state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND2); state_update(state, k, NROUND2);
((unsigned int*)mac)[0] = state[2]; ((unsigned int*)mac)[0] = state[2];
state[1] ^= FrameBitsFinalization; state[1] ^= FrameBitsFinalization;
state_update(state, k, NROUND1); state_update(state, k, NROUND1);
((unsigned int*)mac)[1] = state[2]; ((unsigned int*)mac)[1] = state[2];
//verification of the authentication tag //verification of the authentication tag
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); } for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
if (check == 0) return 0; if (check == 0) return 0;
else return -1; else return -1;
} }
/* /*
TinyJAMBU-192: 192-bit key, 96-bit IV TinyJAMBU-192: 192-bit key, 96-bit IV
Optimized Implementation for 32-bit processor Optimized Implementation for 32-bit processor
The state consists of four 32-bit registers The state consists of four 32-bit registers
state[3] || state[2] || state[1] || state[0] state[3] || state[2] || state[1] || state[0]
Implemented by Hongjun Wu Implemented by Hongjun Wu
*/ */
#include <string.h>
#include <stdio.h>
#include "crypto_aead.h" #include "crypto_aead.h"
#define FrameBitsIV 0x10 #define FrameBitsIV 0x10
...@@ -165,7 +163,7 @@ int crypto_aead_encrypt( ...@@ -165,7 +163,7 @@ int crypto_aead_encrypt(
((unsigned int*)mac)[1] = state[2]; ((unsigned int*)mac)[1] = state[2];
*clen = mlen + 8; *clen = mlen + 8;
memcpy(c + mlen, mac, 8); for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
return 0; return 0;
} }
......
/* /*
TinyJAMBU: 192-bit key, 96-bit IV TinyJAMBU: 192-bit key, 96-bit IV
Reference implementation for 32-bit CPU Reference implementation for 32-bit CPU
The state consists of four 32-bit registers The state consists of four 32-bit registers
state[3] || state[2] || state[1] || state[0] state[3] || state[2] || state[1] || state[0]
Implemented by: Hongjun Wu Implemented by: Hongjun Wu
*/ */
#include <string.h>
#include <stdio.h>
#include "crypto_aead.h" #include "crypto_aead.h"
#define FrameBitsIV 0x10 #define FrameBitsIV 0x10
...@@ -42,21 +40,21 @@ void state_update(unsigned int *state, const unsigned char *key, unsigned int nu ...@@ -42,21 +40,21 @@ void state_update(unsigned int *state, const unsigned char *key, unsigned int nu
/* The input to initialization is the 192-bit key; 96-bit IV;*/ /* The input to initialization is the 192-bit key; 96-bit IV;*/
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state) void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
{ {
int i; int i;
//initialize the state as 0 //initialize the state as 0
for (i = 0; i < 4; i++) state[i] = 0; for (i = 0; i < 4; i++) state[i] = 0;
//update the state with the key //update the state with the key
state_update(state, key, NROUND2); state_update(state, key, NROUND2);
//introduce IV into the state //introduce IV into the state
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
state[1] ^= FrameBitsIV; state[1] ^= FrameBitsIV;
state_update(state, key, NROUND1); state_update(state, key, NROUND1);
state[3] ^= ((unsigned int*)iv)[i]; state[3] ^= ((unsigned int*)iv)[i];
} }
} }
//process the associated data //process the associated data
...@@ -92,15 +90,15 @@ int crypto_aead_encrypt( ...@@ -92,15 +90,15 @@ int crypto_aead_encrypt(
const unsigned char *k const unsigned char *k
) )
{ {
unsigned long long i; unsigned long long i;
unsigned int j; unsigned int j;
unsigned char mac[8]; unsigned char mac[8];
unsigned int state[4]; unsigned int state[4];
//initialization stage //initialization stage
initialization(k, npub, state); initialization(k, npub, state);
//process the associated data //process the associated data
process_ad(k, ad, adlen, state); process_ad(k, ad, adlen, state);
//process the plaintext //process the plaintext
...@@ -133,10 +131,10 @@ int crypto_aead_encrypt( ...@@ -133,10 +131,10 @@ int crypto_aead_encrypt(
state_update(state, k, NROUND1); state_update(state, k, NROUND1);
((unsigned int*)mac)[1] = state[2]; ((unsigned int*)mac)[1] = state[2];
*clen = mlen + 8; *clen = mlen + 8;
memcpy(c + mlen, mac, 8); for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
return 0; return 0;
} }
//decrypt a message //decrypt a message
...@@ -195,6 +193,6 @@ int crypto_aead_decrypt( ...@@ -195,6 +193,6 @@ int crypto_aead_decrypt(
//verification of the authentication tag //verification of the authentication tag
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); } for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
if (check == 0) return 0; if (check == 0) return 0;
else return -1; else return -1;
} }
/* /*
TinyJAMBU-256: 256-bit key, 96-bit IV TinyJAMBU-256: 256-bit key, 96-bit IV
Optimized implementation Optimized implementation
The state consists of four 32-bit registers The state consists of four 32-bit registers
state[3] || state[2] || state[1] || state[0] state[3] || state[2] || state[1] || state[0]
Implemented by: Hongjun Wu Implemented by: Hongjun Wu
*/ */
#include <string.h>
#include <stdio.h>
#include "crypto_aead.h" #include "crypto_aead.h"
#define FrameBitsIV 0x10 #define FrameBitsIV 0x10
...@@ -61,18 +59,18 @@ void initialization(const unsigned char *key, const unsigned char *iv, unsigned ...@@ -61,18 +59,18 @@ void initialization(const unsigned char *key, const unsigned char *iv, unsigned
int i; int i;
//initialize the state as 0 //initialize the state as 0
for (i = 0; i < 4; i++) state[i] = 0; for (i = 0; i < 4; i++) state[i] = 0;
//update the state with the key //update the state with the key
state_update(state, key, NROUND2); state_update(state, key, NROUND2);
//introduce IV into the state //introduce IV into the state
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
state[1] ^= FrameBitsIV; state[1] ^= FrameBitsIV;
state_update(state, key, NROUND1); state_update(state, key, NROUND1);
state[3] ^= ((unsigned int*)iv)[i]; state[3] ^= ((unsigned int*)iv)[i];
} }
} }
//process the associated data //process the associated data
...@@ -150,8 +148,8 @@ int crypto_aead_encrypt( ...@@ -150,8 +148,8 @@ int crypto_aead_encrypt(
((unsigned int*)mac)[1] = state[2]; ((unsigned int*)mac)[1] = state[2];
*clen = mlen + 8; *clen = mlen + 8;
memcpy(c + mlen, mac, 8); for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
return 0; return 0;
} }
......
/* /*
TinyJAMBU-256: 256-bit key, 96-bit IV TinyJAMBU-256: 256-bit key, 96-bit IV
Reference Implementation for 32-bit processor Reference Implementation for 32-bit processor
The state consists of four 32-bit registers The state consists of four 32-bit registers
state[3] || state[2] || state[1] || state[0] state[3] || state[2] || state[1] || state[0]
Implemented by Hongjun Wu Implemented by Hongjun Wu
*/ */
#include <string.h>
#include <stdio.h>
#include "crypto_aead.h" #include "crypto_aead.h"
#define FrameBitsIV 0x10 #define FrameBitsIV 0x10
...@@ -42,21 +40,21 @@ void state_update(unsigned int *state, const unsigned char *key, unsigned int nu ...@@ -42,21 +40,21 @@ void state_update(unsigned int *state, const unsigned char *key, unsigned int nu
/* The input to initialization is the 128-bit key; 96-bit IV;*/ /* The input to initialization is the 128-bit key; 96-bit IV;*/
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state) void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
{ {
int i; int i;
//initialize the state as 0 //initialize the state as 0
for (i = 0; i < 4; i++) state[i] = 0; for (i = 0; i < 4; i++) state[i] = 0;
//update the state with the key //update the state with the key
state_update(state, key, NROUND2); state_update(state, key, NROUND2);
//introduce IV into the state //introduce IV into the state
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
state[1] ^= FrameBitsIV; state[1] ^= FrameBitsIV;
state_update(state, key, NROUND1); state_update(state, key, NROUND1);
state[3] ^= ((unsigned int*)iv)[i]; state[3] ^= ((unsigned int*)iv)[i];
} }
} }
//process the associated data //process the associated data
...@@ -92,15 +90,15 @@ int crypto_aead_encrypt( ...@@ -92,15 +90,15 @@ int crypto_aead_encrypt(
const unsigned char *k const unsigned char *k
) )
{ {
unsigned long long i; unsigned long long i;
unsigned int j; unsigned int j;
unsigned char mac[8]; unsigned char mac[8];
unsigned int state[4]; unsigned int state[4];
//initialization stage //initialization stage
initialization(k, npub, state); initialization(k, npub, state);
//process the associated data //process the associated data
process_ad(k, ad, adlen, state); process_ad(k, ad, adlen, state);
//process the plaintext //process the plaintext
...@@ -133,10 +131,10 @@ int crypto_aead_encrypt( ...@@ -133,10 +131,10 @@ int crypto_aead_encrypt(
state_update(state, k, NROUND1); state_update(state, k, NROUND1);
((unsigned int*)mac)[1] = state[2]; ((unsigned int*)mac)[1] = state[2];
*clen = mlen + 8; *clen = mlen + 8;
memcpy(c + mlen, mac, 8); for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
return 0; return 0;
} }
//decrypt a message //decrypt a message
...@@ -194,6 +192,6 @@ int crypto_aead_decrypt( ...@@ -194,6 +192,6 @@ int crypto_aead_decrypt(
//verification of the authentication tag //verification of the authentication tag
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); } for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
if (check == 0) return 0; if (check == 0) return 0;
else return -1; else return -1;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment