From 112d80420c95e590b2425738c1713125381d8251 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Fri, 9 Jan 2015 13:23:18 +0000
Subject: [PATCH] Downgrade to 256-bit curve for performance.

Also reduced hash function to 256 bits because our target security level
is now 128 bits.
---
 .../org/briarproject/api/AuthorConstants.java | 10 +--
 .../src/org/briarproject/api/UniqueId.java    |  2 +-
 .../crypto/CryptoComponentImpl.java           | 19 +++--
 .../crypto/EllipticCurveConstants.java        | 79 +++++--------------
 .../briarproject/crypto/Sec1KeyParser.java    |  4 +-
 .../briarproject/crypto/SignatureImpl.java    |  4 +-
 .../src/org/briarproject/db/JdbcDatabase.java |  4 +-
 .../EllipticCurveMultiplicationTest.java      | 24 +++---
 .../crypto/EllipticCurvePerformanceTest.java  |  6 +-
 .../briarproject/messaging/ConsumersTest.java |  4 +-
 10 files changed, 55 insertions(+), 101 deletions(-)

diff --git a/briar-api/src/org/briarproject/api/AuthorConstants.java b/briar-api/src/org/briarproject/api/AuthorConstants.java
index 57ad598a75..1b2123d957 100644
--- a/briar-api/src/org/briarproject/api/AuthorConstants.java
+++ b/briar-api/src/org/briarproject/api/AuthorConstants.java
@@ -11,9 +11,9 @@ public interface AuthorConstants {
 	 * Public keys use SEC1 format: 0x04 x y, where x and y are unsigned
 	 * big-endian integers.
 	 * <p>
-	 * For a 384-bit elliptic curve, the maximum length is 2 * (384/8) + 1.
+	 * For a 256-bit elliptic curve, the maximum length is 2 * 256 / 8 + 1.
 	 */
-	int MAX_PUBLIC_KEY_LENGTH = 97;
+	int MAX_PUBLIC_KEY_LENGTH = 65;
 
 	/**
 	 * The maximum length of a signature in bytes.
@@ -24,8 +24,8 @@ public interface AuthorConstants {
 	 * length, len3 is len(s) as a DER length, and r and s are signed
 	 * big-endian integers of minimal length.
 	 * <p>
-	 * For a 384-bit elliptic curve, the lengths are one byte each, so the
-	 * maximum length is 2 * (384/8) + 8.
+	 * For a 256-bit elliptic curve, the lengths are one byte each, so the
+	 * maximum length is 2 * 256 / 8 + 8.
 	 */
-	int MAX_SIGNATURE_LENGTH = 104;
+	int MAX_SIGNATURE_LENGTH = 72;
 }
