remix-project mirror
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.
 
 
 
 
 
remix-project/libs/remix-lib/src/hash.ts

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)
}
}