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
path: root/core
diff options
context:
space:
mode:
authorDavid Hook <dgh@cryptoworkshop.com>2014-03-03 00:50:40 +0400
committerDavid Hook <dgh@cryptoworkshop.com>2014-03-03 00:50:40 +0400
commit41a9e336bcd788ca04013bf730a1627ae9c8655a (patch)
tree6f01e31e1932bfa295f3a36e641a88c9296ad467 /core
parent933119114c96f703d1303a3c77d9ac405091270d (diff)
parent9686528dc72b2ad67d7b755dedb1a38bb7f027d8 (diff)
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'core')
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java56
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java310
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java2
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java79
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/Mod.java29
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/Nat.java70
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/WNafUtil.java66
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java408
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat224.java1284
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java107
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat384.java44
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java2
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java16
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java6
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java10
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java11
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java6
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java10
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java98
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java160
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java242
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java311
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java100
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java189
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java246
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java320
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java16
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java6
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java10
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java57
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java6
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java10
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java100
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java229
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java211
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java320
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java16
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java6
-rw-r--r--core/src/main/java/org/bouncycastle/util/Arrays.java38
-rw-r--r--core/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java28
-rw-r--r--core/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java10
-rw-r--r--core/src/test/data/org/bouncycastle/cms/test/PSSSignData.data1
-rw-r--r--core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1.sigbin3345 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1Enc.sigbin3371 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256.sigbin3417 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256Enc.sigbin3443 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512.sigbin3450 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512Enc.sigbin3476 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/cms/test/counterSig.p7mbin5647 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/eac/test/Belgique CVCA-02032010.7816.cvcertbin433 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/eac/test/REQ_18102010.csrbin346 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/eac/test/at_cert_19a.cvcertbin363 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/eac/test/dv_cer_BEDVBUZABE006_7816.cvcertbin225 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.cerbin807 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.crlbin55139 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.p12bin2742 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.pem52
-rw-r--r--core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/testcases.READMEbin14352 -> 0 bytes
-rw-r--r--core/src/test/data/org/bouncycastle/tsp/test/FileDaFirmare.data3
-rw-r--r--core/src/test/data/org/bouncycastle/tsp/test/FileDaFirmare.txt.tsd.derbin6207 -> 0 bytes
-rw-r--r--core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java8
81 files changed, 4857 insertions, 972 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java b/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
index 7da095b0..329618cd 100644
--- a/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
+++ b/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -11,8 +11,11 @@ import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.custom.sec.SecP192K1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP192R1Curve;
+import org.bouncycastle.math.ec.custom.sec.SecP224K1Curve;
+import org.bouncycastle.math.ec.custom.sec.SecP224R1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
+import org.bouncycastle.math.ec.custom.sec.SecP384R1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP521R1Curve;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
@@ -57,6 +60,38 @@ public class CustomNamedCurves
};
/*
+ * secp224k1
+ */
+ static X9ECParametersHolder secp224k1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = null;
+ ECCurve curve = configureCurve(new SecP224K1Curve());
+ ECPoint G = curve.decodePoint(Hex.decode("04"
+ + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
+ + "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
+ * secp224r1
+ */
+ static X9ECParametersHolder secp224r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
+ ECCurve curve = configureCurve(new SecP224R1Curve());
+ ECPoint G = curve.decodePoint(Hex.decode("04"
+ + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
+ + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
* secp256k1
*/
static X9ECParametersHolder secp256k1 = new X9ECParametersHolder()
@@ -89,6 +124,22 @@ public class CustomNamedCurves
};
/*
+ * secp384r1
+ */
+ static X9ECParametersHolder secp384r1 = new X9ECParametersHolder()
+ {
+ protected X9ECParameters createParameters()
+ {
+ byte[] S = Hex.decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
+ ECCurve curve = configureCurve(new SecP384R1Curve());
+ ECPoint G = curve.decodePoint(Hex.decode("04"
+ + "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ + "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
+ return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ }
+ };
+
+ /*
* secp521r1
*/
static X9ECParametersHolder secp521r1 = new X9ECParametersHolder()
@@ -119,12 +170,17 @@ public class CustomNamedCurves
{
defineCurve("secp192k1", SECObjectIdentifiers.secp192k1, secp192k1);
defineCurve("secp192r1", SECObjectIdentifiers.secp192r1, secp192r1);
+ defineCurve("secp224k1", SECObjectIdentifiers.secp224k1, secp224k1);
+ defineCurve("secp224r1", SECObjectIdentifiers.secp224r1, secp224r1);
defineCurve("secp256k1", SECObjectIdentifiers.secp256k1, secp256k1);
defineCurve("secp256r1", SECObjectIdentifiers.secp256r1, secp256r1);
+ defineCurve("secp384r1", SECObjectIdentifiers.secp384r1, secp384r1);
defineCurve("secp521r1", SECObjectIdentifiers.secp521r1, secp521r1);
objIds.put(Strings.toLowerCase("P-192"), SECObjectIdentifiers.secp192r1);
+ objIds.put(Strings.toLowerCase("P-224"), SECObjectIdentifiers.secp224r1);
objIds.put(Strings.toLowerCase("P-256"), SECObjectIdentifiers.secp256r1);
+ objIds.put(Strings.toLowerCase("P-384"), SECObjectIdentifiers.secp384r1);
objIds.put(Strings.toLowerCase("P-521"), SECObjectIdentifiers.secp521r1);
}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java
index 47dc6bd9..ed256fe8 100644
--- a/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java
+++ b/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java
@@ -1,155 +1,155 @@
-package org.bouncycastle.crypto.signers;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.DSA;
-import org.bouncycastle.crypto.params.ECDomainParameters;
-import org.bouncycastle.crypto.params.ECKeyParameters;
-import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
-import org.bouncycastle.crypto.params.ECPublicKeyParameters;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.math.ec.ECAlgorithms;
-import org.bouncycastle.math.ec.ECConstants;
-import org.bouncycastle.math.ec.ECMultiplier;
-import org.bouncycastle.math.ec.ECPoint;
-import org.bouncycastle.math.ec.FixedPointCombMultiplier;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-/**
- * GOST R 34.10-2001 Signature Algorithm
- */
-public class ECGOST3410Signer
- implements DSA
-{
- ECKeyParameters key;
-
- SecureRandom random;
-
- public void init(
- boolean forSigning,
- CipherParameters param)
- {
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.random = rParam.getRandom();
- this.key = (ECPrivateKeyParameters)rParam.getParameters();
- }
- else
- {
- this.random = new SecureRandom();
- this.key = (ECPrivateKeyParameters)param;
- }
- }
- else
- {
- this.key = (ECPublicKeyParameters)param;
- }
- }
-
- /**
- * generate a signature for the given message using the key we were
- * initialised with. For conventional GOST3410 the message should be a GOST3411
- * hash of the message of interest.
- *
- * @param message the message that will be verified later.
- */
- public BigInteger[] generateSignature(
- byte[] message)
- {
- byte[] mRev = new byte[message.length]; // conversion is little-endian
- for (int i = 0; i != mRev.length; i++)
- {
- mRev[i] = message[mRev.length - 1 - i];
- }
-
- BigInteger e = new BigInteger(1, mRev);
-
- ECDomainParameters ec = key.getParameters();
- BigInteger n = ec.getN();
- BigInteger d = ((ECPrivateKeyParameters)key).getD();
-
- BigInteger r, s;
-
- ECMultiplier basePointMultiplier = new FixedPointCombMultiplier();
-
- do // generate s
- {
- BigInteger k;
- do // generate r
- {
- do
- {
- k = new BigInteger(n.bitLength(), random);
- }
- while (k.equals(ECConstants.ZERO));
-
- ECPoint p = basePointMultiplier.multiply(ec.getG(), k).normalize();
-
- r = p.getAffineXCoord().toBigInteger().mod(n);
- }
- while (r.equals(ECConstants.ZERO));
-
- s = (k.multiply(e)).add(d.multiply(r)).mod(n);
- }
- while (s.equals(ECConstants.ZERO));
-
- return new BigInteger[]{ r, s };
- }
-
- /**
- * return true if the value r and s represent a GOST3410 signature for
- * the passed in message (for standard GOST3410 the message should be
- * a GOST3411 hash of the real message to be verified).
- */
- public boolean verifySignature(
- byte[] message,
- BigInteger r,
- BigInteger s)
- {
- byte[] mRev = new byte[message.length]; // conversion is little-endian
- for (int i = 0; i != mRev.length; i++)
- {
- mRev[i] = message[mRev.length - 1 - i];
- }
-
- BigInteger e = new BigInteger(1, mRev);
- BigInteger n = key.getParameters().getN();
-
- // r in the range [1,n-1]
- if (r.compareTo(ECConstants.ONE) < 0 || r.compareTo(n) >= 0)
- {
- return false;
- }
-
- // s in the range [1,n-1]
- if (s.compareTo(ECConstants.ONE) < 0 || s.compareTo(n) >= 0)
- {
- return false;
- }
-
- BigInteger v = e.modInverse(n);
-
- BigInteger z1 = s.multiply(v).mod(n);
- BigInteger z2 = (n.subtract(r)).multiply(v).mod(n);
-
- ECPoint G = key.getParameters().getG(); // P
- ECPoint Q = ((ECPublicKeyParameters)key).getQ();
-
- ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, z1, Q, z2).normalize();
-
- // components must be bogus.
- if (point.isInfinity())
- {
- return false;
- }
-
- BigInteger R = point.getAffineXCoord().toBigInteger().mod(n);
-
- return R.equals(r);
- }
-}
+package org.bouncycastle.crypto.signers;
+
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.DSA;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECKeyParameters;
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.math.ec.ECAlgorithms;
+import org.bouncycastle.math.ec.ECConstants;
+import org.bouncycastle.math.ec.ECMultiplier;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.FixedPointCombMultiplier;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+/**
+ * GOST R 34.10-2001 Signature Algorithm
+ */
+public class ECGOST3410Signer
+ implements DSA
+{
+ ECKeyParameters key;
+
+ SecureRandom random;
+
+ public void init(
+ boolean forSigning,
+ CipherParameters param)
+ {
+ if (forSigning)
+ {
+ if (param instanceof ParametersWithRandom)
+ {
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
+
+ this.random = rParam.getRandom();
+ this.key = (ECPrivateKeyParameters)rParam.getParameters();
+ }
+ else
+ {
+ this.random = new SecureRandom();
+ this.key = (ECPrivateKeyParameters)param;
+ }
+ }
+ else
+ {
+ this.key = (ECPublicKeyParameters)param;
+ }
+ }
+
+ /**
+ * generate a signature for the given message using the key we were
+ * initialised with. For conventional GOST3410 the message should be a GOST3411
+ * hash of the message of interest.
+ *
+ * @param message the message that will be verified later.
+ */
+ public BigInteger[] generateSignature(
+ byte[] message)
+ {
+ byte[] mRev = new byte[message.length]; // conversion is little-endian
+ for (int i = 0; i != mRev.length; i++)
+ {
+ mRev[i] = message[mRev.length - 1 - i];
+ }
+
+ BigInteger e = new BigInteger(1, mRev);
+
+ ECDomainParameters ec = key.getParameters();
+ BigInteger n = ec.getN();
+ BigInteger d = ((ECPrivateKeyParameters)key).getD();
+
+ BigInteger r, s;
+
+ ECMultiplier basePointMultiplier = new FixedPointCombMultiplier();
+
+ do // generate s
+ {
+ BigInteger k;
+ do // generate r
+ {
+ do
+ {
+ k = new BigInteger(n.bitLength(), random);
+ }
+ while (k.equals(ECConstants.ZERO));
+
+ ECPoint p = basePointMultiplier.multiply(ec.getG(), k).normalize();
+
+ r = p.getAffineXCoord().toBigInteger().mod(n);
+ }
+ while (r.equals(ECConstants.ZERO));
+
+ s = (k.multiply(e)).add(d.multiply(r)).mod(n);
+ }
+ while (s.equals(ECConstants.ZERO));
+
+ return new BigInteger[]{ r, s };
+ }
+
+ /**
+ * return true if the value r and s represent a GOST3410 signature for
+ * the passed in message (for standard GOST3410 the message should be
+ * a GOST3411 hash of the real message to be verified).
+ */
+ public boolean verifySignature(
+ byte[] message,
+ BigInteger r,
+ BigInteger s)
+ {
+ byte[] mRev = new byte[message.length]; // conversion is little-endian
+ for (int i = 0; i != mRev.length; i++)
+ {
+ mRev[i] = message[mRev.length - 1 - i];
+ }
+
+ BigInteger e = new BigInteger(1, mRev);
+ BigInteger n = key.getParameters().getN();
+
+ // r in the range [1,n-1]
+ if (r.compareTo(ECConstants.ONE) < 0 || r.compareTo(n) >= 0)
+ {
+ return false;
+ }
+
+ // s in the range [1,n-1]
+ if (s.compareTo(ECConstants.ONE) < 0 || s.compareTo(n) >= 0)
+ {
+ return false;
+ }
+
+ BigInteger v = e.modInverse(n);
+
+ BigInteger z1 = s.multiply(v).mod(n);
+ BigInteger z2 = (n.subtract(r)).multiply(v).mod(n);
+
+ ECPoint G = key.getParameters().getG(); // P
+ ECPoint Q = ((ECPublicKeyParameters)key).getQ();
+
+ ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, z1, Q, z2).normalize();
+
+ // components must be bogus.
+ if (point.isInfinity())
+ {
+ return false;
+ }
+
+ BigInteger R = point.getAffineXCoord().toBigInteger().mod(n);
+
+ return R.equals(r);
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java
index 72bbbcb4..3e839163 100644
--- a/core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java
+++ b/core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java
@@ -101,7 +101,7 @@ public class ECNRSigner
// BigInteger Vx = tempPair.getPublic().getW().getAffineX();
ECPublicKeyParameters V = (ECPublicKeyParameters)tempPair.getPublic(); // get temp's public key
- BigInteger Vx = V.getQ().normalize().getAffineXCoord().toBigInteger(); // get the point's x coordinate
+ BigInteger Vx = V.getQ().getAffineXCoord().toBigInteger(); // get the point's x coordinate
r = Vx.add(e).mod(n);
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
index 58a52b79..434287d9 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
@@ -220,6 +220,11 @@ public abstract class ECFieldElement
*/
public ECFieldElement sqrt()
{
+ if (isZero() || isOne())
+ {
+ return this;
+ }
+
if (!q.testBit(0))
{
throw new RuntimeException("not done yet");
@@ -227,30 +232,45 @@ public abstract class ECFieldElement
// note: even though this class implements ECConstants don't be tempted to
// remove the explicit declaration, some J2ME environments don't cope.
- // p mod 4 == 3
- if (q.testBit(1))
+
+ if (q.testBit(1)) // q == 4m + 3
{
- // z = g^(u+1) + p, p = 4u + 3
- ECFieldElement z = new Fp(q, r, x.modPow(q.shiftRight(2).add(ECConstants.ONE), q));
+ BigInteger e = q.shiftRight(2).add(ECConstants.ONE);
+ return checkSqrt(new Fp(q, r, x.modPow(e, q)));
+ }
+
+ if (q.testBit(2)) // q == 8m + 5
+ {
+ BigInteger t1 = x.modPow(q.shiftRight(3), q);
+ BigInteger t2 = modMult(t1, x);
+ BigInteger t3 = modMult(t2, t1);
- return z.square().equals(this) ? z : null;
+ if (t3.equals(ECConstants.ONE))
+ {
+ return checkSqrt(new Fp(q, r, t2));
+ }
+
+ // TODO This is constant and could be precomputed
+ BigInteger t4 = ECConstants.TWO.modPow(q.shiftRight(2), q);
+
+ BigInteger y = modMult(t2, t4);
+
+ return checkSqrt(new Fp(q, r, y));
}
- // p mod 4 == 1
- BigInteger qMinusOne = q.subtract(ECConstants.ONE);
+ // q == 8m + 1
- BigInteger legendreExponent = qMinusOne.shiftRight(1);
+ BigInteger legendreExponent = q.shiftRight(1);
if (!(x.modPow(legendreExponent, q).equals(ECConstants.ONE)))
{
return null;
}
- BigInteger u = qMinusOne.shiftRight(2);
- BigInteger k = u.shiftLeft(1).add(ECConstants.ONE);
-
BigInteger X = this.x;
BigInteger fourX = modDouble(modDouble(X));
+ BigInteger k = legendreExponent.add(ECConstants.ONE), qMinusOne = q.subtract(ECConstants.ONE);
+
BigInteger U, V;
Random rand = new Random();
do
@@ -261,7 +281,7 @@ public abstract class ECFieldElement
P = new BigInteger(q.bitLength(), rand);
}
while (P.compareTo(q) >= 0
- || !(modMult(P, P).subtract(fourX).modPow(legendreExponent, q).equals(qMinusOne)));
+ || !modReduce(P.multiply(P).subtract(fourX)).modPow(legendreExponent, q).equals(qMinusOne));
BigInteger[] result = lucasSequence(P, X, k);
U = result[0];
@@ -269,17 +289,7 @@ public abstract class ECFieldElement
if (modMult(V, V).equals(fourX))
{
- // Integer division by 2, mod q
- if (V.testBit(0))
- {
- V = V.add(q);
- }
-
- V = V.shiftRight(1);
-
- //assert modMult(V, V).equals(X);
-
- return new ECFieldElement.Fp(q, r, V);
+ return new ECFieldElement.Fp(q, r, modHalfAbs(V));
}
}
while (U.equals(ECConstants.ONE) || U.equals(qMinusOne));
@@ -287,6 +297,11 @@ public abstract class ECFieldElement
return null;
}
+ private ECFieldElement checkSqrt(ECFieldElement z)
+ {
+ return z.square().equals(this) ? z : null;
+ }
+
private BigInteger[] lucasSequence(
BigInteger P,
BigInteger Q,
@@ -361,6 +376,24 @@ public abstract class ECFieldElement
return _2x;
}
+ protected BigInteger modHalf(BigInteger x)
+ {
+ if (x.testBit(0))
+ {
+ x = q.add(x);
+ }
+ return x.shiftRight(1);
+ }
+
+ protected BigInteger modHalfAbs(BigInteger x)
+ {
+ if (x.testBit(0))
+ {
+ x = q.subtract(x);
+ }
+ return x.shiftRight(1);
+ }
+
protected BigInteger modInverse(BigInteger x)
{
int bits = getFieldSize();
diff --git a/core/src/main/java/org/bouncycastle/math/ec/Mod.java b/core/src/main/java/org/bouncycastle/math/ec/Mod.java
index 2ac6c465..0345af19 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/Mod.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/Mod.java
@@ -1,5 +1,9 @@
package org.bouncycastle.math.ec;
+import java.util.Random;
+
+import org.bouncycastle.crypto.util.Pack;
+
public abstract class Mod
{
public static void invert(int[] p, int[] x, int[] z)
@@ -70,6 +74,31 @@ public abstract class Mod
}
}
+ public static int[] random(int[] p)
+ {
+ int len = p.length;
+ Random rand = new Random();
+ int[] s = Nat.create(len);
+
+ int m = p[len - 1];
+ m |= m >>> 1;
+ m |= m >>> 2;
+ m |= m >>> 4;
+ m |= m >>> 8;
+ m |= m >>> 16;
+
+ do
+ {
+ byte[] bytes = new byte[len << 2];
+ rand. nextBytes(bytes);
+ Pack.bigEndianToInt(bytes, 0, s);
+ s[len - 1] &= m;
+ }
+ while (Nat.gte(len, s, p));
+
+ return s;
+ }
+
public static void subtract(int[] p, int[] x, int[] y, int[] z)
{
int len = p.length;
diff --git a/core/src/main/java/org/bouncycastle/math/ec/Nat.java b/core/src/main/java/org/bouncycastle/math/ec/Nat.java
index 6915b79b..2cf00c59 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/Nat.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/Nat.java
@@ -70,18 +70,19 @@ public abstract class Nat
return (int)c;
}
- public static int addWord(int len, int x, int[] z)
+ public static int addWord(int len, int x, int[] z, int zOff)
{
- long c = (x & M) + (z[0] & M);
- z[0] = (int)c;
+ // assert zOff < len;
+ long c = (x & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
c >>>= 32;
- return c == 0 ? 0 : inc(len, z, 1);
+ return c == 0 ? 0 : inc(len, z, zOff + 1);
}
public static int addWordExt(int len, int x, int[] zz, int zzOff)
{
int extLen = len << 1;
- // assert zzOff <= (extLen - 1);
+ // assert zzOff < extLen;
long c = (x & M) + (zz[zzOff + 0] & M);
zz[zzOff + 0] = (int)c;
c >>>= 32;
@@ -95,6 +96,11 @@ public abstract class Nat
return z;
}
+ public static void copy(int len, int[] x, int[] z)
+ {
+ System.arraycopy(x, 0, z, 0, len);
+ }
+
public static int[] create(int len)
{
return new int[len];
@@ -215,11 +221,21 @@ public abstract class Nat
public static void mul(int len, int[] x, int[] y, int[] zz)
{
- zz[len] = mulWord(len, x[0], y, zz, 0);
+ zz[len] = mulWord(len, x[0], y, zz);
for (int i = 1; i < len; ++i)
{
- zz[i + len] = mulWordAdd(len, x[i], y, zz, i);
+ zz[i + len] = mulWordAddTo(len, x[i], y, 0, zz, i);
+ }
+ }
+
+ public static void mul(int len, int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ zz[zzOff + len] = mulWord(len, x[xOff + 0], y, yOff, zz, zzOff);
+
+ for (int i = 1; i < len; ++i)
+ {
+ zz[zzOff + i + len] = mulWordAddTo(len, x[xOff + i], y, yOff, zz, zzOff + i);
}
}
@@ -237,13 +253,27 @@ public abstract class Nat
return (int)c;
}
- public static int mulWord(int len, int x, int[] y, int[] z, int zOff)
+ public static int mulWord(int len, int x, int[] y, int[] z)
{
long c = 0, xVal = x & M;
int i = 0;
do
{
c += xVal * (y[i] & M);
+ z[i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < len);
+ return (int)c;
+ }
+
+ public static int mulWord(int len, int x, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (y[yOff + i] & M);
z[zOff + i] = (int)c;
c >>>= 32;
}
@@ -251,13 +281,13 @@ public abstract class Nat
return (int)c;
}
- public static int mulWordAdd(int len, int x, int[] y, int[] z, int zOff)
+ public static int mulWordAddTo(int len, int x, int[] y, int yOff, int[] z, int zOff)
{
long c = 0, xVal = x & M;
int i = 0;
do
{
- c += xVal * (y[i] & M) + (z[zOff + i] & M);
+ c += xVal * (y[yOff + i] & M) + (z[zOff + i] & M);
z[zOff + i] = (int)c;
c >>>= 32;
}
@@ -354,6 +384,17 @@ public abstract class Nat
return c >>> 31;
}
+ public static int shiftUpBit(int len, int[] z, int zOff, int c)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ int next = z[zOff + i];
+ z[zOff + i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
public static int shiftUpBit(int len, int[] x, int c, int[] z)
{
for (int i = 0; i < len; ++i)
@@ -417,22 +458,21 @@ public abstract class Nat
for (int i = 1; i < len; ++i)
{
- c = squareWordAddExt(len, x, i, zz);
+ c = squareWordAdd(x, i, zz);
addWordExt(len, c, zz, i << 1);
}
shiftUpBit(extLen, zz, x[0] << 31);
}
- public static int squareWordAddExt(int len, int[] x, int xPos, int[] zz)
+ public static int squareWordAdd(int[] x, int xPos, int[] z)
{
- // assert xPos > 0 && xPos < len;
long c = 0, xVal = x[xPos] & M;
int i = 0;
do
{
- c += xVal * (x[i] & M) + (zz[xPos + i] & M);
- zz[xPos + i] = (int)c;
+ c += xVal * (x[i] & M) + (z[xPos + i] & M);
+ z[xPos + i] = (int)c;
c >>>= 32;
}
while (++i < xPos);
diff --git a/core/src/main/java/org/bouncycastle/math/ec/WNafUtil.java b/core/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
index f8020314..8fb86eeb 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
@@ -6,7 +6,10 @@ public abstract class WNafUtil
{
public static final String PRECOMP_NAME = "bc_wnaf";
- private static int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 };
+ private static final int[] DEFAULT_WINDOW_SIZE_CUTOFFS = new int[]{ 13, 41, 121, 337, 897, 2305 };
+
+ private static final byte[] EMPTY_BYTES = new byte[0];
+ private static final int[] EMPTY_INTS = new int[0];
public static int[] generateCompactNaf(BigInteger k)
{
@@ -14,30 +17,35 @@ public abstract class WNafUtil
{
throw new IllegalArgumentException("'k' must have bitlength < 2^16");
}
+ if (k.signum() == 0)
+ {
+ return EMPTY_INTS;
+ }
BigInteger _3k = k.shiftLeft(1).add(k);
- int digits = _3k.bitLength() - 1;
- int[] naf = new int[(digits + 1) >> 1];
+ int bits = _3k.bitLength();
+ int[] naf = new int[bits >> 1];
- int length = 0, zeroes = 0;
- for (int i = 1; i <= digits; ++i)
- {
- boolean _3kBit = _3k.testBit(i);
- boolean kBit = k.testBit(i);
+ BigInteger diff = _3k.xor(k);
- if (_3kBit == kBit)
+ int highBit = bits - 1, length = 0, zeroes = 0;
+ for (int i = 1; i < highBit; ++i)
+ {
+ if (!diff.testBit(i))
{
++zeroes;
+ continue;
}
- else
- {
- int digit = kBit ? -1 : 1;
- naf[length++] = (digit << 16) | zeroes;
- zeroes = 0;
- }
+
+ int digit = k.testBit(i) ? -1 : 1;
+ naf[length++] = (digit << 16) | zeroes;
+ zeroes = 1;
+ ++i;
}
+ naf[length++] = (1 << 16) | zeroes;
+
if (naf.length > length)
{
naf = trim(naf, length);
@@ -61,6 +69,10 @@ public abstract class WNafUtil
{
throw new IllegalArgumentException("'k' must have bitlength < 2^16");
}
+ if (k.signum() == 0)
+ {
+ return EMPTY_INTS;
+ }
int[] wnaf = new int[k.bitLength() / width + 1];
@@ -171,19 +183,29 @@ public abstract class WNafUtil
public static byte[] generateNaf(BigInteger k)
{
+ if (k.signum() == 0)
+ {
+ return EMPTY_BYTES;
+ }
+
BigInteger _3k = k.shiftLeft(1).add(k);
int digits = _3k.bitLength() - 1;
byte[] naf = new byte[digits];
- for (int i = 1; i <= digits; ++i)
- {
- boolean _3kBit = _3k.testBit(i);
- boolean kBit = k.testBit(i);
+ BigInteger diff = _3k.xor(k);
- naf[i - 1] = (byte)(_3kBit == kBit ? 0 : kBit ? -1 : 1);
+ for (int i = 1; i < digits; ++i)
+ {
+ if (diff.testBit(i))
+ {
+ naf[i - 1] = (byte)(k.testBit(i) ? -1 : 1);
+ ++i;
+ }
}
+ naf[digits - 1] = 1;
+
return naf;
}
@@ -210,6 +232,10 @@ public abstract class WNafUtil
{
throw new IllegalArgumentException("'width' must be in the range [2, 8]");
}
+ if (k.signum() == 0)
+ {
+ return EMPTY_BYTES;
+ }
byte[] wnaf = new byte[k.bitLength() + 1];
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java
index 6351a64c..0ef17fcb 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java
@@ -82,31 +82,69 @@ public abstract class Nat192
return (int)c;
}
- public static int addToExt(int[] x, int xOff, int[] zz, int zzOff)
+ public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[xOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addToEachOther(int[] u, int uOff, int[] v, int vOff)
{
- // assert zzOff <= 6;
long c = 0;
- c += (x[xOff + 0] & M) + (zz[zzOff + 0] & M);
- zz[zzOff + 0] = (int)c;
+ c += (u[uOff + 0] & M) + (v[vOff + 0] & M);
+ u[uOff + 0] = (int)c;
+ v[vOff + 0] = (int)c;
c >>>= 32;
- c += (x[xOff + 1] & M) + (zz[zzOff + 1] & M);
- zz[zzOff + 1] = (int)c;
+ c += (u[uOff + 1] & M) + (v[vOff + 1] & M);
+ u[uOff + 1] = (int)c;
+ v[vOff + 1] = (int)c;
c >>>= 32;
- c += (x[xOff + 2] & M) + (zz[zzOff + 2] & M);
- zz[zzOff + 2] = (int)c;
+ c += (u[uOff + 2] & M) + (v[vOff + 2] & M);
+ u[uOff + 2] = (int)c;
+ v[vOff + 2] = (int)c;
c >>>= 32;
- c += (x[xOff + 3] & M) + (zz[zzOff + 3] & M);
- zz[zzOff + 3] = (int)c;
+ c += (u[uOff + 3] & M) + (v[vOff + 3] & M);
+ u[uOff + 3] = (int)c;
+ v[vOff + 3] = (int)c;
c >>>= 32;
- c += (x[xOff + 4] & M) + (zz[zzOff + 4] & M);
- zz[zzOff + 4] = (int)c;
+ c += (u[uOff + 4] & M) + (v[vOff + 4] & M);
+ u[uOff + 4] = (int)c;
+ v[vOff + 4] = (int)c;
c >>>= 32;
- c += (x[xOff + 5] & M) + (zz[zzOff + 5] & M);
- zz[zzOff + 5] = (int)c;
+ c += (u[uOff + 5] & M) + (v[vOff + 5] & M);
+ u[uOff + 5] = (int)c;
+ v[vOff + 5] = (int)c;
c >>>= 32;
return (int)c;
}
+ public static int addWord(int x, int[] z, int zOff)
+ {
+ // assert zzOff <= 5;
+ long c = (x & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : inc(z, zOff + 1);
+ }
+
public static int addWordExt(int x, int[] zz, int zzOff)
{
// assert zzOff <= 11;
@@ -116,6 +154,16 @@ public abstract class Nat192
return c == 0 ? 0 : incExt(zz, zzOff + 1);
}
+ public static void copy(int[] x, int[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ z[3] = x[3];
+ z[4] = x[4];
+ z[5] = x[5];
+ }
+
public static int[] create()
{
return new int[6];
@@ -139,6 +187,45 @@ public abstract class Nat192
return -1;
}
+ public static int decExt(int[] z, int zOff)
+ {
+ // assert zOff <= 12;
+ for (int i = zOff; i < 12; ++i)
+ {
+ if (--z[i] != -1)
+ {
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ boolean pos = gte(x, xOff, y, yOff);
+ if (pos)
+ {
+ sub(x, xOff, y, yOff, z, zOff);
+ }
+ else
+ {
+ sub(y, yOff, x, xOff, z, zOff);
+ }
+ return pos;
+ }
+
+ public static boolean eq(int[] x, int[] y)
+ {
+ for (int i = 5; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static int[] fromBigInteger(BigInteger x)
{
if (x.signum() < 0 || x.bitLength() > 192)
@@ -185,6 +272,20 @@ public abstract class Nat192
return true;
}
+ public static boolean gte(int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = 5; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
public static boolean gteExt(int[] xx, int[] yy)
{
for (int i = 11; i >= 0; --i)
@@ -322,39 +423,94 @@ public abstract class Nat192
}
}
- public static long mul33AddExt(int w, int[] xx, int xxOff, int[] yy, int yyOff, int[] zz, int zzOff)
+ public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
{
- // assert x >>> 31 == 0;
- // assert xxOff <= 6;
- // assert yyOff <= 6;
- // assert zzOff <= 6;
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+
+ {
+ long c = 0, x_0 = x[xOff + 0] & M;
+ c += x_0 * y_0;
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 6] = (int)c;
+ }
+
+ for (int i = 1; i < 6; ++i)
+ {
+ ++zzOff;
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 6] = (int)c;
+ }
+ }
+
+ public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ // assert w >>> 31 == 0;
long c = 0, wVal = w & M;
- long xx00 = xx[xxOff + 0] & M;
- c += wVal * xx00 + (yy[yyOff + 0] & M);
- zz[zzOff + 0] = (int)c;
+ long x0 = x[xOff + 0] & M;
+ c += wVal * x0 + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
c >>>= 32;
- long xx01 = xx[xxOff + 1] & M;
- c += wVal * xx01 + xx00 + (yy[yyOff + 1] & M);
- zz[zzOff + 1] = (int)c;
+ long x1 = x[xOff + 1] & M;
+ c += wVal * x1 + x0 + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
c >>>= 32;
- long xx02 = xx[xxOff + 2] & M;
- c += wVal * xx02 + xx01 + (yy[yyOff + 2] & M);
- zz[zzOff + 2] = (int)c;
+ long x2 = x[xOff + 2] & M;
+ c += wVal * x2 + x1 + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
c >>>= 32;
- long xx03 = xx[xxOff + 3] & M;
- c += wVal * xx03 + xx02 + (yy[yyOff + 3] & M);
- zz[zzOff + 3] = (int)c;
+ long x3 = x[xOff + 3] & M;
+ c += wVal * x3 + x2 + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
c >>>= 32;
- long xx04 = xx[xxOff + 4] & M;
- c += wVal * xx04 + xx03 + (yy[yyOff + 4] & M);
- zz[zzOff + 4] = (int)c;
+ long x4 = x[xOff + 4] & M;
+ c += wVal * x4 + x3 + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
c >>>= 32;
- long xx05 = xx[xxOff + 5] & M;
- c += wVal * xx05 + xx04 + (yy[yyOff + 5] & M);
- zz[zzOff + 5] = (int)c;
+ long x5 = x[xOff + 5] & M;
+ c += wVal * x5 + x4 + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
c >>>= 32;
- c += xx05;
+ c += x5;
return c;
}
@@ -407,6 +563,24 @@ public abstract class Nat192
return c == 0 ? 0 : inc(z, zOff + 4);
}
+ public static int mul33WordAdd(int x, int y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 3;
+
+ long c = 0, xVal = x & M, yVal = y & M;
+ c += yVal * xVal + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += yVal + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : inc(z, zOff + 3);
+ }
+
public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
{
// assert zOff <= 3;
@@ -423,15 +597,14 @@ public abstract class Nat192
return c == 0 ? 0 : inc(z, zOff + 3);
}
- public static int mulWordExt(int x, int[] y, int[] zz, int zzOff)
+ public static int mulWord(int x, int[] y, int[] z, int zOff)
{
- // assert zzOff <= 6;
long c = 0, xVal = x & M;
int i = 0;
do
{
c += xVal * (y[i] & M);
- zz[zzOff + i] = (int)c;
+ z[zOff + i] = (int)c;
c >>>= 32;
}
while (++i < 6);
@@ -498,6 +671,17 @@ public abstract class Nat192
return c >>> 31;
}
+ public static int shiftUpBit(int[] x, int xOff, int xLen, int c)
+ {
+ for (int i = 0; i < xLen; ++i)
+ {
+ int next = x[xOff + i];
+ x[xOff + i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
public static int shiftUpBit(int[] x, int c, int[] z)
{
for (int i = 0; i < 6; ++i)
@@ -604,19 +788,99 @@ public abstract class Nat192
shiftUpBit(zz, 12, (int)x_0 << 31);
}
- public static int squareWordAddExt(int[] x, int xPos, int[] zz)
+ public static void square(int[] x, int xOff, int[] zz, int zzOff)
{
- // assert xPos > 0 && xPos < 6;
- long c = 0, xVal = x[xPos] & M;
- int i = 0;
- do
+ long x_0 = x[xOff + 0] & M;
+ long zz_1;
+
{
- c += xVal * (x[i] & M) + (zz[xPos + i] & M);
- zz[xPos + i] = (int)c;
- c >>>= 32;
+ int c = 0, i = 5, j = 12;
+ do
+ {
+ long xVal = (x[xOff + i--] & M);
+ long p = xVal * xVal;
+ zz[zzOff + --j] = (c << 31) | (int)(p >>> 33);
+ zz[zzOff + --j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[zzOff + 0] = (int)(p >>> 1);
+ }
}
- while (++i < xPos);
- return (int)c;
+
+ long x_1 = x[xOff + 1] & M;
+ long zz_2 = zz[zzOff + 2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ zz[zzOff + 1] = (int)zz_1;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[xOff + 2] & M;
+ long zz_3 = zz[zzOff + 3] & M;
+ long zz_4 = zz[zzOff + 4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ zz[zzOff + 2] = (int)zz_2;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[xOff + 3] & M;
+ long zz_5 = zz[zzOff + 5] & M;
+ long zz_6 = zz[zzOff + 6] & M;
+ {
+ zz_3 += x_3 * x_0;
+ zz[zzOff + 3] = (int)zz_3;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[xOff + 4] & M;
+ long zz_7 = zz[zzOff + 7] & M;
+ long zz_8 = zz[zzOff + 8] & M;
+ {
+ zz_4 += x_4 * x_0;
+ zz[zzOff + 4] = (int)zz_4;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[xOff + 5] & M;
+ long zz_9 = zz[zzOff + 9] & M;
+ long zz_10 = zz[zzOff + 10] & M;
+ {
+ zz_5 += x_5 * x_0;
+ zz[zzOff + 5] = (int)zz_5;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_10 += zz_9 >>> 32;
+ }
+
+ zz[zzOff + 6] = (int)zz_6;
+ zz[zzOff + 7] = (int)zz_7;
+ zz[zzOff + 8] = (int)zz_8;
+ zz[zzOff + 9] = (int)zz_9;
+ zz[zzOff + 10] = (int)zz_10;
+ zz[zzOff + 11] += (int)(zz_10 >>> 32);
+
+ shiftUpBit(zz, zzOff, 12, (int)x_0 << 31);
}
public static int sub(int[] x, int[] y, int[] z)
@@ -643,6 +907,30 @@ public abstract class Nat192
return (int)c;
}
+ public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) - (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 1] & M) - (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 2] & M) - (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 3] & M) - (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 4] & M) - (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 5] & M) - (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
public static int subBothFrom(int[] x, int[] y, int[] z)
{
long c = 0;
@@ -717,6 +1005,24 @@ public abstract class Nat192
return (int)c;
}
+ public static int subWord(int x, int[] z, int zOff)
+ {
+ // assert zOff <= 5;
+ long c = (z[zOff + 0] & M) - (x & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : dec(z, zOff + 1);
+ }
+
+ public static int subWordExt(int x, int[] zz, int zzOff)
+ {
+ // assert zzOff <= 11;
+ long c = (zz[zzOff + 0] & M) - (x & M);
+ zz[zzOff + 0] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decExt(zz, zzOff + 1);
+ }
+
public static BigInteger toBigInteger(int[] x)
{
byte[] bs = new byte[24];
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat224.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat224.java
new file mode 100644
index 00000000..9763aa41
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat224.java
@@ -0,0 +1,1284 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.crypto.util.Pack;
+
+public abstract class Nat224
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ public static int add(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (y[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (y[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (y[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (y[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (y[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (y[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (y[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int add(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addBothTo(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) + (y[0] & M) + (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += (x[1] & M) + (y[1] & M) + (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += (x[2] & M) + (y[2] & M) + (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += (x[3] & M) + (y[3] & M) + (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += (x[4] & M) + (y[4] & M) + (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += (x[5] & M) + (y[5] & M) + (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += (x[6] & M) + (y[6] & M) + (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addBothTo(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) + (y[yOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (y[yOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (y[yOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (y[yOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (y[yOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (y[yOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (y[yOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ // TODO Re-write to allow full range for x?
+ public static int addDWord(long x, int[] z, int zOff)
+ {
+ // assert zOff <= 5;
+ long c = x;
+ c += (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : inc(z, zOff + 2);
+ }
+
+ public static int addExt(int[] xx, int[] yy, int[] zz)
+ {
+ long c = 0;
+ for (int i = 0; i < 14; ++i)
+ {
+ c += (xx[i] & M) + (yy[i] & M);
+ zz[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn)
+ {
+ long c = cIn & M;
+ c += (x[xOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += (x[xOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addToEachOther(int[] u, int uOff, int[] v, int vOff)
+ {
+ long c = 0;
+ c += (u[uOff + 0] & M) + (v[vOff + 0] & M);
+ u[uOff + 0] = (int)c;
+ v[vOff + 0] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 1] & M) + (v[vOff + 1] & M);
+ u[uOff + 1] = (int)c;
+ v[vOff + 1] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 2] & M) + (v[vOff + 2] & M);
+ u[uOff + 2] = (int)c;
+ v[vOff + 2] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 3] & M) + (v[vOff + 3] & M);
+ u[uOff + 3] = (int)c;
+ v[vOff + 3] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 4] & M) + (v[vOff + 4] & M);
+ u[uOff + 4] = (int)c;
+ v[vOff + 4] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 5] & M) + (v[vOff + 5] & M);
+ u[uOff + 5] = (int)c;
+ v[vOff + 5] = (int)c;
+ c >>>= 32;
+ c += (u[uOff + 6] & M) + (v[vOff + 6] & M);
+ u[uOff + 6] = (int)c;
+ v[vOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int addWord(int x, int[] z, int zOff)
+ {
+ // assert zzOff <= 6;
+ long c = (x & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : inc(z, zOff + 1);
+ }
+
+ public static int addWordExt(int x, int[] zz, int zzOff)
+ {
+ // assert zzOff <= 13;
+ long c = (x & M) + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : incExt(zz, zzOff + 1);
+ }
+
+ public static void copy(int[] x, int[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ z[3] = x[3];
+ z[4] = x[4];
+ z[5] = x[5];
+ z[6] = x[6];
+ }
+
+ public static int[] create()
+ {
+ return new int[7];
+ }
+
+ public static int[] createExt()
+ {
+ return new int[14];
+ }
+
+ public static int dec(int[] z, int zOff)
+ {
+ // assert zOff <= 7;
+ for (int i = zOff; i < 7; ++i)
+ {
+ if (--z[i] != -1)
+ {
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ public static int decExt(int[] zz, int zzOff)
+ {
+ // assert zOff <= 14;
+ for (int i = zzOff; i < 14; ++i)
+ {
+ if (--zz[i] != -1)
+ {
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ boolean pos = gte(x, xOff, y, yOff);
+ if (pos)
+ {
+ sub(x, xOff, y, yOff, z, zOff);
+ }
+ else
+ {
+ sub(y, yOff, x, xOff, z, zOff);
+ }
+ return pos;
+ }
+
+ public static boolean eq(int[] x, int[] y)
+ {
+ for (int i = 6; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > 224)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ int[] z = create();
+ int i = 0;
+ while (x.signum() != 0)
+ {
+ z[i++] = x.intValue();
+ x = x.shiftRight(32);
+ }
+ return z;
+ }
+
+ public static int getBit(int[] x, int bit)
+ {
+ if (bit == 0)
+ {
+ return x[0] & 1;
+ }
+ int w = bit >> 5;
+ if (w < 0 || w >= 7)
+ {
+ return 0;
+ }
+ int b = bit & 31;
+ return (x[w] >>> b) & 1;
+ }
+
+ public static boolean gte(int[] x, int[] y)
+ {
+ for (int i = 6; i >= 0; --i)
+ {
+ int x_i = x[i] ^ Integer.MIN_VALUE;
+ int y_i = y[i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean gte(int[] x, int xOff, int[] y, int yOff)
+ {
+ for (int i = 6; i >= 0; --i)
+ {
+ int x_i = x[xOff + i] ^ Integer.MIN_VALUE;
+ int y_i = y[yOff + i] ^ Integer.MIN_VALUE;
+ if (x_i < y_i)
+ return false;
+ if (x_i > y_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static boolean gteExt(int[] xx, int[] yy)
+ {
+ for (int i = 13; i >= 0; --i)
+ {
+ int xx_i = xx[i] ^ Integer.MIN_VALUE;
+ int yy_i = yy[i] ^ Integer.MIN_VALUE;
+ if (xx_i < yy_i)
+ return false;
+ if (xx_i > yy_i)
+ return true;
+ }
+ return true;
+ }
+
+ public static int inc(int[] z, int zOff)
+ {
+ // assert zOff <= 7;
+ for (int i = zOff; i < 7; ++i)
+ {
+ if (++z[i] != 0)
+ {
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ public static int incExt(int[] zz, int zzOff)
+ {
+ // assert zzOff <= 14;
+ for (int i = zzOff; i < 14; ++i)
+ {
+ if (++zz[i] != 0)
+ {
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ public static boolean isOne(int[] x)
+ {
+ if (x[0] != 1)
+ {
+ return false;
+ }
+ for (int i = 1; i < 7; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isZero(int[] x)
+ {
+ for (int i = 0; i < 7; ++i)
+ {
+ if (x[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean isZeroExt(int[] xx)
+ {
+ for (int i = 0; i < 14; ++i)
+ {
+ if (xx[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void mul(int[] x, int[] y, int[] zz)
+ {
+ long y_0 = y[0] & M;
+ long y_1 = y[1] & M;
+ long y_2 = y[2] & M;
+ long y_3 = y[3] & M;
+ long y_4 = y[4] & M;
+ long y_5 = y[5] & M;
+ long y_6 = y[6] & M;
+
+ {
+ long c = 0, x_0 = x[0] & M;
+ c += x_0 * y_0;
+ zz[0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[5] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_6;
+ zz[6] = (int)c;
+ c >>>= 32;
+ zz[7] = (int)c;
+ }
+
+ for (int i = 1; i < 7; ++i)
+ {
+ long c = 0, x_i = x[i] & M;
+ c += x_i * y_0 + (zz[i + 0] & M);
+ zz[i + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[i + 1] & M);
+ zz[i + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[i + 2] & M);
+ zz[i + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[i + 3] & M);
+ zz[i + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[i + 4] & M);
+ zz[i + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[i + 5] & M);
+ zz[i + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[i + 6] & M);
+ zz[i + 6] = (int)c;
+ c >>>= 32;
+ zz[i + 7] = (int)c;
+ }
+ }
+
+ public static void mul(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+ long y_6 = y[yOff + 6] & M;
+
+ {
+ long c = 0, x_0 = x[xOff + 0] & M;
+ c += x_0 * y_0;
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_1;
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_2;
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_3;
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_4;
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_5;
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_0 * y_6;
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 7] = (int)c;
+ }
+
+ for (int i = 1; i < 7; ++i)
+ {
+ ++zzOff;
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+ zz[zzOff + 7] = (int)c;
+ }
+ }
+
+ public static int mulAdd(int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff)
+ {
+ long y_0 = y[yOff + 0] & M;
+ long y_1 = y[yOff + 1] & M;
+ long y_2 = y[yOff + 2] & M;
+ long y_3 = y[yOff + 3] & M;
+ long y_4 = y[yOff + 4] & M;
+ long y_5 = y[yOff + 5] & M;
+ long y_6 = y[yOff + 6] & M;
+
+ long zc = 0;
+ for (int i = 0; i < 7; ++i)
+ {
+ long c = 0, x_i = x[xOff + i] & M;
+ c += x_i * y_0 + (zz[zzOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>>= 32;
+ c += x_i * y_1 + (zz[zzOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>>= 32;
+ c += x_i * y_2 + (zz[zzOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>>= 32;
+ c += x_i * y_3 + (zz[zzOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>>= 32;
+ c += x_i * y_4 + (zz[zzOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>>= 32;
+ c += x_i * y_5 + (zz[zzOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>>= 32;
+ c += x_i * y_6 + (zz[zzOff + 6] & M);
+ zz[zzOff + 6] = (int)c;
+ c >>>= 32;
+ c += zc + (zz[zzOff + 7] & M);
+ zz[zzOff + 7] = (int)c;
+ zc = c >>> 32;
+ ++zzOff;
+ }
+ return (int)zc;
+ }
+
+ public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ // assert w >>> 31 == 0;
+
+ long c = 0, wVal = w & M;
+ long x0 = x[xOff + 0] & M;
+ c += wVal * x0 + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ long x1 = x[xOff + 1] & M;
+ c += wVal * x1 + x0 + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ long x2 = x[xOff + 2] & M;
+ c += wVal * x2 + x1 + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ long x3 = x[xOff + 3] & M;
+ c += wVal * x3 + x2 + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ long x4 = x[xOff + 4] & M;
+ c += wVal * x4 + x3 + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ long x5 = x[xOff + 5] & M;
+ c += wVal * x5 + x4 + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ long x6 = x[xOff + 6] & M;
+ c += wVal * x6 + x5 + (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ c += x6;
+ return c;
+ }
+
+ public static int mulByWord(int x, int[] z)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (z[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mulByWordAddTo(int x, int[] y, int[] z)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (z[0] & M) + (y[0] & M);
+ z[0] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[1] & M) + (y[1] & M);
+ z[1] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[2] & M) + (y[2] & M);
+ z[2] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[3] & M) + (y[3] & M);
+ z[3] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[4] & M) + (y[4] & M);
+ z[4] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[5] & M) + (y[5] & M);
+ z[5] = (int)c;
+ c >>>= 32;
+ c += xVal * (z[6] & M) + (y[6] & M);
+ z[6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mulWordAddTo(int x, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ c += xVal * (y[yOff + 0] & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 1] & M) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 2] & M) + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 3] & M) + (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 4] & M) + (z[zOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 5] & M) + (z[zOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>>= 32;
+ c += xVal * (y[yOff + 6] & M) + (z[zOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>>= 32;
+ return (int)c;
+ }
+
+ public static int mul33DWordAdd(int x, long y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 3;
+
+ long c = 0, xVal = x & M;
+ long y00 = y & M;
+ c += xVal * y00 + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ long y01 = y >>> 32;
+ c += xVal * y01 + y00 + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += y01 + (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : inc(z, zOff + 4);
+ }
+
+ public static int mul33WordAdd(int x, int y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 4;
+
+ long c = 0, xVal = x & M, yVal = y & M;
+ c += yVal * xVal + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += yVal + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : inc(z, zOff + 3);
+ }
+
+ public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
+ {
+ // assert zOff <= 4;
+ long c = 0, xVal = x & M;
+ c += xVal * (y & M) + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += xVal * (y >>> 32) + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : inc(z, zOff + 3);
+ }
+
+ public static int mulWord(int x, int[] y, int[] z, int zOff)
+ {
+ long c = 0, xVal = x & M;
+ int i = 0;
+ do
+ {
+ c += xVal * (y[i] & M);
+ z[zOff + i] = (int)c;
+ c >>>= 32;
+ }
+ while (++i < 7);
+ return (int)c;
+ }
+
+ public static int shiftDownBit(int[] x, int xLen, int c)
+ {
+ int i = xLen;
+ while (--i >= 0)
+ {
+ int next = x[i];
+ x[i] = (next >>> 1) | (c << 31);
+ c = next;
+ }
+ return c << 31;
+ }
+
+ public static int shiftDownBit(int[] x, int c, int[] z)
+ {
+ int i = 7;
+ while (--i >= 0)
+ {
+ int next = x[i];
+ z[i] = (next >>> 1) | (c << 31);
+ c = next;
+ }
+ return c << 31;
+ }
+
+ public static int shiftDownBits(int[] x, int xLen, int bits, int c)
+ {
+// assert bits > 0 && bits < 32;
+ int i = xLen;
+ while (--i >= 0)
+ {
+ int next = x[i];
+ x[i] = (next >>> bits) | (c << -bits);
+ c = next;
+ }
+ return c << -bits;
+ }
+
+ public static int shiftDownWord(int[] x, int xLen, int c)
+ {
+ int i = xLen;
+ while (--i >= 0)
+ {
+ int next = x[i];
+ x[i] = c;
+ c = next;
+ }
+ return c;
+ }
+
+ public static int shiftUpBit(int[] x, int xLen, int c)
+ {
+ for (int i = 0; i < xLen; ++i)
+ {
+ int next = x[i];
+ x[i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
+ public static int shiftUpBit(int[] x, int xOff, int xLen, int c)
+ {
+ for (int i = 0; i < xLen; ++i)
+ {
+ int next = x[xOff + i];
+ x[xOff + i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
+ public static int shiftUpBit(int[] x, int c, int[] z)
+ {
+ for (int i = 0; i < 7; ++i)
+ {
+ int next = x[i];
+ z[i] = (next << 1) | (c >>> 31);
+ c = next;
+ }
+ return c >>> 31;
+ }
+
+ public static void square(int[] x, int[] zz)
+ {
+ long x_0 = x[0] & M;
+ long zz_1;
+
+ {
+ int c = 0, i = 6, j = 14;
+ do
+ {
+ long xVal = (x[i--] & M);
+ long p = xVal * xVal;
+ zz[--j] = (c << 31) | (int)(p >>> 33);
+ zz[--j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[0] = (int)(p >>> 1);
+ }
+ }
+
+ long x_1 = x[1] & M;
+ long zz_2 = zz[2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ zz[1] = (int)zz_1;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[2] & M;
+ long zz_3 = zz[3] & M;
+ long zz_4 = zz[4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ zz[2] = (int)zz_2;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[3] & M;
+ long zz_5 = zz[5] & M;
+ long zz_6 = zz[6] & M;
+ {
+ zz_3 += x_3 * x_0;
+ zz[3] = (int)zz_3;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[4] & M;
+ long zz_7 = zz[7] & M;
+ long zz_8 = zz[8] & M;
+ {
+ zz_4 += x_4 * x_0;
+ zz[4] = (int)zz_4;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[5] & M;
+ long zz_9 = zz[9] & M;
+ long zz_10 = zz[10] & M;
+ {
+ zz_5 += x_5 * x_0;
+ zz[5] = (int)zz_5;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_6 &= M;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_8 &= M;
+ zz_10 += zz_9 >>> 32;
+ zz_9 &= M;
+ }
+
+ long x_6 = x[6] & M;
+ long zz_11 = zz[11] & M;
+ long zz_12 = zz[12] & M;
+ {
+ zz_6 += x_6 * x_0;
+ zz[6] = (int)zz_6;
+ zz_7 += (zz_6 >>> 32) + x_6 * x_1;
+ zz_8 += (zz_7 >>> 32) + x_6 * x_2;
+ zz_9 += (zz_8 >>> 32) + x_6 * x_3;
+ zz_10 += (zz_9 >>> 32) + x_6 * x_4;
+ zz_11 += (zz_10 >>> 32) + x_6 * x_5;
+ zz_12 += zz_11 >>> 32;
+ }
+
+ zz[7] = (int)zz_7;
+ zz[8] = (int)zz_8;
+ zz[9] = (int)zz_9;
+ zz[10] = (int)zz_10;
+ zz[11] = (int)zz_11;
+ zz[12] = (int)zz_12;
+ zz[13] += (int)(zz_12 >>> 32);
+
+ shiftUpBit(zz, 14, (int)x_0 << 31);
+ }
+
+ public static void square(int[] x, int xOff, int[] zz, int zzOff)
+ {
+ long x_0 = x[xOff + 0] & M;
+ long zz_1;
+
+ {
+ int c = 0, i = 6, j = 14;
+ do
+ {
+ long xVal = (x[xOff + i--] & M);
+ long p = xVal * xVal;
+ zz[zzOff + --j] = (c << 31) | (int)(p >>> 33);
+ zz[zzOff + --j] = (int)(p >>> 1);
+ c = (int)p;
+ }
+ while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[zzOff + 0] = (int)(p >>> 1);
+ }
+ }
+
+ long x_1 = x[xOff + 1] & M;
+ long zz_2 = zz[zzOff + 2] & M;
+
+ {
+ zz_1 += x_1 * x_0;
+ zz[zzOff + 1] = (int)zz_1;
+ zz_2 += zz_1 >>> 32;
+ }
+
+ long x_2 = x[xOff + 2] & M;
+ long zz_3 = zz[zzOff + 3] & M;
+ long zz_4 = zz[zzOff + 4] & M;
+ {
+ zz_2 += x_2 * x_0;
+ zz[zzOff + 2] = (int)zz_2;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
+ }
+
+ long x_3 = x[xOff + 3] & M;
+ long zz_5 = zz[zzOff + 5] & M;
+ long zz_6 = zz[zzOff + 6] & M;
+ {
+ zz_3 += x_3 * x_0;
+ zz[zzOff + 3] = (int)zz_3;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
+ }
+
+ long x_4 = x[xOff + 4] & M;
+ long zz_7 = zz[zzOff + 7] & M;
+ long zz_8 = zz[zzOff + 8] & M;
+ {
+ zz_4 += x_4 * x_0;
+ zz[zzOff + 4] = (int)zz_4;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
+ }
+
+ long x_5 = x[xOff + 5] & M;
+ long zz_9 = zz[zzOff + 9] & M;
+ long zz_10 = zz[zzOff + 10] & M;
+ {
+ zz_5 += x_5 * x_0;
+ zz[zzOff + 5] = (int)zz_5;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_6 &= M;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_8 &= M;
+ zz_10 += zz_9 >>> 32;
+ zz_9 &= M;
+ }
+
+ long x_6 = x[xOff + 6] & M;
+ long zz_11 = zz[zzOff + 11] & M;
+ long zz_12 = zz[zzOff + 12] & M;
+ {
+ zz_6 += x_6 * x_0;
+ zz[zzOff + 6] = (int)zz_6;
+ zz_7 += (zz_6 >>> 32) + x_6 * x_1;
+ zz_8 += (zz_7 >>> 32) + x_6 * x_2;
+ zz_9 += (zz_8 >>> 32) + x_6 * x_3;
+ zz_10 += (zz_9 >>> 32) + x_6 * x_4;
+ zz_11 += (zz_10 >>> 32) + x_6 * x_5;
+ zz_12 += zz_11 >>> 32;
+ }
+
+ zz[zzOff + 7] = (int)zz_7;
+ zz[zzOff + 8] = (int)zz_8;
+ zz[zzOff + 9] = (int)zz_9;
+ zz[zzOff + 10] = (int)zz_10;
+ zz[zzOff + 11] = (int)zz_11;
+ zz[zzOff + 12] = (int)zz_12;
+ zz[zzOff + 13] += (int)(zz_12 >>> 32);
+
+ shiftUpBit(zz, zzOff, 14, (int)x_0 << 31);
+ }
+
+ public static int sub(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (x[0] & M) - (y[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (x[1] & M) - (y[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (x[2] & M) - (y[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (x[3] & M) - (y[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (x[4] & M) - (y[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (x[5] & M) - (y[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (x[6] & M) - (y[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int sub(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
+ {
+ long c = 0;
+ c += (x[xOff + 0] & M) - (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 1] & M) - (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 2] & M) - (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 3] & M) - (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 4] & M) - (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 5] & M) - (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
+ c >>= 32;
+ c += (x[xOff + 6] & M) - (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subBothFrom(int[] x, int[] y, int[] z)
+ {
+ long c = 0;
+ c += (z[0] & M) - (x[0] & M) - (y[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M) - (x[1] & M) - (y[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ c += (z[2] & M) - (x[2] & M) - (y[2] & M);
+ z[2] = (int)c;
+ c >>= 32;
+ c += (z[3] & M) - (x[3] & M) - (y[3] & M);
+ z[3] = (int)c;
+ c >>= 32;
+ c += (z[4] & M) - (x[4] & M) - (y[4] & M);
+ z[4] = (int)c;
+ c >>= 32;
+ c += (z[5] & M) - (x[5] & M) - (y[5] & M);
+ z[5] = (int)c;
+ c >>= 32;
+ c += (z[6] & M) - (x[6] & M) - (y[6] & M);
+ z[6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ // TODO Re-write to allow full range for x?
+ public static int subDWord(long x, int[] z)
+ {
+ long c = -x;
+ c += (z[0] & M);
+ z[0] = (int)c;
+ c >>= 32;
+ c += (z[1] & M);
+ z[1] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : dec(z, 2);
+ }
+
+ public static int subExt(int[] xx, int[] yy, int[] zz)
+ {
+ long c = 0;
+ for (int i = 0; i < 14; ++i)
+ {
+ c += (xx[i] & M) - (yy[i] & M);
+ zz[i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int subFromExt(int[] x, int xOff, int[] zz, int zzOff)
+ {
+ // assert zzOff <= 7;
+ long c = 0;
+ c += (zz[zzOff + 0] & M) - (x[xOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 1] & M) - (x[xOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 2] & M) - (x[xOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 3] & M) - (x[xOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 4] & M) - (x[xOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 5] & M) - (x[xOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 6] & M) - (x[xOff + 6] & M);
+ zz[zzOff + 6] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
+ public static int subWord(int x, int[] z, int zOff)
+ {
+ // assert zOff <= 6;
+ long c = (z[zOff + 0] & M) - (x & M);
+ z[zOff + 0] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : dec(z, zOff + 1);
+ }
+
+ public static int subWordExt(int x, int[] zz, int zzOff)
+ {
+ // assert zzOff <= 13;
+ long c = (zz[zzOff + 0] & M) - (x & M);
+ zz[zzOff + 0] = (int)c;
+ c >>= 32;
+ return c == 0 ? 0 : decExt(zz, zzOff + 1);
+ }
+
+ public static BigInteger toBigInteger(int[] x)
+ {
+ byte[] bs = new byte[28];
+ for (int i = 0; i < 7; ++i)
+ {
+ int x_i = x[i];
+ if (x_i != 0)
+ {
+ Pack.intToBigEndian(x_i, bs, (6 - i) << 2);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
+ public static void zero(int[] z)
+ {
+ z[0] = 0;
+ z[1] = 0;
+ z[2] = 0;
+ z[3] = 0;
+ z[4] = 0;
+ z[5] = 0;
+ z[6] = 0;
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java
index 6a228fdb..86867872 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java
@@ -302,6 +302,18 @@ public abstract class Nat256
return pos;
}
+ public static boolean eq(int[] x, int[] y)
+ {
+ for (int i = 7; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static int[] fromBigInteger(BigInteger x)
{
if (x.signum() < 0 || x.bitLength() > 256)
@@ -632,47 +644,44 @@ public abstract class Nat256
return (int)zc;
}
- public static long mul33AddExt(int w, int[] xx, int xxOff, int[] yy, int yyOff, int[] zz, int zzOff)
+ public static long mul33Add(int w, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
{
- // assert x >>> 31 == 0;
- // assert xxOff <= 8;
- // assert yyOff <= 8;
- // assert zzOff <= 8;
+ // assert w >>> 31 == 0;
long c = 0, wVal = w & M;
- long xx00 = xx[xxOff + 0] & M;
- c += wVal * xx00 + (yy[yyOff + 0] & M);
- zz[zzOff + 0] = (int)c;
+ long x0 = x[xOff + 0] & M;
+ c += wVal * x0 + (y[yOff + 0] & M);
+ z[zOff + 0] = (int)c;
c >>>= 32;
- long xx01 = xx[xxOff + 1] & M;
- c += wVal * xx01 + xx00 + (yy[yyOff + 1] & M);
- zz[zzOff + 1] = (int)c;
+ long x1 = x[xOff + 1] & M;
+ c += wVal * x1 + x0 + (y[yOff + 1] & M);
+ z[zOff + 1] = (int)c;
c >>>= 32;
- long xx02 = xx[xxOff + 2] & M;
- c += wVal * xx02 + xx01 + (yy[yyOff + 2] & M);
- zz[zzOff + 2] = (int)c;
+ long x2 = x[xOff + 2] & M;
+ c += wVal * x2 + x1 + (y[yOff + 2] & M);
+ z[zOff + 2] = (int)c;
c >>>= 32;
- long xx03 = xx[xxOff + 3] & M;
- c += wVal * xx03 + xx02 + (yy[yyOff + 3] & M);
- zz[zzOff + 3] = (int)c;
+ long x3 = x[xOff + 3] & M;
+ c += wVal * x3 + x2 + (y[yOff + 3] & M);
+ z[zOff + 3] = (int)c;
c >>>= 32;
- long xx04 = xx[xxOff + 4] & M;
- c += wVal * xx04 + xx03 + (yy[yyOff + 4] & M);
- zz[zzOff + 4] = (int)c;
+ long x4 = x[xOff + 4] & M;
+ c += wVal * x4 + x3 + (y[yOff + 4] & M);
+ z[zOff + 4] = (int)c;
c >>>= 32;
- long xx05 = xx[xxOff + 5] & M;
- c += wVal * xx05 + xx04 + (yy[yyOff + 5] & M);
- zz[zzOff + 5] = (int)c;
+ long x5 = x[xOff + 5] & M;
+ c += wVal * x5 + x4 + (y[yOff + 5] & M);
+ z[zOff + 5] = (int)c;
c >>>= 32;
- long xx06 = xx[xxOff + 6] & M;
- c += wVal * xx06 + xx05 + (yy[yyOff + 6] & M);
- zz[zzOff + 6] = (int)c;
+ long x6 = x[xOff + 6] & M;
+ c += wVal * x6 + x5 + (y[yOff + 6] & M);
+ z[zOff + 6] = (int)c;
c >>>= 32;
- long xx07 = xx[xxOff + 7] & M;
- c += wVal * xx07 + xx06 + (yy[yyOff + 7] & M);
- zz[zzOff + 7] = (int)c;
+ long x7 = x[xOff + 7] & M;
+ c += wVal * x7 + x6 + (y[yOff + 7] & M);
+ z[zOff + 7] = (int)c;
c >>>= 32;
- c += xx07;
+ c += x7;
return c;
}
@@ -789,6 +798,24 @@ public abstract class Nat256
return c == 0 ? 0 : inc(z, zOff + 4);
}
+ public static int mul33WordAdd(int x, int y, int[] z, int zOff)
+ {
+ // assert x >>> 31 == 0;
+ // assert zOff <= 5;
+
+ long c = 0, xVal = x & M, yVal = y & M;
+ c += yVal * xVal + (z[zOff + 0] & M);
+ z[zOff + 0] = (int)c;
+ c >>>= 32;
+ c += yVal + (z[zOff + 1] & M);
+ z[zOff + 1] = (int)c;
+ c >>>= 32;
+ c += (z[zOff + 2] & M);
+ z[zOff + 2] = (int)c;
+ c >>>= 32;
+ return c == 0 ? 0 : inc(z, zOff + 3);
+ }
+
public static int mulWordDwordAdd(int x, long y, int[] z, int zOff)
{
// assert zOff <= 5;
@@ -805,15 +832,14 @@ public abstract class Nat256
return c == 0 ? 0 : inc(z, zOff + 3);
}
- public static int mulWordExt(int x, int[] y, int[] zz, int zzOff)
+ public static int mulWord(int x, int[] y, int[] z, int zOff)
{
- // assert zzOff <= 8;
long c = 0, xVal = x & M;
int i = 0;
do
{
c += xVal * (y[i] & M);
- zz[zzOff + i] = (int)c;
+ z[zOff + i] = (int)c;
c >>>= 32;
}
while (++i < 8);
@@ -1172,21 +1198,6 @@ public abstract class Nat256
shiftUpBit(zz, zzOff, 16, (int)x_0 << 31);
}
- public static int squareWordAddExt(int[] x, int xPos, int[] zz)
- {
- // assert xPos > 0 && xPos < 8;
- long c = 0, xVal = x[xPos] & M;
- int i = 0;
- do
- {
- c += xVal * (x[i] & M) + (zz[xPos + i] & M);
- zz[xPos + i] = (int)c;
- c >>>= 32;
- }
- while (++i < xPos);
- return (int)c;
- }
-
public static int sub(int[] x, int[] y, int[] z)
{
long c = 0;
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat384.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat384.java
new file mode 100644
index 00000000..67e2dd05
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat384.java
@@ -0,0 +1,44 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import org.bouncycastle.math.ec.Nat;
+
+public abstract class Nat384
+{
+ public static void mul(int[] x, int[] y, int[] zz)
+ {
+ Nat192.mul(x, y, zz);
+ Nat192.mul(x, 6, y, 6, zz, 12);
+
+ int c18 = Nat192.addToEachOther(zz, 6, zz, 12);
+ int c12 = c18 + Nat192.addTo(zz, 0, zz, 6, 0);
+ c18 += Nat192.addTo(zz, 18, zz, 12, c12);
+
+ int[] dx = Nat192.create(), dy = Nat192.create();
+ boolean neg = Nat192.diff(x, 6, x, 0, dx, 0) != Nat192.diff(y, 6, y, 0, dy, 0);
+
+ int[] tt = Nat192.createExt();
+ Nat192.mul(dx, dy, tt);
+
+ c18 += neg ? Nat.addTo(12, tt, 0, zz, 6) : Nat.subFrom(12, tt, 0, zz, 6);
+ Nat.addWordExt(12, c18, zz, 18);
+ }
+
+ public static void square(int[] x, int[] zz)
+ {
+ Nat192.square(x, zz);
+ Nat192.square(x, 6, zz, 12);
+
+ int c18 = Nat192.addToEachOther(zz, 6, zz, 12);
+ int c12 = c18 + Nat192.addTo(zz, 0, zz, 6, 0);
+ c18 += Nat192.addTo(zz, 18, zz, 12, c12);
+
+ int[] dx = Nat192.create();
+ Nat192.diff(x, 6, x, 0, dx, 0);
+
+ int[] tt = Nat192.createExt();
+ Nat192.square(dx, tt);
+
+ c18 += Nat.subFrom(12, tt, 0, zz, 6);
+ Nat.addWordExt(12, c18, zz, 18);
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java
index a43008f0..957f7109 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java
@@ -22,7 +22,7 @@ public abstract class Nat512
c24 += neg ? Nat.addTo(16, tt, 0, zz, 8) : Nat.subFrom(16, tt, 0, zz, 8);
Nat.addWordExt(16, c24, zz, 24);
}
-
+
public static void square(int[] x, int[] zz)
{
Nat256.square(x, zz);
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
index 39fcd3d9..dcb8e0fb 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java
@@ -33,7 +33,7 @@ public class SecP192K1Field
public static void addOne(int[] x, int[] z)
{
- System.arraycopy(x, 0, z, 0, 6);
+ Nat192.copy(x, z);
int c = Nat192.inc(z, 0);
if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
{
@@ -85,7 +85,7 @@ public class SecP192K1Field
public static void reduce(int[] xx, int[] z)
{
- long c = Nat192.mul33AddExt(PInv33, xx, 6, xx, 0, z, 0);
+ long c = Nat192.mul33Add(PInv33, xx, 6, xx, 0, z, 0);
c = Nat192.mul33DWordAdd(PInv33, c, z, 0);
// assert c == 0L || c == 1L;
@@ -96,6 +96,18 @@ public class SecP192K1Field
}
}
+ public static void reduce32(int x, int[] z)
+ {
+ int c = Nat192.mul33WordAdd(PInv33, x, z, 0);
+
+ // assert c == 0L || c == 1L;
+
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ Nat192.addDWord(PInv, z, 0);
+ }
+ }
+
public static void square(int[] x, int[] z)
{
int[] tt = Nat192.createExt();
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
index 91d576d1..3e70754b 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java
@@ -186,7 +186,7 @@ public class SecP192K1FieldElement extends ECFieldElement
int[] t2 = x3;
SecP192K1Field.square(t1, t2);
- return Arrays.areEqual(x1, t2) ? new SecP192K1FieldElement(t1) : null;
+ return Nat192.eq(x1, t2) ? new SecP192K1FieldElement(t1) : null;
}
public boolean equals(Object other)
@@ -202,11 +202,11 @@ public class SecP192K1FieldElement extends ECFieldElement
}
SecP192K1FieldElement o = (SecP192K1FieldElement)other;
- return Arrays.areEqual(x, o.x);
+ return Nat192.eq(x, o.x);
}
public int hashCode()
{
- return Q.hashCode() ^ Arrays.hashCode(x);
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 6);
}
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
index da9e5e24..44f8c7fe 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java
@@ -3,6 +3,7 @@ package org.bouncycastle.math.ec.custom.sec;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.Nat;
public class SecP192K1Point extends ECPoint
{
@@ -225,12 +226,11 @@ public class SecP192K1Point extends ECPoint
int[] S = Y1Squared;
SecP192K1Field.multiply(Y1Squared, X1.x, S);
- SecP192K1Field.twice(S, S);
- SecP192K1Field.twice(S, S);
+ int c = Nat.shiftUpBits(6, S, 2, 0);
+ SecP192K1Field.reduce32(c, S);
- SecP192K1Field.twice(T, t1);
- SecP192K1Field.twice(t1, t1);
- SecP192K1Field.twice(t1, t1);
+ c = Nat.shiftUpBits(6, T, 3, 0, t1);
+ SecP192K1Field.reduce32(c, t1);
SecP192K1FieldElement X3 = new SecP192K1FieldElement(T);
SecP192K1Field.square(M, X3.x);
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
index 02d0b72e..b7e11471 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java
@@ -33,7 +33,7 @@ public class SecP192R1Field
public static void addOne(int[] x, int[] z)
{
- System.arraycopy(x, 0, z, 0, 6);
+ Nat192.copy(x, z);
int c = Nat192.inc(z, 0);
if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
{
@@ -131,6 +131,15 @@ public class SecP192R1Field
}
}
+ public static void reduce32(int x, int[] z)
+ {
+ int c = Nat192.addWord(x, z, 0) + Nat192.addWord(x, z, 2);
+ if (c != 0 || (z[5] == P5 && Nat192.gte(z, P)))
+ {
+ Nat192.sub(z, P, z);
+ }
+ }
+
public static void square(int[] x, int[] z)
{
int[] tt = Nat192.createExt();
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
index cc1a231d..15d7de7d 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java
@@ -163,7 +163,7 @@ public class SecP192R1FieldElement extends ECFieldElement
SecP192R1Field.squareN(t1, 62, t1);
SecP192R1Field.square(t1, t2);
- return Arrays.areEqual(x1, t2) ? new SecP192R1FieldElement(t1) : null;
+ return Nat192.eq(x1, t2) ? new SecP192R1FieldElement(t1) : null;
}
public boolean equals(Object other)
@@ -179,11 +179,11 @@ public class SecP192R1FieldElement extends ECFieldElement
}
SecP192R1FieldElement o = (SecP192R1FieldElement)other;
- return Arrays.areEqual(x, o.x);
+ return Nat192.eq(x, o.x);
}
public int hashCode()
{
- return Q.hashCode() ^ Arrays.hashCode(x);
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 6);
}
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
index fb62217d..49116119 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java
@@ -3,6 +3,7 @@ package org.bouncycastle.math.ec.custom.sec;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.Nat;
public class SecP192R1Point extends ECPoint
{
@@ -237,12 +238,11 @@ public class SecP192R1Point extends ECPoint
int[] S = Y1Squared;
SecP192R1Field.multiply(Y1Squared, X1.x, S);
- SecP192R1Field.twice(S, S);
- SecP192R1Field.twice(S, S);
+ int c = Nat.shiftUpBits(6, S, 2, 0);
+ SecP192R1Field.reduce32(c, S);
- SecP192R1Field.twice(T, t1);
- SecP192R1Field.twice(t1, t1);
- SecP192R1Field.twice(t1, t1);
+ c = Nat.shiftUpBits(6, T, 3, 0, t1);
+ SecP192R1Field.reduce32(c, t1);
SecP192R1FieldElement X3 = new SecP192R1FieldElement(T);
SecP192R1Field.square(M, X3.x);
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
new file mode 100644
index 00000000..4580da4e
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java
@@ -0,0 +1,98 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECConstants;
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.field.FiniteFields;
+import org.bouncycastle.util.encoders.Hex;
+
+public class SecP224K1Curve extends ECCurve
+{
+ public static final BigInteger q = new BigInteger(1,
+ Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"));
+
+ private static final int SECP224K1_DEFAULT_COORDS = COORD_JACOBIAN;
+
+ protected SecP224K1Point infinity;
+
+ public SecP224K1Curve()
+ {
+ super(FiniteFields.getPrimeField(q));
+
+ this.infinity = new SecP224K1Point(this, null, null);
+
+ this.a = fromBigInteger(ECConstants.ZERO);
+ this.b = fromBigInteger(BigInteger.valueOf(5));
+ this.order = new BigInteger(1, Hex.decode("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"));
+ this.cofactor = BigInteger.valueOf(1);
+ this.coord = SECP224K1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP224K1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP224K1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ {
+ return new SecP224K1Point(this, x, y, withCompression);
+ }
+
+ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
+ {
+ ECFieldElement x = fromBigInteger(X1);
+ ECFieldElement alpha = x.square().multiply(x).add(getB());
+ ECFieldElement beta = alpha.sqrt();
+
+ //
+ // if we can't find a sqrt we haven't got a point on the
+ // curve - run!
+ //
+ if (beta == null)
+ {
+ throw new RuntimeException("Invalid point compression");
+ }
+
+ if (beta.testBitZero() != (yTilde == 1))
+ {
+ // Use the other root
+ beta = beta.negate();
+ }
+
+ return new SecP224K1Point(this, x, beta, true);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
new file mode 100644
index 00000000..70895d51
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java
@@ -0,0 +1,160 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+public class SecP224K1Field
+{
+ // 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1
+ static final int[] P = new int[]{ 0xFFFFE56D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF };
+ private static final int P6 = 0xFFFFFFFF;
+ private static final int[] PExt = new int[]{ 0x02C23069, 0x00003526, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFCADA, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int PExt13 = 0xFFFFFFFF;
+ private static final long PInv = 0x0000000100001A93L;
+ private static final int PInv33 = 0x1A93;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat224.add(x, y, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.addDWord(PInv, z, 0);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat224.addExt(xx, yy, zz);
+ if (c != 0 || (zz[13] == PExt13 && Nat224.gteExt(zz, PExt)))
+ {
+ Nat224.subExt(zz, PExt, zz);
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ Nat224.copy(x, z);
+ int c = Nat224.inc(z, 0);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.addDWord(PInv, z, 0);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat224.fromBigInteger(x);
+ if (z[6] == P6 && Nat224.gte(z, P))
+ {
+ Nat224.addDWord(PInv, z, 0);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat224.shiftDownBit(x, 0, z);
+ }
+ else
+ {
+ int c = Nat224.add(x, P, z);
+ Nat224.shiftDownBit(z, c, z);
+ }
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat224.createExt();
+ Nat224.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (Nat224.isZero(x))
+ {
+ Nat224.zero(z);
+ }
+ else
+ {
+ Nat224.sub(P, x, z);
+ }
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long c = Nat224.mul33Add(PInv33, xx, 7, xx, 0, z, 0);
+ c = Nat224.mul33DWordAdd(PInv33, c, z, 0);
+
+ // assert c == 0L || c == 1L;
+
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.addDWord(PInv, z, 0);
+ }
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ int c = Nat224.mul33WordAdd(PInv33, x, z, 0);
+
+ // assert c == 0L || c == 1L;
+
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.addDWord(PInv, z, 0);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat224.createExt();
+ Nat224.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat224.createExt();
+ Nat224.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat224.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat224.sub(x, y, z);
+ if (c != 0)
+ {
+ Nat224.subDWord(PInv, z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat224.subExt(xx, yy, zz);
+ if (c != 0)
+ {
+ Nat224.addExt(zz, PExt, zz);
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat224.shiftUpBit(x, 0, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.addDWord(PInv, z, 0);
+ }
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
new file mode 100644
index 00000000..5496c30a
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java
@@ -0,0 +1,242 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.Mod;
+import org.bouncycastle.util.Arrays;
+
+public class SecP224K1FieldElement extends ECFieldElement
+{
+ public static final BigInteger Q = SecP224K1Curve.q;
+
+ // Calculated as ECConstants.TWO.modPow(Q.shiftRight(2), Q)
+ private static final int[] PRECOMP_POW2 = new int[]{ 0x33bfd202, 0xdcfad133, 0x2287624a, 0xc3811ba8,
+ 0xa85558fc, 0x1eaef5d7, 0x8edf154c };
+
+ protected int[] x;
+
+ public SecP224K1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP224K1FieldElement");
+ }
+
+ this.x = SecP224K1Field.fromBigInteger(x);
+ }
+
+ public SecP224K1FieldElement()
+ {
+ this.x = Nat224.create();
+ }
+
+ protected SecP224K1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat224.isZero(x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat224.isOne(x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat224.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat224.toBigInteger(x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP224K1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.add(x, ((SecP224K1FieldElement)b).x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.addOne(x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.subtract(x, ((SecP224K1FieldElement)b).x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.multiply(x, ((SecP224K1FieldElement)b).x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat224.create();
+ Mod.invert(SecP224K1Field.P, ((SecP224K1FieldElement)b).x, z);
+ SecP224K1Field.multiply(z, x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.negate(x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat224.create();
+ SecP224K1Field.square(x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP224K1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat224.create();
+ Mod.invert(SecP224K1Field.P, x, z);
+ return new SecP224K1FieldElement(z);
+ }
+
+ // D.1.4 91
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ /*
+ * Q == 8m + 5, so we use Pocklington's method for this case.
+ *
+ * First, raise this element to the exponent 2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 (i.e. m + 1)
+ *
+ * Breaking up the exponent's binary representation into "repunits", we get:
+ * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s} { 1 1s } { 1 0s} { 3 1s } { 1 0s}
+ *
+ * Therefore we need an addition chain containing 1, 3, 19, 191 (the lengths of the repunits)
+ * We use: [1], 2, [3], 4, 8, 11, [19], 23, 42, 84, 107, [191]
+ */
+
+ int[] x1 = this.x;
+ if (Nat224.isZero(x1) || Nat224.isOne(x1))
+ {
+ return this;
+ }
+
+ int[] x2 = Nat224.create();
+ SecP224K1Field.square(x1, x2);
+ SecP224K1Field.multiply(x2, x1, x2);
+ int[] x3 = x2;
+ SecP224K1Field.square(x2, x3);
+ SecP224K1Field.multiply(x3, x1, x3);
+ int[] x4 = Nat224.create();
+ SecP224K1Field.square(x3, x4);
+ SecP224K1Field.multiply(x4, x1, x4);
+ int[] x8 = Nat224.create();
+ SecP224K1Field.squareN(x4, 4, x8);
+ SecP224K1Field.multiply(x8, x4, x8);
+ int[] x11 = Nat224.create();
+ SecP224K1Field.squareN(x8, 3, x11);
+ SecP224K1Field.multiply(x11, x3, x11);
+ int[] x19 = x11;
+ SecP224K1Field.squareN(x11, 8, x19);
+ SecP224K1Field.multiply(x19, x8, x19);
+ int[] x23 = x8;
+ SecP224K1Field.squareN(x19, 4, x23);
+ SecP224K1Field.multiply(x23, x4, x23);
+ int[] x42 = x4;
+ SecP224K1Field.squareN(x23, 19, x42);
+ SecP224K1Field.multiply(x42, x19, x42);
+ int[] x84 = Nat224.create();
+ SecP224K1Field.squareN(x42, 42, x84);
+ SecP224K1Field.multiply(x84, x42, x84);
+ int[] x107 = x42;
+ SecP224K1Field.squareN(x84, 23, x107);
+ SecP224K1Field.multiply(x107, x23, x107);
+ int[] x191 = x23;
+ SecP224K1Field.squareN(x107, 84, x191);
+ SecP224K1Field.multiply(x191, x84, x191);
+
+ int[] t1 = x191;
+ SecP224K1Field.squareN(t1, 20, t1);
+ SecP224K1Field.multiply(t1, x19, t1);
+ SecP224K1Field.squareN(t1, 3, t1);
+ SecP224K1Field.multiply(t1, x1, t1);
+ SecP224K1Field.squareN(t1, 2, t1);
+ SecP224K1Field.multiply(t1, x1, t1);
+ SecP224K1Field.squareN(t1, 4, t1);
+ SecP224K1Field.multiply(t1, x3, t1);
+ SecP224K1Field.square(t1, t1);
+
+ int[] t2 = x84;
+ SecP224K1Field.square(t1, t2);
+
+ if (Nat224.eq(x1, t2))
+ {
+ return new SecP224K1FieldElement(t1);
+ }
+
+ /*
+ * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess,
+ * which is ((4x)^(m + 1))/2 mod Q
+ */
+ SecP224K1Field.multiply(t1, PRECOMP_POW2, t1);
+
+ SecP224K1Field.square(t1, t2);
+
+ if (Nat224.eq(x1, t2))
+ {
+ return new SecP224K1FieldElement(t1);
+ }
+
+ return null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP224K1FieldElement))
+ {
+ return false;
+ }
+
+ SecP224K1FieldElement o = (SecP224K1FieldElement)other;
+ return Nat224.eq(x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 7);
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
new file mode 100644
index 00000000..d5eb8294
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java
@@ -0,0 +1,311 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.Nat;
+
+public class SecP224K1Point extends ECPoint
+{
+ /**
+ * Create a point which encodes with point compression.
+ *
+ * @param curve
+ * the curve to use
+ * @param x
+ * affine x co-ordinate
+ * @param y
+ * affine y co-ordinate
+ *
+ * @deprecated Use ECCurve.createPoint to construct points
+ */
+ public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ this(curve, x, y, false);
+ }
+
+ /**
+ * Create a point that encodes with or without point compresion.
+ *
+ * @param curve
+ * the curve to use
+ * @param x
+ * affine x co-ordinate
+ * @param y
+ * affine y co-ordinate
+ * @param withCompression
+ * if true encode with point compression
+ *
+ * @deprecated per-point compression property will be removed, refer
+ * {@link #getEncoded(boolean)}
+ */
+ public SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ {
+ super(curve, x, y);
+
+ if ((x == null) != (y == null))
+ {
+ throw new IllegalArgumentException("Exactly one of the field elements is null");
+ }
+
+ this.withCompression = withCompression;
+ }
+
+ SecP224K1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs,
+ boolean withCompression)
+ {
+ super(curve, x, y, zs);
+
+ this.withCompression = withCompression;
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP224K1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ protected boolean getCompressionYTilde()
+ {
+ return this.getAffineYCoord().testBitZero();
+ }
+
+ // B.3 pg 62
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.x, Y1 = (SecP224K1FieldElement)this.y;
+ SecP224K1FieldElement X2 = (SecP224K1FieldElement)b.getXCoord(), Y2 = (SecP224K1FieldElement)b.getYCoord();
+
+ SecP224K1FieldElement Z1 = (SecP224K1FieldElement)this.zs[0];
+ SecP224K1FieldElement Z2 = (SecP224K1FieldElement)b.getZCoord(0);
+
+ int[] tt1 = Nat224.createExt();
+ int[] tt2 = Nat224.createExt();
+ int[] t3 = Nat224.create();
+ int[] t4 = Nat224.create();
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP224K1Field.square(Z1.x, S2);
+
+ U2 = tt2;
+ SecP224K1Field.multiply(S2, X2.x, U2);
+
+ SecP224K1Field.multiply(S2, Z1.x, S2);
+ SecP224K1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP224K1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP224K1Field.multiply(S1, X1.x, U1);
+
+ SecP224K1Field.multiply(S1, Z2.x, S1);
+ SecP224K1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat224.create();
+ SecP224K1Field.subtract(U1, U2, H);
+
+ int[] R = tt2;
+ SecP224K1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat224.isZero(H))
+ {
+ if (Nat224.isZero(R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP224K1Field.square(H, HSquared);
+
+ int[] G = Nat224.create();
+ SecP224K1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP224K1Field.multiply(HSquared, U1, V);
+
+ Nat224.mul(S1, G, tt1);
+
+ SecP224K1FieldElement X3 = new SecP224K1FieldElement(t4);
+ SecP224K1Field.square(R, X3.x);
+ SecP224K1Field.add(X3.x, G, X3.x);
+ SecP224K1Field.subtract(X3.x, V, X3.x);
+ SecP224K1Field.subtract(X3.x, V, X3.x);
+
+ SecP224K1FieldElement Y3 = new SecP224K1FieldElement(G);
+ SecP224K1Field.subtract(V, X3.x, Y3.x);
+ Nat224.mul(Y3.x, R, tt2);
+ SecP224K1Field.subtractExt(tt2, tt1, tt2);
+ SecP224K1Field.reduce(tt2, Y3.x);
+
+ SecP224K1FieldElement Z3 = new SecP224K1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP224K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP224K1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[] { Z3 };
+
+ return new SecP224K1Point(curve, X3, Y3, zs, this.withCompression);
+ }
+
+ // B.3 pg 62
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP224K1FieldElement Y1 = (SecP224K1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.x, Z1 = (SecP224K1FieldElement)this.zs[0];
+
+ int[] Y1Squared = Nat224.create();
+ SecP224K1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat224.create();
+ SecP224K1Field.square(Y1Squared, T);
+
+ int[] t1 = Nat224.create();
+ SecP224K1Field.square(X1.x, t1);
+
+ int[] M = Nat224.create();
+ SecP224K1Field.twice(t1, M);
+ SecP224K1Field.add(M, t1, M);
+
+ int[] S = Y1Squared;
+ SecP224K1Field.multiply(Y1Squared, X1.x, S);
+ int c = Nat.shiftUpBits(7, S, 2, 0);
+ SecP224K1Field.reduce32(c, S);
+
+ c = Nat.shiftUpBits(7, T, 3, 0, t1);
+ SecP224K1Field.reduce32(c, t1);
+
+ SecP224K1FieldElement X3 = new SecP224K1FieldElement(T);
+ SecP224K1Field.square(M, X3.x);
+ SecP224K1Field.subtract(X3.x, S, X3.x);
+ SecP224K1Field.subtract(X3.x, S, X3.x);
+
+ SecP224K1FieldElement Y3 = new SecP224K1FieldElement(S);
+ SecP224K1Field.subtract(S, X3.x, Y3.x);
+ SecP224K1Field.multiply(Y3.x, M, Y3.x);
+ SecP224K1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP224K1FieldElement Z3 = new SecP224K1FieldElement(M);
+ SecP224K1Field.twice(Y1.x, Z3.x);
+ if (!Z1.isOne())
+ {
+ SecP224K1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP224K1Point(curve, X3, Y3, new ECFieldElement[] { Z3 }, this.withCompression);
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ // D.3.2 pg 102 (see Note:)
+ public ECPoint subtract(ECPoint b)
+ {
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ // Add -b
+ return add(b.negate());
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP224K1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
new file mode 100644
index 00000000..598b4a72
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java
@@ -0,0 +1,100 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.field.FiniteFields;
+import org.bouncycastle.util.encoders.Hex;
+
+public class SecP224R1Curve extends ECCurve
+{
+ public static final BigInteger q = new BigInteger(1,
+ Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"));
+
+ private static final int SecP224R1_DEFAULT_COORDS = COORD_JACOBIAN;
+
+ protected SecP224R1Point infinity;
+
+ public SecP224R1Curve()
+ {
+ super(FiniteFields.getPrimeField(q));
+
+ this.infinity = new SecP224R1Point(this, null, null);
+
+ this.a = fromBigInteger(new BigInteger(1,
+ Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")));
+ this.b = fromBigInteger(new BigInteger(1,
+ Hex.decode("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")));
+ this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"));
+ this.cofactor = BigInteger.valueOf(1);
+
+ this.coord = SecP224R1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP224R1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP224R1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ {
+ return new SecP224R1Point(this, x, y, withCompression);
+ }
+
+ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
+ {
+ ECFieldElement x = fromBigInteger(X1);
+ ECFieldElement alpha = x.square().add(getA()).multiply(x).add(getB());
+ ECFieldElement beta = alpha.sqrt();
+
+ //
+ // if we can't find a sqrt we haven't got a point on the
+ // curve - run!
+ //
+ if (beta == null)
+ {
+ throw new RuntimeException("Invalid point compression");
+ }
+
+ if (beta.testBitZero() != (yTilde == 1))
+ {
+ // Use the other root
+ beta = beta.negate();
+ }
+
+ return new SecP224R1Point(this, x, beta, true);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
new file mode 100644
index 00000000..72a1dc52
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java
@@ -0,0 +1,189 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+public class SecP224R1Field
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ // 2^224 - 2^96 + 1
+ static final int[] P = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int P6 = 0xFFFFFFFF;
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int PExt13 = 0xFFFFFFFF;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat224.add(x, y, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.sub(z, P, z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat224.addExt(xx, yy, zz);
+ if (c != 0 || (zz[13] == PExt13 && Nat224.gteExt(zz, PExt)))
+ {
+ Nat224.subExt(zz, PExt, zz);
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ Nat224.copy(x, z);
+ int c = Nat224.inc(z, 0);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.sub(z, P, z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat224.fromBigInteger(x);
+ if (z[6] == P6 && Nat224.gte(z, P))
+ {
+ Nat224.sub(z, P, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat224.shiftDownBit(x, 0, z);
+ }
+ else
+ {
+ int c = Nat224.add(x, P, z);
+ Nat224.shiftDownBit(z, c, z);
+ }
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat224.createExt();
+ Nat224.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (Nat224.isZero(x))
+ {
+ Nat224.zero(z);
+ }
+ else
+ {
+ Nat224.sub(P, x, z);
+ }
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long xx07 = xx[7] & M, xx08 = xx[8] & M, xx09 = xx[9] & M, xx10 = xx[10] & M;
+ long xx11 = xx[11] & M, xx12 = xx[12] & M, xx13 = xx[13] & M;
+
+ long t0 = xx07 + xx11;
+ long t1 = xx08 + xx12;
+ long t2 = xx09 + xx13;
+
+ long cc = 0;
+ cc += (xx[0] & M) - t0;
+ z[0] = (int)cc;
+ cc >>= 32;
+ cc += (xx[1] & M) - t1;
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (xx[2] & M) - t2;
+ z[2] = (int)cc;
+ cc >>= 32;
+ cc += (xx[3] & M) + t0 - xx10;
+ z[3] = (int)cc;
+ cc >>= 32;
+ cc += (xx[4] & M) + t1 - xx11;
+ z[4] = (int)cc;
+ cc >>= 32;
+ cc += (xx[5] & M) + t2 - xx12;
+ z[5] = (int)cc;
+ cc >>= 32;
+ cc += (xx[6] & M) + xx10 - xx13;
+ z[6] = (int)cc;
+ cc >>= 32;
+
+ int c = (int)cc;
+ if (c > 0)
+ {
+ reduce32(c, z);
+ }
+ else
+ {
+ while (c < 0)
+ {
+ c += Nat224.add(z, P, z);
+ }
+ }
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ int c = Nat224.subWord(x, z, 0) + Nat224.addWord(x, z, 3);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.sub(z, P, z);
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat224.createExt();
+ Nat224.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat224.createExt();
+ Nat224.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat224.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat224.sub(x, y, z);
+ if (c != 0)
+ {
+ Nat224.add(z, P, z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat224.subExt(xx, yy, zz);
+ if (c != 0)
+ {
+ Nat224.addExt(zz, PExt, zz);
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat224.shiftUpBit(x, 0, z);
+ if (c != 0 || (z[6] == P6 && Nat224.gte(z, P)))
+ {
+ Nat224.sub(z, P, z);
+ }
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
new file mode 100644
index 00000000..e9c7d78b
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java
@@ -0,0 +1,246 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.Mod;
+import org.bouncycastle.math.ec.Nat;
+import org.bouncycastle.util.Arrays;
+
+public class SecP224R1FieldElement extends ECFieldElement
+{
+ public static final BigInteger Q = SecP224R1Curve.q;
+
+ protected int[] x;
+
+ public SecP224R1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP224R1FieldElement");
+ }
+
+ this.x = SecP224R1Field.fromBigInteger(x);
+ }
+
+ public SecP224R1FieldElement()
+ {
+ this.x = Nat224.create();
+ }
+
+ protected SecP224R1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat224.isZero(x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat224.isOne(x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat224.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat224.toBigInteger(x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP224R1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.add(x, ((SecP224R1FieldElement)b).x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.addOne(x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.subtract(x, ((SecP224R1FieldElement)b).x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.multiply(x, ((SecP224R1FieldElement)b).x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat224.create();
+ Mod.invert(SecP224R1Field.P, ((SecP224R1FieldElement)b).x, z);
+ SecP224R1Field.multiply(z, x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.negate(x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat224.create();
+ SecP224R1Field.square(x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP224R1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat224.create();
+ Mod.invert(SecP224R1Field.P, x, z);
+ return new SecP224R1FieldElement(z);
+ }
+
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ int[] c = this.x;
+ if (Nat224.isZero(c) || Nat224.isOne(c))
+ {
+ return this;
+ }
+
+ int[] nc = Nat224.create();
+ SecP224R1Field.negate(c, nc);
+
+ int[] r = Mod.random(SecP224R1Field.P);
+
+ for (;;)
+ {
+ int[] d1 = Nat224.create();
+ Nat224.copy(r, d1);
+ int[] e1 = Nat224.create();
+ e1[0] = 1;
+ int[] f1 = Nat224.create();
+ RP(nc, d1, e1, f1);
+
+ int[] d0 = Nat224.create();
+ int[] e0 = Nat224.create();
+
+ for (int k = 1; k < 96; ++k)
+ {
+ Nat224.copy(d1, d0);
+ Nat224.copy(e1, e0);
+
+ RS(d1, e1, f1);
+
+ if (Nat224.isZero(d1))
+ {
+ Mod.invert(SecP224R1Field.P, e0, f1);
+ SecP224R1Field.multiply(f1, d0, f1);
+
+ SecP224R1Field.square(f1, d1);
+
+ return Nat224.eq(c, d1) ? new SecP224R1FieldElement(f1) : null;
+ }
+ }
+
+ // Avoid any possible infinite loop due to a bad random number generator
+ SecP224R1Field.addOne(r, r);
+ }
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP224R1FieldElement))
+ {
+ return false;
+ }
+
+ SecP224R1FieldElement o = (SecP224R1FieldElement)other;
+ return Nat224.eq(x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 7);
+ }
+
+ private static void RM(int[] nc, int[] d0, int[] e0, int[] d1, int[] e1, int[] f1)
+ {
+ int[] t = Nat224.create();
+ SecP224R1Field.multiply(e1, e0, t);
+ SecP224R1Field.multiply(t, nc, t);
+ SecP224R1Field.multiply(d1, d0, f1);
+ SecP224R1Field.add(f1, t, f1);
+ SecP224R1Field.multiply(d1, e0, t);
+ Nat224.copy(f1, d1);
+ SecP224R1Field.multiply(e1, d0, e1);
+ SecP224R1Field.add(e1, t, e1);
+ SecP224R1Field.square(e1, f1);
+ SecP224R1Field.multiply(f1, nc, f1);
+ }
+
+ private static void RP(int[] nc, int[] d1, int[] e1, int[] f1)
+ {
+ Nat224.copy(nc, f1);
+
+ int[] d0 = Nat224.create();
+ int[] e0 = Nat224.create();
+
+ for (int i = 0; i < 7; ++i)
+ {
+ Nat224.copy(d1, d0);
+ Nat224.copy(e1, e0);
+
+ int j = 1 << i;
+ while (--j >= 0)
+ {
+ RS(d1, e1, f1);
+ }
+
+ RM(nc, d0, e0, d1, e1, f1);
+ }
+ }
+
+ private static void RS(int[] d, int[] e, int[] f)
+ {
+ SecP224R1Field.multiply(e, d, e);
+ int[] t = Nat224.create();
+ SecP224R1Field.square(d, t);
+ SecP224R1Field.add(f, t, d);
+ SecP224R1Field.twice(e, e);
+ SecP224R1Field.multiply(f, t, f);
+ int c = Nat.shiftUpBits(7, f, 2, 0);
+ SecP224R1Field.reduce32(c, f);
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
new file mode 100644
index 00000000..177b2fec
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java
@@ -0,0 +1,320 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.Nat;
+
+public class SecP224R1Point extends ECPoint
+{
+ /**
+ * Create a point which encodes with point compression.
+ *
+ * @param curve
+ * the curve to use
+ * @param x
+ * affine x co-ordinate
+ * @param y
+ * affine y co-ordinate
+ *
+ * @deprecated Use ECCurve.createPoint to construct points
+ */
+ public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ this(curve, x, y, false);
+ }
+
+ /**
+ * Create a point that encodes with or without point compresion.
+ *
+ * @param curve
+ * the curve to use
+ * @param x
+ * affine x co-ordinate
+ * @param y
+ * affine y co-ordinate
+ * @param withCompression
+ * if true encode with point compression
+ *
+ * @deprecated per-point compression property will be removed, refer
+ * {@link #getEncoded(boolean)}
+ */
+ public SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ {
+ super(curve, x, y);
+
+ if ((x == null) != (y == null))
+ {
+ throw new IllegalArgumentException("Exactly one of the field elements is null");
+ }
+
+ this.withCompression = withCompression;
+ }
+
+ SecP224R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ {
+ super(curve, x, y, zs);
+
+ this.withCompression = withCompression;
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP224R1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ protected boolean getCompressionYTilde()
+ {
+ return this.getAffineYCoord().testBitZero();
+ }
+
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP224R1FieldElement X1 = (SecP224R1FieldElement)this.x, Y1 = (SecP224R1FieldElement)this.y;
+ SecP224R1FieldElement X2 = (SecP224R1FieldElement)b.getXCoord(), Y2 = (SecP224R1FieldElement)b.getYCoord();
+
+ SecP224R1FieldElement Z1 = (SecP224R1FieldElement)this.zs[0];
+ SecP224R1FieldElement Z2 = (SecP224R1FieldElement)b.getZCoord(0);
+
+ int[] tt1 = Nat224.createExt();
+ int[] tt2 = Nat224.createExt();
+ int[] t3 = Nat224.create();
+ int[] t4 = Nat224.create();
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP224R1Field.square(Z1.x, S2);
+
+ U2 = tt2;
+ SecP224R1Field.multiply(S2, X2.x, U2);
+
+ SecP224R1Field.multiply(S2, Z1.x, S2);
+ SecP224R1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP224R1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP224R1Field.multiply(S1, X1.x, U1);
+
+ SecP224R1Field.multiply(S1, Z2.x, S1);
+ SecP224R1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat224.create();
+ SecP224R1Field.subtract(U1, U2, H);
+
+ int[] R = tt2;
+ SecP224R1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat224.isZero(H))
+ {
+ if (Nat224.isZero(R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP224R1Field.square(H, HSquared);
+
+ int[] G = Nat224.create();
+ SecP224R1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP224R1Field.multiply(HSquared, U1, V);
+
+ Nat224.mul(S1, G, tt1);
+
+ SecP224R1FieldElement X3 = new SecP224R1FieldElement(t4);
+ SecP224R1Field.square(R, X3.x);
+ SecP224R1Field.add(X3.x, G, X3.x);
+ SecP224R1Field.subtract(X3.x, V, X3.x);
+ SecP224R1Field.subtract(X3.x, V, X3.x);
+
+ SecP224R1FieldElement Y3 = new SecP224R1FieldElement(G);
+ SecP224R1Field.subtract(V, X3.x, Y3.x);
+ Nat224.mul(Y3.x, R, tt2);
+ SecP224R1Field.subtractExt(tt2, tt1, tt2);
+ SecP224R1Field.reduce(tt2, Y3.x);
+
+ SecP224R1FieldElement Z3 = new SecP224R1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP224R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP224R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
+
+ return new SecP224R1Point(curve, X3, Y3, zs, this.withCompression);
+ }
+
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP224R1FieldElement Y1 = (SecP224R1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP224R1FieldElement X1 = (SecP224R1FieldElement)this.x, Z1 = (SecP224R1FieldElement)this.zs[0];
+
+ int[] t1 = Nat224.create();
+ int[] t2 = Nat224.create();
+
+ int[] Y1Squared = Nat224.create();
+ SecP224R1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat224.create();
+ SecP224R1Field.square(Y1Squared, T);
+
+ boolean Z1IsOne = Z1.isOne();
+
+ int[] Z1Squared = Z1.x;
+ if (!Z1IsOne)
+ {
+ Z1Squared = t2;
+ SecP224R1Field.square(Z1.x, Z1Squared);
+ }
+
+ SecP224R1Field.subtract(X1.x, Z1Squared, t1);
+
+ int[] M = t2;
+ SecP224R1Field.add(X1.x, Z1Squared, M);
+ SecP224R1Field.multiply(M, t1, M);
+ SecP224R1Field.twice(M, t1);
+ SecP224R1Field.add(M, t1, M);
+
+ int[] S = Y1Squared;
+ SecP224R1Field.multiply(Y1Squared, X1.x, S);
+ int c = Nat.shiftUpBits(7, S, 2, 0);
+ SecP224R1Field.reduce32(c, S);
+
+ c = Nat.shiftUpBits(7, T, 3, 0, t1);
+ SecP224R1Field.reduce32(c, t1);
+
+ SecP224R1FieldElement X3 = new SecP224R1FieldElement(T);
+ SecP224R1Field.square(M, X3.x);
+ SecP224R1Field.subtract(X3.x, S, X3.x);
+ SecP224R1Field.subtract(X3.x, S, X3.x);
+
+ SecP224R1FieldElement Y3 = new SecP224R1FieldElement(S);
+ SecP224R1Field.subtract(S, X3.x, Y3.x);
+ SecP224R1Field.multiply(Y3.x, M, Y3.x);
+ SecP224R1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP224R1FieldElement Z3 = new SecP224R1FieldElement(M);
+ SecP224R1Field.twice(Y1.x, Z3.x);
+ if (!Z1IsOne)
+ {
+ SecP224R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP224R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint subtract(ECPoint b)
+ {
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ // Add -b
+ return add(b.negate());
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP224R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
index 74313386..4f16c5c6 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
@@ -35,7 +35,7 @@ public class SecP256K1Field
public static void addOne(int[] x, int[] z)
{
- System.arraycopy(x, 0, z, 0, 8);
+ Nat256.copy(x, z);
int c = Nat256.inc(z, 0);
if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
{
@@ -87,7 +87,7 @@ public class SecP256K1Field
public static void reduce(int[] xx, int[] z)
{
- long c = Nat256.mul33AddExt(PInv33, xx, 8, xx, 0, z, 0);
+ long c = Nat256.mul33Add(PInv33, xx, 8, xx, 0, z, 0);
c = Nat256.mul33DWordAdd(PInv33, c, z, 0);
// assert c == 0L || c == 1L;
@@ -98,6 +98,18 @@ public class SecP256K1Field
}
}
+ public static void reduce32(int x, int[] z)
+ {
+ int c = Nat256.mul33WordAdd(PInv33, x, z, 0);
+
+ // assert c == 0L || c == 1L;
+
+ if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ Nat256.addDWord(PInv, z, 0);
+ }
+ }
+
public static void square(int[] x, int[] z)
{
int[] tt = Nat256.createExt();
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
index 0a874767..4454ef70 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
@@ -188,7 +188,7 @@ public class SecP256K1FieldElement extends ECFieldElement
int[] t2 = x2;
SecP256K1Field.square(t1, t2);
- return Arrays.areEqual(x1, t2) ? new SecP256K1FieldElement(t1) : null;
+ return Nat256.eq(x1, t2) ? new SecP256K1FieldElement(t1) : null;
}
public boolean equals(Object other)
@@ -204,11 +204,11 @@ public class SecP256K1FieldElement extends ECFieldElement
}
SecP256K1FieldElement o = (SecP256K1FieldElement)other;
- return Arrays.areEqual(x, o.x);
+ return Nat256.eq(x, o.x);
}
public int hashCode()
{
- return Q.hashCode() ^ Arrays.hashCode(x);
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 8);
}
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
index f1d07cad..d6a42694 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
@@ -3,6 +3,7 @@ package org.bouncycastle.math.ec.custom.sec;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.Nat;
public class SecP256K1Point extends ECPoint
{
@@ -225,12 +226,11 @@ public class SecP256K1Point extends ECPoint
int[] S = Y1Squared;
SecP256K1Field.multiply(Y1Squared, X1.x, S);
- SecP256K1Field.twice(S, S);
- SecP256K1Field.twice(S, S);
+ int c = Nat.shiftUpBits(8, S, 2, 0);
+ SecP256K1Field.reduce32(c, S);
- SecP256K1Field.twice(T, t1);
- SecP256K1Field.twice(t1, t1);
- SecP256K1Field.twice(t1, t1);
+ c = Nat.shiftUpBits(8, T, 3, 0, t1);
+ SecP256K1Field.reduce32(c, t1);
SecP256K1FieldElement X3 = new SecP256K1FieldElement(T);
SecP256K1Field.square(M, X3.x);
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
index 21ecc226..d3baceda 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
@@ -9,6 +9,8 @@ public class SecP256R1Field
// 2^256 - 2^224 + 2^192 + 2^96 - 1
static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0xFFFFFFFF };
+ private static final int[] _2P = new int[]{ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000002, 0xFFFFFFFE, 0x00000001 };
private static final int P7 = 0xFFFFFFFF;
private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE,
@@ -34,7 +36,7 @@ public class SecP256R1Field
public static void addOne(int[] x, int[] z)
{
- System.arraycopy(x, 0, z, 0, 8);
+ Nat256.copy(x, z);
int c = Nat256.inc(z, 0);
if (c != 0 || (z[7] == P7 && Nat256.gte(z, P)))
{
@@ -124,28 +126,59 @@ public class SecP256R1Field
cc >>= 32;
int c = (int)cc;
- if (c < 0)
+ if (c > 0)
{
- do
- {
- c += Nat256.add(z, P, z);
- }
- while (c < 0);
+ reduce32(c, z);
}
else
{
- while (c > 0)
+ while (c < -1)
{
- c += Nat256.sub(z, P, z);
+ c += Nat256.add(z, _2P, z) + 1;
}
-
- if (z[7] == P7 && Nat256.gte(z, P))
+ while (c < 0)
{
- Nat256.sub(z, P, z);
+ c += Nat256.add(z, P, z);
}
}
}
+ public static void reduce32(int x, int[] z)
+ {
+ long xx08 = x & M;
+
+ long cc = 0;
+ cc += (z[0] & M) + xx08;
+ z[0] = (int)cc;
+ cc >>= 32;
+ cc += (z[1] & M);
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (z[2] & M);
+ z[2] = (int)cc;
+ cc >>= 32;
+ cc += (z[3] & M) - xx08;
+ z[3] = (int)cc;
+ cc >>= 32;
+ cc += (z[4] & M);
+ z[4] = (int)cc;
+ cc >>= 32;
+ cc += (z[5] & M);
+ z[5] = (int)cc;
+ cc >>= 32;
+ cc += (z[6] & M) - xx08;
+ z[6] = (int)cc;
+ cc >>= 32;
+ cc += (z[7] & M) + xx08;
+ z[7] = (int)cc;
+ cc >>= 32;
+
+ if (cc != 0 || (z[7] == P7 && Nat256.gte(z, P)))
+ {
+ Nat256.sub(z, P, z);
+ }
+ }
+
public static void square(int[] x, int[] z)
{
int[] tt = Nat256.createExt();
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
index b01a20d6..084c21d4 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
@@ -162,7 +162,7 @@ public class SecP256R1FieldElement extends ECFieldElement
SecP256R1Field.squareN(t1, 94, t1);
SecP256R1Field.square(t1, t2);
- return Arrays.areEqual(x1, t2) ? new SecP256R1FieldElement(t1) : null;
+ return Nat256.eq(x1, t2) ? new SecP256R1FieldElement(t1) : null;
}
public boolean equals(Object other)
@@ -178,11 +178,11 @@ public class SecP256R1FieldElement extends ECFieldElement
}
SecP256R1FieldElement o = (SecP256R1FieldElement)other;
- return Arrays.areEqual(x, o.x);
+ return Nat256.eq(x, o.x);
}
public int hashCode()
{
- return Q.hashCode() ^ Arrays.hashCode(x);
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 8);
}
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
index fe971c27..acabefe3 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -3,6 +3,7 @@ package org.bouncycastle.math.ec.custom.sec;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.Nat;
public class SecP256R1Point extends ECPoint
{
@@ -235,12 +236,11 @@ public class SecP256R1Point extends ECPoint
int[] S = Y1Squared;
SecP256R1Field.multiply(Y1Squared, X1.x, S);
- SecP256R1Field.twice(S, S);
- SecP256R1Field.twice(S, S);
+ int c = Nat.shiftUpBits(8, S, 2, 0);
+ SecP256R1Field.reduce32(c, S);
- SecP256R1Field.twice(T, t1);
- SecP256R1Field.twice(t1, t1);
- SecP256R1Field.twice(t1, t1);
+ c = Nat.shiftUpBits(8, T, 3, 0, t1);
+ SecP256R1Field.reduce32(c, t1);
SecP256R1FieldElement X3 = new SecP256R1FieldElement(T);
SecP256R1Field.square(M, X3.x);
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
new file mode 100644
index 00000000..ede502e2
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java
@@ -0,0 +1,100 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.field.FiniteFields;
+import org.bouncycastle.util.encoders.Hex;
+
+public class SecP384R1Curve extends ECCurve
+{
+ public static final BigInteger q = new BigInteger(1,
+ Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"));
+
+ private static final int SecP384R1_DEFAULT_COORDS = COORD_JACOBIAN;
+
+ protected SecP384R1Point infinity;
+
+ public SecP384R1Curve()
+ {
+ super(FiniteFields.getPrimeField(q));
+
+ this.infinity = new SecP384R1Point(this, null, null);
+
+ this.a = fromBigInteger(new BigInteger(1,
+ Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")));
+ this.b = fromBigInteger(new BigInteger(1,
+ Hex.decode("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")));
+ this.order = new BigInteger(1, Hex.decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"));
+ this.cofactor = BigInteger.valueOf(1);
+
+ this.coord = SecP384R1_DEFAULT_COORDS;
+ }
+
+ protected ECCurve cloneCurve()
+ {
+ return new SecP384R1Curve();
+ }
+
+ public boolean supportsCoordinateSystem(int coord)
+ {
+ switch (coord)
+ {
+ case COORD_JACOBIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public BigInteger getQ()
+ {
+ return q;
+ }
+
+ public int getFieldSize()
+ {
+ return q.bitLength();
+ }
+
+ public ECFieldElement fromBigInteger(BigInteger x)
+ {
+ return new SecP384R1FieldElement(x);
+ }
+
+ protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
+ {
+ return new SecP384R1Point(this, x, y, withCompression);
+ }
+
+ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
+ {
+ ECFieldElement x = fromBigInteger(X1);
+ ECFieldElement alpha = x.square().add(getA()).multiply(x).add(getB());
+ ECFieldElement beta = alpha.sqrt();
+
+ //
+ // if we can't find a sqrt we haven't got a point on the
+ // curve - run!
+ //
+ if (beta == null)
+ {
+ throw new RuntimeException("Invalid point compression");
+ }
+
+ if (beta.testBitZero() != (yTilde == 1))
+ {
+ // Use the other root
+ beta = beta.negate();
+ }
+
+ return new SecP384R1Point(this, x, beta, true);
+ }
+
+ public ECPoint getInfinity()
+ {
+ return infinity;
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
new file mode 100644
index 00000000..d7d0d50e
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
@@ -0,0 +1,229 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.Nat;
+
+public class SecP384R1Field
+{
+ private static final long M = 0xFFFFFFFFL;
+
+ // 2^384 - 2^128 - 2^96 + 2^32 - 1
+ static final int[] P = new int[]{ 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int P11 = 0xFFFFFFFF;
+ private static final int[] PExt = new int[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
+ 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x00000001, 0x00000000,
+ 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
+ private static final int PExt23 = 0xFFFFFFFF;
+
+ public static void add(int[] x, int[] y, int[] z)
+ {
+ int c = Nat.add(12, x, y, z);
+ if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P)))
+ {
+ Nat.sub(12, z, P, z);
+ }
+ }
+
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.add(24, xx, yy, zz);
+ if (c != 0 || (zz[23] == PExt23 && Nat.gte(24, zz, PExt)))
+ {
+ Nat.sub(24, zz, PExt, zz);
+ }
+ }
+
+ public static void addOne(int[] x, int[] z)
+ {
+ Nat.copy(12, x, z);
+ int c = Nat.inc(12, z, 0);
+ if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P)))
+ {
+ Nat.sub(12, z, P, z);
+ }
+ }
+
+ public static int[] fromBigInteger(BigInteger x)
+ {
+ int[] z = Nat.fromBigInteger(384, x);
+ if (z[11] == P11 && Nat.gte(12, z, P))
+ {
+ Nat.sub(12, z, P, z);
+ }
+ return z;
+ }
+
+ public static void half(int[] x, int[] z)
+ {
+ if ((x[0] & 1) == 0)
+ {
+ Nat.shiftDownBit(12, x, 0, z);
+ }
+ else
+ {
+ int c = Nat.add(12, x, P, z);
+ Nat.shiftDownBit(12, z, c);
+ }
+ }
+
+ public static void multiply(int[] x, int[] y, int[] z)
+ {
+ int[] tt = Nat.create(24);
+ Nat384.mul(x, y, tt);
+ reduce(tt, z);
+ }
+
+ public static void negate(int[] x, int[] z)
+ {
+ if (Nat.isZero(12, x))
+ {
+ Nat.zero(12, z);
+ }
+ else
+ {
+ Nat.sub(12, P, x, z);
+ }
+ }
+
+ public static void reduce(int[] xx, int[] z)
+ {
+ long xx12 = xx[12] & M, xx13 = xx[13] & M, xx14 = xx[14] & M, xx15 = xx[15] & M;
+ long xx16 = xx[16] & M, xx17 = xx[17] & M, xx18 = xx[18] & M, xx19 = xx[19] & M;
+ long xx20 = xx[20] & M, xx21 = xx[21] & M, xx22 = xx[22] & M, xx23 = xx[23] & M;
+
+ long cc = 0;
+ cc += (xx[0] & M) + xx12 + xx20 + xx21 - xx23;
+ z[0] = (int)cc;
+ cc >>= 32;
+ cc += (xx[1] & M) + xx13 + xx22 + xx23 - xx12 - xx20;
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (xx[2] & M) + xx14 + xx23 - xx13 - xx21;
+ z[2] = (int)cc;
+ cc >>= 32;
+ cc += (xx[3] & M) + xx12 + xx15 + xx20 + xx21 - xx14 - xx22 - xx23;
+ z[3] = (int)cc;
+ cc >>= 32;
+ cc += (xx[4] & M) + xx12 + xx13 + xx16 + xx20 + ((xx21 - xx23) << 1) + xx22 - xx15;
+ z[4] = (int)cc;
+ cc >>= 32;
+ cc += (xx[5] & M) + xx13 + xx14 + xx17 + xx21 + (xx22 << 1) + xx23 - xx16;
+ z[5] = (int)cc;
+ cc >>= 32;
+ cc += (xx[6] & M) + xx14 + xx15 + xx18 + xx22 + (xx23 << 1) - xx17;
+ z[6] = (int)cc;
+ cc >>= 32;
+ cc += (xx[7] & M) + xx15 + xx16 + xx19 + xx23 - xx18;
+ z[7] = (int)cc;
+ cc >>= 32;
+ cc += (xx[8] & M) + xx16 + xx17 + xx20 - xx19;
+ z[8] = (int)cc;
+ cc >>= 32;
+ cc += (xx[9] & M) + xx17 + xx18 + xx21 - xx20;
+ z[9] = (int)cc;
+ cc >>= 32;
+ cc += (xx[10] & M) + xx18 + xx19 + xx22 - xx21;
+ z[10] = (int)cc;
+ cc >>= 32;
+ cc += (xx[11] & M) + xx19 + xx20 + xx23 - xx22;
+ z[11] = (int)cc;
+ cc >>= 32;
+
+ int c = (int)cc;
+ if (c > 0)
+ {
+ reduce32(c, z);
+ }
+ else
+ {
+ while (c < 0)
+ {
+ c += Nat256.add(z, P, z);
+ }
+ }
+ }
+
+ public static void reduce32(int x, int[] z)
+ {
+ long xx12 = x & M;
+
+ long cc = 0;
+ cc += (z[0] & M) + xx12;
+ z[0] = (int)cc;
+ cc >>= 32;
+ cc += (z[1] & M) - xx12;
+ z[1] = (int)cc;
+ cc >>= 32;
+ cc += (z[2] & M);
+ z[2] = (int)cc;
+ cc >>= 32;
+ cc += (z[3] & M) + xx12;
+ z[3] = (int)cc;
+ cc >>= 32;
+ cc += (z[4] & M) + xx12;
+ z[4] = (int)cc;
+ cc >>= 32;
+
+// assert cc >= 0;
+
+ if (cc > 0)
+ {
+ int c = Nat.addWord(12, (int)cc, z, 5);
+ if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P)))
+ {
+ Nat.sub(12, z, P, z);
+ }
+ }
+ }
+
+ public static void square(int[] x, int[] z)
+ {
+ int[] tt = Nat.create(24);
+ Nat384.square(x, tt);
+ reduce(tt, z);
+ }
+
+ public static void squareN(int[] x, int n, int[] z)
+ {
+// assert n > 0;
+
+ int[] tt = Nat.create(24);
+ Nat384.square(x, tt);
+ reduce(tt, z);
+
+ while (--n > 0)
+ {
+ Nat384.square(z, tt);
+ reduce(tt, z);
+ }
+ }
+
+ public static void subtract(int[] x, int[] y, int[] z)
+ {
+ int c = Nat.sub(12, x, y, z);
+ if (c != 0)
+ {
+ Nat.add(12, z, P, z);
+ }
+ }
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat.sub(24, xx, yy, zz);
+ if (c != 0)
+ {
+ Nat.add(24, zz, PExt, zz);
+ }
+ }
+
+ public static void twice(int[] x, int[] z)
+ {
+ int c = Nat.shiftUpBit(12, x, 0, z);
+ if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P)))
+ {
+ Nat.sub(12, z, P, z);
+ }
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
new file mode 100644
index 00000000..b1023190
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
@@ -0,0 +1,211 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import java.math.BigInteger;
+
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.Mod;
+import org.bouncycastle.math.ec.Nat;
+import org.bouncycastle.util.Arrays;
+
+public class SecP384R1FieldElement extends ECFieldElement
+{
+ public static final BigInteger Q = SecP384R1Curve.q;
+
+ protected int[] x;
+
+ public SecP384R1FieldElement(BigInteger x)
+ {
+ if (x == null || x.signum() < 0 || x.compareTo(Q) >= 0)
+ {
+ throw new IllegalArgumentException("x value invalid for SecP384R1FieldElement");
+ }
+
+ this.x = SecP384R1Field.fromBigInteger(x);
+ }
+
+ public SecP384R1FieldElement()
+ {
+ this.x = Nat.create(12);
+ }
+
+ protected SecP384R1FieldElement(int[] x)
+ {
+ this.x = x;
+ }
+
+ public boolean isZero()
+ {
+ return Nat.isZero(12, x);
+ }
+
+ public boolean isOne()
+ {
+ return Nat.isOne(12, x);
+ }
+
+ public boolean testBitZero()
+ {
+ return Nat.getBit(x, 0) == 1;
+ }
+
+ public BigInteger toBigInteger()
+ {
+ return Nat.toBigInteger(12, x);
+ }
+
+ public String getFieldName()
+ {
+ return "SecP384R1Field";
+ }
+
+ public int getFieldSize()
+ {
+ return Q.bitLength();
+ }
+
+ public ECFieldElement add(ECFieldElement b)
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.add(x, ((SecP384R1FieldElement)b).x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement addOne()
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.addOne(x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement subtract(ECFieldElement b)
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.subtract(x, ((SecP384R1FieldElement)b).x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement multiply(ECFieldElement b)
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.multiply(x, ((SecP384R1FieldElement)b).x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement divide(ECFieldElement b)
+ {
+// return multiply(b.invert());
+ int[] z = Nat.create(12);
+ Mod.invert(SecP384R1Field.P, ((SecP384R1FieldElement)b).x, z);
+ SecP384R1Field.multiply(z, x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement negate()
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.negate(x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement square()
+ {
+ int[] z = Nat.create(12);
+ SecP384R1Field.square(x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ public ECFieldElement invert()
+ {
+// return new SecP384R1FieldElement(toBigInteger().modInverse(Q));
+ int[] z = Nat.create(12);
+ Mod.invert(SecP384R1Field.P, x, z);
+ return new SecP384R1FieldElement(z);
+ }
+
+ /**
+ * return a sqrt root - the routine verifies that the calculation returns the right value - if
+ * none exists it returns null.
+ */
+ public ECFieldElement sqrt()
+ {
+ // Raise this element to the exponent 2^382 - 2^126 - 2^94 + 2^30
+
+ int[] x1 = this.x;
+ if (Nat.isZero(12, x1) || Nat.isOne(12, x1))
+ {
+ return this;
+ }
+
+ int[] t1 = Nat.create(12);
+ int[] t2 = Nat.create(12);
+ int[] t3 = Nat.create(12);
+ int[] t4 = Nat.create(12);
+
+ SecP384R1Field.square(x1, t1);
+ SecP384R1Field.multiply(t1, x1, t1);
+
+ SecP384R1Field.squareN(t1, 2, t2);
+ SecP384R1Field.multiply(t2, t1, t2);
+
+ SecP384R1Field.square(t2, t2);
+ SecP384R1Field.multiply(t2, x1, t2);
+
+ SecP384R1Field.squareN(t2, 5, t3);
+ SecP384R1Field.multiply(t3, t2, t3);
+
+ SecP384R1Field.squareN(t3, 5, t4);
+ SecP384R1Field.multiply(t4, t2, t4);
+
+ SecP384R1Field.squareN(t4, 15, t2);
+ SecP384R1Field.multiply(t2, t4, t2);
+
+ SecP384R1Field.squareN(t2, 2, t3);
+ SecP384R1Field.multiply(t1, t3, t1);
+
+ SecP384R1Field.squareN(t3, 28, t3);
+ SecP384R1Field.multiply(t2, t3, t2);
+
+ SecP384R1Field.squareN(t2, 60, t3);
+ SecP384R1Field.multiply(t3, t2, t3);
+
+ int[] r = t2;
+
+ SecP384R1Field.squareN(t3, 120, r);
+ SecP384R1Field.multiply(r, t3, r);
+
+ SecP384R1Field.squareN(r, 15, r);
+ SecP384R1Field.multiply(r, t4, r);
+
+ SecP384R1Field.squareN(r, 33, r);
+ SecP384R1Field.multiply(r, t1, r);
+
+ SecP384R1Field.squareN(r, 64, r);
+ SecP384R1Field.multiply(r, x1, r);
+
+ SecP384R1Field.squareN(r, 30, t1);
+ SecP384R1Field.square(t1, t2);
+
+ return Nat.eq(12, x1, t2) ? new SecP384R1FieldElement(t1) : null;
+ }
+
+ public boolean equals(Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof SecP384R1FieldElement))
+ {
+ return false;
+ }
+
+ SecP384R1FieldElement o = (SecP384R1FieldElement)other;
+ return Nat.eq(12, x, o.x);
+ }
+
+ public int hashCode()
+ {
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 12);
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
new file mode 100644
index 00000000..f0076141
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
@@ -0,0 +1,320 @@
+package org.bouncycastle.math.ec.custom.sec;
+
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.Nat;
+
+public class SecP384R1Point extends ECPoint
+{
+ /**
+ * Create a point which encodes with point compression.
+ *
+ * @param curve
+ * the curve to use
+ * @param x
+ * affine x co-ordinate
+ * @param y
+ * affine y co-ordinate
+ *
+ * @deprecated Use ECCurve.createPoint to construct points
+ */
+ public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ this(curve, x, y, false);
+ }
+
+ /**
+ * Create a point that encodes with or without point compresion.
+ *
+ * @param curve
+ * the curve to use
+ * @param x
+ * affine x co-ordinate
+ * @param y
+ * affine y co-ordinate
+ * @param withCompression
+ * if true encode with point compression
+ *
+ * @deprecated per-point compression property will be removed, refer
+ * {@link #getEncoded(boolean)}
+ */
+ public SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ {
+ super(curve, x, y);
+
+ if ((x == null) != (y == null))
+ {
+ throw new IllegalArgumentException("Exactly one of the field elements is null");
+ }
+
+ this.withCompression = withCompression;
+ }
+
+ SecP384R1Point(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, boolean withCompression)
+ {
+ super(curve, x, y, zs);
+
+ this.withCompression = withCompression;
+ }
+
+ protected ECPoint detach()
+ {
+ return new SecP384R1Point(null, getAffineXCoord(), getAffineYCoord());
+ }
+
+ protected boolean getCompressionYTilde()
+ {
+ return this.getAffineYCoord().testBitZero();
+ }
+
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return this;
+ }
+ if (this == b)
+ {
+ return twice();
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.x, Y1 = (SecP384R1FieldElement)this.y;
+ SecP384R1FieldElement X2 = (SecP384R1FieldElement)b.getXCoord(), Y2 = (SecP384R1FieldElement)b.getYCoord();
+
+ SecP384R1FieldElement Z1 = (SecP384R1FieldElement)this.zs[0];
+ SecP384R1FieldElement Z2 = (SecP384R1FieldElement)b.getZCoord(0);
+
+ int[] tt1 = Nat.create(24);
+ int[] tt2 = Nat.create(24);
+ int[] t3 = Nat.create(12);
+ int[] t4 = Nat.create(12);
+
+ boolean Z1IsOne = Z1.isOne();
+ int[] U2, S2;
+ if (Z1IsOne)
+ {
+ U2 = X2.x;
+ S2 = Y2.x;
+ }
+ else
+ {
+ S2 = t3;
+ SecP384R1Field.square(Z1.x, S2);
+
+ U2 = tt2;
+ SecP384R1Field.multiply(S2, X2.x, U2);
+
+ SecP384R1Field.multiply(S2, Z1.x, S2);
+ SecP384R1Field.multiply(S2, Y2.x, S2);
+ }
+
+ boolean Z2IsOne = Z2.isOne();
+ int[] U1, S1;
+ if (Z2IsOne)
+ {
+ U1 = X1.x;
+ S1 = Y1.x;
+ }
+ else
+ {
+ S1 = t4;
+ SecP384R1Field.square(Z2.x, S1);
+
+ U1 = tt1;
+ SecP384R1Field.multiply(S1, X1.x, U1);
+
+ SecP384R1Field.multiply(S1, Z2.x, S1);
+ SecP384R1Field.multiply(S1, Y1.x, S1);
+ }
+
+ int[] H = Nat.create(12);
+ SecP384R1Field.subtract(U1, U2, H);
+
+ int[] R = Nat.create(12);// tt2;
+ SecP384R1Field.subtract(S1, S2, R);
+
+ // Check if b == this or b == -this
+ if (Nat.isZero(12, H))
+ {
+ if (Nat.isZero(12, R))
+ {
+ // this == b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this == -b, i.e. the result is the point at infinity
+ return curve.getInfinity();
+ }
+
+ int[] HSquared = t3;
+ SecP384R1Field.square(H, HSquared);
+
+ int[] G = Nat.create(12);
+ SecP384R1Field.multiply(HSquared, H, G);
+
+ int[] V = t3;
+ SecP384R1Field.multiply(HSquared, U1, V);
+
+ Nat384.mul(S1, G, tt1);
+
+ SecP384R1FieldElement X3 = new SecP384R1FieldElement(t4);
+ SecP384R1Field.square(R, X3.x);
+ SecP384R1Field.add(X3.x, G, X3.x);
+ SecP384R1Field.subtract(X3.x, V, X3.x);
+ SecP384R1Field.subtract(X3.x, V, X3.x);
+
+ SecP384R1FieldElement Y3 = new SecP384R1FieldElement(G);
+ SecP384R1Field.subtract(V, X3.x, Y3.x);
+ Nat384.mul(Y3.x, R, tt2);
+ SecP384R1Field.subtractExt(tt2, tt1, tt2);
+ SecP384R1Field.reduce(tt2, Y3.x);
+
+ SecP384R1FieldElement Z3 = new SecP384R1FieldElement(H);
+ if (!Z1IsOne)
+ {
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+ if (!Z2IsOne)
+ {
+ SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x);
+ }
+
+ ECFieldElement[] zs = new ECFieldElement[]{ Z3 };
+
+ return new SecP384R1Point(curve, X3, Y3, zs, this.withCompression);
+ }
+
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+
+ SecP384R1FieldElement Y1 = (SecP384R1FieldElement)this.y;
+ if (Y1.isZero())
+ {
+ return curve.getInfinity();
+ }
+
+ SecP384R1FieldElement X1 = (SecP384R1FieldElement)this.x, Z1 = (SecP384R1FieldElement)this.zs[0];
+
+ int[] t1 = Nat.create(12);
+ int[] t2 = Nat.create(12);
+
+ int[] Y1Squared = Nat.create(12);
+ SecP384R1Field.square(Y1.x, Y1Squared);
+
+ int[] T = Nat.create(12);
+ SecP384R1Field.square(Y1Squared, T);
+
+ boolean Z1IsOne = Z1.isOne();
+
+ int[] Z1Squared = Z1.x;
+ if (!Z1IsOne)
+ {
+ Z1Squared = t2;
+ SecP384R1Field.square(Z1.x, Z1Squared);
+ }
+
+ SecP384R1Field.subtract(X1.x, Z1Squared, t1);
+
+ int[] M = t2;
+ SecP384R1Field.add(X1.x, Z1Squared, M);
+ SecP384R1Field.multiply(M, t1, M);
+ SecP384R1Field.twice(M, t1);
+ SecP384R1Field.add(M, t1, M);
+
+ int[] S = Y1Squared;
+ SecP384R1Field.multiply(Y1Squared, X1.x, S);
+ int c = Nat.shiftUpBits(12, S, 2, 0);
+ SecP384R1Field.reduce32(c, S);
+
+ c = Nat.shiftUpBits(12, T, 3, 0, t1);
+ SecP384R1Field.reduce32(c, t1);
+
+ SecP384R1FieldElement X3 = new SecP384R1FieldElement(T);
+ SecP384R1Field.square(M, X3.x);
+ SecP384R1Field.subtract(X3.x, S, X3.x);
+ SecP384R1Field.subtract(X3.x, S, X3.x);
+
+ SecP384R1FieldElement Y3 = new SecP384R1FieldElement(S);
+ SecP384R1Field.subtract(S, X3.x, Y3.x);
+ SecP384R1Field.multiply(Y3.x, M, Y3.x);
+ SecP384R1Field.subtract(Y3.x, t1, Y3.x);
+
+ SecP384R1FieldElement Z3 = new SecP384R1FieldElement(M);
+ SecP384R1Field.twice(Y1.x, Z3.x);
+ if (!Z1IsOne)
+ {
+ SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
+ }
+
+ return new SecP384R1Point(curve, X3, Y3, new ECFieldElement[]{ Z3 }, this.withCompression);
+ }
+
+ public ECPoint twicePlus(ECPoint b)
+ {
+ if (this == b)
+ {
+ return threeTimes();
+ }
+ if (this.isInfinity())
+ {
+ return b;
+ }
+ if (b.isInfinity())
+ {
+ return twice();
+ }
+
+ ECFieldElement Y1 = this.y;
+ if (Y1.isZero())
+ {
+ return b;
+ }
+
+ return twice().add(b);
+ }
+
+ public ECPoint threeTimes()
+ {
+ if (this.isInfinity() || this.y.isZero())
+ {
+ return this;
+ }
+
+ // NOTE: Be careful about recursions between twicePlus and threeTimes
+ return twice().add(this);
+ }
+
+ public ECPoint subtract(ECPoint b)
+ {
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ // Add -b
+ return add(b.negate());
+ }
+
+ public ECPoint negate()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ return new SecP384R1Point(curve, this.x, this.y.negate(), this.zs, this.withCompression);
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
index 2d3c6ffa..df353034 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
@@ -24,7 +24,7 @@ public class SecP521R1Field
public static void addOne(int[] x, int[] z)
{
- System.arraycopy(x, 0, z, 0, 16);
+ Nat.copy(16, x, z);
int c = Nat.inc(16, z, 0) + x[16];
if (c > P16 || (c == P16 && Nat.eq(16, z, P)))
{
@@ -89,7 +89,7 @@ public class SecP521R1Field
public static void reduce23(int[] z)
{
int z16 = z[16];
- int c = Nat.addWord(16, z16 >>> 9, z) + (z16 & P16);
+ int c = Nat.addWord(16, z16 >>> 9, z, 0) + (z16 & P16);
if (c > P16 || (c == P16 && Nat.eq(16, z, P)))
{
c += Nat.inc(16, z, 0);
@@ -133,13 +133,9 @@ public class SecP521R1Field
public static void twice(int[] x, int[] z)
{
- int c = Nat.shiftUpBit(16, x, 0, z) | (x[16] << 1);
- if (c > P16 || (c == P16 && Nat.eq(16, z, P)))
- {
- c += Nat.inc(16, z, 0);
- c &= P16;
- }
- z[16] = c;
+ int x16 = x[16];
+ int c = Nat.shiftUpBit(16, x, x16 << 23, z) | (x16 << 1);
+ z[16] = c & P16;
}
protected static void implMultiply(int[] x, int[] y, int[] zz)
@@ -155,6 +151,6 @@ public class SecP521R1Field
Nat512.square(x, zz);
int x16 = x[16];
- zz[32] = Nat.mulWordAdd(16, x16 << 1, x, zz, 16) + (x16 * x16);
+ zz[32] = Nat.mulWordAddTo(16, x16 << 1, x, 0, zz, 16) + (x16 * x16);
}
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
index 0a395a76..785abaa1 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
@@ -143,7 +143,7 @@ public class SecP521R1FieldElement extends ECFieldElement
SecP521R1Field.squareN(x1, 519, t1);
SecP521R1Field.square(t1, t2);
- return Arrays.areEqual(x1, t2) ? new SecP521R1FieldElement(t1) : null;
+ return Nat.eq(17, x1, t2) ? new SecP521R1FieldElement(t1) : null;
}
public boolean equals(Object other)
@@ -159,11 +159,11 @@ public class SecP521R1FieldElement extends ECFieldElement
}
SecP521R1FieldElement o = (SecP521R1FieldElement)other;
- return Arrays.areEqual(x, o.x);
+ return Nat.eq(17, x, o.x);
}
public int hashCode()
{
- return Q.hashCode() ^ Arrays.hashCode(x);
+ return Q.hashCode() ^ Arrays.hashCode(x, 0, 17);
}
}
diff --git a/core/src/main/java/org/bouncycastle/util/Arrays.java b/core/src/main/java/org/bouncycastle/util/Arrays.java
index 9390fbed..3de0f7a2 100644
--- a/core/src/main/java/org/bouncycastle/util/Arrays.java
+++ b/core/src/main/java/org/bouncycastle/util/Arrays.java
@@ -323,6 +323,25 @@ public final class Arrays
return hc;
}
+
+ public static int hashCode(byte[] data, int off, int len)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = len;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[off + i];
+ }
+
+ return hc;
+ }
public static int hashCode(char[] data)
{
@@ -374,6 +393,25 @@ public final class Arrays
return hc;
}
+ public static int hashCode(int[] data, int off, int len)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = len;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ hc *= 257;
+ hc ^= data[off + i];
+ }
+
+ return hc;
+ }
+
public static int hashCode(short[][][] shorts)
{
int hc = 0;
diff --git a/core/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java b/core/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java
index 1ef8f51b..ddcfc34f 100644
--- a/core/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java
+++ b/core/src/main/java/org/bouncycastle/util/encoders/Base64Encoder.java
@@ -7,20 +7,20 @@ public class Base64Encoder
implements Encoder
{
protected final byte[] encodingTable =
- {
- (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
- (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
- (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
- (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
- (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
- (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
- (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
- (byte)'v',
- (byte)'w', (byte)'x', (byte)'y', (byte)'z',
- (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
- (byte)'7', (byte)'8', (byte)'9',
- (byte)'+', (byte)'/'
- };
+ {
+ (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+ (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+ (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+ (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+ (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+ (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+ (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+ (byte)'v',
+ (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+ (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
+ (byte)'7', (byte)'8', (byte)'9',
+ (byte)'+', (byte)'/'
+ };
protected byte padding = (byte)'=';
diff --git a/core/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java b/core/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java
index 3bb594b0..3069c77d 100644
--- a/core/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java
+++ b/core/src/main/java/org/bouncycastle/util/encoders/HexEncoder.java
@@ -7,11 +7,11 @@ public class HexEncoder
implements Encoder
{
protected final byte[] encodingTable =
- {
- (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
- (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
- };
-
+ {
+ (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
+ (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
+ };
+
/*
* set up the decoding table.
*/
diff --git a/core/src/test/data/org/bouncycastle/cms/test/PSSSignData.data b/core/src/test/data/org/bouncycastle/cms/test/PSSSignData.data
deleted file mode 100644
index ab51e847..00000000
--- a/core/src/test/data/org/bouncycastle/cms/test/PSSSignData.data
+++ /dev/null
@@ -1 +0,0 @@
-This is a test message \ No newline at end of file
diff --git a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1.sig b/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1.sig
deleted file mode 100644
index 1ecfd010..00000000
--- a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1.sig
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1Enc.sig b/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1Enc.sig
deleted file mode 100644
index 2f7e7b67..00000000
--- a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA1Enc.sig
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256.sig b/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256.sig
deleted file mode 100644
index 114c592d..00000000
--- a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256.sig
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256Enc.sig b/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256Enc.sig
deleted file mode 100644
index 28bb8110..00000000
--- a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA256Enc.sig
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512.sig b/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512.sig
deleted file mode 100644
index eb3429ba..00000000
--- a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512.sig
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512Enc.sig b/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512Enc.sig
deleted file mode 100644
index 91556c68..00000000
--- a/core/src/test/data/org/bouncycastle/cms/test/PSSSignDataSHA512Enc.sig
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/cms/test/counterSig.p7m b/core/src/test/data/org/bouncycastle/cms/test/counterSig.p7m
deleted file mode 100644
index 7d82b99c..00000000
--- a/core/src/test/data/org/bouncycastle/cms/test/counterSig.p7m
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/eac/test/Belgique CVCA-02032010.7816.cvcert b/core/src/test/data/org/bouncycastle/eac/test/Belgique CVCA-02032010.7816.cvcert
deleted file mode 100644
index dd2e0e4a..00000000
--- a/core/src/test/data/org/bouncycastle/eac/test/Belgique CVCA-02032010.7816.cvcert
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/eac/test/REQ_18102010.csr b/core/src/test/data/org/bouncycastle/eac/test/REQ_18102010.csr
deleted file mode 100644
index 15b49e86..00000000
--- a/core/src/test/data/org/bouncycastle/eac/test/REQ_18102010.csr
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/eac/test/at_cert_19a.cvcert b/core/src/test/data/org/bouncycastle/eac/test/at_cert_19a.cvcert
deleted file mode 100644
index 16733207..00000000
--- a/core/src/test/data/org/bouncycastle/eac/test/at_cert_19a.cvcert
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/eac/test/dv_cer_BEDVBUZABE006_7816.cvcert b/core/src/test/data/org/bouncycastle/eac/test/dv_cer_BEDVBUZABE006_7816.cvcert
deleted file mode 100644
index 0e3ea89b..00000000
--- a/core/src/test/data/org/bouncycastle/eac/test/dv_cer_BEDVBUZABE006_7816.cvcert
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.cer b/core/src/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.cer
deleted file mode 100644
index 14dfab30..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.cer
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.crl b/core/src/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.crl
deleted file mode 100644
index 06628261..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/ThawteSGCCA.crl
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.p12
deleted file mode 100644
index 79fe2f2f..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.pem
deleted file mode 100644
index 3e507ba9..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-A.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAC0dXvAI0/fhu22j15YEo
-F8M3OYM8fwlvxs2/qtwELR3hVckpRIJmfGpUutb6/TBPgTS8a/fmzcrxLsL/aGSD
-jH4/TmTHrRmhlT/einuudpAXPxaS27Yz7duxRPmyXeyHy3P0ulXDEzOaZdV8kxQs
-J/v+z0knwdAh91omHRfJuNxDQtLfjp1Qtz+jrBCI6s864UblKXG/AwjWOLFQ1E0N
-A2bDo72tr3aw01gryggFkyNrB9K5/15+jJLVLFjuJfP7m3FUjPfGQB9+eZMBWpNH
-hGcSsPibqWVTDMjN0Z/mTGMzZDsEXX0Ao1K21q5vK1sfFYEahv/PCwkcW1dOeTGF
-pQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.p12
deleted file mode 100644
index ef501322..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.pem
deleted file mode 100644
index 6c449109..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-B.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAIYpxwPMRRjPuRBsWKhB0
-ACZHEaO6RtSwu28sHO2TF1o0kHONAnqR37OhMuPR70qBynd5dVDkjpxXUfxhLDPh
-jdaxXuj2vMrbAvDJFsIsKDatlc632IsicSR4DVEnpJmUtLBQFC2VylHMxkGoo5eJ
-dsf5ZY/QqUXf+VReLWfyQXEaSGe8nI7fP61xqTsgzcN4ziqkKSKGvsEtPU/oo23Y
-xZDJpRMPdzu7TqkP3PnzRFy6HUamM2Xpyl2qeYELtGu7nuoSaF/1AX21bPtU9N9N
-+wbxlGuq7NVIKdlIaoQ3FfgCVZGrVwjr7uxow7Gob+pWJJKjOS+IlSRL0MqH1t/U
-yQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.p12
deleted file mode 100644
index 72527d63..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.pem
deleted file mode 100644
index f844ee47..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-C.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAkWkqxLQH4vvX5e2oiydv
-VN8Et+ZznJ78yifF7Tctjm9+EfEBRupHwXHlAZd2n2CsZfhVTqk/Rnffb078X3g5
-9jx9ka0/hhkYyG6XqLybS3yXVpC/mvaeQMRu0Ubi0uSOkcf6rYiaqGjcG5DRaSAz
-SNNrDTEDYNxsuaPJoxZtQ+o1VaB3ksJ2UanzAHy45IJKXlSWS4l0Xsu6NZJxeMLB
-0iL0j5+TcaK37dkNpDi4dhFbeOi30Q8rvC5BDorFMM8GEl+GevH6Rpk0P67WlnOY
-qeDoKjzKi1w0ZDBS8XI95DLsmnHXcg2Iu8Dx1iBJMFST6mLtsMdVQAD+y2NTkbpM
-xA==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.p12
deleted file mode 100644
index c2fa40bb..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.pem
deleted file mode 100644
index 6f93f1c0..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-D.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAkSFw/c7vnAAs4wKzS24X
-oyJrIiazcZD4A2ioqWMQD+QxFJlplJsyE5vcyVxv5Pww5Od1aPJCsSEd/C7h12eA
-576kkQcbv5KQ8LUlpj6eRjzI4E97yc9Yi9C3YibniGCv5mxLpw2bOxix9l8EBj6h
-vTfDMdoQVXkGyI2TCbYppkffJgxrL/wj82XbYeIHL27REf4+bNVRYD3LMXl7koPc
-4vUC6lyxYUELfv6UnAzppqDl+LSUkKvQEe26syIUAE3ArGvy/aYjIYBCwQQu4r9H
-WnXdIvcTdZqi3x9z/aN8Or9/IYIXpk3td6lLqI/DUwkPRS6zcthDo3x/1IFhUCB3
-KQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.p12
deleted file mode 100644
index 02656421..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.pem
deleted file mode 100644
index 0c30777d..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-E.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAkFwewElSyXCGG2ygI3I4
-iYLtjAJAy002ES4JGHvr39dNhYoZ1poop18AU52mrx+SKX5vc/hAipisVa0rK9Jl
-91GF5NQdhU0KWxNCBHZAy3dUf1M63jvTC3eiG8LVV+C77Cx936i8qO5f3qWCN40z
-4W8eMwkCoVtpfzuuHk1by0VwCgU5IYuNIrwxR1bjudOctyhXNJjgr3SIsjDrqpTA
-nS4AauNFVqFfSyyaw5AX+7eA/WrMOGdJBJT1bEhHqrWxLtQzwSzKBKu7FpuF3mVX
-SHcSW4AzA6Yzq2Hcedo+SJt96IDr5xT17ncPMBzdq9pdoHlyJVq9+3O5JQOTx1WD
-6g==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.p12
deleted file mode 100644
index 58410dca..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.pem
deleted file mode 100644
index fcc52054..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-F.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAaiR5Rnhj/vUqDgVqHaJk
-0VcMuvDzkQVmUlAZlsDa3uH3CW43yAXXM6ahacYnOgpLB96aq6cI8E74hHzO6PU6
-M50LLdp+KWu5InQv7+6fgSpShRxnHBKigCuoLy6oKFkCTTnnK002Mplr8+eHZHbi
-clm+k9rQejNalv+P9GSE5JcIEkTSXUDbfe81/ej9DCOcGbFPuL5hFQ8GNIuf+uv2
-OKXQtdpuayFZnD3hoWYE1LMT5W1lK1Jewx03phYeCMAY+MibRhzXWLDMBiwXpvW8
-cgCv777p+tRedunb5eLF+FT+/r617rskD9i9mJjqvoxQaXaYe++UX5mt9xpXZ9oM
-1g==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.p12
deleted file mode 100644
index c8184a25..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.pem
deleted file mode 100644
index d10c2283..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-G.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAoLujmlhRD05T4G8CQa+g
-kIW/l43pazV1+iWaPnADd3/ywX7BNrVkGDaJHPci1BBq8lsiIA9nu7Gfxjl9TsZe
-wwLzZ/LxI9tTR+ikYxy0MID+x45rk1dF0nnya9S3wQAXDhP8ZKN0d8ezvbQ2N2LG
-74YPAtQZngMLMvYlG6MgoDNYOHHDkYZ6uL8PEwU9DtlZ+JPwxI7o7/E/T3XdDpvI
-UcI15axKbD5QMqGQxZwgQYFVMDvKou1upkLQ6ymHYgEzSqNNSzTYVdhVrGgTX+xl
-VZQFdJqR/gkloXbzxC/WqFTGrX1WN6kMvL+ZnVEh7DWELPmLFMfoWYCd4Q2hIjdx
-MQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.p12
deleted file mode 100644
index b38c9eb7..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.pem
deleted file mode 100644
index 0cab0750..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-H.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAPaezAGexMlsmptKQBlrV
-iTDBKfTs555wM05d0CRzd6dq9GHYNk/BMPy0mPmpxLwuyQqjB3rw9+mlGre1jcLf
-Kthaz+Vna1yIGqg5dqqdu7NUX6/8x51hKQ+8B3rmlqx3wjt+bWgo2Qgl8otrHXKY
-EWrKfmTNd3z0+nklqaLFvxmQwQ33CKciw6k9A2O3DaOdf1smCfFyjF/hi4I0pJaX
-vFB/CbCAF/zVmQW+uXMNooZmd+DcKsK5ZN6LzxDXC6iqqaN0WS1kmctjYQ4pOomg
-5pdKfv+gUwUqUTbtL2/WeyuOcHY9XLluYk+nwtdFS25uQpmHZcQ4baeKB5N9IJy8
-jg==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.p12
deleted file mode 100644
index 7b97f68d..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.pem
deleted file mode 100644
index 8717fd86..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-I.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAJanu4ytjXr/ppQEiEsJ3
-1TqGBIoASHHWZsjd4DZmigBgERJqtXK/AsTsljFrSo1lhP3Q9TFqOeikvJ5T3y4q
-8yYY5qaEICsjUuySTIT3r7O00O5mtpdnpsRkBceqvBDDqfWefau00SVoBaqmt2P+
-Bq3x4l7MYqJNI8fPNVHqhSBlnWfxgYO/GZd4ZshhOZgrb96B98XpRlD5uYSlTpJt
-cYvSb2s+BX4RCZIGSpoQJ0dgz3uU5H5i949fbuTbyGLVka0t8gvWN0IPoSPEp3Zj
-mEw5Oz2UV0/R0qF2/yeKKNH3aFMEAzYUAmVqA5OdWiiZgLYcIm6pQvT0iAtgnT9x
-rQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.p12
deleted file mode 100644
index 4073ea60..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.pem
deleted file mode 100644
index c3fba793..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-J.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEADFGQ9QEI1TU+qRg2QFLZ
-OhYryOaAXNOaEBR+f0LCG5My9j0vI3/1BKHwq6kVPVDkfSPrrX1ZNUPOAI+PLrwI
-RGsJw6ST8dyWXeY4LEarHOPLvSTD2u+WaPcRMJSsSTFnsscKgrAeu4VfZixOTpBp
-tI3bfqTPkY9Fra8R1M9PbNsPik0WI34nPS0T9XqF+s/FhHCcL/mX/Hj5aD0qEZWd
-wCSJGDyoZRQeMc7LowMGHpu1eqcqfSLt2TCPeXebVB031AioCe1iJUddb9WxHixH
-GyNlzJl7YwztT9Z3yRqHKde6Dun128N2YThQ/7/Dn54hXcWQCK4gFCTz2deD5S9Z
-TQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.p12 b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.p12
deleted file mode 100644
index 50b3b76f..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.p12
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.pem b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.pem
deleted file mode 100644
index b9805f5b..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/self-testcase-L.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBsMQswCQYDVQQGEwJHQjES
-MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
-eSBDb21wYW55IEx0ZDEKMAgGA1UECxMBYTESMBAGA1UEAxMJbG9jYWxob3N0MB4X
-DTA2MDkxMzE4MjYzMloXDTA3MDkxMzE4MjYzMlowbDELMAkGA1UEBhMCR0IxEjAQ
-BgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMOTXkg
-Q29tcGFueSBMdGQxCjAIBgNVBAsTAWExEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtexL4ZP1CWMsVedm+pD2xPG+md
-VbRqkVSDQYxrHUyRVKletjluY95908bsAlJR9oK/YehXe9W7r+LnotaR+yy1P45g
-hSWa6TNl1sz3NGIZwdU9WdqdNNs9YyDgzFezxzZffrh9xFTSF0CR66Tm1VasKa20
-69RTx4fE5n4kZx+DKfBGCX3PBprvIANZp0nrfuhf21ij9lORI9OkITwqR72PrybB
-9QDZB+7og1jGLAGbRBNR61mLVfKrg2yJVhpk1dHPsUzeVr3BB5XK8i7DvflWw5di
-PeyU4S7qm7WLZ9Wdg1XOchkQWmzqEUPG71dGzG6joPhdp56LFg2Yg58myRcCAwEA
-AaOByTCBxjAdBgNVHQ4EFgQUPd6mAcGQZ8iNGajt0kffN4AeDZswgZYGA1UdIwSB
-jjCBi4AUPd6mAcGQZ8iNGajt0kffN4AeDZuhcKRuMGwxCzAJBgNVBAYTAkdCMRIw
-EAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15
-IENvbXBhbnkgTHRkMQowCAYDVQQLEwFhMRIwEAYDVQQDEwlsb2NhbGhvc3SCAQAw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOCAQEAoArZH56QUnasmPqCd68C
-kcG6hw5S6p7wloY9jz+iwh9b2tF3k1SPCeE7rBV7cevr1ruv/wWttBFiGfJK/hlL
-8C/MMPj1X5JuLY3JgNmNDSK9MLr5Ejvps0AQ+kA4CCSxxpTLWeUlqNnGk/Zcfoqa
-Gyk37PDlHMQC3QWLgAX+wG/rg8WvrAP1ZjM6t25yb6hIPZgCWZbq+j8X5kS3Qxz0
-buc9HMi9oeuejeP7zWRJHhnCcDuClmpI6pk9nkjmunYtF2rMWi7f2eJ0Qjbo1wnn
-rUU5sCGLZ6i3ux/HvMgynho7RVqV+bqV+G9wZem3crNbtLhUSB2SAgYZnMqrLcW9
-jQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAq17Evhk/UJYyxV52b6kPbE8b6Z1VtGqRVINBjGsdTJFUqV62
-OW5j3n3TxuwCUlH2gr9h6Fd71buv4uei1pH7LLU/jmCFJZrpM2XWzPc0YhnB1T1Z
-2p002z1jIODMV7PHNl9+uH3EVNIXQJHrpObVVqwprbTr1FPHh8TmfiRnH4Mp8EYJ
-fc8Gmu8gA1mnSet+6F/bWKP2U5Ej06QhPCpHvY+vJsH1ANkH7uiDWMYsAZtEE1Hr
-WYtV8quDbIlWGmTV0c+xTN5WvcEHlcryLsO9+VbDl2I97JThLuqbtYtn1Z2DVc5y
-GRBabOoRQ8bvV0bMbqOg+F2nnosWDZiDnybJFwIDAQABAoIBAGA8GNn0DaUwo5RI
-htQPqVSWXENlklJ9od1G1FGJeWudFWEDietYfYbdPEcyE9+snXUxCkdSkX0mKBCR
-KdW7JsUlh2pp83t5scmmP+jcTbNlaX9ZM5Nbwun3YCp/cuExWQbEu8HZBp7nWB1v
-lFgHNPi2N7WPqvuSjLNGtHVT9gEwWGUl1zfbuZp8pNT4r1l7nwj+S9pGF3v5RXDt
-qZWSbfPF3ESPkMOpXxGk5uDLx3aoeHBQALVjeNdVlkyxjrG75Pv7ZnrmXjXzcuVv
-aVACiCPWxzaRFR9cRCx/Z34KrJorLglrfIPIrRMKJY33QO2gpYYEpFkLsLth/Ip4
-NMSJ3KkCgYEA36skUOFK0iQcdEaUXR2zcvQd3P3ctxe0JqD7dHFWnY2ndA5+VvAP
-vUjemZgw+tNt1qjLCAwxMi4cEOEICG6zSlMBRcVbqkKPS3gd3fGvD/lfQZ02EePz
-6KYVC7xz1WXIcId/HvkBNmbPEyOLqi9fIJQoYrM3LnB3AFIUqQ4K3UMCgYEAxCRT
-Z6yLGFb6Evkvvc6usqDhpAjWaaTSxlsSf9IGsKXW90OronB1IiTaWgJze1PrwWy4
-z4YOSI8oEEpF7LdwI9hztg9wFGht8lahGkfHtgR7V/QzyLMYfcU/57STI9vvsw2S
-FNqIdeP1Bd/CE8iI6o6HOAadsWlTBBUBUtnZnZ0CgYA/ecthpL5eKt9kZE9gqbgu
-rHb5K5aC45g9yjvyjOO+7N+UATT7qT9eQZrizh1AYdZvMBIGo6cmjY1rgOGNuxTo
-x+u5iEv+YstV6K3ZOeiryOKutVYN97pV0SRx4zagXjVnMhzyhkpAzSaBUPom/zCp
-B0L618+WP1aWYbT5UUHmDwKBgA3Ju+86yuBgJN42lCuUnuVBt/rvABuXEZYOCuPf
-YMcEMXNaV3No0mMfEhZnu7R8tsL3IJq+Ar0JCzjx765vSrvKWIAA39EfcjMp8dNG
-HnzmHcGWEhnWtS8KMa7ZG8rWiCgfGRjML/GRn8TU8PCxFSbf9BN1K5qwG7zauSgY
-1lplAoGAfl1Qw77H27TYGMVBgco/2g05MaKb8TZ4PKn1znlPnNcqFEBi779W0/dD
-Zgb1mjnRQkw68Jj5XA2zv/06yjvTS+nHVEDCdgIrZI2p1IrI3F4tihSoWgYtoe+8
-5OVDiHQ73d6lxVLqIRoRic8ZtWR02PbrK5SmoPsFdeTcmtzqo6c=
------END RSA PRIVATE KEY-----
diff --git a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/testcases.README b/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/testcases.README
deleted file mode 100644
index 64857402..00000000
--- a/core/src/test/data/org/bouncycastle/jce/provider/test/rsa3/testcases.README
+++ /dev/null
Binary files differ
diff --git a/core/src/test/data/org/bouncycastle/tsp/test/FileDaFirmare.data b/core/src/test/data/org/bouncycastle/tsp/test/FileDaFirmare.data
deleted file mode 100644
index 836a9fcc..00000000
--- a/core/src/test/data/org/bouncycastle/tsp/test/FileDaFirmare.data
+++ /dev/null
@@ -1,3 +0,0 @@
-INIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINIZIOINI
-dati da firmaredati da firmaredati da firmaredati da firmaredati da firmare
-FINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFINEFIN \ No newline at end of file
diff --git a/core/src/test/data/org/bouncycastle/tsp/test/FileDaFirmare.txt.tsd.der b/core/src/test/data/org/bouncycastle/tsp/test/FileDaFirmare.txt.tsd.der
deleted file mode 100644
index 1686986e..00000000
--- a/core/src/test/data/org/bouncycastle/tsp/test/FileDaFirmare.txt.tsd.der
+++ /dev/null
Binary files differ
diff --git a/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java b/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
index 18b81efe..ac7f83f5 100644
--- a/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
+++ b/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
@@ -426,7 +426,13 @@ public class ECPointTest extends TestCase
implTestAddSubtract(q, infinity);
implTestMultiply(q, n.bitLength());
implTestMultiply(infinity, n.bitLength());
- implTestEncoding(q);
+
+ ECPoint p = q;
+ for (int i = 0; i < 10; ++i)
+ {
+ implTestEncoding(p);
+ p = p.twice();
+ }
}
private void implAddSubtractMultiplyTwiceEncodingTestAllCoords(X9ECParameters x9ECParameters)