bip152: refactor siphash.
This commit is contained in:
parent
319996a1ba
commit
a14da39384
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
|
||||
@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user