/
Poseidon.sol
85 lines (70 loc) · 2.49 KB
/
Poseidon.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.20;
library PoseidonUnit1L {
function poseidon(uint256[1] calldata) public pure returns (uint256) {}
}
library PoseidonUnit2L {
function poseidon(uint256[2] calldata) public pure returns (uint256) {}
}
library PoseidonUnit3L {
function poseidon(uint256[3] calldata) public pure returns (uint256) {}
}
library PoseidonUnit4L {
function poseidon(uint256[4] calldata) public pure returns (uint256) {}
}
library PoseidonUnit5L {
function poseidon(uint256[5] calldata) public pure returns (uint256) {}
}
library PoseidonUnit6L {
function poseidon(uint256[6] calldata) public pure returns (uint256) {}
}
library SpongePoseidon {
uint32 internal constant BATCH_SIZE = 6;
function hash(uint256[] calldata values) public pure returns (uint256) {
uint256[BATCH_SIZE] memory frame = [uint256(0), 0, 0, 0, 0, 0];
bool dirty = false;
uint256 fullHash = 0;
uint32 k = 0;
for (uint32 i = 0; i < values.length; i++) {
dirty = true;
frame[k] = values[i];
if (k == BATCH_SIZE - 1) {
fullHash = PoseidonUnit6L.poseidon(frame);
dirty = false;
frame = [uint256(0), 0, 0, 0, 0, 0];
frame[0] = fullHash;
k = 1;
} else {
k++;
}
}
if (dirty) {
// we haven't hashed something in the main sponge loop and need to do hash here
fullHash = PoseidonUnit6L.poseidon(frame);
}
return fullHash;
}
}
library PoseidonFacade {
function poseidon1(uint256[1] calldata el) public pure returns (uint256) {
return PoseidonUnit1L.poseidon(el);
}
function poseidon2(uint256[2] calldata el) public pure returns (uint256) {
return PoseidonUnit2L.poseidon(el);
}
function poseidon3(uint256[3] calldata el) public pure returns (uint256) {
return PoseidonUnit3L.poseidon(el);
}
function poseidon4(uint256[4] calldata el) public pure returns (uint256) {
return PoseidonUnit4L.poseidon(el);
}
function poseidon5(uint256[5] calldata el) public pure returns (uint256) {
return PoseidonUnit5L.poseidon(el);
}
function poseidon6(uint256[6] calldata el) public pure returns (uint256) {
return PoseidonUnit6L.poseidon(el);
}
function poseidonSponge(uint256[] calldata el) public pure returns (uint256) {
return SpongePoseidon.hash(el);
}
}