Skip to content

Commit 8cd3e98

Browse files
authored
Merge pull request #23 from str4d/downstream-tweaks
Pull in changes from I2P
2 parents 65d144f + eb22393 commit 8cd3e98

File tree

7 files changed

+85
-3
lines changed

7 files changed

+85
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
*Option 1:
4545
*</p><ol>
4646
*<li>Call initSign() or initVerify() as usual.
47-
*</li><li>Call setParameter(ONE_SHOT_MOE)
47+
*</li><li>Call setParameter(ONE_SHOT_MODE)
4848
*</li><li>Call update(byte[]) or update(byte[], int, int) exactly once
4949
*</li><li>Call sign() or verify() as usual.
5050
*</li><li>If doing additional one-shot signs or verifies with this object, you must

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ public String getFormat() {
9696
* This will hopefully be clarified in the next draft.
9797
* But sun.security.pkcs.PKCS8Key expects them so we must include them for keytool to work.
9898
*
99+
* This encodes the seed. It will return null if constructed from
100+
* a spec which was directly constructed from H, in which case seed is null.
101+
*
99102
* @return 49 bytes for Ed25519, null for other curves
100103
*/
101104
public byte[] getEncoded() {
@@ -178,22 +181,38 @@ public EdDSAParameterSpec getParams() {
178181
return edDsaSpec;
179182
}
180183

184+
/**
185+
* @return will be null if constructed from a spec which was
186+
* directly constructed from H
187+
*/
181188
public byte[] getSeed() {
182189
return seed;
183190
}
184191

192+
/**
193+
* @return the hash of the seed
194+
*/
185195
public byte[] getH() {
186196
return h;
187197
}
188198

199+
/**
200+
* @return the private key
201+
*/
189202
public byte[] geta() {
190203
return a;
191204
}
192205

206+
/**
207+
* @return the public key
208+
*/
193209
public GroupElement getA() {
194210
return A;
195211
}
196212

213+
/**
214+
* @return the public key
215+
*/
197216
public byte[] getAbyte() {
198217
return Abyte;
199218
}

src/net/i2p/crypto/eddsa/math/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
import net.i2p.crypto.eddsa.Utils;
1515

16-
public class Constants {
16+
final class Constants {
1717
public static final byte[] ZERO = Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000");
1818
public static final byte[] ONE = Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000");
1919
public static final byte[] TWO = Utils.hexToBytes("0200000000000000000000000000000000000000000000000000000000000000");

src/net/i2p/crypto/eddsa/math/bigint/BigIntegerLittleEndianEncoding.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ public byte[] encode(FieldElement x) {
4040
* Constant time.
4141
*
4242
* @return array of length b/8
43+
* @throws IllegalStateException if field not set
4344
*/
4445
public byte[] encode(BigInteger x) {
46+
if (f == null)
47+
throw new IllegalStateException("field not set");
4548
byte[] in = x.toByteArray();
4649
byte[] out = new byte[f.getb()/8];
4750
for (int i = 0; i < in.length; i++) {
@@ -53,7 +56,18 @@ public byte[] encode(BigInteger x) {
5356
return out;
5457
}
5558

59+
/**
60+
* Decode a FieldElement from its (b-1)-bit encoding.
61+
* The highest bit is masked out.
62+
*
63+
* @param in the (b-1)-bit encoding of a FieldElement.
64+
* @return the FieldElement represented by 'val'.
65+
* @throws IllegalStateException if field not set
66+
* @throws IllegalArgumentException if encoding is invalid
67+
*/
5668
public FieldElement decode(byte[] in) {
69+
if (f == null)
70+
throw new IllegalStateException("field not set");
5771
if (in.length != f.getb()/8)
5872
throw new IllegalArgumentException("Not a valid encoding");
5973
return new BigIntegerFieldElement(f, toBigInteger(in).and(mask));

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ public ScalarOps getScalarOps() {
6565
return sc;
6666
}
6767

68+
/**
69+
* @return the base (generator)
70+
*/
6871
public GroupElement getB() {
6972
return B;
7073
}

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,59 @@ public EdDSAPrivateKeySpec(byte[] seed, EdDSAParameterSpec spec) {
6060
}
6161
}
6262

63+
/**
64+
* Initialize directly from the hash.
65+
* getSeed() will return null if this constructor is used.
66+
*
67+
* @param h the private key
68+
* @since 0.1.1
69+
*/
70+
public EdDSAPrivateKeySpec(EdDSAParameterSpec spec, byte[] h) {
71+
this.seed = null;
72+
this.h = h;
73+
this.spec = spec;
74+
int b = spec.getCurve().getField().getb();
75+
76+
h[0] &= 248;
77+
h[(b/8)-1] &= 63;
78+
h[(b/8)-1] |= 64;
79+
a = Arrays.copyOfRange(h, 0, b/8);
80+
81+
A = spec.getB().scalarMultiply(a);
82+
}
83+
6384
public EdDSAPrivateKeySpec(byte[] seed, byte[] h, byte[] a, GroupElement A, EdDSAParameterSpec spec) {
6485
this.seed = seed;
6586
this.h = h;
6687
this.a = a;
6788
this.A = A;
68-
this.spec = spec;
89+
this.spec = spec;
6990
}
7091

92+
/**
93+
* @return will be null if constructed directly from the private key
94+
*/
7195
public byte[] getSeed() {
7296
return seed;
7397
}
7498

99+
/**
100+
* @return the hash
101+
*/
75102
public byte[] getH() {
76103
return h;
77104
}
78105

106+
/**
107+
* @return the private key
108+
*/
79109
public byte[] geta() {
80110
return a;
81111
}
82112

113+
/**
114+
* @return the public key
115+
*/
83116
public GroupElement getA() {
84117
return A;
85118
}

test/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpecTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424
public class EdDSAPrivateKeySpecTest {
2525
static final byte[] ZERO_SEED = Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000");
26+
static final byte[] ZERO_H = Utils.hexToBytes("5046adc1dba838867b2bbbfdd0c3423e58b57970b5267a90f57960924a87f1960a6a85eaa642dac835424b5d7c8d637c00408c7a73da672b7f498521420b6dd3");
2627
static final byte[] ZERO_PK = Utils.hexToBytes("3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29");
2728

2829
static final EdDSANamedCurveSpec ed25519 = EdDSANamedCurveTable.getByName("ed25519-sha-512");
@@ -34,6 +35,18 @@ public class EdDSAPrivateKeySpecTest {
3435
public void testEdDSAPrivateKeySpecFromSeed() {
3536
EdDSAPrivateKeySpec key = new EdDSAPrivateKeySpec(ZERO_SEED, ed25519);
3637
assertThat(key.getSeed(), is(equalTo(ZERO_SEED)));
38+
assertThat(key.getH(), is(equalTo(ZERO_H)));
39+
assertThat(key.getA().toByteArray(), is(equalTo(ZERO_PK)));
40+
}
41+
42+
/**
43+
* Test method for {@link net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec#EdDSAPrivateKeySpec(net.i2p.crypto.eddsa.spec.EdDSAParameterSpec, byte[])}.
44+
*/
45+
@Test
46+
public void testEdDSAPrivateKeySpecFromH() {
47+
EdDSAPrivateKeySpec key = new EdDSAPrivateKeySpec(ed25519, ZERO_H);
48+
assertThat(key.getSeed(), is(nullValue()));
49+
assertThat(key.getH(), is(equalTo(ZERO_H)));
3750
assertThat(key.getA().toByteArray(), is(equalTo(ZERO_PK)));
3851
}
3952

0 commit comments

Comments
 (0)