Skip to content
This repository was archived by the owner on Oct 28, 2024. It is now read-only.

Commit 6935926

Browse files
authored
Merge pull request #61 from HarryR/miximus-cleanup
Merkle fixes, Miximus cleanup + security fix
2 parents 76951bb + 5b4f664 commit 6935926

21 files changed

+675
-120
lines changed

Diff for: .solhint.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"expression-indent": false,
1111
"max-line-length": false,
1212
"two-lines-top-level-separator": false,
13-
"separate-by-one-line-in-contract": false
13+
"separate-by-one-line-in-contract": false,
14+
"function-max-lines": false
1415
}
1516
}

Diff for: CMakeLists.txt

+21-28
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,6 @@ project(ethsnarks)
44

55
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
66

7-
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
8-
# Common compilation flags and warning configuration
9-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wfatal-errors -Wno-unused-variable")
10-
if("${MULTICORE}")
11-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
12-
endif()
13-
# Default optimizations flags (to override, use -DOPT_FLAGS=...)
14-
endif()
157

168

179
set(
@@ -60,34 +52,35 @@ option(
6052
OFF
6153
)
6254

55+
option(
56+
USE_MIXED_ADDITION
57+
"Convert each element of the key pair to affine coordinates"
58+
OFF
59+
)
60+
6361
option(
6462
BINARY_OUTPUT
6563
"Use binary output for serialisation"
6664
ON
6765
)
6866

6967
option(
70-
PERFORMANCE
71-
"Enable link-time and aggressive optimizations"
72-
OFF
68+
MONTGOMERY_OUTPUT
69+
"Serialize Fp elements as their Montgomery representations (faster but not human-readable)"
70+
ON
7371
)
7472

73+
7574
option(
7675
WITH_PROCPS
7776
"Use procps for memory profiling"
7877
OFF
7978
)
8079

81-
option(
82-
VERBOSE
83-
"Print internal messages"
84-
OFF
85-
)
86-
8780
option(
8881
DEBUG
8982
"Enable debugging mode"
90-
ON
83+
OFF
9184
)
9285

9386
option(
@@ -103,19 +96,12 @@ if(${CURVE} STREQUAL "BN128")
10396
add_definitions(-DBN_SUPPORT_SNARK=1)
10497
endif()
10598

106-
if("${VERBOSE}")
107-
add_definitions(-DVERBOSE=1)
108-
endif()
109-
11099
if("${MULTICORE}")
111100
add_definitions(-DMULTICORE=1)
112101
endif()
113102

114-
if("${DEBUG}")
103+
if("${DEBUG}" OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
115104
add_definitions(-DDEBUG=1)
116-
add_compile_options(-g)
117-
else()
118-
add_compile_options(-O3)
119105
endif()
120106

121107

@@ -154,6 +140,15 @@ else()
154140
)
155141
endif()
156142

143+
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
144+
# Common compilation flags and warning configuration
145+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wfatal-errors -Wno-unused-variable")
146+
if("${MULTICORE}")
147+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
148+
endif()
149+
# Default optimizations flags (to override, use -DOPT_FLAGS=...)
150+
endif()
151+
157152

158153
find_path(GMP_INCLUDE_DIR NAMES gmp.h)
159154
find_library(GMP_LIBRARY gmp)
@@ -205,6 +200,4 @@ add_library(
205200

206201
target_link_libraries(ff GMP::gmp gmpxx ${PROCPS_LIBRARIES})
207202

208-
#add_subdirectory(depends)
209203
add_subdirectory(src)
210-

Diff for: Makefile

+13
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ bin/miximus_genKeys: build/Makefile
4747
build/src/libmiximus.$(DLL_EXT): build/Makefile
4848
make -C build
4949

50+
cmake-debug: build
51+
cd build && cmake -DCMAKE_BUILD_TYPE=Debug ..
52+
53+
cmake-release: build
54+
cd build && cmake -DCMAKE_BUILD_TYPE=Release ..
55+
56+
release: cmake-release all
57+
58+
debug: cmake-debug all
59+
5060
build/Makefile: build CMakeLists.txt
5161
cd build && cmake ..
5262

@@ -163,6 +173,9 @@ $(GANACHE): node_modules
163173
truffle-test: $(TRUFFLE)
164174
$(NPM) run test
165175

176+
truffle-migrate: $(TRUFFLE)
177+
$(TRUFFLE) migrate
178+
166179
truffle-compile: $(TRUFFLE)
167180
$(TRUFFLE) compile
168181

Diff for: contracts/MerkleTree.sol

+47-15
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ library MerkleTree
6363

6464

6565
function Insert(Data storage self, uint256 leaf)
66-
internal returns (uint256)
66+
internal returns (uint256, uint256)
6767
{
6868
require( leaf != 0 );
6969

@@ -83,7 +83,48 @@ library MerkleTree
8383

8484
self.cur = offset + 1;
8585

86-
return new_root;
86+
return (new_root, offset);
87+
}
88+
89+
90+
/**
91+
* Returns calculated merkle root
92+
*/
93+
function VerifyPath(uint256 leaf, uint256[29] in_path, bool[29] address_bits)
94+
internal pure returns (uint256)
95+
{
96+
uint256[10] memory C;
97+
LongsightL.ConstantsL12p5(C);
98+
99+
uint256[29] memory IVs;
100+
FillLevelIVs(IVs);
101+
102+
uint256 item = leaf;
103+
104+
for (uint depth = 0; depth < TREE_DEPTH; depth++)
105+
{
106+
if (address_bits[depth]) {
107+
item = HashImpl(in_path[depth], item, C, IVs[depth]);
108+
} else {
109+
item = HashImpl(item, in_path[depth], C, IVs[depth]);
110+
}
111+
}
112+
113+
return item;
114+
}
115+
116+
117+
function VerifyPath(Data storage self, uint256 leaf, uint256[29] in_path, bool[29] address_bits)
118+
internal view returns (bool)
119+
{
120+
return VerifyPath(leaf, in_path, address_bits) == GetRoot(self);
121+
}
122+
123+
124+
function GetLeaf(Data storage self, uint depth, uint offset)
125+
internal view returns (uint256)
126+
{
127+
return GetUniqueLeaf(depth, offset, self.leaves[depth][offset]);
87128
}
88129

89130

@@ -98,12 +139,10 @@ library MerkleTree
98139
{
99140
address_bits[depth] = index % 2 == 0 ? false : true;
100141

101-
if (index%2 == 0)
102-
{
103-
proof_path[depth] = GetUniqueLeaf(depth, index, self.leaves[depth][index + 1]);
104-
} else
105-
{
106-
proof_path[depth] = GetUniqueLeaf(depth, index, self.leaves[depth][index - 1]);
142+
if (index%2 == 0) {
143+
proof_path[depth] = GetLeaf(self, depth, index + 1);
144+
} else {
145+
proof_path[depth] = GetLeaf(self, depth, index - 1);
107146
}
108147

109148
index = uint(index / 2);
@@ -161,13 +200,6 @@ library MerkleTree
161200

162201
return self.leaves[TREE_DEPTH][0];
163202
}
164-
165-
166-
function GetLeaf(Data storage self, uint depth, uint offset)
167-
internal view returns (uint256)
168-
{
169-
return self.leaves[depth][offset];
170-
}
171203

172204

173205
function GetRoot (Data storage self)

Diff for: contracts/Miximus.sol

+68-18
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
*/
1919

2020
pragma solidity 0.4.24;
21-
pragma experimental ABIEncoderV2;
2221

2322
import "./Verifier.sol";
2423
import "./SnarkUtils.sol";
2524
import "./MerkleTree.sol";
25+
import "./LongsightL.sol";
2626

2727

2828
contract Miximus
@@ -35,39 +35,89 @@ contract Miximus
3535

3636
MerkleTree.Data internal tree;
3737

38+
39+
function GetRoot()
40+
public view returns (uint256)
41+
{
42+
return tree.GetRoot();
43+
}
44+
45+
46+
/**
47+
* Returns leaf offset
48+
*/
3849
function Deposit(uint256 leaf)
39-
public payable returns (uint256)
50+
public payable returns (uint256 new_root, uint256 new_offset)
4051
{
4152
require( msg.value == AMOUNT );
4253

4354
return tree.Insert(leaf);
4455
}
4556

4657

47-
function Withdraw(
48-
uint256 in_root,
49-
uint256 in_nullifier,
50-
Verifier.Proof in_proof
51-
)
52-
public
58+
function MakeLeafHash(uint256 spend_preimage, uint256 nullifier)
59+
public pure returns (uint256)
5360
{
54-
require( false == nullifiers[in_nullifier] );
61+
uint256[10] memory round_constants;
62+
LongsightL.ConstantsL12p5(round_constants);
63+
64+
uint256 spend_hash = LongsightL.LongsightL12p5_MP([spend_preimage, nullifier], 0, round_constants);
65+
66+
return LongsightL.LongsightL12p5_MP([nullifier, spend_hash], 0, round_constants);
67+
}
5568

56-
uint256[] memory snark_input = new uint256[](3);
5769

58-
snark_input[0] = SnarkUtils.ReverseBits(in_root);
70+
function GetPath(uint256 leaf)
71+
public view returns (uint256[29] out_path, bool[29] out_addr)
72+
{
73+
return tree.GetProof(leaf);
74+
}
5975

60-
snark_input[1] = SnarkUtils.ReverseBits(in_nullifier);
6176

62-
snark_input[2] = SnarkUtils.ReverseBits(uint256(sha256(
77+
function GetExtHash()
78+
public view returns (uint256)
79+
{
80+
return uint256(sha256(
6381
abi.encodePacked(
6482
address(this),
6583
msg.sender
66-
)))) % Verifier.ScalarField();
84+
))) % Verifier.ScalarField();
85+
}
86+
87+
88+
function IsSpent(uint256 nullifier)
89+
public view returns (bool)
90+
{
91+
return nullifiers[nullifier];
92+
}
93+
94+
95+
function VerifyProof( uint256 in_root, uint256 in_nullifier, uint256 in_exthash, uint256[8] proof )
96+
public view returns (bool)
97+
{
98+
uint256[] memory snark_input = new uint256[](3);
99+
snark_input[0] = in_root;
100+
snark_input[1] = in_nullifier;
101+
snark_input[2] = in_exthash;
102+
103+
uint256[14] memory vk;
104+
uint256[] memory vk_gammaABC;
105+
(vk, vk_gammaABC) = GetVerifyingKey();
106+
107+
return Verifier.Verify( vk, vk_gammaABC, proof, snark_input );
108+
}
67109

68-
Verifier.VerifyingKey memory vk = GetVerifyingKey();
69110

70-
bool is_valid = Verifier.Verify( vk, in_proof, snark_input );
111+
function Withdraw(
112+
uint256 in_root,
113+
uint256 in_nullifier,
114+
uint256[8] proof
115+
)
116+
public
117+
{
118+
require( false == nullifiers[in_nullifier] );
119+
120+
bool is_valid = VerifyProof(in_root, in_nullifier, GetExtHash(), proof);
71121

72122
require( is_valid );
73123

@@ -76,7 +126,7 @@ contract Miximus
76126
msg.sender.transfer(AMOUNT);
77127
}
78128

79-
function GetVerifyingKey ()
80-
internal pure returns (Verifier.VerifyingKey memory);
81129

130+
function GetVerifyingKey ()
131+
public view returns (uint256[14] out_vk, uint256[] out_gammaABC);
82132
}

0 commit comments

Comments
 (0)