Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.crypto.ec/share/classes/sun/security/ec/ed/Ed25519Operations.java
41162 views
1
/*
2
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
package sun.security.ec.ed;
26
27
import sun.security.ec.point.*;
28
import sun.security.util.math.*;
29
30
import java.math.BigInteger;
31
import java.util.function.Function;
32
33
/*
34
* Elliptic curve point arithmetic, decoding, and other operations for the
35
* family of curves including edwards25519 and its related group. Though the
36
* operations in this class are optimized for edwards25519, they are correct
37
* for any twisted Edwards curve ax^2 + y^2 = 1 + dx^2y^2 (mod p) with the
38
* following properties:
39
* 1) a = -1 (mod p)
40
* 2) a is square (mod p)
41
* 3) d is not square (mod p)
42
*/
43
public class Ed25519Operations extends EdECOperations {
44
45
private final SmallValue two;
46
private final ImmutableIntegerModuloP d;
47
private final ExtendedHomogeneousPoint.Immutable basePoint;
48
49
private static final BigInteger TWO = BigInteger.valueOf(2);
50
private static final BigInteger SEVEN = BigInteger.valueOf(7);
51
private final BigInteger sizeMinus5;
52
53
public Ed25519Operations(ImmutableIntegerModuloP d, BigInteger baseX,
54
BigInteger baseY) {
55
56
this.two = d.getField().getSmallValue(2);
57
this.d = d;
58
this.basePoint = of(new AffinePoint(
59
d.getField().getElement(baseX), d.getField().getElement(baseY)
60
));
61
this.sizeMinus5 =
62
d.getField().getSize().subtract(BigInteger.valueOf(5));
63
}
64
65
@Override
66
public Point basePointMultiply(byte[] scalar) {
67
return setProduct(basePoint.mutable(), scalar);
68
}
69
70
@Override
71
protected ExtendedHomogeneousPoint.Immutable getNeutral() {
72
IntegerFieldModuloP field = d.getField();
73
return new ExtendedHomogeneousPoint.Immutable(field.get0(),
74
field.get1(), field.get0(), field.get1());
75
}
76
77
@Override
78
protected MutablePoint setSum(MutablePoint p1, MutablePoint p2,
79
MutableIntegerModuloP t1,
80
MutableIntegerModuloP t2,
81
MutableIntegerModuloP t3) {
82
83
ExtendedHomogeneousPoint.Mutable ehp1 =
84
(ExtendedHomogeneousPoint.Mutable) p1;
85
ExtendedHomogeneousPoint.Mutable ehp2 =
86
(ExtendedHomogeneousPoint.Mutable) p2;
87
return setSum(ehp1, ehp2, t1, t2, t3);
88
}
89
90
@Override
91
protected MutablePoint setDouble(MutablePoint p, MutableIntegerModuloP t1,
92
MutableIntegerModuloP t2) {
93
94
ExtendedHomogeneousPoint.Mutable ehp =
95
(ExtendedHomogeneousPoint.Mutable) p;
96
return setDouble(ehp, t1, t2);
97
}
98
99
@Override
100
public ExtendedHomogeneousPoint.Immutable of(AffinePoint p) {
101
return new ExtendedHomogeneousPoint.Immutable(p.getX(), p.getY(),
102
p.getX().multiply(p.getY()), p.getX().getField().get1());
103
}
104
105
@Override
106
public <T extends Throwable>
107
AffinePoint decodeAffinePoint(Function<String, T> exception,
108
int xLSB, IntegerModuloP y) throws T {
109
110
IntegerFieldModuloP field = d.getField();
111
BigInteger p = field.getSize();
112
ImmutableIntegerModuloP y2 = y.square();
113
ImmutableIntegerModuloP u = y2.subtract(field.get1());
114
MutableIntegerModuloP v = d.mutable().setProduct(y2)
115
.setSum(field.get1());
116
117
MutableIntegerModuloP x =
118
u.mutable().setProduct(v.pow(BigInteger.valueOf(3)));
119
ImmutableIntegerModuloP uv7pow =
120
u.multiply(v.pow(SEVEN)).pow(sizeMinus5.shiftRight(3));
121
x.setProduct(uv7pow);
122
123
v.setProduct(x).setProduct(x);
124
// v now holds vx^2
125
BigInteger bigVX2 = v.asBigInteger();
126
if (bigVX2.equals(u.asBigInteger())) {
127
// do nothing---x is correct
128
} else if (bigVX2.equals(u.additiveInverse().asBigInteger())) {
129
BigInteger exp = p.subtract(BigInteger.ONE).shiftRight(2);
130
IntegerModuloP twoPow = field.getElement(TWO.modPow(exp, p));
131
x.setProduct(twoPow);
132
} else {
133
throw exception.apply("Invalid point");
134
}
135
136
if (x.asBigInteger().equals(BigInteger.ZERO) && xLSB == 1) {
137
throw exception.apply("Invalid point");
138
}
139
140
if (xLSB != x.asBigInteger().mod(BigInteger.valueOf(2)).intValue()) {
141
x.setAdditiveInverse();
142
}
143
144
return new AffinePoint(x.fixed(), y.fixed());
145
}
146
147
ExtendedHomogeneousPoint.Mutable setSum(
148
ExtendedHomogeneousPoint.Mutable p1,
149
ExtendedHomogeneousPoint.Mutable p2,
150
MutableIntegerModuloP t1,
151
MutableIntegerModuloP t2,
152
MutableIntegerModuloP t3) {
153
154
t1.setValue(p2.getY()).setDifference(p2.getX());
155
// t1 holds y2 - x2
156
t2.setValue(p1.getY()).setDifference(p1.getX()).setProduct(t1);
157
// t2 holds A = (y1 - x1) * (y2 - x2)
158
t1.setValue(p2.getY()).setSum(p2.getX());
159
// t1 holds y2 + x2
160
t3.setValue(p1.getY()).setSum(p1.getX()).setProduct(t1);
161
// t3 holds B = (y1 + x1) * (y2 + x2)
162
p1.getX().setValue(t3).setDifference(t2);
163
// x holds E = B - A
164
t3.setSum(t2);
165
// t3 holds H = B + A, t2 is unused
166
t2.setValue(d).setSum(d).setProduct(p1.getT()).setProduct(p2.getT());
167
// t2 holds C
168
t1.setValue(p1.getZ()).setProduct(p2.getZ()).setProduct(two);
169
// t1 holds D
170
p1.getY().setValue(t1).setSum(t2);
171
// y holds G
172
p1.getZ().setValue(t1).setDifference(t2);
173
// z holds F
174
175
p1.getT().setValue(p1.getX()).setProduct(t3);
176
p1.getX().setProduct(p1.getZ());
177
p1.getZ().setProduct(p1.getY());
178
p1.getY().setProduct(t3);
179
180
return p1;
181
182
}
183
184
protected ExtendedHomogeneousPoint.Mutable setDouble(
185
ExtendedHomogeneousPoint.Mutable p,
186
MutableIntegerModuloP t1, MutableIntegerModuloP t2) {
187
188
t1.setValue(p.getX()).setSum(p.getY()).setSquare();
189
// t1 holds (x + y)^2
190
p.getX().setSquare();
191
// x = A = x^2
192
p.getY().setSquare();
193
// y = B = y^2
194
t2.setValue(p.getX()).setSum(p.getY()).setReduced();
195
// t2 holds H
196
p.getZ().setSquare().setProduct(two);
197
// z holds C
198
199
p.getT().setValue(t2).setDifference(t1);
200
// t holds E
201
t1.setValue(p.getX()).setDifference(p.getY()).setReduced();
202
// t1 holds G
203
204
p.getZ().setSum(t1);
205
// z holds F
206
207
p.getX().setValue(p.getT()).setProduct(p.getZ());
208
p.getY().setValue(t1).setProduct(t2);
209
p.getT().setProduct(t2);
210
p.getZ().setProduct(t1);
211
212
return p;
213
}
214
}
215
216