hash_sha3.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 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. | Author: Sara Golemon <pollita@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #include "php_hash.h"
  19. #include "php_hash_sha3.h"
  20. #ifdef HAVE_SLOW_HASH3
  21. // ================= slow algo ==============================================
  22. #if (defined(__APPLE__) || defined(__APPLE_CC__)) && \
  23. (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
  24. # if defined(__LITTLE_ENDIAN__)
  25. # undef WORDS_BIGENDIAN
  26. # else
  27. # if defined(__BIG_ENDIAN__)
  28. # define WORDS_BIGENDIAN
  29. # endif
  30. # endif
  31. #endif
  32. static inline uint64_t rol64(uint64_t v, unsigned char b) {
  33. return (v << b) | (v >> (64 - b));
  34. }
  35. static inline unsigned char idx(unsigned char x, unsigned char y) {
  36. return x + (5 * y);
  37. }
  38. #ifdef WORDS_BIGENDIAN
  39. static inline uint64_t load64(const unsigned char* x) {
  40. signed char i;
  41. uint64_t ret = 0;
  42. for (i = 7; i >= 0; --i) {
  43. ret <<= 8;
  44. ret |= x[i];
  45. }
  46. return ret;
  47. }
  48. static inline void store64(unsigned char* x, uint64_t val) {
  49. char i;
  50. for (i = 0; i < 8; ++i) {
  51. x[i] = val & 0xFF;
  52. val >>= 8;
  53. }
  54. }
  55. static inline void xor64(unsigned char* x, uint64_t val) {
  56. char i;
  57. for (i = 0; i < 8; ++i) {
  58. x[i] ^= val & 0xFF;
  59. val >>= 8;
  60. }
  61. }
  62. # define readLane(x, y) load64(ctx->state+sizeof(uint64_t)*idx(x, y))
  63. # define writeLane(x, y, v) store64(ctx->state+sizeof(uint64_t)*idx(x, y), v)
  64. # define XORLane(x, y, v) xor64(ctx->state+sizeof(uint64_t)*idx(x, y), v)
  65. #else
  66. # define readLane(x, y) (((uint64_t*)ctx->state)[idx(x,y)])
  67. # define writeLane(x, y, v) (((uint64_t*)ctx->state)[idx(x,y)] = v)
  68. # define XORLane(x, y, v) (((uint64_t*)ctx->state)[idx(x,y)] ^= v)
  69. #endif
  70. static inline char LFSR86540(unsigned char* pLFSR)
  71. {
  72. unsigned char LFSR = *pLFSR;
  73. char result = LFSR & 0x01;
  74. if (LFSR & 0x80) {
  75. // Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
  76. LFSR = (LFSR << 1) ^ 0x71;
  77. } else {
  78. LFSR <<= 1;
  79. }
  80. *pLFSR = LFSR;
  81. return result;
  82. }
  83. static void permute(PHP_SHA3_CTX* ctx) {
  84. unsigned char LFSRstate = 0x01;
  85. unsigned char round;
  86. for (round = 0; round < 24; ++round) {
  87. { // Theta step (see [Keccak Reference, Section 2.3.2])
  88. uint64_t C[5], D;
  89. unsigned char x, y;
  90. for (x = 0; x < 5; ++x) {
  91. C[x] = readLane(x, 0) ^ readLane(x, 1) ^
  92. readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4);
  93. }
  94. for (x = 0; x < 5; ++x) {
  95. D = C[(x+4)%5] ^ rol64(C[(x+1)%5], 1);
  96. for (y = 0; y < 5; ++y) {
  97. XORLane(x, y, D);
  98. }
  99. }
  100. }
  101. { // p and Pi steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4])
  102. unsigned char x = 1, y = 0, t;
  103. uint64_t current = readLane(x, y);
  104. for (t = 0; t < 24; ++t) {
  105. unsigned char r = ((t + 1) * (t + 2) / 2) % 64;
  106. unsigned char Y = (2*x + 3*y) % 5;
  107. uint64_t temp;
  108. x = y;
  109. y = Y;
  110. temp = readLane(x, y);
  111. writeLane(x, y, rol64(current, r));
  112. current = temp;
  113. }
  114. }
  115. { // X step (see [Keccak Reference, Section 2.3.1])
  116. unsigned char x, y;
  117. for (y = 0; y < 5; ++y) {
  118. uint64_t temp[5];
  119. for (x = 0; x < 5; ++x) {
  120. temp[x] = readLane(x, y);
  121. }
  122. for (x = 0; x < 5; ++x) {
  123. writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5]));
  124. }
  125. }
  126. }
  127. { // i step (see [Keccak Reference, Section 2.3.5])
  128. unsigned char j;
  129. for (j = 0; j < 7; ++j) {
  130. if (LFSR86540(&LFSRstate)) {
  131. uint64_t bitPos = (1<<j) - 1;
  132. XORLane(0, 0, (uint64_t)1 << bitPos);
  133. }
  134. }
  135. }
  136. }
  137. }
  138. // ==========================================================================
  139. static void PHP_SHA3_Init(PHP_SHA3_CTX* ctx,
  140. int bits) {
  141. memset(ctx, 0, sizeof(PHP_SHA3_CTX));
  142. }
  143. static void PHP_SHA3_Update(PHP_SHA3_CTX* ctx,
  144. const unsigned char* buf,
  145. unsigned int count,
  146. size_t block_size) {
  147. while (count > 0) {
  148. unsigned int len = block_size - ctx->pos;
  149. if (len > count) len = count;
  150. count -= len;
  151. while (len-- > 0) {
  152. ctx->state[ctx->pos++] ^= *(buf++);
  153. }
  154. if (ctx->pos >= block_size) {
  155. permute(ctx);
  156. ctx->pos = 0;
  157. }
  158. }
  159. }
  160. static void PHP_SHA3_Final(unsigned char* digest,
  161. PHP_SHA3_CTX* ctx,
  162. int block_size,
  163. int digest_size) {
  164. int len = digest_size;
  165. // Pad state to finalize
  166. ctx->state[ctx->pos++] ^= 0x06;
  167. ctx->state[block_size-1] ^= 0x80;
  168. permute(ctx);
  169. // Square output for digest
  170. for(;;) {
  171. int bs = (len < block_size) ? len : block_size;
  172. memcpy(digest, ctx->state, bs);
  173. digest += bs;
  174. len -= bs;
  175. if (!len) break;
  176. permute(ctx);
  177. }
  178. // Zero out context
  179. ZEND_SECURE_ZERO(ctx, sizeof(PHP_SHA3_CTX));
  180. }
  181. // ==========================================================================
  182. #define DECLARE_SHA3_OPS(bits) \
  183. void PHP_SHA3##bits##Init(PHP_SHA3_##bits##_CTX* ctx) { \
  184. PHP_SHA3_Init(ctx, bits); \
  185. } \
  186. void PHP_SHA3##bits##Update(PHP_SHA3_##bits##_CTX* ctx, \
  187. const unsigned char* input, \
  188. unsigned int inputLen) { \
  189. PHP_SHA3_Update(ctx, input, inputLen, \
  190. (1600 - (2 * bits)) >> 3); \
  191. } \
  192. void PHP_SHA3##bits##Final(unsigned char* digest, \
  193. PHP_SHA3_##bits##_CTX* ctx) { \
  194. PHP_SHA3_Final(digest, ctx, \
  195. (1600 - (2 * bits)) >> 3, \
  196. bits >> 3); \
  197. } \
  198. const php_hash_ops php_hash_sha3_##bits##_ops = { \
  199. (php_hash_init_func_t) PHP_SHA3##bits##Init, \
  200. (php_hash_update_func_t) PHP_SHA3##bits##Update, \
  201. (php_hash_final_func_t) PHP_SHA3##bits##Final, \
  202. php_hash_copy, \
  203. bits >> 3, \
  204. (1600 - (2 * bits)) >> 3, \
  205. sizeof(PHP_SHA3_##bits##_CTX), \
  206. 1 \
  207. }
  208. #else
  209. // ================= fast algo ==============================================
  210. #define SUCCESS SHA3_SUCCESS /* Avoid conflict between KeccacHash.h and zend_types.h */
  211. #include "KeccakHash.h"
  212. // ==========================================================================
  213. static int hash_sha3_copy(const void *ops, void *orig_context, void *dest_context)
  214. {
  215. PHP_SHA3_CTX* orig = (PHP_SHA3_CTX*)orig_context;
  216. PHP_SHA3_CTX* dest = (PHP_SHA3_CTX*)dest_context;
  217. memcpy(dest->hashinstance, orig->hashinstance, sizeof(Keccak_HashInstance));
  218. return SUCCESS;
  219. }
  220. #define DECLARE_SHA3_OPS(bits) \
  221. void PHP_SHA3##bits##Init(PHP_SHA3_##bits##_CTX* ctx) { \
  222. ctx->hashinstance = emalloc(sizeof(Keccak_HashInstance)); \
  223. Keccak_HashInitialize_SHA3_##bits((Keccak_HashInstance *)ctx->hashinstance); \
  224. } \
  225. void PHP_SHA3##bits##Update(PHP_SHA3_##bits##_CTX* ctx, \
  226. const unsigned char* input, \
  227. unsigned int inputLen) { \
  228. Keccak_HashUpdate((Keccak_HashInstance *)ctx->hashinstance, input, inputLen * 8); \
  229. } \
  230. void PHP_SHA3##bits##Final(unsigned char* digest, \
  231. PHP_SHA3_##bits##_CTX* ctx) { \
  232. Keccak_HashFinal((Keccak_HashInstance *)ctx->hashinstance, digest); \
  233. efree(ctx->hashinstance); \
  234. ctx->hashinstance = NULL; \
  235. } \
  236. const php_hash_ops php_hash_sha3_##bits##_ops = { \
  237. (php_hash_init_func_t) PHP_SHA3##bits##Init, \
  238. (php_hash_update_func_t) PHP_SHA3##bits##Update, \
  239. (php_hash_final_func_t) PHP_SHA3##bits##Final, \
  240. hash_sha3_copy, \
  241. bits >> 3, \
  242. (1600 - (2 * bits)) >> 3, \
  243. sizeof(PHP_SHA3_##bits##_CTX), \
  244. 1 \
  245. }
  246. #endif
  247. // ================= both algo ==============================================
  248. DECLARE_SHA3_OPS(224);
  249. DECLARE_SHA3_OPS(256);
  250. DECLARE_SHA3_OPS(384);
  251. DECLARE_SHA3_OPS(512);
  252. #undef DECLARE_SHA3_OPS
  253. /*
  254. * Local variables:
  255. * tab-width: 4
  256. * c-basic-offset: 4
  257. * End:
  258. * vim600: sw=4 ts=4 fdm=marker
  259. * vim<600: sw=4 ts=4
  260. */