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