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