diff --git a/lib/crypto/poly1305.js b/lib/crypto/poly1305.js index 29248e4b..a3b96cf7 100644 --- a/lib/crypto/poly1305.js +++ b/lib/crypto/poly1305.js @@ -104,10 +104,13 @@ Poly1305.prototype.blocks = function blocks(data, bytes, m) { // h *= r, (partial) h %= p for (let i = 0; i < 10; i++) { d[i] = c; + for (let j = 0; j < 10; j++) { - d[i] += this.h[j] * (j <= i - ? this.r[i - j] - : 5 * this.r[i + 10 - j]); + if (j <= i) + d[i] += this.r[i - j]; + else + d[i] += 5 * this.r[i + 10 - j]); + // Sum(h[i] * r[i] * 5) will overflow slightly // above 6 products with an unclamped r, so // carry at 5 @@ -116,9 +119,11 @@ Poly1305.prototype.blocks = function blocks(data, bytes, m) { d[i] &= 0x1fff; } } + c += d[i] >>> 13; d[i] &= 0x1fff; } + c = (c << 2) + c; // c *= 5 c += d[0]; d[0] = (c & 0x1fff); @@ -146,15 +151,21 @@ Poly1305.prototype.update = function update(data) { // handle leftover if (this.leftover) { let want = 16 - this.leftover; + if (want > bytes) want = bytes; + for (let i = 0; i < want; i++) this.buffer[this.leftover + i] = data[m + i]; + bytes -= want; m += want; + this.leftover += want; + if (this.leftover < 16) return; + this.blocks(this.buffer, 16, 0); this.leftover = 0; }