]> git.cryptolib.org Git - avr-crypto-lib.git/blobdiff - mugi/mugi.c
new makefile and modified build process
[avr-crypto-lib.git] / mugi / mugi.c
diff --git a/mugi/mugi.c b/mugi/mugi.c
new file mode 100644 (file)
index 0000000..d196c6e
--- /dev/null
@@ -0,0 +1,216 @@
+/* mugi.c */
+/*
+    This file is part of the AVR-Crypto-Lib.
+    Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * \file       mugi.c
+ * \author     Daniel Otte 
+ * \email   daniel.otte@rub.de
+ * \date       2009-02-15
+ * \brief      implementation of the MUGI key stream generator
+ * \license    GPLv3 or later
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include "aes_sbox.h"
+#include "mugi.h"
+#include "gf256mul.h"
+
+/*
+#include "test_src/cli.h" / * only for debugging * /
+
+void dump_mugi_ctx(mugi_ctx_t* ctx){
+       uint8_t i;
+       cli_putstr_P(PSTR("\r\n== MUGI CTX DUMP==\r\n a:"));
+       cli_hexdump(&(ctx->a[0]), 8);
+       cli_putc(' ');
+       cli_hexdump(&(ctx->a[1]), 8);
+       cli_putc(' ');
+       cli_hexdump(&(ctx->a[2]), 8);
+       cli_putstr_P(PSTR("\r\n b: "));
+       for(i=0; i<4; ++i){
+               cli_putstr_P(PSTR("\r\n    "));
+               cli_hexdump(&(ctx->b[i*4+0]), 8);
+               cli_putc(' ');
+               cli_hexdump(&(ctx->b[i*4+1]), 8);
+               cli_putc(' ');
+               cli_hexdump(&(ctx->b[i*4+2]), 8);
+               cli_putc(' ');
+               cli_hexdump(&(ctx->b[i*4+3]), 8);
+       }
+}
+*/
+
+#define C0 0x08c9bcf367e6096all
+#define C1 0x3ba7ca8485ae67bbll
+#define C2 0x2bf894fe72f36e3cll
+
+#define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
+
+uint64_t changeendian64(uint64_t a){
+       uint8_t r[8];
+       r[0] = ((uint8_t*)&a)[7];
+       r[1] = ((uint8_t*)&a)[6];
+       r[2] = ((uint8_t*)&a)[5];
+       r[3] = ((uint8_t*)&a)[4];
+       r[4] = ((uint8_t*)&a)[3];
+       r[5] = ((uint8_t*)&a)[2];
+       r[6] = ((uint8_t*)&a)[1];
+       r[7] = ((uint8_t*)&a)[0];
+       return *((uint64_t*)r);
+}
+
+static
+uint64_t rotl64(uint64_t a, uint8_t i){
+       uint64_t r;
+       r=changeendian64(a);
+       r=(r<<i | r>>(64-i));
+       r=changeendian64(r);
+       return r;
+}
+
+static
+uint64_t rotr64(uint64_t a, uint8_t i){
+       uint64_t r;
+       r=changeendian64(a);
+       r=(r>>i | r<<(64-i));
+       r=changeendian64(r);
+       return r;
+}
+
+
+#define T(x) (((uint8_t*)&t)[(x)])
+#define D(y) (((uint8_t*)dest)[(y)])
+static void mugi_f(uint64_t* dest, uint64_t* a, uint64_t* b){
+       uint64_t t;
+       uint8_t i,x;
+       t = (*a); 
+       if(b)
+               t ^= (*b);
+       for(i=0; i<8; ++i)
+               T(i) = pgm_read_byte(aes_sbox+T(i));
+       
+       x = T(0) ^ T(1) ^ T(2) ^ T(3);
+       D(4) =
+                 GF256MUL_2(T(0)^T(1))
+               ^ T(0)
+               ^ x;
+       D(5) =
+                 GF256MUL_2(T(1)^T(2))
+               ^ T(1)
+               ^ x;
+       D(2) =
+                 GF256MUL_2(T(2)^T(3))
+               ^ T(2)
+               ^ x;
+       D(3) =
+                 GF256MUL_2(T(3)^T(0))
+               ^ T(3)
+               ^ x;
+       x = T(4) ^ T(5) ^ T(6) ^ T(7);
+       D(0) =
+                 GF256MUL_2(T(4)^T(5))
+               ^ T(4)
+               ^ x;
+       D(1) =
+                 GF256MUL_2(T(5)^T(6))
+               ^ T(5)
+               ^ x;
+       D(6) =
+                 GF256MUL_2(T(6)^T(7))
+               ^ T(6)
+               ^ x;
+       D(7) =
+                 GF256MUL_2(T(7)^T(4))
+               ^ T(7)
+               ^ x;
+} 
+
+static
+void mugi_rho(mugi_ctx_t* ctx){
+       uint64_t t,bx;
+       t = ctx->a[1];
+       ctx->a[1] = ctx->a[2];
+       ctx->a[2] = ctx->a[0];
+       ctx->a[0] = t;
+       mugi_f(&t, &(ctx->a[0]), &(ctx->b[4]));
+       ctx->a[1] ^= t ^ C1;
+       bx = rotl64(ctx->b[10], 17);
+       mugi_f(&t, &(ctx->a[0]), &bx);
+       ctx->a[2] ^= t ^ C2;
+} 
+
+static
+void mugi_rho_init(uint64_t* a){
+       uint64_t t;
+       t = a[1];
+       a[1] = a[2];
+       a[2] = a[0];
+       a[0] = t;
+       mugi_f(&t, &(a[0]), NULL);
+       a[1] ^= t ^ C1;
+       mugi_f(&t, &(a[0]), NULL);
+       a[2] ^= t ^ C2;
+} 
+
+static
+void mugi_lambda(uint64_t* b, uint64_t *a){
+       uint8_t i;
+       uint64_t t;
+       t=b[15];
+       for(i=15; i!=0; --i){
+               b[i]=b[i-1];
+       }
+       b[0]   = t ^ *a;
+       b[4]  ^= b[8];
+       b[10] ^= rotl64(b[14], 32);
+}
+
+void mugi_init(const void* key, const void* iv, mugi_ctx_t* ctx){
+       uint8_t i;
+       uint64_t a0;
+       memcpy(ctx->a, key, 128/8);
+       ctx->a[2] = rotl64(ctx->a[0], 7) ^ rotr64(ctx->a[1], 7) ^ C0;
+       for(i=0; i<16;i++){
+               mugi_rho_init(ctx->a);
+               ctx->b[15-i] = ctx->a[0];
+       }
+       ctx->a[0] ^= ((uint64_t*)iv)[0];
+       ctx->a[1] ^= ((uint64_t*)iv)[1];
+       ctx->a[2] ^= rotl64(((uint64_t*)iv)[0], 7) ^ rotr64(((uint64_t*)iv)[1], 7) ^ C0;
+       for(i=0; i<16;i++){
+               mugi_rho_init(ctx->a);
+       }
+       for(i=0; i<15;i++){
+               a0 = ctx->a[0];
+               mugi_rho(ctx);
+               mugi_lambda(ctx->b, &a0);
+       }
+       a0=0x00;
+}
+
+uint64_t mugi_gen(mugi_ctx_t* ctx){
+       uint64_t r;
+       r=ctx->a[0];
+       mugi_rho(ctx);
+       mugi_lambda(ctx->b, &r);
+       r=ctx->a[2];
+       return r;
+}