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/>.
23 * \brief SEED parts in C for AVR
29 #include <avr/pgmspace.h>
35 uint32_t seed_kc[16] PROGMEM ={
55 static uint64_t f_function(uint64_t a, uint32_t k0, uint32_t k1);
56 uint32_t g_function(uint32_t x);
58 uint32_t bigendian_sum32(uint32_t a, uint32_t b);
59 uint32_t bigendian_sub32(uint32_t a, uint32_t b);
61 /******************************************************************************/
63 uint64_t bigendian_rotl8_64(uint64_t a){
66 a = (a<<8) | (a>>(64-8));
69 a = (a>>8) | (a<<(64-8));
73 /******************************************************************************/
75 uint64_t bigendian_rotr8_64(uint64_t a){
78 a = (a>>8) | (a<<(64-8));
81 a = (a<<8) | (a>>(64-8));
85 /******************************************************************************/
87 uint64_t f_function(uint64_t a, uint32_t k0, uint32_t k1){
90 c = a & 0x00000000FFFFFFFFLL;
91 d = (a>>32) & 0x00000000FFFFFFFFLL;
96 c = bigendian_sum32(c,d);
98 d = bigendian_sum32(c,d);
100 c = bigendian_sum32(c,d);
101 a = ((uint64_t)d << 32) | c;
106 /******************************************************************************/
112 keypair_t getnextkeys(uint32_t *keystate, uint8_t curround){
118 /* ret.k0 = g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
119 ret.k1 = g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); */
120 ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
121 ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
122 ret.k0 = g_function(ret.k0);
123 ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
124 ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
125 ret.k1 = g_function(ret.k1);
128 /* odd round (1,3,5, ...) */
129 ((uint64_t*)keystate)[1] = bigendian_rotl8_64( ((uint64_t*)keystate)[1] );
131 /* even round (0,2,4, ...) */
132 ((uint64_t*)keystate)[0] = bigendian_rotr8_64(((uint64_t*)keystate)[0]);
139 /******************************************************************************/
141 keypair_t getprevkeys(uint32_t *keystate, uint8_t curround){
148 /* odd round (1,3,5, ..., 15) */
149 ((uint64_t*)keystate)[1] = bigendian_rotr8_64( ((uint64_t*)keystate)[1] );
151 /* even round (0,2,4, ..., 14) */
152 ((uint64_t*)keystate)[0] = bigendian_rotl8_64(((uint64_t*)keystate)[0]);
154 /* ret.k0 = g_function(keystate[0] + keystate[2] - pgm_read_dword(&(seed_kc[curround])));
155 ret.k1 = g_function(keystate[1] - keystate[3] + pgm_read_dword(&(seed_kc[curround]))); */
156 ret.k0 = bigendian_sum32(keystate[0], keystate[2]);
157 ret.k0 = bigendian_sub32(ret.k0, pgm_read_dword(&(seed_kc[curround])));
158 ret.k0 = g_function(ret.k0);
159 ret.k1 = bigendian_sub32(keystate[1], keystate[3]);
160 ret.k1 = bigendian_sum32(ret.k1, pgm_read_dword(&(seed_kc[curround])));
161 ret.k1 = g_function(ret.k1);
166 /******************************************************************************/
172 /******************************************************************************/
174 void seed_init(uint8_t * key, seed_ctx_t * ctx){
175 memcpy(ctx->k, key, 128/8);
178 /******************************************************************************/
180 #define L (((uint64_t*)buffer)[0])
181 #define R (((uint64_t*)buffer)[1])
183 void seed_enc(void * buffer, seed_ctx_t * ctx){
187 k = getnextkeys(ctx->k, 2*r);
189 DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
190 DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
191 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
192 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
194 L ^= f_function(R,k.k0,k.k1);
196 k = getnextkeys(ctx->k, 2*r+1);
198 DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
199 DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
200 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
201 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
203 R ^= f_function(L,k.k0,k.k1);
205 /* just an exchange without temp. variable */
211 /******************************************************************************/
213 #define L (((uint64_t*)buffer)[0])
214 #define R (((uint64_t*)buffer)[1])
216 void seed_dec(void * buffer, seed_ctx_t * ctx){
220 k = getprevkeys(ctx->k, 2*r+1);
222 DEBUG_S("\r\n\tDBG ka,0: "); uart_hexdump(&k.k0, 4);
223 DEBUG_S("\r\n\tDBG ka,1: "); uart_hexdump(&k.k1, 4);
224 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+0, 8);
225 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+8, 8);
227 L ^= f_function(R,k.k0,k.k1);
229 k = getprevkeys(ctx->k, 2*r+0);
231 DEBUG_S("\r\n\tDBG kb,0: "); uart_hexdump(&k.k0, 4);
232 DEBUG_S("\r\n\tDBG kb,1: "); uart_hexdump(&k.k1, 4);
233 DEBUG_S("\r\n\t DBG L: "); uart_hexdump((uint8_t*)buffer+8, 8);
234 DEBUG_S("\r\n\t DBG R: "); uart_hexdump((uint8_t*)buffer+0, 8);
236 R ^= f_function(L,k.k0,k.k1);
238 /* just an exchange without temp. variable */