Skip to content

Commit 27e2b0c

Browse files
authored
Merge pull request #19 from lgoldstein/master
Added EdDSASecurityProvider that can be registered in the JCE
2 parents 9c27708 + 23ff20d commit 27e2b0c

15 files changed

+165
-54
lines changed

pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
<packaging>bundle</packaging>
99
<description>Implementation of EdDSA in Java</description>
1010
<url>https://github.com/str4d/ed25519-java</url>
11+
<properties>
12+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13+
</properties>
1114
<licenses>
1215
<license>
1316
<name>CC0 1.0 Universal</name>
@@ -100,6 +103,9 @@
100103
<goals>
101104
<goal>jar</goal>
102105
</goals>
106+
<configuration> <!-- There are some malformed javadoc comments -->
107+
<failOnError>false</failOnError>
108+
</configuration>
103109
</execution>
104110
</executions>
105111
</plugin>

src/net/i2p/crypto/eddsa/EdDSAKey.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
/**
1717
* Common interface for all EdDSA keys.
1818
* @author str4d
19-
*
2019
*/
2120
public interface EdDSAKey {
21+
/**
22+
* The reported key algorithm for all EdDSA keys
23+
*/
24+
String KEY_ALGORITHM = "EdDSA";
25+
2226
/**
2327
* return a parameter specification representing the EdDSA domain
2428
* parameters for the key.
2529
*/
26-
public EdDSAParameterSpec getParams();
30+
EdDSAParameterSpec getParams();
2731
}

src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,12 @@ public EdDSAPrivateKey(PKCS8EncodedKeySpec spec) throws InvalidKeySpecException
5656
EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)));
5757
}
5858

59+
@Override
5960
public String getAlgorithm() {
60-
return "EdDSA";
61+
return KEY_ALGORITHM;
6162
}
6263

64+
@Override
6365
public String getFormat() {
6466
return "PKCS#8";
6567
}
@@ -101,6 +103,7 @@ public String getFormat() {
101103
*
102104
* @return 49 bytes for Ed25519, null for other curves
103105
*/
106+
@Override
104107
public byte[] getEncoded() {
105108
if (!edDsaSpec.equals(EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)))
106109
return null;
@@ -177,6 +180,7 @@ private static byte[] decode(byte[] d) throws InvalidKeySpecException {
177180
}
178181
}
179182

183+
@Override
180184
public EdDSAParameterSpec getParams() {
181185
return edDsaSpec;
182186
}

src/net/i2p/crypto/eddsa/EdDSAPublicKey.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ public EdDSAPublicKey(X509EncodedKeySpec spec) throws InvalidKeySpecException {
5151
EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)));
5252
}
5353

54+
@Override
5455
public String getAlgorithm() {
55-
return "EdDSA";
56+
return KEY_ALGORITHM;
5657
}
5758

59+
@Override
5860
public String getFormat() {
5961
return "X.509";
6062
}
@@ -82,6 +84,7 @@ public String getFormat() {
8284
*
8385
* @return 47 bytes for Ed25519, null for other curves
8486
*/
87+
@Override
8588
public byte[] getEncoded() {
8689
if (!edDsaSpec.equals(EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)))
8790
return null;
@@ -148,6 +151,7 @@ private static byte[] decode(byte[] d) throws InvalidKeySpecException {
148151
}
149152
}
150153

