forked from vyperlang/vyper
-
Notifications
You must be signed in to change notification settings - Fork 2
/
test_ec.py
178 lines (136 loc) · 4.32 KB
/
test_ec.py
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
G1 = [1, 2]
G1_times_two = [
1368015179489954701390400359078579693043519447331113978918064868415326638035,
9918110051302171585080402603319702774565515993150576347155970296011118125764,
]
G1_times_three = [
3353031288059533942658390886683067124040920775575537747144343083137631628272,
19321533766552368860946552437480515441416830039777911637913418824951667761761,
]
negative_G1 = [1, 21888242871839275222246405745257275088696311157297823662689037894645226208581]
curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617
def test_ecadd(get_contract_with_gas_estimation):
ecadder = """
x3: uint256[2]
y3: uint256[2]
@external
def _ecadd(x: uint256[2], y: uint256[2]) -> uint256[2]:
return ecadd(x, y)
@external
def _ecadd2(x: uint256[2], y: uint256[2]) -> uint256[2]:
x2: uint256[2] = x
y2: uint256[2] = [y[0], y[1]]
return ecadd(x2, y2)
@external
def _ecadd3(x: uint256[2], y: uint256[2]) -> uint256[2]:
self.x3 = x
self.y3 = [y[0], y[1]]
return ecadd(self.x3, self.y3)
"""
c = get_contract_with_gas_estimation(ecadder)
assert c._ecadd(G1, G1) == G1_times_two
assert c._ecadd2(G1, G1_times_two) == G1_times_three
assert c._ecadd3(G1, [0, 0]) == G1
assert c._ecadd3(G1, negative_G1) == [0, 0]
def test_ecadd_internal_call(get_contract_with_gas_estimation):
code = """
@internal
def a() -> uint256[2]:
return [1, 2]
@external
def foo() -> uint256[2]:
return ecadd([1, 2], self.a())
"""
c = get_contract_with_gas_estimation(code)
assert c.foo() == G1_times_two
def test_ecadd_ext_call(w3, side_effects_contract, assert_side_effects_invoked, get_contract):
code = """
interface Foo:
def foo(x: uint256[2]) -> uint256[2]: payable
@external
def foo(a: Foo) -> uint256[2]:
return ecadd([1, 2], extcall a.foo([1, 2]))
"""
c1 = side_effects_contract("uint256[2]")
c2 = get_contract(code)
assert c2.foo(c1.address) == G1_times_two
assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={}))
def test_ecadd_evaluation_order(get_contract_with_gas_estimation):
code = """
x: uint256[2]
@internal
def bar() -> uint256[2]:
self.x = ecadd([1, 2], [1, 2])
return [1, 2]
@external
def foo() -> bool:
self.x = [1, 2]
a: uint256[2] = ecadd([1, 2], [1, 2])
b: uint256[2] = ecadd(self.x, self.bar())
return a[0] == b[0] and a[1] == b[1]
"""
c = get_contract_with_gas_estimation(code)
assert c.foo() is True
def test_ecmul(get_contract_with_gas_estimation):
ecmuller = """
x3: uint256[2]
y3: uint256
@external
def _ecmul(x: uint256[2], y: uint256) -> uint256[2]:
return ecmul(x, y)
@external
def _ecmul2(x: uint256[2], y: uint256) -> uint256[2]:
x2: uint256[2] = x
y2: uint256 = y
return ecmul(x2, y2)
@external
def _ecmul3(x: uint256[2], y: uint256) -> uint256[2]:
self.x3 = x
self.y3 = y
return ecmul(self.x3, self.y3)
"""
c = get_contract_with_gas_estimation(ecmuller)
assert c._ecmul(G1, 0) == [0, 0]
assert c._ecmul(G1, 1) == G1
assert c._ecmul(G1, 3) == G1_times_three
assert c._ecmul(G1, curve_order - 1) == negative_G1
assert c._ecmul(G1, curve_order) == [0, 0]
def test_ecmul_internal_call(get_contract_with_gas_estimation):
code = """
@internal
def a() -> uint256:
return 3
@external
def foo() -> uint256[2]:
return ecmul([1, 2], self.a())
"""
c = get_contract_with_gas_estimation(code)
assert c.foo() == G1_times_three
def test_ecmul_ext_call(w3, side_effects_contract, assert_side_effects_invoked, get_contract):
code = """
interface Foo:
def foo(x: uint256) -> uint256: payable
@external
def foo(a: Foo) -> uint256[2]:
return ecmul([1, 2], extcall a.foo(3))
"""
c1 = side_effects_contract("uint256")
c2 = get_contract(code)
assert c2.foo(c1.address) == G1_times_three
assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={}))
def test_ecmul_evaluation_order(get_contract_with_gas_estimation):
code = """
x: uint256[2]
@internal
def bar() -> uint256:
self.x = ecmul([1, 2], 3)
return 3
@external
def foo() -> bool:
self.x = [1, 2]
a: uint256[2] = ecmul([1, 2], 3)
b: uint256[2] = ecmul(self.x, self.bar())
return a[0] == b[0] and a[1] == b[1]
"""
c = get_contract_with_gas_estimation(code)
assert c.foo() is True