3 This file is part of the ARM-Crypto-Lib.
4 Copyright (C) 2006-2010 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/>.
21 * email: daniel.otte@rub.de
22 * license: GPLv3 or later
32 #include <avr/pgmspace.h>
42 void gamma_x(uint32_t* a){
45 a[1] ^= ~((a[3]) | (a[2]));
48 tmp=a[3]; a[3]=a[0]; a[0]=tmp;
49 a[2] ^= a[0] ^ a[1] ^ a[3];
51 a[1] ^= ~((a[3]) | (a[2]));
55 #define ROTL32(a,n) (((a)<<n)|((a)>>(32-n)))
56 #define ROTR32(a,n) (((a)>>n)|((a)<<(32-n)))
59 void pi1(uint32_t* a){
60 a[1] = ROTL32(a[1], 1);
61 a[2] = ROTL32(a[2], 5);
62 a[3] = ROTL32(a[3], 2);
66 void pi2(uint32_t* a){
67 a[1] = ROTR32(a[1], 1);
68 a[2] = ROTR32(a[2], 5);
69 a[3] = ROTR32(a[3], 2);
73 void theta(const uint32_t* k, uint32_t* a){
76 temp = a[0] ^ a[2]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
85 temp = a[1] ^ a[3]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
92 void noekeon_round(uint32_t* key, uint32_t* state, uint8_t const1, uint8_t const2){
93 ((uint8_t*)state)[RC_POS] ^= const1;
95 ((uint8_t*)state)[RC_POS] ^= const2;
107 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A,
108 0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A,
112 0xD4, 0xB3, 0x7D, 0xFA, 0xEF, 0xC5, 0x91, 0x39,
113 0x72, 0xE4, 0xD3, 0xBD, 0x61, 0xC2, 0x9F, 0x25,
117 void changendian32(void* a){
118 ((uint8_t*)a)[0] ^= ((uint8_t*)a)[3];
119 ((uint8_t*)a)[3] ^= ((uint8_t*)a)[0];
120 ((uint8_t*)a)[0] ^= ((uint8_t*)a)[3];
122 ((uint8_t*)a)[1] ^= ((uint8_t*)a)[2];
123 ((uint8_t*)a)[2] ^= ((uint8_t*)a)[1];
124 ((uint8_t*)a)[1] ^= ((uint8_t*)a)[2];
128 void changendian(void* a){
129 changendian32((uint32_t*)(&(((uint32_t*)a)[0])));
130 changendian32((uint32_t*)(&(((uint32_t*)a)[1])));
131 changendian32((uint32_t*)(&(((uint32_t*)a)[2])));
132 changendian32((uint32_t*)(&(((uint32_t*)a)[3])));
135 /******************************************************************************/
137 void noekeon_enc(void* buffer, const void* key){
142 memcpy(keyb, key, 16);
146 for(i=0; i<ROUND_NR; ++i){
147 noekeon_round((uint32_t*)keyb, (uint32_t*)buffer, rc, 0);
149 rc = pgm_read_byte(rc_tab+i);
154 ((uint8_t*)buffer)[RC_POS] ^= rc;
155 theta((uint32_t*)keyb, (uint32_t*)buffer);
161 void noekeon_dec(void* buffer, const void* key){
170 memset(nullv, 0, 16);
171 memcpy(dkey, key, 16);
174 theta((uint32_t*)nullv, (uint32_t*)dkey);
175 // cli_putstr("\r\nTheta: ");
176 // cli_hexdump(dkey, 16);
178 for(i=ROUND_NR-1; i>=0; --i){
180 rc = pgm_read_byte(rc_tab+i);
184 noekeon_round((uint32_t*)dkey, (uint32_t*)buffer, 0, rc);
186 theta((uint32_t*)dkey, (uint32_t*)buffer);
187 ((uint8_t*)buffer)[RC_POS] ^= 0x80;
192 void noekeon_init(const void* key, noekeon_ctx_t* ctx){
195 memset(nullv, 0, 16);
196 memcpy(ctx, key, 16);
197 noekeon_enc(ctx, nullv);