154+
@Override
151155
public EdDSAParameterSpec getParams() {
152156
return edDsaSpec;
153157
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
20+
21+
/**
22+
* A security {@link Provider} that can be registered via {@link Security#addProvider(Provider)}
23+
*
24+
* @author str4d
25+
*/
26+
public class EdDSASecurityProvider extends Provider {
27+
private static final long serialVersionUID = 1210027906682292307L;
28+
public static final String PROVIDER_NAME = "EdDSA";
29+
30+
public EdDSASecurityProvider() {
31+
super(PROVIDER_NAME, 0.1 /* should match POM major.minor version */, "str4d " + PROVIDER_NAME + " security provider wrapper");
32+
33+
AccessController.doPrivileged(new PrivilegedAction<Object>() {
34+
@Override
35+
public Object run() {
36+
setup();
37+
return null;
38+
}
39+
});
40+
}
41+
42+
protected void setup() {
43+
// see https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html
44+
put("KeyPairGenerator." + EdDSAKey.KEY_ALGORITHM, "net.i2p.crypto.eddsa.KeyPairGenerator");
45+
put("KeyFactory." + EdDSAKey.KEY_ALGORITHM, "net.i2p.crypto.eddsa.KeyFactory");
46+
put("Signature." + EdDSANamedCurveTable.CURVE_ED25519_SHA512, "net.i2p.crypto.eddsa.EdDSAEngine");
47+
}
48+
}

src/net/i2p/crypto/eddsa/spec/EdDSANamedCurveTable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*
2626
*/
2727
public class EdDSANamedCurveTable {
28-
public static final String CURVE_ED25519_SHA512 = "ed25519-sha-512";
28+
public static final String CURVE_ED25519_SHA512 = "SHA512withEd25519";
2929

3030
private static final Field ed25519field = new Field(
3131
256, // b
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<html><body>
22
<p>
33
Specifications for curves and keys, and a table for named curves,
4-
initially containing only the 25519 curve "ed25519-sha-512".
4+
initially containing only the EdDSA curve "SHA512withEd25519".
55
</p>
66
</body></html>

test/net/i2p/crypto/eddsa/EdDSAEngineTest.java

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
*/
1212
package net.i2p.crypto.eddsa;
1313

14-
import static org.hamcrest.Matchers.*;
15-
import static org.junit.Assert.*;
14+
import static org.hamcrest.Matchers.equalTo;
15+
import static org.hamcrest.Matchers.is;
16+
import static org.junit.Assert.assertThat;
1617

1718
import java.nio.charset.Charset;
1819
import java.security.MessageDigest;
@@ -45,9 +46,9 @@ public class EdDSAEngineTest {
4546

4647
@Test
4748
public void testSign() throws Exception {
49+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
4850
//Signature sgr = Signature.getInstance("EdDSA", "I2P");
49-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
50-
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("ed25519-sha-512");
51+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
5152

5253
for (Ed25519TestVectors.TestTuple testCase : Ed25519TestVectors.testCases) {
5354
EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(testCase.seed, spec);
@@ -63,10 +64,9 @@ public void testSign() throws Exception {
6364

6465
@Test
6566
public void testVerify() throws Exception {
67+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
6668
//Signature sgr = Signature.getInstance("EdDSA", "I2P");
67-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
68-
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("ed25519-sha-512");
69-
69+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
7070
for (Ed25519TestVectors.TestTuple testCase : Ed25519TestVectors.testCases) {
7171
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(testCase.pk, spec);
7272
PublicKey vKey = new EdDSAPublicKey(pubKey);
@@ -84,11 +84,10 @@ public void testVerify() throws Exception {
8484
*/
8585
@Test
8686
public void testVerifyWrongSigLength() throws Exception {
87+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
8788
//Signature sgr = Signature.getInstance("EdDSA", "I2P");
88-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
89-
90-
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK,
91-
EdDSANamedCurveTable.getByName("ed25519-sha-512"));
89+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
90+
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK, spec);
9291
PublicKey vKey = new EdDSAPublicKey(pubKey);
9392
sgr.initVerify(vKey);
9493

@@ -101,9 +100,8 @@ public void testVerifyWrongSigLength() throws Exception {
101100

102101
@Test
103102
public void testSignResetsForReuse() throws Exception {
104-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
105-
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("ed25519-sha-512");
106-
103+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
104+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
107105
EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(TEST_SEED, spec);
108106
PrivateKey sKey = new EdDSAPrivateKey(privKey);
109107
sgr.initSign(sKey);
@@ -119,10 +117,9 @@ public void testSignResetsForReuse() throws Exception {
119117

120118
@Test
121119
public void testVerifyResetsForReuse() throws Exception {
122-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
123-
124-
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK,
125-
EdDSANamedCurveTable.getByName("ed25519-sha-512"));
120+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
121+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
122+
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK, spec);
126123
PublicKey vKey = new EdDSAPublicKey(pubKey);
127124
sgr.initVerify(vKey);
128125

@@ -137,9 +134,8 @@ public void testVerifyResetsForReuse() throws Exception {
137134

138135
@Test
139136
public void testSignOneShotMode() throws Exception {
140-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
141-
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("ed25519-sha-512");
142-
137+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
138+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
143139
EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(TEST_SEED, spec);
144140
PrivateKey sKey = new EdDSAPrivateKey(privKey);
145141
sgr.initSign(sKey);
@@ -152,10 +148,9 @@ public void testSignOneShotMode() throws Exception {
152148

153149
@Test
154150
public void testVerifyOneShotMode() throws Exception {
155-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
156-
157-
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK,
158-
EdDSANamedCurveTable.getByName("ed25519-sha-512"));
151+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
152+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
153+
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK, spec);
159154
PublicKey vKey = new EdDSAPublicKey(pubKey);
160155
sgr.initVerify(vKey);
161156
sgr.setParameter(EdDSAEngine.ONE_SHOT_MODE);
@@ -167,9 +162,8 @@ public void testVerifyOneShotMode() throws Exception {
167162

168163
@Test
169164
public void testSignOneShotModeMultipleUpdates() throws Exception {
170-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
171-
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("ed25519-sha-512");
172-
165+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
166+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
173167
EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(TEST_SEED, spec);
174168
PrivateKey sKey = new EdDSAPrivateKey(privKey);
175169
sgr.initSign(sKey);
@@ -184,10 +178,9 @@ public void testSignOneShotModeMultipleUpdates() throws Exception {
184178

185179
@Test
186180
public void testVerifyOneShotModeMultipleUpdates() throws Exception {
187-
Signature sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
188-
189-
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK,
190-
EdDSANamedCurveTable.getByName("ed25519-sha-512"));
181+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
182+
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK, spec);
183+
Signature sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
191184
PublicKey vKey = new EdDSAPublicKey(pubKey);
192185
sgr.initVerify(vKey);
193186
sgr.setParameter(EdDSAEngine.ONE_SHOT_MODE);
@@ -201,10 +194,9 @@ public void testVerifyOneShotModeMultipleUpdates() throws Exception {
201194

202195
@Test
203196
public void testSignOneShot() throws Exception {
204-
EdDSAEngine sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
205-
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("ed25519-sha-512");
206-
197+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
207198
EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(TEST_SEED, spec);
199+
EdDSAEngine sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
208200
PrivateKey sKey = new EdDSAPrivateKey(privKey);
209201
sgr.initSign(sKey);
210202

@@ -213,10 +205,9 @@ public void testSignOneShot() throws Exception {
213205

214206
@Test
215207
public void testVerifyOneShot() throws Exception {
216-
EdDSAEngine sgr = new EdDSAEngine(MessageDigest.getInstance("SHA-512"));
217-
218-
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK,
219-
EdDSANamedCurveTable.getByName("ed25519-sha-512"));
208+
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
209+
EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(TEST_PK, spec);
210+
EdDSAEngine sgr = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
220211
PublicKey vKey = new EdDSAPublicKey(pubKey);
221212
sgr.initVerify(vKey);
222213

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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.KeyFactory;
15+
import java.security.KeyPairGenerator;
16+
import java.security.NoSuchProviderException;
17+
import java.security.Security;
18+
import java.security.Signature;
19+
20+
import net.i2p.crypto.eddsa.EdDSASecurityProvider;
21+
22+
import org.junit.Rule;
23+
import org.junit.Test;
24+
import org.junit.rules.ExpectedException;
25+
26+
/**
27+
* @author str4d
28+
*
29+
*/
30+
public class EdDSASecurityProviderTest {
31+
32+
@Rule
33+
public ExpectedException exception = ExpectedException.none();
34+
35+
@Test
36+
public void canGetInstancesWhenProviderIsPresent() throws Exception {
37+
Security.addProvider(new EdDSASecurityProvider());
38+
39+
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EdDSA", "EdDSA");
40+
KeyFactory keyFac = KeyFactory.getInstance("EdDSA", "EdDSA");
41+
Signature sgr = Signature.getInstance("SHA512withEd25519", "EdDSA");
42+
43+
Security.removeProvider("EdDSA");
44+
}
45+
46+
@Test
47+
public void cannotGetInstancesWhenProviderIsNotPresent() throws Exception {
48+
exception.expect(NoSuchProviderException.class);
49+
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EdDSA", "EdDSA");
50+
}
51+
}

test/net/i2p/crypto/eddsa/math/ConstantsTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
*/
1212
package net.i2p.crypto.eddsa.math;
1313

14-
import static org.hamcrest.Matchers.*;
15-
import static org.junit.Assert.*;
14+
import static org.hamcrest.Matchers.equalTo;
15+
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
16+
import static org.hamcrest.Matchers.is;
17+
import static org.junit.Assert.assertThat;
18+
import static org.junit.Assert.fail;
1619

1720
import java.security.MessageDigest;
1821
import java.security.NoSuchAlgorithmException;
@@ -28,7 +31,7 @@
2831
*
2932
*/
3033
public class ConstantsTest {
31-
static final EdDSANamedCurveSpec ed25519 = EdDSANamedCurveTable.getByName("ed25519-sha-512");
34+
static final EdDSANamedCurveSpec ed25519 = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
3235
static final Curve curve = ed25519.getCurve();
3336

3437
static final FieldElement ZERO = curve.getField().ZERO;

0 commit comments

Comments
 (0)