blake_small.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /* blake_small.c */
  2. /*
  3. This file is part of the ARM-Crypto-Lib.
  4. Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. /*
  17. * \file blake_small.c
  18. * \author Daniel Otte
  19. * \email daniel.otte@rub.de
  20. * \date 2009-05-04
  21. * \license GPLv3 or later
  22. *
  23. */
  24. #include <stdint.h>
  25. #include <string.h>
  26. #include <crypto/memxor.h>
  27. #include <crypto/blake_small.h>
  28. #include <crypto/blake_common.h>
  29. static const
  30. uint32_t blake_c[] = {
  31. 0x243F6A88, 0x85A308D3,
  32. 0x13198A2E, 0x03707344,
  33. 0xA4093822, 0x299F31D0,
  34. 0x082EFA98, 0xEC4E6C89,
  35. 0x452821E6, 0x38D01377,
  36. 0xBE5466CF, 0x34E90C6C,
  37. 0xC0AC29B7, 0xC97C50DD,
  38. 0x3F84D5B5, 0xB5470917
  39. };
  40. #define ROTL32(a, n) (((a)<<(n))|((a)>>(32-(n))))
  41. #define ROTR32(a, n) (((a)>>(n))|((a)<<(32-(n))))
  42. #define CHANGE_ENDIAN32(a) (((a)<<24)| \
  43. ((0x0000ff00&(a))<<8)| \
  44. ((0x00ff0000&(a))>>8)| \
  45. (a)>>24 )
  46. static
  47. void blake_small_expand(uint32_t* v, const blake_small_ctx_t* ctx){
  48. uint8_t i;
  49. memcpy(v, ctx->h, 8*4);
  50. for(i=0; i<8; ++i){
  51. v[8+i] = blake_c[i];
  52. }
  53. memxor((uint8_t*)v+8, ctx->s, 4*4);
  54. }
  55. static
  56. void blake_small_changeendian(void* dest, const void* src){
  57. uint8_t i;
  58. for(i=0; i<16; ++i){
  59. ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(((uint32_t*)src)[i]);
  60. }
  61. }
  62. #define A (v[idx.v8[0]])
  63. #define B (v[idx.v8[1]])
  64. #define C (v[idx.v8[2]])
  65. #define D (v[idx.v8[3]])
  66. static
  67. void blake_small_compress(uint32_t* v,const void* m){
  68. uint8_t r,i;
  69. uint16_t s, *p=(uint16_t*)blake_sigma;
  70. union {
  71. uint32_t v32;
  72. uint8_t v8[4];
  73. } idx;
  74. for(r=0; r<14; ++r){
  75. for(i=0; i<8; ++i){
  76. idx.v32 = ((uint32_t*)blake_index_lut)[i];
  77. s = *p++;
  78. if(p==(uint16_t*)(blake_sigma+160)){
  79. p=(uint16_t*)blake_sigma;
  80. }
  81. A += B + (((uint32_t*)m)[s&0xff] ^ blake_c[s>>8]);
  82. D = ROTR32(A^D, 16);
  83. C += D;
  84. B = ROTR32(B^C, 12);
  85. A += B + (((uint32_t*)m)[s>>8] ^ blake_c[s&0xff]);
  86. D = ROTR32(A^D, 8);
  87. C += D;
  88. B = ROTR32(B^C, 7);
  89. }
  90. }
  91. }
  92. static
  93. void blake_small_collapse(blake_small_ctx_t* ctx, uint32_t* v){
  94. uint8_t i;
  95. for(i=0; i<8; ++i){
  96. ctx->h[i] ^= ctx->s[i%4] ^ v[i] ^ v[8+i];
  97. }
  98. }
  99. void blake_small_nextBlock(blake_small_ctx_t* ctx, const void* msg){
  100. uint32_t v[16];
  101. uint32_t m[16];
  102. union {
  103. uint64_t v64;
  104. uint32_t v32[2];
  105. }ctr;
  106. blake_small_expand(v,ctx);
  107. ctx->counter++;
  108. ctr.v64 = ctx->counter*512;
  109. v[12] ^= ctr.v32[0];
  110. v[13] ^= ctr.v32[0];
  111. v[14] ^= ctr.v32[1];
  112. v[15] ^= ctr.v32[1];
  113. blake_small_changeendian(m, msg);
  114. blake_small_compress(v, m);
  115. blake_small_collapse(ctx, v);
  116. }
  117. void blake_small_lastBlock(blake_small_ctx_t* ctx, const void* msg, uint16_t length_b){
  118. while(length_b>=BLAKE_SMALL_BLOCKSIZE){
  119. blake_small_nextBlock(ctx, msg);
  120. msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
  121. length_b -= BLAKE_SMALL_BLOCKSIZE;
  122. }
  123. union {
  124. uint8_t v8[64];
  125. uint32_t v32[16];
  126. uint64_t v64[ 8];
  127. } buffer;
  128. uint32_t v[16];
  129. union {
  130. uint64_t v64;
  131. uint32_t v32[2];
  132. }ctr;
  133. ctr.v64 = ctx->counter*512+length_b;
  134. memset(buffer.v8, 0, 64);
  135. memcpy(buffer.v8, msg, (length_b+7)/8);
  136. buffer.v8[length_b/8] |= 0x80 >> (length_b&0x7);
  137. blake_small_changeendian(buffer.v8, buffer.v8);
  138. blake_small_expand(v, ctx);
  139. if(length_b>512-64-2){
  140. v[12] ^= ctr.v32[0];
  141. v[13] ^= ctr.v32[0];
  142. v[14] ^= ctr.v32[1];
  143. v[15] ^= ctr.v32[1];
  144. blake_small_compress(v, buffer.v8);
  145. blake_small_collapse(ctx, v);
  146. memset(buffer.v8, 0, 64-8);
  147. blake_small_expand(v, ctx);
  148. }else{
  149. if(length_b){
  150. v[12] ^= ctr.v32[0];
  151. v[13] ^= ctr.v32[0];
  152. v[14] ^= ctr.v32[1];
  153. v[15] ^= ctr.v32[1];
  154. }
  155. }
  156. if(ctx->appendone)
  157. buffer.v8[64-8-4] |= 0x01;
  158. buffer.v32[14] = ctr.v32[1];
  159. buffer.v32[15] = ctr.v32[0];
  160. blake_small_compress(v, buffer.v8);
  161. blake_small_collapse(ctx, v);
  162. }
  163. static const
  164. uint32_t blake256_iv[] = {
  165. 0x6A09E667L, 0xBB67AE85,
  166. 0x3C6EF372L, 0xA54FF53A,
  167. 0x510E527FL, 0x9B05688C,
  168. 0x1F83D9ABL, 0x5BE0CD19
  169. };
  170. void blake256_init(blake256_ctx_t* ctx){
  171. uint8_t i;
  172. for(i=0; i<8; ++i){
  173. ctx->h[i] = blake256_iv[i];
  174. }
  175. memset(ctx->s, 0, 4*4);
  176. ctx->counter = 0;
  177. ctx->appendone = 1;
  178. }
  179. static const
  180. uint32_t blake224_iv[] = {
  181. 0xC1059ED8, 0x367CD507,
  182. 0x3070DD17, 0xF70E5939,
  183. 0xFFC00B31, 0x68581511,
  184. 0x64F98FA7, 0xBEFA4FA4
  185. };
  186. void blake224_init(blake224_ctx_t* ctx){
  187. uint8_t i;
  188. for(i=0; i<8; ++i){
  189. ctx->h[i] = blake224_iv[i];
  190. }
  191. memset(ctx->s, 0, 4*4);
  192. ctx->counter = 0;
  193. ctx->appendone = 0;
  194. }
  195. void blake256_ctx2hash(void* dest, const blake256_ctx_t* ctx){
  196. uint8_t i;
  197. for(i=0; i<8; ++i){
  198. ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(ctx->h[i]);
  199. }
  200. }
  201. void blake224_ctx2hash(void* dest, const blake224_ctx_t* ctx){
  202. uint8_t i;
  203. for(i=0; i<7; ++i){
  204. ((uint32_t*)dest)[i] = CHANGE_ENDIAN32(ctx->h[i]);
  205. }
  206. }
  207. void blake256_nextBlock(blake256_ctx_t* ctx, const void* block){
  208. blake_small_nextBlock(ctx, block);
  209. }
  210. void blake224_nextBlock(blake224_ctx_t* ctx, const void* block){
  211. blake_small_nextBlock(ctx, block);
  212. }
  213. void blake256_lastBlock(blake256_ctx_t* ctx, const void* block, uint16_t length_b){
  214. blake_small_lastBlock(ctx, block, length_b);
  215. }
  216. void blake224_lastBlock(blake224_ctx_t* ctx, const void* block, uint16_t length_b){
  217. blake_small_lastBlock(ctx, block, length_b);
  218. }
  219. void blake256(void* dest, const void* msg, uint32_t length_b){
  220. blake_small_ctx_t ctx;
  221. blake256_init(&ctx);
  222. while(length_b>=BLAKE_SMALL_BLOCKSIZE){
  223. blake_small_nextBlock(&ctx, msg);
  224. msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
  225. length_b -= BLAKE_SMALL_BLOCKSIZE;
  226. }
  227. blake_small_lastBlock(&ctx, msg, length_b);
  228. blake256_ctx2hash(dest, &ctx);
  229. }
  230. void blake224(void* dest, const void* msg, uint32_t length_b){
  231. blake_small_ctx_t ctx;
  232. blake224_init(&ctx);
  233. while(length_b>=BLAKE_SMALL_BLOCKSIZE){
  234. blake_small_nextBlock(&ctx, msg);
  235. msg = (uint8_t*)msg + BLAKE_SMALL_BLOCKSIZE_B;
  236. length_b -= BLAKE_SMALL_BLOCKSIZE;
  237. }
  238. blake_small_lastBlock(&ctx, msg, length_b);
  239. blake224_ctx2hash(dest, &ctx);
  240. }