Skip to content

Commit

Permalink
feat: change checksum address hashing algorithm
Browse files Browse the repository at this point in the history
changes the hashing algo for checksum addresses from pedersen to keccak
this enables more efficient address checksum computation on x86
  • Loading branch information
janek26 committed Aug 3, 2022
1 parent fe4e5b4 commit 0f32adf
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 5 deletions.
4 changes: 2 additions & 2 deletions __tests__/utils/address.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ describe('address checksums', () => {
'0x2fd23d9182193775423497fc0c472e156c57c69e4089a1967fb288a2d84e914'
);
expect(checksumAddress).toEqual(
'0x02FD23D9182193775423497Fc0c472E156C57C69E4089a1967fb288a2D84e914'
'0x02Fd23d9182193775423497fc0c472E156C57C69E4089A1967fb288A2d84e914'
);
});
test('should be able to verify checksum address', () => {
const isValid = validateChecksumAddress(
'0x02FD23D9182193775423497Fc0c472E156C57C69E4089a1967fb288a2D84e914'
'0x02Fd23d9182193775423497fc0c472E156C57C69E4089A1967fb288A2d84e914'
);
expect(isValid).toEqual(true);
});
Expand Down
4 changes: 2 additions & 2 deletions src/utils/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { arrayify } from '@ethersproject/bytes';

import { MASK_251, ZERO } from '../constants';
import { addHexPrefix, removeHexPrefix } from './encode';
import { pedersen } from './hash';
import { keccakBn } from './hash';
import { BigNumberish, assertInRange, toBN, toHex } from './number';

export function addAddressPadding(address: BigNumberish): string {
Expand All @@ -25,7 +25,7 @@ export function validateAndParseAddress(address: BigNumberish): string {
// from https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
export function getChecksumAddress(address: BigNumberish): string {
const chars = removeHexPrefix(validateAndParseAddress(address)).toLowerCase().split('');
const hashed = arrayify(pedersen([0, address]), { hexPad: 'left' }); // as the hash will be 251 bits (63 chars) we need to pad it to 64 chars without changing the number value ("left")
const hashed = arrayify(keccakBn(address), { hexPad: 'left' }); // in case the hash is 251 bits (63 chars) we need to pad it to 64 chars without changing the number value ("left")

for (let i = 0; i < chars.length; i += 2) {
if (hashed[i >> 1] >> 4 >= 8) {
Expand Down
9 changes: 8 additions & 1 deletion src/utils/hash.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import BN from 'bn.js';
import { keccak256 } from 'ethereum-cryptography/keccak';
import { hexToBytes } from 'ethereum-cryptography/utils';
import assert from 'minimalistic-assert';

import {
Expand All @@ -13,12 +14,18 @@ import {
} from '../constants';
import { RawCalldata } from '../types/lib';
import { ec } from './ellipticCurve';
import { addHexPrefix, buf2hex, utf8ToArray } from './encode';
import { addHexPrefix, buf2hex, removeHexPrefix, utf8ToArray } from './encode';
import { BigNumberish, toBN, toFelt, toHex } from './number';

export const transactionVersion = 0;
export const feeTransactionVersion = toBN(2).pow(toBN(128)).add(toBN(transactionVersion));

export function keccakBn(value: BigNumberish): string {
const hexWithoutPrefix = removeHexPrefix(toHex(toBN(value)));
const evenHex = hexWithoutPrefix.length % 2 === 0 ? hexWithoutPrefix : `0${hexWithoutPrefix}`;
return addHexPrefix(buf2hex(keccak256(hexToBytes(evenHex))));
}

function keccakHex(value: string): string {
return addHexPrefix(buf2hex(keccak256(utf8ToArray(value))));
}
Expand Down

0 comments on commit 0f32adf

Please sign in to comment.