bip152: refactor siphash.

This commit is contained in:
Christopher Jeffrey 2016-08-26 02:26:07 -07:00
parent 319996a1ba
commit a14da39384
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 30 additions and 22 deletions

View File

@ -11,13 +11,12 @@
/**
* Javascript siphash implementation. Used for compact block relay.
* @param {Buffer} data - Blocks are uint64le's.
* @param {Buffer} k0 - Must be encoded as a uint64le.
* @param {Buffer} k1 - Must be encoded as a uint64le.
* @param {Buffer} data
* @param {Buffer} key - 128 bit key.
* @returns {Buffer} uint64le
*/
function siphash(data, k0, k1) {
function siphash(data, key) {
var blocks = Math.ceil(data.length / 8);
var c0 = U64(0x736f6d65, 0x70736575);
var c1 = U64(0x646f7261, 0x6e646f6d);
@ -25,11 +24,10 @@ function siphash(data, k0, k1) {
var c3 = U64(0x74656462, 0x79746573);
var f0 = U64(blocks << 27, 0);
var f1 = U64(0, 0xff);
var k0 = U64.fromRaw(key, 0);
var k1 = U64.fromRaw(key, 8);
var i, d, v0, v1, v2, v3;
k0 = U64.fromRaw(k0);
k1 = U64.fromRaw(k1);
// Init
v0 = c0.xor(k0);
v1 = c1.xor(k1);

View File

@ -36,8 +36,7 @@ function CompactBlock(options) {
this.available = [];
this.idMap = {};
this.count = 0;
this.k0 = null;
this.k1 = null;
this.sipKey = null;
this.timeout = null;
if (options)
@ -68,8 +67,7 @@ CompactBlock.prototype.fromOptions = function fromOptions(options) {
if (options.count)
this.count = options.count;
this.k0 = options.k0;
this.k1 = options.k1;
this.sipKey = options.sipKey;
this.initKey();
this.init();
@ -230,7 +228,7 @@ CompactBlock.prototype.sid = function sid(hash) {
if (typeof hash === 'string')
hash = new Buffer(hash, 'hex');
hash = siphash(hash, this.k0, this.k1);
hash = siphash(hash, this.sipKey);
return hash.readUInt32LE(0, true)
+ hash.readUInt16LE(4, true)
@ -242,10 +240,15 @@ CompactBlock.prototype.hasIndex = function hasIndex(index) {
};
CompactBlock.prototype.initKey = function initKey() {
var data = Buffer.concat([this.abbr(), this.keyNonce]);
var hash = utils.sha256(data);
this.k0 = hash.slice(0, 8);
this.k1 = hash.slice(8, 16);
var data = new Buffer(88);
var hash;
this.abbr().copy(data, 0);
this.keyNonce.copy(data, 80);
hash = utils.sha256(data);
this.sipKey = hash.slice(0, 16);
};
CompactBlock.prototype.init = function init() {
@ -329,7 +332,7 @@ CompactBlock.prototype.fromBlock = function fromBlock(block, nonce) {
this.totalTX = block.totalTX;
if (!nonce)
nonce = utils.nonce().toArrayLike(Buffer, 'be', 8);
nonce = utils.nonce(true);
this.keyNonce = nonce;
@ -554,7 +557,6 @@ TXResponse.prototype.toRaw = function toRaw(witness, writer) {
* @constructor
*/
// NOTE TO SELF: Protocol version >= 70014
function SendCompact(mode, version) {
if (!(this instanceof SendCompact))
return new SendCompact(mode, version);

View File

@ -1068,10 +1068,15 @@ utils.U64 = new bn('ffffffffffffffff', 'hex');
* @returns {BN}
*/
utils.nonce = function _nonce() {
utils.nonce = function _nonce(buffer) {
var nonce = new Buffer(8);
nonce.writeUInt32LE((Math.random() * 0x100000000) >>> 0, 0, true);
nonce.writeUInt32LE((Math.random() * 0x100000000) >>> 0, 4, true);
if (buffer)
return nonce;
return new bn(nonce);
};

View File

@ -8,20 +8,23 @@ describe('SipHash', function() {
it('should perform siphash with no data', function() {
var k0 = U64(0x07060504, 0x03020100).toRaw();
var k1 = U64(0x0f0e0d0c, 0x0b0a0908).toRaw();
assert.equal(siphash(new Buffer(0), k0, k1).toString('hex'), '310e0edd47db6f72');
var key = Buffer.concat([k0, k1]);
assert.equal(siphash(new Buffer(0), key).toString('hex'), '310e0edd47db6f72');
});
it('should perform siphash with data', function() {
var k0 = U64(0x07060504, 0x03020100).toRaw();
var k1 = U64(0x0f0e0d0c, 0x0b0a0908).toRaw();
var data = U64(0x07060504, 0x03020100).toRaw();
assert.equal(siphash(data, k0, k1).toString('hex'), '6224939a79f5f593');
var key = Buffer.concat([k0, k1]);
assert.equal(siphash(data, key).toString('hex'), '6224939a79f5f593');
});
it('should perform siphash with uint256', function() {
var k0 = U64(0x07060504, 0x03020100).toRaw();
var k1 = U64(0x0f0e0d0c, 0x0b0a0908).toRaw();
var hash = new Buffer('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex');
assert.equal(siphash(hash, k0, k1).toString('hex'), 'ce7cf2722f512771');
var key = Buffer.concat([k0, k1]);
assert.equal(siphash(hash, key).toString('hex'), 'ce7cf2722f512771');
});
});