Annotation of embedaddon/php/ext/hash/hash_gost.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 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:
! 20: /* $Id: hash_gost.c 321634 2012-01-01 13:15:04Z felipe $ */
! 21:
! 22: #include "php_hash.h"
! 23: #include "php_hash_gost.h"
! 24: #include "php_hash_gost_tables.h"
! 25:
! 26: /* {{{ Gost()
! 27: * derived from gost_compress() by Markku-Juhani Saarinen <mjos@ssh.fi>
! 28: */
! 29:
! 30: #define round(k1, k2) \
! 31: t = (k1) + r; \
! 32: l ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \
! 33: tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24]; \
! 34: t = (k2) + l; \
! 35: r ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \
! 36: tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24];
! 37:
! 38: #define R(key, h, i, t, l, r) \
! 39: r = h[i]; \
! 40: l = h[i + 1]; \
! 41: round(key[0], key[1]) \
! 42: round(key[2], key[3]) \
! 43: round(key[4], key[5]) \
! 44: round(key[6], key[7]) \
! 45: round(key[0], key[1]) \
! 46: round(key[2], key[3]) \
! 47: round(key[4], key[5]) \
! 48: round(key[6], key[7]) \
! 49: round(key[0], key[1]) \
! 50: round(key[2], key[3]) \
! 51: round(key[4], key[5]) \
! 52: round(key[6], key[7]) \
! 53: round(key[7], key[6]) \
! 54: round(key[5], key[4]) \
! 55: round(key[3], key[2]) \
! 56: round(key[1], key[0]) \
! 57: t = r; \
! 58: r = l; \
! 59: l = t; \
! 60:
! 61: #define X(w, u, v) \
! 62: w[0] = u[0] ^ v[0]; \
! 63: w[1] = u[1] ^ v[1]; \
! 64: w[2] = u[2] ^ v[2]; \
! 65: w[3] = u[3] ^ v[3]; \
! 66: w[4] = u[4] ^ v[4]; \
! 67: w[5] = u[5] ^ v[5]; \
! 68: w[6] = u[6] ^ v[6]; \
! 69: w[7] = u[7] ^ v[7];
! 70:
! 71: #define P(key, w) \
! 72: key[0] = (w[0] & 0x000000ff) | ((w[2] & 0x000000ff) << 8) | \
! 73: ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24); \
! 74: key[1] = ((w[0] & 0x0000ff00) >> 8) | (w[2] & 0x0000ff00) | \
! 75: ((w[4] & 0x0000ff00) << 8) | ((w[6] & 0x0000ff00) << 16); \
! 76: key[2] = ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) | \
! 77: (w[4] & 0x00ff0000) | ((w[6] & 0x00ff0000) << 8); \
! 78: key[3] = ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) | \
! 79: ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000); \
! 80: key[4] = (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) | \
! 81: ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24); \
! 82: key[5] = ((w[1] & 0x0000ff00) >> 8) | (w[3] & 0x0000ff00) | \
! 83: ((w[5] & 0x0000ff00) << 8) | ((w[7] & 0x0000ff00) << 16); \
! 84: key[6] = ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) | \
! 85: (w[5] & 0x00ff0000) | ((w[7] & 0x00ff0000) << 8); \
! 86: key[7] = ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) | \
! 87: ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000);
! 88:
! 89: #define A(x, l, r) \
! 90: l = x[0] ^ x[2]; \
! 91: r = x[1] ^ x[3]; \
! 92: x[0] = x[2]; \
! 93: x[1] = x[3]; \
! 94: x[2] = x[4]; \
! 95: x[3] = x[5]; \
! 96: x[4] = x[6]; \
! 97: x[5] = x[7]; \
! 98: x[6] = l; \
! 99: x[7] = r;
! 100:
! 101: #define AA(x, l, r) \
! 102: l = x[0]; \
! 103: r = x[2]; \
! 104: x[0] = x[4]; \
! 105: x[2] = x[6]; \
! 106: x[4] = l ^ r; \
! 107: x[6] = x[0] ^ r; \
! 108: l = x[1]; \
! 109: r = x[3]; \
! 110: x[1] = x[5]; \
! 111: x[3] = x[7]; \
! 112: x[5] = l ^ r; \
! 113: x[7] = x[1] ^ r;
! 114:
! 115: #define C(x) \
! 116: x[0] ^= 0xff00ff00; \
! 117: x[1] ^= 0xff00ff00; \
! 118: x[2] ^= 0x00ff00ff; \
! 119: x[3] ^= 0x00ff00ff; \
! 120: x[4] ^= 0x00ffff00; \
! 121: x[5] ^= 0xff0000ff; \
! 122: x[6] ^= 0x000000ff; \
! 123: x[7] ^= 0xff00ffff;
! 124:
! 125: #define S(s, l, r) \
! 126: s[i] = r; \
! 127: s[i + 1] = l;
! 128:
! 129: #define SHIFT12(u, m, s) \
! 130: u[0] = m[0] ^ s[6]; \
! 131: u[1] = m[1] ^ s[7]; \
! 132: u[2] = m[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ \
! 133: (s[1] & 0xffff) ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ \
! 134: (s[7] & 0xffff0000) ^ (s[7] >> 16); \
! 135: u[3] = m[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ \
! 136: (s[1] << 16) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ \
! 137: (s[3] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ \
! 138: (s[7] << 16) ^ (s[7] >> 16); \
! 139: u[4] = m[4] ^ \
! 140: (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^ \
! 141: (s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ \
! 142: (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ \
! 143: (s[6] >> 16) ^(s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16); \
! 144: u[5] = m[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^ \
! 145: (s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ \
! 146: (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[6] << 16) ^ \
! 147: (s[6] >> 16) ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16); \
! 148: u[6] = m[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16) ^ \
! 149: (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6] ^ \
! 150: (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16); \
! 151: u[7] = m[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ \
! 152: (s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^ \
! 153: (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ \
! 154: (s[7] << 16) ^ (s[7] >> 16);
! 155:
! 156: #define SHIFT16(h, v, u) \
! 157: v[0] = h[0] ^ (u[1] << 16) ^ (u[0] >> 16); \
! 158: v[1] = h[1] ^ (u[2] << 16) ^ (u[1] >> 16); \
! 159: v[2] = h[2] ^ (u[3] << 16) ^ (u[2] >> 16); \
! 160: v[3] = h[3] ^ (u[4] << 16) ^ (u[3] >> 16); \
! 161: v[4] = h[4] ^ (u[5] << 16) ^ (u[4] >> 16); \
! 162: v[5] = h[5] ^ (u[6] << 16) ^ (u[5] >> 16); \
! 163: v[6] = h[6] ^ (u[7] << 16) ^ (u[6] >> 16); \
! 164: v[7] = h[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[7] >> 16) ^ \
! 165: (u[1] & 0xffff0000) ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000);
! 166:
! 167: #define SHIFT61(h, v) \
! 168: h[0] = (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^ (v[1] >> 16) ^ \
! 169: (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ (v[4] << 16) ^ \
! 170: (v[5] >> 16) ^ v[5] ^ (v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ \
! 171: (v[7] & 0xffff); \
! 172: h[1] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ (v[1] & 0xffff) ^ \
! 173: v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^ (v[4] >> 16) ^ (v[5] << 16) ^ \
! 174: (v[6] << 16) ^ v[6] ^ (v[7] & 0xffff0000) ^ (v[7] >> 16); \
! 175: h[2] = (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ \
! 176: (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ \
! 177: (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^ (v[7] & 0xffff) ^ (v[7] << 16) ^ \
! 178: (v[7] >> 16); \
! 179: h[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ \
! 180: (v[1] & 0xffff0000) ^ (v[1] >> 16) ^ (v[2] << 16) ^ (v[2] >> 16) ^ v[2] ^ \
! 181: (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ \
! 182: (v[7] & 0xffff) ^ (v[7] >> 16); \
! 183: h[4] = (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^ \
! 184: (v[3] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ \
! 185: v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16); \
! 186: h[5] = (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^ (v[1] >> 16) ^ \
! 187: (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^ (v[3] >> 16) ^ v[3] ^ \
! 188: (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^ (v[5] << 16) ^ (v[6] << 16) ^ \
! 189: (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff0000); \
! 190: h[6] = v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^ \
! 191: (v[4] >> 16) ^ (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ \
! 192: (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ v[7]; \
! 193: h[7] = v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ (v[2] << 16) ^ \
! 194: (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5] ^ \
! 195: (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];
! 196:
! 197: #define PASS \
! 198: X(w, u, v); \
! 199: P(key, w); \
! 200: R(key, h, i, t, l, r); \
! 201: S(s, l, r); \
! 202: if (i != 6) { \
! 203: A(u, l, r); \
! 204: if (i == 2) { \
! 205: C(u); \
! 206: } \
! 207: AA(v, l, r); \
! 208: }
! 209:
! 210: static inline void Gost(php_hash_uint32 state[8], php_hash_uint32 data[8])
! 211: {
! 212: int i;
! 213: php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = state, *m = data;
! 214:
! 215: memcpy(u, state, sizeof(u));
! 216: memcpy(v, data, sizeof(v));
! 217:
! 218: for (i = 0; i < 8; i += 2) {
! 219: PASS;
! 220: }
! 221: SHIFT12(u, m, s);
! 222: SHIFT16(h, v, u);
! 223: SHIFT61(h, v);
! 224: }
! 225: /* }}} */
! 226:
! 227: static inline void GostTransform(PHP_GOST_CTX *context, const unsigned char input[32])
! 228: {
! 229: int i, j;
! 230: php_hash_uint32 data[8], temp = 0, save = 0;
! 231:
! 232: for (i = 0, j = 0; i < 8; ++i, j += 4) {
! 233: data[i] = ((php_hash_uint32) input[j]) | (((php_hash_uint32) input[j + 1]) << 8) |
! 234: (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24);
! 235: save = context->state[i + 8];
! 236: context->state[i + 8] += data[i] + temp;
! 237: temp = ((context->state[i + 8] < data[i]) || (context->state[i + 8] < save)) ? 1 : 0;
! 238: }
! 239:
! 240: Gost(context->state, data);
! 241: }
! 242:
! 243: PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *context)
! 244: {
! 245: memset(context, 0, sizeof(*context));
! 246: }
! 247:
! 248: static const php_hash_uint32 MAX32 = 0xffffffffLU;
! 249:
! 250: PHP_HASH_API void PHP_GOSTUpdate(PHP_GOST_CTX *context, const unsigned char *input, size_t len)
! 251: {
! 252: if ((MAX32 - context->count[0]) < (len * 8)) {
! 253: context->count[1]++;
! 254: context->count[0] = MAX32 - context->count[0];
! 255: context->count[0] = (len * 8) - context->count[0];
! 256: } else {
! 257: context->count[0] += len * 8;
! 258: }
! 259:
! 260: if (context->length + len < 32) {
! 261: memcpy(&context->buffer[context->length], input, len);
! 262: context->length += len;
! 263: } else {
! 264: size_t i = 0, r = (context->length + len) % 32;
! 265:
! 266: if (context->length) {
! 267: i = 32 - context->length;
! 268: memcpy(&context->buffer[context->length], input, i);
! 269: GostTransform(context, context->buffer);
! 270: }
! 271:
! 272: for (; i + 32 <= len; i += 32) {
! 273: GostTransform(context, input + i);
! 274: }
! 275:
! 276: memcpy(context->buffer, input + i, r);
! 277: memset(&context->buffer[r], 0, 32 - r);
! 278: context->length = r;
! 279: }
! 280: }
! 281:
! 282: PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context)
! 283: {
! 284: php_hash_uint32 i, j, l[8] = {0};
! 285:
! 286: if (context->length) {
! 287: GostTransform(context, context->buffer);
! 288: }
! 289:
! 290: memcpy(l, context->count, sizeof(context->count));
! 291: Gost(context->state, l);
! 292: memcpy(l, &context->state[8], sizeof(l));
! 293: Gost(context->state, l);
! 294:
! 295: for (i = 0, j = 0; j < 32; i++, j += 4) {
! 296: digest[j] = (unsigned char) (context->state[i] & 0xff);
! 297: digest[j + 1] = (unsigned char) ((context->state[i] >> 8) & 0xff);
! 298: digest[j + 2] = (unsigned char) ((context->state[i] >> 16) & 0xff);
! 299: digest[j + 3] = (unsigned char) ((context->state[i] >> 24) & 0xff);
! 300: }
! 301:
! 302: memset(context, 0, sizeof(*context));
! 303: }
! 304:
! 305: const php_hash_ops php_hash_gost_ops = {
! 306: (php_hash_init_func_t) PHP_GOSTInit,
! 307: (php_hash_update_func_t) PHP_GOSTUpdate,
! 308: (php_hash_final_func_t) PHP_GOSTFinal,
! 309: (php_hash_copy_func_t) php_hash_copy,
! 310: 32,
! 311: 32,
! 312: sizeof(PHP_GOST_CTX)
! 313: };
! 314:
! 315: /*
! 316: * Local variables:
! 317: * tab-width: 4
! 318: * c-basic-offset: 4
! 319: * End:
! 320: * vim600: sw=4 ts=4 fdm=marker
! 321: * vim<600: sw=4 ts=4
! 322: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>