PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/ext/hash/hash_ripemd.c

http://github.com/infusion/PHP
C | 775 lines | 488 code | 115 blank | 172 comment | 36 complexity | b47a3f62d794553aa693b7dc1efa916f MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2011 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. /* $Id: hash_ripemd.c 306939 2011-01-01 02:19:59Z felipe $ */
  19. /* Heavily borrowed from md5.c & sha1.c of PHP archival fame
  20. Note that ripemd laughs in the face of logic and uses
  21. little endian byte ordering */
  22. #include "php_hash.h"
  23. #include "php_hash_ripemd.h"
  24. const php_hash_ops php_hash_ripemd128_ops = {
  25. (php_hash_init_func_t) PHP_RIPEMD128Init,
  26. (php_hash_update_func_t) PHP_RIPEMD128Update,
  27. (php_hash_final_func_t) PHP_RIPEMD128Final,
  28. (php_hash_copy_func_t) php_hash_copy,
  29. 16,
  30. 64,
  31. sizeof(PHP_RIPEMD128_CTX)
  32. };
  33. const php_hash_ops php_hash_ripemd160_ops = {
  34. (php_hash_init_func_t) PHP_RIPEMD160Init,
  35. (php_hash_update_func_t) PHP_RIPEMD160Update,
  36. (php_hash_final_func_t) PHP_RIPEMD160Final,
  37. (php_hash_copy_func_t) php_hash_copy,
  38. 20,
  39. 64,
  40. sizeof(PHP_RIPEMD160_CTX)
  41. };
  42. const php_hash_ops php_hash_ripemd256_ops = {
  43. (php_hash_init_func_t) PHP_RIPEMD256Init,
  44. (php_hash_update_func_t) PHP_RIPEMD256Update,
  45. (php_hash_final_func_t) PHP_RIPEMD256Final,
  46. (php_hash_copy_func_t) php_hash_copy,
  47. 32,
  48. 64,
  49. sizeof(PHP_RIPEMD256_CTX)
  50. };
  51. const php_hash_ops php_hash_ripemd320_ops = {
  52. (php_hash_init_func_t) PHP_RIPEMD320Init,
  53. (php_hash_update_func_t) PHP_RIPEMD320Update,
  54. (php_hash_final_func_t) PHP_RIPEMD320Final,
  55. (php_hash_copy_func_t) php_hash_copy,
  56. 40,
  57. 64,
  58. sizeof(PHP_RIPEMD320_CTX)
  59. };
  60. /* {{{ PHP_RIPEMD128Init
  61. * ripemd128 initialization. Begins a ripemd128 operation, writing a new context.
  62. */
  63. PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX * context)
  64. {
  65. context->count[0] = context->count[1] = 0;
  66. /* Load magic initialization constants.
  67. */
  68. context->state[0] = 0x67452301;
  69. context->state[1] = 0xEFCDAB89;
  70. context->state[2] = 0x98BADCFE;
  71. context->state[3] = 0x10325476;
  72. }
  73. /* }}} */
  74. /* {{{ PHP_RIPEMD256Init
  75. * ripemd256 initialization. Begins a ripemd256 operation, writing a new context.
  76. */
  77. PHP_HASH_API void PHP_RIPEMD256Init(PHP_RIPEMD256_CTX * context)
  78. {
  79. context->count[0] = context->count[1] = 0;
  80. /* Load magic initialization constants.
  81. */
  82. context->state[0] = 0x67452301;
  83. context->state[1] = 0xEFCDAB89;
  84. context->state[2] = 0x98BADCFE;
  85. context->state[3] = 0x10325476;
  86. context->state[4] = 0x76543210;
  87. context->state[5] = 0xFEDCBA98;
  88. context->state[6] = 0x89ABCDEF;
  89. context->state[7] = 0x01234567;
  90. }
  91. /* }}} */
  92. /* {{{ PHP_RIPEMD160Init
  93. * ripemd160 initialization. Begins a ripemd160 operation, writing a new context.
  94. */
  95. PHP_HASH_API void PHP_RIPEMD160Init(PHP_RIPEMD160_CTX * context)
  96. {
  97. context->count[0] = context->count[1] = 0;
  98. /* Load magic initialization constants.
  99. */
  100. context->state[0] = 0x67452301;
  101. context->state[1] = 0xEFCDAB89;
  102. context->state[2] = 0x98BADCFE;
  103. context->state[3] = 0x10325476;
  104. context->state[4] = 0xC3D2E1F0;
  105. }
  106. /* }}} */
  107. /* {{{ PHP_RIPEMD320Init
  108. * ripemd320 initialization. Begins a ripemd320 operation, writing a new context.
  109. */
  110. PHP_HASH_API void PHP_RIPEMD320Init(PHP_RIPEMD320_CTX * context)
  111. {
  112. context->count[0] = context->count[1] = 0;
  113. /* Load magic initialization constants.
  114. */
  115. context->state[0] = 0x67452301;
  116. context->state[1] = 0xEFCDAB89;
  117. context->state[2] = 0x98BADCFE;
  118. context->state[3] = 0x10325476;
  119. context->state[4] = 0xC3D2E1F0;
  120. context->state[5] = 0x76543210;
  121. context->state[6] = 0xFEDCBA98;
  122. context->state[7] = 0x89ABCDEF;
  123. context->state[8] = 0x01234567;
  124. context->state[9] = 0x3C2D1E0F;
  125. }
  126. /* }}} */
  127. /* Basic ripemd function */
  128. #define F0(x,y,z) ((x) ^ (y) ^ (z))
  129. #define F1(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
  130. #define F2(x,y,z) (((x) | (~(y))) ^ (z))
  131. #define F3(x,y,z) (((x) & (z)) | ((y) & (~(z))))
  132. #define F4(x,y,z) ((x) ^ ((y) | (~(z))))
  133. static const php_hash_uint32 K_values[5] = { 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E }; /* 128, 256, 160, 320 */
  134. static const php_hash_uint32 KK_values[4] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x00000000 }; /* 128 & 256 */
  135. static const php_hash_uint32 KK160_values[5] = { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000 }; /* 160 & 320 */
  136. #define K(n) K_values[ (n) >> 4]
  137. #define KK(n) KK_values[(n) >> 4]
  138. #define KK160(n) KK160_values[(n) >> 4]
  139. static const unsigned char R[80] = {
  140. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  141. 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
  142. 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
  143. 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
  144. 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 };
  145. static const unsigned char RR[80] = {
  146. 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
  147. 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
  148. 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
  149. 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
  150. 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 };
  151. static const unsigned char S[80] = {
  152. 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
  153. 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
  154. 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
  155. 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
  156. 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 };
  157. static const unsigned char SS[80] = {
  158. 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
  159. 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
  160. 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
  161. 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
  162. 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
  163. #define ROLS(j, x) (((x) << S[j]) | ((x) >> (32 - S[j])))
  164. #define ROLSS(j, x) (((x) << SS[j]) | ((x) >> (32 - SS[j])))
  165. #define ROL(n, x) (((x) << n) | ((x) >> (32 - n)))
  166. /* {{{ RIPEMDDecode
  167. Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is
  168. a multiple of 4.
  169. */
  170. static void RIPEMDDecode(php_hash_uint32 *output, const unsigned char *input, unsigned int len)
  171. {
  172. unsigned int i, j;
  173. for (i = 0, j = 0; j < len; i++, j += 4)
  174. output[i] = ((php_hash_uint32) input[j + 0]) | (((php_hash_uint32) input[j + 1]) << 8) |
  175. (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24);
  176. }
  177. /* }}} */
  178. /* {{{ RIPEMD128Transform
  179. * ripemd128 basic transformation. Transforms state based on block.
  180. */
  181. static void RIPEMD128Transform(php_hash_uint32 state[4], const unsigned char block[64])
  182. {
  183. php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
  184. php_hash_uint32 aa = state[0], bb = state[1], cc = state[2], dd = state[3];
  185. php_hash_uint32 tmp, x[16];
  186. int j;
  187. RIPEMDDecode(x, block, 64);
  188. for(j = 0; j < 16; j++) {
  189. tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
  190. a = d; d = c; c = b; b = tmp;
  191. tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
  192. aa = dd; dd = cc; cc = bb; bb = tmp;
  193. }
  194. for(j = 16; j < 32; j++) {
  195. tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
  196. a = d; d = c; c = b; b = tmp;
  197. tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
  198. aa = dd; dd = cc; cc = bb; bb = tmp;
  199. }
  200. for(j = 32; j < 48; j++) {
  201. tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
  202. a = d; d = c; c = b; b = tmp;
  203. tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
  204. aa = dd; dd = cc; cc = bb; bb = tmp;
  205. }
  206. for(j = 48; j < 64; j++) {
  207. tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
  208. a = d; d = c; c = b; b = tmp;
  209. tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
  210. aa = dd; dd = cc; cc = bb; bb = tmp;
  211. }
  212. tmp = state[1] + c + dd;
  213. state[1] = state[2] + d + aa;
  214. state[2] = state[3] + a + bb;
  215. state[3] = state[0] + b + cc;
  216. state[0] = tmp;
  217. tmp = 0;
  218. memset(x, 0, sizeof(x));
  219. }
  220. /* }}} */
  221. /* {{{ PHP_RIPEMD128Update
  222. ripemd128 block update operation. Continues a ripemd128 message-digest
  223. operation, processing another message block, and updating the
  224. context.
  225. */
  226. PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX * context, const unsigned char *input, unsigned int inputLen)
  227. {
  228. unsigned int i, index, partLen;
  229. /* Compute number of bytes mod 64 */
  230. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  231. /* Update number of bits */
  232. if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
  233. context->count[1]++;
  234. }
  235. context->count[1] += ((php_hash_uint32) inputLen >> 29);
  236. partLen = 64 - index;
  237. /* Transform as many times as possible.
  238. */
  239. if (inputLen >= partLen) {
  240. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  241. RIPEMD128Transform(context->state, context->buffer);
  242. for (i = partLen; i + 63 < inputLen; i += 64) {
  243. RIPEMD128Transform(context->state, &input[i]);
  244. }
  245. index = 0;
  246. } else {
  247. i = 0;
  248. }
  249. /* Buffer remaining input */
  250. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
  251. }
  252. /* }}} */
  253. /* {{{ RIPEMD256Transform
  254. * ripemd256 basic transformation. Transforms state based on block.
  255. */
  256. static void RIPEMD256Transform(php_hash_uint32 state[8], const unsigned char block[64])
  257. {
  258. php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
  259. php_hash_uint32 aa = state[4], bb = state[5], cc = state[6], dd = state[7];
  260. php_hash_uint32 tmp, x[16];
  261. int j;
  262. RIPEMDDecode(x, block, 64);
  263. for(j = 0; j < 16; j++) {
  264. tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j));
  265. a = d; d = c; c = b; b = tmp;
  266. tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK(j));
  267. aa = dd; dd = cc; cc = bb; bb = tmp;
  268. }
  269. tmp = a; a = aa; aa = tmp;
  270. for(j = 16; j < 32; j++) {
  271. tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j));
  272. a = d; d = c; c = b; b = tmp;
  273. tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK(j));
  274. aa = dd; dd = cc; cc = bb; bb = tmp;
  275. }
  276. tmp = b; b = bb; bb = tmp;
  277. for(j = 32; j < 48; j++) {
  278. tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j));
  279. a = d; d = c; c = b; b = tmp;
  280. tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK(j));
  281. aa = dd; dd = cc; cc = bb; bb = tmp;
  282. }
  283. tmp = c; c = cc; cc = tmp;
  284. for(j = 48; j < 64; j++) {
  285. tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j));
  286. a = d; d = c; c = b; b = tmp;
  287. tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK(j));
  288. aa = dd; dd = cc; cc = bb; bb = tmp;
  289. }
  290. tmp = d; d = dd; dd = tmp;
  291. state[0] += a;
  292. state[1] += b;
  293. state[2] += c;
  294. state[3] += d;
  295. state[4] += aa;
  296. state[5] += bb;
  297. state[6] += cc;
  298. state[7] += dd;
  299. tmp = 0;
  300. memset(x, 0, sizeof(x));
  301. }
  302. /* }}} */
  303. /* {{{ PHP_RIPEMD256Update
  304. ripemd256 block update operation. Continues a ripemd256 message-digest
  305. operation, processing another message block, and updating the
  306. context.
  307. */
  308. PHP_HASH_API void PHP_RIPEMD256Update(PHP_RIPEMD256_CTX * context, const unsigned char *input, unsigned int inputLen)
  309. {
  310. unsigned int i, index, partLen;
  311. /* Compute number of bytes mod 64 */
  312. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  313. /* Update number of bits */
  314. if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
  315. context->count[1]++;
  316. }
  317. context->count[1] += ((php_hash_uint32) inputLen >> 29);
  318. partLen = 64 - index;
  319. /* Transform as many times as possible.
  320. */
  321. if (inputLen >= partLen) {
  322. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  323. RIPEMD256Transform(context->state, context->buffer);
  324. for (i = partLen; i + 63 < inputLen; i += 64) {
  325. RIPEMD256Transform(context->state, &input[i]);
  326. }
  327. index = 0;
  328. } else {
  329. i = 0;
  330. }
  331. /* Buffer remaining input */
  332. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
  333. }
  334. /* }}} */
  335. /* {{{ RIPEMD160Transform
  336. * ripemd160 basic transformation. Transforms state based on block.
  337. */
  338. static void RIPEMD160Transform(php_hash_uint32 state[5], const unsigned char block[64])
  339. {
  340. php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
  341. php_hash_uint32 aa = state[0], bb = state[1], cc = state[2], dd = state[3], ee = state[4];
  342. php_hash_uint32 tmp, x[16];
  343. int j;
  344. RIPEMDDecode(x, block, 64);
  345. for(j = 0; j < 16; j++) {
  346. tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
  347. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  348. tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  349. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  350. }
  351. for(j = 16; j < 32; j++) {
  352. tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
  353. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  354. tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  355. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  356. }
  357. for(j = 32; j < 48; j++) {
  358. tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
  359. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  360. tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  361. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  362. }
  363. for(j = 48; j < 64; j++) {
  364. tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
  365. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  366. tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  367. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  368. }
  369. for(j = 64; j < 80; j++) {
  370. tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
  371. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  372. tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  373. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  374. }
  375. tmp = state[1] + c + dd;
  376. state[1] = state[2] + d + ee;
  377. state[2] = state[3] + e + aa;
  378. state[3] = state[4] + a + bb;
  379. state[4] = state[0] + b + cc;
  380. state[0] = tmp;
  381. tmp = 0;
  382. memset(x, 0, sizeof(x));
  383. }
  384. /* }}} */
  385. /* {{{ PHP_RIPEMD160Update
  386. ripemd160 block update operation. Continues a ripemd160 message-digest
  387. operation, processing another message block, and updating the
  388. context.
  389. */
  390. PHP_HASH_API void PHP_RIPEMD160Update(PHP_RIPEMD160_CTX * context, const unsigned char *input, unsigned int inputLen)
  391. {
  392. unsigned int i, index, partLen;
  393. /* Compute number of bytes mod 64 */
  394. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  395. /* Update number of bits */
  396. if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
  397. context->count[1]++;
  398. }
  399. context->count[1] += ((php_hash_uint32) inputLen >> 29);
  400. partLen = 64 - index;
  401. /* Transform as many times as possible.
  402. */
  403. if (inputLen >= partLen) {
  404. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  405. RIPEMD160Transform(context->state, context->buffer);
  406. for (i = partLen; i + 63 < inputLen; i += 64) {
  407. RIPEMD160Transform(context->state, &input[i]);
  408. }
  409. index = 0;
  410. } else {
  411. i = 0;
  412. }
  413. /* Buffer remaining input */
  414. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
  415. }
  416. /* }}} */
  417. /* {{{ RIPEMD320Transform
  418. * ripemd320 basic transformation. Transforms state based on block.
  419. */
  420. static void RIPEMD320Transform(php_hash_uint32 state[10], const unsigned char block[64])
  421. {
  422. php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
  423. php_hash_uint32 aa = state[5], bb = state[6], cc = state[7], dd = state[8], ee = state[9];
  424. php_hash_uint32 tmp, x[16];
  425. int j;
  426. RIPEMDDecode(x, block, 64);
  427. for(j = 0; j < 16; j++) {
  428. tmp = ROLS( j, a + F0(b, c, d) + x[R[j]] + K(j)) + e;
  429. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  430. tmp = ROLSS(j, aa + F4(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  431. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  432. }
  433. tmp = b; b = bb; bb = tmp;
  434. for(j = 16; j < 32; j++) {
  435. tmp = ROLS( j, a + F1(b, c, d) + x[R[j]] + K(j)) + e;
  436. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  437. tmp = ROLSS(j, aa + F3(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  438. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  439. }
  440. tmp = d; d = dd; dd = tmp;
  441. for(j = 32; j < 48; j++) {
  442. tmp = ROLS( j, a + F2(b, c, d) + x[R[j]] + K(j)) + e;
  443. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  444. tmp = ROLSS(j, aa + F2(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  445. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  446. }
  447. tmp = a; a = aa; aa = tmp;
  448. for(j = 48; j < 64; j++) {
  449. tmp = ROLS( j, a + F3(b, c, d) + x[R[j]] + K(j)) + e;
  450. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  451. tmp = ROLSS(j, aa + F1(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  452. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  453. }
  454. tmp = c; c = cc; cc = tmp;
  455. for(j = 64; j < 80; j++) {
  456. tmp = ROLS( j, a + F4(b, c, d) + x[R[j]] + K(j)) + e;
  457. a = e; e = d; d = ROL(10, c); c = b; b = tmp;
  458. tmp = ROLSS(j, aa + F0(bb, cc, dd) + x[RR[j]] + KK160(j)) + ee;
  459. aa = ee; ee = dd; dd = ROL(10, cc); cc = bb; bb = tmp;
  460. }
  461. tmp = e; e = ee; ee = tmp;
  462. state[0] += a;
  463. state[1] += b;
  464. state[2] += c;
  465. state[3] += d;
  466. state[4] += e;
  467. state[5] += aa;
  468. state[6] += bb;
  469. state[7] += cc;
  470. state[8] += dd;
  471. state[9] += ee;
  472. tmp = 0;
  473. memset(x, 0, sizeof(x));
  474. }
  475. /* }}} */
  476. /* {{{ PHP_RIPEMD320Update
  477. ripemd320 block update operation. Continues a ripemd320 message-digest
  478. operation, processing another message block, and updating the
  479. context.
  480. */
  481. PHP_HASH_API void PHP_RIPEMD320Update(PHP_RIPEMD320_CTX * context, const unsigned char *input, unsigned int inputLen)
  482. {
  483. unsigned int i, index, partLen;
  484. /* Compute number of bytes mod 64 */
  485. index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
  486. /* Update number of bits */
  487. if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
  488. context->count[1]++;
  489. }
  490. context->count[1] += ((php_hash_uint32) inputLen >> 29);
  491. partLen = 64 - index;
  492. /* Transform as many times as possible.
  493. */
  494. if (inputLen >= partLen) {
  495. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
  496. RIPEMD320Transform(context->state, context->buffer);
  497. for (i = partLen; i + 63 < inputLen; i += 64) {
  498. RIPEMD320Transform(context->state, &input[i]);
  499. }
  500. index = 0;
  501. } else {
  502. i = 0;
  503. }
  504. /* Buffer remaining input */
  505. memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
  506. }
  507. /* }}} */
  508. static const unsigned char PADDING[64] =
  509. {
  510. 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  511. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  512. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  513. };
  514. /* {{{ RIPEMDEncode
  515. Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is
  516. a multiple of 4.
  517. */
  518. static void RIPEMDEncode(unsigned char *output, php_hash_uint32 *input, unsigned int len)
  519. {
  520. unsigned int i, j;
  521. for (i = 0, j = 0; j < len; i++, j += 4) {
  522. output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
  523. output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
  524. output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
  525. output[j + 0] = (unsigned char) (input[i] & 0xff);
  526. }
  527. }
  528. /* }}} */
  529. /* {{{ PHP_RIPEMD128Final
  530. ripemd128 finalization. Ends a ripemd128 message-digest operation, writing the
  531. the message digest and zeroizing the context.
  532. */
  533. PHP_HASH_API void PHP_RIPEMD128Final(unsigned char digest[16], PHP_RIPEMD128_CTX * context)
  534. {
  535. unsigned char bits[8];
  536. unsigned int index, padLen;
  537. /* Save number of bits */
  538. bits[0] = (unsigned char) (context->count[0] & 0xFF);
  539. bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
  540. bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
  541. bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
  542. bits[4] = (unsigned char) (context->count[1] & 0xFF);
  543. bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
  544. bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
  545. bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
  546. /* Pad out to 56 mod 64.
  547. */
  548. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  549. padLen = (index < 56) ? (56 - index) : (120 - index);
  550. PHP_RIPEMD128Update(context, PADDING, padLen);
  551. /* Append length (before padding) */
  552. PHP_RIPEMD128Update(context, bits, 8);
  553. /* Store state in digest */
  554. RIPEMDEncode(digest, context->state, 16);
  555. /* Zeroize sensitive information.
  556. */
  557. memset((unsigned char*) context, 0, sizeof(*context));
  558. }
  559. /* }}} */
  560. /* {{{ PHP_RIPEMD256Final
  561. ripemd256 finalization. Ends a ripemd256 message-digest operation, writing the
  562. the message digest and zeroizing the context.
  563. */
  564. PHP_HASH_API void PHP_RIPEMD256Final(unsigned char digest[32], PHP_RIPEMD256_CTX * context)
  565. {
  566. unsigned char bits[8];
  567. unsigned int index, padLen;
  568. /* Save number of bits */
  569. bits[0] = (unsigned char) (context->count[0] & 0xFF);
  570. bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
  571. bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
  572. bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
  573. bits[4] = (unsigned char) (context->count[1] & 0xFF);
  574. bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
  575. bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
  576. bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
  577. /* Pad out to 56 mod 64.
  578. */
  579. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  580. padLen = (index < 56) ? (56 - index) : (120 - index);
  581. PHP_RIPEMD256Update(context, PADDING, padLen);
  582. /* Append length (before padding) */
  583. PHP_RIPEMD256Update(context, bits, 8);
  584. /* Store state in digest */
  585. RIPEMDEncode(digest, context->state, 32);
  586. /* Zeroize sensitive information.
  587. */
  588. memset((unsigned char*) context, 0, sizeof(*context));
  589. }
  590. /* }}} */
  591. /* {{{ PHP_RIPEMD160Final
  592. ripemd160 finalization. Ends a ripemd160 message-digest operation, writing the
  593. the message digest and zeroizing the context.
  594. */
  595. PHP_HASH_API void PHP_RIPEMD160Final(unsigned char digest[20], PHP_RIPEMD160_CTX * context)
  596. {
  597. unsigned char bits[8];
  598. unsigned int index, padLen;
  599. /* Save number of bits */
  600. bits[0] = (unsigned char) (context->count[0] & 0xFF);
  601. bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
  602. bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
  603. bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
  604. bits[4] = (unsigned char) (context->count[1] & 0xFF);
  605. bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
  606. bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
  607. bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
  608. /* Pad out to 56 mod 64.
  609. */
  610. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  611. padLen = (index < 56) ? (56 - index) : (120 - index);
  612. PHP_RIPEMD160Update(context, PADDING, padLen);
  613. /* Append length (before padding) */
  614. PHP_RIPEMD160Update(context, bits, 8);
  615. /* Store state in digest */
  616. RIPEMDEncode(digest, context->state, 20);
  617. /* Zeroize sensitive information.
  618. */
  619. memset((unsigned char*) context, 0, sizeof(*context));
  620. }
  621. /* }}} */
  622. /* {{{ PHP_RIPEMD320Final
  623. ripemd320 finalization. Ends a ripemd320 message-digest operation, writing the
  624. the message digest and zeroizing the context.
  625. */
  626. PHP_HASH_API void PHP_RIPEMD320Final(unsigned char digest[40], PHP_RIPEMD320_CTX * context)
  627. {
  628. unsigned char bits[8];
  629. unsigned int index, padLen;
  630. /* Save number of bits */
  631. bits[0] = (unsigned char) (context->count[0] & 0xFF);
  632. bits[1] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
  633. bits[2] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
  634. bits[3] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
  635. bits[4] = (unsigned char) (context->count[1] & 0xFF);
  636. bits[5] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
  637. bits[6] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
  638. bits[7] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
  639. /* Pad out to 56 mod 64.
  640. */
  641. index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
  642. padLen = (index < 56) ? (56 - index) : (120 - index);
  643. PHP_RIPEMD320Update(context, PADDING, padLen);
  644. /* Append length (before padding) */
  645. PHP_RIPEMD320Update(context, bits, 8);
  646. /* Store state in digest */
  647. RIPEMDEncode(digest, context->state, 40);
  648. /* Zeroize sensitive information.
  649. */
  650. memset((unsigned char*) context, 0, sizeof(*context));
  651. }
  652. /* }}} */
  653. /*
  654. * Local variables:
  655. * tab-width: 4
  656. * c-basic-offset: 4
  657. * End:
  658. * vim600: sw=4 ts=4 fdm=marker
  659. * vim<600: sw=4 ts=4
  660. */