Commit 5dbc59fa by Enrico Pozzobon

Merge branch 'email-submissions'

parents da92cb38 ab62fe67
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
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);
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);
/*
* Date: 29 November 2018
* Contact: Thomas Peyrin - thomas.peyrin@gmail.com
* Mustafa Khairallah - mustafam001@e.ntu.edu.sg
*/
#include "crypto_aead.h"
#include "api.h"
#include "skinny.h"
#include <stdio.h>
#include <stdlib.h>
void pad (const unsigned char* m, unsigned char* mp, int l, int len8) {
int i;
for (i = 0; i < l; i++) {
if (i < len8) {
mp[i] = m[i];
}
else if (i == l - 1) {
mp[i] = (len8 & 0x0f);
}
else {
mp[i] = 0x00;
}
}
}
void g8A (unsigned char* s, unsigned char* c) {
unsigned int tmps[4];
unsigned int tmpc[4];
tmps[0] = *((unsigned int *)&s[0]);
tmps[1] = *((unsigned int *)&s[4]);
tmps[2] = *((unsigned int *)&s[8]);
tmps[3] = *((unsigned int *)&s[12]);
// c[i] = (s[i] >> 1) ^ (s[i] & 0x80) ^ ((s[i] & 0x01) << 7);
//
// (s[i] >> 1) -> ((s[i]>>1)&0x7f)
// (s[i] & 0x80) -> (s[i])&0x80) not changed
// ((s[i] & 0x01) << 7) -> ((s[i]<<7)&0x80)
// use word access because of speeding up
tmpc[0] = ((tmps[0]>>1) & 0x7f7f7f7f) ^ (tmps[0] & 0x80808080) ^ ((tmps[0]<<7) & 0x80808080);
tmpc[1] = ((tmps[1]>>1) & 0x7f7f7f7f) ^ (tmps[1] & 0x80808080) ^ ((tmps[1]<<7) & 0x80808080);
tmpc[2] = ((tmps[2]>>1) & 0x7f7f7f7f) ^ (tmps[2] & 0x80808080) ^ ((tmps[2]<<7) & 0x80808080);
tmpc[3] = ((tmps[3]>>1) & 0x7f7f7f7f) ^ (tmps[3] & 0x80808080) ^ ((tmps[3]<<7) & 0x80808080);
*((unsigned int *)&c[0]) = tmpc[0];
*((unsigned int *)&c[4]) = tmpc[1];
*((unsigned int *)&c[8]) = tmpc[2];
*((unsigned int *)&c[12]) = tmpc[3];
}
void g8A_for_Tag_Generation (unsigned char* s, unsigned char* c) {
unsigned int tmps[4];
unsigned int tmpc[4];
tmps[0] = *((unsigned int *)&s[0]);
tmps[1] = *((unsigned int *)&s[4]);
tmps[2] = *((unsigned int *)&s[8]);
tmps[3] = *((unsigned int *)&s[12]);
// c[i] = (s[i] >> 1) ^ (s[i] & 0x80) ^ ((s[i] & 0x01) << 7);
//
// (s[i] >> 1) -> ((s[i]>>1)&0x7f)
// (s[i] & 0x80) -> (s[i])&0x80) not changed
// ((s[i] & 0x01) << 7) -> ((s[i]<<7)&0x80)
// use word access because of speeding up
tmpc[0] = ((tmps[0]>>1) & 0x7f7f7f7f) ^ (tmps[0] & 0x80808080) ^ ((tmps[0]<<7) & 0x80808080);
tmpc[1] = ((tmps[1]>>1) & 0x7f7f7f7f) ^ (tmps[1] & 0x80808080) ^ ((tmps[1]<<7) & 0x80808080);
tmpc[2] = ((tmps[2]>>1) & 0x7f7f7f7f) ^ (tmps[2] & 0x80808080) ^ ((tmps[2]<<7) & 0x80808080);
tmpc[3] = ((tmps[3]>>1) & 0x7f7f7f7f) ^ (tmps[3] & 0x80808080) ^ ((tmps[3]<<7) & 0x80808080);
// use byte access because of memory alignment.
// c is not always in word(4 byte) alignment.
c[0] = tmpc[0] &0xFF;
c[1] = (tmpc[0]>>8) &0xFF;
c[2] = (tmpc[0]>>16)&0xFF;
c[3] = (tmpc[0]>>24)&0xFF;
c[4] = tmpc[1] &0xFF;
c[5] = (tmpc[1]>>8) &0xFF;
c[6] = (tmpc[1]>>16)&0xFF;
c[7] = (tmpc[1]>>24)&0xFF;
c[8] = tmpc[2] &0xFF;
c[9] = (tmpc[2]>>8) &0xFF;
c[10] = (tmpc[2]>>16)&0xFF;
c[11] = (tmpc[2]>>24)&0xFF;
c[12] = tmpc[3] &0xFF;
c[13] = (tmpc[3]>>8) &0xFF;
c[14] = (tmpc[3]>>16)&0xFF;
c[15] = (tmpc[3]>>24)&0xFF;
}
void rho_ad_eqov16 (const unsigned char* m,
unsigned char* s) {
*((unsigned int *)&s[0]) ^= *((unsigned int *)&m[0]);
*((unsigned int *)&s[4]) ^= *((unsigned int *)&m[4]);
*((unsigned int *)&s[8]) ^= *((unsigned int *)&m[8]);
*((unsigned int *)&s[12]) ^= *((unsigned int *)&m[12]);
}
void rho_ad_ud16 (const unsigned char* m,
unsigned char* s,
int len8) {
unsigned char mp [16];
pad(m,mp,16,len8);
*((unsigned int *)&s[0]) ^= *((unsigned int *)&mp[0]);
*((unsigned int *)&s[4]) ^= *((unsigned int *)&mp[4]);
*((unsigned int *)&s[8]) ^= *((unsigned int *)&mp[8]);
*((unsigned int *)&s[12]) ^= *((unsigned int *)&mp[12]);
}
void rho_eqov16 (const unsigned char* m,
unsigned char* c,
unsigned char* s) {
g8A(s,c);
*((unsigned int *)&s[0]) ^= *((unsigned int *)&m[0]);
*((unsigned int *)&s[4]) ^= *((unsigned int *)&m[4]);
*((unsigned int *)&s[8]) ^= *((unsigned int *)&m[8]);
*((unsigned int *)&s[12]) ^= *((unsigned int *)&m[12]);
*((unsigned int *)&c[0]) ^= *((unsigned int *)&m[0]);
*((unsigned int *)&c[4]) ^= *((unsigned int *)&m[4]);
*((unsigned int *)&c[8]) ^= *((unsigned int *)&m[8]);
*((unsigned int *)&c[12]) ^= *((unsigned int *)&m[12]);
}
void rho_ud16 (const unsigned char* m,
unsigned char* c,
unsigned char* s,
int len8,
int ver) {
int i;
unsigned char mp [16];
pad(m,mp,ver,len8);
g8A(s,c);
*((unsigned int *)&s[0]) ^= *((unsigned int *)&mp[0]);
*((unsigned int *)&s[4]) ^= *((unsigned int *)&mp[4]);
*((unsigned int *)&s[8]) ^= *((unsigned int *)&mp[8]);
*((unsigned int *)&s[12]) ^= *((unsigned int *)&mp[12]);
for (i = 0; i < ver; i++) {
if (i < len8) {
c[i] = c[i] ^ mp[i];
}
else {
c[i] = 0;
}
}
}
void irho (unsigned char* m,
const unsigned char* c,
unsigned char* s,
int len8,
int ver) {
int i;
unsigned char cp [16];
pad(c,cp,ver,len8);
g8A(s,m);
for (i = 0; i < ver; i++) {
if (i < len8) {
s[i] = s[i] ^ cp[i] ^ m[i];
}
else {
s[i] = s[i] ^ cp[i];
}
if (i < len8) {
m[i] = m[i] ^ cp[i];
}
else {
m[i] = 0;
}
}
}
void reset_lfsr_gf56 (unsigned char* CNT) {
*((unsigned int *)&CNT[0]) = 0x00000001;
*((unsigned int *)&CNT[4]) = 0x00000000;
}
void lfsr_gf56 (unsigned char* CNT) {
unsigned int tmpCNT[2];
unsigned int fb0;
tmpCNT[0] = *((unsigned int *)&CNT[0]); // CNT3 CNT2 CNT1 CNT0
tmpCNT[1] = *((unsigned int *)&CNT[4]); // CNT7 CNT6 CNT5 CNT4
fb0 = 0;
if ((tmpCNT[1] >> 23)&0x01) {
fb0 = 0x95;
}
tmpCNT[1] = tmpCNT[1] << 1 | tmpCNT[0] >> 31;
tmpCNT[0] = tmpCNT[0] << 1 ^ fb0;
*((unsigned int *)&CNT[0]) = tmpCNT[0];
*((unsigned int *)&CNT[4]) = tmpCNT[1];
}
void block_cipher(unsigned char* s,
const unsigned char* k, unsigned char* T,
unsigned char* CNT,
skinny_ctrl* p_skinny_ctrl) {
p_skinny_ctrl->func_skinny_128_384_enc (s,p_skinny_ctrl,CNT,T,k);
}
void nonce_encryption (const unsigned char* N,
unsigned char* CNT,
unsigned char*s, const unsigned char* k,
unsigned char D,
skinny_ctrl* p_skinny_ctrl) {
unsigned char T [16];
*((unsigned int *)&T[0]) = *((unsigned int *)&N[0]);
*((unsigned int *)&T[4]) = *((unsigned int *)&N[4]);
*((unsigned int *)&T[8]) = *((unsigned int *)&N[8]);
*((unsigned int *)&T[12]) = *((unsigned int *)&N[12]);
CNT[7] = D;
block_cipher(s,k,T,CNT,p_skinny_ctrl);
}
void generate_tag (unsigned char** c, unsigned char* s,
int n, unsigned long long* clen) {
g8A_for_Tag_Generation(s, *c);
*c = *c + n;
*c = *c - *clen;
}
unsigned long long msg_encryption (const unsigned char** M, unsigned char** c,
const unsigned char* N,
unsigned char* CNT,
unsigned char*s, const unsigned char* k,
unsigned char D,
unsigned long long mlen,
skinny_ctrl* p_skinny_ctrl) {
int len8;
if (mlen >= 16) {
len8 = 16;
mlen = mlen - 16;
rho_eqov16(*M, *c, s);
}
else {
len8 = mlen;
mlen = 0;
rho_ud16(*M, *c, s, len8, 16);
}
*c = *c + len8;
*M = *M + len8;
lfsr_gf56(CNT);
if (mlen != 0) {
nonce_encryption(N,CNT,s,k,D,p_skinny_ctrl);
}
return mlen;
}
unsigned long long msg_decryption (unsigned char** M, const unsigned char** c,
const unsigned char* N,
unsigned char* CNT,
unsigned char*s, const unsigned char* k,
unsigned char D,
unsigned long long clen,
skinny_ctrl* p_skinny_ctrl) {
int len8;
if (clen >= 16) {
len8 = 16;
clen = clen - 16;
}
else {
len8 = clen;
clen = 0;
}
irho(*M, *c, s, len8, 16);
*c = *c + len8;
*M = *M + len8;
lfsr_gf56(CNT);
nonce_encryption(N,CNT,s,k,D,p_skinny_ctrl);
return clen;
}
unsigned long long ad2msg_encryption (const unsigned char** M,
unsigned char* CNT,
unsigned char*s, const unsigned char* k,
unsigned char D,
unsigned long long mlen,
skinny_ctrl* p_skinny_ctrl) {
unsigned char T [16];
int len8;
if (mlen <= 16) {
len8 = mlen;
mlen = 0;
pad (*M,T,16,len8);
}
else {
len8 = 16;
mlen = mlen - 16;
unsigned char *pM = (unsigned char *)(*M);
*((unsigned int *)&T[0]) = *((unsigned int *)&pM[0]);
*((unsigned int *)&T[4]) = *((unsigned int *)&pM[4]);
*((unsigned int *)&T[8]) = *((unsigned int *)&pM[8]);
*((unsigned int *)&T[12]) = *((unsigned int *)&pM[12]);
}
CNT[7] = D;
block_cipher(s,k,T,CNT,p_skinny_ctrl);
lfsr_gf56(CNT);
*M = *M + len8;
return mlen;
}
unsigned long long ad_encryption (const unsigned char** A, unsigned char* s,
const unsigned char* k, unsigned long long adlen,
unsigned char* CNT,
unsigned char D,
skinny_ctrl* p_skinny_ctrl) {
unsigned char T [16];
int len8;
if (adlen >= 16) {
len8 = 16;
adlen = adlen - 16;
rho_ad_eqov16(*A, s);
}
else {
len8 = adlen;
adlen = 0;
rho_ad_ud16(*A, s, len8);
}
*A = *A + len8;
lfsr_gf56(CNT);
if (adlen != 0) {
if (adlen >= 16) {
len8 = 16;
adlen = adlen - 16;
unsigned char *pA = (unsigned char *)(*A);
*((unsigned int *)&T[0]) = *((unsigned int *)&pA[0]);
*((unsigned int *)&T[4]) = *((unsigned int *)&pA[4]);
*((unsigned int *)&T[8]) = *((unsigned int *)&pA[8]);
*((unsigned int *)&T[12]) = *((unsigned int *)&pA[12]);
}
else {
len8 = adlen;
adlen = 0;
pad(*A, T, 16, len8);
}
*A = *A + len8;
CNT[7] = D;
block_cipher(s,k,T,CNT,p_skinny_ctrl);
lfsr_gf56(CNT);
}
return adlen;
}
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 char s[16];
unsigned char CNT[8]; // size 7 -> 8 for word access
unsigned char T[16];
const unsigned char* N;
unsigned char w;
unsigned long long xlen;
skinny_ctrl l_skinny_ctrl;
l_skinny_ctrl.func_skinny_128_384_enc = skinny_128_384_enc123_12;
(void)nsec;
N = npub;
xlen = mlen;
*((unsigned int *)&s[0]) = 0x00000000;
*((unsigned int *)&s[4]) = 0x00000000;
*((unsigned int *)&s[8]) = 0x00000000;
*((unsigned int *)&s[12]) = 0x00000000;
reset_lfsr_gf56(CNT);
w = 48;
if (adlen == 0) {
w = w ^ 2;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
else if (adlen%(32) == 0) {
w = w ^ 8;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
else if (adlen%(32) < 16) {
w = w ^ 2;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
else if (adlen%(32) == 16) {
w = w ^ 0;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
else {
w = w ^ 10;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
if (adlen == 0) { // AD is an empty string
lfsr_gf56(CNT);
}
else while (adlen > 0) {
adlen = ad_encryption(&ad,s,k,adlen,CNT,40,&l_skinny_ctrl);
}
if ((w & 8) == 0) {
xlen = ad2msg_encryption (&m,CNT,s,k,44,xlen,&l_skinny_ctrl);
}
else if (mlen == 0) {
lfsr_gf56(CNT);
}
while (xlen > 0) {
xlen = ad_encryption(&m,s,k,xlen,CNT,44,&l_skinny_ctrl);
}
nonce_encryption(N,CNT,s,k,w,&l_skinny_ctrl);
// because, nonce_encryption is called at the last block of AD encryption
l_skinny_ctrl.func_skinny_128_384_enc = skinny_128_384_enc1_1;
// Tag generation
g8A(s, T);
m = m - mlen;
reset_lfsr_gf56(CNT);
*((unsigned int *)&s[0]) = *((unsigned int *)&T[0]);
*((unsigned int *)&s[4]) = *((unsigned int *)&T[4]);
*((unsigned int *)&s[8]) = *((unsigned int *)&T[8]);
*((unsigned int *)&s[12]) = *((unsigned int *)&T[12]);
*clen = mlen + 16;
if (mlen > 0) {
nonce_encryption(N,CNT,s,k,36,&l_skinny_ctrl);
while (mlen > 16) {
mlen = msg_encryption(&m,&c,N,CNT,s,k,36,mlen,&l_skinny_ctrl);
}
rho_ud16(m, c, s, mlen, 16);
c = c + mlen;
m = m + mlen;
}
// Tag Concatenation
// use byte access because of memory alignment.
// c is not always in word(4 byte) alignment.
for (int i = 0; i < 16; i = i + 1) {
*(c + i) = T[i];
}
c = c - *clen;
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 char s[16];
unsigned char CNT[8]; // size 7 -> 8 for word access
unsigned char T[16];
const unsigned char* N;
unsigned char w;
unsigned long long xlen;
const unsigned char* mauth;
skinny_ctrl l_skinny_ctrl;
l_skinny_ctrl.func_skinny_128_384_enc = skinny_128_384_enc123_12;
(void)nsec;
mauth = m;
N = npub;
xlen = clen-16;
reset_lfsr_gf56(CNT);
for (int i = 0; i < 16; i++) {
T[i] = *(c + clen - 16 + i);
}
*((unsigned int *)&s[0]) = *((unsigned int *)&T[0]);
*((unsigned int *)&s[4]) = *((unsigned int *)&T[4]);
*((unsigned int *)&s[8]) = *((unsigned int *)&T[8]);
*((unsigned int *)&s[12]) = *((unsigned int *)&T[12]);
clen = clen - 16;
*mlen = clen;
if (clen > 0) {
nonce_encryption(N,CNT,s,k,36,&l_skinny_ctrl);
while (clen > 16) {
clen = msg_decryption(&m,&c,N,CNT,s,k,36,clen,&l_skinny_ctrl);
}
irho(m, c, s, clen, 16);
c = c + clen;
m = m + clen;
}
*((unsigned int *)&s[0]) = 0x00000000;
*((unsigned int *)&s[4]) = 0x00000000;
*((unsigned int *)&s[8]) = 0x00000000;
*((unsigned int *)&s[12]) = 0x00000000;
reset_lfsr_gf56(CNT);
w = 48;
if (adlen == 0) {
w = w ^ 2;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
else if (adlen%(32) == 0) {
w = w ^ 8;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
else if (adlen%(32) < 16) {
w = w ^ 2;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
else if (adlen%(32) == 16) {
w = w ^ 0;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
else {
w = w ^ 10;
if (xlen == 0) {
w =w ^ 1;
}
else if (xlen%(32) == 0) {
w = w ^ 4;
}
else if (xlen%(32) < 16) {
w = w ^ 1;
}
else if (xlen%(32) == 16) {
w = w ^ 0;
}
else {
w = w ^ 5;
}
}
if (adlen == 0) { // AD is an empty string
lfsr_gf56(CNT);
}
else while (adlen > 0) {
adlen = ad_encryption(&ad,s,k,adlen,CNT,40,&l_skinny_ctrl);
}
if ((w & 8) == 0) {
xlen = ad2msg_encryption (&mauth,CNT,s,k,44,xlen,&l_skinny_ctrl);
}
else if (clen == 0) {
lfsr_gf56(CNT);
}
while (xlen > 0) {
xlen = ad_encryption(&mauth,s,k,xlen,CNT,44,&l_skinny_ctrl);
}
nonce_encryption(N,CNT,s,k,w,&l_skinny_ctrl);
// Tag generation
g8A_for_Tag_Generation(s, T);
for (int i = 0; i < 16; i++) {
if (T[i] != (*(c+i))) {
return -1;
}
}
return 0;
}
typedef struct ___skinny_ctrl {
unsigned char roundKeys[704]; // number of round : 40
void (*func_skinny_128_384_enc)(unsigned char*, struct ___skinny_ctrl*, unsigned char* CNT, unsigned char* T, const unsigned char* K);
} skinny_ctrl;
extern void skinny_128_384_enc123_12 (unsigned char* input, skinny_ctrl* pskinny_ctrl, unsigned char* CNT, unsigned char* T, const unsigned char* K);
extern void skinny_128_384_enc12_12 (unsigned char* input, skinny_ctrl* pskinny_ctrl, unsigned char* CNT, unsigned char* T, const unsigned char* K);
extern void skinny_128_384_enc1_1 (unsigned char* input, skinny_ctrl* pskinny_ctrl, unsigned char* CNT, unsigned char* T, const unsigned char* K);
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
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);
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);
/*
* Date: 29 November 2018
* Contact: Thomas Peyrin - thomas.peyrin@gmail.com
* Mustafa Khairallah - mustafam001@e.ntu.edu.sg
*/
#include "crypto_aead.h"
#include "api.h"
#include "skinny.h"
#include <stdio.h>
#include <stdlib.h>
void pad (const unsigned char* m, unsigned char* mp, int l, int len8) {
int i;
for (i = 0; i < l; i++) {
if (i < len8) {
mp[i] = m[i];
}
else if (i == l - 1) {
mp[i] = (len8 & 0x0f);
}
else {
mp[i] = 0x00;
}
}
}
void g8A (unsigned char* s, unsigned char* c) {
unsigned int tmps[4];
unsigned int tmpc[4];
tmps[0] = *((unsigned int *)&s[0]);
tmps[1] = *((unsigned int *)&s[4]);
tmps[2] = *((unsigned int *)&s[8]);
tmps[3] = *((unsigned int *)&s[12]);
// c[i] = (s[i] >> 1) ^ (s[i] & 0x80) ^ ((s[i] & 0x01) << 7);
//
// (s[i] >> 1) -> ((s[i]>>1)&0x7f)
// (s[i] & 0x80) -> (s[i])&0x80) not changed
// ((s[i] & 0x01) << 7) -> ((s[i]<<7)&0x80)
// use word access because of speeding up
tmpc[0] = ((tmps[0]>>1) & 0x7f7f7f7f) ^ (tmps[0] & 0x80808080) ^ ((tmps[0]<<7) & 0x80808080);
tmpc[1] = ((tmps[1]>>1) & 0x7f7f7f7f) ^ (tmps[1] & 0x80808080) ^ ((tmps[1]<<7) & 0x80808080);
tmpc[2] = ((tmps[2]>>1) & 0x7f7f7f7f) ^ (tmps[2] & 0x80808080) ^ ((tmps[2]<<7) & 0x80808080);
tmpc[3] = ((tmps[3]>>1) & 0x7f7f7f7f) ^ (tmps[3] & 0x80808080) ^ ((tmps[3]<<7) & 0x80808080);
*((unsigned int *)&c[0]) = tmpc[0];
*((unsigned int *)&c[4]) = tmpc[1];
*((unsigned int *)&c[8]) = tmpc[2];
*((unsigned int *)&c[12]) = tmpc[3];
}
void g8A_for_Tag_Generation (unsigned char* s, unsigned char* c) {
unsigned int tmps[4];
unsigned int tmpc[4];
tmps[0] = *((unsigned int *)&s[0]);
tmps[1] = *((unsigned int *)&s[4]);
tmps[2] = *((unsigned int *)&s[8]);
tmps[3] = *((unsigned int *)&s[12]);
// c[i] = (s[i] >> 1) ^ (s[i] & 0x80) ^ ((s[i] & 0x01) << 7);
//
// (s[i] >> 1) -> ((s[i]>>1)&0x7f)
// (s[i] & 0x80) -> (s[i])&0x80) not changed
// ((s[i] & 0x01) << 7) -> ((s[i]<<7)&0x80)
// use word access because of speeding up
tmpc[0] = ((tmps[0]>>1) & 0x7f7f7f7f) ^ (tmps[0] & 0x80808080) ^ ((tmps[0]<<7) & 0x80808080);
tmpc[1] = ((tmps[1]>>1) & 0x7f7f7f7f) ^ (tmps[1] & 0x80808080) ^ ((tmps[1]<<7) & 0x80808080);
tmpc[2] = ((tmps[2]>>1) & 0x7f7f7f7f) ^ (tmps[2] & 0x80808080) ^ ((tmps[2]<<7) & 0x80808080);
tmpc[3] = ((tmps[3]>>1) & 0x7f7f7f7f) ^ (tmps[3] & 0x80808080) ^ ((tmps[3]<<7) & 0x80808080);
// use byte access because of memory alignment.
// c is not always in word(4 byte) alignment.
c[0] = tmpc[0] &0xFF;
c[1] = (tmpc[0]>>8) &0xFF;
c[2] = (tmpc[0]>>16)&0xFF;
c[3] = (tmpc[0]>>24)&0xFF;
c[4] = tmpc[1] &0xFF;
c[5] = (tmpc[1]>>8) &0xFF;
c[6] = (tmpc[1]>>16)&0xFF;
c[7] = (tmpc[1]>>24)&0xFF;
c[8] = tmpc[2] &0xFF;
c[9] = (tmpc[2]>>8) &0xFF;
c[10] = (tmpc[2]>>16)&0xFF;
c[11] = (tmpc[2]>>24)&0xFF;
c[12] = tmpc[3] &0xFF;
c[13] = (tmpc[3]>>8) &0xFF;
c[14] = (tmpc[3]>>16)&0xFF;
c[15] = (tmpc[3]>>24)&0xFF;
}
void rho_ad_eqov16 (const unsigned char* m,
unsigned char* s) {
*((unsigned int *)&s[0]) ^= *((unsigned int *)&m[0]);
*((unsigned int *)&s[4]) ^= *((unsigned int *)&m[4]);
*((unsigned int *)&s[8]) ^= *((unsigned int *)&m[8]);
*((unsigned int *)&s[12]) ^= *((unsigned int *)&m[12]);
}
void rho_ad_ud16 (const unsigned char* m,
unsigned char* s,
int len8) {
unsigned char mp [16];
pad(m,mp,16,len8);
*((unsigned int *)&s[0]) ^= *((unsigned int *)&mp[0]);
*((unsigned int *)&s[4]) ^= *((unsigned int *)&mp[4]);
*((unsigned int *)&s[8]) ^= *((unsigned int *)&mp[8]);
*((unsigned int *)&s[12]) ^= *((unsigned int *)&mp[12]);
}
void rho_eqov16 (const unsigned char* m,
unsigned char* c,
unsigned char* s) {
g8A(s,c);
*((unsigned int *)&s[0]) ^= *((unsigned int *)&m[0]);
*((unsigned int *)&s[4]) ^= *((unsigned int *)&m[4]);
*((unsigned int *)&s[8]) ^= *((unsigned int *)&m[8]);
*((unsigned int *)&s[12]) ^= *((unsigned int *)&m[12]);
*((unsigned int *)&c[0]) ^= *((unsigned int *)&m[0]);
*((unsigned int *)&c[4]) ^= *((unsigned int *)&m[4]);
*((unsigned int *)&c[8]) ^= *((unsigned int *)&m[8]);
*((unsigned int *)&c[12]) ^= *((unsigned int *)&m[12]);
}
void rho_ud16 (const unsigned char* m,
unsigned char* c,
unsigned char* s,
int len8,
int ver) {
int i;
unsigned char mp [16];
pad(m,mp,ver,len8);
g8A(s,c);
*((unsigned int *)&s[0]) ^= *((unsigned int *)&mp[0]);
*((unsigned int *)&s[4]) ^= *((unsigned int *)&mp[4]);
*((unsigned int *)&s[8]) ^= *((unsigned int *)&mp[8]);
*((unsigned int *)&s[12]) ^= *((unsigned int *)&mp[12]);
for (i = 0; i < ver; i++) {
if (i < len8) {
c[i] = c[i] ^ mp[i];
}
else {
c[i] = 0;
}
}
}
void irho (unsigned char* m,
const unsigned char* c,
unsigned char* s,
int len8,
int ver) {
int i;
unsigned char cp [16];
pad(c,cp,ver,len8);
g8A(s,m);
for (i = 0; i < ver; i++) {
if (i < len8) {
s[i] = s[i] ^ cp[i] ^ m[i];
}
else {
s[i] = s[i] ^ cp[i];
}
if (i < len8) {
m[i] = m[i] ^ cp[i];
}
else {
m[i] = 0;
}
}
}
void reset_lfsr_gf56 (unsigned char* CNT) {
*((unsigned int *)&CNT[0]) = 0x00000001;
*((unsigned int *)&CNT[4]) = 0x00000000;
}
void lfsr_gf56 (unsigned char* CNT) {
unsigned int tmpCNT[2];
unsigned int fb0;
tmpCNT[0] = *((unsigned int *)&CNT[0]); // CNT3 CNT2 CNT1 CNT0
tmpCNT[1] = *((unsigned int *)&CNT[4]); // CNT7 CNT6 CNT5 CNT4
fb0 = 0;
if ((tmpCNT[1] >> 23)&0x01) {
fb0 = 0x95;
}
tmpCNT[1] = tmpCNT[1] << 1 | tmpCNT[0] >> 31;
tmpCNT[0] = tmpCNT[0] << 1 ^ fb0;
*((unsigned int *)&CNT[0]) = tmpCNT[0];
*((unsigned int *)&CNT[4]) = tmpCNT[1];
}
void block_cipher(unsigned char* s,
const unsigned char* k, unsigned char* T,
unsigned char* CNT,
skinny_ctrl* p_skinny_ctrl) {
p_skinny_ctrl->func_skinny_128_384_enc (s,p_skinny_ctrl,CNT,T,k);
}
void nonce_encryption (const unsigned char* N,
unsigned char* CNT,
unsigned char*s, const unsigned char* k,
unsigned char D,
skinny_ctrl* p_skinny_ctrl) {
unsigned char T [16];
*((unsigned int *)&T[0]) = *((unsigned int *)&N[0]);
*((unsigned int *)&T[4]) = *((unsigned int *)&N[4]);
*((unsigned int *)&T[8]) = *((unsigned int *)&N[8]);
*((unsigned int *)&T[12]) = *((unsigned int *)&N[12]);
CNT[7] = D;
block_cipher(s,k,T,CNT,p_skinny_ctrl);
}
void generate_tag (unsigned char** c, unsigned char* s,
int n, unsigned long long* clen) {
g8A_for_Tag_Generation(s, *c);
*c = *c + n;
*c = *c - *clen;
}
unsigned long long msg_encryption_eqov16 (const unsigned char** M, unsigned char** c,
const unsigned char* N,
unsigned char* CNT,
unsigned char*s, const unsigned char* k,
unsigned char D,
unsigned long long mlen,
skinny_ctrl* p_skinny_ctrl) {
rho_eqov16(*M, *c, s);
*c = *c + 16;
*M = *M + 16;
lfsr_gf56(CNT);
nonce_encryption(N,CNT,s,k,D,p_skinny_ctrl);
return mlen - 16;
}
unsigned long long msg_encryption_ud16 (const unsigned char** M, unsigned char** c,
const unsigned char* N,
unsigned char* CNT,
unsigned char*s, const unsigned char* k,
unsigned char D,
unsigned long long mlen,
skinny_ctrl* p_skinny_ctrl) {
rho_ud16(*M, *c, s, mlen, 16);
*c = *c + mlen;
*M = *M + mlen;
lfsr_gf56(CNT);
nonce_encryption(N,CNT,s,k,D,p_skinny_ctrl);
return 0;
}
unsigned long long msg_decryption (unsigned char** M, const unsigned char** c,
const unsigned char* N,
unsigned char* CNT,
unsigned char*s, const unsigned char* k,
unsigned char D,
unsigned long long clen,
skinny_ctrl* p_skinny_ctrl) {
int len8;
if (clen >= 16) {
len8 = 16;
clen = clen - 16;
}
else {
len8 = clen;
clen = 0;
}
irho(*M, *c, s, len8, 16);
*c = *c + len8;
*M = *M + len8;
lfsr_gf56(CNT);
nonce_encryption(N,CNT,s,k,D,p_skinny_ctrl);
return clen;
}
unsigned long long ad_encryption_eqov32 (const unsigned char** A, unsigned char* s,
const unsigned char* k, unsigned long long adlen,
unsigned char* CNT,
unsigned char D,
skinny_ctrl* p_skinny_ctrl) {
unsigned char T [16];
rho_ad_eqov16(*A, s);
*A = *A + 16;
lfsr_gf56(CNT);
//pad(*A, T, 16, 16);
*((unsigned int *)&T[0]) = *((unsigned int *)&(*A)[0]);
*((unsigned int *)&T[4]) = *((unsigned int *)&(*A)[4]);
*((unsigned int *)&T[8]) = *((unsigned int *)&(*A)[8]);
*((unsigned int *)&T[12]) = *((unsigned int *)&(*A)[12]);
*A = *A + 16;
CNT[7] = D;
block_cipher(s,k,T,CNT,p_skinny_ctrl);
lfsr_gf56(CNT);
return adlen - 32;
}
unsigned long long ad_encryption_ov16 (const unsigned char** A, unsigned char* s,
const unsigned char* k, unsigned long long adlen,
unsigned char* CNT,
unsigned char D,
skinny_ctrl* p_skinny_ctrl) {
unsigned char T [16];
adlen = adlen - 16;
rho_ad_eqov16(*A, s);
*A = *A + 16;
lfsr_gf56(CNT);
pad(*A, T, 16, adlen);
*A = *A + adlen;
CNT[7] = D;
block_cipher(s,k,T,CNT,p_skinny_ctrl);
lfsr_gf56(CNT);
return 0;
}
unsigned long long ad_encryption_eq16 (const unsigned char** A, unsigned char* s,
unsigned char* CNT) {
rho_ad_eqov16(*A, s);
*A = *A + 16;
lfsr_gf56(CNT);
return 0;
}
unsigned long long ad_encryption_ud16 (const unsigned char** A, unsigned char* s,
unsigned long long adlen,
unsigned char* CNT) {
rho_ad_ud16(*A, s, adlen);
*A = *A + adlen;
lfsr_gf56(CNT);
return 0;
}
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 char s[16];
// size 7 -> 8 for word access
unsigned char CNT[8];
const unsigned char* A;
const unsigned char* M;
const unsigned char* N;
skinny_ctrl l_skinny_ctrl;
(void) nsec;
A = ad;
M = m;
N = npub;
l_skinny_ctrl.func_skinny_128_384_enc = skinny_128_384_enc123_12;
*((unsigned int *)&s[0]) = 0x00000000;
*((unsigned int *)&s[4]) = 0x00000000;
*((unsigned int *)&s[8]) = 0x00000000;
*((unsigned int *)&s[12]) = 0x00000000;
reset_lfsr_gf56(CNT);
if (adlen == 0) { // AD is an empty string
lfsr_gf56(CNT);
nonce_encryption(N,CNT,s,k,0x1a,&l_skinny_ctrl);
}
else while (adlen > 0) {
if (adlen < 16) { // The last block of AD is odd and incomplete
adlen = ad_encryption_ud16(&A,s,adlen,CNT);
nonce_encryption(N,CNT,s,k,0x1a,&l_skinny_ctrl);
}
else if (adlen == 16) { // The last block of AD is odd and complete
adlen = ad_encryption_eq16(&A,s,CNT);
nonce_encryption(N,CNT,s,k,0x18,&l_skinny_ctrl);
}
else if (adlen < (32)) { // The last block of AD is even and incomplete
adlen = ad_encryption_ov16(&A,s,k,adlen,CNT,0x08,&l_skinny_ctrl);
nonce_encryption(N,CNT,s,k,0x1a,&l_skinny_ctrl);
}
else if (adlen == (32)) { // The last block of AD is even and complete
adlen = ad_encryption_eqov32(&A,s,k,adlen,CNT,0x08,&l_skinny_ctrl);
nonce_encryption(N,CNT,s,k,0x18,&l_skinny_ctrl);
}
else { // A normal full pair of blocks of AD
adlen = ad_encryption_eqov32(&A,s,k,adlen,CNT,0x08,&l_skinny_ctrl);
}
}
// because, nonce_encryption is called at the last block of AD encryption
l_skinny_ctrl.func_skinny_128_384_enc = skinny_128_384_enc1_1;
reset_lfsr_gf56(CNT);
*clen = mlen + 16;
if (mlen == 0) { // M is an empty string
lfsr_gf56(CNT);
nonce_encryption(N,CNT,s,k,0x15,&l_skinny_ctrl);
}
else while (mlen > 0) {
if (mlen < 16) { // The last block of M is incomplete
mlen = msg_encryption_ud16(&M,&c,N,CNT,s,k,0x15,mlen,&l_skinny_ctrl);
}
else if (mlen == 16) { // The last block of M is complete
mlen = msg_encryption_eqov16(&M,&c,N,CNT,s,k,0x14,mlen,&l_skinny_ctrl);
}
else { // A normal full message block
mlen = msg_encryption_eqov16(&M,&c,N,CNT,s,k,0x04,mlen,&l_skinny_ctrl);
}
}
// Tag generation
generate_tag(&c,s,16,clen);
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 char s[16];
unsigned char T[16];
// size 7 -> 8 for word access
unsigned char CNT[8];
const unsigned char* A;
unsigned char* M;
const unsigned char* N;
unsigned int i;
skinny_ctrl l_skinny_ctrl;
(void) nsec;
A = ad;
M = m;
N = npub;
l_skinny_ctrl.func_skinny_128_384_enc = skinny_128_384_enc123_12;
for (i = 0; i < 16; i++) {
s[i] = 0;
}
reset_lfsr_gf56(CNT);
if (adlen == 0) { // AD is an empty string
lfsr_gf56(CNT);
nonce_encryption(N,CNT,s,k,0x1a,&l_skinny_ctrl);
}
else while (adlen > 0) {
if (adlen < 16) { // The last block of AD is odd and incomplete
adlen = ad_encryption_ud16(&A,s,adlen,CNT);
nonce_encryption(N,CNT,s,k,0x1a,&l_skinny_ctrl);
}
else if (adlen == 16) { // The last block of AD is odd and complete
adlen = ad_encryption_eq16(&A,s,CNT);
nonce_encryption(N,CNT,s,k,0x18,&l_skinny_ctrl);
}
else if (adlen < (32)) { // The last block of AD is even and incomplete
adlen = ad_encryption_ov16(&A,s,k,adlen,CNT,0x08,&l_skinny_ctrl);
nonce_encryption(N,CNT,s,k,0x1a,&l_skinny_ctrl);
}
else if (adlen == (32)) { // The last block of AD is even and complete
adlen = ad_encryption_eqov32(&A,s,k,adlen,CNT,0x08,&l_skinny_ctrl);
nonce_encryption(N,CNT,s,k,0x18,&l_skinny_ctrl);
}
else { // A normal full pair of blocks of AD
adlen = ad_encryption_eqov32(&A,s,k,adlen,CNT,0x08,&l_skinny_ctrl);
}
}
l_skinny_ctrl.func_skinny_128_384_enc = skinny_128_384_enc1_1;
reset_lfsr_gf56(CNT);
clen = clen - 16;
*mlen = clen;
if (clen == 0) { // C is an empty string
lfsr_gf56(CNT);
nonce_encryption(N,CNT,s,k,0x15,&l_skinny_ctrl);
}
else while (clen > 0) {
if (clen < 16) { // The last block of C is incomplete
clen = msg_decryption(&M,&c,N,CNT,s,k,0x15,clen,&l_skinny_ctrl);
}
else if (clen == 16) { // The last block of C is complete
clen = msg_decryption(&M,&c,N,CNT,s,k,0x14,clen,&l_skinny_ctrl);
}
else { // A normal full message block
clen = msg_decryption(&M,&c,N,CNT,s,k,0x04,clen,&l_skinny_ctrl);
}
}
// Tag generation
g8A_for_Tag_Generation(s, T);
for (i = 0; i < 16; i++) {
if (T[i] != (*(c+i))) {
return -1;
}
}
return 0;
}
typedef struct ___skinny_ctrl {
unsigned char roundKeys[704]; // number of round : 40
void (*func_skinny_128_384_enc)(unsigned char*, struct ___skinny_ctrl*, unsigned char* CNT, unsigned char* T, const unsigned char* K);
} skinny_ctrl;
extern void skinny_128_384_enc123_12 (unsigned char* input, skinny_ctrl* pskinny_ctrl, unsigned char* CNT, unsigned char* T, const unsigned char* K);
extern void skinny_128_384_enc12_12 (unsigned char* input, skinny_ctrl* pskinny_ctrl, unsigned char* CNT, unsigned char* T, const unsigned char* K);
extern void skinny_128_384_enc1_1 (unsigned char* input, skinny_ctrl* pskinny_ctrl, unsigned char* CNT, unsigned char* T, const unsigned char* K);
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -505,6 +505,7 @@ const unsigned char *k
}
}
l_skinny_ctrl.func_skinny_128_384_enc = skinny_128_384_enc1_1;
reset_lfsr_gf56(CNT);
clen = clen - 16;
......
......@@ -35,11 +35,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 1
// AC(c0 c1)
"eor.w r6, r2, #0x1 \n\t" // k0^rc
"ldrb.w r6, [r1,#0] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#512] \n\t"
"str.w r3, [r0,#516] \n\t"
"str.w r7, [r0,#516] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -86,11 +90,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 2
// AC(c0 c1)
"eor.w r6, r2, #0x3 \n\t" // k0^rc
"ldrb.w r6, [r1,#1] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#520] \n\t"
"str.w r3, [r0,#524] \n\t"
"str.w r7, [r0,#524] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -137,11 +145,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 3
// AC(c0 c1)
"eor.w r6, r2, #0x7 \n\t" // k0^rc
"ldrb.w r6, [r1,#2] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#528] \n\t"
"str.w r3, [r0,#532] \n\t"
"str.w r7, [r0,#532] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -188,11 +200,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 4
// AC(c0 c1)
"eor.w r6, r2, #0xf \n\t" // k0^rc
"ldrb.w r6, [r1,#3] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#536] \n\t"
"str.w r3, [r0,#540] \n\t"
"str.w r7, [r0,#540] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -239,8 +255,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 5
// AC(c0 c1)
"eor.w r6, r2, #0xf \n\t" // k0^rc
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"ldrb.w r6, [r1,#4] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#544] \n\t"
......@@ -291,8 +310,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 6
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0xe \n\t" // k0^rc
"ldrb.w r6, [r1,#5] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#552] \n\t"
......@@ -343,9 +365,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 7
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0xd \n\t" // k0^rc
"ldrb.w r6, [r1,#6] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#560] \n\t"
......@@ -396,8 +420,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 8
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0xb \n\t" // k0^rc
"ldrb.w r6, [r1,#7] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#568] \n\t"
......@@ -448,8 +475,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 9
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x7 \n\t" // k0^rc
"ldrb.w r6, [r1,#8] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#576] \n\t"
......@@ -500,8 +530,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 10
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0xf \n\t" // k0^rc
"ldrb.w r6, [r1,#9] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#584] \n\t"
......@@ -552,8 +585,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 11
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0xe \n\t" // k0^rc
"ldrb.w r6, [r1,#10] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#592] \n\t"
......@@ -604,8 +640,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 12
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0xc \n\t" // k0^rc
"ldrb.w r6, [r1,#11] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#600] \n\t"
......@@ -656,8 +695,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 13
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x9 \n\t" // k0^rc
"ldrb.w r6, [r1,#12] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#608] \n\t"
......@@ -708,8 +750,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 14
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x3 \n\t" // k0^rc
"ldrb.w r6, [r1,#13] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#616] \n\t"
......@@ -760,8 +805,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 15
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0x7 \n\t" // k0^rc
"ldrb.w r6, [r1,#14] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#624] \n\t"
......@@ -812,11 +860,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 16
// AC(c0 c1)
"eor.w r6, r2, #0xe \n\t" // k0^rc
"ldrb.w r6, [r1,#15] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#632] \n\t"
"str.w r3, [r0,#636] \n\t"
"str.w r7, [r0,#636] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -863,8 +915,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 17
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0xd \n\t" // k0^rc
"ldrb.w r6, [r1,#16] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#640] \n\t"
......@@ -915,8 +970,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 18
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0xa \n\t" // k0^rc
"ldrb.w r6, [r1,#17] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#648] \n\t"
......@@ -967,8 +1025,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 19
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x5 \n\t" // k0^rc
"ldrb.w r6, [r1,#18] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#656] \n\t"
......@@ -1019,8 +1080,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 20
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0xb \n\t" // k0^rc
"ldrb.w r6, [r1,#19] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#664] \n\t"
......@@ -1071,8 +1135,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 21
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0x6 \n\t" // k0^rc
"ldrb.w r6, [r1,#20] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#672] \n\t"
......@@ -1123,8 +1190,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 22
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0xc \n\t" // k0^rc
"ldrb.w r6, [r1,#21] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#680] \n\t"
......@@ -1175,8 +1245,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 23
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0x8 \n\t" // k0^rc
"ldrb.w r6, [r1,#22] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#688] \n\t"
......@@ -1227,8 +1300,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 24
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x0 \n\t" // k0^rc
"ldrb.w r6, [r1,#23] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#696] \n\t"
......@@ -1279,8 +1355,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 25
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0x1 \n\t" // k0^rc
"ldrb.w r6, [r1,#24] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#704] \n\t"
......@@ -1331,11 +1410,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 26
// AC(c0 c1)
"eor.w r6, r2, #0x2 \n\t" // k0^rc
"ldrb.w r6, [r1,#25] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#712] \n\t"
"str.w r3, [r0,#716] \n\t"
"str.w r7, [r0,#716] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -1382,11 +1465,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 27
// AC(c0 c1)
"eor.w r6, r2, #0x5 \n\t" // k0^rc
"ldrb.w r6, [r1,#26] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#720] \n\t"
"str.w r3, [r0,#724] \n\t"
"str.w r7, [r0,#724] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -1433,11 +1520,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 28
// AC(c0 c1)
"eor.w r6, r2, #0xb \n\t" // k0^rc
"ldrb.w r6, [r1,#27] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#728] \n\t"
"str.w r3, [r0,#732] \n\t"
"str.w r7, [r0,#732] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -1484,8 +1575,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 29
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0x7 \n\t" // k0^rc
"ldrb.w r6, [r1,#28] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#736] \n\t"
......@@ -1536,8 +1630,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 30
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0xe \n\t" // k0^rc
"ldrb.w r6, [r1,#29] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#744] \n\t"
......@@ -1588,8 +1685,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 31
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0xc \n\t" // k0^rc
"ldrb.w r6, [r1,#30] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#752] \n\t"
......@@ -1640,8 +1740,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 32
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x8 \n\t" // k0^rc
"ldrb.w r6, [r1,#31] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#760] \n\t"
......@@ -1692,8 +1795,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 33
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x1 \n\t" // k0^rc
"ldrb.w r6, [r1,#32] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#768] \n\t"
......@@ -1744,8 +1850,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 34
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0x3 \n\t" // k0^rc
"ldrb.w r6, [r1,#33] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#776] \n\t"
......@@ -1796,11 +1905,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 35
// AC(c0 c1)
"eor.w r6, r2, #0x6 \n\t" // k0^rc
"ldrb.w r6, [r1,#34] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#784] \n\t"
"str.w r3, [r0,#788] \n\t"
"str.w r7, [r0,#788] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -1847,11 +1960,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 36
// AC(c0 c1)
"eor.w r6, r2, #0xd \n\t" // k0^rc
"ldrb.w r6, [r1,#35] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#792] \n\t"
"str.w r3, [r0,#796] \n\t"
"str.w r7, [r0,#796] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -1898,8 +2015,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 37
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0xb \n\t" // k0^rc
"ldrb.w r6, [r1,#36] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#800] \n\t"
......@@ -1950,8 +2070,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 38
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x6 \n\t" // k0^rc
"ldrb.w r6, [r1,#37] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#808] \n\t"
......@@ -2002,8 +2125,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 39
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0xd \n\t" // k0^rc
"ldrb.w r6, [r1,#38] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#816] \n\t"
......@@ -2054,8 +2180,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 40
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0xa \n\t" // k0^rc
"ldrb.w r6, [r1,#39] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#824] \n\t"
......@@ -2106,8 +2235,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 41
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x4 \n\t" // k0^rc
"ldrb.w r6, [r1,#40] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#832] \n\t"
......@@ -2158,8 +2290,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 42
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0x9 \n\t" // k0^rc
"ldrb.w r6, [r1,#41] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#840] \n\t"
......@@ -2210,8 +2345,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 43
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0x2 \n\t" // k0^rc
"ldrb.w r6, [r1,#42] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#848] \n\t"
......@@ -2262,8 +2400,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 44
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0x4 \n\t" // k0^rc
"ldrb.w r6, [r1,#43] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#856] \n\t"
......@@ -2314,11 +2455,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 45
// AC(c0 c1)
"eor.w r6, r2, #0x8 \n\t" // k0^rc
"ldrb.w r6, [r1,#44] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#864] \n\t"
"str.w r3, [r0,#868] \n\t"
"str.w r7, [r0,#868] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -2365,8 +2510,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 46
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0x1 \n\t" // k0^rc
"ldrb.w r6, [r1,#45] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#872] \n\t"
......@@ -2417,8 +2565,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 47
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0x2 \n\t" // k0^rc
"ldrb.w r6, [r1,#46] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#880] \n\t"
......@@ -2469,11 +2620,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 48
// AC(c0 c1)
"eor.w r6, r2, #0x4 \n\t" // k0^rc
"ldrb.w r6, [r1,#47] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#888] \n\t"
"str.w r3, [r0,#892] \n\t"
"str.w r7, [r0,#892] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -2520,11 +2675,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 49
// AC(c0 c1)
"eor.w r6, r2, #0x9 \n\t" // k0^rc
"ldrb.w r6, [r1,#48] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#896] \n\t"
"str.w r3, [r0,#900] \n\t"
"str.w r7, [r0,#900] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -2571,8 +2730,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 50
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0x3 \n\t" // k0^rc
"ldrb.w r6, [r1,#49] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#904] \n\t"
......@@ -2623,8 +2785,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 51
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0x6 \n\t" // k0^rc
"ldrb.w r6, [r1,#50] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#912] \n\t"
......@@ -2675,11 +2840,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 52
// AC(c0 c1)
"eor.w r6, r2, #0xc \n\t" // k0^rc
"ldrb.w r6, [r1,#51] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#920] \n\t"
"str.w r3, [r0,#924] \n\t"
"str.w r7, [r0,#924] \n\t"
// permutation
// r2 (k3 k2 k1 k0) k13 k8 k15 k9
......@@ -2726,8 +2895,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 53
// AC(c0 c1)
"eor.w r7, r3, #0x1 \n\t" // k0^rc
"eor.w r6, r2, #0x9 \n\t" // k0^rc
"ldrb.w r6, [r1,#52] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#928] \n\t"
......@@ -2778,8 +2950,11 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 54
// AC(c0 c1)
"eor.w r7, r3, #0x3 \n\t" // k0^rc
"eor.w r6, r2, #0x2 \n\t" // k0^rc
"ldrb.w r6, [r1,#53] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#936] \n\t"
......@@ -2830,8 +3005,12 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 55
// AC(c0 c1)
"eor.w r7, r3, #0x2 \n\t" // k0^rc
"eor.w r6, r2, #0x5 \n\t" // k0^rc
"ldrb.w r6, [r1,#54] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#944] \n\t"
"str.w r7, [r0,#948] \n\t"
......@@ -2881,11 +3060,15 @@ void RunEncryptionKeyScheduleTK3(unsigned char *roundKeys, unsigned char *pRC)
// round 56
// AC(c0 c1)
"eor.w r6, r2, #0xa \n\t" // k0^rc
"ldrb.w r6, [r1,#55] \n\t" // load RC
"eor.w r7, r3, r6, lsr #4 \n\t" // k4^rc
"and.w r6, r6, #0xf \n\t"
"eor.w r6, r6, r2 \n\t" // k0^rc
// round key store
"str.w r6, [r0,#952] \n\t"
"str.w r3, [r0,#956] \n\t"
"str.w r7, [r0,#956] \n\t"
// permutation
......
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