3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2009 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/>.
22 * \email daniel.otte@rub.de
24 * \license GPLv3 or later
30 #include <avr/pgmspace.h>
39 uint32_t shabal_u(uint32_t a){
40 return (a<<1)+a; /* a*3 */
44 uint32_t shabal_v(uint32_t a){
45 return (a<<2)+a; /* a*5 */
48 #define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
51 void shabal_p(shabal_ctx_t* ctx, const void* m){
54 ctx->b[i] = ROTL32(ctx->b[i],17);
56 for(j=0;j<SHABAL_P;++j){
58 ctx->a[(i+16*j)%SHABAL_R] =
59 shabal_u(ctx->a[(i+16*j)%SHABAL_R]
60 ^ shabal_v(ROTL32(ctx->a[(i+16*j+SHABAL_R-1)%SHABAL_R],15))
61 ^ ctx->c[(8-i+16)%16])
62 ^ ctx->b[(i+SHABAL_O1)%16]
63 ^ ((ctx->b[(i+SHABAL_O2)%16]) & ~(ctx->b[(i+SHABAL_O3)%16]))
65 ctx->b[i] = ROTL32(ctx->b[i], 1) ^ ~(ctx->a[(i+16*j)%SHABAL_R]);
70 ctx->a[j%SHABAL_R] += ctx->c[(j+3)%16];
74 ctx->a[(36 - 1 - j)%12] =
75 ctx->a[(36 - 1 - j) % 12]
76 + ctx->c[(36 * 16 + 6 - j) % 16];
82 uint32_t shabal192_iv[] PROGMEM = {
84 0xFD749ED4, 0xB798E530, 0x33904B6F, 0x46BDA85E,
85 0x076934B4, 0x454B4058, 0x77F74527, 0xFB4CF465,
86 0x62931DA9, 0xE778C8DB, 0x22B3998E, 0xAC15CFB9,
88 0x58BCBAC4, 0xEC47A08E, 0xAEE933B2, 0xDFCBC824,
89 0xA7944804, 0xBF65BDB0, 0x5A9D4502, 0x59979AF7,
90 0xC5CEA54E, 0x4B6B8150, 0x16E71909, 0x7D632319,
91 0x930573A0, 0xF34C63D1, 0xCAF914B4, 0xFDD6612C,
93 0x61550878, 0x89EF2B75, 0xA1660C46, 0x7EF3855B,
94 0x7297B58C, 0x1BC67793, 0x7FB1C723, 0xB66FC640,
95 0x1A48B71C, 0xF0976D17, 0x088CE80A, 0xA454EDF3,
96 0x1C096BF4, 0xAC76224B, 0x5215781C, 0xCD5D2669
100 uint32_t shabal224_iv[] PROGMEM = {
102 0xA5201467, 0xA9B8D94A, 0xD4CED997, 0x68379D7B,
103 0xA7FC73BA, 0xF1A2546B, 0x606782BF, 0xE0BCFD0F,
104 0x2F25374E, 0x069A149F, 0x5E2DFF25, 0xFAECF061,
106 0xEC9905D8, 0xF21850CF, 0xC0A746C8, 0x21DAD498,
107 0x35156EEB, 0x088C97F2, 0x26303E40, 0x8A2D4FB5,
108 0xFEEE44B6, 0x8A1E9573, 0x7B81111A, 0xCBC139F0,
109 0xA3513861, 0x1D2C362E, 0x918C580E, 0xB58E1B9C,
111 0xE4B573A1, 0x4C1A0880, 0x1E907C51, 0x04807EFD,
112 0x3AD8CDE5, 0x16B21302, 0x02512C53, 0x2204CB18,
113 0x99405F2D, 0xE5B648A1, 0x70AB1D43, 0xA10C25C2,
114 0x16F1AC05, 0x38BBEB56, 0x9B01DC60, 0xB1096D83
117 uint32_t shabal256_iv[] PROGMEM = {
119 0x52F84552, 0xE54B7999, 0x2D8EE3EC, 0xB9645191,
120 0xE0078B86, 0xBB7C44C9, 0xD2B5C1CA, 0xB0D2EB8C,
121 0x14CE5A45, 0x22AF50DC, 0xEFFDBC6B, 0xEB21B74A,
123 0xB555C6EE, 0x3E710596, 0xA72A652F, 0x9301515F,
124 0xDA28C1FA, 0x696FD868, 0x9CB6BF72, 0x0AFE4002,
125 0xA6E03615, 0x5138C1D4, 0xBE216306, 0xB38B8890,
126 0x3EA8B96B, 0x3299ACE4, 0x30924DD4, 0x55CB34A5,
128 0xB405F031, 0xC4233EBA, 0xB3733979, 0xC0DD9D55,
129 0xC51C28AE, 0xA327B8E1, 0x56C56167, 0xED614433,
130 0x88B59D60, 0x60E2CEBA, 0x758B4B8B, 0x83E82A7F,
131 0xBC968828, 0xE6E00BF7, 0xBA839E55, 0x9B491C60
134 uint32_t shabal384_iv[] PROGMEM = {
136 0xC8FCA331, 0xE55C504E, 0x003EBF26, 0xBB6B8D83,
137 0x7B0448C1, 0x41B82789, 0x0A7C9601, 0x8D659CFF,
138 0xB6E2673E, 0xCA54C77B, 0x1460FD7E, 0x3FCB8F2D,
140 0x527291FC, 0x2A16455F, 0x78E627E5, 0x944F169F,
141 0x1CA6F016, 0xA854EA25, 0x8DB98ABE, 0xF2C62641,
142 0x30117DCB, 0xCF5C4309, 0x93711A25, 0xF9F671B8,
143 0xB01D2116, 0x333F4B89, 0xB285D165, 0x86829B36,
145 0xF764B11A, 0x76172146, 0xCEF6934D, 0xC6D28399,
146 0xFE095F61, 0x5E6018B4, 0x5048ECF5, 0x51353261,
147 0x6E6E36DC, 0x63130DAD, 0xA9C69BD6, 0x1E90EA0C,
148 0x7C35073B, 0x28D95E6D, 0xAA340E0D, 0xCB3DEE70
151 uint32_t shabal512_iv[] PROGMEM = {
153 0x20728DFD, 0x46C0BD53, 0xE782B699, 0x55304632,
154 0x71B4EF90, 0x0EA9E82C, 0xDBB930F1, 0xFAD06B8B,
155 0xBE0CAE40, 0x8BD14410, 0x76D2ADAC, 0x28ACAB7F,
157 0xC1099CB7, 0x07B385F3, 0xE7442C26, 0xCC8AD640,
158 0xEB6F56C7, 0x1EA81AA9, 0x73B9D314, 0x1DE85D08,
159 0x48910A5A, 0x893B22DB, 0xC5A0DF44, 0xBBC4324E,
160 0x72D2F240, 0x75941D99, 0x6D8BDE82, 0xA1A7502B,
162 0xD9BF68D1, 0x58BAD750, 0x56028CB2, 0x8134F359,
163 0xB5D469D8, 0x941A8CC2, 0x418B2A6E, 0x04052780,
164 0x7F07D787, 0x5194358F, 0x3C60D665, 0xBE97D79A,
165 0x950C3434, 0xAED9A06D, 0x2537DC8D, 0x7CDB5969,
168 void shabal192_init(shabal_ctx_t* ctx){
170 ctx->b = ctx->b_buffer;
171 ctx->c = ctx->c_buffer;
173 for(i=0;i<SHABAL_R;++i){
174 ctx->a[i] = pgm_read_dword(&(shabal192_iv[i]));
177 ctx->b[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+i]));
180 ctx->c[i] = pgm_read_dword(&(shabal192_iv[SHABAL_R+16+i]));
184 void shabal224_init(shabal_ctx_t* ctx){
186 ctx->b = ctx->b_buffer;
187 ctx->c = ctx->c_buffer;
189 for(i=0;i<SHABAL_R;++i){
190 ctx->a[i] = pgm_read_dword(&(shabal224_iv[i]));
193 ctx->b[i] = pgm_read_dword(&(shabal224_iv[SHABAL_R+i]));
196 ctx->c[i] = pgm_read_dword(&(shabal224_iv[SHABAL_R+16+i]));
199 void shabal256_init(shabal_ctx_t* ctx){
201 ctx->b = ctx->b_buffer;
202 ctx->c = ctx->c_buffer;
204 for(i=0;i<SHABAL_R;++i){
205 ctx->a[i] = pgm_read_dword(&(shabal256_iv[i]));
208 ctx->b[i] = pgm_read_dword(&(shabal256_iv[SHABAL_R+i]));
211 ctx->c[i] = pgm_read_dword(&(shabal256_iv[SHABAL_R+16+i]));
214 void shabal384_init(shabal_ctx_t* ctx){
216 ctx->b = ctx->b_buffer;
217 ctx->c = ctx->c_buffer;
219 for(i=0;i<SHABAL_R;++i){
220 ctx->a[i] = pgm_read_dword(&(shabal384_iv[i]));
223 ctx->b[i] = pgm_read_dword(&(shabal384_iv[SHABAL_R+i]));
226 ctx->c[i] = pgm_read_dword(&(shabal384_iv[SHABAL_R+16+i]));
229 void shabal512_init(shabal_ctx_t* ctx){
231 ctx->b = ctx->b_buffer;
232 ctx->c = ctx->c_buffer;
234 for(i=0;i<SHABAL_R;++i){
235 ctx->a[i] = pgm_read_dword(&(shabal512_iv[i]));
238 ctx->b[i] = pgm_read_dword(&(shabal512_iv[SHABAL_R+i]));
241 ctx->c[i] = pgm_read_dword(&(shabal512_iv[SHABAL_R+16+i]));
245 void shabal_nextBlock(shabal_ctx_t* ctx, const void* block){
249 ctx->b[i] += ((uint32_t*)block)[i];
251 ctx->a[0] ^= ctx->w.w32[0];
252 ctx->a[1] ^= ctx->w.w32[1];
253 shabal_p(ctx, block);
255 ctx->c[i] -= ((uint32_t*)block)[i];
263 void shabal_lastBlock(shabal_ctx_t* ctx, const void* block, uint16_t length_b){
267 while(length_b>=SHABAL_BLOCKSIZE){
268 shabal_nextBlock(ctx, block);
269 block = (uint8_t*)block + SHABAL_BLOCKSIZE_B;
270 length_b -= SHABAL_BLOCKSIZE;
272 memset(buffer, 0, 64);
273 memcpy(buffer, block, (length_b+7)/8);
274 buffer[length_b/8] |= 0x80>>(length_b%8);
277 ctx->b[i] += ((uint32_t*)buffer)[i];
279 ctx->a[0] ^= ctx->w.w32[0];
280 ctx->a[1] ^= ctx->w.w32[1];
281 shabal_p(ctx, buffer);
287 ctx->a[0] ^= ctx->w.w32[0];
288 ctx->a[1] ^= ctx->w.w32[1];
289 shabal_p(ctx, buffer);
298 void shabal_ctx2hash(void* dest, const shabal_ctx_t* ctx, uint16_t outlength_b){
299 memcpy(dest, &(ctx->c[16-outlength_b/32]), outlength_b/8);
302 void shabal192_ctx2hash(void* dest, const shabal_ctx_t* ctx){
303 shabal_ctx2hash(dest, ctx, 192);
306 void shabal224_ctx2hash(void* dest, const shabal_ctx_t* ctx){
307 shabal_ctx2hash(dest, ctx, 224);
310 void shabal256_ctx2hash(void* dest, const shabal_ctx_t* ctx){
311 shabal_ctx2hash(dest, ctx, 256);
314 void shabal384_ctx2hash(void* dest, const shabal_ctx_t* ctx){
315 shabal_ctx2hash(dest, ctx, 384);
318 void shabal512_ctx2hash(void* dest, const shabal_ctx_t* ctx){
319 shabal_ctx2hash(dest, ctx, 512);
322 void shabal192(void* dest, void* msg, uint32_t length_b){
324 shabal192_init(&ctx);
325 while(length_b>=SHABAL_BLOCKSIZE){
326 shabal_nextBlock(&ctx, msg);
327 msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
328 length_b -= SHABAL_BLOCKSIZE;
330 shabal_lastBlock(&ctx, msg, length_b);
331 shabal192_ctx2hash(dest, &ctx);
334 void shabal224(void* dest, void* msg, uint32_t length_b){
336 shabal224_init(&ctx);
337 while(length_b>=SHABAL_BLOCKSIZE){
338 shabal_nextBlock(&ctx, msg);
339 msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
340 length_b -= SHABAL_BLOCKSIZE;
342 shabal_lastBlock(&ctx, msg, length_b);
343 shabal224_ctx2hash(dest, &ctx);
346 void shabal256(void* dest, void* msg, uint32_t length_b){
348 shabal256_init(&ctx);
349 while(length_b>=SHABAL_BLOCKSIZE){
350 shabal_nextBlock(&ctx, msg);
351 msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
352 length_b -= SHABAL_BLOCKSIZE;
354 shabal_lastBlock(&ctx, msg, length_b);
355 shabal256_ctx2hash(dest, &ctx);
358 void shabal384(void* dest, void* msg, uint32_t length_b){
360 shabal384_init(&ctx);
361 while(length_b>=SHABAL_BLOCKSIZE){
362 shabal_nextBlock(&ctx, msg);
363 msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
364 length_b -= SHABAL_BLOCKSIZE;
366 shabal_lastBlock(&ctx, msg, length_b);
367 shabal384_ctx2hash(dest, &ctx);
370 void shabal512(void* dest, void* msg, uint32_t length_b){
372 shabal512_init(&ctx);
373 while(length_b>=SHABAL_BLOCKSIZE){
374 shabal_nextBlock(&ctx, msg);
375 msg = (uint8_t*)msg+SHABAL_BLOCKSIZE_B;
376 length_b -= SHABAL_BLOCKSIZE;
378 shabal_lastBlock(&ctx, msg, length_b);
379 shabal512_ctx2hash(dest, &ctx);