aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc
diff options
context:
space:
mode:
authorTaylor Gerring <taylor.gerring@gmail.com>2015-02-16 21:28:33 +0800
committerTaylor Gerring <taylor.gerring@gmail.com>2015-02-16 21:28:33 +0800
commit702218008ee2b6d708d6b2821cdef80736bb3224 (patch)
treed55ff7ce88187082378e7d8e4c2f3aad14d23b4e /Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc
parent202362d9258335c695eb75f55f4be74a50a1af33 (diff)
downloadgo-tangerine-702218008ee2b6d708d6b2821cdef80736bb3224.tar.gz
go-tangerine-702218008ee2b6d708d6b2821cdef80736bb3224.tar.zst
go-tangerine-702218008ee2b6d708d6b2821cdef80736bb3224.zip
Add versioned dependencies from godep
Diffstat (limited to 'Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc')
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/ecrecover.se40
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/ecrecover_compiled.evm1
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_add.se32
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_double.se16
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_mul.se37
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/modexp.se11
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/substitutes.py78
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/test.py129
8 files changed, 344 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/ecrecover.se b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/ecrecover.se
new file mode 100644
index 000000000..ce28f58c2
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/ecrecover.se
@@ -0,0 +1,40 @@
+# So I looked up on Wikipedia what Jacobian form actually is, and noticed that it's
+# actually a rather different and more clever construction than the naive version
+# that I created. It may possible to achieve a further 20-50% savings by applying
+# that version.
+
+extern all: [call]
+
+data JORDANMUL
+data JORDANADD
+data EXP
+
+def init():
+ self.JORDANMUL = create('jacobian_mul.se')
+ self.JORDANADD = create('jacobian_add.se')
+ self.EXP = create('modexp.se')
+
+def call(h, v, r, s):
+ N = -432420386565659656852420866394968145599
+ P = -4294968273
+ h = mod(h, N)
+ r = mod(r, P)
+ s = mod(s, N)
+ Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
+ Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
+ x = r
+ xcubed = mulmod(mulmod(x, x, P), x, P)
+ beta = self.EXP.call(addmod(xcubed, 7, P), div(P + 1, 4), P)
+
+ # Static-gascost ghetto conditional
+ y_is_positive = mod(v, 2) xor mod(beta, 2)
+ y = beta * y_is_positive + (P - beta) * (1 - y_is_positive)
+
+ GZ = self.JORDANMUL.call(Gx, 1, Gy, 1, N - h, outsz=4)
+ XY = self.JORDANMUL.call(x, 1, y, 1, s, outsz=4)
+ COMB = self.JORDANADD.call(GZ[0], GZ[1], GZ[2], GZ[3], XY[0], XY[1], XY[2], XY[3], 1, outsz=5)
+ COMB[4] = self.EXP.call(r, N - 2, N)
+ Q = self.JORDANMUL.call(data=COMB, datasz=5, outsz=4)
+ ox = mulmod(Q[0], self.EXP.call(Q[1], P - 2, P), P)
+ oy = mulmod(Q[2], self.EXP.call(Q[3], P - 2, P), P)
+ return([ox, oy], 2)
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/ecrecover_compiled.evm b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/ecrecover_compiled.evm
new file mode 100644
index 000000000..f575fe70f
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/ecrecover_compiled.evm
@@ -0,0 +1 @@
+6000607f535961071c80610013593961072f566000605f535961013d8061001359396101505661012b8061000e60003961013956600061023f5360003560001a6000141561012a5760806001602037602051151561002c576060511561002f565b60005b156100695760806080599059016000905260a052600060a051526001602060a05101526000604060a05101526001606060a051015260a051f25b6401000003d160000380608051826003846020516020510909098182600260605109836040516040510909828283098382830984858660026020510983098603866040518509088560405183098686888985604051098a038a85602051090809878689846040510909888960605183098a038a6080518509088960805183096080608059905901600090526101e052866101e051528560206101e05101528260406101e05101528160606101e05101526101e051f250505050505050505050505b5b6000f25b816000f090506000555961040680610168593961056e566000603f535961013d8061001359396101505661012b8061000e60003961013956600061023f5360003560001a6000141561012a5760806001602037602051151561002c576060511561002f565b60005b156100695760806080599059016000905260a052600060a051526001602060a05101526000604060a05101526001606060a051015260a051f25b6401000003d160000380608051826003846020516020510909098182600260605109836040516040510909828283098382830984858660026020510983098603866040518509088560405183098686888985604051098a038a85602051090809878689846040510909888960605183098a038a6080518509088960805183096080608059905901600090526101e052866101e051528560206101e05101528260406101e05101528160606101e05101526101e051f250505050505050505050505b5b6000f25b816000f0905060005561029a8061016860003961040256600061043f5360003560001a60001415610299576101006001602037602051151561002d5760605115610030565b60005b1561007657608059905901600090526101405260a051610140515260c051602061014051015260e051604061014051015261010051606061014051015261014051610120525b60a05115156100885760e0511561008b565b60005b156100d0576080599059016000905261016052602051610160515260405160206101605101526060516040610160510152608051606061016051015261016051610120525b61012051156100e157608061012051f25b6401000003d16000036000818260a0516040510983038360c051602051090814156101b1576000818260e051608051098303836101005160605109081415610175576080608080599059016000905260006101c0601f01536020516101e052604051610200526060516102205260805161024052818160816101c0601f01600060005460195a03f1508090509050f26101b0565b608060805990590160009052610280526000610280515260016020610280510152600060406102805101526001606061028051015261028051f25b5b808160405160c051098283610100516060510984038460805160e05109080981828360c0516020510984038460405160a051090883608051610100510909828283098382830984856020518309860386604051850908856040518309868760a051830988038860c0518509088760c051830988898a60405185098b038b8460205109088909898a836040510989098a8b60605183098c038c6080518509088b60805183096080608059905901600090526103e052866103e051528560206103e05101528260406103e05101528160606103e05101526103e051f2505050505050505050505050505b5b6000f25b816000f090506001556101928061058660003961071856600061013f5360003560001a600014156101915760a0600160203770014551231950b75fc4402da1732fc9bebf60000360a0510660a05260a05115606051156020511502011561007e5760806080599059016000905260c052600060c051526001602060c05101526000604060c05101526001606060c051015260c051f25b610120599059016000905260e052600060e051526000602060e05101526001604060e05101526000606060e05101526001608060e0510152600060a060e0510152600060c060e0510152600060e060e0510152600061010060e051015260e0517f80000000000000000000000000000000000000000000000000000000000000005b6000811115610187578060a0511615610165576080602083016081601f85016000600054614e20f15060205160a083015260405160c083015260605160e0830152608051610100830152608060208301610101601f85016000600154614e20f161017b565b6080602083016081601f85016000600054614e20f15b50600281049050610100565b608060208301f250505b5b6000f25b816000f0905060005559610406806107475939610b4d566000603f535961013d8061001359396101505661012b8061000e60003961013956600061023f5360003560001a6000141561012a5760806001602037602051151561002c576060511561002f565b60005b156100695760806080599059016000905260a052600060a051526001602060a05101526000604060a05101526001606060a051015260a051f25b6401000003d160000380608051826003846020516020510909098182600260605109836040516040510909828283098382830984858660026020510983098603866040518509088560405183098686888985604051098a038a85602051090809878689846040510909888960605183098a038a6080518509088960805183096080608059905901600090526101e052866101e051528560206101e05101528260406101e05101528160606101e05101526101e051f250505050505050505050505b5b6000f25b816000f0905060005561029a8061016860003961040256600061043f5360003560001a60001415610299576101006001602037602051151561002d5760605115610030565b60005b1561007657608059905901600090526101405260a051610140515260c051602061014051015260e051604061014051015261010051606061014051015261014051610120525b60a05115156100885760e0511561008b565b60005b156100d0576080599059016000905261016052602051610160515260405160206101605101526060516040610160510152608051606061016051015261016051610120525b61012051156100e157608061012051f25b6401000003d16000036000818260a0516040510983038360c051602051090814156101b1576000818260e051608051098303836101005160605109081415610175576080608080599059016000905260006101c0601f01536020516101e052604051610200526060516102205260805161024052818160816101c0601f01600060005460195a03f1508090509050f26101b0565b608060805990590160009052610280526000610280515260016020610280510152600060406102805101526001606061028051015261028051f25b5b808160405160c051098283610100516060510984038460805160e05109080981828360c0516020510984038460405160a051090883608051610100510909828283098382830984856020518309860386604051850908856040518309868760a051830988038860c0518509088760c051830988898a60405185098b038b8460205109088909898a836040510989098a8b60605183098c038c6080518509088b60805183096080608059905901600090526103e052866103e051528560206103e05101528260406103e05101528160606103e05101526103e051f2505050505050505050505050505b5b6000f25b816000f09050600155596100d080610b655939610c35566100be8061000e6000396100cc5660003560001a600014156100bd576060600160203760017f80000000000000000000000000000000000000000000000000000000000000005b60008111156100b157606051816040511615156020510a606051848509099150606051600282046040511615156020510a606051848509099150606051600482046040511615156020510a606051848509099150606051600882046040511615156020510a606051848509099150601081049050610038565b8160c052602060c0f250505b5b6000f25b816000f090506002556103d280610c4d60003961101f56600061095f5360003560001a600014156103d1576080600160203770014551231950b75fc4402da1732fc9bebf60000360a0526401000003d160000360c05260a0516020510660205260c0516060510660605260a051608051066080527f79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179860e0527f483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8610100526060516101205260c0516101205160c05161012051610120510909610140526000610180601f015360c051600761014051086101a0526004600160c05101046101c05260c0516101e05260206102006061610180601f01600060025460195a03f1506102005161016052600261016051066002604051061861022052610220516001036101605160c05103026102205161016051020161024052608080599059016000905260006102a0601f015360e0516102c05260016102e052610100516103005260016103205260205160a0510361034052818160a16102a0601f01600060005460195a03f150809050905061026052608080599059016000905260006103c0601f0153610120516103e052600161040052610240516104205260016104405260805161046052818160a16103c0601f01600060005460195a03f15080905090506103805260a080599059016000905260006104e0601f015361026051516105005260206102605101516105205260406102605101516105405260606102605101516105605261038051516105805260206103805101516105a05260406103805101516105c05260606103805101516105e05260016106005281816101216104e0601f01600060015460195a03f15080905090506104a0526000610640601f015360605161066052600260a051036106805260a0516106a05260206106c06061610640601f01600060025460195a03f1506106c05160806104a05101526104a05160208103805160018303608080599059016000905260008353818160a185600060005460195a03f150838552809050905090509050905090506106e05260c05160006107e0601f015360206106e051015161080052600260c051036108205260c05161084052602061086060616107e0601f01600060025460195a03f150610860516106e05151096107c05260c05160006108a0601f015360606106e05101516108c052600260c051036108e05260c05161090052602061092060616108a0601f01600060025460195a03f1506109205160406106e05101510961088052604060405990590160009052610940526107c051610940515261088051602061094051015261094051f25b5b6000f2
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_add.se b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_add.se
new file mode 100644
index 000000000..29dc390b2
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_add.se
@@ -0,0 +1,32 @@
+extern all: [call]
+data DOUBLE
+
+def init():
+ self.DOUBLE = create('jacobian_double.se')
+
+def call(axn, axd, ayn, ayd, bxn, bxd, byn, byd):
+ if !axn and !ayn:
+ o = [bxn, bxd, byn, byd]
+ if !bxn and !byn:
+ o = [axn, axd, ayn, ayd]
+ if o:
+ return(o, 4)
+ with P = -4294968273:
+ if addmod(mulmod(axn, bxd, P), P - mulmod(axd, bxn, P), P) == 0:
+ if addmod(mulmod(ayn, byd, P), P - mulmod(ayd, byn, P), P) == 0:
+ return(self.DOUBLE.call(axn, axd, ayn, ayd, outsz=4), 4)
+ else:
+ return([0, 1, 0, 1], 4)
+ with mn = mulmod(addmod(mulmod(byn, ayd, P), P - mulmod(ayn, byd, P), P), mulmod(bxd, axd, P), P):
+ with md = mulmod(mulmod(byd, ayd, P), addmod(mulmod(bxn, axd, P), P - mulmod(axn, bxd, P), P), P):
+ with msqn = mulmod(mn, mn, P):
+ with msqd = mulmod(md, md, P):
+ with msqman = addmod(mulmod(msqn, axd, P), P - mulmod(msqd, axn, P), P):
+ with msqmad = mulmod(msqd, axd, P):
+ with xn = addmod(mulmod(msqman, bxd, P), P - mulmod(msqmad, bxn, P), P):
+ with xd = mulmod(msqmad, bxd, P):
+ with mamxn = mulmod(mn, addmod(mulmod(axn, xd, P), P - mulmod(xn, axd, P), P), P):
+ with mamxd = mulmod(md, mulmod(axd, xd, P), P):
+ with yn = addmod(mulmod(mamxn, ayd, P), P - mulmod(mamxd, ayn, P), P):
+ with yd = mulmod(mamxd, ayd, P):
+ return([xn, xd, yn, yd], 4)
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_double.se b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_double.se
new file mode 100644
index 000000000..b7d8221a6
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_double.se
@@ -0,0 +1,16 @@
+def call(axn, axd, ayn, ayd):
+ if !axn and !ayn:
+ return([0, 1, 0, 1], 4)
+ with P = -4294968273:
+ # No need to add (A, 1) because A = 0 for bitcoin
+ with mn = mulmod(mulmod(mulmod(axn, axn, P), 3, P), ayd, P):
+ with md = mulmod(mulmod(axd, axd, P), mulmod(ayn, 2, P), P):
+ with msqn = mulmod(mn, mn, P):
+ with msqd = mulmod(md, md, P):
+ with xn = addmod(mulmod(msqn, axd, P), P - mulmod(msqd, mulmod(axn, 2, P), P), P):
+ with xd = mulmod(msqd, axd, P):
+ with mamxn = mulmod(addmod(mulmod(axn, xd, P), P - mulmod(axd, xn, P), P), mn, P):
+ with mamxd = mulmod(mulmod(axd, xd, P), md, P):
+ with yn = addmod(mulmod(mamxn, ayd, P), P - mulmod(mamxd, ayn, P), P):
+ with yd = mulmod(mamxd, ayd, P):
+ return([xn, xd, yn, yd], 4)
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_mul.se b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_mul.se
new file mode 100644
index 000000000..bf5b96bb4
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/jacobian_mul.se
@@ -0,0 +1,37 @@
+# Expected gas cost
+#
+# def expect(n, point_at_infinity=False):
+# n = n % (2**256 - 432420386565659656852420866394968145599)
+# if point_at_infinity:
+# return 79
+# if n == 0:
+# return 34479
+# L = int(1 + math.log(n) / math.log(2))
+# H = len([x for x in b.encode(n, 2) if x == '1'])
+# return 34221 + 94 * L + 343 * H
+
+data DOUBLE
+data ADD
+
+def init():
+ self.DOUBLE = create('jacobian_double.se')
+ self.ADD = create('jacobian_add.se')
+
+def call(axn, axd, ayn, ayd, n):
+ n = mod(n, -432420386565659656852420866394968145599)
+ if !axn * !ayn + !n: # Constant-gas version of !axn and !ayn or !n
+ return([0, 1, 0, 1], 4)
+ with o = [0, 0, 1, 0, 1, 0, 0, 0, 0]:
+ with b = 2 ^ 255:
+ while gt(b, 0):
+ if n & b:
+ ~call(20000, self.DOUBLE, 0, o + 31, 129, o + 32, 128)
+ o[5] = axn
+ o[6] = axd
+ o[7] = ayn
+ o[8] = ayd
+ ~call(20000, self.ADD, 0, o + 31, 257, o + 32, 128)
+ else:
+ ~call(20000, self.DOUBLE, 0, o + 31, 129, o + 32, 128)
+ b = div(b, 2)
+ return(o + 32, 4)
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/modexp.se b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/modexp.se
new file mode 100644
index 000000000..687b12a04
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/modexp.se
@@ -0,0 +1,11 @@
+def call(b, e, m):
+ with o = 1:
+ with bit = 2 ^ 255:
+ while gt(bit, 0):
+ # A touch of loop unrolling for 20% efficiency gain
+ o = mulmod(mulmod(o, o, m), b ^ !(!(e & bit)), m)
+ o = mulmod(mulmod(o, o, m), b ^ !(!(e & div(bit, 2))), m)
+ o = mulmod(mulmod(o, o, m), b ^ !(!(e & div(bit, 4))), m)
+ o = mulmod(mulmod(o, o, m), b ^ !(!(e & div(bit, 8))), m)
+ bit = div(bit, 16)
+ return(o)
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/substitutes.py b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/substitutes.py
new file mode 100644
index 000000000..0007da0cf
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/substitutes.py
@@ -0,0 +1,78 @@
+import bitcoin as b
+import math
+import sys
+
+
+def signed(o):
+ return map(lambda x: x - 2**256 if x >= 2**255 else x, o)
+
+
+def hamming_weight(n):
+ return len([x for x in b.encode(n, 2) if x == '1'])
+
+
+def binary_length(n):
+ return len(b.encode(n, 2))
+
+
+def jacobian_mul_substitute(A, B, C, D, N):
+ if A == 0 and C == 0 or (N % b.N) == 0:
+ return {"gas": 86, "output": [0, 1, 0, 1]}
+ else:
+ output = b.jordan_multiply(((A, B), (C, D)), N)
+ return {
+ "gas": 35262 + 95 * binary_length(N % b.N) + 355 * hamming_weight(N % b.N),
+ "output": signed(list(output[0]) + list(output[1]))
+ }
+
+
+def jacobian_add_substitute(A, B, C, D, E, F, G, H):
+ if A == 0 or E == 0:
+ gas = 149
+ elif (A * F - B * E) % b.P == 0:
+ if (C * H - D * G) % b.P == 0:
+ gas = 442
+ else:
+ gas = 177
+ else:
+ gas = 301
+ output = b.jordan_add(((A, B), (C, D)), ((E, F), (G, H)))
+ return {
+ "gas": gas,
+ "output": signed(list(output[0]) + list(output[1]))
+ }
+
+
+def modexp_substitute(base, exp, mod):
+ return {
+ "gas": 5150,
+ "output": signed([pow(base, exp, mod) if mod > 0 else 0])
+ }
+
+
+def ecrecover_substitute(z, v, r, s):
+ P, A, B, N, Gx, Gy = b.P, b.A, b.B, b.N, b.Gx, b.Gy
+ x = r
+ beta = pow(x*x*x+A*x+B, (P + 1) / 4, P)
+ BETA_PREMIUM = modexp_substitute(x, (P + 1) / 4, P)["gas"]
+ y = beta if v % 2 ^ beta % 2 else (P - beta)
+ Gz = b.jordan_multiply(((Gx, 1), (Gy, 1)), (N - z) % N)
+ GZ_PREMIUM = jacobian_mul_substitute(Gx, 1, Gy, 1, (N - z) % N)["gas"]
+ XY = b.jordan_multiply(((x, 1), (y, 1)), s)
+ XY_PREMIUM = jacobian_mul_substitute(x, 1, y, 1, s % N)["gas"]
+ Qr = b.jordan_add(Gz, XY)
+ QR_PREMIUM = jacobian_add_substitute(Gz[0][0], Gz[0][1], Gz[1][0], Gz[1][1],
+ XY[0][0], XY[0][1], XY[1][0], XY[1][1]
+ )["gas"]
+ Q = b.jordan_multiply(Qr, pow(r, N - 2, N))
+ Q_PREMIUM = jacobian_mul_substitute(Qr[0][0], Qr[0][1], Qr[1][0], Qr[1][1],
+ pow(r, N - 2, N))["gas"]
+ R_PREMIUM = modexp_substitute(r, N - 2, N)["gas"]
+ OX_PREMIUM = modexp_substitute(Q[0][1], P - 2, P)["gas"]
+ OY_PREMIUM = modexp_substitute(Q[1][1], P - 2, P)["gas"]
+ Q = b.from_jordan(Q)
+ return {
+ "gas": 991 + BETA_PREMIUM + GZ_PREMIUM + XY_PREMIUM + QR_PREMIUM +
+ Q_PREMIUM + R_PREMIUM + OX_PREMIUM + OY_PREMIUM,
+ "output": signed(Q)
+ }
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/test.py b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/test.py
new file mode 100644
index 000000000..48d21e32f
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/examples/ecc/test.py
@@ -0,0 +1,129 @@
+import bitcoin as b
+import random
+import sys
+import math
+from pyethereum import tester as t
+import substitutes
+import time
+
+vals = [random.randrange(2**256) for i in range(12)]
+
+test_points = [list(p[0]) + list(p[1]) for p in
+ [b.jordan_multiply(((b.Gx, 1), (b.Gy, 1)), r) for r in vals]]
+
+G = [b.Gx, 1, b.Gy, 1]
+Z = [0, 1, 0, 1]
+
+
+def neg_point(p):
+ return [p[0], b.P - p[1], p[2], b.P - p[3]]
+
+s = t.state()
+s.block.gas_limit = 10000000
+t.gas_limit = 1000000
+
+
+c = s.contract('modexp.se')
+print "Starting modexp tests"
+
+for i in range(0, len(vals) - 2, 3):
+ o1 = substitutes.modexp_substitute(vals[i], vals[i+1], vals[i+2])
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=vals[i:i+3])
+ #assert o1["gas"] == o2["gas"], (o1, o2)
+ assert o1["output"] == o2["output"], (o1, o2)
+
+c = s.contract('jacobian_add.se')
+print "Starting addition tests"
+
+for i in range(2):
+ P = test_points[i * 2]
+ Q = test_points[i * 2 + 1]
+ NP = neg_point(P)
+
+ o1 = substitutes.jacobian_add_substitute(*(P + Q))
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=P + Q)
+ #assert o1["gas"] == o2["gas"], (o1, o2)
+ assert o1["output"] == o2["output"], (o1, o2)
+
+ o1 = substitutes.jacobian_add_substitute(*(P + NP))
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=P + NP)
+ #assert o1["gas"] == o2["gas"], (o1, o2)
+ assert o1["output"] == o2["output"], (o1, o2)
+
+ o1 = substitutes.jacobian_add_substitute(*(P + P))
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=P + P)
+ #assert o1["gas"] == o2["gas"], (o1, o2)
+ assert o1["output"] == o2["output"], (o1, o2)
+
+ o1 = substitutes.jacobian_add_substitute(*(P + Z))
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=P + Z)
+ #assert o1["gas"] == o2["gas"], (o1, o2)
+ assert o1["output"] == o2["output"], (o1, o2)
+
+ o1 = substitutes.jacobian_add_substitute(*(Z + P))
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=Z + P)
+ #assert o1["gas"] == o2["gas"], (o1, o2)
+ assert o1["output"] == o2["output"], (o1, o2)
+
+
+c = s.contract('jacobian_mul.se')
+print "Starting multiplication tests"
+
+
+mul_tests = [
+ Z + [0],
+ Z + [vals[0]],
+ test_points[0] + [0],
+ test_points[1] + [b.N],
+ test_points[2] + [1],
+ test_points[2] + [2],
+ test_points[2] + [3],
+ test_points[2] + [4],
+ test_points[3] + [5],
+ test_points[3] + [6],
+ test_points[4] + [7],
+ test_points[4] + [2**254],
+ test_points[4] + [vals[1]],
+ test_points[4] + [vals[2]],
+ test_points[4] + [vals[3]],
+ test_points[5] + [2**256 - 1],
+]
+
+for i, test in enumerate(mul_tests):
+ print 'trying mul_test %i' % i, test
+ o1 = substitutes.jacobian_mul_substitute(*test)
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=test)
+ # assert o1["gas"] == o2["gas"], (o1, o2, test)
+ assert o1["output"] == o2["output"], (o1, o2, test)
+
+c = s.contract('ecrecover.se')
+print "Starting ecrecover tests"
+
+for i in range(5):
+ print 'trying ecrecover_test', vals[i*2], vals[i*2+1]
+ k = vals[i*2]
+ h = vals[i*2+1]
+ V, R, S = b.ecdsa_raw_sign(b.encode(h, 256, 32), k)
+ aa = time.time()
+ o1 = substitutes.ecrecover_substitute(h, V, R, S)
+ print 'sub', time.time() - aa
+ a = time.time()
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=[h, V, R, S])
+ print time.time() - a
+ # assert o1["gas"] == o2["gas"], (o1, o2, h, V, R, S)
+ assert o1["output"] == o2["output"], (o1, o2, h, V, R, S)
+
+# Explicit tests
+
+data = [[
+ 0xf007a9c78a4b2213220adaaf50c89a49d533fbefe09d52bbf9b0da55b0b90b60,
+ 0x1b,
+ 0x5228fc9e2fabfe470c32f459f4dc17ef6a0a81026e57e4d61abc3bc268fc92b5,
+ 0x697d4221cd7bc5943b482173de95d3114b9f54c5f37cc7f02c6910c6dd8bd107
+]]
+
+for datum in data:
+ o1 = substitutes.ecrecover_substitute(*datum)
+ o2 = s.profile(t.k0, c, 0, funid=0, abi=datum)
+ #assert o1["gas"] == o2["gas"], (o1, o2, datum)
+ assert o1["output"] == o2["output"], (o1, o2, datum)