Skip to content

Commit 3e903e9

Browse files
committed
Tron EVM 1.0
1 parent 38146a4 commit 3e903e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+11522
-16
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/*
2+
* Copyright (c) [2016] [ <ether.camp> ]
3+
* This file is part of the ethereumJ library.
4+
*
5+
* The ethereumJ library is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* The ethereumJ library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package org.tron.common.crypto.zksnark;
19+
20+
import java.math.BigInteger;
21+
22+
/**
23+
* Implementation of Barreto–Naehrig curve defined over abstract finite field. This curve is one of the keys to zkSNARKs. <br/>
24+
* This specific curve was introduced in
25+
* <a href="https://github.com/scipr-lab/libff#elliptic-curve-choices">libff</a>
26+
* and used by a proving system in
27+
* <a href="https://github.com/zcash/zcash/wiki/specification#zcash-protocol">ZCash protocol</a> <br/>
28+
* <br/>
29+
*
30+
* Curve equation: <br/>
31+
* Y^2 = X^3 + b, where "b" is a constant number belonging to corresponding specific field <br/>
32+
* Point at infinity is encoded as <code>(0, 0, 0)</code> <br/>
33+
* <br/>
34+
*
35+
* This curve has embedding degree 12 with respect to "r" (see {@link Params#R}), which means that "r" is a multiple of "p ^ 12 - 1",
36+
* this condition is important for pairing operation implemented in {@link PairingCheck}<br/>
37+
* <br/>
38+
*
39+
* Code of curve arithmetic has been ported from
40+
* <a href="https://github.com/scipr-lab/libff/blob/master/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp">libff</a> <br/>
41+
* <br/>
42+
*
43+
* Current implementation uses Jacobian coordinate system as
44+
* <a href="https://github.com/scipr-lab/libff/blob/master/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp">libff</a> does,
45+
* use {@link #toEthNotation()} to convert Jacobian coords to Ethereum encoding <br/>
46+
*
47+
* @author Mikhail Kalinin
48+
* @since 05.09.2017
49+
*/
50+
public abstract class BN128<T extends Field<T>> {
51+
52+
protected T x;
53+
protected T y;
54+
protected T z;
55+
56+
protected BN128(T x, T y, T z) {
57+
this.x = x;
58+
this.y = y;
59+
this.z = z;
60+
}
61+
62+
/**
63+
* Point at infinity in Ethereum notation: should return (0; 0; 0),
64+
* {@link #isZero()} method called for that point, also, returns {@code true}
65+
*/
66+
abstract protected BN128<T> zero();
67+
abstract protected BN128<T> instance(T x, T y, T z);
68+
abstract protected T b();
69+
abstract protected T one();
70+
71+
/**
72+
* Transforms given Jacobian to affine coordinates and then creates a point
73+
*/
74+
public BN128<T> toAffine() {
75+
76+
if (isZero()) {
77+
BN128<T> zero = zero();
78+
return instance(zero.x, one(), zero.z); // (0; 1; 0)
79+
}
80+
81+
T zInv = z.inverse();
82+
T zInv2 = zInv.squared();
83+
T zInv3 = zInv2.mul(zInv);
84+
85+
T ax = x.mul(zInv2);
86+
T ay = y.mul(zInv3);
87+
88+
return instance(ax, ay, one());
89+
}
90+
91+
/**
92+
* Runs affine transformation and encodes point at infinity as (0; 0; 0)
93+
*/
94+
public BN128<T> toEthNotation() {
95+
BN128<T> affine = toAffine();
96+
97+
// affine zero is (0; 1; 0), convert to Ethereum zero: (0; 0; 0)
98+
if (affine.isZero()) {
99+
return zero();
100+
} else {
101+
return affine;
102+
}
103+
}
104+
105+
protected boolean isOnCurve() {
106+
107+
if (isZero()) return true;
108+
109+
T z6 = z.squared().mul(z).squared();
110+
111+
T left = y.squared(); // y^2
112+
T right = x.squared().mul(x).add(b().mul(z6)); // x^3 + b * z^6
113+
return left.equals(right);
114+
}
115+
116+
public BN128<T> add(BN128<T> o) {
117+
118+
if (this.isZero()) return o; // 0 + P = P
119+
if (o.isZero()) return this; // P + 0 = P
120+
121+
T x1 = this.x, y1 = this.y, z1 = this.z;
122+
T x2 = o.x, y2 = o.y, z2 = o.z;
123+
124+
// ported code is started from here
125+
// next calculations are done in Jacobian coordinates
126+
127+
T z1z1 = z1.squared();
128+
T z2z2 = z2.squared();
129+
130+
T u1 = x1.mul(z2z2);
131+
T u2 = x2.mul(z1z1);
132+
133+
T z1Cubed = z1.mul(z1z1);
134+
T z2Cubed = z2.mul(z2z2);
135+
136+
T s1 = y1.mul(z2Cubed); // s1 = y1 * Z2^3
137+
T s2 = y2.mul(z1Cubed); // s2 = y2 * Z1^3
138+
139+
if (u1.equals(u2) && s1.equals(s2)) {
140+
return dbl(); // P + P = 2P
141+
}
142+
143+
T h = u2.sub(u1); // h = u2 - u1
144+
T i = h.dbl().squared(); // i = (2 * h)^2
145+
T j = h.mul(i); // j = h * i
146+
T r = s2.sub(s1).dbl(); // r = 2 * (s2 - s1)
147+
T v = u1.mul(i); // v = u1 * i
148+
T zz = z1.add(z2).squared()
149+
.sub(z1.squared()).sub(z2.squared());
150+
151+
T x3 = r.squared().sub(j).sub(v.dbl()); // x3 = r^2 - j - 2 * v
152+
T y3 = v.sub(x3).mul(r).sub(s1.mul(j).dbl()); // y3 = r * (v - x3) - 2 * (s1 * j)
153+
T z3 = zz.mul(h); // z3 = ((z1+z2)^2 - z1^2 - z2^2) * h = zz * h
154+
155+
return instance(x3, y3, z3);
156+
}
157+
158+
public BN128<T> mul(BigInteger s) {
159+
160+
if (s.compareTo(BigInteger.ZERO) == 0) // P * 0 = 0
161+
return zero();
162+
163+
if (isZero()) return this; // 0 * s = 0
164+
165+
BN128<T> res = zero();
166+
167+
for (int i = s.bitLength() - 1; i >= 0; i--) {
168+
169+
res = res.dbl();
170+
171+
if (s.testBit(i)) {
172+
res = res.add(this);
173+
}
174+
}
175+
176+
return res;
177+
}
178+
179+
private BN128<T> dbl() {
180+
181+
if (isZero()) return this;
182+
183+
// ported code is started from here
184+
// next calculations are done in Jacobian coordinates with z = 1
185+
186+
T a = x.squared(); // a = x^2
187+
T b = y.squared(); // b = y^2
188+
T c = b.squared(); // c = b^2
189+
T d = x.add(b).squared().sub(a).sub(c);
190+
d = d.add(d); // d = 2 * ((x + b)^2 - a - c)
191+
T e = a.add(a).add(a); // e = 3 * a
192+
T f = e.squared(); // f = e^2
193+
194+
T x3 = f.sub(d.add(d)); // rx = f - 2 * d
195+
T y3 = e.mul(d.sub(x3)).sub(c.dbl().dbl().dbl()); // ry = e * (d - rx) - 8 * c
196+
T z3 = y.mul(z).dbl(); // z3 = 2 * y * z
197+
198+
return instance(x3, y3, z3);
199+
}
200+
201+
public T x() {
202+
return x;
203+
}
204+
205+
public T y() {
206+
return y;
207+
}
208+
209+
public boolean isZero() {
210+
return z.isZero();
211+
}
212+
213+
protected boolean isValid() {
214+
215+
// check whether coordinates belongs to the Field
216+
if (!x.isValid() || !y.isValid() || !z.isValid()) {
217+
return false;
218+
}
219+
220+
// check whether point is on the curve
221+
if (!isOnCurve()) {
222+
return false;
223+
}
224+
225+
return true;
226+
}
227+
228+
@Override
229+
public String toString() {
230+
return String.format("(%s; %s; %s)", x.toString(), y.toString(), z.toString());
231+
}
232+
233+
@Override
234+
@SuppressWarnings("all")
235+
public boolean equals(Object o) {
236+
if (this == o) return true;
237+
if (!(o instanceof BN128)) return false;
238+
239+
BN128<?> bn128 = (BN128<?>) o;
240+
241+
if (x != null ? !x.equals(bn128.x) : bn128.x != null) return false;
242+
if (y != null ? !y.equals(bn128.y) : bn128.y != null) return false;
243+
return !(z != null ? !z.equals(bn128.z) : bn128.z != null);
244+
}
245+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) [2016] [ <ether.camp> ]
3+
* This file is part of the ethereumJ library.
4+
*
5+
* The ethereumJ library is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* The ethereumJ library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package org.tron.common.crypto.zksnark;
19+
20+
import static org.tron.common.crypto.zksnark.Params.B_Fp;
21+
22+
/**
23+
* Definition of {@link BN128} over F_p, where "p" equals {@link Params#P} <br/>
24+
*
25+
* Curve equation: <br/>
26+
* Y^2 = X^3 + b, where "b" equals {@link Params#B_Fp} <br/>
27+
*
28+
* @author Mikhail Kalinin
29+
* @since 21.08.2017
30+
*/
31+
public class BN128Fp extends BN128<Fp> {
32+
33+
// the point at infinity
34+
static final BN128<Fp> ZERO = new BN128Fp(Fp.ZERO, Fp.ZERO, Fp.ZERO);
35+
36+
protected BN128Fp(Fp x, Fp y, Fp z) {
37+
super(x, y, z);
38+
}
39+
40+
@Override
41+
protected BN128<Fp> zero() {
42+
return ZERO;
43+
}
44+
45+
@Override
46+
protected BN128<Fp> instance(Fp x, Fp y, Fp z) {
47+
return new BN128Fp(x, y, z);
48+
}
49+
50+
@Override
51+
protected Fp b() {
52+
return B_Fp;
53+
}
54+
55+
@Override
56+
protected Fp one() {
57+
return Fp._1;
58+
}
59+
60+
/**
61+
* Checks whether x and y belong to Fp,
62+
* then checks whether point with (x; y) coordinates lays on the curve.
63+
*
64+
* Returns new point if all checks have been passed,
65+
* otherwise returns null
66+
*/
67+
public static BN128<Fp> create(byte[] xx, byte[] yy) {
68+
69+
Fp x = Fp.create(xx);
70+
Fp y = Fp.create(yy);
71+
72+
// check for point at infinity
73+
if (x.isZero() && y.isZero()) {
74+
return ZERO;
75+
}
76+
77+
BN128<Fp> p = new BN128Fp(x, y, Fp._1);
78+
79+
// check whether point is a valid one
80+
if (p.isValid()) {
81+
return p;
82+
} else {
83+
return null;
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)