hash_snefru.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Michael Wallner <mike@php.net> |
  16. | Sara Golemon <pollita@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. /* $Id$ */
  20. #include "php_hash.h"
  21. #include "php_hash_snefru.h"
  22. #include "php_hash_snefru_tables.h"
  23. #define round(L, C, N, SB) \
  24. SBE = SB[C & 0xff]; \
  25. L ^= SBE; \
  26. N ^= SBE
  27. #ifndef DBG_SNEFRU
  28. #define DBG_SNEFRU 0
  29. #endif
  30. #if DBG_SNEFRU
  31. void ph(php_hash_uint32 h[16])
  32. {
  33. int i;
  34. for (i = 0; i < 16; i++)
  35. printf ("%08lx", h[i]); printf("\n");
  36. }
  37. #endif
  38. static inline void Snefru(php_hash_uint32 input[16])
  39. {
  40. static int shifts[4] = {16, 8, 16, 24};
  41. int b, index, rshift, lshift;
  42. const php_hash_uint32 *t0,*t1;
  43. php_hash_uint32 SBE,B00,B01,B02,B03,B04,B05,B06,B07,B08,B09,B10,B11,B12,B13,B14,B15;
  44. B00 = input[0];
  45. B01 = input[1];
  46. B02 = input[2];
  47. B03 = input[3];
  48. B04 = input[4];
  49. B05 = input[5];
  50. B06 = input[6];
  51. B07 = input[7];
  52. B08 = input[8];
  53. B09 = input[9];
  54. B10 = input[10];
  55. B11 = input[11];
  56. B12 = input[12];
  57. B13 = input[13];
  58. B14 = input[14];
  59. B15 = input[15];
  60. for (index = 0; index < 8; index++) {
  61. t0 = tables[2*index+0];
  62. t1 = tables[2*index+1];
  63. for (b = 0; b < 4; b++) {
  64. round(B15, B00, B01, t0);
  65. round(B00, B01, B02, t0);
  66. round(B01, B02, B03, t1);
  67. round(B02, B03, B04, t1);
  68. round(B03, B04, B05, t0);
  69. round(B04, B05, B06, t0);
  70. round(B05, B06, B07, t1);
  71. round(B06, B07, B08, t1);
  72. round(B07, B08, B09, t0);
  73. round(B08, B09, B10, t0);
  74. round(B09, B10, B11, t1);
  75. round(B10, B11, B12, t1);
  76. round(B11, B12, B13, t0);
  77. round(B12, B13, B14, t0);
  78. round(B13, B14, B15, t1);
  79. round(B14, B15, B00, t1);
  80. rshift = shifts[b];
  81. lshift = 32-rshift;
  82. B00 = (B00 >> rshift) | (B00 << lshift);
  83. B01 = (B01 >> rshift) | (B01 << lshift);
  84. B02 = (B02 >> rshift) | (B02 << lshift);
  85. B03 = (B03 >> rshift) | (B03 << lshift);
  86. B04 = (B04 >> rshift) | (B04 << lshift);
  87. B05 = (B05 >> rshift) | (B05 << lshift);
  88. B06 = (B06 >> rshift) | (B06 << lshift);
  89. B07 = (B07 >> rshift) | (B07 << lshift);
  90. B08 = (B08 >> rshift) | (B08 << lshift);
  91. B09 = (B09 >> rshift) | (B09 << lshift);
  92. B10 = (B10 >> rshift) | (B10 << lshift);
  93. B11 = (B11 >> rshift) | (B11 << lshift);
  94. B12 = (B12 >> rshift) | (B12 << lshift);
  95. B13 = (B13 >> rshift) | (B13 << lshift);
  96. B14 = (B14 >> rshift) | (B14 << lshift);
  97. B15 = (B15 >> rshift) | (B15 << lshift);
  98. }
  99. }
  100. input[0] ^= B15;
  101. input[1] ^= B14;
  102. input[2] ^= B13;
  103. input[3] ^= B12;
  104. input[4] ^= B11;
  105. input[5] ^= B10;
  106. input[6] ^= B09;
  107. input[7] ^= B08;
  108. #if DBG_SNEFRU
  109. ph(input);
  110. #endif
  111. }
  112. static inline void SnefruTransform(PHP_SNEFRU_CTX *context, const unsigned char input[32])
  113. {
  114. int i, j;
  115. for (i = 0, j = 0; i < 32; i += 4, ++j) {
  116. context->state[8+j] = ((input[i] & 0xff) << 24) | ((input[i+1] & 0xff) << 16) |
  117. ((input[i+2] & 0xff) << 8) | (input[i+3] & 0xff);
  118. }
  119. Snefru(context->state);
  120. memset(&context->state[8], 0, sizeof(php_hash_uint32) * 8);
  121. }
  122. PHP_HASH_API void PHP_SNEFRUInit(PHP_SNEFRU_CTX *context)
  123. {
  124. memset(context, 0, sizeof(*context));
  125. }
  126. static const php_hash_uint32 MAX32 = 0xffffffffLU;
  127. PHP_HASH_API void PHP_SNEFRUUpdate(PHP_SNEFRU_CTX *context, const unsigned char *input, size_t len)
  128. {
  129. if ((MAX32 - context->count[1]) < (len * 8)) {
  130. context->count[0]++;
  131. context->count[1] = MAX32 - context->count[1];
  132. context->count[1] = (len * 8) - context->count[1];
  133. } else {
  134. context->count[1] += len * 8;
  135. }
  136. if (context->length + len < 32) {
  137. memcpy(&context->buffer[context->length], input, len);
  138. context->length += len;
  139. } else {
  140. size_t i = 0, r = (context->length + len) % 32;
  141. if (context->length) {
  142. i = 32 - context->length;
  143. memcpy(&context->buffer[context->length], input, i);
  144. SnefruTransform(context, context->buffer);
  145. }
  146. for (; i + 32 <= len; i += 32) {
  147. SnefruTransform(context, input + i);
  148. }
  149. memcpy(context->buffer, input + i, r);
  150. memset(&context->buffer[r], 0, 32 - r);
  151. context->length = r;
  152. }
  153. }
  154. PHP_HASH_API void PHP_SNEFRUFinal(unsigned char digest[32], PHP_SNEFRU_CTX *context)
  155. {
  156. php_hash_uint32 i, j;
  157. if (context->length) {
  158. SnefruTransform(context, context->buffer);
  159. }
  160. context->state[14] = context->count[0];
  161. context->state[15] = context->count[1];
  162. Snefru(context->state);
  163. for (i = 0, j = 0; j < 32; i++, j += 4) {
  164. digest[j] = (unsigned char) ((context->state[i] >> 24) & 0xff);
  165. digest[j + 1] = (unsigned char) ((context->state[i] >> 16) & 0xff);
  166. digest[j + 2] = (unsigned char) ((context->state[i] >> 8) & 0xff);
  167. digest[j + 3] = (unsigned char) (context->state[i] & 0xff);
  168. }
  169. memset(context, 0, sizeof(*context));
  170. }
  171. const php_hash_ops php_hash_snefru_ops = {
  172. (php_hash_init_func_t) PHP_SNEFRUInit,
  173. (php_hash_update_func_t) PHP_SNEFRUUpdate,
  174. (php_hash_final_func_t) PHP_SNEFRUFinal,
  175. (php_hash_copy_func_t) php_hash_copy,
  176. 32,
  177. 32,
  178. sizeof(PHP_SNEFRU_CTX)
  179. };
  180. /*
  181. * Local variables:
  182. * tab-width: 4
  183. * c-basic-offset: 4
  184. * End:
  185. * vim600: sw=4 ts=4 fdm=marker
  186. * vim<600: sw=4 ts=4
  187. */