mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 05:39:53 +01:00
Test that our elliptic curve is equal to the named curve; benchmarks.
This commit is contained in:
@@ -1,21 +1,18 @@
|
|||||||
package org.briarproject.crypto;
|
package org.briarproject.crypto;
|
||||||
|
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.A;
|
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.B;
|
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.CURVE;
|
import static org.briarproject.crypto.EllipticCurveConstants.CURVE;
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.G;
|
import static org.briarproject.crypto.EllipticCurveConstants.G;
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.H;
|
import static org.briarproject.crypto.EllipticCurveConstants.H;
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.P;
|
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.PARAMETERS;
|
import static org.briarproject.crypto.EllipticCurveConstants.PARAMETERS;
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.Q;
|
import static org.briarproject.crypto.EllipticCurveConstants.Q;
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.X;
|
|
||||||
import static org.briarproject.crypto.EllipticCurveConstants.Y;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
import org.briarproject.BriarTestCase;
|
import org.briarproject.BriarTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves;
|
||||||
|
import org.spongycastle.asn1.x9.X9ECParameters;
|
||||||
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
||||||
import org.spongycastle.crypto.agreement.ECDHCBasicAgreement;
|
import org.spongycastle.crypto.agreement.ECDHCBasicAgreement;
|
||||||
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
||||||
@@ -30,17 +27,24 @@ public class EllipticCurveMultiplicationTest extends BriarTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultiplierProducesSameResultsAsDefault() throws Exception {
|
public void testMultiplierProducesSameResultsAsDefault() throws Exception {
|
||||||
// Construct a curve and base point using the default multiplier
|
// Instantiate the built-in implementation of the curve, which uses
|
||||||
ECCurve defaultCurve = new ECCurve.Fp(P, A, B);
|
// the default multiplier
|
||||||
ECPoint defaultG = defaultCurve.createPoint(X, Y);
|
X9ECParameters defaultX9Parameters =
|
||||||
// Check that the curve and base point are equal to those constructed
|
TeleTrusTNamedCurves.getByName("brainpoolp384r1");
|
||||||
// using the Montgomery ladder multiplier
|
ECCurve defaultCurve = defaultX9Parameters.getCurve();
|
||||||
|
ECPoint defaultG = defaultX9Parameters.getG();
|
||||||
|
BigInteger defaultQ = 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(CURVE, defaultCurve);
|
||||||
assertEquals(G, defaultG);
|
assertEquals(G, defaultG);
|
||||||
|
assertEquals(Q, defaultQ);
|
||||||
|
assertEquals(H, defaultH);
|
||||||
// ECDomainParameters doesn't have an equals() method, but it's just a
|
// ECDomainParameters doesn't have an equals() method, but it's just a
|
||||||
// container for the parameters
|
// container for the parameters
|
||||||
ECDomainParameters defaultParameters =
|
ECDomainParameters defaultParameters = new ECDomainParameters(
|
||||||
new ECDomainParameters(defaultCurve, defaultG, Q, H);
|
defaultCurve, defaultG, defaultQ, defaultH);
|
||||||
// Generate two key pairs with each set of parameters, using the same
|
// Generate two key pairs with each set of parameters, using the same
|
||||||
// deterministic PRNG for both sets of parameters
|
// deterministic PRNG for both sets of parameters
|
||||||
byte[] seed = new byte[32];
|
byte[] seed = new byte[32];
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
package org.briarproject.crypto;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.spongycastle.asn1.sec.SECNamedCurves;
|
||||||
|
import org.spongycastle.asn1.teletrust.TeleTrusTNamedCurves;
|
||||||
|
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.generators.ECKeyPairGenerator;
|
||||||
|
import org.spongycastle.crypto.params.ECDomainParameters;
|
||||||
|
import org.spongycastle.crypto.params.ECKeyGenerationParameters;
|
||||||
|
import org.spongycastle.crypto.params.ECPrivateKeyParameters;
|
||||||
|
import org.spongycastle.crypto.params.ECPublicKeyParameters;
|
||||||
|
import org.spongycastle.crypto.params.ParametersWithRandom;
|
||||||
|
import org.spongycastle.crypto.signers.DSADigestSigner;
|
||||||
|
import org.spongycastle.crypto.signers.DSAKCalculator;
|
||||||
|
import org.spongycastle.crypto.signers.ECDSASigner;
|
||||||
|
import org.spongycastle.crypto.signers.HMacDSAKCalculator;
|
||||||
|
import org.spongycastle.math.ec.ECCurve;
|
||||||
|
import org.spongycastle.math.ec.ECPoint;
|
||||||
|
import org.spongycastle.math.ec.MontgomeryLadderMultiplier;
|
||||||
|
|
||||||
|
// Not a JUnit test
|
||||||
|
public class EllipticCurvePerformanceTest {
|
||||||
|
|
||||||
|
private static final SecureRandom random = new SecureRandom();
|
||||||
|
private static final int SAMPLES = 50;
|
||||||
|
private static final int BYTES_TO_SIGN = 1024;
|
||||||
|
private static final List<String> SEC_NAMES = Arrays.asList(
|
||||||
|
"secp256k1", "secp256r1", "secp384r1", "secp521r1");
|
||||||
|
private static final List<String> BRAINPOOL_NAMES = Arrays.asList(
|
||||||
|
"brainpoolp256r1", "brainpoolp384r1", "brainpoolp512r1");
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
for(String name : SEC_NAMES) {
|
||||||
|
ECDomainParameters params =
|
||||||
|
convertParams(SECNamedCurves.getByName(name));
|
||||||
|
runTest(name + " default", params);
|
||||||
|
runTest(name + " constant", constantTime(params));
|
||||||
|
}
|
||||||
|
for(String name : BRAINPOOL_NAMES) {
|
||||||
|
ECDomainParameters params =
|
||||||
|
convertParams(TeleTrusTNamedCurves.getByName(name));
|
||||||
|
runTest(name + " default", params);
|
||||||
|
runTest(name + " constant", constantTime(params));
|
||||||
|
}
|
||||||
|
runTest("ours", EllipticCurveConstants.PARAMETERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runTest(String name, ECDomainParameters params) {
|
||||||
|
// Generate two key pairs using the given parameters
|
||||||
|
ECKeyGenerationParameters generatorParams =
|
||||||
|
new ECKeyGenerationParameters(params, random);
|
||||||
|
ECKeyPairGenerator generator = new ECKeyPairGenerator();
|
||||||
|
generator.init(generatorParams);
|
||||||
|
AsymmetricCipherKeyPair keyPair1 = generator.generateKeyPair();
|
||||||
|
ECPublicKeyParameters public1 =
|
||||||
|
(ECPublicKeyParameters) keyPair1.getPublic();
|
||||||
|
ECPrivateKeyParameters private1 =
|
||||||
|
(ECPrivateKeyParameters) keyPair1.getPrivate();
|
||||||
|
AsymmetricCipherKeyPair keyPair2 = generator.generateKeyPair();
|
||||||
|
ECPublicKeyParameters public2 =
|
||||||
|
(ECPublicKeyParameters) keyPair2.getPublic();
|
||||||
|
// Time some ECDH key agreements
|
||||||
|
List<Long> samples = new ArrayList<Long>();
|
||||||
|
for(int i = 0; i < SAMPLES; i++) {
|
||||||
|
ECDHCBasicAgreement agreement = new ECDHCBasicAgreement();
|
||||||
|
long start = System.nanoTime();
|
||||||
|
agreement.init(private1);
|
||||||
|
agreement.calculateAgreement(public2);
|
||||||
|
samples.add(System.nanoTime() - start);
|
||||||
|
}
|
||||||
|
long agreementMedian = median(samples);
|
||||||
|
// Time some signatures
|
||||||
|
List<byte[]> signatures = new ArrayList<byte[]>();
|
||||||
|
samples.clear();
|
||||||
|
for(int i = 0; i < SAMPLES; i++) {
|
||||||
|
Digest digest = new SHA384Digest();
|
||||||
|
DSAKCalculator calculator = new HMacDSAKCalculator(digest);
|
||||||
|
DSADigestSigner signer = new DSADigestSigner(new ECDSASigner(
|
||||||
|
calculator), digest);
|
||||||
|
long start = System.nanoTime();
|
||||||
|
signer.init(true, new ParametersWithRandom(private1, random));
|
||||||
|
signer.update(new byte[BYTES_TO_SIGN], 0, BYTES_TO_SIGN);
|
||||||
|
signatures.add(signer.generateSignature());
|
||||||
|
samples.add(System.nanoTime() - start);
|
||||||
|
}
|
||||||
|
long signatureMedian = median(samples);
|
||||||
|
// Time some signature verifications
|
||||||
|
samples.clear();
|
||||||
|
for(int i = 0; i < SAMPLES; i++) {
|
||||||
|
Digest digest = new SHA384Digest();
|
||||||
|
DSAKCalculator calculator = new HMacDSAKCalculator(digest);
|
||||||
|
DSADigestSigner signer = new DSADigestSigner(new ECDSASigner(
|
||||||
|
calculator), digest);
|
||||||
|
long start = System.nanoTime();
|
||||||
|
signer.init(false, public1);
|
||||||
|
signer.update(new byte[BYTES_TO_SIGN], 0, BYTES_TO_SIGN);
|
||||||
|
if(!signer.verifySignature(signatures.get(i)))
|
||||||
|
throw new AssertionError();
|
||||||
|
samples.add(System.nanoTime() - start);
|
||||||
|
}
|
||||||
|
long verificationMedian = median(samples);
|
||||||
|
System.out.println(name + ": "
|
||||||
|
+ agreementMedian + " "
|
||||||
|
+ signatureMedian + " "
|
||||||
|
+ verificationMedian);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long median(List<Long> list) {
|
||||||
|
int size = list.size();
|
||||||
|
if(size == 0) throw new IllegalArgumentException();
|
||||||
|
Collections.sort(list);
|
||||||
|
if(size % 2 == 1) return list.get(size / 2);
|
||||||
|
return list.get(size / 2 - 1) + list.get(size / 2) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ECDomainParameters convertParams(X9ECParameters in) {
|
||||||
|
return new ECDomainParameters(in.getCurve(), in.getG(), in.getN(),
|
||||||
|
in.getH());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ECDomainParameters constantTime(ECDomainParameters in) {
|
||||||
|
ECCurve curve = in.getCurve().configure().setMultiplier(
|
||||||
|
new MontgomeryLadderMultiplier()).create();
|
||||||
|
BigInteger x = in.getG().getAffineXCoord().toBigInteger();
|
||||||
|
BigInteger y = in.getG().getAffineYCoord().toBigInteger();
|
||||||
|
ECPoint g = curve.createPoint(x, y);
|
||||||
|
return new ECDomainParameters(curve, g, in.getN(), in.getH());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user