You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
5.2 KiB
205 lines
5.2 KiB
import { keccak224, keccak384, keccak256 as k256, keccak512 } from 'ethereum-cryptography/keccak'
|
|
const createHash = require('create-hash')
|
|
import { encode, Input } from 'rlp'
|
|
import { toBytes, setLengthLeft, isHexString } from '@ethereumjs/util'
|
|
|
|
/**
|
|
* Creates Keccak hash of a Uint8Array input
|
|
* @param a The input data (Uint8Array)
|
|
* @param bits (number = 256) The Keccak width
|
|
*/
|
|
export const keccak = function(a: Uint8Array, bits: number = 256): Uint8Array {
|
|
switch (bits) {
|
|
case 224: {
|
|
return toBytes(keccak224(Buffer.from(a)))
|
|
}
|
|
case 256: {
|
|
return toBytes(k256(Buffer.from(a)))
|
|
}
|
|
case 384: {
|
|
return toBytes(keccak384(Buffer.from(a)))
|
|
}
|
|
case 512: {
|
|
return toBytes(keccak512(Buffer.from(a)))
|
|
}
|
|
default: {
|
|
throw new Error(`Invalid algorithm: keccak${bits}`)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates Keccak-256 hash of the input, alias for keccak(a, 256).
|
|
* @param a The input data (Buffer)
|
|
*/
|
|
export const keccak256 = function(a: Buffer): Uint8Array {
|
|
return keccak(a)
|
|
}
|
|
|
|
/**
|
|
* Creates Keccak hash of a utf-8 string input
|
|
* @param a The input data (String)
|
|
* @param bits (number = 256) The Keccak width
|
|
*/
|
|
export const keccakFromString = function(a: string, bits: number = 256) {
|
|
assertIsString(a)
|
|
const buf = Buffer.from(a, 'utf8')
|
|
return keccak(buf, bits)
|
|
}
|
|
|
|
/**
|
|
* Creates Keccak hash of an 0x-prefixed string input
|
|
* @param a The input data (String)
|
|
* @param bits (number = 256) The Keccak width
|
|
*/
|
|
export const keccakFromHexString = function(a: string, bits: number = 256) {
|
|
assertIsHexString(a)
|
|
return keccak(Buffer.from(toBytes(a)), bits)
|
|
}
|
|
|
|
/**
|
|
* Creates Keccak hash of a number array input
|
|
* @param a The input data (number[])
|
|
* @param bits (number = 256) The Keccak width
|
|
*/
|
|
export const keccakFromArray = function(a: number[], bits: number = 256) {
|
|
assertIsArray(a)
|
|
return keccak(Buffer.from(toBytes(a)), bits)
|
|
}
|
|
|
|
/**
|
|
* Creates SHA256 hash of an input.
|
|
* @param a The input data (Buffer|Array|String)
|
|
*/
|
|
const _sha256 = function(a: any): Buffer {
|
|
a = toBytes(a)
|
|
return createHash('sha256')
|
|
.update(a)
|
|
.digest()
|
|
}
|
|
|
|
/**
|
|
* Creates SHA256 hash of a Buffer input.
|
|
* @param a The input data (Buffer)
|
|
*/
|
|
export const sha256 = function(a: Buffer): Buffer {
|
|
assertIsBuffer(a)
|
|
return _sha256(a)
|
|
}
|
|
|
|
/**
|
|
* Creates SHA256 hash of a string input.
|
|
* @param a The input data (string)
|
|
*/
|
|
export const sha256FromString = function(a: string): Buffer {
|
|
assertIsString(a)
|
|
return _sha256(a)
|
|
}
|
|
|
|
/**
|
|
* Creates SHA256 hash of a number[] input.
|
|
* @param a The input data (number[])
|
|
*/
|
|
export const sha256FromArray = function(a: number[]): Buffer {
|
|
assertIsArray(a)
|
|
return _sha256(a)
|
|
}
|
|
|
|
/**
|
|
* Creates RIPEMD160 hash of the input.
|
|
* @param a The input data (Buffer|Array|String|Number)
|
|
* @param padded Whether it should be padded to 256 bits or not
|
|
*/
|
|
const _ripemd160 = function(a: any, padded: boolean): Buffer {
|
|
a = toBytes(a)
|
|
const hash = createHash('rmd160')
|
|
.update(a)
|
|
.digest()
|
|
if (padded === true) {
|
|
return Buffer.from(setLengthLeft(hash, 32))
|
|
} else {
|
|
return hash
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates RIPEMD160 hash of a Buffer input.
|
|
* @param a The input data (Buffer)
|
|
* @param padded Whether it should be padded to 256 bits or not
|
|
*/
|
|
export const ripemd160 = function(a: Buffer, padded: boolean): Buffer {
|
|
assertIsBuffer(a)
|
|
return _ripemd160(a, padded)
|
|
}
|
|
|
|
/**
|
|
* Creates RIPEMD160 hash of a string input.
|
|
* @param a The input data (String)
|
|
* @param padded Whether it should be padded to 256 bits or not
|
|
*/
|
|
export const ripemd160FromString = function(a: string, padded: boolean): Buffer {
|
|
assertIsString(a)
|
|
return _ripemd160(a, padded)
|
|
}
|
|
|
|
/**
|
|
* Creates RIPEMD160 hash of a number[] input.
|
|
* @param a The input data (number[])
|
|
* @param padded Whether it should be padded to 256 bits or not
|
|
*/
|
|
export const ripemd160FromArray = function(a: number[], padded: boolean): Buffer {
|
|
assertIsArray(a)
|
|
return _ripemd160(a, padded)
|
|
}
|
|
|
|
/**
|
|
* Creates SHA-3 hash of the RLP encoded version of the input.
|
|
* @param a The input data
|
|
*/
|
|
export const rlphash = function(a: Input): Buffer {
|
|
return Buffer.from(keccak(Buffer.from(encode(a))))
|
|
}
|
|
|
|
/**
|
|
* Throws if a string is not hex prefixed
|
|
* @param {string} input string to check hex prefix of
|
|
*/
|
|
export const assertIsHexString = function(input: string): void {
|
|
if (!isHexString(input)) {
|
|
const msg = `This method only supports 0x-prefixed hex strings but input was: ${input}`
|
|
throw new Error(msg)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Throws if input is not a buffer
|
|
* @param {Buffer} input value to check
|
|
*/
|
|
export const assertIsBuffer = function(input: Buffer): void {
|
|
if (!Buffer.isBuffer(input)) {
|
|
const msg = `This method only supports Buffer but input was: ${input}`
|
|
throw new Error(msg)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Throws if input is not an array
|
|
* @param {number[]} input value to check
|
|
*/
|
|
export const assertIsArray = function(input: number[]): void {
|
|
if (!Array.isArray(input)) {
|
|
const msg = `This method only supports number arrays but input was: ${input}`
|
|
throw new Error(msg)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Throws if input is not a string
|
|
* @param {string} input value to check
|
|
*/
|
|
export const assertIsString = function(input: string): void {
|
|
if (typeof input !== 'string') {
|
|
const msg = `This method only supports strings but input was: ${input}`
|
|
throw new Error(msg)
|
|
}
|
|
} |