ed-precompiled_ed25519 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES.md +88 -0
- data/LICENSE +22 -0
- data/README.md +181 -0
- data/ed25519.png +0 -0
- data/ext/ed25519_jruby/LICENSE.txt +123 -0
- data/ext/ed25519_jruby/README.md +77 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAEngine.java +491 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAKey.java +31 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAPrivateKey.java +338 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAPublicKey.java +275 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSASecurityProvider.java +59 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/KeyFactory.java +75 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/KeyPairGenerator.java +97 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/Utils.java +103 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Constants.java +23 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Curve.java +100 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Encoding.java +54 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Field.java +99 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/FieldElement.java +76 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/GroupElement.java +1034 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ScalarOps.java +34 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElement.java +131 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerLittleEndianEncoding.java +102 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerScalarOps.java +37 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/package.html +6 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519FieldElement.java +988 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519LittleEndianEncoding.java +256 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519ScalarOps.java +693 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAGenParameterSpec.java +32 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSANamedCurveSpec.java +35 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSANamedCurveTable.java +71 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java +97 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java +133 -0
- data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAPublicKeySpec.java +61 -0
- data/ext/ed25519_jruby/org/cryptorb/Ed25519Provider.java +95 -0
- data/ext/ed25519_ref10/api.h +4 -0
- data/ext/ed25519_ref10/base.h +1344 -0
- data/ext/ed25519_ref10/base2.h +40 -0
- data/ext/ed25519_ref10/d.h +1 -0
- data/ext/ed25519_ref10/d2.h +1 -0
- data/ext/ed25519_ref10/ed25519_ref10.c +99 -0
- data/ext/ed25519_ref10/ed25519_ref10.h +33 -0
- data/ext/ed25519_ref10/extconf.rb +7 -0
- data/ext/ed25519_ref10/fe.c +1085 -0
- data/ext/ed25519_ref10/fe.h +56 -0
- data/ext/ed25519_ref10/ge.c +407 -0
- data/ext/ed25519_ref10/ge.h +95 -0
- data/ext/ed25519_ref10/ge_add.h +97 -0
- data/ext/ed25519_ref10/ge_madd.h +88 -0
- data/ext/ed25519_ref10/ge_msub.h +88 -0
- data/ext/ed25519_ref10/ge_p2_dbl.h +73 -0
- data/ext/ed25519_ref10/ge_sub.h +97 -0
- data/ext/ed25519_ref10/keypair.c +22 -0
- data/ext/ed25519_ref10/open.c +47 -0
- data/ext/ed25519_ref10/pow22523.h +160 -0
- data/ext/ed25519_ref10/pow225521.h +160 -0
- data/ext/ed25519_ref10/sc.h +17 -0
- data/ext/ed25519_ref10/sc_muladd.c +366 -0
- data/ext/ed25519_ref10/sc_reduce.c +272 -0
- data/ext/ed25519_ref10/sha512.c +304 -0
- data/ext/ed25519_ref10/sha512.h +8 -0
- data/ext/ed25519_ref10/sign.c +41 -0
- data/ext/ed25519_ref10/sqrtm1.h +1 -0
- data/ext/ed25519_ref10/verify.c +40 -0
- data/lib/ed25519/signing_key.rb +60 -0
- data/lib/ed25519/verify_key.rb +45 -0
- data/lib/ed25519/version.rb +5 -0
- data/lib/ed25519.rb +77 -0
- metadata +126 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdDSA-Java by str4d
|
|
3
|
+
*
|
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
|
6
|
+
* to EdDSA-Java.
|
|
7
|
+
*
|
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
package net.i2p.crypto.eddsa;
|
|
13
|
+
|
|
14
|
+
import java.security.InvalidKeyException;
|
|
15
|
+
import java.security.Key;
|
|
16
|
+
import java.security.KeyFactorySpi;
|
|
17
|
+
import java.security.PrivateKey;
|
|
18
|
+
import java.security.PublicKey;
|
|
19
|
+
import java.security.spec.InvalidKeySpecException;
|
|
20
|
+
import java.security.spec.KeySpec;
|
|
21
|
+
import java.security.spec.PKCS8EncodedKeySpec;
|
|
22
|
+
import java.security.spec.X509EncodedKeySpec;
|
|
23
|
+
|
|
24
|
+
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
|
|
25
|
+
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @author str4d
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
31
|
+
public final class KeyFactory extends KeyFactorySpi {
|
|
32
|
+
|
|
33
|
+
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
|
|
34
|
+
throws InvalidKeySpecException {
|
|
35
|
+
if (keySpec instanceof EdDSAPrivateKeySpec) {
|
|
36
|
+
return new EdDSAPrivateKey((EdDSAPrivateKeySpec) keySpec);
|
|
37
|
+
}
|
|
38
|
+
if (keySpec instanceof PKCS8EncodedKeySpec) {
|
|
39
|
+
return new EdDSAPrivateKey((PKCS8EncodedKeySpec) keySpec);
|
|
40
|
+
}
|
|
41
|
+
throw new InvalidKeySpecException("key spec not recognised: " + keySpec.getClass());
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected PublicKey engineGeneratePublic(KeySpec keySpec)
|
|
45
|
+
throws InvalidKeySpecException {
|
|
46
|
+
if (keySpec instanceof EdDSAPublicKeySpec) {
|
|
47
|
+
return new EdDSAPublicKey((EdDSAPublicKeySpec) keySpec);
|
|
48
|
+
}
|
|
49
|
+
if (keySpec instanceof X509EncodedKeySpec) {
|
|
50
|
+
return new EdDSAPublicKey((X509EncodedKeySpec) keySpec);
|
|
51
|
+
}
|
|
52
|
+
throw new InvalidKeySpecException("key spec not recognised: " + keySpec.getClass());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@SuppressWarnings("unchecked")
|
|
56
|
+
protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
|
|
57
|
+
throws InvalidKeySpecException {
|
|
58
|
+
if (keySpec.isAssignableFrom(EdDSAPublicKeySpec.class) && key instanceof EdDSAPublicKey) {
|
|
59
|
+
EdDSAPublicKey k = (EdDSAPublicKey) key;
|
|
60
|
+
if (k.getParams() != null) {
|
|
61
|
+
return (T) new EdDSAPublicKeySpec(k.getA(), k.getParams());
|
|
62
|
+
}
|
|
63
|
+
} else if (keySpec.isAssignableFrom(EdDSAPrivateKeySpec.class) && key instanceof EdDSAPrivateKey) {
|
|
64
|
+
EdDSAPrivateKey k = (EdDSAPrivateKey) key;
|
|
65
|
+
if (k.getParams() != null) {
|
|
66
|
+
return (T) new EdDSAPrivateKeySpec(k.getSeed(), k.getH(), k.geta(), k.getA(), k.getParams());
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
throw new InvalidKeySpecException("not implemented yet " + key + " " + keySpec);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
protected Key engineTranslateKey(Key key) throws InvalidKeyException {
|
|
73
|
+
throw new InvalidKeyException("No other EdDSA key providers known");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdDSA-Java by str4d
|
|
3
|
+
*
|
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
|
6
|
+
* to EdDSA-Java.
|
|
7
|
+
*
|
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
package net.i2p.crypto.eddsa;
|
|
13
|
+
|
|
14
|
+
import java.security.InvalidAlgorithmParameterException;
|
|
15
|
+
import java.security.InvalidParameterException;
|
|
16
|
+
import java.security.KeyPair;
|
|
17
|
+
import java.security.KeyPairGeneratorSpi;
|
|
18
|
+
import java.security.SecureRandom;
|
|
19
|
+
import java.security.spec.AlgorithmParameterSpec;
|
|
20
|
+
import java.util.Hashtable;
|
|
21
|
+
|
|
22
|
+
import net.i2p.crypto.eddsa.spec.EdDSAGenParameterSpec;
|
|
23
|
+
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
|
|
24
|
+
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
|
25
|
+
import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
|
|
26
|
+
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
|
|
27
|
+
import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Default keysize is 256 (Ed25519)
|
|
31
|
+
*/
|
|
32
|
+
public final class KeyPairGenerator extends KeyPairGeneratorSpi {
|
|
33
|
+
private static final int DEFAULT_KEYSIZE = 256;
|
|
34
|
+
private EdDSAParameterSpec edParams;
|
|
35
|
+
private SecureRandom random;
|
|
36
|
+
private boolean initialized;
|
|
37
|
+
|
|
38
|
+
private static final Hashtable<Integer, AlgorithmParameterSpec> edParameters;
|
|
39
|
+
|
|
40
|
+
static {
|
|
41
|
+
edParameters = new Hashtable<Integer, AlgorithmParameterSpec>();
|
|
42
|
+
|
|
43
|
+
edParameters.put(Integer.valueOf(256), new EdDSAGenParameterSpec(EdDSANamedCurveTable.ED_25519));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public void initialize(int keysize, SecureRandom random) {
|
|
47
|
+
AlgorithmParameterSpec edParams = edParameters.get(Integer.valueOf(keysize));
|
|
48
|
+
if (edParams == null)
|
|
49
|
+
throw new InvalidParameterException("unknown key type.");
|
|
50
|
+
try {
|
|
51
|
+
initialize(edParams, random);
|
|
52
|
+
} catch (InvalidAlgorithmParameterException e) {
|
|
53
|
+
throw new InvalidParameterException("key type not configurable.");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@Override
|
|
58
|
+
public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException {
|
|
59
|
+
if (params instanceof EdDSAParameterSpec) {
|
|
60
|
+
edParams = (EdDSAParameterSpec) params;
|
|
61
|
+
} else if (params instanceof EdDSAGenParameterSpec) {
|
|
62
|
+
edParams = createNamedCurveSpec(((EdDSAGenParameterSpec) params).getName());
|
|
63
|
+
} else
|
|
64
|
+
throw new InvalidAlgorithmParameterException("parameter object not a EdDSAParameterSpec");
|
|
65
|
+
|
|
66
|
+
this.random = random;
|
|
67
|
+
initialized = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public KeyPair generateKeyPair() {
|
|
71
|
+
if (!initialized)
|
|
72
|
+
initialize(DEFAULT_KEYSIZE, new SecureRandom());
|
|
73
|
+
|
|
74
|
+
byte[] seed = new byte[edParams.getCurve().getField().getb()/8];
|
|
75
|
+
random.nextBytes(seed);
|
|
76
|
+
|
|
77
|
+
EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(seed, edParams);
|
|
78
|
+
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(privKey.getA(), edParams);
|
|
79
|
+
|
|
80
|
+
return new KeyPair(new EdDSAPublicKey(pubKey), new EdDSAPrivateKey(privKey));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Create an EdDSANamedCurveSpec from the provided curve name. The current
|
|
85
|
+
* implementation fetches the pre-created curve spec from a table.
|
|
86
|
+
* @param curveName the EdDSA named curve.
|
|
87
|
+
* @return the specification for the named curve.
|
|
88
|
+
* @throws InvalidAlgorithmParameterException if the named curve is unknown.
|
|
89
|
+
*/
|
|
90
|
+
protected EdDSANamedCurveSpec createNamedCurveSpec(String curveName) throws InvalidAlgorithmParameterException {
|
|
91
|
+
EdDSANamedCurveSpec spec = EdDSANamedCurveTable.getByName(curveName);
|
|
92
|
+
if (spec == null) {
|
|
93
|
+
throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
|
|
94
|
+
}
|
|
95
|
+
return spec;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdDSA-Java by str4d
|
|
3
|
+
*
|
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
|
6
|
+
* to EdDSA-Java.
|
|
7
|
+
*
|
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
package net.i2p.crypto.eddsa;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Basic utilities for EdDSA.
|
|
16
|
+
* Not for external use, not maintained as a public API.
|
|
17
|
+
*
|
|
18
|
+
* @author str4d
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
public class Utils {
|
|
22
|
+
/**
|
|
23
|
+
* Constant-time byte comparison.
|
|
24
|
+
* @param b a byte
|
|
25
|
+
* @param c a byte
|
|
26
|
+
* @return 1 if b and c are equal, 0 otherwise.
|
|
27
|
+
*/
|
|
28
|
+
public static int equal(int b, int c) {
|
|
29
|
+
int result = 0;
|
|
30
|
+
int xor = b ^ c;
|
|
31
|
+
for (int i = 0; i < 8; i++) {
|
|
32
|
+
result |= xor >> i;
|
|
33
|
+
}
|
|
34
|
+
return (result ^ 0x01) & 0x01;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Constant-time byte[] comparison.
|
|
39
|
+
* @param b a byte[]
|
|
40
|
+
* @param c a byte[]
|
|
41
|
+
* @return 1 if b and c are equal, 0 otherwise.
|
|
42
|
+
*/
|
|
43
|
+
public static int equal(byte[] b, byte[] c) {
|
|
44
|
+
int result = 0;
|
|
45
|
+
for (int i = 0; i < 32; i++) {
|
|
46
|
+
result |= b[i] ^ c[i];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return equal(result, 0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Constant-time determine if byte is negative.
|
|
54
|
+
* @param b the byte to check.
|
|
55
|
+
* @return 1 if the byte is negative, 0 otherwise.
|
|
56
|
+
*/
|
|
57
|
+
public static int negative(int b) {
|
|
58
|
+
return (b >> 8) & 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Get the i'th bit of a byte array.
|
|
63
|
+
* @param h the byte array.
|
|
64
|
+
* @param i the bit index.
|
|
65
|
+
* @return 0 or 1, the value of the i'th bit in h
|
|
66
|
+
*/
|
|
67
|
+
public static int bit(byte[] h, int i) {
|
|
68
|
+
return (h[i >> 3] >> (i & 7)) & 1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Converts a hex string to bytes.
|
|
73
|
+
* @param s the hex string to be converted.
|
|
74
|
+
* @return the byte[]
|
|
75
|
+
*/
|
|
76
|
+
public static byte[] hexToBytes(String s) {
|
|
77
|
+
int len = s.length();
|
|
78
|
+
byte[] data = new byte[len / 2];
|
|
79
|
+
for (int i = 0; i < len; i += 2) {
|
|
80
|
+
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
|
81
|
+
+ Character.digit(s.charAt(i+1), 16));
|
|
82
|
+
}
|
|
83
|
+
return data;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Converts bytes to a hex string.
|
|
88
|
+
* @param raw the byte[] to be converted.
|
|
89
|
+
* @return the hex representation as a string.
|
|
90
|
+
*/
|
|
91
|
+
public static String bytesToHex(byte[] raw) {
|
|
92
|
+
if ( raw == null ) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
final StringBuilder hex = new StringBuilder(2 * raw.length);
|
|
96
|
+
for (final byte b : raw) {
|
|
97
|
+
hex.append(Character.forDigit((b & 0xF0) >> 4, 16))
|
|
98
|
+
.append(Character.forDigit((b & 0x0F), 16));
|
|
99
|
+
}
|
|
100
|
+
return hex.toString();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdDSA-Java by str4d
|
|
3
|
+
*
|
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
|
6
|
+
* to EdDSA-Java.
|
|
7
|
+
*
|
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
package net.i2p.crypto.eddsa.math;
|
|
13
|
+
|
|
14
|
+
import net.i2p.crypto.eddsa.Utils;
|
|
15
|
+
|
|
16
|
+
final class Constants {
|
|
17
|
+
public static final byte[] ZERO = Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000");
|
|
18
|
+
public static final byte[] ONE = Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000");
|
|
19
|
+
public static final byte[] TWO = Utils.hexToBytes("0200000000000000000000000000000000000000000000000000000000000000");
|
|
20
|
+
public static final byte[] FOUR = Utils.hexToBytes("0400000000000000000000000000000000000000000000000000000000000000");
|
|
21
|
+
public static final byte[] FIVE = Utils.hexToBytes("0500000000000000000000000000000000000000000000000000000000000000");
|
|
22
|
+
public static final byte[] EIGHT = Utils.hexToBytes("0800000000000000000000000000000000000000000000000000000000000000");
|
|
23
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdDSA-Java by str4d
|
|
3
|
+
*
|
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
|
6
|
+
* to EdDSA-Java.
|
|
7
|
+
*
|
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
package net.i2p.crypto.eddsa.math;
|
|
13
|
+
|
|
14
|
+
import java.io.Serializable;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A twisted Edwards curve.
|
|
18
|
+
* Points on the curve satisfy $-x^2 + y^2 = 1 + d x^2y^2$
|
|
19
|
+
* @author str4d
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
public class Curve implements Serializable {
|
|
23
|
+
private static final long serialVersionUID = 4578920872509827L;
|
|
24
|
+
private final Field f;
|
|
25
|
+
private final FieldElement d;
|
|
26
|
+
private final FieldElement d2;
|
|
27
|
+
private final FieldElement I;
|
|
28
|
+
|
|
29
|
+
private final GroupElement zeroP2;
|
|
30
|
+
private final GroupElement zeroP3;
|
|
31
|
+
private final GroupElement zeroPrecomp;
|
|
32
|
+
|
|
33
|
+
public Curve(Field f, byte[] d, FieldElement I) {
|
|
34
|
+
this.f = f;
|
|
35
|
+
this.d = f.fromByteArray(d);
|
|
36
|
+
this.d2 = this.d.add(this.d);
|
|
37
|
+
this.I = I;
|
|
38
|
+
|
|
39
|
+
FieldElement zero = f.ZERO;
|
|
40
|
+
FieldElement one = f.ONE;
|
|
41
|
+
zeroP2 = GroupElement.p2(this, zero, one, one);
|
|
42
|
+
zeroP3 = GroupElement.p3(this, zero, one, one, zero);
|
|
43
|
+
zeroPrecomp = GroupElement.precomp(this, one, one, zero);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public Field getField() {
|
|
47
|
+
return f;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public FieldElement getD() {
|
|
51
|
+
return d;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public FieldElement get2D() {
|
|
55
|
+
return d2;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public FieldElement getI() {
|
|
59
|
+
return I;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public GroupElement getZero(GroupElement.Representation repr) {
|
|
63
|
+
switch (repr) {
|
|
64
|
+
case P2:
|
|
65
|
+
return zeroP2;
|
|
66
|
+
case P3:
|
|
67
|
+
return zeroP3;
|
|
68
|
+
case PRECOMP:
|
|
69
|
+
return zeroPrecomp;
|
|
70
|
+
default:
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public GroupElement createPoint(byte[] P, boolean precompute) {
|
|
76
|
+
GroupElement ge = new GroupElement(this, P);
|
|
77
|
+
if (precompute)
|
|
78
|
+
ge.precompute(true);
|
|
79
|
+
return ge;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@Override
|
|
83
|
+
public int hashCode() {
|
|
84
|
+
return f.hashCode() ^
|
|
85
|
+
d.hashCode() ^
|
|
86
|
+
I.hashCode();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@Override
|
|
90
|
+
public boolean equals(Object o) {
|
|
91
|
+
if (o == this)
|
|
92
|
+
return true;
|
|
93
|
+
if (!(o instanceof Curve))
|
|
94
|
+
return false;
|
|
95
|
+
Curve c = (Curve) o;
|
|
96
|
+
return f.equals(c.getField()) &&
|
|
97
|
+
d.equals(c.getD()) &&
|
|
98
|
+
I.equals(c.getI());
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdDSA-Java by str4d
|
|
3
|
+
*
|
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
|
6
|
+
* to EdDSA-Java.
|
|
7
|
+
*
|
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
package net.i2p.crypto.eddsa.math;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Common interface for all $(b-1)$-bit encodings of elements
|
|
16
|
+
* of EdDSA finite fields.
|
|
17
|
+
* @author str4d
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
public abstract class Encoding {
|
|
21
|
+
protected Field f;
|
|
22
|
+
|
|
23
|
+
public synchronized void setField(Field f) {
|
|
24
|
+
if (this.f != null)
|
|
25
|
+
throw new IllegalStateException("already set");
|
|
26
|
+
this.f = f;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Encode a FieldElement in its $(b-1)$-bit encoding.
|
|
31
|
+
* @param x the FieldElement to encode
|
|
32
|
+
* @return the $(b-1)$-bit encoding of this FieldElement.
|
|
33
|
+
*/
|
|
34
|
+
public abstract byte[] encode(FieldElement x);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Decode a FieldElement from its $(b-1)$-bit encoding.
|
|
38
|
+
* The highest bit is masked out.
|
|
39
|
+
* @param in the $(b-1)$-bit encoding of a FieldElement.
|
|
40
|
+
* @return the FieldElement represented by 'val'.
|
|
41
|
+
*/
|
|
42
|
+
public abstract FieldElement decode(byte[] in);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* From the Ed25519 paper:<br>
|
|
46
|
+
* $x$ is negative if the $(b-1)$-bit encoding of $x$ is lexicographically larger
|
|
47
|
+
* than the $(b-1)$-bit encoding of -x. If $q$ is an odd prime and the encoding
|
|
48
|
+
* is the little-endian representation of $\{0, 1,\dots, q-1\}$ then the negative
|
|
49
|
+
* elements of $F_q$ are $\{1, 3, 5,\dots, q-2\}$.
|
|
50
|
+
* @param x the FieldElement to check
|
|
51
|
+
* @return true if negative
|
|
52
|
+
*/
|
|
53
|
+
public abstract boolean isNegative(FieldElement x);
|
|
54
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdDSA-Java by str4d
|
|
3
|
+
*
|
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
|
6
|
+
* to EdDSA-Java.
|
|
7
|
+
*
|
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
package net.i2p.crypto.eddsa.math;
|
|
13
|
+
|
|
14
|
+
import java.io.Serializable;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* An EdDSA finite field. Includes several pre-computed values.
|
|
18
|
+
* @author str4d
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
public class Field implements Serializable {
|
|
22
|
+
private static final long serialVersionUID = 8746587465875676L;
|
|
23
|
+
|
|
24
|
+
public final FieldElement ZERO;
|
|
25
|
+
public final FieldElement ONE;
|
|
26
|
+
public final FieldElement TWO;
|
|
27
|
+
public final FieldElement FOUR;
|
|
28
|
+
public final FieldElement FIVE;
|
|
29
|
+
public final FieldElement EIGHT;
|
|
30
|
+
|
|
31
|
+
private final int b;
|
|
32
|
+
private final FieldElement q;
|
|
33
|
+
/**
|
|
34
|
+
* q-2
|
|
35
|
+
*/
|
|
36
|
+
private final FieldElement qm2;
|
|
37
|
+
/**
|
|
38
|
+
* (q-5) / 8
|
|
39
|
+
*/
|
|
40
|
+
private final FieldElement qm5d8;
|
|
41
|
+
private final Encoding enc;
|
|
42
|
+
|
|
43
|
+
public Field(int b, byte[] q, Encoding enc) {
|
|
44
|
+
this.b = b;
|
|
45
|
+
this.enc = enc;
|
|
46
|
+
this.enc.setField(this);
|
|
47
|
+
|
|
48
|
+
this.q = fromByteArray(q);
|
|
49
|
+
|
|
50
|
+
// Set up constants
|
|
51
|
+
ZERO = fromByteArray(Constants.ZERO);
|
|
52
|
+
ONE = fromByteArray(Constants.ONE);
|
|
53
|
+
TWO = fromByteArray(Constants.TWO);
|
|
54
|
+
FOUR = fromByteArray(Constants.FOUR);
|
|
55
|
+
FIVE = fromByteArray(Constants.FIVE);
|
|
56
|
+
EIGHT = fromByteArray(Constants.EIGHT);
|
|
57
|
+
|
|
58
|
+
// Precompute values
|
|
59
|
+
qm2 = this.q.subtract(TWO);
|
|
60
|
+
qm5d8 = this.q.subtract(FIVE).divide(EIGHT);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public FieldElement fromByteArray(byte[] x) {
|
|
64
|
+
return enc.decode(x);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public int getb() {
|
|
68
|
+
return b;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public FieldElement getQ() {
|
|
72
|
+
return q;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public FieldElement getQm2() {
|
|
76
|
+
return qm2;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public FieldElement getQm5d8() {
|
|
80
|
+
return qm5d8;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public Encoding getEncoding(){
|
|
84
|
+
return enc;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Override
|
|
88
|
+
public int hashCode() {
|
|
89
|
+
return q.hashCode();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@Override
|
|
93
|
+
public boolean equals(Object obj) {
|
|
94
|
+
if (!(obj instanceof Field))
|
|
95
|
+
return false;
|
|
96
|
+
Field f = (Field) obj;
|
|
97
|
+
return b == f.b && q.equals(f.q);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EdDSA-Java by str4d
|
|
3
|
+
*
|
|
4
|
+
* To the extent possible under law, the person who associated CC0 with
|
|
5
|
+
* EdDSA-Java has waived all copyright and related or neighboring rights
|
|
6
|
+
* to EdDSA-Java.
|
|
7
|
+
*
|
|
8
|
+
* You should have received a copy of the CC0 legalcode along with this
|
|
9
|
+
* work. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
package net.i2p.crypto.eddsa.math;
|
|
13
|
+
|
|
14
|
+
import java.io.Serializable;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Note: concrete subclasses must implement hashCode() and equals()
|
|
18
|
+
*/
|
|
19
|
+
public abstract class FieldElement implements Serializable {
|
|
20
|
+
private static final long serialVersionUID = 1239527465875676L;
|
|
21
|
+
|
|
22
|
+
protected final Field f;
|
|
23
|
+
|
|
24
|
+
public FieldElement(Field f) {
|
|
25
|
+
if (null == f) {
|
|
26
|
+
throw new IllegalArgumentException("field cannot be null");
|
|
27
|
+
}
|
|
28
|
+
this.f = f;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Encode a FieldElement in its $(b-1)$-bit encoding.
|
|
33
|
+
* @return the $(b-1)$-bit encoding of this FieldElement.
|
|
34
|
+
*/
|
|
35
|
+
public byte[] toByteArray() {
|
|
36
|
+
return f.getEncoding().encode(this);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public abstract boolean isNonZero();
|
|
40
|
+
|
|
41
|
+
public boolean isNegative() {
|
|
42
|
+
return f.getEncoding().isNegative(this);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public abstract FieldElement add(FieldElement val);
|
|
46
|
+
|
|
47
|
+
public FieldElement addOne() {
|
|
48
|
+
return add(f.ONE);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public abstract FieldElement subtract(FieldElement val);
|
|
52
|
+
|
|
53
|
+
public FieldElement subtractOne() {
|
|
54
|
+
return subtract(f.ONE);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public abstract FieldElement negate();
|
|
58
|
+
|
|
59
|
+
public FieldElement divide(FieldElement val) {
|
|
60
|
+
return multiply(val.invert());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public abstract FieldElement multiply(FieldElement val);
|
|
64
|
+
|
|
65
|
+
public abstract FieldElement square();
|
|
66
|
+
|
|
67
|
+
public abstract FieldElement squareAndDouble();
|
|
68
|
+
|
|
69
|
+
public abstract FieldElement invert();
|
|
70
|
+
|
|
71
|
+
public abstract FieldElement pow22523();
|
|
72
|
+
|
|
73
|
+
public abstract FieldElement cmov(FieldElement val, final int b);
|
|
74
|
+
|
|
75
|
+
// Note: concrete subclasses must implement hashCode() and equals()
|
|
76
|
+
}
|