]> git.cryptolib.org Git - avr-crypto-lib.git/blob - blake/blake_large.c
bug fixing and support for malloc instead of stack memory (some functions)
[avr-crypto-lib.git] / blake / blake_large.c
1 /* blake_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    blake_large.c
21  * \author  Daniel Otte
22  * \email   daniel.otte@rub.de
23  * \date    2009-05-08
24  * \license GPLv3 or later
25  *
26  */
27
28 #include <stdint.h>
29 #include <string.h>
30 #include <avr/pgmspace.h>
31 #include "memxor.h"
32 #include "blake_large.h"
33 #include "blake_common.h"
34
35 static uint64_t pgm_read_qword(const void *p)
36 {
37     union {
38         uint64_t v64;
39         uint32_t v32[2];
40     } r;
41     r.v32[0] = pgm_read_dword(p);
42     r.v32[1] = pgm_read_dword((uint8_t* )p + 4);
43     return r.v64;
44 }
45
46 static const uint64_t blake_c[] PROGMEM = {
47         0x243F6A8885A308D3LL, 0x13198A2E03707344LL,
48         0xA4093822299F31D0LL, 0x082EFA98EC4E6C89LL,
49         0x452821E638D01377LL, 0xBE5466CF34E90C6CLL,
50         0xC0AC29B7C97C50DDLL, 0x3F84D5B5B5470917LL,
51         0x9216D5D98979FB1BLL, 0xD1310BA698DFB5ACLL,
52         0x2FFD72DBD01ADFB7LL, 0xB8E1AFED6A267E96LL,
53         0xBA7C9045F12C7F99LL, 0x24A19947B3916CF7LL,
54         0x0801F2E2858EFC16LL, 0x636920D871574E69LL
55 };
56
57 #define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n))))
58 #define ROTR64(a, n) (((a)>>(n))|((a)<<(64-(n))))
59 #define CHANGE_ENDIAN32(a) (((a)<<24)| \
60                             ((0x0000ff00&(a))<<8)| \
61                                                     ((0x00ff0000&(a))>>8)| \
62                                                     (a)>>24 )
63
64 static
65 void blake_large_expand(uint64_t *v, const blake_large_ctx_t *ctx)
66 {
67     uint8_t i;
68     memcpy(v, ctx->h, 8 * 8);
69     for (i = 0; i < 8; ++i) {
70         v[8 + i] = pgm_read_qword(&(blake_c[i]));
71     }
72     memxor((uint8_t*) v + 8, ctx->s, 4 * 8);
73
74 }
75
76 static
77 void blake_large_changeendian(void *dest, const void *src)
78 {
79     uint8_t i;
80     uint32_t tmp;
81     for (i = 0; i < 32; i += 2) {
82         tmp = CHANGE_ENDIAN32(((uint32_t* )src)[i]);
83         ((uint32_t*) dest)[i] = CHANGE_ENDIAN32(((uint32_t* )src)[i + 1]);
84         ((uint32_t*) dest)[i + 1] = tmp;
85     }
86 }
87
88 static
89 void blake_large_compress(uint64_t *v, const void *m)
90 {
91     uint8_t r, i;
92     uint8_t a, b, c, d, s0, s1, sigma_idx = 0;
93     for (r = 0; r < 16; ++r) {
94         for (i = 0; i < 8; ++i) {
95             a = pgm_read_byte(blake_index_lut + 4 * i + 0);
96             b = pgm_read_byte(blake_index_lut + 4 * i + 1);
97             c = pgm_read_byte(blake_index_lut + 4 * i + 2);
98             d = pgm_read_byte(blake_index_lut + 4 * i + 3);
99             s0 = pgm_read_byte(blake_sigma + sigma_idx);
100             s1 = s0 & 0x0f;
101             s0 >>= 4;
102             ++sigma_idx;
103             if (sigma_idx >= 80) {
104                 sigma_idx -= 80;
105             }
106             v[a] += v[b]
107                     + (((uint64_t*) m)[s0] ^ pgm_read_qword(&(blake_c[s1])));
108             v[d] = ROTR64(v[d] ^ v[a], 32);
109             v[c] += v[d];
110             v[b] = ROTR64(v[b] ^ v[c], 25);
111             v[a] += v[b]
112                     + (((uint64_t*) m)[s1] ^ pgm_read_qword(&(blake_c[s0])));
113             v[d] = ROTR64(v[d] ^ v[a], 16);
114             v[c] += v[d];
115             v[b] = ROTR64(v[b] ^ v[c], 11);
116         }
117     }
118 }
119
120 static
121 void blake_large_collapse(blake_large_ctx_t *ctx, uint64_t *v)
122 {
123     uint8_t i;
124     for (i = 0; i < 8; ++i) {
125         ctx->h[i] ^= ctx->s[i % 4] ^ v[i] ^ v[8 + i];
126     }
127 }
128
129 void blake_large_nextBlock(blake_large_ctx_t *ctx, const void *msg)
130 {
131     uint64_t v[16];
132     uint64_t m[16];
133     union {
134         uint64_t v64;
135         uint32_t v32[2];
136     } ctr;
137     blake_large_expand(v, ctx);
138     ctx->counter++;
139     ctr.v64 = ctx->counter * 1024;
140     v[12] ^= ctr.v64;
141     v[13] ^= ctr.v64;
142     blake_large_changeendian(m, msg);
143     blake_large_compress(v, m);
144     blake_large_collapse(ctx, v);
145 }
146
147 void blake_large_lastBlock(blake_large_ctx_t *ctx, const void *msg,
148         uint16_t length_b)
149 {
150     while (length_b >= BLAKE_LARGE_BLOCKSIZE) {
151         blake_large_nextBlock(ctx, msg);
152         msg = (uint8_t*) msg + BLAKE_LARGE_BLOCKSIZE_B;
153         length_b -= BLAKE_LARGE_BLOCKSIZE;
154     }
155     union {
156         uint8_t v8[128];
157         uint64_t v64[16];
158     } buffer;
159     uint64_t v[16];
160     uint64_t ctr;
161     ctr = ctx->counter * 1024 + length_b;
162     memset(buffer.v8, 0, 128);
163     memcpy(buffer.v8, msg, (length_b + 7) / 8);
164     buffer.v8[length_b / 8] |= 0x80 >> (length_b & 0x7);
165     blake_large_changeendian(buffer.v8, buffer.v8);
166     blake_large_expand(v, ctx);
167     if (length_b > 1024 - 128 - 2) {
168         v[12] ^= ctr;
169         v[13] ^= ctr;
170         blake_large_compress(v, buffer.v8);
171         blake_large_collapse(ctx, v);
172         memset(buffer.v8, 0, 128 - 8);
173         blake_large_expand(v, ctx);
174     } else {
175         if (length_b) {
176             v[12] ^= ctr;
177             v[13] ^= ctr;
178         }
179     }
180     if (ctx->appendone)
181         buffer.v8[128 - 16 - 8] |= 0x01;
182     buffer.v64[15] = ctr;
183     blake_large_compress(v, buffer.v8);
184     blake_large_collapse(ctx, v);
185
186 }
187
188 const uint64_t blake512_iv[] PROGMEM = {
189         0x6A09E667F3BCC908LL, 0xBB67AE8584CAA73BLL,
190         0x3C6EF372FE94F82BLL, 0xA54FF53A5F1D36F1LL,
191         0x510E527FADE682D1LL, 0x9B05688C2B3E6C1FLL,
192         0x1F83D9ABFB41BD6BLL, 0x5BE0CD19137E2179LL
193 };
194
195 void blake512_init(blake512_ctx_t *ctx)
196 {
197     uint8_t i;
198     for (i = 0; i < 8; ++i) {
199         ctx->h[i] = pgm_read_qword(&(blake512_iv[i]));
200     }
201     memset(ctx->s, 0, 4 * 8);
202     ctx->counter = 0;
203     ctx->appendone = 1;
204 }
205
206 const uint64_t blake384_iv[] PROGMEM = {
207         0xCBBB9D5DC1059ED8LL, 0x629A292A367CD507LL,
208         0x9159015A3070DD17LL, 0x152FECD8F70E5939LL,
209         0x67332667FFC00B31LL, 0x8EB44A8768581511LL,
210         0xDB0C2E0D64F98FA7LL, 0x47B5481DBEFA4FA4LL
211 };
212
213 void blake384_init(blake384_ctx_t *ctx)
214 {
215     uint8_t i;
216     for (i = 0; i < 8; ++i) {
217         ctx->h[i] = pgm_read_qword(&(blake384_iv[i]));
218     }
219     memset(ctx->s, 0, 4 * 8);
220     ctx->counter = 0;
221     ctx->appendone = 0;
222 }
223
224 void blake512_ctx2hash(void *dest, const blake512_ctx_t *ctx)
225 {
226     uint8_t i;
227     for (i = 0; i < 8; ++i) {
228         ((uint32_t*) dest)[2 * i + 0] = CHANGE_ENDIAN32((ctx->h[i]) >> 32);
229         ((uint32_t*) dest)[2 * i + 1] = CHANGE_ENDIAN32((uint32_t )ctx->h[i]);
230     }
231 }
232
233 void blake384_ctx2hash(void *dest, const blake384_ctx_t *ctx)
234 {
235     uint8_t i;
236     for (i = 0; i < 6; ++i) {
237         ((uint32_t*) dest)[2 * i + 0] = CHANGE_ENDIAN32((ctx->h[i]) >> 32);
238         ((uint32_t*) dest)[2 * i + 1] = CHANGE_ENDIAN32((uint32_t )ctx->h[i]);
239     }
240 }
241
242 void blake512_nextBlock(blake512_ctx_t *ctx, const void *block)
243 {
244     blake_large_nextBlock(ctx, block);
245 }
246
247 void blake384_nextBlock(blake384_ctx_t *ctx, const void *block)
248 {
249     blake_large_nextBlock(ctx, block);
250 }
251
252 void blake512_lastBlock(blake512_ctx_t *ctx, const void *block,
253         uint16_t length_b)
254 {
255     blake_large_lastBlock(ctx, block, length_b);
256 }
257
258 void blake384_lastBlock(blake384_ctx_t *ctx, const void *block,
259         uint16_t length_b)
260 {
261     blake_large_lastBlock(ctx, block, length_b);
262 }
263
264 void blake512(void *dest, const void *msg, uint32_t length_b)
265 {
266     blake_large_ctx_t ctx;
267     blake512_init(&ctx);
268     while (length_b >= BLAKE_LARGE_BLOCKSIZE) {
269         blake_large_nextBlock(&ctx, msg);
270         msg = (uint8_t*) msg + BLAKE_LARGE_BLOCKSIZE_B;
271         length_b -= BLAKE_LARGE_BLOCKSIZE;
272     }
273     blake_large_lastBlock(&ctx, msg, length_b);
274     blake512_ctx2hash(dest, &ctx);
275 }
276
277 void blake384(void *dest, const void *msg, uint32_t length_b)
278 {
279     blake_large_ctx_t ctx;
280     blake384_init(&ctx);
281     while (length_b >= BLAKE_LARGE_BLOCKSIZE) {
282         blake_large_nextBlock(&ctx, msg);
283         msg = (uint8_t*) msg + BLAKE_LARGE_BLOCKSIZE_B;
284         length_b -= BLAKE_LARGE_BLOCKSIZE;
285     }
286     blake_large_lastBlock(&ctx, msg, length_b);
287     blake384_ctx2hash(dest, &ctx);
288 }