3 This file is part of the Crypto-avr-lib/microcrypt-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/>.
21 * email: daniel.otte@rub.de
22 * license: GPLv3 or later
30 #include <avr/pgmspace.h>
39 void gamma(uint32_t* a){
42 a[1] ^= ~((a[3]) | (a[2]));
45 tmp=a[3]; a[3]=a[0]; a[0]=tmp;
46 a[2] ^= a[0] ^ a[1] ^ a[3];
48 a[1] ^= ~((a[3]) | (a[2]));
52 #define ROTL32(a,n) (((a)<<n)|((a)>>(32-n)))
53 #define ROTR32(a,n) (((a)>>n)|((a)<<(32-n)))
56 void pi1(uint32_t* a){
57 a[1] = ROTL32(a[1], 1);
58 a[2] = ROTL32(a[2], 5);
59 a[3] = ROTL32(a[3], 2);
63 void pi2(uint32_t* a){
64 a[1] = ROTR32(a[1], 1);
65 a[2] = ROTR32(a[2], 5);
66 a[3] = ROTR32(a[3], 2);
70 void theta(uint32_t* k, uint32_t* a){
73 temp = a[0] ^ a[2]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
82 temp = a[1] ^ a[3]; temp ^= ROTR32(temp, 8) ^ ROTL32(temp, 8);
89 void noekeon_round(uint32_t* key, uint32_t* state, uint8_t const1, uint8_t const2){
90 ((uint8_t*)state)[RC_POS] ^= const1;
92 ((uint8_t*)state)[RC_POS] ^= const2;
98 uint8_t rc_tab[] PROGMEM = {
100 0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A,
101 0x2F, 0x5E, 0xBC, 0x63, 0xC6, 0x97, 0x35, 0x6A,
105 0xD4, 0xB3, 0x7D, 0xFA, 0xEF, 0xC5, 0x91, 0x39,
106 0x72, 0xE4, 0xD3, 0xBD, 0x61, 0xC2, 0x9F, 0x25,
110 void changendian32(void* a){
111 ((uint8_t*)a)[0] ^= ((uint8_t*)a)[3];
112 ((uint8_t*)a)[3] ^= ((uint8_t*)a)[0];
113 ((uint8_t*)a)[0] ^= ((uint8_t*)a)[3];
115 ((uint8_t*)a)[1] ^= ((uint8_t*)a)[2];
116 ((uint8_t*)a)[2] ^= ((uint8_t*)a)[1];
117 ((uint8_t*)a)[1] ^= ((uint8_t*)a)[2];
121 void changendian(void* a){
122 changendian32((uint32_t*)(&(((uint32_t*)a)[0])));
123 changendian32((uint32_t*)(&(((uint32_t*)a)[1])));
124 changendian32((uint32_t*)(&(((uint32_t*)a)[2])));
125 changendian32((uint32_t*)(&(((uint32_t*)a)[3])));
128 /******************************************************************************/
130 void noekeon_enc(void* buffer, void* key){
137 for(i=0; i<ROUND_NR; ++i){
138 noekeon_round((uint32_t*)key, (uint32_t*)buffer, rc, 0);
139 rc = pgm_read_byte(rc_tab+i);
141 ((uint8_t*)buffer)[RC_POS] ^= rc;
142 theta((uint32_t*)key, (uint32_t*)buffer);
149 void noekeon_dec(void* buffer, void* key){
159 memset(nullv, 0, 16);
160 memcpy(dkey, key, 16);
162 theta((uint32_t*)nullv, (uint32_t*)dkey);
163 // uart_putstr_P(PSTR("\r\nTheta: "));
164 // uart_hexdump(dkey, 16);
166 for(i=ROUND_NR-1; i>=0; --i){
167 rc = pgm_read_byte(rc_tab+i);
168 noekeon_round((uint32_t*)dkey, (uint32_t*)buffer, 0, rc);
170 theta((uint32_t*)dkey, (uint32_t*)buffer);
171 ((uint8_t*)buffer)[RC_POS] ^= 0x80;
177 void noekeon_init(void* key, noekeon_ctx_t* ctx){
180 memset(nullv, 0, 16);
181 memcpy(ctx, key, 16);
182 noekeon_enc(ctx, nullv);