Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/test/java/org/spongycastle/math/ec/test/ECPointPerformanceTest.java')
-rw-r--r--core/src/test/java/org/spongycastle/math/ec/test/ECPointPerformanceTest.java198
1 files changed, 198 insertions, 0 deletions
diff --git a/core/src/test/java/org/spongycastle/math/ec/test/ECPointPerformanceTest.java b/core/src/test/java/org/spongycastle/math/ec/test/ECPointPerformanceTest.java
new file mode 100644
index 00000000..6be0c00b
--- /dev/null
+++ b/core/src/test/java/org/spongycastle/math/ec/test/ECPointPerformanceTest.java
@@ -0,0 +1,198 @@
+package org.spongycastle.math.ec.test;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x9.ECNamedCurveTable;
+import org.spongycastle.asn1.x9.X9ECParameters;
+import org.spongycastle.crypto.ec.CustomNamedCurves;
+import org.spongycastle.math.ec.ECCurve;
+import org.spongycastle.math.ec.ECPoint;
+import org.spongycastle.util.Times;
+
+/**
+ * Compares the performance of the the window NAF point multiplication against conventional point
+ * multiplication.
+ */
+public class ECPointPerformanceTest extends TestCase
+{
+ static final int MILLIS_PER_ROUND = 200;
+ static final int MILLIS_WARMUP = 1000;
+
+ static final int MULTS_PER_CHECK = 16;
+ static final int NUM_ROUNDS = 10;
+
+ private static String[] COORD_NAMES = new String[]{ "AFFINE", "HOMOGENEOUS", "JACOBIAN", "JACOBIAN-CHUDNOVSKY",
+ "JACOBIAN-MODIFIED", "LAMBDA-AFFINE", "LAMBDA-PROJECTIVE", "SKEWED" };
+
+ private void randMult(String curveName) throws Exception
+ {
+ X9ECParameters spec = ECNamedCurveTable.getByName(curveName);
+ if (spec != null)
+ {
+ randMult(curveName, spec);
+ }
+
+ spec = CustomNamedCurves.getByName(curveName);
+ if (spec != null)
+ {
+ randMult(curveName + " (custom)", spec);
+ }
+ }
+
+ private void randMult(String label, X9ECParameters spec) throws Exception
+ {
+ ECCurve C = spec.getCurve();
+ ECPoint G = (ECPoint)spec.getG();
+ BigInteger n = spec.getN();
+
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
+ random.setSeed(System.currentTimeMillis());
+
+ System.out.println(label);
+
+ int[] coords = ECCurve.getAllCoordinateSystems();
+ for (int i = 0; i < coords.length; ++i)
+ {
+ int coord = coords[i];
+ if (C.supportsCoordinateSystem(coord))
+ {
+ ECCurve c = C;
+ ECPoint g = G;
+
+ boolean defaultCoord = (c.getCoordinateSystem() == coord);
+ if (!defaultCoord)
+ {
+ c = C.configure().setCoordinateSystem(coord).create();
+ g = c.importPoint(G);
+ }
+
+ double avgRate = randMult(random, g, n);
+ String coordName = COORD_NAMES[coord];
+ StringBuffer sb = new StringBuffer();
+ sb.append(" ");
+ sb.append(defaultCoord ? '*' : ' ');
+ sb.append(coordName);
+ for (int j = sb.length(); j < 30; ++j)
+ {
+ sb.append(' ');
+ }
+ sb.append(": ");
+ sb.append(avgRate);
+ sb.append(" mults/sec");
+ for (int j = sb.length(); j < 64; ++j)
+ {
+ sb.append(' ');
+ }
+ sb.append('(');
+ sb.append(1000.0 / avgRate);
+ sb.append(" millis/mult)");
+ System.out.println(sb.toString());
+ }
+ }
+ }
+
+ private double randMult(SecureRandom random, ECPoint g, BigInteger n) throws Exception
+ {
+ BigInteger[] ks = new BigInteger[128];
+ for (int i = 0; i < ks.length; ++i)
+ {
+ ks[i] = new BigInteger(n.bitLength() - 1, random);
+ }
+
+ int ki = 0;
+ ECPoint p = g;
+
+ {
+ long startTime = Times.nanoTime();
+ long goalTime = startTime + 1000000L * MILLIS_WARMUP;
+
+ do
+ {
+ BigInteger k = ks[ki];
+ p = g.multiply(k);
+ if ((ki & 1) != 0)
+ {
+ g = p;
+ }
+ if (++ki == ks.length)
+ {
+ ki = 0;
+ }
+ }
+ while (Times.nanoTime() < goalTime);
+ }
+
+ double minRate = Double.MAX_VALUE, maxRate = Double.MIN_VALUE, totalRate = 0.0;
+
+ for (int i = 1; i <= NUM_ROUNDS; i++)
+ {
+ long startTime = Times.nanoTime();
+ long goalTime = startTime + 1000000L * MILLIS_PER_ROUND;
+ long count = 0, endTime;
+
+ do
+ {
+ ++count;
+
+ for (int j = 0; j < MULTS_PER_CHECK; ++j)
+ {
+ BigInteger k = ks[ki];
+ p = g.multiply(k);
+ if ((ki & 1) != 0)
+ {
+ g = p;
+ }
+ if (++ki == ks.length)
+ {
+ ki = 0;
+ }
+ }
+
+ endTime = Times.nanoTime();
+ }
+ while (endTime < goalTime);
+
+ double roundElapsed = (double)(endTime - startTime);
+ double roundRate = count * MULTS_PER_CHECK * 1000000000L / roundElapsed;
+
+ minRate = Math.min(minRate, roundRate);
+ maxRate = Math.max(maxRate, roundRate);
+ totalRate += roundRate;
+ }
+
+ return (totalRate - minRate - maxRate) / (NUM_ROUNDS - 2);
+ }
+
+ public void testMultiply() throws Exception
+ {
+ SortedSet names = new TreeSet(AllTests.enumToList(ECNamedCurveTable.getNames()));
+ names.addAll(AllTests.enumToList(CustomNamedCurves.getNames()));
+
+ Set oids = new HashSet();
+
+ Iterator it = names.iterator();
+ while (it.hasNext())
+ {
+ String name = (String)it.next();
+ ASN1ObjectIdentifier oid = ECNamedCurveTable.getOID(name);
+ if (oid == null)
+ {
+ oid = CustomNamedCurves.getOID(name);
+ }
+ if (oid != null && !oids.add(oid))
+ {
+ continue;
+ }
+
+ randMult(name);
+ }
+ }
+}