Annotation of embedaddon/php/ext/hash/hash_salsa.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_salsa.c 321634 2012-01-01 13:15:04Z felipe $ */
! 21:
! 22: #include "php_hash.h"
! 23: #include "php_hash_salsa.h"
! 24:
! 25: #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
! 26:
! 27: /* {{{ Salsa10
! 28:
! 29: The 64-byte input x to Salsa10 is viewed in little-endian form as 16 integers
! 30: x0, x1, x2, ..., x15 in {0,1,...,2^32-1}. These 16 integers are fed through
! 31: 320 invertible modifications, where each modification changes one integer.
! 32: The modifications involve, overall,
! 33:
! 34: * 10 additions of constants modulo 2^32;
! 35: * 320 more additions modulo 2^32;
! 36: * 80 ``or'' operations;
! 37: * 240 ``xor'' operations; and
! 38: * 320 constant-distance rotations.
! 39:
! 40: The resulting 16 integers are added to the original x0, x1, x2, ..., x15
! 41: respectively modulo 2^32, producing, in little-endian form, the 64-byte output
! 42: Salsa10(x).
! 43:
! 44: D.J.Bernstein
! 45: */
! 46: static void Salsa10(php_hash_uint32 x[16], php_hash_uint32 in[16])
! 47: {
! 48: int i;
! 49:
! 50: for (i = 10; i > 0; --i) {
! 51: x[ 4] ^= R(x[ 0]+x[12], 6); x[ 8] ^= R(x[ 4]+x[ 0],17);
! 52: x[12] += R(x[ 8]|x[ 4],16); x[ 0] += R(x[12]^x[ 8], 5);
! 53: x[ 9] += R(x[ 5]|x[ 1], 8); x[13] += R(x[ 9]|x[ 5], 7);
! 54: x[ 1] ^= R(x[13]+x[ 9],17); x[ 5] += R(x[ 1]^x[13],12);
! 55: x[14] ^= R(x[10]+x[ 6], 7); x[ 2] += R(x[14]^x[10],15);
! 56: x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],15);
! 57: x[ 3] += R(x[15]|x[11],20); x[ 7] ^= R(x[ 3]+x[15],16);
! 58: x[11] += R(x[ 7]^x[ 3], 7); x[15] += R(x[11]^x[ 7], 8);
! 59: x[ 1] += R(x[ 0]|x[ 3], 8)^i;x[ 2] ^= R(x[ 1]+x[ 0],14);
! 60: x[ 3] ^= R(x[ 2]+x[ 1], 6); x[ 0] += R(x[ 3]^x[ 2],18);
! 61: x[ 6] += R(x[ 5]^x[ 4], 8); x[ 7] += R(x[ 6]^x[ 5],12);
! 62: x[ 4] += R(x[ 7]|x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],15);
! 63: x[11] ^= R(x[10]+x[ 9],18); x[ 8] += R(x[11]^x[10],11);
! 64: x[ 9] ^= R(x[ 8]+x[11], 8); x[10] += R(x[ 9]|x[ 8], 6);
! 65: x[12] += R(x[15]^x[14],17); x[13] ^= R(x[12]+x[15],15);
! 66: x[14] += R(x[13]|x[12], 9); x[15] += R(x[14]^x[13], 7);
! 67: }
! 68: for (i = 0; i < 16; ++i) {
! 69: x[i] += in[i];
! 70: }
! 71: }
! 72: /* }}} */
! 73:
! 74: /* {{{ Salsa20
! 75:
! 76: The 64-byte input x to Salsa20 is viewed in little-endian form as 16 words
! 77: x0, x1, x2, ..., x15 in {0,1,...,2^32-1}. These 16 words are fed through 320
! 78: invertible modifications, where each modification changes one word. The
! 79: resulting 16 words are added to the original x0, x1, x2, ..., x15 respectively
! 80: modulo 2^32, producing, in little-endian form, the 64-byte output Salsa20(x).
! 81:
! 82: Each modification involves xor'ing into one word a rotated version of the sum
! 83: of two other words modulo 2^32. Thus the 320 modifications involve, overall,
! 84: 320 additions, 320 xor's, and 320 rotations. The rotations are all by constant
! 85: distances.
! 86:
! 87: The entire series of modifications is a series of 10 identical double-rounds.
! 88: Each double-round is a series of 2 rounds. Each round is a set of 4 parallel
! 89: quarter-rounds. Each quarter-round modifies 4 words.
! 90:
! 91: D.J.Bernstein
! 92: */
! 93: static void Salsa20(php_hash_uint32 x[16], php_hash_uint32 in[16])
! 94: {
! 95: int i;
! 96:
! 97: for (i = 20; i > 0; i -= 2) {
! 98: x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
! 99: x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
! 100: x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
! 101: x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
! 102: x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
! 103: x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
! 104: x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
! 105: x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
! 106: x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
! 107: x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
! 108: x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
! 109: x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
! 110: x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
! 111: x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
! 112: x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
! 113: x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
! 114: }
! 115: for (i = 0; i < 16; ++i) {
! 116: x[i] += in[i];
! 117: }
! 118: }
! 119: /* }}} */
! 120:
! 121: static inline void SalsaTransform(PHP_SALSA_CTX *context, const unsigned char input[64])
! 122: {
! 123: php_hash_uint32 i, j, a[16];
! 124:
! 125: #if 0
! 126: fprintf(stderr, "> INPUT: %.*s\n", 64, input);
! 127: #endif
! 128:
! 129: for (i = 0, j = 0; j < 64; i++, j += 4) {
! 130: a[i] = ((php_hash_uint32) input[j + 3]) | (((php_hash_uint32) input[j + 2]) << 8) |
! 131: (((php_hash_uint32) input[j + 1]) << 16) | (((php_hash_uint32) input[j]) << 24);
! 132: }
! 133:
! 134: if (!context->init) {
! 135: memcpy(context->state, a, sizeof(a));
! 136: context->init = 1;
! 137: }
! 138:
! 139: context->Transform(context->state, a);
! 140: memset(a, 0, sizeof(a));
! 141: }
! 142:
! 143: PHP_HASH_API void PHP_SALSA10Init(PHP_SALSA_CTX *context)
! 144: {
! 145: memset(context, 0, sizeof(*context));
! 146: context->Transform = Salsa10;
! 147: }
! 148:
! 149: PHP_HASH_API void PHP_SALSA20Init(PHP_SALSA_CTX *context)
! 150: {
! 151: memset(context, 0, sizeof(*context));
! 152: context->Transform = Salsa20;
! 153: }
! 154:
! 155: PHP_HASH_API void PHP_SALSAUpdate(PHP_SALSA_CTX *context, const unsigned char *input, size_t len)
! 156: {
! 157: if (context->length + len < 64) {
! 158: memcpy(&context->buffer[context->length], input, len);
! 159: context->length += len;
! 160: } else {
! 161: size_t i = 0, r = (context->length + len) % 64;
! 162:
! 163: if (context->length) {
! 164: i = 64 - context->length;
! 165: memcpy(&context->buffer[context->length], input, i);
! 166: SalsaTransform(context, context->buffer);
! 167: memset(context->buffer, 0, 64);
! 168: }
! 169:
! 170: for (; i + 64 <= len; i += 64) {
! 171: SalsaTransform(context, input + i);
! 172: }
! 173:
! 174: memcpy(context->buffer, input + i, r);
! 175: context->length = r;
! 176: }
! 177: }
! 178:
! 179: PHP_HASH_API void PHP_SALSAFinal(unsigned char digest[64], PHP_SALSA_CTX *context)
! 180: {
! 181: php_hash_uint32 i, j;
! 182:
! 183: if (context->length) {
! 184: SalsaTransform(context, context->buffer);
! 185: }
! 186:
! 187: for (i = 0, j = 0; j < 64; i++, j += 4) {
! 188: digest[j] = (unsigned char) ((context->state[i] >> 24) & 0xff);
! 189: digest[j + 1] = (unsigned char) ((context->state[i] >> 16) & 0xff);
! 190: digest[j + 2] = (unsigned char) ((context->state[i] >> 8) & 0xff);
! 191: digest[j + 3] = (unsigned char) (context->state[i] & 0xff);
! 192: }
! 193:
! 194: memset(context, 0, sizeof(*context));
! 195: }
! 196:
! 197: const php_hash_ops php_hash_salsa10_ops = {
! 198: (php_hash_init_func_t) PHP_SALSA10Init,
! 199: (php_hash_update_func_t) PHP_SALSAUpdate,
! 200: (php_hash_final_func_t) PHP_SALSAFinal,
! 201: (php_hash_copy_func_t) php_hash_copy,
! 202: 64,
! 203: 64,
! 204: sizeof(PHP_SALSA_CTX)
! 205: };
! 206:
! 207: const php_hash_ops php_hash_salsa20_ops = {
! 208: (php_hash_init_func_t) PHP_SALSA20Init,
! 209: (php_hash_update_func_t) PHP_SALSAUpdate,
! 210: (php_hash_final_func_t) PHP_SALSAFinal,
! 211: (php_hash_copy_func_t) php_hash_copy,
! 212: 64,
! 213: 64,
! 214: sizeof(PHP_SALSA_CTX)
! 215: };
! 216:
! 217: /*
! 218: * Local variables:
! 219: * tab-width: 4
! 220: * c-basic-offset: 4
! 221: * End:
! 222: * vim600: sw=4 ts=4 fdm=marker
! 223: * vim<600: sw=4 ts=4
! 224: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>