001: package org.bouncycastle.math.ec.test;
002:
003: import java.io.FileInputStream;
004: import java.io.FileOutputStream;
005: import java.io.IOException;
006: import java.math.BigInteger;
007: import java.security.NoSuchAlgorithmException;
008: import java.security.SecureRandom;
009: import java.util.Iterator;
010: import java.util.Properties;
011: import java.util.Set;
012:
013: import org.bouncycastle.asn1.sec.SECNamedCurves;
014: import org.bouncycastle.asn1.x9.X9ECParameters;
015: import org.bouncycastle.math.ec.ECFieldElement;
016: import org.bouncycastle.math.ec.ECPoint;
017:
018: public class F2mProofer {
019: private static final int NUM_SAMPLES = 1000;
020:
021: private static final String PATH = "crypto/test/src/org/bouncycastle/math/ec/test/samples/";
022:
023: private static final String INPUT_FILE_NAME_PREFIX = "Input_";
024:
025: private static final String RESULT_FILE_NAME_PREFIX = "Output_";
026:
027: /**
028: * The standard curves on which the tests are done
029: */
030: public static final String[] CURVES = { "sect163r2", "sect233r1",
031: "sect283r1", "sect409r1", "sect571r1" };
032:
033: private String pointToString(ECPoint.F2m p) {
034: ECFieldElement.F2m x = (ECFieldElement.F2m) p.getX();
035: ECFieldElement.F2m y = (ECFieldElement.F2m) p.getY();
036:
037: int m = x.getM();
038: int len = m / 2 + 5;
039:
040: StringBuffer sb = new StringBuffer(len);
041: sb.append('(');
042: sb.append(x.toBigInteger().toString(16));
043: sb.append(", ");
044: sb.append(y.toBigInteger().toString(16));
045: sb.append(')');
046:
047: return sb.toString();
048: }
049:
050: private void generateRandomInput(X9ECParameters x9ECParameters)
051: throws NoSuchAlgorithmException, IOException {
052: ECPoint.F2m g = (ECPoint.F2m) x9ECParameters.getG();
053: int m = ((ECFieldElement.F2m) (g.getX())).getM();
054:
055: SecureRandom secRand = SecureRandom.getInstance("SHA1PRNG");
056: Properties inputProps = new Properties();
057: for (int i = 0; i < NUM_SAMPLES; i++) {
058: BigInteger rand = new BigInteger(m, secRand);
059: inputProps.put(Integer.toString(i), rand.toString(16));
060: }
061: String bits = Integer.toString(m);
062: FileOutputStream fos = new FileOutputStream(PATH
063: + INPUT_FILE_NAME_PREFIX + bits + ".properties");
064: inputProps.store(fos, "Input Samples of length" + bits);
065: }
066:
067: private void multiplyPoints(X9ECParameters x9ECParameters,
068: String classPrefix) throws IOException {
069: ECPoint.F2m g = (ECPoint.F2m) x9ECParameters.getG();
070: int m = ((ECFieldElement.F2m) (g.getX())).getM();
071:
072: String inputFileName = PATH + INPUT_FILE_NAME_PREFIX + m
073: + ".properties";
074: Properties inputProps = new Properties();
075: inputProps.load(new FileInputStream(inputFileName));
076:
077: Properties outputProps = new Properties();
078:
079: for (int i = 0; i < NUM_SAMPLES; i++) {
080: BigInteger rand = new BigInteger(inputProps
081: .getProperty(Integer.toString(i)), 16);
082: ECPoint.F2m result = (ECPoint.F2m) g.multiply(rand);
083: String resultStr = pointToString(result);
084: outputProps.setProperty(Integer.toString(i), resultStr);
085: }
086:
087: String outputFileName = PATH + RESULT_FILE_NAME_PREFIX
088: + classPrefix + "_" + m + ".properties";
089: FileOutputStream fos = new FileOutputStream(outputFileName);
090: outputProps.store(fos, "Output Samples of length" + m);
091: }
092:
093: private Properties loadResults(String classPrefix, int m)
094: throws IOException {
095: FileInputStream fis = new FileInputStream(PATH
096: + RESULT_FILE_NAME_PREFIX + classPrefix + "_" + m
097: + ".properties");
098: Properties res = new Properties();
099: res.load(fis);
100: return res;
101:
102: }
103:
104: private void compareResult(X9ECParameters x9ECParameters,
105: String classPrefix1, String classPrefix2)
106: throws IOException {
107: ECPoint.F2m g = (ECPoint.F2m) x9ECParameters.getG();
108: int m = ((ECFieldElement.F2m) (g.getX())).getM();
109:
110: Properties res1 = loadResults(classPrefix1, m);
111: Properties res2 = loadResults(classPrefix2, m);
112:
113: Set keys = res1.keySet();
114: Iterator iter = keys.iterator();
115: while (iter.hasNext()) {
116: String key = (String) iter.next();
117: String result1 = res1.getProperty(key);
118: String result2 = res2.getProperty(key);
119: if (!(result1.equals(result2))) {
120: System.err.println("Difference found: m = " + m + ", "
121: + result1 + " does not equal " + result2);
122: }
123: }
124:
125: }
126:
127: private static void usage() {
128: System.err
129: .println("Usage: F2mProofer [-init | -multiply <className> "
130: + "| -compare <className1> <className2>]");
131: }
132:
133: public static void main(String[] args) throws Exception {
134: if (args.length == 0) {
135: usage();
136: return;
137: }
138: F2mProofer proofer = new F2mProofer();
139: if (args[0].equals("-init")) {
140: System.out.println("Generating random input...");
141: for (int i = 0; i < CURVES.length; i++) {
142: X9ECParameters x9ECParameters = SECNamedCurves
143: .getByName(CURVES[i]);
144: proofer.generateRandomInput(x9ECParameters);
145: }
146: System.out
147: .println("Successfully generated random input in "
148: + PATH);
149: } else if (args[0].equals("-compare")) {
150: if (args.length < 3) {
151: usage();
152: return;
153: }
154: String classPrefix1 = args[1];
155: String classPrefix2 = args[2];
156: System.out.println("Comparing results...");
157: for (int i = 0; i < CURVES.length; i++) {
158: X9ECParameters x9ECParameters = SECNamedCurves
159: .getByName(CURVES[i]);
160: proofer.compareResult(x9ECParameters, classPrefix1,
161: classPrefix2);
162: }
163: System.out.println("Successfully compared results in "
164: + PATH);
165: } else if (args[0].equals("-multiply")) {
166: if (args.length < 2) {
167: usage();
168: return;
169: }
170: String classPrefix = args[1];
171: System.out.println("Multiplying points...");
172: for (int i = 0; i < CURVES.length; i++) {
173: X9ECParameters x9ECParameters = SECNamedCurves
174: .getByName(CURVES[i]);
175: proofer.multiplyPoints(x9ECParameters, classPrefix);
176: }
177: System.out
178: .println("Successfully generated multiplied points in "
179: + PATH);
180: } else {
181: usage();
182: }
183: }
184: }
|