bip152: refactor siphash.
This commit is contained in:
parent
319996a1ba
commit
a14da39384
@ -11,13 +11,12 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Javascript siphash implementation. Used for compact block relay.
|
* Javascript siphash implementation. Used for compact block relay.
|
||||||
* @param {Buffer} data - Blocks are uint64le's.
|
* @param {Buffer} data
|
||||||
* @param {Buffer} k0 - Must be encoded as a uint64le.
|
* @param {Buffer} key - 128 bit key.
|
||||||
* @param {Buffer} k1 - Must be encoded as a uint64le.
|
|
||||||
* @returns {Buffer} uint64le
|
* @returns {Buffer} uint64le
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function siphash(data, k0, k1) {
|
function siphash(data, key) {
|
||||||
var blocks = Math.ceil(data.length / 8);
|
var blocks = Math.ceil(data.length / 8);
|
||||||
var c0 = U64(0x736f6d65, 0x70736575);
|
var c0 = U64(0x736f6d65, 0x70736575);
|
||||||
var c1 = U64(0x646f7261, 0x6e646f6d);
|
var c1 = U64(0x646f7261, 0x6e646f6d);
|
||||||
@ -25,11 +24,10 @@ function siphash(data, k0, k1) {
|
|||||||
var c3 = U64(0x74656462, 0x79746573);
|
var c3 = U64(0x74656462, 0x79746573);
|
||||||
var f0 = U64(blocks << 27, 0);
|
var f0 = U64(blocks << 27, 0);
|
||||||
var f1 = U64(0, 0xff);
|
var f1 = U64(0, 0xff);
|
||||||
|
var k0 = U64.fromRaw(key, 0);
|
||||||
|
var k1 = U64.fromRaw(key, 8);
|
||||||
var i, d, v0, v1, v2, v3;
|
var i, d, v0, v1, v2, v3;
|
||||||
|
|
||||||
k0 = U64.fromRaw(k0);
|
|
||||||
k1 = U64.fromRaw(k1);
|
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
v0 = c0.xor(k0);
|
v0 = c0.xor(k0);
|
||||||
v1 = c1.xor(k1);
|
v1 = c1.xor(k1);
|
||||||
|
|||||||
@ -36,8 +36,7 @@ function CompactBlock(options) {
|
|||||||
this.available = [];
|
this.available = [];
|
||||||
this.idMap = {};
|
this.idMap = {};
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
this.k0 = null;
|
this.sipKey = null;
|
||||||
this.k1 = null;
|
|
||||||
this.timeout = null;
|
this.timeout = null;
|
||||||
|
|
||||||
if (options)
|
if (options)
|
||||||
@ -68,8 +67,7 @@ CompactBlock.prototype.fromOptions = function fromOptions(options) {
|
|||||||
if (options.count)
|
if (options.count)
|
||||||
this.count = options.count;
|
this.count = options.count;
|
||||||
|
|
||||||
this.k0 = options.k0;
|
this.sipKey = options.sipKey;
|
||||||
this.k1 = options.k1;
|
|
||||||
|
|
||||||
this.initKey();
|
this.initKey();
|
||||||
this.init();
|
this.init();
|
||||||
@ -230,7 +228,7 @@ CompactBlock.prototype.sid = function sid(hash) {
|
|||||||
if (typeof hash === 'string')
|
if (typeof hash === 'string')
|
||||||
hash = new Buffer(hash, 'hex');
|
hash = new Buffer(hash, 'hex');
|
||||||
|
|
||||||
hash = siphash(hash, this.k0, this.k1);
|
hash = siphash(hash, this.sipKey);
|
||||||
|
|
||||||
return hash.readUInt32LE(0, true)
|
return hash.readUInt32LE(0, true)
|
||||||
+ hash.readUInt16LE(4, true)
|
+ hash.readUInt16LE(4, true)
|
||||||
@ -242,10 +240,15 @@ CompactBlock.prototype.hasIndex = function hasIndex(index) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CompactBlock.prototype.initKey = function initKey() {
|
CompactBlock.prototype.initKey = function initKey() {
|
||||||
var data = Buffer.concat([this.abbr(), this.keyNonce]);
|
var data = new Buffer(88);
|
||||||
var hash = utils.sha256(data);
|
var hash;
|
||||||
this.k0 = hash.slice(0, 8);
|
|
||||||
this.k1 = hash.slice(8, 16);
|
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() {
|
CompactBlock.prototype.init = function init() {
|
||||||
@ -329,7 +332,7 @@ CompactBlock.prototype.fromBlock = function fromBlock(block, nonce) {
|
|||||||
this.totalTX = block.totalTX;
|
this.totalTX = block.totalTX;
|
||||||
|
|
||||||
if (!nonce)
|
if (!nonce)
|
||||||
nonce = utils.nonce().toArrayLike(Buffer, 'be', 8);
|
nonce = utils.nonce(true);
|
||||||
|
|
||||||
this.keyNonce = nonce;
|
this.keyNonce = nonce;
|
||||||
|
|
||||||
@ -554,7 +557,6 @@ TXResponse.prototype.toRaw = function toRaw(witness, writer) {
|
|||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// NOTE TO SELF: Protocol version >= 70014
|
|
||||||
function SendCompact(mode, version) {
|
function SendCompact(mode, version) {
|
||||||
if (!(this instanceof SendCompact))
|
if (!(this instanceof SendCompact))
|
||||||
return new SendCompact(mode, version);
|
return new SendCompact(mode, version);
|
||||||
|
|||||||
@ -1068,10 +1068,15 @@ utils.U64 = new bn('ffffffffffffffff', 'hex');
|
|||||||
* @returns {BN}
|
* @returns {BN}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
utils.nonce = function _nonce() {
|
utils.nonce = function _nonce(buffer) {
|
||||||
var nonce = new Buffer(8);
|
var nonce = new Buffer(8);
|
||||||
|
|
||||||
nonce.writeUInt32LE((Math.random() * 0x100000000) >>> 0, 0, true);
|
nonce.writeUInt32LE((Math.random() * 0x100000000) >>> 0, 0, true);
|
||||||
nonce.writeUInt32LE((Math.random() * 0x100000000) >>> 0, 4, true);
|
nonce.writeUInt32LE((Math.random() * 0x100000000) >>> 0, 4, true);
|
||||||
|
|
||||||
|
if (buffer)
|
||||||
|
return nonce;
|
||||||
|
|
||||||
return new bn(nonce);
|
return new bn(nonce);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -8,20 +8,23 @@ describe('SipHash', function() {
|
|||||||
it('should perform siphash with no data', function() {
|
it('should perform siphash with no data', function() {
|
||||||
var k0 = U64(0x07060504, 0x03020100).toRaw();
|
var k0 = U64(0x07060504, 0x03020100).toRaw();
|
||||||
var k1 = U64(0x0f0e0d0c, 0x0b0a0908).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() {
|
it('should perform siphash with data', function() {
|
||||||
var k0 = U64(0x07060504, 0x03020100).toRaw();
|
var k0 = U64(0x07060504, 0x03020100).toRaw();
|
||||||
var k1 = U64(0x0f0e0d0c, 0x0b0a0908).toRaw();
|
var k1 = U64(0x0f0e0d0c, 0x0b0a0908).toRaw();
|
||||||
var data = U64(0x07060504, 0x03020100).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() {
|
it('should perform siphash with uint256', function() {
|
||||||
var k0 = U64(0x07060504, 0x03020100).toRaw();
|
var k0 = U64(0x07060504, 0x03020100).toRaw();
|
||||||
var k1 = U64(0x0f0e0d0c, 0x0b0a0908).toRaw();
|
var k1 = U64(0x0f0e0d0c, 0x0b0a0908).toRaw();
|
||||||
var hash = new Buffer('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex');
|
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');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user