X-Git-Url: https://git.cryptolib.org/?p=avr-crypto-lib.git;a=blobdiff_plain;f=mugi%2Fmugi.c;fp=mugi%2Fmugi.c;h=d196c6eecebb570d1eaf1f3841c08ab8510e14b3;hp=0000000000000000000000000000000000000000;hb=4f50c75ee5a6cc88bf7ea71957ed509e298e6c25;hpb=7701e318e4e2bac7f84dbf6e368f1501814948fc diff --git a/mugi/mugi.c b/mugi/mugi.c new file mode 100644 index 0000000..d196c6e --- /dev/null +++ b/mugi/mugi.c @@ -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 . +*/ +/** + * \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 +#include +#include +#include +#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<>(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; +}