crypto: better addition for siphash.

This commit is contained in:
Christopher Jeffrey 2017-06-03 03:41:06 -07:00
parent a4a2ba7c6f
commit f0b43764b1
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -37,19 +37,19 @@ function siphash24(data, key, shift) {
var i, d, v0, v1, v2, v3;
// Init
v0 = c0.xor(k0);
v1 = c1.xor(k1);
v2 = c2.xor(k0);
v3 = c3.xor(k1);
v0 = c0.ixor(k0);
v1 = c1.ixor(k1);
v2 = c2.ixor(k0);
v3 = c3.ixor(k1);
// Blocks
for (i = 0; i < blocks; i++) {
d = U64.fromRaw(data, p);
p += 8;
v3.xor(d);
v3.ixor(d);
sipround(v0, v1, v2, v3);
sipround(v0, v1, v2, v3);
v0.xor(d);
v0.ixor(d);
}
switch (data.length & 7) {
@ -58,7 +58,7 @@ function siphash24(data, key, shift) {
case 6:
f0.hi |= data[p + 5] << 8;
case 5:
f0.hi |= data[p + 4] << 0;
f0.hi |= data[p + 4];
case 4:
f0.lo |= data[p + 3] << 24;
case 3:
@ -66,53 +66,46 @@ function siphash24(data, key, shift) {
case 2:
f0.lo |= data[p + 1] << 8;
case 1:
f0.lo |= data[p + 0] << 0;
if (f0.lo < 0)
f0.lo += 0x100000000;
if (f0.hi < 0)
f0.hi += 0x100000000;
break;
case 0:
break;
f0.lo |= data[p];
}
// Finalization
v3.xor(f0);
v3.ixor(f0);
sipround(v0, v1, v2, v3);
sipround(v0, v1, v2, v3);
v0.xor(f0);
v2.xor(f1);
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.xor(v1);
v0.xor(v2);
v0.xor(v3);
v0.ixor(v1);
v0.ixor(v2);
v0.ixor(v3);
return v0.toRaw();
}
function sipround(v0, v1, v2, v3) {
v0.add(v1);
v1.rotl(13);
v1.xor(v0);
v0.iadd(v1);
v1.irotl(13);
v1.ixor(v0);
v0.rotl(32);
v0.irotl(32);
v2.add(v3);
v3.rotl(16);
v3.xor(v2);
v2.iadd(v3);
v3.irotl(16);
v3.ixor(v2);
v0.add(v3);
v3.rotl(21);
v3.xor(v0);
v0.iadd(v3);
v3.irotl(21);
v3.ixor(v0);
v2.add(v1);
v1.rotl(17);
v1.xor(v2);
v2.iadd(v1);
v1.irotl(17);
v1.ixor(v2);
v2.rotl(32);
v2.irotl(32);
}
/**
@ -154,56 +147,31 @@ function U64(hi, lo) {
if (!(this instanceof U64))
return new U64(hi, lo);
this.hi = 0;
this.lo = 0;
this.join(hi, lo);
this.hi = hi | 0;
this.lo = lo | 0;
}
U64.prototype.join = function join(hi, lo) {
this.hi = hi >>> 0;
this.lo = lo >>> 0;
U64.prototype.iadd = function iadd(b) {
var a = this;
var sum, c;
// Credit to @indutny for this method.
sum = (a.lo >>> 0) + (b.lo >>> 0);
c = (sum >= 0x100000000) | 0;
a.hi = (((a.hi + b.hi) | 0) + c) | 0;
a.lo = sum | 0;
return a;
};
U64.prototype.ixor = function ixor(b) {
this.hi ^= b.hi;
this.lo ^= b.lo;
return this;
};
U64.prototype.add = function add(b) {
var a = this;
var a48 = a.hi >>> 16;
var a32 = a.hi & 0xffff;
var a16 = a.lo >>> 16;
var a00 = a.lo & 0xffff;
var b48 = b.hi >>> 16;
var b32 = b.hi & 0xffff;
var b16 = b.lo >>> 16;
var b00 = b.lo & 0xffff;
var c48 = 0;
var c32 = 0;
var c16 = 0;
var c00 = 0;
var hi, lo;
c00 += a00 + b00;
c16 += c00 >>> 16;
c00 &= 0xffff;
c16 += a16 + b16;
c32 += c16 >>> 16;
c16 &= 0xffff;
c32 += a32 + b32;
c48 += c32 >>> 16;
c32 &= 0xffff;
c48 += a48 + b48;
c48 &= 0xffff;
hi = (c48 << 16) | c32;
lo = (c16 << 16) | c00;
return a.join(hi, lo);
};
U64.prototype.xor = function xor(b) {
return this.join(this.hi ^ b.hi, this.lo ^ b.lo);
};
U64.prototype.rotl = function rotl(bits) {
U64.prototype.irotl = function irotl(bits) {
var ahi = this.hi;
var alo = this.lo;
var bhi = this.hi;
@ -232,13 +200,16 @@ U64.prototype.rotl = function rotl(bits) {
}
// a | b
return this.join(ahi | bhi, alo | blo);
this.hi = ahi | bhi;
this.lo = alo | blo;
return this;
};
U64.prototype.toRaw = function toRaw() {
var data = Buffer.allocUnsafe(8);
data.writeUInt32LE(this.hi, 4, true);
data.writeUInt32LE(this.lo, 0, true);
data.writeUInt32LE(this.hi >>> 0, 4, true);
data.writeUInt32LE(this.lo >>> 0, 0, true);
return data;
};