]> git.cryptolib.org Git - avr-crypto-lib.git/blob - groestl/groestl_large.c
bcfd8e51ae67c81f807c466b21d7f20d7db38314
[avr-crypto-lib.git] / groestl / groestl_large.c
1 /* groestl_large.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
5
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.
10
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.
15
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/>.
18 */
19 /*
20  * \file    groestl_large.c
21  * \author  Daniel Otte
22  * \email   daniel.otte@rub.de
23  * \date    2009-06-11
24  * \license GPLv3 or later
25  * 
26  */
27
28 #include "groestl_large.h"
29 #include "aes_sbox.h"
30 #include "gf256mul.h"
31 #include "memxor.h"
32 #include <stdint.h>
33 #include <avr/pgmspace.h>
34 #include <string.h>
35
36 #define ROUNDS 14
37 #define POLYNOM 0x1b
38
39 #define DEBUG 0
40
41 #if DEBUG
42  #include "cli.h"
43  void dump_m(const uint8_t* m){
44          uint8_t i,j;
45          for(i=0; i<16; ++i){
46                 cli_putstr_P(PSTR("\r\n"));
47                 for(j=0; j<8; ++j){
48                         cli_putc(' ');
49                         cli_hexdump(m+8*i+j, 1);
50                 }
51          }
52  }
53 #else
54  #define dump_m(m)
55 #endif
56
57 static uint8_t matrix[] PROGMEM = {
58  2, 2, 3, 4, 5, 3, 5, 7,
59  7, 2, 2, 3, 4, 5, 3, 5,
60  5, 7, 2, 2, 3, 4, 5, 3,
61  3, 5, 7, 2, 2, 3, 4, 5,
62  5, 3, 5, 7, 2, 2, 3, 4,
63  4, 5, 3, 5, 7, 2, 2, 3,
64  3, 4, 5, 3, 5, 7, 2, 2,
65  2, 3, 4, 5, 3, 5, 7, 2
66 };
67
68 void groestl_large_rounds(uint8_t *m, uint8_t q){
69         uint8_t r,i,j;
70         uint8_t tmp[16];
71         for(r=0; r<ROUNDS; ++r){
72                 if(q){
73                         m[7] ^= 0xff ^ r;
74                 }else{
75                         m[0] ^= r;
76                 }       
77 #if DEBUG               
78                 if(r<2){
79                         cli_putstr_P(PSTR("\r\npost add-const"));
80                         dump_m(m);
81                 }
82 #endif
83                 for(i=0;i<16*8; ++i){
84                         m[i] = pgm_read_byte(aes_sbox+m[i]);
85                 }
86                 for(i=1; i<7; ++i){
87                         for(j=0; j<16; ++j)
88                                 tmp[j] = m[i+8*j];
89                         for(j=0; j<16; ++j){
90                                 m[i+((j-i+16)%16)*8] = tmp[j];
91                         }
92                 }
93                 for(j=0; j<16; ++j)
94                         tmp[j] = m[7+8*j];
95                 for(j=0; j<16; ++j){
96                         m[7+((j-11+16)%16)*8] = tmp[j];
97                 }
98                 
99 #if DEBUG               
100                 if(r<2){
101                         cli_putstr_P(PSTR("\r\npost shift-bytes"));
102                         dump_m(m);
103                 }
104 #endif          
105                 for(i=0; i<16; ++i){
106                         memcpy(tmp, m+8*i, 8);
107                         for(j=0; j<8; ++j){
108                                 m[j+i*8] = gf256mul(pgm_read_byte(matrix+8*j+0),tmp[0], POLYNOM)
109                                         ^ gf256mul(pgm_read_byte(matrix+8*j+1),tmp[1], POLYNOM)
110                                         ^ gf256mul(pgm_read_byte(matrix+8*j+2),tmp[2], POLYNOM)
111                                         ^ gf256mul(pgm_read_byte(matrix+8*j+3),tmp[3], POLYNOM)
112                                         ^ gf256mul(pgm_read_byte(matrix+8*j+4),tmp[4], POLYNOM)
113                                         ^ gf256mul(pgm_read_byte(matrix+8*j+5),tmp[5], POLYNOM)
114                                         ^ gf256mul(pgm_read_byte(matrix+8*j+6),tmp[6], POLYNOM)
115                                         ^ gf256mul(pgm_read_byte(matrix+8*j+7),tmp[7], POLYNOM);
116                         }
117                 }
118 #if DEBUG
119                 if(r<2){
120                         cli_putstr_P(PSTR("\r\npost mix-bytes"));
121                         dump_m(m);
122                 }
123 #endif                  
124         }
125 }
126
127 void groestl384_init(groestl384_ctx_t* ctx){
128         memset(ctx->h, 0, 16*8);
129         ctx->h[8*16-1] = (uint8_t)384;
130         ctx->h[8*16-2] = (uint8_t)(384>>8);
131         ctx->counter = 0;
132 }
133
134 void groestl512_init(groestl512_ctx_t* ctx){
135         memset(ctx->h, 0, 16*8);
136         ctx->h[8*16-2] = 2;
137         ctx->counter = 0;
138 }
139
140 void groestl_large_nextBlock(groestl_large_ctx_t* ctx, const void* block){
141         uint8_t tmp1[128], tmp2[128];
142 /*
143         for(i=0; i<8; ++i){
144                 for(j=0; j<8; ++j){
145                         tmp1[j*8+i] = ((uint8_t*)block)[i*8+j];
146                 }
147         }
148 */ 
149         memcpy(tmp1, block, 128);
150         memcpy(tmp2, tmp1, 128);
151         memxor(tmp1, ctx->h, 128);
152         groestl_large_rounds(tmp1, 0);
153         groestl_large_rounds(tmp2, 1);
154         memxor(ctx->h, tmp1, 128);
155         memxor(ctx->h, tmp2, 128);
156         ctx->counter++;
157 }
158
159 void groestl_large_lastBlock(groestl_large_ctx_t* ctx, const void* block, uint16_t length_b){
160         uint8_t buffer[128];
161         while(length_b>=GROESTL_LARGE_BLOCKSIZE){
162                 groestl_large_nextBlock(ctx, block);
163                 length_b -= GROESTL_LARGE_BLOCKSIZE;
164                 block = (uint8_t*)block + GROESTL_LARGE_BLOCKSIZE_B;
165         }
166         memset(buffer, 0, 128);
167         memcpy(buffer, block, (length_b+7)/8);
168         buffer[length_b/8] |= 0x80>>(length_b%8);
169         if(length_b>1024-65){
170                 groestl_large_nextBlock(ctx, buffer);
171                 memset(buffer, 0, 128-4);
172         }
173         ctx->counter++;
174         buffer[128-1]  = (uint8_t)(ctx->counter);
175         buffer[128-2]  = (uint8_t)((ctx->counter)>>8);
176         buffer[128-3]  = (uint8_t)((ctx->counter)>>16);
177         buffer[128-4]  = (uint8_t)((ctx->counter)>>24);
178         groestl_large_nextBlock(ctx, buffer);
179 }
180
181 void groestl_large_ctx2hash(void* dest, const groestl_large_ctx_t* ctx, uint16_t outlength_b){
182         uint8_t tmp[128];
183         memcpy(tmp, ctx->h, 128);
184         groestl_large_rounds(tmp, 0);
185         memxor(tmp, ctx->h, 128);
186 #if DEBUG
187         cli_putstr_P(PSTR("\r\npost finalisation"));
188         dump_m(tmp);
189 #endif          
190         memcpy(dest, tmp+128-outlength_b/8, outlength_b/8);
191 }
192
193 void groestl384_ctx2hash(void* dest, const groestl384_ctx_t* ctx){
194         groestl_large_ctx2hash(dest, ctx, 384);
195 }
196
197 void groestl512_ctx2hash(void* dest, const groestl512_ctx_t* ctx){
198         groestl_large_ctx2hash(dest, ctx, 512);
199 }
200
201 void groestl384_nextBlock(groestl384_ctx_t* ctx, const void* block){
202         groestl_large_nextBlock(ctx, block);
203 }
204
205 void groestl512_nextBlock(groestl512_ctx_t* ctx, const void* block){
206         groestl_large_nextBlock(ctx, block);
207 }
208
209 void groestl384_lastBlock(groestl384_ctx_t* ctx, const void* block, uint16_t length_b){
210         groestl_large_lastBlock(ctx, block, length_b);
211 }
212
213 void groestl512_lastBlock(groestl512_ctx_t* ctx, const void* block, uint16_t length_b){
214         groestl_large_lastBlock(ctx, block, length_b);
215 }
216
217 void groestl384(void* dest, const void* msg, uint32_t length_b){
218         groestl_large_ctx_t ctx;
219         groestl384_init(&ctx);
220         while(length_b>=GROESTL_LARGE_BLOCKSIZE){
221                 groestl_large_nextBlock(&ctx, msg);
222                 length_b -= GROESTL_LARGE_BLOCKSIZE;
223                 msg = (uint8_t*)msg + GROESTL_LARGE_BLOCKSIZE_B;
224         }
225         groestl_large_lastBlock(&ctx, msg, length_b);
226         groestl_large_ctx2hash(dest, &ctx, 384);
227 }
228
229 void groestl512(void* dest, const void* msg, uint32_t length_b){
230         groestl_large_ctx_t ctx;
231         groestl512_init(&ctx);
232         while(length_b>=GROESTL_LARGE_BLOCKSIZE){
233                 groestl_large_nextBlock(&ctx, msg);
234                 length_b -= GROESTL_LARGE_BLOCKSIZE;
235                 msg = (uint8_t*)msg + GROESTL_LARGE_BLOCKSIZE_B;
236         }
237         groestl_large_lastBlock(&ctx, msg, length_b);
238         groestl_large_ctx2hash(dest, &ctx, 512);
239 }
240
241
242