Skip to content

Commit 4a682fc

Browse files
Brechtpddong77
authored andcommitted
[Protocol3] Switch hash function from MiMC/e7r91 to Poseidon (#256)
* [Protocol3] Swtiched to Poseidon for Merkle tree hashes * [Protocol3] Arbitrary n-ary Merkle tree * [Protocol3] Updated ethsnarks * [Protocol3] Use poseidon in eddsa signatures * [Protocol3] Updated ethsnarks * [Protocol3] Added EVM implementation of poseidon * [Protocol3] Fixed failing tests * [Protocol3] Fixed verifyProof on python SparseMerkleTree implementation * Update ExchangeBalances.sol * Update ExchangeBalances.sol * Update PoseidonContract.sol * Update ExchangeWithdrawals.sol * Update IExchange.sol * Update IExchange.sol * Update ExchangeAccounts.sol * [Protocol3] Use constant for genesis Merkle root * [Protocol3] Cleaned up EdDSA code * removed circuit_service building code
1 parent ea0df44 commit 4a682fc

27 files changed

+957
-675
lines changed

.gitmodules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[submodule "packages/loopring_v3/ethsnarks"]
22
path = packages/loopring_v3/ethsnarks
33
url = https://github.com/HarryR/ethsnarks
4+
branch = master

packages/loopring_v3/ABI/version30/IExchange.abi

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/loopring_v3/circuit/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,4 @@ set(circuit_src_folder "../../../../protocol3-circuits/")
77
add_executable(dex_circuit "${circuit_src_folder}/main.cpp")
88
target_link_libraries(dex_circuit ethsnarks_jubjub)
99

10-
add_library(circuit_service SHARED "${circuit_src_folder}/service.cpp")
11-
target_link_libraries(circuit_service ethsnarks_jubjub)
1210

packages/loopring_v3/contracts/iface/IExchange.sol

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ contract IExchange
241241
uint32 nonce,
242242
uint96 balance,
243243
uint256 tradeHistoryRoot,
244-
uint256[20] calldata accountMerkleProof,
245-
uint256[8] calldata balanceMerkleProof
244+
uint256[30] calldata accountMerkleProof,
245+
uint256[12] calldata balanceMerkleProof
246246
)
247247
external
248248
pure
@@ -344,7 +344,7 @@ contract IExchange
344344
/// @param amount The amount of LRC that needs to be withdrawn
345345
function withdrawProtocolFeeStake(
346346
address recipient,
347-
uint amount
347+
uint amount
348348
)
349349
external;
350350

@@ -523,7 +523,7 @@ contract IExchange
523523
/// @param blockIdx The 0-based index of the block to be verified with the given proof
524524
/// @param proof The ZK proof
525525
function verifyBlock(
526-
uint blockIdx,
526+
uint blockIdx,
527527
uint256[8] calldata proof
528528
)
529529
external;
@@ -771,8 +771,8 @@ contract IExchange
771771
uint32 nonce,
772772
uint96 balance,
773773
uint256 tradeHistoryRoot,
774-
uint256[20] calldata accountMerkleProof,
775-
uint256[8] calldata balanceMerkleProof
774+
uint256[30] calldata accountMerkleProof,
775+
uint256[12] calldata balanceMerkleProof
776776
)
777777
external;
778778

@@ -806,8 +806,8 @@ contract IExchange
806806
uint32 nonce,
807807
uint96 balance,
808808
uint256 tradeHistoryRoot,
809-
uint256[20] calldata accountMerkleProof,
810-
uint256[8] calldata balanceMerkleProof
809+
uint256[30] calldata accountMerkleProof,
810+
uint256[12] calldata balanceMerkleProof
811811
)
812812
external;
813813

packages/loopring_v3/contracts/impl/Exchange.sol

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ contract Exchange is IExchange, Claimable, ReentrancyGuard
194194
uint32 nonce,
195195
uint96 balance,
196196
uint256 tradeHistoryRoot,
197-
uint256[20] calldata accountPath,
198-
uint256[8] calldata balancePath
197+
uint256[30] calldata accountPath,
198+
uint256[12] calldata balancePath
199199
)
200200
external
201201
pure
@@ -600,8 +600,8 @@ contract Exchange is IExchange, Claimable, ReentrancyGuard
600600
uint32 nonce,
601601
uint96 balance,
602602
uint256 tradeHistoryRoot,
603-
uint256[20] calldata accountPath,
604-
uint256[8] calldata balancePath
603+
uint256[30] calldata accountPath,
604+
uint256[12] calldata balancePath
605605
)
606606
external
607607
nonReentrant
@@ -628,8 +628,8 @@ contract Exchange is IExchange, Claimable, ReentrancyGuard
628628
uint32 nonce,
629629
uint96 balance,
630630
uint256 tradeHistoryRoot,
631-
uint256[20] calldata accountPath,
632-
uint256[8] calldata balancePath
631+
uint256[30] calldata accountPath,
632+
uint256[12] calldata balancePath
633633
)
634634
external
635635
nonReentrant

