groestl_small.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /* groestl_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 groestl_small.c
  18. * \author Daniel Otte
  19. * \email daniel.otte@rub.de
  20. * \date 2009-05-19
  21. * \license GPLv3 or later
  22. *
  23. */
  24. #include <crypto/groestl_small.h>
  25. #include <crypto/aes_sbox.h>
  26. #include <crypto/gf256mul.h>
  27. #include <crypto/memxor.h>
  28. #include <stdint.h>
  29. #include <string.h>
  30. #define ROUNDS 10
  31. #define POLYNOM 0x1b
  32. #define DEBUG 0
  33. #if DEBUG
  34. #include <crypto/cli.h>
  35. void dump_m(const uint8_t* m){
  36. uint8_t i,j;
  37. for(i=0; i<8; ++i){
  38. cli_putstr("\r\n");
  39. for(j=0; j<8; ++j){
  40. cli_putc(' ');
  41. cli_hexdump(m+8*i+j, 1);
  42. }
  43. }
  44. }
  45. #else
  46. #define dump_m(m)
  47. #endif
  48. static const uint8_t matrix[] = {
  49. 2, 2, 3, 4, 5, 3, 5, 7,
  50. 7, 2, 2, 3, 4, 5, 3, 5,
  51. 5, 7, 2, 2, 3, 4, 5, 3,
  52. 3, 5, 7, 2, 2, 3, 4, 5,
  53. 5, 3, 5, 7, 2, 2, 3, 4,
  54. 4, 5, 3, 5, 7, 2, 2, 3,
  55. 3, 4, 5, 3, 5, 7, 2, 2,
  56. 2, 3, 4, 5, 3, 5, 7, 2
  57. };
  58. static
  59. void shift_columns(uint8_t* a, const uint8_t *shifts){
  60. uint8_t tmp[8];
  61. uint8_t i,j,s;
  62. for(i=0; i<8; ++i){
  63. s = *shifts++;
  64. if(s==0){
  65. continue;
  66. }
  67. for(j=0;j<8;++j){
  68. tmp[j] = a[i+j*8];
  69. }
  70. for(j=0;j<8;++j){
  71. a[i+((j-s+8)%8)*8] = tmp[j];
  72. }
  73. }
  74. }
  75. static const uint8_t p_shifts[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
  76. static const uint8_t q_shifts[8] = { 1, 3, 5, 7, 0, 2, 4, 6 };
  77. static
  78. void groestl_small_rounds(uint8_t *m, uint8_t q){
  79. uint8_t r,i,j;
  80. uint8_t tmp[8];
  81. for(r=0; r<ROUNDS; ++r){
  82. if(q){
  83. for(i=0; i<64/4; ++i){
  84. ((uint32_t*)m)[i] ^= 0xffffffff;
  85. }
  86. for(i=0;i<8; ++i){
  87. m[7+i*8] ^= r ^ (i<<4);
  88. }
  89. }else{
  90. for(i=0;i<8; ++i){
  91. m[i*8] ^= r ^ (i<<4);
  92. }
  93. }
  94. #if DEBUG
  95. if(r<2){
  96. cli_putstr("\r\npost add-const");
  97. dump_m(m);
  98. }
  99. #endif
  100. for(i=0;i<8*8; ++i){
  101. m[i] = aes_sbox[m[i]];
  102. }
  103. if(q){
  104. shift_columns(m, q_shifts);
  105. }else{
  106. shift_columns(m, p_shifts);
  107. }
  108. #if DEBUG
  109. if(r<2){
  110. cli_putstr("\r\npost shift-bytes");
  111. dump_m(m);
  112. }
  113. #endif
  114. for(i=0; i<8; ++i){
  115. memcpy(tmp, m+8*i, 8);
  116. for(j=0; j<8; ++j){
  117. m[j+i*8] = gf256mul(matrix[8*j+0],tmp[0], POLYNOM)
  118. ^ gf256mul(matrix[8*j+1],tmp[1], POLYNOM)
  119. ^ gf256mul(matrix[8*j+2],tmp[2], POLYNOM)
  120. ^ gf256mul(matrix[8*j+3],tmp[3], POLYNOM)
  121. ^ gf256mul(matrix[8*j+4],tmp[4], POLYNOM)
  122. ^ gf256mul(matrix[8*j+5],tmp[5], POLYNOM)
  123. ^ gf256mul(matrix[8*j+6],tmp[6], POLYNOM)
  124. ^ gf256mul(matrix[8*j+7],tmp[7], POLYNOM);
  125. }
  126. }
  127. #if DEBUG
  128. if(r<2){
  129. cli_putstr("\r\npost mix-bytes");
  130. dump_m(m);
  131. }
  132. #endif
  133. }
  134. }
  135. void groestl224_init(groestl224_ctx_t* ctx){
  136. memset(ctx->h, 0, 8*8);
  137. ctx->h[8*8-1] = 224;
  138. ctx->counter = 1;
  139. }
  140. void groestl256_init(groestl256_ctx_t* ctx){
  141. memset(ctx->h, 0, 8*8);
  142. ctx->h[8*8-2] = 1;
  143. ctx->counter = 1;
  144. }
  145. void groestl_small_nextBlock(groestl_small_ctx_t* ctx, const void* block){
  146. uint8_t tmp1[64], tmp2[64];
  147. /* for(i=0; i<8; ++i){
  148. for(j=0; j<8; ++j){
  149. tmp1[j*8+i] = ((uint8_t*)block)[i*8+j];
  150. }
  151. }
  152. */
  153. memcpy(tmp1, block, 64);
  154. memcpy(tmp2, tmp1, 64);
  155. memxor(tmp1, ctx->h, 64);
  156. groestl_small_rounds(tmp1, 0);
  157. groestl_small_rounds(tmp2, 1);
  158. memxor(ctx->h, tmp1, 64);
  159. memxor(ctx->h, tmp2, 64);
  160. ctx->counter++;
  161. }
  162. void groestl_small_lastBlock(groestl_small_ctx_t* ctx, const void* block, uint16_t length_b){
  163. uint8_t buffer[64];
  164. while(length_b>=GROESTL_SMALL_BLOCKSIZE){
  165. groestl_small_nextBlock(ctx, block);
  166. length_b -= GROESTL_SMALL_BLOCKSIZE;
  167. block = (uint8_t*)block + GROESTL_SMALL_BLOCKSIZE_B;
  168. }
  169. memset(buffer, 0, 64);
  170. memcpy(buffer, block, (length_b+7)/8);
  171. buffer[length_b/8] |= 0x80>>(length_b&0x7);
  172. if(length_b>512-65){
  173. groestl_small_nextBlock(ctx, buffer);
  174. memset(buffer, 0, 64-4);
  175. }
  176. // ctx->counter++;
  177. buffer[64-1] = (uint8_t)(ctx->counter);
  178. buffer[64-2] = (uint8_t)((ctx->counter)>>8);
  179. buffer[64-3] = (uint8_t)((ctx->counter)>>16);
  180. buffer[64-4] = (uint8_t)((ctx->counter)>>24);
  181. groestl_small_nextBlock(ctx, buffer);
  182. }
  183. void groestl_small_ctx2hash(void* dest, const groestl_small_ctx_t* ctx, uint16_t outlength_b){
  184. uint8_t tmp[64];
  185. memcpy(tmp, ctx->h, 64);
  186. groestl_small_rounds(tmp, 0);
  187. memxor(tmp, ctx->h, 64);
  188. #if DEBUG
  189. cli_putstr("\r\npost finalisation");
  190. dump_m(tmp);
  191. #endif
  192. memcpy(dest, tmp+64-outlength_b/8, outlength_b/8);
  193. }
  194. void groestl224_ctx2hash(void* dest, const groestl224_ctx_t* ctx){
  195. groestl_small_ctx2hash(dest, ctx, 224);
  196. }
  197. void groestl256_ctx2hash(void* dest, const groestl256_ctx_t* ctx){
  198. groestl_small_ctx2hash(dest, ctx, 256);
  199. }
  200. void groestl224_nextBlock(groestl224_ctx_t* ctx, const void* block){
  201. groestl_small_nextBlock(ctx, block);
  202. }
  203. void groestl256_nextBlock(groestl256_ctx_t* ctx, const void* block){
  204. groestl_small_nextBlock(ctx, block);
  205. }
  206. void groestl224_lastBlock(groestl224_ctx_t* ctx, const void* block, uint16_t length_b){
  207. groestl_small_lastBlock(ctx, block, length_b);
  208. }
  209. void groestl256_lastBlock(groestl256_ctx_t* ctx, const void* block, uint16_t length_b){
  210. groestl_small_lastBlock(ctx, block, length_b);
  211. }
  212. void groestl224(void* dest, const void* msg, uint32_t length_b){
  213. groestl_small_ctx_t ctx;
  214. groestl224_init(&ctx);
  215. while(length_b>=GROESTL_SMALL_BLOCKSIZE){
  216. groestl_small_nextBlock(&ctx, msg);
  217. length_b -= GROESTL_SMALL_BLOCKSIZE;
  218. msg = (uint8_t*)msg + GROESTL_SMALL_BLOCKSIZE_B;
  219. }
  220. groestl_small_lastBlock(&ctx, msg, length_b);
  221. groestl_small_ctx2hash(dest, &ctx, 224);
  222. }
  223. void groestl256(void* dest, const void* msg, uint32_t length_b){
  224. groestl_small_ctx_t ctx;
  225. groestl256_init(&ctx);
  226. while(length_b>=GROESTL_SMALL_BLOCKSIZE){
  227. groestl_small_nextBlock(&ctx, msg);
  228. length_b -= GROESTL_SMALL_BLOCKSIZE;
  229. msg = (uint8_t*)msg + GROESTL_SMALL_BLOCKSIZE_B;
  230. }
  231. groestl_small_lastBlock(&ctx, msg, length_b);
  232. groestl_small_ctx2hash(dest, &ctx, 256);
  233. }