3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2006-2011 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 #include <avr/pgmspace.h>
66 3x Fx Ex 0x 5x 4x Bx Cx Dx Ax 9x 6x 7x 8x 2x 1x
68 9x Ex 5x 6x Ax 2x 3x Cx Fx 0x 4x Dx 7x Bx 1x 8x
71 static const uint8_t pq_lut[16] PROGMEM = {
72 0x39, 0xFE, 0xE5, 0x06, 0x5A, 0x42, 0xB3, 0xCC,
73 0xDF, 0xA0, 0x94, 0x6D, 0x77, 0x8B, 0x21, 0x18
76 uint8_t khazad_sbox(uint8_t a){
78 b = pgm_read_byte(pq_lut+(a>>4))&0xf0;
79 c = pgm_read_byte(pq_lut+(a&0xf))&0x0f;
84 b = pgm_read_byte(pq_lut+(b>>4))<<4;
85 c = pgm_read_byte(pq_lut+(c&0xf))>>4;
90 b = pgm_read_byte(pq_lut+(b>>4))&0xf0;
91 c = pgm_read_byte(pq_lut+(c&0xf))&0x0f;
95 static void gamma_1(uint8_t* a){
103 /******************************************************************************/
104 /* p8 (x) = x^8 + x^4 + x^3 + x^2 + 1 */
108 * 01x 03x 04x 05x 06x 08x 0Bx 07x
109 * 03x 01x 05x 04x 08x 06x 07x 0Bx
110 * 04x 05x 01x 03x 0Bx 07x 06x 08x
111 * 05x 04x 03x 01x 07x 0Bx 08x 06x
112 * 06x 08x 0Bx 07x 01x 03x 04x 05x
113 * 08x 06x 07x 0Bx 03x 01x 05x 04x
114 * 0Bx 07x 06x 08x 04x 05x 01x 03x
115 * 07x 0Bx 08x 06x 05x 04x 03x 01x
118 static const uint8_t h[8][4] PROGMEM = {
119 { 0x13, 0x45, 0x68, 0xB7 },
120 { 0x31, 0x54, 0x86, 0x7B },
121 { 0x45, 0x13, 0xB7, 0x68 },
122 { 0x54, 0x31, 0x7B, 0x86 },
123 { 0x68, 0xB7, 0x13, 0x45 },
124 { 0x86, 0x7B, 0x31, 0x54 },
125 { 0xB7, 0x68, 0x45, 0x13 },
126 { 0x7B, 0x86, 0x54, 0x31 }
129 static void theta(uint8_t* a){
137 x = pgm_read_byte(hp++);
138 accu ^= gf256mul(*a++, x>>4, POLYNOM);
139 accu ^= gf256mul(*a++, x&0xf, POLYNOM);
147 /******************************************************************************/
149 static void khazad_round(uint8_t* a, const uint8_t* k){
155 /******************************************************************************/
157 void khazad_init(const void* key, khazad_ctx_t* ctx){
161 c[i] = khazad_sbox(r*8+i);
163 memcpy(ctx->k[r], (uint8_t*)key+8, 8);
164 khazad_round(ctx->k[r], c);
165 memxor(ctx->k[r], (uint8_t*)key, 8);
168 c[i] = khazad_sbox(r*8+i);
170 memcpy(ctx->k[r], ctx->k[r-1], 8);
171 khazad_round(ctx->k[r], c);
172 memxor(ctx->k[r], (uint8_t*)key+8, 8);
175 c[i] = khazad_sbox(r*8+i);
177 memcpy(ctx->k[r], ctx->k[r-1], 8);
178 khazad_round(ctx->k[r], c);
179 memxor(ctx->k[r], ctx->k[r-2], 8);
183 /******************************************************************************/
185 void khazad_enc(void* buffer, const khazad_ctx_t* ctx){
187 memxor(buffer, ctx->k[0], 8);
189 khazad_round(buffer, ctx->k[r]);
192 memxor(buffer, ctx->k[8], 8);
195 /******************************************************************************/
197 void khazad_dec(void* buffer, const khazad_ctx_t* ctx){
199 memxor(buffer, ctx->k[8], 8);
202 memxor(buffer, ctx->k[r--], 8);
206 memxor(buffer, ctx->k[0], 8);