2 * Written in 2013 by Gregor Pintar <grpintar@gmail.com>
4 * To the extent possible under law, the author(s) have dedicated
5 * all copyright and related and neighboring rights to this software
6 * to the public domain worldwide.
8 * This software is distributed without any warranty.
10 * You should have received a copy of the CC0 Public Domain Dedication.
11 * If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
20 #include <kripto/cast.h>
21 #include <kripto/loadstore.h>
22 #include <kripto/memwipe.h>
23 #include <kripto/block.h>
24 #include <kripto/block/threefish256.h>
25 #include <kripto/hash.h>
26 #include <kripto/desc/hash.h>
27 #include <kripto/object/hash.h>
29 #include <kripto/hash/skein256.h>
33 struct kripto_hash_object obj
;
43 #define POS_ADD(TWEAK, ADD) \
63 static void skein256_process(kripto_hash
*s
)
67 (void)kripto_block_recreate(s
->block
, s
->r
, s
->h
, 32);
68 kripto_block_tweak(s
->block
, s
->tweak
, 16);
69 kripto_block_encrypt(s
->block
, s
->buf
, s
->h
);
71 for(i
= 0; i
< 32; i
++) s
->h
[i
] ^= s
->buf
[i
];
74 static kripto_hash
*skein256_recreate
87 memset(s
->tweak
, 0, 16);
100 STORE64L(t
, s
->buf
+ 8);
101 memset(s
->buf
+ 16, 0, 16);
103 s
->tweak
[15] = 0xC4; /* type CFG, first, final */
108 s
->tweak
[15] = 0x70; /* type MSG, first */
113 static void skein256_input
122 for(i
= 0; i
< len
; i
++)
124 s
->buf
[s
->i
++] = CU8(in
)[i
];
128 POS_ADD(s
->tweak
, 32);
131 s
->tweak
[15] = 0x30; /* type MSG */
137 static void skein256_finish(kripto_hash
*s
)
139 POS_ADD(s
->tweak
, s
->i
);
141 memset(s
->buf
+ s
->i
, 0, 32 - s
->i
);
142 s
->tweak
[15] |= 0x80; /* add final */
145 memset(s
->buf
, 0, 32);
146 memset(s
->tweak
, 0, 12);
147 s
->tweak
[0] = 8; /* 8 byte counter */
148 s
->tweak
[15] = 0xFF; /* type OUT, first, final */
155 static void skein256_output(kripto_hash
*s
, void *out
, size_t len
)
157 assert(s
->i
+ len
<= 32);
159 if(!s
->f
) skein256_finish(s
);
161 memcpy(out
, s
->h
+ s
->i
, len
);
165 static kripto_hash
*skein256_create(unsigned int r
, size_t len
)
169 s
= malloc(sizeof(kripto_hash
));
172 s
->obj
.desc
= kripto_hash_skein256
;
174 s
->block
= kripto_block_create(kripto_block_threefish256
, r
, "", 1);
181 (void)skein256_recreate(s
, r
, len
);
186 static void skein256_destroy(kripto_hash
*s
)
188 kripto_block_destroy(s
->block
);
189 kripto_memwipe(s
, sizeof(kripto_hash
));
193 static int skein256_hash
204 s
.block
= kripto_block_create(kripto_block_threefish256
, r
, "", 1);
205 if(!s
.block
) return -1;
207 (void)skein256_recreate(&s
, r
, out_len
);
208 skein256_input(&s
, in
, in_len
);
209 skein256_output(&s
, out
, out_len
);
211 kripto_block_destroy(s
.block
);
212 kripto_memwipe(&s
, sizeof(kripto_hash
));
217 static const kripto_hash_desc skein256
=
229 const kripto_hash_desc
*const kripto_hash_skein256
= &skein256
;