diff options
Diffstat (limited to 'core/src')
9 files changed, 225 insertions, 185 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/ec/ECElGamalEncryptor.java b/core/src/main/java/org/bouncycastle/crypto/ec/ECElGamalEncryptor.java index 0e893ea1..a5296830 100644 --- a/core/src/main/java/org/bouncycastle/crypto/ec/ECElGamalEncryptor.java +++ b/core/src/main/java/org/bouncycastle/crypto/ec/ECElGamalEncryptor.java @@ -7,7 +7,9 @@ import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.math.ec.ECMultiplier; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; /** * this does your basic ElGamal encryption algorithm using EC @@ -65,8 +67,10 @@ public class ECElGamalEncryptor ECDomainParameters ec = key.getParameters(); BigInteger k = ECUtil.generateK(ec.getN(), random); + ECMultiplier basePointMultiplier = new FixedPointCombMultiplier(); + ECPoint[] gamma_phi = new ECPoint[]{ - ec.getG().multiply(k), + basePointMultiplier.multiply(ec.getG(), k), key.getQ().multiply(k).add(point) }; diff --git a/core/src/main/java/org/bouncycastle/crypto/ec/ECFixedTransform.java b/core/src/main/java/org/bouncycastle/crypto/ec/ECFixedTransform.java index c382059d..02f5ca37 100644 --- a/core/src/main/java/org/bouncycastle/crypto/ec/ECFixedTransform.java +++ b/core/src/main/java/org/bouncycastle/crypto/ec/ECFixedTransform.java @@ -5,7 +5,9 @@ import java.math.BigInteger; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.math.ec.ECMultiplier; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; /** * this transforms the original randomness used for an ElGamal encryption by a fixed value. @@ -39,7 +41,7 @@ public class ECFixedTransform } /** - * Transform an existing cipher test pair using the ElGamal algorithm. Note: it is assumed this + * Transform an existing cipher text pair using the ElGamal algorithm. Note: it is assumed this * transform has been initialised with the same public key that was used to create the original * cipher text. * @@ -54,9 +56,13 @@ public class ECFixedTransform } ECDomainParameters ec = key.getParameters(); + BigInteger n = ec.getN(); + + ECMultiplier basePointMultiplier = new FixedPointCombMultiplier(); + BigInteger k = this.k.mod(n); ECPoint[] gamma_phi = new ECPoint[]{ - ec.getG().multiply(k).add(cipherText.getX()), + basePointMultiplier.multiply(ec.getG(), k).add(cipherText.getX()), key.getQ().multiply(k).add(cipherText.getY()) }; diff --git a/core/src/main/java/org/bouncycastle/crypto/ec/ECNewPublicKeyTransform.java b/core/src/main/java/org/bouncycastle/crypto/ec/ECNewPublicKeyTransform.java index 74016c18..9f7a0bf1 100644 --- a/core/src/main/java/org/bouncycastle/crypto/ec/ECNewPublicKeyTransform.java +++ b/core/src/main/java/org/bouncycastle/crypto/ec/ECNewPublicKeyTransform.java @@ -4,9 +4,12 @@ import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.math.ec.ECMultiplier; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; /** * this does your basic Elgamal encryption algorithm using EC @@ -49,7 +52,7 @@ public class ECNewPublicKeyTransform } /** - * Transform an existing cipher test pair using the ElGamal algorithm. Note: the input cipherText will + * Transform an existing cipher text pair using the ElGamal algorithm. Note: the input cipherText will * need to be preserved in order to complete the transformation to the new public key. * * @param cipherText the EC point to process. @@ -62,13 +65,19 @@ public class ECNewPublicKeyTransform throw new IllegalStateException("ECNewPublicKeyTransform not initialised"); } - BigInteger n = key.getParameters().getN(); - BigInteger k = ECUtil.generateK(n, random); + ECDomainParameters ec = key.getParameters(); + BigInteger n = ec.getN(); - ECPoint g = key.getParameters().getG(); - ECPoint gamma = g.multiply(k); - ECPoint phi = key.getQ().multiply(k).add(cipherText.getY()); + ECMultiplier basePointMultiplier = new FixedPointCombMultiplier(); + BigInteger k = ECUtil.generateK(n, random); - return new ECPair(gamma.normalize(), phi.normalize()); + ECPoint[] gamma_phi = new ECPoint[]{ + basePointMultiplier.multiply(ec.getG(), k), + key.getQ().multiply(k).add(cipherText.getY()) + }; + + ec.getCurve().normalizeAll(gamma_phi); + + return new ECPair(gamma_phi[0], gamma_phi[1]); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/ec/ECNewRandomnessTransform.java b/core/src/main/java/org/bouncycastle/crypto/ec/ECNewRandomnessTransform.java index b293759a..c146a0fb 100644 --- a/core/src/main/java/org/bouncycastle/crypto/ec/ECNewRandomnessTransform.java +++ b/core/src/main/java/org/bouncycastle/crypto/ec/ECNewRandomnessTransform.java @@ -4,9 +4,12 @@ import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.math.ec.ECMultiplier; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; /** * this transforms the original randomness used for an ElGamal encryption. @@ -66,16 +69,23 @@ public class ECNewRandomnessTransform throw new IllegalStateException("ECNewRandomnessTransform not initialised"); } - BigInteger n = key.getParameters().getN(); - BigInteger k = ECUtil.generateK(n, random); - ECPoint g = key.getParameters().getG(); - ECPoint gamma = g.multiply(k); - ECPoint phi = key.getQ().multiply(k).add(cipherText.getY()); + ECDomainParameters ec = key.getParameters(); + BigInteger n = ec.getN(); + + ECMultiplier basePointMultiplier = new FixedPointCombMultiplier(); + BigInteger k = ECUtil.generateK(n, random); + + ECPoint[] gamma_phi = new ECPoint[]{ + basePointMultiplier.multiply(ec.getG(), k).add(cipherText.getX()), + key.getQ().multiply(k).add(cipherText.getY()) + }; + + ec.getCurve().normalizeAll(gamma_phi); lastK = k; - return new ECPair(cipherText.getX().add(gamma).normalize(), phi.normalize()); + return new ECPair(gamma_phi[0], gamma_phi[1]); } /** diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java index d5f5fc85..38807a4c 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java @@ -12,6 +12,7 @@ import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; public class ECKeyPairGenerator implements AsymmetricCipherKeyPairGenerator, ECConstants @@ -49,7 +50,7 @@ public class ECKeyPairGenerator } while (d.equals(ZERO) || (d.compareTo(n) >= 0)); - ECPoint Q = params.getG().multiply(d); + ECPoint Q = new FixedPointCombMultiplier().multiply(params.getG(), d); return new AsymmetricCipherKeyPair( new ECPublicKeyParameters(Q, params), diff --git a/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKeyEncapsulation.java b/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKeyEncapsulation.java index dcdb752a..746d26ca 100755 --- a/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKeyEncapsulation.java +++ b/core/src/main/java/org/bouncycastle/crypto/kems/ECIESKeyEncapsulation.java @@ -13,7 +13,9 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.KDFParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECMultiplier; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; @@ -121,8 +123,10 @@ public class ECIESKeyEncapsulation // Compute the static-ephemeral key agreement BigInteger rPrime = CofactorMode ? r.multiply(h).mod(n) : r; + ECMultiplier basePointMultiplier = new FixedPointCombMultiplier(); + ECPoint[] ghTilde = new ECPoint[]{ - ecParams.getG().multiply(r), + basePointMultiplier.multiply(ecParams.getG(), r), ecPubKey.getQ().multiply(rPrime) }; diff --git a/core/src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java b/core/src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java index 8d326ffd..a5607d5a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java +++ b/core/src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java @@ -6,7 +6,9 @@ import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECMultiplier; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; @@ -70,6 +72,7 @@ public class DualECSP800DRBG private ECPoint _Q; private byte[] _s; private int _sLength; + private ECMultiplier _fixedPointMultiplier = new FixedPointCombMultiplier(); /** * Construct a SP800-90A Dual EC DRBG. @@ -199,7 +202,7 @@ public class DualECSP800DRBG //System.err.println("S: " + new String(Hex.encode(_s))); - byte[] r = _Q.multiply(s).normalize().getAffineXCoord().toBigInteger().toByteArray(); + byte[] r = getScalarMultipleXCoord(_Q, s).toByteArray(); if (r.length > _outlen) { @@ -220,7 +223,7 @@ public class DualECSP800DRBG { s = getScalarMultipleXCoord(_P, s); - byte[] r = _Q.multiply(s).normalize().getAffineXCoord().toBigInteger().toByteArray(); + byte[] r = getScalarMultipleXCoord(_Q, s).toByteArray(); int required = output.length - outOffset; @@ -237,7 +240,7 @@ public class DualECSP800DRBG } // Need to preserve length of S as unsigned int. - _s = BigIntegers.asUnsignedByteArray(_sLength, _P.multiply(s).normalize().getAffineXCoord().toBigInteger()); + _s = BigIntegers.asUnsignedByteArray(_sLength, getScalarMultipleXCoord(_P, s)); return numberOfBits; } @@ -302,6 +305,6 @@ public class DualECSP800DRBG private BigInteger getScalarMultipleXCoord(ECPoint p, BigInteger s) { - return p.multiply(s).normalize().getAffineXCoord().toBigInteger(); + return _fixedPointMultiplier.multiply(p, s).normalize().getAffineXCoord().toBigInteger(); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java index bcc4edf2..0a3ef37f 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java @@ -13,7 +13,9 @@ import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.math.ec.ECAlgorithms; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; +import org.bouncycastle.math.ec.ECMultiplier; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; import org.bouncycastle.util.Arrays; /** @@ -57,9 +59,9 @@ public class DSTU4145Signer public BigInteger[] generateSignature(byte[] message) { - ECDomainParameters parameters = key.getParameters(); + ECDomainParameters ec = key.getParameters(); - ECCurve curve = parameters.getCurve(); + ECCurve curve = ec.getCurve(); ECFieldElement h = hash2FieldElement(curve, message); if (h.isZero()) @@ -67,10 +69,14 @@ public class DSTU4145Signer h = curve.fromBigInteger(ONE); } - BigInteger n = parameters.getN(); + BigInteger n = ec.getN(); BigInteger e, r, s; ECFieldElement Fe, y; + BigInteger d = ((ECPrivateKeyParameters)key).getD(); + + ECMultiplier basePointMultiplier = new FixedPointCombMultiplier(); + do { do @@ -78,7 +84,7 @@ public class DSTU4145Signer do { e = generateRandomInteger(n, random); - Fe = parameters.getG().multiply(e).normalize().getAffineXCoord(); + Fe = basePointMultiplier.multiply(ec.getG(), e).normalize().getAffineXCoord(); } while (Fe.isZero()); @@ -87,7 +93,7 @@ public class DSTU4145Signer } while (r.signum() == 0); - s = r.multiply(((ECPrivateKeyParameters)key).getD()).add(e).mod(n); + s = r.multiply(d).add(e).mod(n); } while (s.signum() == 0); 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 f6d7f4fa..47dc6bd9 100644 --- a/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java +++ b/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java @@ -1,158 +1,155 @@ -package org.bouncycastle.crypto.signers; - -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DSA; -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.ECPoint; - -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); - BigInteger n = key.getParameters().getN(); - - BigInteger r = null; - BigInteger s = null; - - do // generate s - { - BigInteger k = null; - - do // generate r - { - do - { - k = new BigInteger(n.bitLength(), random); - } - while (k.equals(ECConstants.ZERO)); - - ECPoint p = key.getParameters().getG().multiply(k).normalize(); - - BigInteger x = p.getAffineXCoord().toBigInteger(); - - r = x.mod(n); - } - while (r.equals(ECConstants.ZERO)); - - BigInteger d = ((ECPrivateKeyParameters)key).getD(); - - s = (k.multiply(e)).add(d.multiply(r)).mod(n); - } - while (s.equals(ECConstants.ZERO)); - - BigInteger[] res = new BigInteger[2]; - - res[0] = r; - res[1] = s; - - return res; - } - - /** - * 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);
+ }
+}
|