diff --git a/src/hash.ts b/src/hash.ts index 2c2e32de..e9e40ca7 100644 --- a/src/hash.ts +++ b/src/hash.ts @@ -3,7 +3,7 @@ const createHash = require('create-hash') const ethjsUtil = require('ethjs-util') import * as rlp from 'rlp' import { toBuffer, setLengthLeft } from './bytes' -import { assertIsString, assertIsBuffer, assertIsArray } from './helpers' +import { assertIsString, assertIsBuffer, assertIsArray, assertIsHexString } from './helpers' /** * Creates Keccak hash of a Buffer input @@ -26,23 +26,26 @@ export const keccak256 = function(a: Buffer): Buffer { } /** - * Creates Keccak hash of a String input - * @param a The input data (String) If string is 0x-prefixed hex value it's - * interpreted as hexadecimal, otherwise as utf8. + * 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) - let buf - if (!ethjsUtil.isHexString(a)) { - buf = Buffer.from(a, 'utf8') - } else { - buf = toBuffer(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(toBuffer(a), bits) +} + /** * Creates Keccak hash of a number array input * @param a The input data (number[]) diff --git a/test/hash.spec.ts b/test/hash.spec.ts index b7dad973..a76d0c90 100644 --- a/test/hash.spec.ts +++ b/test/hash.spec.ts @@ -3,6 +3,7 @@ import { keccak, keccak256, keccakFromString, + keccakFromHexString, keccakFromArray, sha256, sha256FromString, @@ -39,13 +40,7 @@ describe('keccak256', function() { }) describe('keccakFromString', function() { - it('with hexprefix should produce a hash', function() { - const msg = '0x3c9229289a6125f7fdf1885a77bb12c37a8d3b4962d936f7e3084dece32a3ca1' - const r = '82ff40c0a986c6a5cfad4ddf4c3aa6996f1a7837f9c398e17e5de5cbd5a12b28' - const hash = keccakFromString(msg) - assert.equal(hash.toString('hex'), r) - }) - it('without hexprefix should produce a hash', function() { + it('should produce a hash', function() { const msg = '3c9229289a6125f7fdf1885a77bb12c37a8d3b4962d936f7e3084dece32a3ca1' const r = '22ae1937ff93ec72c4d46ff3e854661e3363440acd6f6e4adf8f1a8978382251' const hash = keccakFromString(msg) @@ -59,6 +54,27 @@ describe('keccakFromString', function() { }) }) +describe('keccakFromHexString', function() { + it('should produce a hash', function() { + const msg = '0x3c9229289a6125f7fdf1885a77bb12c37a8d3b4962d936f7e3084dece32a3ca1' + const r = '82ff40c0a986c6a5cfad4ddf4c3aa6996f1a7837f9c398e17e5de5cbd5a12b28' + const hash = keccakFromHexString(msg) + assert.equal(hash.toString('hex'), r) + }) + it('should throw if input is not hex-prefixed', function() { + const msg = '3c9229289a6125f7fdf1885a77bb12c37a8d3b4962d936f7e3084dece32a3ca1' + assert.throws(function() { + keccakFromHexString(msg) + }) + }) + it('should throw if input is not a string', function() { + const buf = toBuffer('0x3c9229289a6125f7fdf1885a77bb12c37a8d3b4962d936f7e3084dece32a3ca1') + assert.throws(function() { + keccakFromHexString((buf) as string) + }) + }) +}) + describe('keccakFromArray', function() { it('should produce a hash', function() { const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 0]