siphash: add siphash32 and siphash64.

This commit is contained in:
Christopher Jeffrey 2017-09-30 22:58:50 -07:00
parent 54b930baba
commit 86746e2bd0
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -16,14 +16,15 @@
const native = require('../native').binding; const native = require('../native').binding;
/** /**
* Javascript siphash implementation. Used for compact block relay. * Javascript siphash 2-4 implementation.
* @alias module:crypto/siphash.siphash24 * @private
* @param {Buffer} data * @param {Buffer} data
* @param {Buffer} key - 128 bit key. * @param {Buffer} key - 128 bit key.
* @param {Number} shift
* @returns {Array} [hi, lo] * @returns {Array} [hi, lo]
*/ */
function siphash24(data, key, shift) { function _siphash(data, key, shift) {
const blocks = Math.floor(data.length / 8); const blocks = Math.floor(data.length / 8);
const c0 = U64(0x736f6d65, 0x70736575); const c0 = U64(0x736f6d65, 0x70736575);
const c1 = U64(0x646f7261, 0x6e646f6d); const c1 = U64(0x646f7261, 0x6e646f6d);
@ -85,30 +86,50 @@ function siphash24(data, key, shift) {
return [v0.hi, v0.lo]; return [v0.hi, v0.lo];
} }
function sipround(v0, v1, v2, v3) { /**
v0.iadd(v1); * Javascript siphash 2-4 implementation (64 bit ints).
v1.irotl(13); * @private
v1.ixor(v0); * @param {Number} hi
* @param {Number} lo
* @param {Buffer} key - 128 bit key.
* @returns {Array} [hi, lo]
*/
v0.irotl(32); function _siphash64(hi, lo, key) {
const c0 = U64(0x736f6d65, 0x70736575);
const c1 = U64(0x646f7261, 0x6e646f6d);
const c2 = U64(0x6c796765, 0x6e657261);
const c3 = U64(0x74656462, 0x79746573);
const f0 = U64(hi, lo);
const f1 = U64(0, 0xff);
const k0 = U64.fromRaw(key, 0);
const k1 = U64.fromRaw(key, 8);
v2.iadd(v3); // Init
v3.irotl(16); const v0 = c0.ixor(k0);
v3.ixor(v2); const v1 = c1.ixor(k1);
const v2 = c2.ixor(k0);
const v3 = c3.ixor(k1);
v0.iadd(v3); // Finalization
v3.irotl(21); v3.ixor(f0);
v3.ixor(v0); sipround(v0, v1, v2, v3);
sipround(v0, v1, v2, v3);
v0.ixor(f0);
v2.ixor(f1);
sipround(v0, v1, v2, v3);
sipround(v0, v1, v2, v3);
sipround(v0, v1, v2, v3);
sipround(v0, v1, v2, v3);
v0.ixor(v1);
v0.ixor(v2);
v0.ixor(v3);
v2.iadd(v1); return [v0.hi, v0.lo];
v1.irotl(17);
v1.ixor(v2);
v2.irotl(32);
} }
/** /**
* Javascript siphash implementation (shift=56). * Javascript siphash 2-4 implementation (shift=56).
* @alias module:crypto/siphash.siphash * @alias module:crypto/siphash.siphash
* @param {Buffer} data * @param {Buffer} data
* @param {Buffer} key - 128 bit key. * @param {Buffer} key - 128 bit key.
@ -116,11 +137,11 @@ function sipround(v0, v1, v2, v3) {
*/ */
function siphash(data, key) { function siphash(data, key) {
return siphash24(data, key, 56); return _siphash(data, key, 56);
} }
/** /**
* Javascript siphash implementation (shift=59). * Javascript siphash 2-4 implementation (shift=59).
* @alias module:crypto/siphash.siphash256 * @alias module:crypto/siphash.siphash256
* @param {Buffer} data * @param {Buffer} data
* @param {Buffer} key - 128 bit key. * @param {Buffer} key - 128 bit key.
@ -128,12 +149,39 @@ function siphash(data, key) {
*/ */
function siphash256(data, key) { function siphash256(data, key) {
return siphash24(data, key, 59); return _siphash(data, key, 59);
}
/**
* Javascript siphash 2-4 implementation (32 bit ints).
* @alias module:crypto/siphash.siphash32
* @param {Number} num
* @param {Buffer} key - 128 bit key.
* @returns {Number}
*/
function siphash32(num, key) {
return _siphash64(0, num, key)[1];
}
/**
* Javascript siphash 2-4 implementation (64 bit ints).
* @alias module:crypto/siphash.siphash64
* @param {Number} hi
* @param {Number} lo
* @param {Buffer} key - 128 bit key.
* @returns {Array} [hi, lo]
*/
function siphash64(hi, lo, key) {
return _siphash64(hi, lo, key);
} }
if (native) { if (native) {
siphash = native.siphash; siphash = native.siphash;
siphash256 = native.siphash256; siphash256 = native.siphash256;
siphash32 = native.siphash32;
siphash64 = native.siphash64;
} }
/* /*
@ -217,6 +265,32 @@ U64.fromRaw = function fromRaw(data, off) {
return new U64(hi, lo); return new U64(hi, lo);
}; };
/*
* Helpers
*/
function sipround(v0, v1, v2, v3) {
v0.iadd(v1);
v1.irotl(13);
v1.ixor(v0);
v0.irotl(32);
v2.iadd(v3);
v3.irotl(16);
v3.ixor(v2);
v0.iadd(v3);
v3.irotl(21);
v3.ixor(v0);
v2.iadd(v1);
v1.irotl(17);
v1.ixor(v2);
v2.irotl(32);
}
/* /*
* Expose * Expose
*/ */
@ -224,5 +298,7 @@ U64.fromRaw = function fromRaw(data, off) {
exports = siphash; exports = siphash;
exports.siphash = siphash; exports.siphash = siphash;
exports.siphash256 = siphash256; exports.siphash256 = siphash256;
exports.siphash32 = siphash32;
exports.siphash64 = siphash64;
module.exports = exports; module.exports = exports;