diff --git a/briar-api/src/org/briarproject/api/UniqueId.java b/briar-api/src/org/briarproject/api/UniqueId.java
index 38d4e9bc48..75cf1f6509 100644
--- a/briar-api/src/org/briarproject/api/UniqueId.java
+++ b/briar-api/src/org/briarproject/api/UniqueId.java
@@ -5,7 +5,7 @@ import java.util.Arrays;
 public abstract class UniqueId {
 
 	/** The length of a unique identifier in bytes. */
-	public static final int LENGTH = 48;
+	public static final int LENGTH = 32;
 
 	protected final byte[] id;
 
diff --git a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
index 34a36f0fdc..8685f56ac7 100644
--- a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
+++ b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
@@ -3,7 +3,6 @@ package org.briarproject.crypto;
 import static java.util.logging.Level.INFO;
 import static org.briarproject.api.invitation.InvitationConstants.CODE_BITS;
 import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
-import static org.briarproject.crypto.EllipticCurveConstants.P;
 import static org.briarproject.crypto.EllipticCurveConstants.PARAMETERS;
 import static org.briarproject.util.ByteUtils.MAX_32_BIT_UNSIGNED;
 
@@ -35,7 +34,7 @@ import org.spongycastle.crypto.CipherParameters;
 import org.spongycastle.crypto.Digest;
 import org.spongycastle.crypto.Mac;
 import org.spongycastle.crypto.agreement.ECDHCBasicAgreement;
-import org.spongycastle.crypto.digests.SHA384Digest;
+import org.spongycastle.crypto.digests.SHA256Digest;
 import org.spongycastle.crypto.engines.AESLightEngine;
 import org.spongycastle.crypto.generators.ECKeyPairGenerator;
 import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
@@ -51,8 +50,8 @@ class CryptoComponentImpl implements CryptoComponent {
 			Logger.getLogger(CryptoComponentImpl.class.getName());
 
 	private static final int CIPHER_KEY_BYTES = 32; // 256 bits
-	private static final int AGREEMENT_KEY_PAIR_BITS = 384;
-	private static final int SIGNATURE_KEY_PAIR_BITS = 384;
+	private static final int AGREEMENT_KEY_PAIR_BITS = 256;
+	private static final int SIGNATURE_KEY_PAIR_BITS = 256;
 	private static final int STORAGE_IV_BYTES = 16; // 128 bits
 	private static final int PBKDF_SALT_BYTES = 16; // 128 bits
 	private static final int PBKDF_TARGET_MILLIS = 500;
@@ -99,9 +98,9 @@ class CryptoComponentImpl implements CryptoComponent {
 		agreementKeyPairGenerator.init(params);
 		signatureKeyPairGenerator = new ECKeyPairGenerator();
 		signatureKeyPairGenerator.init(params);
-		agreementKeyParser = new Sec1KeyParser(PARAMETERS, P,
+		agreementKeyParser = new Sec1KeyParser(PARAMETERS,
 				AGREEMENT_KEY_PAIR_BITS);
-		signatureKeyParser = new Sec1KeyParser(PARAMETERS, P,
+		signatureKeyParser = new Sec1KeyParser(PARAMETERS,
 				SIGNATURE_KEY_PAIR_BITS);
 	}
 
@@ -112,7 +111,7 @@ class CryptoComponentImpl implements CryptoComponent {
 	}
 
 	public MessageDigest getMessageDigest() {
-		return new DoubleDigest(new SHA384Digest());
+		return new DoubleDigest(new SHA256Digest());
 	}
 
 	public PseudoRandom getPseudoRandom(int seed1, int seed2) {
@@ -405,7 +404,7 @@ class CryptoComponentImpl implements CryptoComponent {
 		if(label[label.length - 1] != '\0')
 			throw new IllegalArgumentException();
 		// Initialise the PRF
-		Mac prf = new HMac(new SHA384Digest());
+		Mac prf = new HMac(new SHA256Digest());
 		KeyParameter k = new KeyParameter(secret);
 		prf.init(k);
 		int macLength = prf.getMacSize();
@@ -426,7 +425,7 @@ class CryptoComponentImpl implements CryptoComponent {
 	// Password-based key derivation function - see PKCS#5 v2.1, section 5.2
 	private byte[] pbkdf2(String password, byte[] salt, int iterations) {
 		byte[] utf8 = StringUtils.toUtf8(password);
-		Digest digest = new SHA384Digest();
+		Digest digest = new SHA256Digest();
 		PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(digest);
 		gen.init(utf8, salt, iterations);
 		int keyLengthInBits = CIPHER_KEY_BYTES * 8;
@@ -468,7 +467,7 @@ class CryptoComponentImpl implements CryptoComponent {
 		byte[] salt = new byte[PBKDF_SALT_BYTES];
 		int keyLengthInBits = CIPHER_KEY_BYTES * 8;
 		long start = System.nanoTime();
-		Digest digest = new SHA384Digest();
+		Digest digest = new SHA256Digest();
 		PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(digest);
 		gen.init(password, salt, iterations);
 		gen.generateDerivedParameters(keyLengthInBits);
diff --git a/briar-core/src/org/briarproject/crypto/EllipticCurveConstants.java b/briar-core/src/org/briarproject/crypto/EllipticCurveConstants.java
index b244e19467..76be537299 100644
--- a/briar-core/src/org/briarproject/crypto/EllipticCurveConstants.java
+++ b/briar-core/src/org/briarproject/crypto/EllipticCurveConstants.java
@@ -2,68 +2,29 @@ package org.briarproject.crypto;
 
 import java.math.BigInteger;
 
+import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves;
+import org.spongycastle.asn1.x9.X9ECParameters;
 import org.spongycastle.crypto.params.ECDomainParameters;
 import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.math.ec.ECMultiplier;
 import org.spongycastle.math.ec.ECPoint;
 import org.spongycastle.math.ec.MontgomeryLadderMultiplier;
 
-/** Parameters for curve brainpoolP384r1 - see RFC 5639. */
-interface EllipticCurveConstants {
-
-	/**
-	 * The prime specifying the finite field. (This is called p in RFC 5639 and
-	 * q in SEC 2.)
-	 */
-	BigInteger P = new BigInteger("8CB91E82" + "A3386D28" + "0F5D6F7E" +
-			"50E641DF" + "152F7109" + "ED5456B4" + "12B1DA19" + "7FB71123" +
-			"ACD3A729" + "901D1A71" + "87470013" + "3107EC53", 16);
-
-	/**
-	 * A coefficient of the equation y^2 = x^3 + A*x + B defining the elliptic
-	 * curve. (This is called A in RFC 5639 and a in SEC 2.)
-	 */
-	BigInteger A = new BigInteger("7BC382C6" + "3D8C150C" + "3C72080A" +
-			"CE05AFA0" + "C2BEA28E" + "4FB22787" + "139165EF" + "BA91F90F" +
-			"8AA5814A" + "503AD4EB" + "04A8C7DD" + "22CE2826", 16);
-
-	/**
-	 * A coefficient of the equation y^2 = x^3 + A*x + B defining the elliptic
-	 * curve. (This is called B in RFC 5639 b in SEC 2.)
-	 */
-	BigInteger B = new BigInteger("04A8C7DD" + "22CE2826" + "8B39B554" +
-			"16F0447C" + "2FB77DE1" + "07DCD2A6" + "2E880EA5" + "3EEB62D5" +
-			"7CB43902" + "95DBC994" + "3AB78696" + "FA504C11", 16);
-
-	/**
-	 * The x co-ordinate of the base point G. (This is called x in RFC 5639 and
-	 * SEC 2.)
-	 */
-	BigInteger X = new BigInteger("1D1C64F0" + "68CF45FF" + "A2A63A81" +
-			"B7C13F6B" + "8847A3E7" + "7EF14FE3" + "DB7FCAFE" + "0CBD10E8" +
-			"E826E034" + "36D646AA" + "EF87B2E2" + "47D4AF1E", 16);
-
-	/**
-	 * The y co-ordinate of the base point G. (This is called y in RFC 5639 and
-	 * SEC 2.)
-	 */
-	BigInteger Y = new BigInteger("8ABE1D75" + "20F9C2A4" + "5CB1EB8E" +
-			"95CFD552" + "62B70B29" + "FEEC5864" + "E19C054F" + "F9912928" +
-			"0E464621" + "77918111" + "42820341" + "263C5315", 16);
-
-	/**
-	 * The order of the base point G. (This is called q in RFC 5639 and n in
-	 * SEC 2.)
-	 */
-	BigInteger Q = new BigInteger("8CB91E82" + "A3386D28" + "0F5D6F7E" +
-			"50E641DF" + "152F7109" + "ED5456B3" + "1F166E6C" + "AC0425A7" +
-			"CF3AB6AF" + "6B7FC310" + "3B883202" + "E9046565", 16);
-
-	/** The cofactor of G. (This is called h in RFC 5639 and SEC 2.) */
-	BigInteger H = BigInteger.ONE;
-
-	// Static parameter objects derived from the above parameters
-	ECCurve CURVE = new ECCurve.Fp(P, A, B).configure().setMultiplier(
-			new MontgomeryLadderMultiplier()).create();
-	ECPoint G = CURVE.createPoint(X, Y);
-	ECDomainParameters PARAMETERS = new ECDomainParameters(CURVE, G, Q, H);
+/** Parameters for curve brainpoolp256r1 - see RFC 5639. */
+class EllipticCurveConstants {
+
+	static final ECDomainParameters PARAMETERS;
+
+	static {
+		// Start with the default implementation of the curve
+		X9ECParameters x9 = TeleTrusTNamedCurves.getByName("brainpoolp256r1");
+		// Use a constant-time multiplier
+		ECMultiplier monty = new MontgomeryLadderMultiplier();
+		ECCurve curve = x9.getCurve().configure().setMultiplier(monty).create();
+		BigInteger gX = x9.getG().getAffineXCoord().toBigInteger();
+		BigInteger gY = x9.getG().getAffineYCoord().toBigInteger();
+		ECPoint g = curve.createPoint(gX, gY);
+		// Convert to ECDomainParameters using the new multiplier
+		PARAMETERS = new ECDomainParameters(curve, g, x9.getN(), x9.getH());
+	}
 }
diff --git a/briar-core/src/org/briarproject/crypto/Sec1KeyParser.java b/briar-core/src/org/briarproject/crypto/Sec1KeyParser.java
index efb3b7781d..d383138d98 100644
--- a/briar-core/src/org/briarproject/crypto/Sec1KeyParser.java
+++ b/briar-core/src/org/briarproject/crypto/Sec1KeyParser.java
@@ -29,10 +29,10 @@ class Sec1KeyParser implements KeyParser {
 	private final BigInteger modulus;
 	private final int keyBits, bytesPerInt, publicKeyBytes, privateKeyBytes;
 
-	Sec1KeyParser(ECDomainParameters params, BigInteger modulus, int keyBits) {
+	Sec1KeyParser(ECDomainParameters params, int keyBits) {
 		this.params = params;
-		this.modulus = modulus;
 		this.keyBits = keyBits;
+		modulus = ((ECCurve.Fp) params.getCurve()).getQ();
 		bytesPerInt = (keyBits + 7) / 8;
 		publicKeyBytes = 1 + 2 * bytesPerInt;
 		privateKeyBytes = bytesPerInt;
diff --git a/briar-core/src/org/briarproject/crypto/SignatureImpl.java b/briar-core/src/org/briarproject/crypto/SignatureImpl.java
index a79e8dc63c..0c2a02eb4a 100644
--- a/briar-core/src/org/briarproject/crypto/SignatureImpl.java
+++ b/briar-core/src/org/briarproject/crypto/SignatureImpl.java
@@ -7,7 +7,7 @@ import org.briarproject.api.crypto.PrivateKey;
 import org.briarproject.api.crypto.PublicKey;
 import org.briarproject.api.crypto.Signature;
 import org.spongycastle.crypto.Digest;
-import org.spongycastle.crypto.digests.SHA384Digest;
+import org.spongycastle.crypto.digests.SHA256Digest;
 import org.spongycastle.crypto.params.ECPrivateKeyParameters;
 import org.spongycastle.crypto.params.ECPublicKeyParameters;
 import org.spongycastle.crypto.params.ParametersWithRandom;
@@ -23,7 +23,7 @@ class SignatureImpl implements Signature {
 
 	SignatureImpl(SecureRandom secureRandom) {
 		this.secureRandom = secureRandom;
-		Digest digest = new SHA384Digest();
+		Digest digest = new SHA256Digest();
 		DSAKCalculator calculator = new HMacDSAKCalculator(digest);
 		signer = new DSADigestSigner(new ECDSASigner(calculator), digest);
 	}
diff --git a/briar-core/src/org/briarproject/db/JdbcDatabase.java b/briar-core/src/org/briarproject/db/JdbcDatabase.java
index d131b4a1d2..aaa8aee814 100644
--- a/briar-core/src/org/briarproject/db/JdbcDatabase.java
+++ b/briar-core/src/org/briarproject/db/JdbcDatabase.java
@@ -62,8 +62,8 @@ import org.briarproject.api.transport.TemporarySecret;
  */
 abstract class JdbcDatabase implements Database<Connection> {
 
-	private static final int SCHEMA_VERSION = 7;
-	private static final int MIN_SCHEMA_VERSION = 7;
+	private static final int SCHEMA_VERSION = 8;
+	private static final int MIN_SCHEMA_VERSION = 8;
 
 	private static final String CREATE_SETTINGS =
 			"CREATE TABLE settings"
diff --git a/briar-tests/src/org/briarproject/crypto/EllipticCurveMultiplicationTest.java b/briar-tests/src/org/briarproject/crypto/EllipticCurveMultiplicationTest.java
index 12e15dce75..c3f2dd1853 100644
--- a/briar-tests/src/org/briarproject/crypto/EllipticCurveMultiplicationTest.java
+++ b/briar-tests/src/org/briarproject/crypto/EllipticCurveMultiplicationTest.java
@@ -1,10 +1,6 @@
 package org.briarproject.crypto;
 
-import static org.briarproject.crypto.EllipticCurveConstants.CURVE;
-import static org.briarproject.crypto.EllipticCurveConstants.G;
-import static org.briarproject.crypto.EllipticCurveConstants.H;
 import static org.briarproject.crypto.EllipticCurveConstants.PARAMETERS;
-import static org.briarproject.crypto.EllipticCurveConstants.Q;
 
 import java.math.BigInteger;
 import java.security.SecureRandom;
@@ -27,24 +23,22 @@ public class EllipticCurveMultiplicationTest extends BriarTestCase {
 
 	@Test
 	public void testMultiplierProducesSameResultsAsDefault() throws Exception {
-		// Instantiate the built-in implementation of the curve, which uses
-		// the default multiplier
+		// Instantiate the default implementation of the curve
 		X9ECParameters defaultX9Parameters =
-				TeleTrusTNamedCurves.getByName("brainpoolp384r1");
+				TeleTrusTNamedCurves.getByName("brainpoolp256r1");
 		ECCurve defaultCurve = defaultX9Parameters.getCurve();
 		ECPoint defaultG = defaultX9Parameters.getG();
-		BigInteger defaultQ = defaultX9Parameters.getN();
+		BigInteger defaultN = defaultX9Parameters.getN();
 		BigInteger defaultH = defaultX9Parameters.getH();
-		// Check that the built-in parameters are equal to our parameters,
-		// which use the Montgomery ladder multiplier
-		assertEquals(CURVE, defaultCurve);
-		assertEquals(G, defaultG);
-		assertEquals(Q, defaultQ);
-		assertEquals(H, defaultH);
+		// Check that the default parameters are equal to our parameters
+		assertEquals(PARAMETERS.getCurve(), defaultCurve);
+		assertEquals(PARAMETERS.getG(), defaultG);
+		assertEquals(PARAMETERS.getN(), defaultN);
+		assertEquals(PARAMETERS.getH(), defaultH);
 		// ECDomainParameters doesn't have an equals() method, but it's just a
 		// container for the parameters
 		ECDomainParameters defaultParameters = new ECDomainParameters(
-				defaultCurve, defaultG, defaultQ, defaultH);
+				defaultCurve, defaultG, defaultN, defaultH);
 		// Generate two key pairs with each set of parameters, using the same
 		// deterministic PRNG for both sets of parameters
 		byte[] seed = new byte[32];
diff --git a/briar-tests/src/org/briarproject/crypto/EllipticCurvePerformanceTest.java b/briar-tests/src/org/briarproject/crypto/EllipticCurvePerformanceTest.java
index fdc0e04b2f..fd876bc99e 100644
--- a/briar-tests/src/org/briarproject/crypto/EllipticCurvePerformanceTest.java
+++ b/briar-tests/src/org/briarproject/crypto/EllipticCurvePerformanceTest.java
@@ -13,7 +13,7 @@ import org.spongycastle.asn1.x9.X9ECParameters;
 import org.spongycastle.crypto.AsymmetricCipherKeyPair;
 import org.spongycastle.crypto.Digest;
 import org.spongycastle.crypto.agreement.ECDHCBasicAgreement;
-import org.spongycastle.crypto.digests.SHA384Digest;
+import org.spongycastle.crypto.digests.SHA256Digest;
 import org.spongycastle.crypto.generators.ECKeyPairGenerator;
 import org.spongycastle.crypto.params.ECDomainParameters;
 import org.spongycastle.crypto.params.ECKeyGenerationParameters;
@@ -83,7 +83,7 @@ public class EllipticCurvePerformanceTest {
 		List<byte[]> signatures = new ArrayList<byte[]>();
 		samples.clear();
 		for(int i = 0; i < SAMPLES; i++) {
-			Digest digest = new SHA384Digest();
+			Digest digest = new SHA256Digest();
 			DSAKCalculator calculator = new HMacDSAKCalculator(digest);
 			DSADigestSigner signer = new DSADigestSigner(new ECDSASigner(
 					calculator), digest);
@@ -97,7 +97,7 @@ public class EllipticCurvePerformanceTest {
 		// Time some signature verifications
 		samples.clear();
 		for(int i = 0; i < SAMPLES; i++) {
-			Digest digest = new SHA384Digest();
+			Digest digest = new SHA256Digest();
 			DSAKCalculator calculator = new HMacDSAKCalculator(digest);
 			DSADigestSigner signer = new DSADigestSigner(new ECDSASigner(
 					calculator), digest);
diff --git a/briar-tests/src/org/briarproject/messaging/ConsumersTest.java b/briar-tests/src/org/briarproject/messaging/ConsumersTest.java
index ccf1038d22..f214336067 100644
--- a/briar-tests/src/org/briarproject/messaging/ConsumersTest.java
+++ b/briar-tests/src/org/briarproject/messaging/ConsumersTest.java
@@ -63,7 +63,7 @@ public class ConsumersTest extends BriarTestCase {
 		private final java.security.MessageDigest delegate;
 
 		private TestMessageDigest() throws GeneralSecurityException {
-			delegate = java.security.MessageDigest.getInstance("SHA-384");
+			delegate = java.security.MessageDigest.getInstance("SHA-256");
 		}
 
 		public byte[] digest() {
@@ -99,6 +99,6 @@ public class ConsumersTest extends BriarTestCase {
 
 		public void update(byte[] input, int offset, int len) {
 			delegate.update(input, offset, len);
-		}		
+		}
 	}
 }
-- 
GitLab