packages/loopring_v3/contracts/impl/libexchange/ExchangeAccounts.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ library ExchangeAccounts
166166
uint32 nonce,
167167
uint96 balance,
168168
uint256 tradeHistoryRoot,
169-
uint256[20] memory accountMerkleProof,
170-
uint256[8] memory balanceMerkleProof
169+
uint256[30] memory accountMerkleProof,
170+
uint256[12] memory balanceMerkleProof
171171
)
172172
public
173173
view

packages/loopring_v3/contracts/impl/libexchange/ExchangeBalances.sol

Lines changed: 76 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
pragma solidity 0.5.7;
1818

1919
import "../../lib/MathUint.sol";
20-
21-
import "../../thirdparty/MiMC.sol";
20+
import "../../lib/Poseidon.sol";
2221

2322

2423
/// @title ExchangeBalances.
@@ -37,8 +36,8 @@ library ExchangeBalances
3736
uint32 nonce,
3837
uint96 balance,
3938
uint256 tradeHistoryRoot,
40-
uint256[20] memory accountMerkleProof,
41-
uint256[8] memory balanceMerkleProof
39+
uint256[30] memory accountMerkleProof,
40+
uint256[12] memory balanceMerkleProof
4241
)
4342
public
4443
pure
@@ -67,8 +66,8 @@ library ExchangeBalances
6766
uint32 nonce,
6867
uint96 balance,
6968
uint256 tradeHistoryRoot,
70-
uint256[20] memory accountMerkleProof,
71-
uint256[8] memory balanceMerkleProof
69+
uint256[30] memory accountMerkleProof,
70+
uint256[12] memory balanceMerkleProof
7271
)
7372
public
7473
pure
@@ -96,29 +95,45 @@ library ExchangeBalances
9695
uint16 tokenID,
9796
uint balance,
9897
uint tradeHistoryRoot,
99-
uint256[8] memory balanceMerkleProof
98+
uint256[12] memory balanceMerkleProof
10099
)
101100
internal
102101
pure
103102
returns (uint256)
104103
{
105-
uint256[29] memory salts;
106-
getMerkleTreeHashingSalts(salts);
107-
108-
uint256[] memory balanceLeafElements = new uint256[](2);
109-
balanceLeafElements[0] = balance;
110-
balanceLeafElements[1] = tradeHistoryRoot;
111-
uint256 balanceItem = MiMC.Hash(balanceLeafElements, 1);
112-
113-
// Calculate merkle root of balances tree
104+
uint256 balanceItem = hashImpl(balance, tradeHistoryRoot, 0, 0);
114105
uint _id = tokenID;
115-
for (uint depth = 0; depth < 8; depth++) {
116-
if (_id & 1 == 1) {
117-
balanceItem = hashImpl(balanceMerkleProof[depth], balanceItem, salts[depth]);
118-
} else {
119-
balanceItem = hashImpl(balanceItem, balanceMerkleProof[depth], salts[depth]);
106+
for (uint depth = 0; depth < 4; depth++) {
107+
if (_id & 3 == 0) {
108+
balanceItem = hashImpl(
109+
balanceItem,
110+
balanceMerkleProof[depth * 3],
111+
balanceMerkleProof[depth * 3 + 1],
112+
balanceMerkleProof[depth * 3 + 2]
113+
);
114+
} else if (_id & 3 == 1) {
115+
balanceItem = hashImpl(
116+
balanceMerkleProof[depth * 3],
117+
balanceItem,
118+
balanceMerkleProof[depth * 3 + 1],
119+
balanceMerkleProof[depth * 3 + 2]
120+
);
121+
} else if (_id & 3 == 2) {
122+
balanceItem = hashImpl(
123+
balanceMerkleProof[depth * 3],
124+
balanceMerkleProof[depth * 3 + 1],
125+
balanceItem,
126+
balanceMerkleProof[depth * 3 + 2]
127+
);
128+
} else if (_id & 3 == 3) {
129+
balanceItem = hashImpl(
130+
balanceMerkleProof[depth * 3],
131+
balanceMerkleProof[depth * 3 + 1],
132+
balanceMerkleProof[depth * 3 + 2],
133+
balanceItem
134+
);
120135
}
121-
_id = _id / 2;
136+
_id = _id >> 2;
122137
}
123138
return balanceItem;
124139
}
@@ -129,89 +144,59 @@ library ExchangeBalances
129144
uint256 pubKeyY,
130145
uint256 nonce,
131146
uint256 balancesRoot,
132-
uint256[20] memory accountMerkleProof
147+
uint256[30] memory accountMerkleProof
133148
)
134149
internal
135150
pure
136151
returns (uint256)
137152
{
138-
uint256[29] memory salts;
139-
getMerkleTreeHashingSalts(salts);
140-
141-
uint256[] memory accountLeafElements = new uint256[](4);
142-
accountLeafElements[0] = pubKeyX;
143-
accountLeafElements[1] = pubKeyY;
144-
accountLeafElements[2] = nonce;
145-
accountLeafElements[3] = balancesRoot;
146-
uint256 accountItem = MiMC.Hash(accountLeafElements, 1);
147-
153+
uint256 accountItem = hashImpl(pubKeyX, pubKeyY, nonce, balancesRoot);
148154
uint _id = accountID;
149-
for (uint depth = 0; depth < 20; depth++) {
150-
if (_id & 1 == 1) {
151-
accountItem = hashImpl(accountMerkleProof[depth], accountItem, salts[depth]);
152-
} else {
153-
accountItem = hashImpl(accountItem, accountMerkleProof[depth], salts[depth]);
155+
for (uint depth = 0; depth < 10; depth++) {
156+
if (_id & 3 == 0) {
157+
accountItem = hashImpl(
158+
accountItem,
159+
accountMerkleProof[depth * 3],
160+
accountMerkleProof[depth * 3 + 1],
161+
accountMerkleProof[depth * 3 + 2]
162+
);
163+
} else if (_id & 3 == 1) {
164+
accountItem = hashImpl(
165+
accountMerkleProof[depth * 3],
166+
accountItem,
167+
accountMerkleProof[depth * 3 + 1],
168+
accountMerkleProof[depth * 3 + 2]
169+
);
170+
} else if (_id & 3 == 2) {
171+
accountItem = hashImpl(
172+
accountMerkleProof[depth * 3],
173+
accountMerkleProof[depth * 3 + 1],
174+
accountItem,
175+
accountMerkleProof[depth * 3 + 2]
176+
);
177+
} else if (_id & 3 == 3) {
178+
accountItem = hashImpl(
179+
accountMerkleProof[depth * 3],
180+
accountMerkleProof[depth * 3 + 1],
181+
accountMerkleProof[depth * 3 + 2],
182+
accountItem
183+
);
154184
}
155-
_id = _id / 2;
185+
_id = _id >> 2;
156186
}
157187
return accountItem;
158188
}
159189

160-
function hashImpl (
161-
uint256 left,
162-
uint256 right,
163-
uint256 IV
190+
function hashImpl(
191+
uint256 t0,
192+
uint256 t1,
193+
uint256 t2,
194+
uint256 t3
164195
)
165196
internal
166197
pure
167198
returns (uint256)
168199
{
169-
uint256[] memory x = new uint256[](2);
170-
x[0] = left;
171-
x[1] = right;
172-
173-
return MiMC.Hash(x, IV);
174-
}
175-
176-
function getMerkleTreeHashingSalts (
177-
uint256[29] memory salts
178-
)
179-
public
180-
pure
181-
{
182-
// Actually only up to 20 items in the list will be used in 3.0. We keep more in case
183-
// we will change the depth of the Merkle tree in the future.
184-
185-
// When we calculate the tree hashes, the leaf nodes will use salts[0] as the hashing
186-
// salt, the parent nodes of the leafs will use salts[1], ...
187-
salts[0] = 149674538925118052205057075966660054952481571156186698930522557832224430770;
188-
salts[1] = 9670701465464311903249220692483401938888498641874948577387207195814981706974;
189-
salts[2] = 18318710344500308168304415114839554107298291987930233567781901093928276468271;
190-
salts[3] = 6597209388525824933845812104623007130464197923269180086306970975123437805179;
191-
salts[4] = 21720956803147356712695575768577036859892220417043839172295094119877855004262;
192-
salts[5] = 10330261616520855230513677034606076056972336573153777401182178891807369896722;
193-
salts[6] = 17466547730316258748333298168566143799241073466140136663575045164199607937939;
194-
salts[7] = 18881017304615283094648494495339883533502299318365959655029893746755475886610;
195-
salts[8] = 21580915712563378725413940003372103925756594604076607277692074507345076595494;
196-
salts[9] = 12316305934357579015754723412431647910012873427291630993042374701002287130550;
197-
salts[10] = 18905410889238873726515380969411495891004493295170115920825550288019118582494;
198-
salts[11] = 12819107342879320352602391015489840916114959026915005817918724958237245903353;
199-
salts[12] = 8245796392944118634696709403074300923517437202166861682117022548371601758802;
200-
salts[13] = 16953062784314687781686527153155644849196472783922227794465158787843281909585;
201-
salts[14] = 19346880451250915556764413197424554385509847473349107460608536657852472800734;
202-
salts[15] = 14486794857958402714787584825989957493343996287314210390323617462452254101347;
203-
salts[16] = 11127491343750635061768291849689189917973916562037173191089384809465548650641;
204-
salts[17] = 12217916643258751952878742936579902345100885664187835381214622522318889050675;
205-
salts[18] = 722025110834410790007814375535296040832778338853544117497481480537806506496;
206-
salts[19] = 15115624438829798766134408951193645901537753720219896384705782209102859383951;
207-
salts[20] = 11495230981884427516908372448237146604382590904456048258839160861769955046544;
208-
salts[21] = 16867999085723044773810250829569850875786210932876177117428755424200948460050;
209-
salts[22] = 1884116508014449609846749684134533293456072152192763829918284704109129550542;
210-
salts[23] = 14643335163846663204197941112945447472862168442334003800621296569318670799451;
211-
salts[24] = 1933387276732345916104540506251808516402995586485132246682941535467305930334;
212-
salts[25] = 7286414555941977227951257572976885370489143210539802284740420664558593616067;
213-
salts[26] = 16932161189449419608528042274282099409408565503929504242784173714823499212410;
214-
salts[27] = 16562533130736679030886586765487416082772837813468081467237161865787494093536;
215-
salts[28] = 6037428193077828806710267464232314380014232668931818917272972397574634037180;
200+
return Poseidon.hash_t5f6p52(t0, t1, t2, t3, 0);
216201
}
217-
}
202+
}

packages/loopring_v3/contracts/impl/libexchange/ExchangeData.sol

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ library ExchangeData
161161
uint96 amount;
162162
}
163163

164+
function GENESIS_MERKLE_ROOT() internal pure returns (bytes32) {
165+
return 0x2b4827daf74c0ab30deb68b1c337dec40579bb3ff45ce9478288e1a2b83a3a01;
166+
}
164167
function MAX_PROOF_GENERATION_TIME_IN_SECONDS() internal pure returns (uint32) { return 1 hours; }
165168
function MAX_GAP_BETWEEN_FINALIZED_AND_VERIFIED_BLOCKS() internal pure returns (uint32) { return 2500; }
166169
function MAX_OPEN_DEPOSIT_REQUESTS() internal pure returns (uint16) { return 1024; }

packages/loopring_v3/contracts/impl/libexchange/ExchangeGenesis.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ library ExchangeGenesis
5858
S.lrcAddress = loopring.lrcAddress();
5959

6060
ExchangeData.Block memory genesisBlock = ExchangeData.Block(
61-
0x06ea7e01611a784ff676387ee0a6f58933eb184d8a2ff765608488e7e8da76d3,
61+
ExchangeData.GENESIS_MERKLE_ROOT(),
6262
0x0,
6363
ExchangeData.BlockState.VERIFIED,
6464
ExchangeData.BlockType(0),

packages/loopring_v3/contracts/impl/libexchange/ExchangeWithdrawals.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ library ExchangeWithdrawals
161161
uint32 nonce,
162162
uint96 balance,
163163
uint256 tradeHistoryRoot,
164-
uint256[20] memory accountMerkleProof,
165-
uint256[8] memory balanceMerkleProof
164+
uint256[30] memory accountMerkleProof,
165+
uint256[12] memory balanceMerkleProof
166166
)
167167
public
168168
{

0 commit comments

Comments
 (0)