diff options
author | Florian Dold <florian.dold@gmail.com> | 2013-11-19 11:15:52 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2013-11-19 11:15:52 +0000 |
commit | e1dbf0dae09d3ecddc992a5a7b04a82ca03dcd2a (patch) | |
tree | 2447f7f92541c738d13a7659c7ba791146defa27 /src/main/java | |
parent | 3d17385928f938d170230be1b334ff159355775d (diff) | |
download | gnunet-java-e1dbf0dae09d3ecddc992a5a7b04a82ca03dcd2a.tar.gz gnunet-java-e1dbf0dae09d3ecddc992a5a7b04a82ca03dcd2a.zip |
- crypto + crypto tests
Diffstat (limited to 'src/main/java')
17 files changed, 779 insertions, 220 deletions
diff --git a/src/main/java/org/gnunet/util/HashCode.java b/src/main/java/org/gnunet/util/HashCode.java index 389217f..a93a867 100644 --- a/src/main/java/org/gnunet/util/HashCode.java +++ b/src/main/java/org/gnunet/util/HashCode.java | |||
@@ -39,12 +39,48 @@ public class HashCode implements Message { | |||
39 | @FixedSizeIntegerArray(length = 64, signed = false, bitSize = 8) | 39 | @FixedSizeIntegerArray(length = 64, signed = false, bitSize = 8) |
40 | public byte[] data; // should be immutable, final, can't be due to construct | 40 | public byte[] data; // should be immutable, final, can't be due to construct |
41 | 41 | ||
42 | 42 | /** | |
43 | * Create a hash code initialized to zero. | ||
44 | */ | ||
43 | public HashCode() { | 45 | public HashCode() { |
44 | data = new byte[64]; | 46 | data = new byte[64]; |
45 | } | 47 | } |
46 | 48 | ||
47 | public HashCode(byte[] hash) { | 49 | /** |
50 | * Create a HashCode from an existing SHA-512 hash code value. | ||
51 | * | ||
52 | * @param hash SHA-512 hash code value | ||
53 | * @return a HashCode | ||
54 | */ | ||
55 | public static HashCode fromHashCode(byte[] hash) { | ||
56 | return new HashCode(hash); | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Create a HashCode from data to be hashed. | ||
61 | * | ||
62 | * @param data data to hash | ||
63 | * @return a HashCode | ||
64 | */ | ||
65 | public static HashCode hash(byte[] data) { | ||
66 | MessageDigest digest; | ||
67 | try { | ||
68 | digest = MessageDigest.getInstance("SHA-512"); | ||
69 | } catch (NoSuchAlgorithmException e) { | ||
70 | throw new RuntimeException("crypto algorithm 'SHA-512' required but not provided"); | ||
71 | } | ||
72 | byte[] hb = digest.digest(data); | ||
73 | HashCode h = new HashCode(hb); | ||
74 | return h; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * Private constructor for HashCode from the hash code value. Made | ||
79 | * private because there are two ways to create hash codes from byte arrays. | ||
80 | * | ||
81 | * @param hash hash code value to store in the HashCode | ||
82 | */ | ||
83 | private HashCode(byte[] hash) { | ||
48 | if (hash.length != 64) { | 84 | if (hash.length != 64) { |
49 | throw new AssertionError("HashCode has to have length 64"); | 85 | throw new AssertionError("HashCode has to have length 64"); |
50 | } | 86 | } |
diff --git a/src/main/java/org/gnunet/util/crypto/Curve25519.java b/src/main/java/org/gnunet/util/crypto/Curve25519.java deleted file mode 100644 index 86e6949..0000000 --- a/src/main/java/org/gnunet/util/crypto/Curve25519.java +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | package org.gnunet.util.crypto; | ||
22 | |||
23 | |||
24 | import java.math.BigInteger; | ||
25 | |||
26 | /** | ||
27 | * Java-only implementation of arithmetic on DJBs Curve25519. | ||
28 | * The curve is a Montgomery curve, and we use coordinates in | ||
29 | * Montgomery form. | ||
30 | * Very, very slow. | ||
31 | */ | ||
32 | public class Curve25519 { | ||
33 | private BigInteger X; | ||
34 | private BigInteger Z; | ||
35 | |||
36 | private BigInteger B = new BigInteger("486662"); | ||
37 | |||
38 | // curve parameter q = 255^(-19) | ||
39 | private static final BigInteger q = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819949"); | ||
40 | |||
41 | |||
42 | public Curve25519(BigInteger X, BigInteger Z) { | ||
43 | this.X = X; | ||
44 | this.Z = Z; | ||
45 | } | ||
46 | |||
47 | public Curve25519 scalarmult(BigInteger e) { | ||
48 | if (e.equals(BigInteger.ZERO)) { | ||
49 | return new Curve25519(BigInteger.ZERO, BigInteger.ONE); | ||
50 | } | ||
51 | Curve25519 Q = scalarmult(e.shiftRight(1)); | ||
52 | Q = Q.add(Q); | ||
53 | if (e.testBit(0)) Q = Q.add(this); | ||
54 | return Q; | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Addition law for montgomery curve in montgomery coordinates. | ||
59 | * | ||
60 | * @param other | ||
61 | * @return | ||
62 | */ | ||
63 | public Curve25519 add(Curve25519 other) { | ||
64 | return null; | ||
65 | } | ||
66 | |||
67 | |||
68 | |||
69 | } | ||
diff --git a/src/main/java/org/gnunet/util/crypto/DsaPrng.java b/src/main/java/org/gnunet/util/crypto/DsaPrng.java index c26848e..259aaa6 100644 --- a/src/main/java/org/gnunet/util/crypto/DsaPrng.java +++ b/src/main/java/org/gnunet/util/crypto/DsaPrng.java | |||
@@ -32,15 +32,21 @@ import java.util.Arrays; | |||
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Deterministic generator for the 'k'-value of DSA, conforming to RFC 6979. | 34 | * Deterministic generator for the 'k'-value of DSA, conforming to RFC 6979. |
35 | * SHA-1 is used as H. | 35 | * SHA-512 is used as H. |
36 | */ | 36 | */ |
37 | public class DsaPrng { | 37 | public class DsaPrng { |
38 | private static final int qlen = 32; | ||
39 | private Mac mac; | 38 | private Mac mac; |
40 | private byte[] V = new byte[64]; | 39 | private byte[] V = new byte[64]; |
41 | private byte[] K = new byte[64]; | 40 | private byte[] K = new byte[64]; |
41 | private static final int qlen = 32; | ||
42 | 42 | ||
43 | public byte[] hmacK(byte[]... args) { | 43 | /** |
44 | * Compute the HMAC of the fiven data with our current K-value. | ||
45 | * | ||
46 | * @param args data | ||
47 | * @return result of the hmac | ||
48 | */ | ||
49 | private byte[] hmacK(byte[]... args) { | ||
44 | try { | 50 | try { |
45 | mac.init(new SecretKeySpec(K, "HmacSHA1")); | 51 | mac.init(new SecretKeySpec(K, "HmacSHA1")); |
46 | } catch (InvalidKeyException e) { | 52 | } catch (InvalidKeyException e) { |
@@ -52,6 +58,12 @@ public class DsaPrng { | |||
52 | return mac.doFinal(); | 58 | return mac.doFinal(); |
53 | } | 59 | } |
54 | 60 | ||
61 | /** | ||
62 | * Create an instance of the deterministic random number generator for the DSA 'k' vale. | ||
63 | * | ||
64 | * @param key private key | ||
65 | * @param message message | ||
66 | */ | ||
55 | public DsaPrng(byte[] key, byte[] message) { | 67 | public DsaPrng(byte[] key, byte[] message) { |
56 | try { | 68 | try { |
57 | mac = Mac.getInstance("HmacSHA1"); | 69 | mac = Mac.getInstance("HmacSHA1"); |
@@ -73,6 +85,12 @@ public class DsaPrng { | |||
73 | V = hmacK(V); | 85 | V = hmacK(V); |
74 | } | 86 | } |
75 | 87 | ||
88 | /** | ||
89 | * Get the next deterministically generated candidate for | ||
90 | * the k value used in DSA. | ||
91 | * | ||
92 | * @return the next candidate value for 'k' | ||
93 | */ | ||
76 | public BigInteger nextK() { | 94 | public BigInteger nextK() { |
77 | byte[] T = new byte[0]; | 95 | byte[] T = new byte[0]; |
78 | while (T.length < qlen) { | 96 | while (T.length < qlen) { |
diff --git a/src/main/java/org/gnunet/util/crypto/EcdhePrivateKey.java b/src/main/java/org/gnunet/util/crypto/EcdhePrivateKey.java index e3cd861..9f4672e 100644 --- a/src/main/java/org/gnunet/util/crypto/EcdhePrivateKey.java +++ b/src/main/java/org/gnunet/util/crypto/EcdhePrivateKey.java | |||
@@ -1,4 +1,89 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
1 | package org.gnunet.util.crypto; | 21 | package org.gnunet.util.crypto; |
2 | 22 | ||
3 | public class EcdhePrivateKey { | 23 | import org.gnunet.construct.FixedSizeIntegerArray; |
24 | import org.gnunet.construct.Message; | ||
25 | import org.gnunet.util.HashCode; | ||
26 | |||
27 | import java.math.BigInteger; | ||
28 | import java.security.SecureRandom; | ||
29 | |||
30 | /** | ||
31 | * Private key for elliptic curve Diffie Hellman exchange. | ||
32 | */ | ||
33 | public class EcdhePrivateKey implements Message { | ||
34 | /** | ||
35 | * Private key byte string, in little endian form. | ||
36 | */ | ||
37 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) | ||
38 | public byte[] d; | ||
39 | |||
40 | /** | ||
41 | * Create an ecdh private key without allocating the key data. | ||
42 | */ | ||
43 | public EcdhePrivateKey() { | ||
44 | // empty constructor for org.gnunet.construct.* | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * Get the public key for this private key. | ||
49 | * | ||
50 | * @return the public key for this private key | ||
51 | */ | ||
52 | public EcdhePublicKey getPublicKey() { | ||
53 | BigInteger dCoeff = Ed25519.decodeScalar(d); | ||
54 | Ed25519 A = Ed25519.B.scalarmult(dCoeff); | ||
55 | return new EcdhePublicKey(A); | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | * Derive key material from the give public key and a this private ECDHE key. | ||
60 | * | ||
61 | * @param publicKey public key to use for the ECDH | ||
62 | * @return key material | ||
63 | */ | ||
64 | public HashCode ecdh(EcdhePublicKey publicKey) { | ||
65 | BigInteger dCoeff = Ed25519.decodeScalar(d); | ||
66 | Ed25519 Q = publicKey.asPoint().scalarmult(dCoeff); | ||
67 | // hash big endian representation of the x-coordinate. | ||
68 | return HashCode.hash(Q.P0.toByteArray()); | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * Create a random private key. | ||
73 | * | ||
74 | * @return a random private key | ||
75 | */ | ||
76 | public static EcdhePrivateKey createRandom() { | ||
77 | SecureRandom sr = new SecureRandom(); | ||
78 | EcdhePrivateKey privateKey = new EcdhePrivateKey(); | ||
79 | privateKey.d = new byte[32]; | ||
80 | sr.nextBytes(privateKey.d); | ||
81 | // clear bits so that d mod 8 = 0 | ||
82 | privateKey.d[0] &= (byte) 248; | ||
83 | // make sure the key fits in 255 bits | ||
84 | privateKey.d[31] &= (byte) 127; | ||
85 | // make sure key does not have lots of leading zeros | ||
86 | privateKey.d[31] |= (byte) 64; | ||
87 | return privateKey; | ||
88 | } | ||
4 | } | 89 | } |
diff --git a/src/main/java/org/gnunet/util/crypto/EcdhePublicKey.java b/src/main/java/org/gnunet/util/crypto/EcdhePublicKey.java index 3943137..844bddf 100644 --- a/src/main/java/org/gnunet/util/crypto/EcdhePublicKey.java +++ b/src/main/java/org/gnunet/util/crypto/EcdhePublicKey.java | |||
@@ -1,20 +1,83 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
1 | package org.gnunet.util.crypto; | 21 | package org.gnunet.util.crypto; |
2 | 22 | ||
3 | import org.gnunet.construct.FixedSizeIntegerArray; | 23 | import org.gnunet.construct.FixedSizeIntegerArray; |
24 | import org.gnunet.util.Strings; | ||
4 | 25 | ||
26 | /** | ||
27 | * Public key for elliptic curve diffie hellman exchange. | ||
28 | */ | ||
5 | public class EcdhePublicKey { | 29 | public class EcdhePublicKey { |
6 | /** | 30 | /** |
7 | * x-coordinate of the point on the curve. | 31 | * Point on the curve, in Ed25519-compressed form. |
8 | * The number is stored as little endian. | ||
9 | */ | 32 | */ |
10 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) | 33 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) |
11 | public byte[] x; | 34 | public byte[] y; |
12 | 35 | ||
13 | /** | 36 | /** |
14 | * y-coordinate of the point on the curve. | 37 | * Create a public key without allocating the key's data. |
15 | * The number is stored as little endian. | 38 | * Necessary for constructing the key with 'org.gnunet.construct.*'. |
16 | */ | 39 | */ |
17 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) | 40 | public EcdhePublicKey() { |
18 | public byte[] y; | 41 | // empty |
42 | } | ||
43 | |||
44 | /** | ||
45 | * Create a public key from the given point on the Ed25519 curve. | ||
46 | * | ||
47 | * @param a point to create the public key from | ||
48 | */ | ||
49 | public EcdhePublicKey(Ed25519 a) { | ||
50 | y = a.encode(); | ||
51 | } | ||
19 | 52 | ||
53 | /** | ||
54 | * Convert the public key to a point on the Ed25519 curve. | ||
55 | * | ||
56 | * @return point corresponding to this public key | ||
57 | */ | ||
58 | public Ed25519 asPoint() { | ||
59 | return Ed25519.decode(y); | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * Get a GNUnet-style string representation of this key. | ||
64 | * | ||
65 | * @return the GNUnet-style string representation of this key. | ||
66 | */ | ||
67 | @Override | ||
68 | public String toString() { | ||
69 | return Strings.dataToString(y); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * Load an ECDHE key from a string. | ||
74 | * | ||
75 | * @param s string with the key data | ||
76 | * @return a public key | ||
77 | */ | ||
78 | public EcdhePublicKey fromString(String s) { | ||
79 | EcdhePublicKey publicKey = new EcdhePublicKey(); | ||
80 | Strings.stringToData(s, publicKey.y); | ||
81 | return publicKey; | ||
82 | } | ||
20 | } | 83 | } |
diff --git a/src/main/java/org/gnunet/util/crypto/EcdsaPrivateKey.java b/src/main/java/org/gnunet/util/crypto/EcdsaPrivateKey.java index 43bd55a..2ac3fa8 100644 --- a/src/main/java/org/gnunet/util/crypto/EcdsaPrivateKey.java +++ b/src/main/java/org/gnunet/util/crypto/EcdsaPrivateKey.java | |||
@@ -1,41 +1,121 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
1 | package org.gnunet.util.crypto; | 21 | package org.gnunet.util.crypto; |
2 | 22 | ||
3 | import org.gnunet.construct.FixedSizeIntegerArray; | 23 | import org.gnunet.construct.FixedSizeIntegerArray; |
4 | import org.gnunet.construct.Message; | 24 | import org.gnunet.construct.Message; |
25 | import org.gnunet.util.HashCode; | ||
5 | 26 | ||
27 | import java.math.BigInteger; | ||
6 | import java.security.SecureRandom; | 28 | import java.security.SecureRandom; |
7 | 29 | ||
30 | /** | ||
31 | * Private key for elliptic curve DSA. | ||
32 | */ | ||
8 | public class EcdsaPrivateKey implements Message { | 33 | public class EcdsaPrivateKey implements Message { |
34 | /** | ||
35 | * Private key byte string, in little endian form. | ||
36 | */ | ||
9 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) | 37 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) |
10 | public byte[] d; | 38 | public byte[] d; |
11 | 39 | ||
40 | /** | ||
41 | * Create a private key without allocating the key data. | ||
42 | */ | ||
43 | public EcdsaPrivateKey() { | ||
44 | // empty, needed by org.gnunet.construct.* | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * Get the anonymous private key. Corresponds to '1'. | ||
49 | * | ||
50 | * @return the anonymous private ECDSA key | ||
51 | */ | ||
12 | public static EcdsaPrivateKey getAnonymous() { | 52 | public static EcdsaPrivateKey getAnonymous() { |
13 | return null; | 53 | EcdsaPrivateKey privateKey = new EcdsaPrivateKey(); |
54 | privateKey.d = new byte[32]; | ||
55 | privateKey.d[31] = 1; | ||
56 | return privateKey; | ||
14 | } | 57 | } |
15 | 58 | ||
59 | /** | ||
60 | * Sign the given data with this private key. Must include a purpose to mitigate | ||
61 | * replay / copy and paste attacks. | ||
62 | * | ||
63 | * @param purpose purpose for the signature | ||
64 | * @param data data to sign | ||
65 | * @return the signature over both the data and the purpose | ||
66 | */ | ||
16 | public EcdsaSignature sign(int purpose, byte[] data) { | 67 | public EcdsaSignature sign(int purpose, byte[] data) { |
17 | EcdsaSignature signature = new EcdsaSignature(); | 68 | return sign(getPublicKey(), purpose, data); |
18 | return signature; | ||
19 | } | 69 | } |
20 | 70 | ||
21 | public static EcdsaPrivateKey fromFile(String privKeyFilename) { | 71 | /** |
22 | return null; | 72 | * Sign the given data with this private key. Must include a purpose to mitigate |
73 | * replay / copy and paste attacks. | ||
74 | * | ||
75 | * @param publicKey public key corresponding to this private key, supplying this parameter | ||
76 | * leads to better performance as the public key does not have to be derived | ||
77 | * @param purpose purpose for the signature | ||
78 | * @param data data to sign | ||
79 | * @return the signature over both the data and the purpose | ||
80 | */ | ||
81 | public EcdsaSignature sign(EcdsaPublicKey publicKey, int purpose, byte[] data) { | ||
82 | EcdsaSignature signature = new EcdsaSignature(); | ||
83 | DsaPrng prng = new DsaPrng(d, data); | ||
84 | HashCode h = HashCode.hash(data); | ||
85 | byte[] zData = new byte[32]; | ||
86 | System.arraycopy(h.data, 0, zData, 0, 32); | ||
87 | BigInteger z = new BigInteger(1, zData); | ||
88 | BigInteger dCoeff = Ed25519.decodeScalar(d); | ||
89 | while (true) { | ||
90 | BigInteger k = prng.nextK(); | ||
91 | Ed25519 P = Ed25519.B.scalarmult(k); | ||
92 | BigInteger r = P.P0.mod(Ed25519.q); | ||
93 | if (r.equals(BigInteger.ZERO)) | ||
94 | continue; | ||
95 | BigInteger s = k.modInverse(Ed25519.q).multiply(z.add(r.multiply(dCoeff))); | ||
96 | if (!r.equals(BigInteger.ZERO)) { | ||
97 | signature.r = Ed25519.encodeScalar(r); | ||
98 | signature.s = Ed25519.encodeScalar(s); | ||
99 | return signature; | ||
100 | } | ||
101 | } | ||
23 | } | 102 | } |
24 | 103 | ||
104 | /** | ||
105 | * Get the public key for this private key. | ||
106 | * | ||
107 | * @return the public key for this private key | ||
108 | */ | ||
25 | public EcdsaPublicKey getPublicKey() { | 109 | public EcdsaPublicKey getPublicKey() { |
26 | // FIXME: this is not the real implementation, | 110 | Ed25519 A = Ed25519.B.scalarmult(Ed25519.decodeScalar(d)); |
27 | // beware that this dummy implementation leaks the key! | 111 | return new EcdsaPublicKey(A); |
28 | EcdsaPublicKey publicKey = new EcdsaPublicKey(); | ||
29 | byte[] v = new byte[32]; | ||
30 | System.arraycopy(d, 0, v, 0, 8); | ||
31 | System.arraycopy(d, 0, v, 8, 8); | ||
32 | System.arraycopy(d, 0, v, 16, 8); | ||
33 | System.arraycopy(d, 0, v, 24, 8); | ||
34 | System.arraycopy(v, 0, publicKey.x, 0, 32); | ||
35 | System.arraycopy(v, 0, publicKey.y, 0, 32); | ||
36 | return publicKey; | ||
37 | } | 112 | } |
38 | 113 | ||
114 | /** | ||
115 | * Create a randomly generated private ecdsa key. | ||
116 | * | ||
117 | * @return a freshly generated key | ||
118 | */ | ||
39 | public static EcdsaPrivateKey createRandom() { | 119 | public static EcdsaPrivateKey createRandom() { |
40 | SecureRandom sr = new SecureRandom(); | 120 | SecureRandom sr = new SecureRandom(); |
41 | EcdsaPrivateKey privateKey = new EcdsaPrivateKey(); | 121 | EcdsaPrivateKey privateKey = new EcdsaPrivateKey(); |
diff --git a/src/main/java/org/gnunet/util/crypto/EcdsaPublicKey.java b/src/main/java/org/gnunet/util/crypto/EcdsaPublicKey.java index 7468109..ce0c981 100644 --- a/src/main/java/org/gnunet/util/crypto/EcdsaPublicKey.java +++ b/src/main/java/org/gnunet/util/crypto/EcdsaPublicKey.java | |||
@@ -1,3 +1,23 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
1 | package org.gnunet.util.crypto; | 21 | package org.gnunet.util.crypto; |
2 | 22 | ||
3 | import org.gnunet.construct.FixedSizeIntegerArray; | 23 | import org.gnunet.construct.FixedSizeIntegerArray; |
@@ -12,12 +32,6 @@ import java.util.Arrays; | |||
12 | public class EcdsaPublicKey implements Message { | 32 | public class EcdsaPublicKey implements Message { |
13 | private static final Logger logger = LoggerFactory | 33 | private static final Logger logger = LoggerFactory |
14 | .getLogger(EcdsaPublicKey.class); | 34 | .getLogger(EcdsaPublicKey.class); |
15 | /** | ||
16 | * x-coordinate of the point on the curve. | ||
17 | * The number is stored as little endian. | ||
18 | */ | ||
19 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) | ||
20 | public byte[] x; | ||
21 | 35 | ||
22 | /** | 36 | /** |
23 | * y-coordinate of the point on the curve. | 37 | * y-coordinate of the point on the curve. |
@@ -26,28 +40,32 @@ public class EcdsaPublicKey implements Message { | |||
26 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) | 40 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) |
27 | public byte[] y; | 41 | public byte[] y; |
28 | 42 | ||
43 | /** | ||
44 | * Create an ECDSA public key from a curve point. | ||
45 | * | ||
46 | * @param a curve point. | ||
47 | */ | ||
29 | public EcdsaPublicKey(Ed25519 a) { | 48 | public EcdsaPublicKey(Ed25519 a) { |
30 | 49 | y = a.encode(); | |
31 | } | 50 | } |
32 | 51 | ||
52 | /** | ||
53 | * Create a public key without allocating space for the key data. | ||
54 | * Necessary for constructing this class with org.gnunet.construct.* | ||
55 | */ | ||
33 | public EcdsaPublicKey() { | 56 | public EcdsaPublicKey() { |
34 | x = new byte[32]; | 57 | // empty |
35 | y = new byte[32]; | ||
36 | } | 58 | } |
37 | 59 | ||
38 | public static EcdsaPublicKey fromStringUncompressed(String s) { | 60 | /** |
39 | if (s.length() != org.gnunet.util.Strings.getEncodedStringLength(64)) { | 61 | * Load an ECDSA key from a string. |
40 | logger.debug("invalid key length"); | 62 | * |
41 | return null; | 63 | * @param s string with the key data |
42 | } | 64 | * @return a public key |
43 | byte[] data = new byte[64]; | 65 | */ |
44 | if (!Strings.stringToData(s, data)) { | 66 | public static EcdsaPublicKey fromString(String s) { |
45 | logger.debug("invalid key format"); | ||
46 | return null; | ||
47 | } | ||
48 | EcdsaPublicKey publicKey = new EcdsaPublicKey(); | 67 | EcdsaPublicKey publicKey = new EcdsaPublicKey(); |
49 | System.arraycopy(data, 0, publicKey.x, 0, 32); | 68 | Strings.stringToData(s, publicKey.y); |
50 | System.arraycopy(data, 32, publicKey.y, 0, 32); | ||
51 | return publicKey; | 69 | return publicKey; |
52 | } | 70 | } |
53 | 71 | ||
@@ -60,17 +78,13 @@ public class EcdsaPublicKey implements Message { | |||
60 | public static EcdsaPublicKey random() { | 78 | public static EcdsaPublicKey random() { |
61 | SecureRandom sr = new SecureRandom(); | 79 | SecureRandom sr = new SecureRandom(); |
62 | EcdsaPublicKey publicKey = new EcdsaPublicKey(); | 80 | EcdsaPublicKey publicKey = new EcdsaPublicKey(); |
63 | sr.nextBytes(publicKey.x); | ||
64 | sr.nextBytes(publicKey.y); | 81 | sr.nextBytes(publicKey.y); |
65 | return publicKey; | 82 | return publicKey; |
66 | } | 83 | } |
67 | 84 | ||
68 | @Override | 85 | @Override |
69 | public String toString() { | 86 | public String toString() { |
70 | byte[] keyData = new byte[64]; | 87 | return Strings.dataToString(y); |
71 | System.arraycopy(x, 0, keyData, 0, 32); | ||
72 | System.arraycopy(y, 0, keyData, 32, 32); | ||
73 | return Strings.dataToString(keyData); | ||
74 | } | 88 | } |
75 | 89 | ||
76 | @Override | 90 | @Override |
@@ -80,7 +94,6 @@ public class EcdsaPublicKey implements Message { | |||
80 | 94 | ||
81 | EcdsaPublicKey publicKey = (EcdsaPublicKey) o; | 95 | EcdsaPublicKey publicKey = (EcdsaPublicKey) o; |
82 | 96 | ||
83 | if (!Arrays.equals(x, publicKey.x)) return false; | ||
84 | if (!Arrays.equals(y, publicKey.y)) return false; | 97 | if (!Arrays.equals(y, publicKey.y)) return false; |
85 | 98 | ||
86 | return true; | 99 | return true; |
@@ -88,8 +101,8 @@ public class EcdsaPublicKey implements Message { | |||
88 | 101 | ||
89 | @Override | 102 | @Override |
90 | public int hashCode() { | 103 | public int hashCode() { |
91 | int result = Arrays.hashCode(x); | 104 | int result = Arrays.hashCode(y); |
92 | result = 31 * result + Arrays.hashCode(y); | ||
93 | return result; | 105 | return result; |
94 | } | 106 | } |
107 | |||
95 | } | 108 | } |
diff --git a/src/main/java/org/gnunet/util/crypto/EcdsaSignature.java b/src/main/java/org/gnunet/util/crypto/EcdsaSignature.java index b668a3f..76a5e22 100644 --- a/src/main/java/org/gnunet/util/crypto/EcdsaSignature.java +++ b/src/main/java/org/gnunet/util/crypto/EcdsaSignature.java | |||
@@ -23,11 +23,15 @@ package org.gnunet.util.crypto; | |||
23 | 23 | ||
24 | import org.gnunet.construct.FixedSizeIntegerArray; | 24 | import org.gnunet.construct.FixedSizeIntegerArray; |
25 | import org.gnunet.construct.Message; | 25 | import org.gnunet.construct.Message; |
26 | import org.gnunet.util.HashCode; | ||
26 | import org.gnunet.util.Strings; | 27 | import org.gnunet.util.Strings; |
27 | 28 | ||
28 | import java.math.BigInteger; | 29 | import java.math.BigInteger; |
29 | import java.nio.ByteBuffer; | 30 | import java.security.SecureRandom; |
30 | 31 | ||
32 | /** | ||
33 | * ECDSA Signature. | ||
34 | */ | ||
31 | public class EcdsaSignature implements Message { | 35 | public class EcdsaSignature implements Message { |
32 | /** | 36 | /** |
33 | * R value of the signature in compressed form. | 37 | * R value of the signature in compressed form. |
@@ -48,13 +52,38 @@ public class EcdsaSignature implements Message { | |||
48 | this.s = new byte[32]; | 52 | this.s = new byte[32]; |
49 | } | 53 | } |
50 | 54 | ||
55 | /** | ||
56 | * Verify that this signature has been created by the given public key and signs the | ||
57 | * given data and purpose. | ||
58 | * | ||
59 | * @param m message that was signed | ||
60 | * @param purpose purpose of the signature | ||
61 | * @param publicKey public key to check for | ||
62 | * @return whether the signature is valid | ||
63 | */ | ||
51 | public boolean verify(byte[] m, int purpose, EcdsaPublicKey publicKey) { | 64 | public boolean verify(byte[] m, int purpose, EcdsaPublicKey publicKey) { |
52 | return false; | 65 | HashCode h = HashCode.hash(m); |
66 | byte[] zData = new byte[32]; | ||
67 | System.arraycopy(h.data, 0, zData, 0, 32); | ||
68 | BigInteger z = new BigInteger(1, zData); | ||
69 | BigInteger sCoeff = Ed25519.decodeScalar(s); | ||
70 | BigInteger rCoeff = Ed25519.decodeScalar(r); | ||
71 | BigInteger w = sCoeff.modInverse(Ed25519.q); | ||
72 | BigInteger u1 = z.multiply(w).mod(Ed25519.q); | ||
73 | BigInteger u2 = rCoeff.multiply(w).mod(Ed25519.q); | ||
74 | Ed25519 P = Ed25519.B.scalarmult(u1).add(Ed25519.B.scalarmult(u2)); | ||
75 | return P.P0.equals(rCoeff.mod(Ed25519.q)); | ||
53 | } | 76 | } |
54 | 77 | ||
78 | /** | ||
79 | * Load a signature from a string. | ||
80 | * | ||
81 | * @param value serialized signature | ||
82 | * @return signature | ||
83 | */ | ||
55 | public static EcdsaSignature fromString(String value) { | 84 | public static EcdsaSignature fromString(String value) { |
56 | byte[] data = new byte[64]; | 85 | byte[] data = new byte[64]; |
57 | if (!Strings.stringToData(value, data)) { | 86 | if (! Strings.stringToData(value, data)) { |
58 | throw new AssertionError(); | 87 | throw new AssertionError(); |
59 | } | 88 | } |
60 | EcdsaSignature sig = new EcdsaSignature(); | 89 | EcdsaSignature sig = new EcdsaSignature(); |
@@ -63,6 +92,12 @@ public class EcdsaSignature implements Message { | |||
63 | return sig; | 92 | return sig; |
64 | } | 93 | } |
65 | 94 | ||
95 | |||
96 | /** | ||
97 | * Serialize the signature to a string. | ||
98 | * | ||
99 | * @return serialized signature | ||
100 | */ | ||
66 | @Override | 101 | @Override |
67 | public String toString() { | 102 | public String toString() { |
68 | byte[] sigData = new byte[64]; | 103 | byte[] sigData = new byte[64]; |
@@ -72,4 +107,16 @@ public class EcdsaSignature implements Message { | |||
72 | } | 107 | } |
73 | 108 | ||
74 | 109 | ||
110 | /** | ||
111 | * Return a signature that is invalid with very, very high probability. | ||
112 | * | ||
113 | * @return signature with random garbage | ||
114 | */ | ||
115 | public static EcdsaSignature randomGarbage() { | ||
116 | EcdsaSignature sig = new EcdsaSignature(); | ||
117 | SecureRandom r = new SecureRandom(); | ||
118 | r.nextBytes(sig.r); | ||
119 | r.nextBytes(sig.s); | ||
120 | return sig; | ||
121 | } | ||
75 | } | 122 | } |
diff --git a/src/main/java/org/gnunet/util/crypto/EcdsaSignedMessage.java b/src/main/java/org/gnunet/util/crypto/EcdsaSignedMessage.java index 0cb293a..bfc3fe4 100644 --- a/src/main/java/org/gnunet/util/crypto/EcdsaSignedMessage.java +++ b/src/main/java/org/gnunet/util/crypto/EcdsaSignedMessage.java | |||
@@ -26,7 +26,7 @@ import org.gnunet.construct.NestedMessage; | |||
26 | import org.gnunet.construct.UInt32; | 26 | import org.gnunet.construct.UInt32; |
27 | 27 | ||
28 | /** | 28 | /** |
29 | * A message together with a signature on the message and it's purpose. | 29 | * A message together with a signature on the message and its purpose. |
30 | */ | 30 | */ |
31 | public class EcdsaSignedMessage<M extends Message> implements Message { | 31 | public class EcdsaSignedMessage<M extends Message> implements Message { |
32 | @NestedMessage | 32 | @NestedMessage |
diff --git a/src/main/java/org/gnunet/util/crypto/Ed25519.java b/src/main/java/org/gnunet/util/crypto/Ed25519.java index 0947de4..caa2ec8 100644 --- a/src/main/java/org/gnunet/util/crypto/Ed25519.java +++ b/src/main/java/org/gnunet/util/crypto/Ed25519.java | |||
@@ -1,48 +1,148 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
1 | package org.gnunet.util.crypto; | 21 | package org.gnunet.util.crypto; |
2 | 22 | ||
3 | 23 | ||
4 | import java.math.BigInteger; | 24 | import java.math.BigInteger; |
5 | import java.security.MessageDigest; | 25 | import java.security.MessageDigest; |
6 | import java.security.NoSuchAlgorithmException; | 26 | import java.security.NoSuchAlgorithmException; |
27 | import java.util.Arrays; | ||
7 | 28 | ||
8 | /** | 29 | /** |
9 | * Java-only implementation of arithmetic on DJBs Ed25519. | 30 | * Java-only implementation of arithmetic on DJBs Ed25519. |
10 | * Very, very slow. | 31 | * Very, very slow. |
11 | */ | 32 | */ |
12 | public class Ed25519 { | 33 | public class Ed25519 { |
13 | // curve parameter b | 34 | /** |
14 | static final int b = 256; | 35 | * curve parameter b |
15 | // curve parameter q = 255^(-19) | 36 | */ |
16 | private static final BigInteger q = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819949"); | 37 | public static final int b = 256; |
17 | // q-3 | 38 | /** |
18 | private static final BigInteger qm2 = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819947"); | 39 | * curve parameter q = 2^255-19 |
19 | // q-3 | 40 | */ |
20 | private static final BigInteger qp3 = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819952"); | 41 | public static final BigInteger q = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819949"); |
42 | /** | ||
43 | * q-2 | ||
44 | */ | ||
45 | private static final BigInteger qm2 = q.subtract(BigInteger.valueOf(2)); | ||
46 | /** | ||
47 | * q+3 | ||
48 | */ | ||
49 | private static final BigInteger qp3 = q.add(BigInteger.valueOf(3)); | ||
50 | /** | ||
51 | * ??? | ||
52 | */ | ||
21 | static final BigInteger l = new BigInteger("7237005577332262213973186563042994240857116359379907606001950938285454250989"); | 53 | static final BigInteger l = new BigInteger("7237005577332262213973186563042994240857116359379907606001950938285454250989"); |
54 | /** | ||
55 | * ??? | ||
56 | */ | ||
22 | private static final BigInteger d = new BigInteger("-4513249062541557337682894930092624173785641285191125241628941591882900924598840740"); | 57 | private static final BigInteger d = new BigInteger("-4513249062541557337682894930092624173785641285191125241628941591882900924598840740"); |
58 | /** | ||
59 | * ??? | ||
60 | */ | ||
23 | private static final BigInteger I = new BigInteger("19681161376707505956807079304988542015446066515923890162744021073123829784752"); | 61 | private static final BigInteger I = new BigInteger("19681161376707505956807079304988542015446066515923890162744021073123829784752"); |
24 | private static final BigInteger By = new BigInteger("46316835694926478169428394003475163141307993866256225615783033603165251855960"); | 62 | /** |
63 | * x-coordinate of the base point | ||
64 | */ | ||
25 | private static final BigInteger Bx = new BigInteger("15112221349535400772501151409588531511454012693041857206046113283949847762202"); | 65 | private static final BigInteger Bx = new BigInteger("15112221349535400772501151409588531511454012693041857206046113283949847762202"); |
26 | static final Ed25519 B = new Ed25519(Bx.mod(q),By.mod(q)); | 66 | /** |
27 | // 2^255 | 67 | * x-coordinate of the base point. |
28 | private static final BigInteger un = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819967"); | 68 | * Corresponds to '9' on Curve25519 in montgomery form |
69 | */ | ||
70 | private static final BigInteger By = new BigInteger("46316835694926478169428394003475163141307993866256225615783033603165251855960"); | ||
71 | /** | ||
72 | * base point | ||
73 | */ | ||
74 | public static final Ed25519 B = new Ed25519(Bx.mod(q),By.mod(q)); | ||
29 | 75 | ||
76 | /** | ||
77 | * Mask where only the first 255 bits are set. | ||
78 | */ | ||
79 | private static final BigInteger mask255 = BigInteger.ONE.shiftLeft(255).subtract(BigInteger.ONE); | ||
30 | 80 | ||
81 | /** | ||
82 | * First coordinate (x) of this point. | ||
83 | */ | ||
31 | BigInteger P0; | 84 | BigInteger P0; |
85 | |||
86 | /** | ||
87 | * Second coordinate (y) of this point. | ||
88 | */ | ||
32 | BigInteger P1; | 89 | BigInteger P1; |
33 | 90 | ||
91 | /** | ||
92 | * Create a curve point from its coordinates. | ||
93 | * @param P0 x-coordinate | ||
94 | * @param P1 y-coordinate | ||
95 | */ | ||
34 | public Ed25519(BigInteger P0, BigInteger P1) { | 96 | public Ed25519(BigInteger P0, BigInteger P1) { |
35 | this.P0 = P0; | 97 | this.P0 = P0; |
36 | this.P1 = P1; | 98 | this.P1 = P1; |
37 | } | 99 | } |
38 | 100 | ||
39 | public static Ed25519 decompress(BigInteger y) { | 101 | /** |
102 | * Create a curve point from its string representation | ||
103 | * | ||
104 | * @param s the string representation | ||
105 | * @return a curve point corresponsing to 's' | ||
106 | */ | ||
107 | public static Ed25519 decode(byte[] s) { | ||
108 | BigInteger y = decodeScalar(s); | ||
109 | BigInteger x = recoverX(y); | ||
110 | if ((x.testBit(0)?1:0) != bit(s, b-1)) { | ||
111 | x = q.subtract(x); | ||
112 | } | ||
113 | Ed25519 v = new Ed25519(x, y); | ||
114 | if (!v.isOnCurve()) { | ||
115 | throw new AssertionError("not on curve"); | ||
116 | } | ||
117 | return v; | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * Get the i'th bit of a byte array | ||
122 | * | ||
123 | * @param h byte array | ||
124 | * @param i bit index | ||
125 | * @return value of the i'th bit in h | ||
126 | */ | ||
127 | private static int bit(byte[] h, int i) { | ||
128 | return h[i/8] >> (i%8) & 1; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Recover the (positive) x-coordinate from y. | ||
133 | * | ||
134 | * @param y the y coordinate | ||
135 | * @return positive x-coordinate | ||
136 | */ | ||
137 | public static BigInteger recoverX(BigInteger y) { | ||
40 | BigInteger y2 = y.multiply(y); | 138 | BigInteger y2 = y.multiply(y); |
41 | BigInteger xx = (y2.subtract(BigInteger.ONE)).multiply(inv(d.multiply(y2).add(BigInteger.ONE))); | 139 | BigInteger xx = (y2.subtract(BigInteger.ONE)).multiply(inv(d.multiply(y2).add(BigInteger.ONE))); |
42 | BigInteger x = xx.modPow(qp3.divide(BigInteger.valueOf(8)), q); | 140 | BigInteger x = xx.modPow(qp3.divide(BigInteger.valueOf(8)), q); |
43 | if (!x.multiply(x).subtract(xx).mod(q).equals(BigInteger.ZERO)) x = (x.multiply(I).mod(q)); | 141 | if (!x.multiply(x).subtract(xx).mod(q).equals(BigInteger.ZERO)) |
44 | if (!x.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) x = q.subtract(x); | 142 | x = (x.multiply(I).mod(q)); |
45 | return new Ed25519(x, y); | 143 | if (!x.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) |
144 | x = q.subtract(x); | ||
145 | return x; | ||
46 | } | 146 | } |
47 | 147 | ||
48 | /** | 148 | /** |
@@ -72,6 +172,12 @@ public class Ed25519 { | |||
72 | return new Ed25519(x3.mod(q), y3.mod(q)); | 172 | return new Ed25519(x3.mod(q), y3.mod(q)); |
73 | } | 173 | } |
74 | 174 | ||
175 | /** | ||
176 | * Multiply this point by a scalar value. | ||
177 | * | ||
178 | * @param e scalar factor | ||
179 | * @return this*e | ||
180 | */ | ||
75 | public Ed25519 scalarmult(BigInteger e) { | 181 | public Ed25519 scalarmult(BigInteger e) { |
76 | if (e.equals(BigInteger.ZERO)) { | 182 | if (e.equals(BigInteger.ZERO)) { |
77 | return new Ed25519(BigInteger.ZERO, BigInteger.ONE); | 183 | return new Ed25519(BigInteger.ZERO, BigInteger.ONE); |
@@ -82,32 +188,59 @@ public class Ed25519 { | |||
82 | return Q; | 188 | return Q; |
83 | } | 189 | } |
84 | 190 | ||
191 | /** | ||
192 | * Decode an integer from it's little endian byte array form. | ||
193 | * Takes a 32-byte array. The highest order bit is masked out. | ||
194 | * | ||
195 | * @param s string representation of a scalar | ||
196 | * @return scalar represented by 's' | ||
197 | */ | ||
85 | public static BigInteger decodeScalar(byte[] s) { | 198 | public static BigInteger decodeScalar(byte[] s) { |
199 | if (s.length != 32) { | ||
200 | throw new AssertionError(); | ||
201 | } | ||
202 | // convert 's' to big endian | ||
86 | byte[] out = new byte[s.length]; | 203 | byte[] out = new byte[s.length]; |
87 | for (int i=0; i < s.length;i++) { | 204 | for (int i=0; i < s.length;i++) { |
88 | out[i] = s[s.length-1-i]; | 205 | out[i] = s[s.length-1-i]; |
89 | } | 206 | } |
90 | return new BigInteger(out).and(un); | 207 | return new BigInteger(1, out).and(mask255); |
91 | } | 208 | } |
92 | 209 | ||
210 | /** | ||
211 | * Encode a scalar to little endian byte array form. | ||
212 | * The resulting array is always 32 bytes large. | ||
213 | * | ||
214 | * @param n scalar to encode | ||
215 | * @return byte representation of 'n' | ||
216 | */ | ||
93 | public static byte[] encodeScalar(BigInteger n) { | 217 | public static byte[] encodeScalar(BigInteger n) { |
94 | byte[] in = n.toByteArray(); | 218 | byte[] in = n.and(mask255).toByteArray(); |
95 | // reverse the array | 219 | if (in.length > 32) { |
96 | for (int i = 0; i < in.length / 2; i++) { | 220 | throw new AssertionError("size too big: " + in.length); |
97 | byte tmp = in[i]; | 221 | } |
98 | in[i] = in[in.length - i - 1]; | 222 | byte[] full = new byte[32]; |
99 | in[in.length - i - 1] = tmp; | 223 | // reverse 'in' and copy to the beginning of 'full' |
224 | for (int i = 0; i < in.length; i++) { | ||
225 | full[in.length - i - 1] = in[i]; | ||
100 | } | 226 | } |
101 | return in; | 227 | return full; |
102 | } | 228 | } |
103 | 229 | ||
230 | /** | ||
231 | * Compress end encode a point on the curve. | ||
232 | * | ||
233 | * @return compressed and encoded point | ||
234 | */ | ||
104 | public byte[] encode() { | 235 | public byte[] encode() { |
105 | byte[] out = encodeScalar(P1); | 236 | byte[] out = encodeScalar(P1); |
106 | out[out.length-1] |= (P0.testBit(0) ? 0x80 : 0); | 237 | System.out.println("encodeScalar " + P1); |
238 | System.out.println("out1 " + Arrays.toString(out)); | ||
239 | out[out.length-1] |= (P0.testBit(0) ? (byte) 0x80 : 0); | ||
240 | System.out.println("out2 " + Arrays.toString(out)); | ||
107 | return out; | 241 | return out; |
108 | } | 242 | } |
109 | 243 | ||
110 | |||
111 | /** | 244 | /** |
112 | * Hash the data in m and return 2^h(m) | 245 | * Hash the data in m and return 2^h(m) |
113 | * | 246 | * |
@@ -122,6 +255,7 @@ public class Ed25519 { | |||
122 | throw new RuntimeException("crypto algorithm required but not provided"); | 255 | throw new RuntimeException("crypto algorithm required but not provided"); |
123 | } | 256 | } |
124 | final byte[] h = sha512.digest(m); | 257 | final byte[] h = sha512.digest(m); |
258 | // reverse h | ||
125 | for (int i = 0; i < 32; i++) { | 259 | for (int i = 0; i < 32; i++) { |
126 | byte tmp = h[i]; | 260 | byte tmp = h[i]; |
127 | h[i] = h[63 - i]; | 261 | h[i] = h[63 - i]; |
@@ -130,4 +264,42 @@ public class Ed25519 { | |||
130 | return new BigInteger(1, h); | 264 | return new BigInteger(1, h); |
131 | } | 265 | } |
132 | 266 | ||
267 | /** | ||
268 | * Check whether this point is on the curve, and thus valid. | ||
269 | * | ||
270 | * @return whether is point is on the curve | ||
271 | */ | ||
272 | public boolean isOnCurve() { | ||
273 | BigInteger x = P0; | ||
274 | BigInteger y = P1; | ||
275 | BigInteger xx = x.multiply(x); | ||
276 | BigInteger yy = y.multiply(y); | ||
277 | BigInteger dxxyy = d.multiply(yy).multiply(xx); | ||
278 | return xx.negate().add(yy).subtract(BigInteger.ONE).subtract(dxxyy).mod(q).equals(BigInteger.ZERO); | ||
279 | } | ||
280 | |||
281 | @Override | ||
282 | public String toString() { | ||
283 | return "(" + P0.toString() + ", " + P1.toString() + ")"; | ||
284 | } | ||
285 | |||
286 | @Override | ||
287 | public boolean equals(Object o) { | ||
288 | if (this == o) return true; | ||
289 | if (o == null || getClass() != o.getClass()) return false; | ||
290 | |||
291 | Ed25519 ed25519 = (Ed25519) o; | ||
292 | |||
293 | if (!P0.equals(ed25519.P0)) return false; | ||
294 | if (!P1.equals(ed25519.P1)) return false; | ||
295 | |||
296 | return true; | ||
297 | } | ||
298 | |||
299 | @Override | ||
300 | public int hashCode() { | ||
301 | int result = P0.hashCode(); | ||
302 | result = 31 * result + P1.hashCode(); | ||
303 | return result; | ||
304 | } | ||
133 | } | 305 | } |
diff --git a/src/main/java/org/gnunet/util/crypto/EddsaPrivateKey.java b/src/main/java/org/gnunet/util/crypto/EddsaPrivateKey.java index 21aa647..2d1dbcb 100644 --- a/src/main/java/org/gnunet/util/crypto/EddsaPrivateKey.java +++ b/src/main/java/org/gnunet/util/crypto/EddsaPrivateKey.java | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
1 | package org.gnunet.util.crypto; | 20 | package org.gnunet.util.crypto; |
2 | 21 | ||
3 | import org.gnunet.construct.FixedSizeIntegerArray; | 22 | import org.gnunet.construct.FixedSizeIntegerArray; |
@@ -17,7 +36,21 @@ public class EddsaPrivateKey implements Message { | |||
17 | return sign(getPublicKey(), purpose, m); | 36 | return sign(getPublicKey(), purpose, m); |
18 | } | 37 | } |
19 | 38 | ||
39 | |||
40 | /** | ||
41 | * Sign the given data with this private key. Must include a purpose to mitigate | ||
42 | * replay / copy and paste attacks. | ||
43 | * | ||
44 | * @param publicKey public key corresponding to this private key, supplying this parameter | ||
45 | * leads to better performance as the public key does not have to be derived | ||
46 | * @param purpose purpose for the signature | ||
47 | * @param m data to sign | ||
48 | * @return the signature over both the data and the purpose | ||
49 | */ | ||
20 | public EddsaSignature sign(EddsaPublicKey publicKey, int purpose, byte[] m) { | 50 | public EddsaSignature sign(EddsaPublicKey publicKey, int purpose, byte[] m) { |
51 | if (!publicKey.asPoint().isOnCurve()) { | ||
52 | throw new AssertionError(); | ||
53 | } | ||
21 | MessageDigest sha512; | 54 | MessageDigest sha512; |
22 | try { | 55 | try { |
23 | sha512 = MessageDigest.getInstance("SHA-512"); | 56 | sha512 = MessageDigest.getInstance("SHA-512"); |
@@ -40,6 +73,12 @@ public class EddsaPrivateKey implements Message { | |||
40 | 73 | ||
41 | BigInteger S = r.add(Ed25519.Hint(buf.array()).multiply(a)).mod(Ed25519.l); | 74 | BigInteger S = r.add(Ed25519.Hint(buf.array()).multiply(a)).mod(Ed25519.l); |
42 | 75 | ||
76 | if (!R.isOnCurve()) { | ||
77 | throw new AssertionError(); | ||
78 | } | ||
79 | if (!publicKey.asPoint().isOnCurve()) { | ||
80 | throw new AssertionError(); | ||
81 | } | ||
43 | return new EddsaSignature(R, S); | 82 | return new EddsaSignature(R, S); |
44 | } | 83 | } |
45 | 84 | ||
@@ -55,6 +94,12 @@ public class EddsaPrivateKey implements Message { | |||
55 | } | 94 | } |
56 | 95 | ||
57 | 96 | ||
97 | /** | ||
98 | * Compute the coefficient that is used to derive the public key. | ||
99 | * See 'Daniel J. Bernstein et al, High-speed high-security signatures' for details. | ||
100 | * | ||
101 | * @return the public key coefficient | ||
102 | */ | ||
58 | private BigInteger computePublicKeyCoefficient() { | 103 | private BigInteger computePublicKeyCoefficient() { |
59 | MessageDigest sha512; | 104 | MessageDigest sha512; |
60 | try { | 105 | try { |
@@ -71,12 +116,30 @@ public class EddsaPrivateKey implements Message { | |||
71 | return a; | 116 | return a; |
72 | } | 117 | } |
73 | 118 | ||
119 | /** | ||
120 | * Get the public key for this private key. | ||
121 | * | ||
122 | * @return the public key for this private key | ||
123 | */ | ||
74 | public EddsaPublicKey getPublicKey() { | 124 | public EddsaPublicKey getPublicKey() { |
75 | BigInteger a = computePublicKeyCoefficient(); | 125 | BigInteger a = computePublicKeyCoefficient(); |
76 | Ed25519 A = Ed25519.B.scalarmult(a); | 126 | Ed25519 A = Ed25519.B.scalarmult(a); |
77 | return new EddsaPublicKey(A); | 127 | if (!A.isOnCurve()) { |
128 | throw new AssertionError(); | ||
129 | } | ||
130 | EddsaPublicKey publicKey = new EddsaPublicKey(A); | ||
131 | |||
132 | if (!A.equals(publicKey.asPoint())) { | ||
133 | throw new AssertionError(); | ||
134 | } | ||
135 | return publicKey; | ||
78 | } | 136 | } |
79 | 137 | ||
138 | /** | ||
139 | * Create a random private key. | ||
140 | * | ||
141 | * @return a random private key | ||
142 | */ | ||
80 | public static EddsaPrivateKey createRandom() { | 143 | public static EddsaPrivateKey createRandom() { |
81 | SecureRandom sr = new SecureRandom(); | 144 | SecureRandom sr = new SecureRandom(); |
82 | EddsaPrivateKey privateKey = new EddsaPrivateKey(); | 145 | EddsaPrivateKey privateKey = new EddsaPrivateKey(); |
diff --git a/src/main/java/org/gnunet/util/crypto/EddsaPublicKey.java b/src/main/java/org/gnunet/util/crypto/EddsaPublicKey.java index b548cf7..aa43a0b 100644 --- a/src/main/java/org/gnunet/util/crypto/EddsaPublicKey.java +++ b/src/main/java/org/gnunet/util/crypto/EddsaPublicKey.java | |||
@@ -1,33 +1,114 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
1 | package org.gnunet.util.crypto; | 21 | package org.gnunet.util.crypto; |
2 | 22 | ||
3 | import org.gnunet.construct.FixedSizeIntegerArray; | 23 | import org.gnunet.construct.FixedSizeIntegerArray; |
4 | import org.gnunet.construct.Message; | 24 | import org.gnunet.construct.Message; |
25 | import org.gnunet.util.Strings; | ||
5 | 26 | ||
27 | import java.security.SecureRandom; | ||
28 | import java.util.Arrays; | ||
29 | |||
30 | /** | ||
31 | * EdDSA public key. | ||
32 | */ | ||
6 | public class EddsaPublicKey implements Message { | 33 | public class EddsaPublicKey implements Message { |
7 | /** | 34 | /** |
8 | * x-coordinate of the point on the curve. | 35 | * y-coordinate of the point on the curve, in Ed25519-compressed form. |
9 | * The number is stored as little endian. | 36 | * The number is stored as little endian. |
10 | */ | 37 | */ |
11 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) | 38 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) |
12 | public byte[] x; | 39 | public byte[] y; |
13 | 40 | ||
14 | /** | 41 | /** |
15 | * y-coordinate of the point on the curve. | 42 | * Create a public key without allocating space for the key data. |
16 | * The number is stored as little endian. | 43 | * Necessary for constructing this class with org.gnunet.construct.* |
17 | */ | 44 | */ |
18 | @FixedSizeIntegerArray(bitSize = 8, signed = false, length = 32) | ||
19 | public byte[] y; | ||
20 | |||
21 | public EddsaPublicKey() { | 45 | public EddsaPublicKey() { |
22 | // default constructor for Construct | 46 | // default constructor for Construct |
23 | } | 47 | } |
24 | 48 | ||
25 | public EddsaPublicKey(Ed25519 a) { | 49 | public EddsaPublicKey(Ed25519 a) { |
26 | x = Ed25519.encodeScalar(a.P0); | 50 | y = a.encode(); |
27 | y = Ed25519.encodeScalar(a.P1); | 51 | } |
52 | |||
53 | /** | ||
54 | * Convert this public key to a point on the Ed25519 curve. | ||
55 | * | ||
56 | * @return a point corresponding to this key | ||
57 | */ | ||
58 | Ed25519 asPoint() { | ||
59 | return Ed25519.decode(y); | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * Load an ECDSA key from a string. | ||
64 | * | ||
65 | * @param s string with the key data | ||
66 | * @return a public key | ||
67 | */ | ||
68 | public EcdhePublicKey fromString(String s) { | ||
69 | EcdhePublicKey publicKey = new EcdhePublicKey(); | ||
70 | Strings.stringToData(s, publicKey.y); | ||
71 | return publicKey; | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * Create a random public key. The generated key might not even be valid | ||
76 | * (i.e. not on the curve), thus this method should only be used for testing. | ||
77 | * | ||
78 | * @return a random, possibly invalid public key | ||
79 | */ | ||
80 | public static EcdsaPublicKey random() { | ||
81 | SecureRandom sr = new SecureRandom(); | ||
82 | EcdsaPublicKey publicKey = new EcdsaPublicKey(); | ||
83 | sr.nextBytes(publicKey.y); | ||
84 | return publicKey; | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * Converrt this public key to a string | ||
89 | * | ||
90 | * @return a string representing this public key | ||
91 | */ | ||
92 | @Override | ||
93 | public String toString() { | ||
94 | return Strings.dataToString(y); | ||
95 | } | ||
96 | |||
97 | @Override | ||
98 | public boolean equals(Object o) { | ||
99 | if (this == o) return true; | ||
100 | if (o == null || getClass() != o.getClass()) return false; | ||
101 | |||
102 | EcdsaPublicKey publicKey = (EcdsaPublicKey) o; | ||
103 | |||
104 | if (!Arrays.equals(y, publicKey.y)) return false; | ||
105 | |||
106 | return true; | ||
28 | } | 107 | } |
29 | 108 | ||
30 | public Ed25519 asPoint() { | 109 | @Override |
31 | return new Ed25519(Ed25519.decodeScalar(x), Ed25519.decodeScalar(y)); | 110 | public int hashCode() { |
111 | int result = Arrays.hashCode(y); | ||
112 | return result; | ||
32 | } | 113 | } |
33 | } | 114 | } |
diff --git a/src/main/java/org/gnunet/util/crypto/EddsaSignature.java b/src/main/java/org/gnunet/util/crypto/EddsaSignature.java index 25eea34..fa16a9c 100644 --- a/src/main/java/org/gnunet/util/crypto/EddsaSignature.java +++ b/src/main/java/org/gnunet/util/crypto/EddsaSignature.java | |||
@@ -18,26 +18,6 @@ | |||
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /* | ||
22 | This file is part of GNUnet. | ||
23 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
24 | |||
25 | GNUnet is free software; you can redistribute it and/or modify | ||
26 | it under the terms of the GNU General Public License as published | ||
27 | by the Free Software Foundation; either version 3, or (at your | ||
28 | option) any later version. | ||
29 | |||
30 | GNUnet is distributed in the hope that it will be useful, but | ||
31 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
33 | General Public License for more details. | ||
34 | |||
35 | You should have received a copy of the GNU General Public License | ||
36 | along with GNUnet; see the file COPYING. If not, write to the | ||
37 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
38 | Boston, MA 02111-1307, USA. | ||
39 | */ | ||
40 | |||
41 | package org.gnunet.util.crypto; | 21 | package org.gnunet.util.crypto; |
42 | 22 | ||
43 | 23 | ||
@@ -75,7 +55,7 @@ public class EddsaSignature implements Message { | |||
75 | } | 55 | } |
76 | 56 | ||
77 | public boolean verify(byte[] m, int purpose, EddsaPublicKey publicKey) { | 57 | public boolean verify(byte[] m, int purpose, EddsaPublicKey publicKey) { |
78 | Ed25519 R = Ed25519.decompress(Ed25519.decodeScalar(r)); | 58 | Ed25519 R = Ed25519.decode(r); |
79 | Ed25519 A = publicKey.asPoint(); | 59 | Ed25519 A = publicKey.asPoint(); |
80 | BigInteger S = Ed25519.decodeScalar(s); | 60 | BigInteger S = Ed25519.decodeScalar(s); |
81 | ByteBuffer Stemp = ByteBuffer.allocate(32 + 32 + m.length); | 61 | ByteBuffer Stemp = ByteBuffer.allocate(32 + 32 + m.length); |
@@ -83,7 +63,19 @@ public class EddsaSignature implements Message { | |||
83 | BigInteger h = Ed25519.Hint(Stemp.array()); | 63 | BigInteger h = Ed25519.Hint(Stemp.array()); |
84 | Ed25519 ra = Ed25519.B.scalarmult(S); | 64 | Ed25519 ra = Ed25519.B.scalarmult(S); |
85 | Ed25519 rb = R.add(A.scalarmult(h)); | 65 | Ed25519 rb = R.add(A.scalarmult(h)); |
86 | return rb.equals(rb); | 66 | if (!A.isOnCurve()) { |
67 | throw new AssertionError(); | ||
68 | } | ||
69 | if (!R.isOnCurve()) { | ||
70 | throw new AssertionError(); | ||
71 | } | ||
72 | if (!ra.isOnCurve()) { | ||
73 | throw new AssertionError(); | ||
74 | } | ||
75 | if (!rb.isOnCurve()) { | ||
76 | throw new AssertionError(); | ||
77 | } | ||
78 | return ra.equals(rb); | ||
87 | } | 79 | } |
88 | 80 | ||
89 | public static EddsaSignature fromString(String value) { | 81 | public static EddsaSignature fromString(String value) { |
diff --git a/src/main/java/org/gnunet/util/crypto/EddsaSignedMessage.java b/src/main/java/org/gnunet/util/crypto/EddsaSignedMessage.java index 27f969a..01f0ea1 100644 --- a/src/main/java/org/gnunet/util/crypto/EddsaSignedMessage.java +++ b/src/main/java/org/gnunet/util/crypto/EddsaSignedMessage.java | |||
@@ -18,26 +18,6 @@ | |||
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /* | ||
22 | This file is part of GNUnet. | ||
23 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) | ||
24 | |||
25 | GNUnet is free software; you can redistribute it and/or modify | ||
26 | it under the terms of the GNU General Public License as published | ||
27 | by the Free Software Foundation; either version 3, or (at your | ||
28 | option) any later version. | ||
29 | |||
30 | GNUnet is distributed in the hope that it will be useful, but | ||
31 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
33 | General Public License for more details. | ||
34 | |||
35 | You should have received a copy of the GNU General Public License | ||
36 | along with GNUnet; see the file COPYING. If not, write to the | ||
37 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
38 | Boston, MA 02111-1307, USA. | ||
39 | */ | ||
40 | |||
41 | package org.gnunet.util.crypto; | 21 | package org.gnunet.util.crypto; |
42 | 22 | ||
43 | import org.gnunet.construct.Construct; | 23 | import org.gnunet.construct.Construct; |
diff --git a/src/main/java/org/gnunet/voting/Ballot.java b/src/main/java/org/gnunet/voting/Ballot.java index 72d444f..e300010 100644 --- a/src/main/java/org/gnunet/voting/Ballot.java +++ b/src/main/java/org/gnunet/voting/Ballot.java | |||
@@ -180,13 +180,13 @@ public class Ballot { | |||
180 | if (!optCaPub.isPresent()) { | 180 | if (!optCaPub.isPresent()) { |
181 | throw new InvalidBallotException("no CA pub key given"); | 181 | throw new InvalidBallotException("no CA pub key given"); |
182 | } | 182 | } |
183 | caPub = EcdsaPublicKey.fromStringUncompressed(optCaPub.get()); | 183 | caPub = EcdsaPublicKey.fromString(optCaPub.get()); |
184 | if (null == caPub) { | 184 | if (null == caPub) { |
185 | throw new InvalidBallotException("CA pub key invalid"); | 185 | throw new InvalidBallotException("CA pub key invalid"); |
186 | } | 186 | } |
187 | Optional<String> optIssuerPub = cfg.getValueString("election", "ISSUER_PUB"); | 187 | Optional<String> optIssuerPub = cfg.getValueString("election", "ISSUER_PUB"); |
188 | if (optIssuerPub.isPresent()) { | 188 | if (optIssuerPub.isPresent()) { |
189 | issuerPub = EcdsaPublicKey.fromStringUncompressed(optIssuerPub.get()); | 189 | issuerPub = EcdsaPublicKey.fromString(optIssuerPub.get()); |
190 | Optional<String> optIssuerSig = cfg.getValueString("election", "ISSUER_SIG"); | 190 | Optional<String> optIssuerSig = cfg.getValueString("election", "ISSUER_SIG"); |
191 | if (!optIssuerSig.isPresent()) { | 191 | if (!optIssuerSig.isPresent()) { |
192 | throw new InvalidBallotException("issuer public key present, but no signature"); | 192 | throw new InvalidBallotException("issuer public key present, but no signature"); |
@@ -227,7 +227,7 @@ public class Ballot { | |||
227 | 227 | ||
228 | Optional<String> optVoterPub = cfg.getValueString("vote", "VOTER_PUB"); | 228 | Optional<String> optVoterPub = cfg.getValueString("vote", "VOTER_PUB"); |
229 | if (optVoterPub.isPresent()) { | 229 | if (optVoterPub.isPresent()) { |
230 | voterPub = EcdsaPublicKey.fromStringUncompressed(optVoterPub.get()); | 230 | voterPub = EcdsaPublicKey.fromString(optVoterPub.get()); |
231 | if (null == voterPub) { | 231 | if (null == voterPub) { |
232 | throw new InvalidBallotException("voter public key present but invalid"); | 232 | throw new InvalidBallotException("voter public key present but invalid"); |
233 | } | 233 | } |
@@ -268,15 +268,13 @@ public class Ballot { | |||
268 | digest.update(x.getKey().getBytes()); | 268 | digest.update(x.getKey().getBytes()); |
269 | digest.update(x.getValue().data); | 269 | digest.update(x.getValue().data); |
270 | } | 270 | } |
271 | digest.update(issuerPub.x); | ||
272 | digest.update(issuerPub.y); | 271 | digest.update(issuerPub.y); |
273 | digest.update(caPub.x); | ||
274 | digest.update(caPub.y); | 272 | digest.update(caPub.y); |
275 | digest.update(Longs.toByteArray(startTime.getSeconds())); | 273 | digest.update(Longs.toByteArray(startTime.getSeconds())); |
276 | digest.update(Longs.toByteArray(endTime.getSeconds())); | 274 | digest.update(Longs.toByteArray(endTime.getSeconds())); |
277 | digest.update(Longs.toByteArray(closingTime.getSeconds())); | 275 | digest.update(Longs.toByteArray(closingTime.getSeconds())); |
278 | digest.update(Longs.toByteArray(queryTime.getSeconds())); | 276 | digest.update(Longs.toByteArray(queryTime.getSeconds())); |
279 | return new HashCode(digest.digest()); | 277 | return HashCode.fromHashCode(digest.digest()); |
280 | } | 278 | } |
281 | 279 | ||
282 | /** | 280 | /** |
diff --git a/src/main/java/org/gnunet/voting/CertifyGroupTool.java b/src/main/java/org/gnunet/voting/CertifyGroupTool.java index b8d267a..ec82eba 100644 --- a/src/main/java/org/gnunet/voting/CertifyGroupTool.java +++ b/src/main/java/org/gnunet/voting/CertifyGroupTool.java | |||
@@ -109,7 +109,7 @@ public class CertifyGroupTool extends Program { | |||
109 | setReturnValue(1); | 109 | setReturnValue(1); |
110 | return; | 110 | return; |
111 | } | 111 | } |
112 | final EcdsaPublicKey memberPubKey = EcdsaPublicKey.fromStringUncompressed(memberPubKeyString); | 112 | final EcdsaPublicKey memberPubKey = EcdsaPublicKey.fromString(memberPubKeyString); |
113 | if (null == memberPubKey) { | 113 | if (null == memberPubKey) { |
114 | System.err.println("not a valid pubkey: '" + memberPubKeyString + "'"); | 114 | System.err.println("not a valid pubkey: '" + memberPubKeyString + "'"); |
115 | setReturnValue(1); | 115 | setReturnValue(1); |
diff --git a/src/main/java/org/gnunet/voting/GroupCert.java b/src/main/java/org/gnunet/voting/GroupCert.java index 2e64101..296aae7 100644 --- a/src/main/java/org/gnunet/voting/GroupCert.java +++ b/src/main/java/org/gnunet/voting/GroupCert.java | |||
@@ -114,11 +114,11 @@ public class GroupCert { | |||
114 | throw new InvalidGroupCertException("invalid signature in group cert"); | 114 | throw new InvalidGroupCertException("invalid signature in group cert"); |
115 | } | 115 | } |
116 | groupCert.expiration = AbsoluteTime.fromSeconds(optExpiration.get()); | 116 | groupCert.expiration = AbsoluteTime.fromSeconds(optExpiration.get()); |
117 | groupCert.signerPublicKey = EcdsaPublicKey.fromStringUncompressed(optCa.get()); | 117 | groupCert.signerPublicKey = EcdsaPublicKey.fromString(optCa.get()); |
118 | if (null == groupCert.signerPublicKey) { | 118 | if (null == groupCert.signerPublicKey) { |
119 | throw new InvalidGroupCertException("invalid CA in group cert"); | 119 | throw new InvalidGroupCertException("invalid CA in group cert"); |
120 | } | 120 | } |
121 | groupCert.member = EcdsaPublicKey.fromStringUncompressed(optMember.get()); | 121 | groupCert.member = EcdsaPublicKey.fromString(optMember.get()); |
122 | if (null == groupCert.member) { | 122 | if (null == groupCert.member) { |
123 | throw new InvalidGroupCertException("invalid member in group cert"); | 123 | throw new InvalidGroupCertException("invalid member in group cert"); |
124 | } | 124 | } |