| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 | 
							- import { exists, output } from './_assert.js';
 
- import { Hash, createView, toBytes } from './utils.js';
 
- // Polyfill for Safari 14
 
- function setBigUint64(view, byteOffset, value, isLE) {
 
-     if (typeof view.setBigUint64 === 'function')
 
-         return view.setBigUint64(byteOffset, value, isLE);
 
-     const _32n = BigInt(32);
 
-     const _u32_max = BigInt(0xffffffff);
 
-     const wh = Number((value >> _32n) & _u32_max);
 
-     const wl = Number(value & _u32_max);
 
-     const h = isLE ? 4 : 0;
 
-     const l = isLE ? 0 : 4;
 
-     view.setUint32(byteOffset + h, wh, isLE);
 
-     view.setUint32(byteOffset + l, wl, isLE);
 
- }
 
- // Choice: a ? b : c
 
- export const Chi = (a, b, c) => (a & b) ^ (~a & c);
 
- // Majority function, true if any two inpust is true
 
- export const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
 
- /**
 
-  * Merkle-Damgard hash construction base class.
 
-  * Could be used to create MD5, RIPEMD, SHA1, SHA2.
 
-  */
 
- export class HashMD extends Hash {
 
-     constructor(blockLen, outputLen, padOffset, isLE) {
 
-         super();
 
-         this.blockLen = blockLen;
 
-         this.outputLen = outputLen;
 
-         this.padOffset = padOffset;
 
-         this.isLE = isLE;
 
-         this.finished = false;
 
-         this.length = 0;
 
-         this.pos = 0;
 
-         this.destroyed = false;
 
-         this.buffer = new Uint8Array(blockLen);
 
-         this.view = createView(this.buffer);
 
-     }
 
-     update(data) {
 
-         exists(this);
 
-         const { view, buffer, blockLen } = this;
 
-         data = toBytes(data);
 
-         const len = data.length;
 
-         for (let pos = 0; pos < len;) {
 
-             const take = Math.min(blockLen - this.pos, len - pos);
 
-             // Fast path: we have at least one block in input, cast it to view and process
 
-             if (take === blockLen) {
 
-                 const dataView = createView(data);
 
-                 for (; blockLen <= len - pos; pos += blockLen)
 
-                     this.process(dataView, pos);
 
-                 continue;
 
-             }
 
-             buffer.set(data.subarray(pos, pos + take), this.pos);
 
-             this.pos += take;
 
-             pos += take;
 
-             if (this.pos === blockLen) {
 
-                 this.process(view, 0);
 
-                 this.pos = 0;
 
-             }
 
-         }
 
-         this.length += data.length;
 
-         this.roundClean();
 
-         return this;
 
-     }
 
-     digestInto(out) {
 
-         exists(this);
 
-         output(out, this);
 
-         this.finished = true;
 
-         // Padding
 
-         // We can avoid allocation of buffer for padding completely if it
 
-         // was previously not allocated here. But it won't change performance.
 
-         const { buffer, view, blockLen, isLE } = this;
 
-         let { pos } = this;
 
-         // append the bit '1' to the message
 
-         buffer[pos++] = 0b10000000;
 
-         this.buffer.subarray(pos).fill(0);
 
-         // we have less than padOffset left in buffer, so we cannot put length in
 
-         // current block, need process it and pad again
 
-         if (this.padOffset > blockLen - pos) {
 
-             this.process(view, 0);
 
-             pos = 0;
 
-         }
 
-         // Pad until full block byte with zeros
 
-         for (let i = pos; i < blockLen; i++)
 
-             buffer[i] = 0;
 
-         // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
 
-         // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
 
-         // So we just write lowest 64 bits of that value.
 
-         setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
 
-         this.process(view, 0);
 
-         const oview = createView(out);
 
-         const len = this.outputLen;
 
-         // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
 
-         if (len % 4)
 
-             throw new Error('_sha2: outputLen should be aligned to 32bit');
 
-         const outLen = len / 4;
 
-         const state = this.get();
 
-         if (outLen > state.length)
 
-             throw new Error('_sha2: outputLen bigger than state');
 
-         for (let i = 0; i < outLen; i++)
 
-             oview.setUint32(4 * i, state[i], isLE);
 
-     }
 
-     digest() {
 
-         const { buffer, outputLen } = this;
 
-         this.digestInto(buffer);
 
-         const res = buffer.slice(0, outputLen);
 
-         this.destroy();
 
-         return res;
 
-     }
 
-     _cloneInto(to) {
 
-         to || (to = new this.constructor());
 
-         to.set(...this.get());
 
-         const { blockLen, buffer, length, finished, destroyed, pos } = this;
 
-         to.length = length;
 
-         to.pos = pos;
 
-         to.finished = finished;
 
-         to.destroyed = destroyed;
 
-         if (length % blockLen)
 
-             to.buffer.set(buffer);
 
-         return to;
 
-     }
 
- }
 
- //# sourceMappingURL=_md.js.map
 
 
  |