All files / src hash_onion.ts

90.91% Statements 20/22
75% Branches 6/8
100% Functions 2/2
90.48% Lines 19/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57                              2x 2x   2x 2x 2x 2x   2x 4x   2x         2x           2x         2x 2x     2x 1001000x 1001000x 2000x   1001000x     2x    
/*
 * Copyright © 2020 Lisk Foundation
 *
 * See the LICENSE file at the top-level directory of this distribution
 * for licensing information.
 *
 * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation,
 * no part of this software, including this file, may be copied, modified,
 * propagated, or distributed except according to the terms contained in the
 * LICENSE file.
 *
 * Removal or modification of this copyright notice is prohibited.
 *
 */
 
import { hash } from './hash';
import { getRandomBytes } from './nacl';
 
const HASH_SIZE = 16;
const INPUT_SIZE = 64;
const defaultCount = 1000000;
const defaultDistance = 1000;
 
export const generateHashOnionSeed = () =>
	hash(getRandomBytes(INPUT_SIZE)).slice(0, HASH_SIZE);
 
export const hashOnion = (
	seed: Buffer,
	count: number = defaultCount,
	distance: number = defaultDistance,
): ReadonlyArray<Buffer> => {
	Iif (count < distance) {
		throw new Error(
			'Invalid count or distance. Count must be greater than distance',
		);
	}
 
	Iif (count % distance !== 0) {
		throw new Error('Invalid count. Count must be multiple of distance');
	}
 
	// tslint:disable-next-line no-let
	let previousHash = seed;
	const hashes = [seed];
 
	// tslint:disable-next-line no-let
	for (let i = 1; i <= count; i += 1) {
		const nextHash = hash(previousHash).slice(0, HASH_SIZE);
		if (i % distance === 0) {
			hashes.push(nextHash);
		}
		previousHash = nextHash;
	}
 
	return hashes.reverse();
};