Mercurial > libavutil.hg
comparison aes.c @ 212:d31d4880105e libavutil
use 2 state arrays so that fewer temporary variables are needed
author | michael |
---|---|
date | Tue, 16 Jan 2007 17:17:05 +0000 |
parents | 3ef3f2ad70a4 |
children | e50daf73d26c |
comparison
equal
deleted
inserted
replaced
211:3ef3f2ad70a4 | 212:d31d4880105e |
---|---|
23 #include "common.h" | 23 #include "common.h" |
24 #include "aes.h" | 24 #include "aes.h" |
25 | 25 |
26 typedef struct AVAES{ | 26 typedef struct AVAES{ |
27 uint8_t round_key[15][4][4]; | 27 uint8_t round_key[15][4][4]; |
28 uint8_t state[4][4]; | 28 uint8_t state[2][4][4]; |
29 int rounds; | 29 int rounds; |
30 }AVAES; | 30 }AVAES; |
31 | 31 |
32 const int av_aes_size= sizeof(AVAES); | 32 const int av_aes_size= sizeof(AVAES); |
33 | 33 |
44 static uint32_t enc_multbl[4][256]; | 44 static uint32_t enc_multbl[4][256]; |
45 static uint32_t dec_multbl[4][256]; | 45 static uint32_t dec_multbl[4][256]; |
46 #endif | 46 #endif |
47 | 47 |
48 static inline void addkey(uint64_t state[2], uint64_t round_key[2]){ | 48 static inline void addkey(uint64_t state[2], uint64_t round_key[2]){ |
49 state[0] ^= round_key[0]; | 49 state[2] = state[0] ^ round_key[0]; |
50 state[1] ^= round_key[1]; | 50 state[3] = state[1] ^ round_key[1]; |
51 } | 51 } |
52 | 52 |
53 static void subshift(uint8_t s0[4], uint8_t s1[4], uint8_t s3[4], uint8_t *box){ | 53 static void subshift(uint8_t s0[2][16], uint8_t s1[2][16], uint8_t s3[2][16], uint8_t *box){ |
54 int t; | 54 s0[0][0]=box[s0[1][ 0]]; s0[0][ 4]=box[s0[1][ 4]]; s0[0][ 8]=box[s0[1][ 8]]; s0[0][12]=box[s0[1][12]]; |
55 s0[0]=box[s0[ 0]]; s0[ 4]=box[s0[ 4]]; s0[ 8]=box[s0[ 8]]; s0[12]=box[s0[12]]; | 55 s1[0][0]=box[s1[1][ 4]]; s1[0][ 4]=box[s1[1][ 8]]; s1[0][ 8]=box[s1[1][12]]; s1[0][12]=box[s1[1][ 0]]; |
56 t=s1[0]; s1[0]=box[s1[ 4]]; s1[ 4]=box[s1[ 8]]; s1[ 8]=box[s1[12]]; s1[12]=box[t]; | 56 s0[0][2]=box[s0[1][10]]; s0[0][10]=box[s0[1][ 2]]; s0[0][ 6]=box[s0[1][14]]; s0[0][14]=box[s0[1][ 6]]; |
57 t=s0[2]; s0[2]=box[s0[10]]; s0[10]=box[ t]; t=s0[ 6]; s0[ 6]=box[s0[14]]; s0[14]=box[t]; | 57 s3[0][0]=box[s3[1][12]]; s3[0][12]=box[s3[1][ 8]]; s3[0][ 8]=box[s3[1][ 4]]; s3[0][ 4]=box[s3[1][ 0]]; |
58 t=s3[0]; s3[0]=box[s3[12]]; s3[12]=box[s3[ 8]]; s3[ 8]=box[s3[ 4]]; s3[ 4]=box[t]; | |
59 } | 58 } |
60 | 59 |
61 #define ROT(x,s) ((x<<s)|(x>>(32-s))) | 60 #define ROT(x,s) ((x<<s)|(x>>(32-s))) |
62 #if 0 | 61 #if 0 |
63 static inline void mix(uint8_t state[4][4], uint32_t multbl[4][256]){ | 62 static inline void mix(uint8_t state[4][4], uint32_t multbl[4][256]){ |
70 ((uint32_t *)(state))[i] = multbl[0][state[i][0]] ^ multbl[1][state[i][1]] | 69 ((uint32_t *)(state))[i] = multbl[0][state[i][0]] ^ multbl[1][state[i][1]] |
71 ^multbl[2][state[i][2]] ^ multbl[3][state[i][3]]; | 70 ^multbl[2][state[i][2]] ^ multbl[3][state[i][3]]; |
72 #endif | 71 #endif |
73 } | 72 } |
74 #endif | 73 #endif |
75 static inline void mix2(uint8_t state[4][4], uint32_t multbl[4][256], int s1, int s3){ | 74 |
76 int a = multbl[0][state[0][0]] ^ multbl[1][state[s1 ][1]] | 75 static inline void mix(uint8_t state[2][4][4], uint32_t multbl[4][256], int s1, int s3){ |
77 ^multbl[2][state[2][2]] ^ multbl[3][state[s3 ][3]]; | 76 ((uint32_t *)(state))[0] = multbl[0][state[1][0][0]] ^ multbl[1][state[1][s1 ][1]] |
78 int b = multbl[0][state[1][0]] ^ multbl[1][state[s3-1][1]] | 77 ^multbl[2][state[1][2][2]] ^ multbl[3][state[1][s3 ][3]]; |
79 ^multbl[2][state[3][2]] ^ multbl[3][state[s1-1][3]]; | 78 ((uint32_t *)(state))[1] = multbl[0][state[1][1][0]] ^ multbl[1][state[1][s3-1][1]] |
80 int c = multbl[0][state[2][0]] ^ multbl[1][state[s3 ][1]] | 79 ^multbl[2][state[1][3][2]] ^ multbl[3][state[1][s1-1][3]]; |
81 ^multbl[2][state[0][2]] ^ multbl[3][state[s1 ][3]]; | 80 ((uint32_t *)(state))[2] = multbl[0][state[1][2][0]] ^ multbl[1][state[1][s3 ][1]] |
82 int d = multbl[0][state[3][0]] ^ multbl[1][state[s1-1][1]] | 81 ^multbl[2][state[1][0][2]] ^ multbl[3][state[1][s1 ][3]]; |
83 ^multbl[2][state[1][2]] ^ multbl[3][state[s3-1][3]]; | 82 ((uint32_t *)(state))[3] = multbl[0][state[1][3][0]] ^ multbl[1][state[1][s1-1][1]] |
84 | 83 ^multbl[2][state[1][1][2]] ^ multbl[3][state[1][s3-1][3]]; |
85 ((uint32_t *)(state))[0]=a; | |
86 ((uint32_t *)(state))[1]=b; | |
87 ((uint32_t *)(state))[2]=c; | |
88 ((uint32_t *)(state))[3]=d; | |
89 } | 84 } |
90 | 85 |
91 static inline void crypt(AVAES *a, int s, uint8_t *sbox, uint32_t *multbl){ | 86 static inline void crypt(AVAES *a, int s, uint8_t *sbox, uint32_t *multbl){ |
92 int r; | 87 int r; |
93 | 88 |
94 for(r=a->rounds; r>1; r--){ | 89 for(r=a->rounds; r>1; r--){ |
95 addkey(a->state, a->round_key[r]); | 90 addkey(a->state, a->round_key[r]); |
96 mix2(a->state, multbl, 3-s, 1+s); | 91 mix(a->state, multbl, 3-s, 1+s); |
97 } | 92 } |
98 addkey(a->state, a->round_key[1]); | 93 addkey(a->state, a->round_key[1]); |
99 subshift(a->state[0], a->state[0]+3-s, a->state[0]+1+s, sbox); | 94 subshift(a->state[0][0], a->state[0][0]+3-s, a->state[0][0]+1+s, sbox); |
100 addkey(a->state, a->round_key[0]); | 95 addkey(a->state, a->round_key[0]); |
101 } | 96 } |
102 | 97 |
103 static void aes_decrypt(AVAES *a){ | 98 static void aes_decrypt(AVAES *a){ |
104 crypt(a, 0, inv_sbox, dec_multbl); | 99 crypt(a, 0, inv_sbox, dec_multbl); |
173 } | 168 } |
174 } | 169 } |
175 | 170 |
176 if(decrypt){ | 171 if(decrypt){ |
177 for(i=1; i<rounds; i++){ | 172 for(i=1; i<rounds; i++){ |
178 subshift(a->round_key[i][0], a->round_key[i][0]+3, a->round_key[i][0]+1, sbox); | 173 uint8_t tmp[2][16]; |
179 mix2(a->round_key[i], dec_multbl, 1, 3); | 174 memcpy(tmp[1], a->round_key[i][0], 16); |
175 subshift(tmp[0], tmp[0]+3, tmp[0]+1, sbox); | |
176 memcpy(tmp[1], tmp[0], 16); | |
177 mix(tmp, dec_multbl, 1, 3); | |
178 memcpy(a->round_key[i][0], tmp[0], 16); | |
180 } | 179 } |
181 }else{ | 180 }else{ |
182 for(i=0; i<(rounds+1)>>1; i++){ | 181 for(i=0; i<(rounds+1)>>1; i++){ |
183 for(j=0; j<16; j++) | 182 for(j=0; j<16; j++) |
184 FFSWAP(int, a->round_key[i][0][j], a->round_key[rounds-i][0][j]); | 183 FFSWAP(int, a->round_key[i][0][j], a->round_key[rounds-i][0][j]); |
211 for(i=0; i<2; i++){ | 210 for(i=0; i<2; i++){ |
212 av_aes_init(&b, rkey[i], 128, 1); | 211 av_aes_init(&b, rkey[i], 128, 1); |
213 memcpy(b.state, rct[i], 16); | 212 memcpy(b.state, rct[i], 16); |
214 aes_decrypt(&b); | 213 aes_decrypt(&b); |
215 for(j=0; j<16; j++) | 214 for(j=0; j<16; j++) |
216 if(rpt[i][j] != b.state[0][j]) | 215 if(rpt[i][j] != b.state[1][0][j]) |
217 av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n", j, rpt[i][j], b.state[0][j]); | 216 av_log(NULL, AV_LOG_ERROR, "%d %02X %02X\n", j, rpt[i][j], b.state[1][0][j]); |
218 } | 217 } |
219 | 218 |
220 for(i=0; i<10000; i++){ | 219 for(i=0; i<10000; i++){ |
221 for(j=0; j<16; j++){ | 220 for(j=0; j<16; j++){ |
222 pt[j]= random(); | 221 pt[j]= random(); |
223 } | 222 } |
224 memcpy(ae.state, pt, 16); | 223 memcpy(ae.state, pt, 16); |
225 {START_TIMER | 224 {START_TIMER |
226 aes_encrypt(&ae); | 225 aes_encrypt(&ae); |
227 if(!(i&(i-1))) | 226 if(!(i&(i-1))) |
228 av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n", ae.state[0][0], ae.state[1][1], ae.state[2][2], ae.state[3][3]); | 227 av_log(NULL, AV_LOG_ERROR, "%02X %02X %02X %02X\n", ae.state[1][0][0], ae.state[1][1][1], ae.state[1][2][2], ae.state[1][3][3]); |
229 memcpy(ad.state, ae.state, 16); | 228 memcpy(ad.state[0], ae.state[1], 16); |
230 aes_decrypt(&ad); | 229 aes_decrypt(&ad); |
231 STOP_TIMER("aes")} | 230 STOP_TIMER("aes")} |
232 for(j=0; j<16; j++){ | 231 for(j=0; j<16; j++){ |
233 if(pt[j] != ad.state[0][j]){ | 232 if(pt[j] != ad.state[1][0][j]){ |
234 av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n", i,j, pt[j], ad.state[0][j]); | 233 av_log(NULL, AV_LOG_ERROR, "%d %d %02X %02X\n", i,j, pt[j], ad.state[1][0][j]); |
235 } | 234 } |
236 } | 235 } |
237 } | 236 } |
238 return 0; | 237 return 0; |
239 } | 238 } |