- Add GETTING_STARTED.md with quick start guide and development modes - Add INSTALL.sh automated installation script - Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md - Add QUICK_REFERENCE.md for common commands - Add SETUP_GUIDE.md with detailed setup instructions - Update README.md with improved project overview - Add did-wallet app dependencies and node_modules
75 lines
2.5 KiB
JavaScript
75 lines
2.5 KiB
JavaScript
import { concat as uint8ArrayConcat } from 'uint8arrays/concat';
|
|
import { ConsumableBuffer } from './consumable-buffer.js';
|
|
export function wrapHash(hashFn) {
|
|
function hashing(value) {
|
|
if (value instanceof InfiniteHash) {
|
|
// already a hash. return it
|
|
return value;
|
|
}
|
|
else {
|
|
return new InfiniteHash(value, hashFn);
|
|
}
|
|
}
|
|
return hashing;
|
|
}
|
|
export class InfiniteHash {
|
|
_value;
|
|
_hashFn;
|
|
_depth;
|
|
_availableBits;
|
|
_currentBufferIndex;
|
|
_buffers;
|
|
constructor(value, hashFn) {
|
|
if (!(value instanceof Uint8Array)) {
|
|
throw new Error('can only hash Uint8Arrays');
|
|
}
|
|
this._value = value;
|
|
this._hashFn = hashFn;
|
|
this._depth = -1;
|
|
this._availableBits = 0;
|
|
this._currentBufferIndex = 0;
|
|
this._buffers = [];
|
|
}
|
|
async take(bits) {
|
|
let pendingBits = bits;
|
|
while (this._availableBits < pendingBits) {
|
|
await this._produceMoreBits();
|
|
}
|
|
let result = 0;
|
|
while (pendingBits > 0) {
|
|
const hash = this._buffers[this._currentBufferIndex];
|
|
const available = Math.min(hash.availableBits(), pendingBits);
|
|
const took = hash.take(available);
|
|
result = (result << available) + took;
|
|
pendingBits -= available;
|
|
this._availableBits -= available;
|
|
if (hash.availableBits() === 0) {
|
|
this._currentBufferIndex++;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
untake(bits) {
|
|
let pendingBits = bits;
|
|
while (pendingBits > 0) {
|
|
const hash = this._buffers[this._currentBufferIndex];
|
|
const availableForUntake = Math.min(hash.totalBits() - hash.availableBits(), pendingBits);
|
|
hash.untake(availableForUntake);
|
|
pendingBits -= availableForUntake;
|
|
this._availableBits += availableForUntake;
|
|
if (this._currentBufferIndex > 0 && hash.totalBits() === hash.availableBits()) {
|
|
this._depth--;
|
|
this._currentBufferIndex--;
|
|
}
|
|
}
|
|
}
|
|
async _produceMoreBits() {
|
|
this._depth++;
|
|
const value = this._depth > 0 ? uint8ArrayConcat([this._value, Uint8Array.from([this._depth])]) : this._value;
|
|
const hashValue = await this._hashFn(value);
|
|
const buffer = new ConsumableBuffer(hashValue);
|
|
this._buffers.push(buffer);
|
|
this._availableBits += buffer.availableBits();
|
|
}
|
|
}
|
|
//# sourceMappingURL=consumable-hash.js.map
|