cubehash.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* cubehash.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 cubehash.c
  18. * \email daniel.otte@rub.de
  19. * \author Daniel Otte
  20. * \date 2010-02-20
  21. * \license GPLv3 or later
  22. *
  23. */
  24. #include <crypto/memxor.h>
  25. #include <crypto/cubehash.h>
  26. #include <string.h>
  27. #include <stdint.h>
  28. inline
  29. static uint32_t rol32(uint32_t a, uint8_t r){
  30. return (a<<r)|(a>>(32-r));
  31. }
  32. /*
  33. • Add x_0jklm into x_1jklm modulo 2**32 , for each (j, k, l, m).
  34. • Rotate x_0jklm upwards by 7 bits, for each (j, k, l, m).
  35. • Swap x_00klm with x_01klm , for each (k, l, m).
  36. • Xor x_1jklm into x_0jklm , for each (j, k, l, m).
  37. • Swap x_1jk0m with x_1jk1m , for each (j, k, m).
  38. • Add x_0jklm into x_1jklm modulo 2**32 , for each (j, k, l, m).
  39. • Rotate x_0jklm upwards by 11 bits, for each (j, k, l, m).
  40. • Swap x_0j0lm with x_0j1lm , for each (j, l, m).
  41. • Xor x_1jklm into x_0jklm , for each (j, k, l, m).
  42. • Swap x_1jkl0 with x_1jkl1 , for each (j, k, l).
  43. */
  44. static void cubehash_round(cubehash_ctx_t* ctx){
  45. uint8_t i;
  46. uint32_t t;
  47. for(i=0; i<16; ++i){
  48. ctx->a[i+16] += ctx->a[i];
  49. ctx->a[i] = rol32(ctx->a[i], 7);
  50. }
  51. for(i=0; i<8; ++i){
  52. t = ctx->a[i];
  53. ctx->a[i] = ctx->a[i+8];
  54. ctx->a[i+8] = t;
  55. }
  56. for(i=0; i<16; ++i){
  57. ctx->a[i] ^= ctx->a[i+16];
  58. }
  59. for(i=16; i<4*4+16; i+=4){
  60. t = ctx->a[i];
  61. ctx->a[i] = ctx->a[i+2];
  62. ctx->a[i+2] = t;
  63. t = ctx->a[i+1];
  64. ctx->a[i+1] = ctx->a[i+3];
  65. ctx->a[i+3] = t;
  66. }
  67. for(i=0; i<16; ++i){
  68. ctx->a[i+16] += ctx->a[i];
  69. ctx->a[i] = rol32(ctx->a[i], 11);
  70. }
  71. for(i=0; i<4; ++i){
  72. t = ctx->a[i];
  73. ctx->a[i] = ctx->a[i+4];
  74. ctx->a[i+4] = t;
  75. }
  76. for(i=8; i<4+8; ++i){
  77. t = ctx->a[i];
  78. ctx->a[i] = ctx->a[i+4];
  79. ctx->a[i+4] = t;
  80. }
  81. for(i=0; i<16; ++i){
  82. ctx->a[i] ^= ctx->a[i+16];
  83. }
  84. for(i=16; i<16+16; i+=2){
  85. t = ctx->a[i];
  86. ctx->a[i] = ctx->a[i+1];
  87. ctx->a[i+1] = t;
  88. }
  89. }
  90. void cubehash_init(uint8_t r, uint8_t b, uint16_t h, cubehash_ctx_t* ctx){
  91. memset(ctx->a, 0, 32*4);
  92. ctx->a[0] = h/8;
  93. ctx->a[1] = b;
  94. ctx->a[2] = r;
  95. ctx->rounds = r;
  96. ctx->blocksize_B = b;
  97. for(b=0; b<10*r; ++b){
  98. cubehash_round(ctx);
  99. }
  100. }
  101. void cubehash_nextBlock(cubehash_ctx_t* ctx, void* block){
  102. uint8_t i;
  103. memxor(ctx->a, block, ctx->blocksize_B);
  104. for(i=0; i<ctx->rounds; ++i){
  105. cubehash_round(ctx);
  106. }
  107. }
  108. void cubehash_lastBlock(cubehash_ctx_t* ctx, void* block, uint16_t length_b){
  109. while(length_b>=ctx->blocksize_B*8){
  110. cubehash_nextBlock(ctx, block);
  111. block = (uint8_t*)block + ctx->blocksize_B;
  112. length_b -= ctx->blocksize_B*8;
  113. }
  114. uint8_t buffer[ctx->blocksize_B];
  115. uint8_t i;
  116. memset(buffer, 0, ctx->blocksize_B);
  117. memcpy(buffer, block, (length_b+7)/8);
  118. buffer[length_b/8] |= 0x80 >> (length_b&7);
  119. cubehash_nextBlock(ctx, buffer);
  120. ctx->a[31] ^= 1;
  121. for(i=0; i<10*(ctx->rounds); ++i){
  122. cubehash_round(ctx);
  123. }
  124. }
  125. void cubehash_ctx2hash(void* dest, uint16_t length_b, cubehash_ctx_t* ctx){
  126. memcpy(dest, ctx->a, (length_b+7)/8);
  127. }
  128. /******************************************************************************/
  129. void cubehash224_init(cubehash_ctx_t* ctx){
  130. cubehash_init(16, 32, 224, ctx);
  131. }
  132. void cubehash224_ctx2hash(void* dest, cubehash_ctx_t* ctx){
  133. cubehash_ctx2hash(dest, 224, ctx);
  134. }
  135. /******************************************************************************/
  136. void cubehash256_init(cubehash_ctx_t* ctx){
  137. cubehash_init(16, 32, 256, ctx);
  138. }
  139. void cubehash256_ctx2hash(void* dest, cubehash_ctx_t* ctx){
  140. cubehash_ctx2hash(dest, 256, ctx);
  141. }
  142. /******************************************************************************/
  143. void cubehash384_init(cubehash_ctx_t* ctx){
  144. cubehash_init(16, 32, 384, ctx);
  145. }
  146. void cubehash384_ctx2hash(void* dest, cubehash_ctx_t* ctx){
  147. cubehash_ctx2hash(dest, 384, ctx);
  148. }
  149. /******************************************************************************/
  150. void cubehash512_init(cubehash_ctx_t* ctx){
  151. cubehash_init(16, 32, 512, ctx);
  152. }
  153. void cubehash512_ctx2hash(void* dest, cubehash_ctx_t* ctx){
  154. cubehash_ctx2hash(dest, 512, ctx);
  155. }