3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
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.
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.
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/>.
22 * \email daniel.otte@rub.de
24 * \brief implementation of the MUGI key stream generator
25 * \license GPLv3 or later
31 #include <avr/pgmspace.h>
37 #include "cli.h" / * only for debugging * /
39 void dump_mugi_ctx(mugi_ctx_t* ctx){
41 cli_putstr_P(PSTR("\r\n== MUGI CTX DUMP==\r\n a:"));
42 cli_hexdump(&(ctx->a[0]), 8);
44 cli_hexdump(&(ctx->a[1]), 8);
46 cli_hexdump(&(ctx->a[2]), 8);
47 cli_putstr_P(PSTR("\r\n b: "));
49 cli_putstr_P(PSTR("\r\n "));
50 cli_hexdump(&(ctx->b[i*4+0]), 8);
52 cli_hexdump(&(ctx->b[i*4+1]), 8);
54 cli_hexdump(&(ctx->b[i*4+2]), 8);
56 cli_hexdump(&(ctx->b[i*4+3]), 8);
61 #define C0 0x08c9bcf367e6096all
62 #define C1 0x3ba7ca8485ae67bbll
63 #define C2 0x2bf894fe72f36e3cll
65 #define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
67 uint64_t changeendian64(uint64_t a){
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];
84 uint64_t rotl64(uint64_t a, uint8_t i){
93 uint64_t rotr64(uint64_t a, uint8_t i){
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){
111 T(i) = pgm_read_byte(aes_sbox+T(i));
113 x = T(0) ^ T(1) ^ T(2) ^ T(3);
115 GF256MUL_2(T(0)^T(1))
119 GF256MUL_2(T(1)^T(2))
123 GF256MUL_2(T(2)^T(3))
127 GF256MUL_2(T(3)^T(0))
130 x = T(4) ^ T(5) ^ T(6) ^ T(7);
132 GF256MUL_2(T(4)^T(5))
136 GF256MUL_2(T(5)^T(6))
140 GF256MUL_2(T(6)^T(7))
144 GF256MUL_2(T(7)^T(4))
150 void mugi_rho(mugi_ctx_t* ctx){
153 ctx->a[1] = ctx->a[2];
154 ctx->a[2] = ctx->a[0];
156 mugi_f(&t, &(ctx->a[0]), &(ctx->b[4]));
158 bx = rotl64(ctx->b[10], 17);
159 mugi_f(&t, &(ctx->a[0]), &bx);
164 void mugi_rho_init(uint64_t* a){
170 mugi_f(&t, &(a[0]), NULL);
172 mugi_f(&t, &(a[0]), NULL);
177 void mugi_lambda(uint64_t* b, uint64_t *a){
181 for(i=15; i!=0; --i){
186 b[10] ^= rotl64(b[14], 32);
189 void mugi_init(const void* key, const void* iv, mugi_ctx_t* ctx){
192 memcpy(ctx->a, key, 128/8);
193 ctx->a[2] = rotl64(ctx->a[0], 7) ^ rotr64(ctx->a[1], 7) ^ C0;
195 mugi_rho_init(ctx->a);
196 ctx->b[15-i] = ctx->a[0];
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;
202 mugi_rho_init(ctx->a);
207 mugi_lambda(ctx->b, &a0);
212 uint64_t mugi_gen(mugi_ctx_t* ctx){
216 mugi_lambda(ctx->b, &r);