]> git.cryptolib.org Git - avr-crypto-lib.git/blob - noekeon.c
fc25d62a78f2641d8e2203cc63238121db25e0ae
[avr-crypto-lib.git] / noekeon.c
1 /*
2  * author: Daniel Otte
3  * email:  daniel.otte@rub.de
4  * license: GPLv3
5  * 
6  * 
7  * 
8  */
9
10 #include <stdint.h>
11 #include <string.h>
12 #include <avr/pgmspace.h>
13 #include "noekeon.h"
14 #include "uart.h"
15
16 #define ROUND_NR 16
17
18 #define RC_POS 0
19
20 static
21 void gamma(uint32_t* a){
22         uint32_t tmp;
23         
24         a[1] ^= ~((a[3]) | (a[2]));
25         a[0] ^=   a[2] & a[1];  
26         
27         tmp=a[3]; a[3]=a[0]; a[0]=tmp;
28         a[2] ^= a[0] ^ a[1] ^ a[3];
29         
30         a[1] ^= ~((a[3]) | (a[2]));
31         a[0] ^=   a[2] & a[1];  
32 }       
33
34 #define ROTL32(a,n) (((a)<<n)|((a)>>(32-n)))
35 #define ROTR32(a,n) (((a)>>n)|((a)<<(32-n)))
36
37 static
38 void pi1(uint32_t* a){
39         a[1] = ROTL32(a[1], 1);
40         a[2] = ROTL32(a[2], 5);
41         a[3] = ROTL32(a[3], 2);
42 }
43
44 static
45 void pi2(uint32_t* a){
46         a[1] = ROTR32(a[1], 1);
47         a[2] = ROTR32(a[2], 5);
48         a[3] = ROTR32(a[3], 2);
49 }
50
51 static
52 void theta(uint32_t* k, uint32_t* a){
53         uint32_t temp;
54
55         temp = a[0] ^ a[2]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
56         a[1] ^= temp;
57         a[3] ^= temp;
58         
59         a[0] ^= k[0];
60         a[1] ^= k[1];
61         a[2] ^= k[2];
62         a[3] ^= k[3];
63
64         temp = a[1] ^ a[3]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
65         a[0] ^= temp;
66         a[2] ^= temp;   
67
68 }
69
70 static 
71 void noekeon_round(uint32_t* key, uint32_t* state, uint8_t const1, uint8_t const2){
72         ((uint8_t*)state)[RC_POS] ^= const1;
73         theta(key, state);
74         ((uint8_t*)state)[RC_POS] ^= const2;
75         pi1(state);
76         gamma(state);
77         pi2(state);
78 }
79
80 uint8_t rc_tab[] PROGMEM = {
81 /*      0x80, */
82               0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A,
83         0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A,
84         0xD4
85 };
86 /* for more rounds
87  0xD4, 0xB3, 0x7D, 0xFA, 0xEF, 0xC5, 0x91, 0x39,
88  0x72, 0xE4, 0xD3, 0xBD, 0x61, 0xC2, 0x9F, 0x25,
89 */
90
91 static
92 void changendian32(void* a){
93         ((uint8_t*)a)[0] ^= ((uint8_t*)a)[3];
94         ((uint8_t*)a)[3] ^= ((uint8_t*)a)[0];
95         ((uint8_t*)a)[0] ^= ((uint8_t*)a)[3];
96         
97         ((uint8_t*)a)[1] ^= ((uint8_t*)a)[2];
98         ((uint8_t*)a)[2] ^= ((uint8_t*)a)[1];
99         ((uint8_t*)a)[1] ^= ((uint8_t*)a)[2];
100 }
101
102 static
103 void changendian(void* a){
104         changendian32((uint32_t*)(&(((uint32_t*)a)[0])));
105         changendian32((uint32_t*)(&(((uint32_t*)a)[1])));
106         changendian32((uint32_t*)(&(((uint32_t*)a)[2])));
107         changendian32((uint32_t*)(&(((uint32_t*)a)[3])));
108 }
109
110 /******************************************************************************/
111
112 void noekeon_enc(void* buffer, void* key){
113         uint8_t rc=0x80;
114         int8_t i;
115         
116         changendian(buffer);
117         changendian(key);
118
119         for(i=0; i<ROUND_NR; ++i){
120                 noekeon_round((uint32_t*)key, (uint32_t*)buffer, rc, 0);
121                 rc = pgm_read_byte(rc_tab+i);
122         }
123         ((uint8_t*)buffer)[RC_POS] ^= rc;
124         theta((uint32_t*)key, (uint32_t*)buffer);
125
126         changendian(buffer);
127         changendian(key);
128 }
129
130
131 void noekeon_dec(void* buffer, void* key){
132         uint8_t rc;
133         int8_t i;
134         uint8_t nullv[16];
135         uint8_t dkey[16];
136         
137
138         changendian(buffer);
139         changendian(key);
140         
141         memset(nullv, 0, 16);
142         memcpy(dkey, key, 16);
143         
144         theta((uint32_t*)nullv, (uint32_t*)dkey);
145         uart_putstr_P(PSTR("\r\nTheta: "));
146         uart_hexdump(dkey, 16);
147         
148         for(i=ROUND_NR-1; i>=0; --i){
149                 rc = pgm_read_byte(rc_tab+i);
150                 noekeon_round((uint32_t*)dkey, (uint32_t*)buffer, 0, rc);
151         }
152         theta((uint32_t*)dkey, (uint32_t*)buffer);
153         ((uint8_t*)buffer)[RC_POS] ^= 0x80;
154
155         changendian(buffer);
156         changendian(key);
157 }
158
159 void noekeon_init(void* key, noekeon_ctx_t* ctx){
160         uint8_t nullv[16];
161         
162         memset(nullv, 0, 16);
163         memcpy(ctx, key, 16);
164         noekeon_enc(ctx, nullv);
165 }
166