]> git.cryptolib.org Git - avr-crypto-lib.git/blob - mugi/mugi.c
first steps to keccak in asm
[avr-crypto-lib.git] / mugi / mugi.c
1 /* mugi.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 /**
20  * \file        mugi.c
21  * \author      Daniel Otte 
22  * \email   daniel.otte@rub.de
23  * \date        2009-02-15
24  * \brief       implementation of the MUGI key stream generator
25  * \license     GPLv3 or later
26  */
27  
28 #include <stdint.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <avr/pgmspace.h>
32 #include "aes_sbox.h"
33 #include "mugi.h"
34 #include "gf256mul.h"
35
36 /*
37 #include "cli.h" / * only for debugging * /
38
39 void dump_mugi_ctx(mugi_ctx_t* ctx){
40         uint8_t i;
41         cli_putstr_P(PSTR("\r\n== MUGI CTX DUMP==\r\n a:"));
42         cli_hexdump(&(ctx->a[0]), 8);
43         cli_putc(' ');
44         cli_hexdump(&(ctx->a[1]), 8);
45         cli_putc(' ');
46         cli_hexdump(&(ctx->a[2]), 8);
47         cli_putstr_P(PSTR("\r\n b: "));
48         for(i=0; i<4; ++i){
49                 cli_putstr_P(PSTR("\r\n    "));
50                 cli_hexdump(&(ctx->b[i*4+0]), 8);
51                 cli_putc(' ');
52                 cli_hexdump(&(ctx->b[i*4+1]), 8);
53                 cli_putc(' ');
54                 cli_hexdump(&(ctx->b[i*4+2]), 8);
55                 cli_putc(' ');
56                 cli_hexdump(&(ctx->b[i*4+3]), 8);
57         }
58 }
59 */
60
61 #define C0 0x08c9bcf367e6096all
62 #define C1 0x3ba7ca8485ae67bbll
63 #define C2 0x2bf894fe72f36e3cll
64
65 #define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
66
67 uint64_t changeendian64(uint64_t a){
68         union {
69                 uint8_t v8[8];
70                 uint64_t v64;
71         } r;
72         r.v8[0] = ((uint8_t*)&a)[7];
73         r.v8[1] = ((uint8_t*)&a)[6];
74         r.v8[2] = ((uint8_t*)&a)[5];
75         r.v8[3] = ((uint8_t*)&a)[4];
76         r.v8[4] = ((uint8_t*)&a)[3];
77         r.v8[5] = ((uint8_t*)&a)[2];
78         r.v8[6] = ((uint8_t*)&a)[1];
79         r.v8[7] = ((uint8_t*)&a)[0];
80         return r.v64;
81 }
82
83 static
84 uint64_t rotl64(uint64_t a, uint8_t i){
85         uint64_t r;
86         r=changeendian64(a);
87         r=(r<<i | r>>(64-i));
88         r=changeendian64(r);
89         return r;
90 }
91
92 static
93 uint64_t rotr64(uint64_t a, uint8_t i){
94         uint64_t r;
95         r=changeendian64(a);
96         r=(r>>i | r<<(64-i));
97         r=changeendian64(r);
98         return r;
99 }
100
101
102 #define T(x) (((uint8_t*)&t)[(x)])
103 #define D(y) (((uint8_t*)dest)[(y)])
104 static void mugi_f(uint64_t* dest, uint64_t* a, uint64_t* b){
105         uint64_t t;
106         uint8_t i,x;
107         t = (*a); 
108         if(b)
109                 t ^= (*b);
110         for(i=0; i<8; ++i)
111                 T(i) = pgm_read_byte(aes_sbox+T(i));
112         
113         x = T(0) ^ T(1) ^ T(2) ^ T(3);
114         D(4) =
115                   GF256MUL_2(T(0)^T(1))
116                 ^ T(0)
117                 ^ x;
118         D(5) =
119                   GF256MUL_2(T(1)^T(2))
120                 ^ T(1)
121                 ^ x;
122         D(2) =
123                   GF256MUL_2(T(2)^T(3))
124                 ^ T(2)
125                 ^ x;
126         D(3) =
127                   GF256MUL_2(T(3)^T(0))
128                 ^ T(3)
129                 ^ x;
130         x = T(4) ^ T(5) ^ T(6) ^ T(7);
131         D(0) =
132                   GF256MUL_2(T(4)^T(5))
133                 ^ T(4)
134                 ^ x;
135         D(1) =
136                   GF256MUL_2(T(5)^T(6))
137                 ^ T(5)
138                 ^ x;
139         D(6) =
140                   GF256MUL_2(T(6)^T(7))
141                 ^ T(6)
142                 ^ x;
143         D(7) =
144                   GF256MUL_2(T(7)^T(4))
145                 ^ T(7)
146                 ^ x;
147
148
149 static
150 void mugi_rho(mugi_ctx_t* ctx){
151         uint64_t t,bx;
152         t = ctx->a[1];
153         ctx->a[1] = ctx->a[2];
154         ctx->a[2] = ctx->a[0];
155         ctx->a[0] = t;
156         mugi_f(&t, &(ctx->a[0]), &(ctx->b[4]));
157         ctx->a[1] ^= t ^ C1;
158         bx = rotl64(ctx->b[10], 17);
159         mugi_f(&t, &(ctx->a[0]), &bx);
160         ctx->a[2] ^= t ^ C2;
161
162
163 static
164 void mugi_rho_init(uint64_t* a){
165         uint64_t t;
166         t = a[1];
167         a[1] = a[2];
168         a[2] = a[0];
169         a[0] = t;
170         mugi_f(&t, &(a[0]), NULL);
171         a[1] ^= t ^ C1;
172         mugi_f(&t, &(a[0]), NULL);
173         a[2] ^= t ^ C2;
174
175
176 static
177 void mugi_lambda(uint64_t* b, uint64_t *a){
178         uint8_t i;
179         uint64_t t;
180         t=b[15];
181         for(i=15; i!=0; --i){
182                 b[i]=b[i-1];
183         }
184         b[0]   = t ^ *a;
185         b[4]  ^= b[8];
186         b[10] ^= rotl64(b[14], 32);
187 }
188
189 void mugi_init(const void* key, const void* iv, mugi_ctx_t* ctx){
190         uint8_t i;
191         uint64_t a0;
192         memcpy(ctx->a, key, 128/8);
193         ctx->a[2] = rotl64(ctx->a[0], 7) ^ rotr64(ctx->a[1], 7) ^ C0;
194         for(i=0; i<16;i++){
195                 mugi_rho_init(ctx->a);
196                 ctx->b[15-i] = ctx->a[0];
197         }
198         ctx->a[0] ^= ((uint64_t*)iv)[0];
199         ctx->a[1] ^= ((uint64_t*)iv)[1];
200         ctx->a[2] ^= rotl64(((uint64_t*)iv)[0], 7) ^ rotr64(((uint64_t*)iv)[1], 7) ^ C0;
201         for(i=0; i<16;i++){
202                 mugi_rho_init(ctx->a);
203         }
204         for(i=0; i<15;i++){
205                 a0 = ctx->a[0];
206                 mugi_rho(ctx);
207                 mugi_lambda(ctx->b, &a0);
208         }
209         a0=0x00;
210 }
211
212 uint64_t mugi_gen(mugi_ctx_t* ctx){
213         uint64_t r;
214         r=ctx->a[0];
215         mugi_rho(ctx);
216         mugi_lambda(ctx->b, &r);
217         r=ctx->a[2];
218         return r;
219 }