Skip to content

Commit 258eef5

Browse files
committed
feat: add hash account key
1 parent 2e5eb01 commit 258eef5

File tree

2 files changed

+22
-19
lines changed

2 files changed

+22
-19
lines changed

contracts/src/libraries/SparseMerkleProof.sol

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,20 @@ library SparseMerkleProof {
113113
}
114114

115115
/**
116-
* @notice Hashes account or storage key.
117-
* @dev If the input represents an address (20 bytes), it must be right padded to 32 bytes before hashing.
118-
* @param _value The value to be hashed.
119-
* @return bytes32 Value hash.
116+
* @notice Hashes an account key (address) using the Poseidon2 hash function.
117+
* @dev Matches gnark-crypto's left-padding of partial Merkle-Damgard blocks.
118+
* @param _addr The address to be hashed as the account key.
119+
* @return Value hash as bytes32.
120120
*/
121-
function hashKey(bytes32 _value) external pure returns (bytes32) {
122-
return Poseidon2.hash(Poseidon2.padBytes32(_value));
121+
function hashAccountKey(address _addr) external pure returns (bytes32) {
122+
bytes memory padded = Poseidon2.padBytes32(bytes32(bytes20(_addr)));
123+
bytes32 word1;
124+
bytes32 word2;
125+
assembly {
126+
word1 := mload(add(padded, 0x20))
127+
word2 := mload(add(padded, 0x40))
128+
}
129+
return Poseidon2.hash(abi.encodePacked(word1, bytes32(uint256(word2) >> 192)));
123130
}
124131

125132
/**
@@ -179,6 +186,7 @@ library SparseMerkleProof {
179186
/**
180187
* @notice Format proof.
181188
* @param _rawProof Non formatted proof array.
189+
* @return nextFreeNode Next free node.
182190
* @return formattedNodes bytes32[2] NextFreeNode.
183191
* @return leafHash Leaf hash extracted from the proof.
184192
* @return proof Formatted proof array.

contracts/test/hardhat/libraries/SparseMerkleProof.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Poseidon2, SparseMerkleProof } from "../../../typechain-types";
55
import merkleProofTestData from "../_testData/merkle-proof-data-poseidon2.json";
66
import { deployFromFactory } from "../common/deployment";
77
import { expectRevertWithCustomError } from "../common/helpers";
8-
import { dataSlice, zeroPadBytes } from "ethers";
8+
import { dataSlice } from "ethers";
99

1010
describe("SparseMerkleProof", () => {
1111
let sparseMerkleProof: SparseMerkleProof;
@@ -325,24 +325,19 @@ describe("SparseMerkleProof", () => {
325325
});
326326
});
327327

328-
describe("hashKey", () => {
328+
describe("hashAccountKey", () => {
329329
it("Should return account key hash", async () => {
330330
const {
331331
accountProof: { key },
332332
} = merkleProofTestData;
333333

334-
const rightPaddedKey = zeroPadBytes(key, 32);
335-
const hKey = await sparseMerkleProof.hashKey(rightPaddedKey);
334+
const hKey = await sparseMerkleProof.hashAccountKey(key);
336335
expect(hKey).to.be.equal(ACCOUNT_KEY_HASH);
337336
});
338337

339-
it("Should return storage key hash", async () => {
340-
const {
341-
storageProofs: [{ key }],
342-
} = merkleProofTestData;
343-
344-
const hKey = await sparseMerkleProof.hashKey(key);
345-
expect(hKey).to.be.equal(STORAGE_KEY_HASH);
338+
it("Should return account key hash for addresses with non zero 14-19 bytes", async () => {
339+
const hKey = await sparseMerkleProof.hashAccountKey("0x67feaf59f9a311707d935dda2f10a9c577398e34");
340+
expect(hKey).to.be.equal("0x3bc7a71c1f207312790ba36858f144e630cd7cb0703a0d3569a128a923bbfb35");
346341
});
347342
});
348343

@@ -385,7 +380,7 @@ describe("SparseMerkleProof", () => {
385380
} = merkleProofTestData;
386381

387382
const leaf = await sparseMerkleProof.getLeaf(proofRelatedNodes[proofRelatedNodes.length - 1]);
388-
const expectedHKey = await sparseMerkleProof.hashKey(zeroPadBytes(key, 32));
383+
const expectedHKey = await sparseMerkleProof.hashAccountKey(key);
389384
const expectedHValue = await sparseMerkleProof.hashAccountValue(value);
390385

391386
expect(leaf.prev[0]).to.be.equal(0n);
@@ -427,7 +422,7 @@ describe("SparseMerkleProof", () => {
427422
} = merkleProofTestData;
428423

429424
const leaf = await sparseMerkleProof.getLeaf(proofRelatedNodes[proofRelatedNodes.length - 1]);
430-
const expectedHKey = await sparseMerkleProof.hashKey(zeroPadBytes(key, 32));
425+
const expectedHKey = await sparseMerkleProof.hashStorageValue(key);
431426
const expectedHValue = await sparseMerkleProof.hashStorageValue(value);
432427

433428
expect(leaf.prev[0]).to.be.equal(0n);

0 commit comments

Comments
 (0)