crypto: improve siphash u64 handling.

This commit is contained in:
Christopher Jeffrey 2017-06-01 08:44:16 -07:00
parent 95ac218ef2
commit a4a2ba7c6f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -145,84 +145,94 @@ if (native) {
}
/*
* Helpers
* U64
* @constructor
* @ignore
*/
function U64(hi, lo) {
if (!(this instanceof U64))
return new U64(hi, lo);
this.hi = hi || 0;
this.lo = lo || 0;
this.hi = 0;
this.lo = 0;
this.join(hi, lo);
}
U64.prototype.add = function add(b) {
var r, carry;
r = this.lo + b.lo;
carry = (r - (r % 0x100000000)) / 0x100000000;
this.hi = (this.hi + b.hi + carry) & 0xffffffff;
this.lo = r & 0xffffffff;
if (this.hi < 0)
this.hi += 0x100000000;
if (this.lo < 0)
this.lo += 0x100000000;
U64.prototype.join = function join(hi, lo) {
this.hi = hi >>> 0;
this.lo = lo >>> 0;
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) {
this.hi ^= b.hi;
this.lo ^= b.lo;
if (this.hi < 0)
this.hi += 0x100000000;
if (this.lo < 0)
this.lo += 0x100000000;
return this;
return this.join(this.hi ^ b.hi, this.lo ^ b.lo);
};
U64.prototype.rotl = function rotl(b) {
var h1, l1, h2, l2, c;
U64.prototype.rotl = function rotl(bits) {
var ahi = this.hi;
var alo = this.lo;
var bhi = this.hi;
var blo = this.lo;
// v1 = x << b
if (b < 32) {
h1 = this.hi << b;
c = this.lo >>> (32 - b);
l1 = this.lo << b;
h1 |= c;
// a = x << b
if (bits < 32) {
ahi <<= bits;
ahi |= alo >>> (32 - bits);
alo <<= bits;
} else {
h1 = this.lo << (b - 32);
l1 = 0;
ahi = alo << (bits - 32);
alo = 0;
}
// v2 = x >> (64 - b)
b = 64 - b;
if (b < 32) {
h2 = this.hi >>> b;
c = this.hi & (0xffffffff >>> (32 - b));
l2 = this.lo >>> b;
l2 |= c << (32 - b);
bits = 64 - bits;
// b = x >> (64 - b)
if (bits < 32) {
blo >>>= bits;
blo |= bhi << (32 - bits);
bhi >>>= bits;
} else {
h2 = 0;
l2 = this.hi >>> (b - 32);
blo = bhi >>> (bits - 32);
bhi = 0;
}
// v1 | v2
this.hi = h1 | h2;
this.lo = l1 | l2;
if (this.hi < 0)
this.hi += 0x100000000;
if (this.lo < 0)
this.lo += 0x100000000;
return this;
// a | b
return this.join(ahi | bhi, alo | blo);
};
U64.prototype.toRaw = function toRaw() {