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/EdDSAParameters.java
41162 views
1
/*
2
* Copyright (c) 2020, 2021, 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.ParametersMap;
28
import sun.security.provider.SHAKE256;
29
import sun.security.util.ObjectIdentifier;
30
import sun.security.util.KnownOIDs;
31
import sun.security.util.math.*;
32
import sun.security.util.math.intpoly.*;
33
import sun.security.x509.AlgorithmId;
34
35
import java.io.IOException;
36
import java.math.BigInteger;
37
import java.nio.charset.StandardCharsets;
38
import java.security.*;
39
import java.security.spec.*;
40
import java.util.function.Function;
41
42
/*
43
* The set of parameters that defines an instance of the EdDSA signature
44
* scheme.
45
*/
46
public class EdDSAParameters {
47
48
public interface DigesterFactory {
49
// Default digest creator
50
Digester createDigester();
51
52
// Override this method if multiple key lengths are needed
53
default Digester createDigester(int len) {
54
return createDigester();
55
}
56
57
// Return a digest over all the provided byte arrays
58
default byte[] digest(byte[]... data) {
59
Digester d = createDigester();
60
for (byte[] curData : data) {
61
d.update(curData, 0, curData.length);
62
}
63
return d.digest();
64
}
65
}
66
67
// Hash for Ed25519
68
private static class SHA512DigesterFactory implements DigesterFactory {
69
@Override
70
public Digester createDigester() {
71
try {
72
MessageDigest md = MessageDigest.getInstance("SHA-512");
73
return new MessageDigester(md);
74
} catch (NoSuchAlgorithmException ex) {
75
throw new ProviderException(ex);
76
}
77
}
78
}
79
80
// Hash for Ed448
81
private static class SHAKE256DigesterFactory implements DigesterFactory {
82
@Override
83
// Most usage for Ed448 is 114bytes long
84
public Digester createDigester() {
85
return new SHAKE256Digester(114);
86
}
87
88
// Ed448 uses 64bytes long hasg for the signature message
89
@Override
90
public Digester createDigester(int len) {
91
return new SHAKE256Digester(len);
92
}
93
}
94
95
public interface Digester {
96
void update(byte data);
97
void update(byte[] data, int off, int len);
98
byte[] digest();
99
}
100
101
private static class MessageDigester implements Digester {
102
private final MessageDigest md;
103
104
private MessageDigester(MessageDigest md) {
105
this.md = md;
106
}
107
108
@Override
109
public void update(byte data) {
110
md.update(data);
111
}
112
@Override
113
public void update(byte[] data, int off, int len) {
114
md.update(data, off, len);
115
}
116
@Override
117
public byte[] digest() {
118
try {
119
return md.digest();
120
} finally {
121
md.reset();
122
}
123
}
124
}
125
126
private static class SHAKE256Digester implements Digester {
127
SHAKE256 md;
128
129
SHAKE256Digester(int len) {
130
md = new SHAKE256(len);
131
}
132
@Override
133
public void update(byte data) {
134
md.update(data);
135
}
136
@Override
137
public void update(byte[] data, int off, int len) {
138
md.update(data, off, len);
139
}
140
@Override
141
public byte[] digest() {
142
try {
143
return md.digest();
144
} finally {
145
md.reset();
146
}
147
}
148
}
149
150
static ParametersMap<EdDSAParameters> namedParams = new ParametersMap<>();
151
152
private final String name;
153
private final ObjectIdentifier oid;
154
private final IntegerFieldModuloP field;
155
private final IntegerFieldModuloP orderField;
156
private final ImmutableIntegerModuloP d;
157
private final EdECOperations edOperations;
158
private final DigesterFactory digester;
159
private final int keyLength;
160
private final int bits;
161
private final int logCofactor;
162
private final Function<EdDSAParameterSpec, byte[]> dom;
163
164
public EdDSAParameters(String name, ObjectIdentifier oid,
165
IntegerFieldModuloP field,
166
IntegerFieldModuloP orderField,
167
ImmutableIntegerModuloP d,
168
EdECOperations edOps,
169
DigesterFactory digester,
170
Function<EdDSAParameterSpec, byte[]> dom,
171
int keyLength, int bits, int logCofactor) {
172
this.oid = oid;
173
this.name = name;
174
this.field = field;
175
this.orderField = orderField;
176
this.d = d;
177
this.edOperations = edOps;
178
this.digester = digester;
179
this.keyLength = keyLength;
180
this.bits = bits;
181
this.logCofactor = logCofactor;
182
this.dom = dom;
183
}
184
185
public String getName() {
186
return name;
187
}
188
public ObjectIdentifier getOid() {
189
return oid;
190
}
191
public IntegerFieldModuloP getField() {
192
return field;
193
}
194
public IntegerFieldModuloP getOrderField() {
195
return orderField;
196
}
197
public ImmutableIntegerModuloP getD() {
198
return d;
199
}
200
public EdECOperations getEdOperations() {
201
return edOperations;
202
}
203
public int getKeyLength() {
204
return keyLength;
205
}
206
public int getBits() {
207
return bits;
208
}
209
public int getLogCofactor() {
210
return logCofactor;
211
}
212
213
public Digester createDigester() {
214
return digester.createDigester();
215
}
216
217
public Digester createDigester(int len) {
218
return digester.createDigester(len);
219
}
220
221
public byte[] digest(byte[]... data) {
222
return digester.digest(data);
223
}
224
225
public byte[] dom(EdDSAParameterSpec sigParams) {
226
return dom.apply(sigParams);
227
}
228
229
private static final String prefixStr25519 =
230
"SigEd25519 no Ed25519 collisions";
231
private static final String prefixStr448 = "SigEd448";
232
233
// Used for Ed25519
234
static byte[] dom2(EdDSAParameterSpec sigParams) {
235
if (!sigParams.isPrehash() && !sigParams.getContext().isPresent()) {
236
return new byte[0];
237
}
238
return domImpl(prefixStr25519, sigParams);
239
}
240
241
// Used for Ed488
242
static byte[] dom4(EdDSAParameterSpec sigParams) {
243
return domImpl(prefixStr448, sigParams);
244
}
245
246
static byte[] domImpl(String prefixStr, EdDSAParameterSpec sigParams) {
247
byte[] prefix = prefixStr.getBytes(StandardCharsets.US_ASCII);
248
byte[] context = sigParams.getContext().orElse(new byte[0]);
249
int length = prefix.length + 2 + context.length;
250
byte[] result = new byte[length];
251
System.arraycopy(prefix, 0, result, 0, prefix.length);
252
byte x = (byte) (sigParams.isPrehash() ? 1 : 0);
253
result[prefix.length] = x;
254
result[prefix.length + 1] = (byte) context.length;
255
System.arraycopy(context, 0, result, prefix.length + 2,
256
context.length);
257
return result;
258
}
259
260
static {
261
// set up Ed25519
262
IntegerFieldModuloP ed25519Field = new IntegerPolynomial25519();
263
IntegerFieldModuloP ed25519OrderField = new Curve25519OrderField();
264
BigInteger biD = new BigInteger("3709570593466943934313808350875" +
265
"4565189542113879843219016388785533085940283555");
266
ImmutableIntegerModuloP d = ed25519Field.getElement(biD);
267
BigInteger baseX = new BigInteger("15112221349535400772501151409" +
268
"588531511454012693041857206046113283949847762202");
269
BigInteger baseY = new BigInteger("46316835694926478169428394003" +
270
"475163141307993866256225615783033603165251855960");
271
EdECOperations edOps = new Ed25519Operations(d, baseX, baseY);
272
String name = NamedParameterSpec.ED25519.getName();
273
ObjectIdentifier oid = ObjectIdentifier.of(KnownOIDs.Ed25519);
274
int bits = 255;
275
DigesterFactory digester = new SHA512DigesterFactory();
276
EdDSAParameters params = new EdDSAParameters(name, oid,
277
ed25519Field, ed25519OrderField, d, edOps,
278
digester, EdDSAParameters::dom2, 32, bits, 3);
279
280
namedParams.put(name, oid, bits, params);
281
282
// set up Ed448
283
IntegerFieldModuloP ed448Field = new IntegerPolynomial448();
284
IntegerFieldModuloP ed448OrderField = new Curve448OrderField();
285
biD = ed448Field.getSize().subtract(new BigInteger("39081"));
286
d = ed448Field.getElement(biD);
287
baseX = new BigInteger("224580040295924300187604334" +
288
"099896036246789641632564134246125461686950415467406032909" +
289
"029192869357953282578032075146446173674602635247710");
290
baseY = new BigInteger("298819210078481492676017930" +
291
"443930673437544040154080242095928241372331506189835876003" +
292
"536878655418784733982303233503462500531545062832660");
293
edOps = new Ed448Operations(d, baseX, baseY);
294
name = NamedParameterSpec.ED448.getName();
295
oid = ObjectIdentifier.of(KnownOIDs.Ed448);
296
bits = 448;
297
digester = new SHAKE256DigesterFactory();
298
params = new EdDSAParameters(name, oid,
299
ed448Field, ed448OrderField, d, edOps,
300
digester, EdDSAParameters::dom4, 57, bits, 2);
301
302
namedParams.put(name, oid, bits, params);
303
304
namedParams.fix();
305
}
306
307
public static
308
<T extends Throwable>
309
EdDSAParameters getBySize(Function<String, T> exception,
310
int size) throws T {
311
312
return namedParams.getBySize(exception, size);
313
}
314
315
public static
316
<T extends Throwable>
317
EdDSAParameters get(Function<String, T> exception,
318
AlgorithmId algId) throws T {
319
320
return namedParams.get(exception, algId);
321
}
322
323
public static
324
<T extends Throwable>
325
EdDSAParameters get(Function<String, T> exception,
326
AlgorithmParameterSpec params) throws T {
327
328
return namedParams.get(exception, params);
329
}
330
}
331
332