ed25519 1.0.0-jruby → 1.1.0-jruby
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGES.md +13 -0
- data/README.md +9 -9
- data/Rakefile +3 -3
- 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/cryptosphere/Ed25519Provider.java +95 -0
- data/lib/ed25519.rb +8 -8
- data/lib/ed25519/signing_key.rb +9 -0
- data/lib/ed25519/version.rb +1 -1
- data/lib/ed25519_java.jar +0 -0
- metadata +32 -3
- data/ext/ed25519_java/org/cryptosphere/ed25519.java +0 -228
- data/lib/ed25519/provider/jruby.rb +0 -39
@@ -0,0 +1,59 @@
|
|
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.AccessController;
|
15
|
+
import java.security.PrivilegedAction;
|
16
|
+
import java.security.Provider;
|
17
|
+
import java.security.Security;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* A security {@link Provider} that can be registered via {@link Security#addProvider(Provider)}
|
21
|
+
*
|
22
|
+
* @author str4d
|
23
|
+
*/
|
24
|
+
public class EdDSASecurityProvider extends Provider {
|
25
|
+
private static final long serialVersionUID = 1210027906682292307L;
|
26
|
+
public static final String PROVIDER_NAME = "EdDSA";
|
27
|
+
|
28
|
+
public EdDSASecurityProvider() {
|
29
|
+
super(PROVIDER_NAME, 0.2 /* should match POM major.minor version */, "str4d " + PROVIDER_NAME + " security provider wrapper");
|
30
|
+
|
31
|
+
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
32
|
+
@Override
|
33
|
+
public Object run() {
|
34
|
+
setup();
|
35
|
+
return null;
|
36
|
+
}
|
37
|
+
});
|
38
|
+
}
|
39
|
+
|
40
|
+
protected void setup() {
|
41
|
+
// See https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html
|
42
|
+
put("KeyFactory." + EdDSAKey.KEY_ALGORITHM, "net.i2p.crypto.eddsa.KeyFactory");
|
43
|
+
put("KeyPairGenerator." + EdDSAKey.KEY_ALGORITHM, "net.i2p.crypto.eddsa.KeyPairGenerator");
|
44
|
+
put("Signature." + EdDSAEngine.SIGNATURE_ALGORITHM, "net.i2p.crypto.eddsa.EdDSAEngine");
|
45
|
+
|
46
|
+
// OID Mappings
|
47
|
+
// See section "Mapping from OID to name".
|
48
|
+
// The Key* -> OID mappings correspond to the default algorithm in KeyPairGenerator.
|
49
|
+
//
|
50
|
+
// From draft-ieft-curdle-pkix-04:
|
51
|
+
// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
|
52
|
+
put("Alg.Alias.KeyFactory.1.3.101.112", EdDSAKey.KEY_ALGORITHM);
|
53
|
+
put("Alg.Alias.KeyFactory.OID.1.3.101.112", EdDSAKey.KEY_ALGORITHM);
|
54
|
+
put("Alg.Alias.KeyPairGenerator.1.3.101.112", EdDSAKey.KEY_ALGORITHM);
|
55
|
+
put("Alg.Alias.KeyPairGenerator.OID.1.3.101.112", EdDSAKey.KEY_ALGORITHM);
|
56
|
+
put("Alg.Alias.Signature.1.3.101.112", EdDSAEngine.SIGNATURE_ALGORITHM);
|
57
|
+
put("Alg.Alias.Signature.OID.1.3.101.112", EdDSAEngine.SIGNATURE_ALGORITHM);
|
58
|
+
}
|
59
|
+
}
|
@@ -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
|
+
}
|