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

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/bouncycastle/crypto/signers')
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/DSADigestSigner.java163
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/DSAKCalculator.java41
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java168
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java170
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java197
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java160
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java188
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/GOST3410Signer.java131
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/GenericSigner.java136
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java152
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2PSSSigner.java668
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2Signer.java618
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java348
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java240
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java43
15 files changed, 0 insertions, 3423 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/DSADigestSigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/DSADigestSigner.java
deleted file mode 100644
index 684eb9c0..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/DSADigestSigner.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.io.IOException;
-import java.math.BigInteger;
-
-import org.bouncycastle.asn1.ASN1EncodableVector;
-import org.bouncycastle.asn1.ASN1Encoding;
-import org.bouncycastle.asn1.ASN1Integer;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERSequence;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.DSA;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.Signer;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-
-public class DSADigestSigner
- implements Signer
-{
- private final Digest digest;
- private final DSA dsaSigner;
- private boolean forSigning;
-
- public DSADigestSigner(
- DSA signer,
- Digest digest)
- {
- this.digest = digest;
- this.dsaSigner = signer;
- }
-
- public void init(
- boolean forSigning,
- CipherParameters parameters)
- {
- this.forSigning = forSigning;
-
- AsymmetricKeyParameter k;
-
- if (parameters instanceof ParametersWithRandom)
- {
- k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters();
- }
- else
- {
- k = (AsymmetricKeyParameter)parameters;
- }
-
- if (forSigning && !k.isPrivate())
- {
- throw new IllegalArgumentException("Signing Requires Private Key.");
- }
-
- if (!forSigning && k.isPrivate())
- {
- throw new IllegalArgumentException("Verification Requires Public Key.");
- }
-
- reset();
-
- dsaSigner.init(forSigning, parameters);
- }
-
- /**
- * update the internal digest with the byte b
- */
- public void update(
- byte input)
- {
- digest.update(input);
- }
-
- /**
- * update the internal digest with the byte array in
- */
- public void update(
- byte[] input,
- int inOff,
- int length)
- {
- digest.update(input, inOff, length);
- }
-
- /**
- * Generate a signature for the message we've been loaded with using
- * the key we were initialised with.
- */
- public byte[] generateSignature()
- {
- if (!forSigning)
- {
- throw new IllegalStateException("DSADigestSigner not initialised for signature generation.");
- }
-
- byte[] hash = new byte[digest.getDigestSize()];
- digest.doFinal(hash, 0);
-
- BigInteger[] sig = dsaSigner.generateSignature(hash);
-
- try
- {
- return derEncode(sig[0], sig[1]);
- }
- catch (IOException e)
- {
- throw new IllegalStateException("unable to encode signature");
- }
- }
-
- public boolean verifySignature(
- byte[] signature)
- {
- if (forSigning)
- {
- throw new IllegalStateException("DSADigestSigner not initialised for verification");
- }
-
- byte[] hash = new byte[digest.getDigestSize()];
- digest.doFinal(hash, 0);
-
- try
- {
- BigInteger[] sig = derDecode(signature);
- return dsaSigner.verifySignature(hash, sig[0], sig[1]);
- }
- catch (IOException e)
- {
- return false;
- }
- }
-
- public void reset()
- {
- digest.reset();
- }
-
- private byte[] derEncode(
- BigInteger r,
- BigInteger s)
- throws IOException
- {
- ASN1EncodableVector v = new ASN1EncodableVector();
- v.add(new ASN1Integer(r));
- v.add(new ASN1Integer(s));
-
- return new DERSequence(v).getEncoded(ASN1Encoding.DER);
- }
-
- private BigInteger[] derDecode(
- byte[] encoding)
- throws IOException
- {
- ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding);
-
- return new BigInteger[]
- {
- ((ASN1Integer)s.getObjectAt(0)).getValue(),
- ((ASN1Integer)s.getObjectAt(1)).getValue()
- };
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/DSAKCalculator.java b/core/src/main/java/org/bouncycastle/crypto/signers/DSAKCalculator.java
deleted file mode 100644
index fced06ea..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/DSAKCalculator.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-/**
- * Interface define calculators of K values for DSA/ECDSA.
- */
-public interface DSAKCalculator
-{
- /**
- * Return true if this calculator is deterministic, false otherwise.
- *
- * @return true if deterministic, otherwise false.
- */
- boolean isDeterministic();
-
- /**
- * Non-deterministic initialiser.
- *
- * @param n the order of the DSA group.
- * @param random a source of randomness.
- */
- void init(BigInteger n, SecureRandom random);
-
- /**
- * Deterministic initialiser.
- *
- * @param n the order of the DSA group.
- * @param d the DSA private value.
- * @param message the message being signed.
- */
- void init(BigInteger n, BigInteger d, byte[] message);
-
- /**
- * Return the next valid value of K.
- *
- * @return a K value.
- */
- BigInteger nextK();
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
deleted file mode 100644
index f3614f39..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
+++ /dev/null
@@ -1,168 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.DSA;
-import org.bouncycastle.crypto.params.DSAKeyParameters;
-import org.bouncycastle.crypto.params.DSAParameters;
-import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
-import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-
-/**
- * The Digital Signature Algorithm - as described in "Handbook of Applied
- * Cryptography", pages 452 - 453.
- */
-public class DSASigner
- implements DSA
-{
- private final DSAKCalculator kCalculator;
-
- private DSAKeyParameters key;
- private SecureRandom random;
-
- /**
- * Default configuration, random K values.
- */
- public DSASigner()
- {
- this.kCalculator = new RandomDSAKCalculator();
- }
-
- /**
- * Configuration with an alternate, possibly deterministic calculator of K.
- *
- * @param kCalculator a K value calculator.
- */
- public DSASigner(DSAKCalculator kCalculator)
- {
- this.kCalculator = kCalculator;
- }
-
- public void init(
- boolean forSigning,
- CipherParameters param)
- {
- SecureRandom providedRandom = null;
-
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.key = (DSAPrivateKeyParameters)rParam.getParameters();
- providedRandom = rParam.getRandom();
- }
- else
- {
- this.key = (DSAPrivateKeyParameters)param;
- }
- }
- else
- {
- this.key = (DSAPublicKeyParameters)param;
- }
-
- this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
- }
-
- /**
- * generate a signature for the given message using the key we were
- * initialised with. For conventional DSA the message should be a SHA-1
- * hash of the message of interest.
- *
- * @param message the message that will be verified later.
- */
- public BigInteger[] generateSignature(
- byte[] message)
- {
- DSAParameters params = key.getParameters();
- BigInteger m = calculateE(params.getQ(), message);
-
- if (kCalculator.isDeterministic())
- {
- kCalculator.init(params.getQ(), ((DSAPrivateKeyParameters)key).getX(), message);
- }
- else
- {
- kCalculator.init(params.getQ(), random);
- }
-
- BigInteger k = kCalculator.nextK();
-
- BigInteger r = params.getG().modPow(k, params.getP()).mod(params.getQ());
-
- k = k.modInverse(params.getQ()).multiply(
- m.add(((DSAPrivateKeyParameters)key).getX().multiply(r)));
-
- BigInteger s = k.mod(params.getQ());
-
- BigInteger[] res = new BigInteger[2];
-
- res[0] = r;
- res[1] = s;
-
- return res;
- }
-
- /**
- * return true if the value r and s represent a DSA signature for
- * the passed in message for standard DSA the message should be a
- * SHA-1 hash of the real message to be verified.
- */
- public boolean verifySignature(
- byte[] message,
- BigInteger r,
- BigInteger s)
- {
- DSAParameters params = key.getParameters();
- BigInteger m = calculateE(params.getQ(), message);
- BigInteger zero = BigInteger.valueOf(0);
-
- if (zero.compareTo(r) >= 0 || params.getQ().compareTo(r) <= 0)
- {
- return false;
- }
-
- if (zero.compareTo(s) >= 0 || params.getQ().compareTo(s) <= 0)
- {
- return false;
- }
-
- BigInteger w = s.modInverse(params.getQ());
-
- BigInteger u1 = m.multiply(w).mod(params.getQ());
- BigInteger u2 = r.multiply(w).mod(params.getQ());
-
- u1 = params.getG().modPow(u1, params.getP());
- u2 = ((DSAPublicKeyParameters)key).getY().modPow(u2, params.getP());
-
- BigInteger v = u1.multiply(u2).mod(params.getP()).mod(params.getQ());
-
- return v.equals(r);
- }
-
- private BigInteger calculateE(BigInteger n, byte[] message)
- {
- if (n.bitLength() >= message.length * 8)
- {
- return new BigInteger(1, message);
- }
- else
- {
- byte[] trunc = new byte[n.bitLength() / 8];
-
- System.arraycopy(message, 0, trunc, 0, trunc.length);
-
- return new BigInteger(1, trunc);
- }
- }
-
- protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
- {
- return !needed ? null : (provided != null) ? provided : new SecureRandom();
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java
deleted file mode 100644
index bceb8220..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/DSTU4145Signer.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-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.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;
-
-/**
- * DSTU 4145-2002
- * <p>
- * National Ukrainian standard of digital signature based on elliptic curves (DSTU 4145-2002).
- * </p>
- */
-public class DSTU4145Signer
- implements DSA
-{
- private static final BigInteger ONE = BigInteger.valueOf(1);
-
- private ECKeyParameters key;
- private SecureRandom random;
-
- public void init(boolean forSigning, CipherParameters param)
- {
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.random = rParam.getRandom();
- param = rParam.getParameters();
- }
- else
- {
- this.random = new SecureRandom();
- }
-
- this.key = (ECPrivateKeyParameters)param;
- }
- else
- {
- this.key = (ECPublicKeyParameters)param;
- }
-
- }
-
- public BigInteger[] generateSignature(byte[] message)
- {
- ECDomainParameters ec = key.getParameters();
-
- ECCurve curve = ec.getCurve();
-
- ECFieldElement h = hash2FieldElement(curve, message);
- if (h.isZero())
- {
- h = curve.fromBigInteger(ONE);
- }
-
- BigInteger n = ec.getN();
- BigInteger e, r, s;
- ECFieldElement Fe, y;
-
- BigInteger d = ((ECPrivateKeyParameters)key).getD();
-
- ECMultiplier basePointMultiplier = createBasePointMultiplier();
-
- do
- {
- do
- {
- do
- {
- e = generateRandomInteger(n, random);
- Fe = basePointMultiplier.multiply(ec.getG(), e).normalize().getAffineXCoord();
- }
- while (Fe.isZero());
-
- y = h.multiply(Fe);
- r = fieldElement2Integer(n, y);
- }
- while (r.signum() == 0);
-
- s = r.multiply(d).add(e).mod(n);
- }
- while (s.signum() == 0);
-
- return new BigInteger[]{r, s};
- }
-
- public boolean verifySignature(byte[] message, BigInteger r, BigInteger s)
- {
- if (r.signum() <= 0 || s.signum() <= 0)
- {
- return false;
- }
-
- ECDomainParameters parameters = key.getParameters();
-
- BigInteger n = parameters.getN();
- if (r.compareTo(n) >= 0 || s.compareTo(n) >= 0)
- {
- return false;
- }
-
- ECCurve curve = parameters.getCurve();
-
- ECFieldElement h = hash2FieldElement(curve, message);
- if (h.isZero())
- {
- h = curve.fromBigInteger(ONE);
- }
-
- ECPoint R = ECAlgorithms.sumOfTwoMultiplies(parameters.getG(), s, ((ECPublicKeyParameters)key).getQ(), r).normalize();
-
- // components must be bogus.
- if (R.isInfinity())
- {
- return false;
- }
-
- ECFieldElement y = h.multiply(R.getAffineXCoord());
- return fieldElement2Integer(n, y).compareTo(r) == 0;
- }
-
- protected ECMultiplier createBasePointMultiplier()
- {
- return new FixedPointCombMultiplier();
- }
-
- /**
- * Generates random integer such, than its bit length is less than that of n
- */
- private static BigInteger generateRandomInteger(BigInteger n, SecureRandom random)
- {
- return new BigInteger(n.bitLength() - 1, random);
- }
-
- private static ECFieldElement hash2FieldElement(ECCurve curve, byte[] hash)
- {
- byte[] data = Arrays.reverse(hash);
- return curve.fromBigInteger(truncate(new BigInteger(1, data), curve.getFieldSize()));
- }
-
- private static BigInteger fieldElement2Integer(BigInteger n, ECFieldElement fe)
- {
- return truncate(fe.toBigInteger(), n.bitLength() - 1);
- }
-
- private static BigInteger truncate(BigInteger x, int bitLength)
- {
- if (x.bitLength() > bitLength)
- {
- x = x.mod(ONE.shiftLeft(bitLength));
- }
- return x;
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
deleted file mode 100644
index 5fce1121..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-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;
-
-/**
- * EC-DSA as described in X9.62
- */
-public class ECDSASigner
- implements ECConstants, DSA
-{
- private final DSAKCalculator kCalculator;
-
- private ECKeyParameters key;
- private SecureRandom random;
-
- /**
- * Default configuration, random K values.
- */
- public ECDSASigner()
- {
- this.kCalculator = new RandomDSAKCalculator();
- }
-
- /**
- * Configuration with an alternate, possibly deterministic calculator of K.
- *
- * @param kCalculator a K value calculator.
- */
- public ECDSASigner(DSAKCalculator kCalculator)
- {
- this.kCalculator = kCalculator;
- }
-
- public void init(
- boolean forSigning,
- CipherParameters param)
- {
- SecureRandom providedRandom = null;
-
- if (forSigning)
- {
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)param;
-
- this.key = (ECPrivateKeyParameters)rParam.getParameters();
- providedRandom = rParam.getRandom();
- }
- else
- {
- this.key = (ECPrivateKeyParameters)param;
- }
- }
- else
- {
- this.key = (ECPublicKeyParameters)param;
- }
-
- this.random = initSecureRandom(forSigning && !kCalculator.isDeterministic(), providedRandom);
- }
-
- // 5.3 pg 28
- /**
- * generate a signature for the given message using the key we were
- * initialised with. For conventional DSA the message should be a SHA-1
- * hash of the message of interest.
- *
- * @param message the message that will be verified later.
- */
- public BigInteger[] generateSignature(
- byte[] message)
- {
- ECDomainParameters ec = key.getParameters();
- BigInteger n = ec.getN();
- BigInteger e = calculateE(n, message);
- BigInteger d = ((ECPrivateKeyParameters)key).getD();
-
- if (kCalculator.isDeterministic())
- {
- kCalculator.init(n, d, message);
- }
- else
- {
- kCalculator.init(n, random);
- }
-
- BigInteger r, s;
-
- ECMultiplier basePointMultiplier = createBasePointMultiplier();
-
- // 5.3.2
- do // generate s
- {
- BigInteger k;
- do // generate r
- {
- k = kCalculator.nextK();
-
- ECPoint p = basePointMultiplier.multiply(ec.getG(), k).normalize();
-
- // 5.3.3
- r = p.getAffineXCoord().toBigInteger().mod(n);
- }
- while (r.equals(ZERO));
-
- s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
- }
- while (s.equals(ZERO));
-
- return new BigInteger[]{ r, s };
- }
-
- // 5.4 pg 29
- /**
- * return true if the value r and s represent a DSA signature for
- * the passed in message (for standard DSA the message should be
- * a SHA-1 hash of the real message to be verified).
- */
- public boolean verifySignature(
- byte[] message,
- BigInteger r,
- BigInteger s)
- {
- ECDomainParameters ec = key.getParameters();
- BigInteger n = ec.getN();
- BigInteger e = calculateE(n, message);
-
- // r in the range [1,n-1]
- if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0)
- {
- return false;
- }
-
- // s in the range [1,n-1]
- if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0)
- {
- return false;
- }
-
- BigInteger c = s.modInverse(n);
-
- BigInteger u1 = e.multiply(c).mod(n);
- BigInteger u2 = r.multiply(c).mod(n);
-
- ECPoint G = ec.getG();
- ECPoint Q = ((ECPublicKeyParameters)key).getQ();
-
- ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2).normalize();
-
- // components must be bogus.
- if (point.isInfinity())
- {
- return false;
- }
-
- BigInteger v = point.getAffineXCoord().toBigInteger().mod(n);
-
- return v.equals(r);
- }
-
- protected BigInteger calculateE(BigInteger n, byte[] message)
- {
- int log2n = n.bitLength();
- int messageBitLength = message.length * 8;
-
- BigInteger e = new BigInteger(1, message);
- if (log2n < messageBitLength)
- {
- e = e.shiftRight(messageBitLength - log2n);
- }
- return e;
- }
-
- protected ECMultiplier createBasePointMultiplier()
- {
- return new FixedPointCombMultiplier();
- }
-
- protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
- {
- return !needed ? null : (provided != null) ? provided : new SecureRandom();
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java
deleted file mode 100644
index 0ef88762..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/ECGOST3410Signer.java
+++ /dev/null
@@ -1,160 +0,0 @@
-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 = createBasePointMultiplier();
-
- 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);
- }
-
- protected ECMultiplier createBasePointMultiplier()
- {
- return new FixedPointCombMultiplier();
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java
deleted file mode 100644
index 3e839163..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/ECNRSigner.java
+++ /dev/null
@@ -1,188 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.DSA;
-import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
-import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
-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;
-
-/**
- * EC-NR as described in IEEE 1363-2000
- */
-public class ECNRSigner
- implements DSA
-{
- private boolean forSigning;
- private ECKeyParameters key;
- private SecureRandom random;
-
- public void init(
- boolean forSigning,
- CipherParameters param)
- {
- this.forSigning = forSigning;
-
- 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;
- }
- }
-
- // Section 7.2.5 ECSP-NR, pg 34
- /**
- * generate a signature for the given message using the key we were
- * initialised with. Generally, the order of the curve should be at
- * least as long as the hash of the message of interest, and with
- * ECNR it *must* be at least as long.
- *
- * @param digest the digest to be signed.
- * @exception DataLengthException if the digest is longer than the key allows
- */
- public BigInteger[] generateSignature(
- byte[] digest)
- {
- if (! this.forSigning)
- {
- throw new IllegalStateException("not initialised for signing");
- }
-
- BigInteger n = ((ECPrivateKeyParameters)this.key).getParameters().getN();
- int nBitLength = n.bitLength();
-
- BigInteger e = new BigInteger(1, digest);
- int eBitLength = e.bitLength();
-
- ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)key;
-
- if (eBitLength > nBitLength)
- {
- throw new DataLengthException("input too large for ECNR key.");
- }
-
- BigInteger r = null;
- BigInteger s = null;
-
- AsymmetricCipherKeyPair tempPair;
- do // generate r
- {
- // generate another, but very temporary, key pair using
- // the same EC parameters
- ECKeyPairGenerator keyGen = new ECKeyPairGenerator();
-
- keyGen.init(new ECKeyGenerationParameters(privKey.getParameters(), this.random));
-
- tempPair = keyGen.generateKeyPair();
-
- // BigInteger Vx = tempPair.getPublic().getW().getAffineX();
- ECPublicKeyParameters V = (ECPublicKeyParameters)tempPair.getPublic(); // get temp's public key
- BigInteger Vx = V.getQ().getAffineXCoord().toBigInteger(); // get the point's x coordinate
-
- r = Vx.add(e).mod(n);
- }
- while (r.equals(ECConstants.ZERO));
-
- // generate s
- BigInteger x = privKey.getD(); // private key value
- BigInteger u = ((ECPrivateKeyParameters)tempPair.getPrivate()).getD(); // temp's private key value
- s = u.subtract(r.multiply(x)).mod(n);
-
- BigInteger[] res = new BigInteger[2];
- res[0] = r;
- res[1] = s;
-
- return res;
- }
-
- // Section 7.2.6 ECVP-NR, pg 35
- /**
- * return true if the value r and s represent a signature for the
- * message passed in. Generally, the order of the curve should be at
- * least as long as the hash of the message of interest, and with
- * ECNR, it *must* be at least as long. But just in case the signer
- * applied mod(n) to the longer digest, this implementation will
- * apply mod(n) during verification.
- *
- * @param digest the digest to be verified.
- * @param r the r value of the signature.
- * @param s the s value of the signature.
- * @exception DataLengthException if the digest is longer than the key allows
- */
- public boolean verifySignature(
- byte[] digest,
- BigInteger r,
- BigInteger s)
- {
- if (this.forSigning)
- {
- throw new IllegalStateException("not initialised for verifying");
- }
-
- ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key;
- BigInteger n = pubKey.getParameters().getN();
- int nBitLength = n.bitLength();
-
- BigInteger e = new BigInteger(1, digest);
- int eBitLength = e.bitLength();
-
- if (eBitLength > nBitLength)
- {
- throw new DataLengthException("input too large for ECNR key.");
- }
-
- // r in the range [1,n-1]
- if (r.compareTo(ECConstants.ONE) < 0 || r.compareTo(n) >= 0)
- {
- return false;
- }
-
- // s in the range [0,n-1] NB: ECNR spec says 0
- if (s.compareTo(ECConstants.ZERO) < 0 || s.compareTo(n) >= 0)
- {
- return false;
- }
-
- // compute P = sG + rW
-
- ECPoint G = pubKey.getParameters().getG();
- ECPoint W = pubKey.getQ();
- // calculate P using Bouncy math
- ECPoint P = ECAlgorithms.sumOfTwoMultiplies(G, s, W, r).normalize();
-
- // components must be bogus.
- if (P.isInfinity())
- {
- return false;
- }
-
- BigInteger x = P.getAffineXCoord().toBigInteger();
- BigInteger t = r.subtract(x).mod(n);
-
- return t.equals(e);
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/GOST3410Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/GOST3410Signer.java
deleted file mode 100644
index 135f1857..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/GOST3410Signer.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.DSA;
-import org.bouncycastle.crypto.params.GOST3410KeyParameters;
-import org.bouncycastle.crypto.params.GOST3410Parameters;
-import org.bouncycastle.crypto.params.GOST3410PrivateKeyParameters;
-import org.bouncycastle.crypto.params.GOST3410PublicKeyParameters;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-
-/**
- * GOST R 34.10-94 Signature Algorithm
- */
-public class GOST3410Signer
- implements DSA
-{
- GOST3410KeyParameters 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 = (GOST3410PrivateKeyParameters)rParam.getParameters();
- }
- else
- {
- this.random = new SecureRandom();
- this.key = (GOST3410PrivateKeyParameters)param;
- }
- }
- else
- {
- this.key = (GOST3410PublicKeyParameters)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 m = new BigInteger(1, mRev);
- GOST3410Parameters params = key.getParameters();
- BigInteger k;
-
- do
- {
- k = new BigInteger(params.getQ().bitLength(), random);
- }
- while (k.compareTo(params.getQ()) >= 0);
-
- BigInteger r = params.getA().modPow(k, params.getP()).mod(params.getQ());
-
- BigInteger s = k.multiply(m).
- add(((GOST3410PrivateKeyParameters)key).getX().multiply(r)).
- mod(params.getQ());
-
- 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 m = new BigInteger(1, mRev);
- GOST3410Parameters params = key.getParameters();
- BigInteger zero = BigInteger.valueOf(0);
-
- if (zero.compareTo(r) >= 0 || params.getQ().compareTo(r) <= 0)
- {
- return false;
- }
-
- if (zero.compareTo(s) >= 0 || params.getQ().compareTo(s) <= 0)
- {
- return false;
- }
-
- BigInteger v = m.modPow(params.getQ().subtract(new BigInteger("2")),params.getQ());
-
- BigInteger z1 = s.multiply(v).mod(params.getQ());
- BigInteger z2 = (params.getQ().subtract(r)).multiply(v).mod(params.getQ());
-
- z1 = params.getA().modPow(z1, params.getP());
- z2 = ((GOST3410PublicKeyParameters)key).getY().modPow(z2, params.getP());
-
- BigInteger u = z1.multiply(z2).mod(params.getP()).mod(params.getQ());
-
- return u.equals(r);
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/GenericSigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/GenericSigner.java
deleted file mode 100644
index 6819e141..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/GenericSigner.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import org.bouncycastle.crypto.AsymmetricBlockCipher;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.CryptoException;
-import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.Signer;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.util.Arrays;
-
-public class GenericSigner
- implements Signer
-{
- private final AsymmetricBlockCipher engine;
- private final Digest digest;
- private boolean forSigning;
-
- public GenericSigner(
- AsymmetricBlockCipher engine,
- Digest digest)
- {
- this.engine = engine;
- this.digest = digest;
- }
-
- /**
- * initialise the signer for signing or verification.
- *
- * @param forSigning
- * true if for signing, false otherwise
- * @param parameters
- * necessary parameters.
- */
- public void init(
- boolean forSigning,
- CipherParameters parameters)
- {
- this.forSigning = forSigning;
- AsymmetricKeyParameter k;
-
- if (parameters instanceof ParametersWithRandom)
- {
- k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters();
- }
- else
- {
- k = (AsymmetricKeyParameter)parameters;
- }
-
- if (forSigning && !k.isPrivate())
- {
- throw new IllegalArgumentException("signing requires private key");
- }
-
- if (!forSigning && k.isPrivate())
- {
- throw new IllegalArgumentException("verification requires public key");
- }
-
- reset();
-
- engine.init(forSigning, parameters);
- }
-
- /**
- * update the internal digest with the byte b
- */
- public void update(
- byte input)
- {
- digest.update(input);
- }
-
- /**
- * update the internal digest with the byte array in
- */
- public void update(
- byte[] input,
- int inOff,
- int length)
- {
- digest.update(input, inOff, length);
- }
-
- /**
- * Generate a signature for the message we've been loaded with using the key
- * we were initialised with.
- */
- public byte[] generateSignature()
- throws CryptoException, DataLengthException
- {
- if (!forSigning)
- {
- throw new IllegalStateException("GenericSigner not initialised for signature generation.");
- }
-
- byte[] hash = new byte[digest.getDigestSize()];
- digest.doFinal(hash, 0);
-
- return engine.processBlock(hash, 0, hash.length);
- }
-
- /**
- * return true if the internal state represents the signature described in
- * the passed in array.
- */
- public boolean verifySignature(
- byte[] signature)
- {
- if (forSigning)
- {
- throw new IllegalStateException("GenericSigner not initialised for verification");
- }
-
- byte[] hash = new byte[digest.getDigestSize()];
- digest.doFinal(hash, 0);
-
- try
- {
- byte[] sig = engine.processBlock(signature, 0, signature.length);
-
- return Arrays.constantTimeAreEqual(sig, hash);
- }
- catch (Exception e)
- {
- return false;
- }
- }
-
- public void reset()
- {
- digest.reset();
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java b/core/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java
deleted file mode 100644
index db78d4a3..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/HMacDSAKCalculator.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.macs.HMac;
-import org.bouncycastle.crypto.params.KeyParameter;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.BigIntegers;
-
-/**
- * A deterministic K calculator based on the algorithm in section 3.2 of RFC 6979.
- */
-public class HMacDSAKCalculator
- implements DSAKCalculator
-{
- private static final BigInteger ZERO = BigInteger.valueOf(0);
-
- private final HMac hMac;
- private final byte[] K;
- private final byte[] V;
-
- private BigInteger n;
-
- /**
- * Base constructor.
- *
- * @param digest digest to build the HMAC on.
- */
- public HMacDSAKCalculator(Digest digest)
- {
- this.hMac = new HMac(digest);
- this.V = new byte[hMac.getMacSize()];
- this.K = new byte[hMac.getMacSize()];
- }
-
- public boolean isDeterministic()
- {
- return true;
- }
-
- public void init(BigInteger n, SecureRandom random)
- {
- throw new IllegalStateException("Operation not supported");
- }
-
- public void init(BigInteger n, BigInteger d, byte[] message)
- {
- this.n = n;
-
- Arrays.fill(V, (byte)0x01);
- Arrays.fill(K, (byte)0);
-
- byte[] x = new byte[(n.bitLength() + 7) / 8];
- byte[] dVal = BigIntegers.asUnsignedByteArray(d);
-
- System.arraycopy(dVal, 0, x, x.length - dVal.length, dVal.length);
-
- byte[] m = new byte[(n.bitLength() + 7) / 8];
-
- BigInteger mInt = bitsToInt(message);
-
- if (mInt.compareTo(n) > 0)
- {
- mInt = mInt.subtract(n);
- }
-
- byte[] mVal = BigIntegers.asUnsignedByteArray(mInt);
-
- System.arraycopy(mVal, 0, m, m.length - mVal.length, mVal.length);
-
- hMac.init(new KeyParameter(K));
-
- hMac.update(V, 0, V.length);
- hMac.update((byte)0x00);
- hMac.update(x, 0, x.length);
- hMac.update(m, 0, m.length);
-
- hMac.doFinal(K, 0);
-
- hMac.init(new KeyParameter(K));
-
- hMac.update(V, 0, V.length);
-
- hMac.doFinal(V, 0);
-
- hMac.update(V, 0, V.length);
- hMac.update((byte)0x01);
- hMac.update(x, 0, x.length);
- hMac.update(m, 0, m.length);
-
- hMac.doFinal(K, 0);
-
- hMac.init(new KeyParameter(K));
-
- hMac.update(V, 0, V.length);
-
- hMac.doFinal(V, 0);
- }
-
- public BigInteger nextK()
- {
- byte[] t = new byte[((n.bitLength() + 7) / 8)];
-
- for (;;)
- {
- int tOff = 0;
-
- while (tOff < t.length)
- {
- hMac.update(V, 0, V.length);
-
- hMac.doFinal(V, 0);
-
- int len = Math.min(t.length - tOff, V.length);
- System.arraycopy(V, 0, t, tOff, len);
- tOff += len;
- }
-
- BigInteger k = bitsToInt(t);
-
- if (k.compareTo(ZERO) > 0 && k.compareTo(n) < 0)
- {
- return k;
- }
-
- hMac.update(V, 0, V.length);
- hMac.update((byte)0x00);
-
- hMac.doFinal(K, 0);
-
- hMac.init(new KeyParameter(K));
-
- hMac.update(V, 0, V.length);
-
- hMac.doFinal(V, 0);
- }
- }
-
- private BigInteger bitsToInt(byte[] t)
- {
- BigInteger v = new BigInteger(1, t);
-
- if (t.length * 8 > n.bitLength())
- {
- v = v.shiftRight(t.length * 8 - n.bitLength());
- }
-
- return v;
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2PSSSigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2PSSSigner.java
deleted file mode 100644
index fcd5816a..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2PSSSigner.java
+++ /dev/null
@@ -1,668 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.security.SecureRandom;
-import java.util.Hashtable;
-
-import org.bouncycastle.crypto.AsymmetricBlockCipher;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.CryptoException;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.InvalidCipherTextException;
-import org.bouncycastle.crypto.SignerWithRecovery;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.crypto.params.ParametersWithSalt;
-import org.bouncycastle.crypto.params.RSAKeyParameters;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Integers;
-
-/**
- * ISO9796-2 - mechanism using a hash function with recovery (scheme 2 and 3).
- * <p>
- * Note: the usual length for the salt is the length of the hash
- * function used in bytes.
- */
-public class ISO9796d2PSSSigner
- implements SignerWithRecovery
-{
- static final public int TRAILER_IMPLICIT = 0xBC;
- static final public int TRAILER_RIPEMD160 = 0x31CC;
- static final public int TRAILER_RIPEMD128 = 0x32CC;
- static final public int TRAILER_SHA1 = 0x33CC;
- static final public int TRAILER_SHA256 = 0x34CC;
- static final public int TRAILER_SHA512 = 0x35CC;
- static final public int TRAILER_SHA384 = 0x36CC;
- static final public int TRAILER_WHIRLPOOL = 0x37CC;
-
- private static Hashtable trailerMap = new Hashtable();
-
- static
- {
- trailerMap.put("RIPEMD128", Integers.valueOf(TRAILER_RIPEMD128));
- trailerMap.put("RIPEMD160", Integers.valueOf(TRAILER_RIPEMD160));
-
- trailerMap.put("SHA-1", Integers.valueOf(TRAILER_SHA1));
- trailerMap.put("SHA-256", Integers.valueOf(TRAILER_SHA256));
- trailerMap.put("SHA-384", Integers.valueOf(TRAILER_SHA384));
- trailerMap.put("SHA-512", Integers.valueOf(TRAILER_SHA512));
-
- trailerMap.put("Whirlpool", Integers.valueOf(TRAILER_WHIRLPOOL));
- }
-
- private Digest digest;
- private AsymmetricBlockCipher cipher;
-
- private SecureRandom random;
- private byte[] standardSalt;
-
- private int hLen;
- private int trailer;
- private int keyBits;
- private byte[] block;
- private byte[] mBuf;
- private int messageLength;
- private int saltLength;
- private boolean fullMessage;
- private byte[] recoveredMessage;
-
- private byte[] preSig;
- private byte[] preBlock;
- private int preMStart;
- private int preTLength;
-
- /**
- * Generate a signer for the with either implicit or explicit trailers
- * for ISO9796-2, scheme 2 or 3.
- *
- * @param cipher base cipher to use for signature creation/verification
- * @param digest digest to use.
- * @param saltLength length of salt in bytes.
- * @param implicit whether or not the trailer is implicit or gives the hash.
- */
- public ISO9796d2PSSSigner(
- AsymmetricBlockCipher cipher,
- Digest digest,
- int saltLength,
- boolean implicit)
- {
- this.cipher = cipher;
- this.digest = digest;
- this.hLen = digest.getDigestSize();
- this.saltLength = saltLength;
-
- if (implicit)
- {
- trailer = TRAILER_IMPLICIT;
- }
- else
- {
- Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName());
-
- if (trailerObj != null)
- {
- trailer = trailerObj.intValue();
- }
- else
- {
- throw new IllegalArgumentException("no valid trailer for digest");
- }
- }
- }
-
- /**
- * Constructor for a signer with an explicit digest trailer.
- *
- * @param cipher cipher to use.
- * @param digest digest to sign with.
- * @param saltLength length of salt in bytes.
- */
- public ISO9796d2PSSSigner(
- AsymmetricBlockCipher cipher,
- Digest digest,
- int saltLength)
- {
- this(cipher, digest, saltLength, false);
- }
-
- /**
- * Initialise the signer.
- *
- * @param forSigning true if for signing, false if for verification.
- * @param param parameters for signature generation/verification. If the
- * parameters are for generation they should be a ParametersWithRandom,
- * a ParametersWithSalt, or just an RSAKeyParameters object. If RSAKeyParameters
- * are passed in a SecureRandom will be created.
- * @throws IllegalArgumentException if wrong parameter type or a fixed
- * salt is passed in which is the wrong length.
- */
- public void init(
- boolean forSigning,
- CipherParameters param)
- {
- RSAKeyParameters kParam;
- int lengthOfSalt = saltLength;
-
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom p = (ParametersWithRandom)param;
-
- kParam = (RSAKeyParameters)p.getParameters();
- if (forSigning)
- {
- random = p.getRandom();
- }
- }
- else if (param instanceof ParametersWithSalt)
- {
- ParametersWithSalt p = (ParametersWithSalt)param;
-
- kParam = (RSAKeyParameters)p.getParameters();
- standardSalt = p.getSalt();
- lengthOfSalt = standardSalt.length;
- if (standardSalt.length != saltLength)
- {
- throw new IllegalArgumentException("Fixed salt is of wrong length");
- }
- }
- else
- {
- kParam = (RSAKeyParameters)param;
- if (forSigning)
- {
- random = new SecureRandom();
- }
- }
-
- cipher.init(forSigning, kParam);
-
- keyBits = kParam.getModulus().bitLength();
-
- block = new byte[(keyBits + 7) / 8];
-
- if (trailer == TRAILER_IMPLICIT)
- {
- mBuf = new byte[block.length - digest.getDigestSize() - lengthOfSalt - 1 - 1];
- }
- else
- {
- mBuf = new byte[block.length - digest.getDigestSize() - lengthOfSalt - 1 - 2];
- }
-
- reset();
- }
-
- /**
- * compare two byte arrays - constant time
- */
- private boolean isSameAs(
- byte[] a,
- byte[] b)
- {
- boolean isOkay = true;
-
- if (messageLength != b.length)
- {
- isOkay = false;
- }
-
- for (int i = 0; i != b.length; i++)
- {
- if (a[i] != b[i])
- {
- isOkay = false;
- }
- }
-
- return isOkay;
- }
-
- /**
- * clear possible sensitive data
- */
- private void clearBlock(
- byte[] block)
- {
- for (int i = 0; i != block.length; i++)
- {
- block[i] = 0;
- }
- }
-
- public void updateWithRecoveredMessage(byte[] signature)
- throws InvalidCipherTextException
- {
- byte[] block = cipher.processBlock(signature, 0, signature.length);
-
- //
- // adjust block size for leading zeroes if necessary
- //
- if (block.length < (keyBits + 7) / 8)
- {
- byte[] tmp = new byte[(keyBits + 7) / 8];
-
- System.arraycopy(block, 0, tmp, tmp.length - block.length, block.length);
- clearBlock(block);
- block = tmp;
- }
-
- int tLength;
-
- if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0)
- {
- tLength = 1;
- }
- else
- {
- int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF);
-
- Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName());
-
- if (trailerObj != null)
- {
- if (sigTrail != trailerObj.intValue())
- {
- throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail);
- }
- }
- else
- {
- throw new IllegalArgumentException("unrecognised hash in signature");
- }
-
- tLength = 2;
- }
-
- //
- // calculate H(m2)
- //
- byte[] m2Hash = new byte[hLen];
- digest.doFinal(m2Hash, 0);
-
- //
- // remove the mask
- //
- byte[] dbMask = maskGeneratorFunction1(block, block.length - hLen - tLength, hLen, block.length - hLen - tLength);
- for (int i = 0; i != dbMask.length; i++)
- {
- block[i] ^= dbMask[i];
- }
-
- block[0] &= 0x7f;
-
- //
- // find out how much padding we've got
- //
- int mStart = 0;
- for (; mStart != block.length; mStart++)
- {
- if (block[mStart] == 0x01)
- {
- break;
- }
- }
-
- mStart++;
-
- if (mStart >= block.length)
- {
- clearBlock(block);
- }
-
- fullMessage = (mStart > 1);
-
- recoveredMessage = new byte[dbMask.length - mStart - saltLength];
-
- System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length);
- System.arraycopy(recoveredMessage, 0, mBuf, 0, recoveredMessage.length);
-
- preSig = signature;
- preBlock = block;
- preMStart = mStart;
- preTLength = tLength;
- }
-
- /**
- * update the internal digest with the byte b
- */
- public void update(
- byte b)
- {
- if (preSig == null && messageLength < mBuf.length)
- {
- mBuf[messageLength++] = b;
- }
- else
- {
- digest.update(b);
- }
- }
-
- /**
- * update the internal digest with the byte array in
- */
- public void update(
- byte[] in,
- int off,
- int len)
- {
- if (preSig == null)
- {
- while (len > 0 && messageLength < mBuf.length)
- {
- this.update(in[off]);
- off++;
- len--;
- }
- }
-
- if (len > 0)
- {
- digest.update(in, off, len);
- }
- }
-
- /**
- * reset the internal state
- */
- public void reset()
- {
- digest.reset();
- messageLength = 0;
- if (mBuf != null)
- {
- clearBlock(mBuf);
- }
- if (recoveredMessage != null)
- {
- clearBlock(recoveredMessage);
- recoveredMessage = null;
- }
- fullMessage = false;
- if (preSig != null)
- {
- preSig = null;
- clearBlock(preBlock);
- preBlock = null;
- }
- }
-
- /**
- * generate a signature for the loaded message using the key we were
- * initialised with.
- */
- public byte[] generateSignature()
- throws CryptoException
- {
- int digSize = digest.getDigestSize();
-
- byte[] m2Hash = new byte[digSize];
-
- digest.doFinal(m2Hash, 0);
-
- byte[] C = new byte[8];
- LtoOSP(messageLength * 8, C);
-
- digest.update(C, 0, C.length);
-
- digest.update(mBuf, 0, messageLength);
-
- digest.update(m2Hash, 0, m2Hash.length);
-
- byte[] salt;
-
- if (standardSalt != null)
- {
- salt = standardSalt;
- }
- else
- {
- salt = new byte[saltLength];
- random.nextBytes(salt);
- }
-
- digest.update(salt, 0, salt.length);
-
- byte[] hash = new byte[digest.getDigestSize()];
-
- digest.doFinal(hash, 0);
-
- int tLength = 2;
- if (trailer == TRAILER_IMPLICIT)
- {
- tLength = 1;
- }
-
- int off = block.length - messageLength - salt.length - hLen - tLength - 1;
-
- block[off] = 0x01;
-
- System.arraycopy(mBuf, 0, block, off + 1, messageLength);
- System.arraycopy(salt, 0, block, off + 1 + messageLength, salt.length);
-
- byte[] dbMask = maskGeneratorFunction1(hash, 0, hash.length, block.length - hLen - tLength);
- for (int i = 0; i != dbMask.length; i++)
- {
- block[i] ^= dbMask[i];
- }
-
- System.arraycopy(hash, 0, block, block.length - hLen - tLength, hLen);
-
- if (trailer == TRAILER_IMPLICIT)
- {
- block[block.length - 1] = (byte)TRAILER_IMPLICIT;
- }
- else
- {
- block[block.length - 2] = (byte)(trailer >>> 8);
- block[block.length - 1] = (byte)trailer;
- }
-
- block[0] &= 0x7f;
-
- byte[] b = cipher.processBlock(block, 0, block.length);
-
- clearBlock(mBuf);
- clearBlock(block);
- messageLength = 0;
-
- return b;
- }
-
- /**
- * return true if the signature represents a ISO9796-2 signature
- * for the passed in message.
- */
- public boolean verifySignature(
- byte[] signature)
- {
- //
- // calculate H(m2)
- //
- byte[] m2Hash = new byte[hLen];
- digest.doFinal(m2Hash, 0);
-
- byte[] block;
- int tLength;
- int mStart = 0;
-
- if (preSig == null)
- {
- try
- {
- updateWithRecoveredMessage(signature);
- }
- catch (Exception e)
- {
- return false;
- }
- }
- else
- {
- if (!Arrays.areEqual(preSig, signature))
- {
- throw new IllegalStateException("updateWithRecoveredMessage called on different signature");
- }
- }
-
- block = preBlock;
- mStart = preMStart;
- tLength = preTLength;
-
- preSig = null;
- preBlock = null;
-
- //
- // check the hashes
- //
- byte[] C = new byte[8];
- LtoOSP(recoveredMessage.length * 8, C);
-
- digest.update(C, 0, C.length);
-
- if (recoveredMessage.length != 0)
- {
- digest.update(recoveredMessage, 0, recoveredMessage.length);
- }
-
- digest.update(m2Hash, 0, m2Hash.length);
-
- // Update for the salt
- digest.update(block, mStart + recoveredMessage.length, saltLength);
-
- byte[] hash = new byte[digest.getDigestSize()];
- digest.doFinal(hash, 0);
-
- int off = block.length - tLength - hash.length;
-
- boolean isOkay = true;
-
- for (int i = 0; i != hash.length; i++)
- {
- if (hash[i] != block[off + i])
- {
- isOkay = false;
- }
- }
-
- clearBlock(block);
- clearBlock(hash);
-
- if (!isOkay)
- {
- fullMessage = false;
- clearBlock(recoveredMessage);
- return false;
- }
-
- //
- // if they've input a message check what we've recovered against
- // what was input.
- //
- if (messageLength != 0)
- {
- if (!isSameAs(mBuf, recoveredMessage))
- {
- clearBlock(mBuf);
- return false;
- }
- messageLength = 0;
- }
-
- clearBlock(mBuf);
- return true;
- }
-
- /**
- * Return true if the full message was recoveredMessage.
- *
- * @return true on full message recovery, false otherwise, or if not sure.
- * @see org.bouncycastle.crypto.SignerWithRecovery#hasFullMessage()
- */
- public boolean hasFullMessage()
- {
- return fullMessage;
- }
-
- /**
- * Return a reference to the recoveredMessage message.
- *
- * @return the full/partial recoveredMessage message.
- * @see org.bouncycastle.crypto.SignerWithRecovery#getRecoveredMessage()
- */
- public byte[] getRecoveredMessage()
- {
- return recoveredMessage;
- }
-
- /**
- * int to octet string.
- */
- private void ItoOSP(
- int i,
- byte[] sp)
- {
- sp[0] = (byte)(i >>> 24);
- sp[1] = (byte)(i >>> 16);
- sp[2] = (byte)(i >>> 8);
- sp[3] = (byte)(i >>> 0);
- }
-
- /**
- * long to octet string.
- */
- private void LtoOSP(
- long l,
- byte[] sp)
- {
- sp[0] = (byte)(l >>> 56);
- sp[1] = (byte)(l >>> 48);
- sp[2] = (byte)(l >>> 40);
- sp[3] = (byte)(l >>> 32);
- sp[4] = (byte)(l >>> 24);
- sp[5] = (byte)(l >>> 16);
- sp[6] = (byte)(l >>> 8);
- sp[7] = (byte)(l >>> 0);
- }
-
- /**
- * mask generator function, as described in PKCS1v2.
- */
- private byte[] maskGeneratorFunction1(
- byte[] Z,
- int zOff,
- int zLen,
- int length)
- {
- byte[] mask = new byte[length];
- byte[] hashBuf = new byte[hLen];
- byte[] C = new byte[4];
- int counter = 0;
-
- digest.reset();
-
- while (counter < (length / hLen))
- {
- ItoOSP(counter, C);
-
- digest.update(Z, zOff, zLen);
- digest.update(C, 0, C.length);
- digest.doFinal(hashBuf, 0);
-
- System.arraycopy(hashBuf, 0, mask, counter * hLen, hLen);
-
- counter++;
- }
-
- if ((counter * hLen) < length)
- {
- ItoOSP(counter, C);
-
- digest.update(Z, zOff, zLen);
- digest.update(C, 0, C.length);
- digest.doFinal(hashBuf, 0);
-
- System.arraycopy(hashBuf, 0, mask, counter * hLen, mask.length - (counter * hLen));
- }
-
- return mask;
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2Signer.java b/core/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2Signer.java
deleted file mode 100644
index 563fae63..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/ISO9796d2Signer.java
+++ /dev/null
@@ -1,618 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.util.Hashtable;
-
-import org.bouncycastle.crypto.AsymmetricBlockCipher;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.CryptoException;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.InvalidCipherTextException;
-import org.bouncycastle.crypto.SignerWithRecovery;
-import org.bouncycastle.crypto.params.RSAKeyParameters;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Integers;
-
-/**
- * ISO9796-2 - mechanism using a hash function with recovery (scheme 1)
- */
-public class ISO9796d2Signer
- implements SignerWithRecovery
-{
- static final public int TRAILER_IMPLICIT = 0xBC;
- static final public int TRAILER_RIPEMD160 = 0x31CC;
- static final public int TRAILER_RIPEMD128 = 0x32CC;
- static final public int TRAILER_SHA1 = 0x33CC;
- static final public int TRAILER_SHA256 = 0x34CC;
- static final public int TRAILER_SHA512 = 0x35CC;
- static final public int TRAILER_SHA384 = 0x36CC;
- static final public int TRAILER_WHIRLPOOL = 0x37CC;
-
- private static Hashtable trailerMap = new Hashtable();
-
- static
- {
- trailerMap.put("RIPEMD128", Integers.valueOf(TRAILER_RIPEMD128));
- trailerMap.put("RIPEMD160", Integers.valueOf(TRAILER_RIPEMD160));
-
- trailerMap.put("SHA-1", Integers.valueOf(TRAILER_SHA1));
- trailerMap.put("SHA-256", Integers.valueOf(TRAILER_SHA256));
- trailerMap.put("SHA-384", Integers.valueOf(TRAILER_SHA384));
- trailerMap.put("SHA-512", Integers.valueOf(TRAILER_SHA512));
-
- trailerMap.put("Whirlpool", Integers.valueOf(TRAILER_WHIRLPOOL));
- }
-
- private Digest digest;
- private AsymmetricBlockCipher cipher;
-
- private int trailer;
- private int keyBits;
- private byte[] block;
- private byte[] mBuf;
- private int messageLength;
- private boolean fullMessage;
- private byte[] recoveredMessage;
-
- private byte[] preSig;
- private byte[] preBlock;
-
- /**
- * Generate a signer for the with either implicit or explicit trailers
- * for ISO9796-2.
- *
- * @param cipher base cipher to use for signature creation/verification
- * @param digest digest to use.
- * @param implicit whether or not the trailer is implicit or gives the hash.
- */
- public ISO9796d2Signer(
- AsymmetricBlockCipher cipher,
- Digest digest,
- boolean implicit)
- {
- this.cipher = cipher;
- this.digest = digest;
-
- if (implicit)
- {
- trailer = TRAILER_IMPLICIT;
- }
- else
- {
- Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName());
-
- if (trailerObj != null)
- {
- trailer = trailerObj.intValue();
- }
- else
- {
- throw new IllegalArgumentException("no valid trailer for digest");
- }
- }
- }
-
- /**
- * Constructor for a signer with an explicit digest trailer.
- *
- * @param cipher cipher to use.
- * @param digest digest to sign with.
- */
- public ISO9796d2Signer(
- AsymmetricBlockCipher cipher,
- Digest digest)
- {
- this(cipher, digest, false);
- }
-
- public void init(
- boolean forSigning,
- CipherParameters param)
- {
- RSAKeyParameters kParam = (RSAKeyParameters)param;
-
- cipher.init(forSigning, kParam);
-
- keyBits = kParam.getModulus().bitLength();
-
- block = new byte[(keyBits + 7) / 8];
-
- if (trailer == TRAILER_IMPLICIT)
- {
- mBuf = new byte[block.length - digest.getDigestSize() - 2];
- }
- else
- {
- mBuf = new byte[block.length - digest.getDigestSize() - 3];
- }
-
- reset();
- }
-
- /**
- * compare two byte arrays - constant time
- */
- private boolean isSameAs(
- byte[] a,
- byte[] b)
- {
- boolean isOkay = true;
-
- if (messageLength > mBuf.length)
- {
- if (mBuf.length > b.length)
- {
- isOkay = false;
- }
-
- for (int i = 0; i != mBuf.length; i++)
- {
- if (a[i] != b[i])
- {
- isOkay = false;
- }
- }
- }
- else
- {
- if (messageLength != b.length)
- {
- isOkay = false;
- }
-
- for (int i = 0; i != b.length; i++)
- {
- if (a[i] != b[i])
- {
- isOkay = false;
- }
- }
- }
-
- return isOkay;
- }
-
- /**
- * clear possible sensitive data
- */
- private void clearBlock(
- byte[] block)
- {
- for (int i = 0; i != block.length; i++)
- {
- block[i] = 0;
- }
- }
-
- public void updateWithRecoveredMessage(byte[] signature)
- throws InvalidCipherTextException
- {
- byte[] block = cipher.processBlock(signature, 0, signature.length);
-
- if (((block[0] & 0xC0) ^ 0x40) != 0)
- {
- throw new InvalidCipherTextException("malformed signature");
- }
-
- if (((block[block.length - 1] & 0xF) ^ 0xC) != 0)
- {
- throw new InvalidCipherTextException("malformed signature");
- }
-
- int delta = 0;
-
- if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0)
- {
- delta = 1;
- }
- else
- {
- int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF);
- Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName());
-
- if (trailerObj != null)
- {
- if (sigTrail != trailerObj.intValue())
- {
- throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail);
- }
- }
- else
- {
- throw new IllegalArgumentException("unrecognised hash in signature");
- }
-
- delta = 2;
- }
-
- //
- // find out how much padding we've got
- //
- int mStart = 0;
-
- for (mStart = 0; mStart != block.length; mStart++)
- {
- if (((block[mStart] & 0x0f) ^ 0x0a) == 0)
- {
- break;
- }
- }
-
- mStart++;
-
- int off = block.length - delta - digest.getDigestSize();
-
- //
- // there must be at least one byte of message string
- //
- if ((off - mStart) <= 0)
- {
- throw new InvalidCipherTextException("malformed block");
- }
-
- //
- // if we contain the whole message as well, check the hash of that.
- //
- if ((block[0] & 0x20) == 0)
- {
- fullMessage = true;
-
- recoveredMessage = new byte[off - mStart];
- System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length);
- }
- else
- {
- fullMessage = false;
-
- recoveredMessage = new byte[off - mStart];
- System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length);
- }
-
- preSig = signature;
- preBlock = block;
-
- digest.update(recoveredMessage, 0, recoveredMessage.length);
- messageLength = recoveredMessage.length;
- System.arraycopy(recoveredMessage, 0, mBuf, 0, recoveredMessage.length);
- }
-
- /**
- * update the internal digest with the byte b
- */
- public void update(
- byte b)
- {
- digest.update(b);
-
- if (messageLength < mBuf.length)
- {
- mBuf[messageLength] = b;
- }
-
- messageLength++;
- }
-
- /**
- * update the internal digest with the byte array in
- */
- public void update(
- byte[] in,
- int off,
- int len)
- {
- while (len > 0 && messageLength < mBuf.length)
- {
- this.update(in[off]);
- off++;
- len--;
- }
-
- digest.update(in, off, len);
- messageLength += len;
- }
-
- /**
- * reset the internal state
- */
- public void reset()
- {
- digest.reset();
- messageLength = 0;
- clearBlock(mBuf);
-
- if (recoveredMessage != null)
- {
- clearBlock(recoveredMessage);
- }
-
- recoveredMessage = null;
- fullMessage = false;
-
- if (preSig != null)
- {
- preSig = null;
- clearBlock(preBlock);
- preBlock = null;
- }
- }
-
- /**
- * generate a signature for the loaded message using the key we were
- * initialised with.
- */
- public byte[] generateSignature()
- throws CryptoException
- {
- int digSize = digest.getDigestSize();
-
- int t = 0;
- int delta = 0;
-
- if (trailer == TRAILER_IMPLICIT)
- {
- t = 8;
- delta = block.length - digSize - 1;
- digest.doFinal(block, delta);
- block[block.length - 1] = (byte)TRAILER_IMPLICIT;
- }
- else
- {
- t = 16;
- delta = block.length - digSize - 2;
- digest.doFinal(block, delta);
- block[block.length - 2] = (byte)(trailer >>> 8);
- block[block.length - 1] = (byte)trailer;
- }
-
- byte header = 0;
- int x = (digSize + messageLength) * 8 + t + 4 - keyBits;
-
- if (x > 0)
- {
- int mR = messageLength - ((x + 7) / 8);
- header = 0x60;
-
- delta -= mR;
-
- System.arraycopy(mBuf, 0, block, delta, mR);
- }
- else
- {
- header = 0x40;
- delta -= messageLength;
-
- System.arraycopy(mBuf, 0, block, delta, messageLength);
- }
-
- if ((delta - 1) > 0)
- {
- for (int i = delta - 1; i != 0; i--)
- {
- block[i] = (byte)0xbb;
- }
- block[delta - 1] ^= (byte)0x01;
- block[0] = (byte)0x0b;
- block[0] |= header;
- }
- else
- {
- block[0] = (byte)0x0a;
- block[0] |= header;
- }
-
- byte[] b = cipher.processBlock(block, 0, block.length);
-
- clearBlock(mBuf);
- clearBlock(block);
-
- return b;
- }
-
- /**
- * return true if the signature represents a ISO9796-2 signature
- * for the passed in message.
- */
- public boolean verifySignature(
- byte[] signature)
- {
- byte[] block = null;
-
- if (preSig == null)
- {
- try
- {
- block = cipher.processBlock(signature, 0, signature.length);
- }
- catch (Exception e)
- {
- return false;
- }
- }
- else
- {
- if (!Arrays.areEqual(preSig, signature))
- {
- throw new IllegalStateException("updateWithRecoveredMessage called on different signature");
- }
-
- block = preBlock;
-
- preSig = null;
- preBlock = null;
- }
-
- if (((block[0] & 0xC0) ^ 0x40) != 0)
- {
- return returnFalse(block);
- }
-
- if (((block[block.length - 1] & 0xF) ^ 0xC) != 0)
- {
- return returnFalse(block);
- }
-
- int delta = 0;
-
- if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0)
- {
- delta = 1;
- }
- else
- {
- int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF);
- Integer trailerObj = (Integer)trailerMap.get(digest.getAlgorithmName());
-
- if (trailerObj != null)
- {
- if (sigTrail != trailerObj.intValue())
- {
- throw new IllegalStateException("signer initialised with wrong digest for trailer " + sigTrail);
- }
- }
- else
- {
- throw new IllegalArgumentException("unrecognised hash in signature");
- }
-
- delta = 2;
- }
-
- //
- // find out how much padding we've got
- //
- int mStart = 0;
-
- for (mStart = 0; mStart != block.length; mStart++)
- {
- if (((block[mStart] & 0x0f) ^ 0x0a) == 0)
- {
- break;
- }
- }
-
- mStart++;
-
- //
- // check the hashes
- //
- byte[] hash = new byte[digest.getDigestSize()];
-
- int off = block.length - delta - hash.length;
-
- //
- // there must be at least one byte of message string
- //
- if ((off - mStart) <= 0)
- {
- return returnFalse(block);
- }
-
- //
- // if we contain the whole message as well, check the hash of that.
- //
- if ((block[0] & 0x20) == 0)
- {
- fullMessage = true;
-
- // check right number of bytes passed in.
- if (messageLength > off - mStart)
- {
- return returnFalse(block);
- }
-
- digest.reset();
- digest.update(block, mStart, off - mStart);
- digest.doFinal(hash, 0);
-
- boolean isOkay = true;
-
- for (int i = 0; i != hash.length; i++)
- {
- block[off + i] ^= hash[i];
- if (block[off + i] != 0)
- {
- isOkay = false;
- }
- }
-
- if (!isOkay)
- {
- return returnFalse(block);
- }
-
- recoveredMessage = new byte[off - mStart];
- System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length);
- }
- else
- {
- fullMessage = false;
-
- digest.doFinal(hash, 0);
-
- boolean isOkay = true;
-
- for (int i = 0; i != hash.length; i++)
- {
- block[off + i] ^= hash[i];
- if (block[off + i] != 0)
- {
- isOkay = false;
- }
- }
-
- if (!isOkay)
- {
- return returnFalse(block);
- }
-
- recoveredMessage = new byte[off - mStart];
- System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length);
- }
-
- //
- // if they've input a message check what we've recovered against
- // what was input.
- //
- if (messageLength != 0)
- {
- if (!isSameAs(mBuf, recoveredMessage))
- {
- return returnFalse(block);
- }
- }
-
- clearBlock(mBuf);
- clearBlock(block);
-
- return true;
- }
-
- private boolean returnFalse(byte[] block)
- {
- clearBlock(mBuf);
- clearBlock(block);
-
- return false;
- }
-
- /**
- * Return true if the full message was recoveredMessage.
- *
- * @return true on full message recovery, false otherwise.
- * @see org.bouncycastle.crypto.SignerWithRecovery#hasFullMessage()
- */
- public boolean hasFullMessage()
- {
- return fullMessage;
- }
-
- /**
- * Return a reference to the recoveredMessage message.
- *
- * @return the full/partial recoveredMessage message.
- * @see org.bouncycastle.crypto.SignerWithRecovery#getRecoveredMessage()
- */
- public byte[] getRecoveredMessage()
- {
- return recoveredMessage;
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java
deleted file mode 100644
index 8c9eb940..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/PSSSigner.java
+++ /dev/null
@@ -1,348 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.security.SecureRandom;
-
-import org.bouncycastle.crypto.AsymmetricBlockCipher;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.CryptoException;
-import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.Signer;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.crypto.params.RSABlindingParameters;
-import org.bouncycastle.crypto.params.RSAKeyParameters;
-
-/**
- * RSA-PSS as described in PKCS# 1 v 2.1.
- * <p>
- * Note: the usual value for the salt length is the number of
- * bytes in the hash function.
- */
-public class PSSSigner
- implements Signer
-{
- static final public byte TRAILER_IMPLICIT = (byte)0xBC;
-
- private Digest contentDigest;
- private Digest mgfDigest;
- private AsymmetricBlockCipher cipher;
- private SecureRandom random;
-
- private int hLen;
- private int mgfhLen;
- private int sLen;
- private int emBits;
- private byte[] salt;
- private byte[] mDash;
- private byte[] block;
- private byte trailer;
-
- /**
- * basic constructor
- *
- * @param cipher the asymmetric cipher to use.
- * @param digest the digest to use.
- * @param sLen the length of the salt to use (in bytes).
- */
- public PSSSigner(
- AsymmetricBlockCipher cipher,
- Digest digest,
- int sLen)
- {
- this(cipher, digest, sLen, TRAILER_IMPLICIT);
- }
-
- public PSSSigner(
- AsymmetricBlockCipher cipher,
- Digest contentDigest,
- Digest mgfDigest,
- int sLen)
- {
- this(cipher, contentDigest, mgfDigest, sLen, TRAILER_IMPLICIT);
- }
-
- public PSSSigner(
- AsymmetricBlockCipher cipher,
- Digest digest,
- int sLen,
- byte trailer)
- {
- this(cipher, digest, digest, sLen, trailer);
- }
-
- public PSSSigner(
- AsymmetricBlockCipher cipher,
- Digest contentDigest,
- Digest mgfDigest,
- int sLen,
- byte trailer)
- {
- this.cipher = cipher;
- this.contentDigest = contentDigest;
- this.mgfDigest = mgfDigest;
- this.hLen = contentDigest.getDigestSize();
- this.mgfhLen = mgfDigest.getDigestSize();
- this.sLen = sLen;
- this.salt = new byte[sLen];
- this.mDash = new byte[8 + sLen + hLen];
- this.trailer = trailer;
- }
-
- public void init(
- boolean forSigning,
- CipherParameters param)
- {
- CipherParameters params;
-
- if (param instanceof ParametersWithRandom)
- {
- ParametersWithRandom p = (ParametersWithRandom)param;
-
- params = p.getParameters();
- random = p.getRandom();
- }
- else
- {
- params = param;
- if (forSigning)
- {
- random = new SecureRandom();
- }
- }
-
- cipher.init(forSigning, params);
-
- RSAKeyParameters kParam;
-
- if (params instanceof RSABlindingParameters)
- {
- kParam = ((RSABlindingParameters)params).getPublicKey();
- }
- else
- {
- kParam = (RSAKeyParameters)params;
- }
-
- emBits = kParam.getModulus().bitLength() - 1;
-
- if (emBits < (8 * hLen + 8 * sLen + 9))
- {
- throw new IllegalArgumentException("key too small for specified hash and salt lengths");
- }
-
- block = new byte[(emBits + 7) / 8];
-
- reset();
- }
-
- /**
- * clear possible sensitive data
- */
- private void clearBlock(
- byte[] block)
- {
- for (int i = 0; i != block.length; i++)
- {
- block[i] = 0;
- }
- }
-
- /**
- * update the internal digest with the byte b
- */
- public void update(
- byte b)
- {
- contentDigest.update(b);
- }
-
- /**
- * update the internal digest with the byte array in
- */
- public void update(
- byte[] in,
- int off,
- int len)
- {
- contentDigest.update(in, off, len);
- }
-
- /**
- * reset the internal state
- */
- public void reset()
- {
- contentDigest.reset();
- }
-
- /**
- * generate a signature for the message we've been loaded with using
- * the key we were initialised with.
- */
- public byte[] generateSignature()
- throws CryptoException, DataLengthException
- {
- contentDigest.doFinal(mDash, mDash.length - hLen - sLen);
-
- if (sLen != 0)
- {
- random.nextBytes(salt);
-
- System.arraycopy(salt, 0, mDash, mDash.length - sLen, sLen);
- }
-
- byte[] h = new byte[hLen];
-
- contentDigest.update(mDash, 0, mDash.length);
-
- contentDigest.doFinal(h, 0);
-
- block[block.length - sLen - 1 - hLen - 1] = 0x01;
- System.arraycopy(salt, 0, block, block.length - sLen - hLen - 1, sLen);
-
- byte[] dbMask = maskGeneratorFunction1(h, 0, h.length, block.length - hLen - 1);
- for (int i = 0; i != dbMask.length; i++)
- {
- block[i] ^= dbMask[i];
- }
-
- block[0] &= (0xff >> ((block.length * 8) - emBits));
-
- System.arraycopy(h, 0, block, block.length - hLen - 1, hLen);
-
- block[block.length - 1] = trailer;
-
- byte[] b = cipher.processBlock(block, 0, block.length);
-
- clearBlock(block);
-
- return b;
- }
-
- /**
- * return true if the internal state represents the signature described
- * in the passed in array.
- */
- public boolean verifySignature(
- byte[] signature)
- {
- contentDigest.doFinal(mDash, mDash.length - hLen - sLen);
-
- try
- {
- byte[] b = cipher.processBlock(signature, 0, signature.length);
- System.arraycopy(b, 0, block, block.length - b.length, b.length);
- }
- catch (Exception e)
- {
- return false;
- }
-
- if (block[block.length - 1] != trailer)
- {
- clearBlock(block);
- return false;
- }
-
- byte[] dbMask = maskGeneratorFunction1(block, block.length - hLen - 1, hLen, block.length - hLen - 1);
-
- for (int i = 0; i != dbMask.length; i++)
- {
- block[i] ^= dbMask[i];
- }
-
- block[0] &= (0xff >> ((block.length * 8) - emBits));
-
- for (int i = 0; i != block.length - hLen - sLen - 2; i++)
- {
- if (block[i] != 0)
- {
- clearBlock(block);
- return false;
- }
- }
-
- if (block[block.length - hLen - sLen - 2] != 0x01)
- {
- clearBlock(block);
- return false;
- }
-
- System.arraycopy(block, block.length - sLen - hLen - 1, mDash, mDash.length - sLen, sLen);
-
- contentDigest.update(mDash, 0, mDash.length);
- contentDigest.doFinal(mDash, mDash.length - hLen);
-
- for (int i = block.length - hLen - 1, j = mDash.length - hLen;
- j != mDash.length; i++, j++)
- {
- if ((block[i] ^ mDash[j]) != 0)
- {
- clearBlock(mDash);
- clearBlock(block);
- return false;
- }
- }
-
- clearBlock(mDash);
- clearBlock(block);
-
- return true;
- }
-
- /**
- * int to octet string.
- */
- private void ItoOSP(
- int i,
- byte[] sp)
- {
- sp[0] = (byte)(i >>> 24);
- sp[1] = (byte)(i >>> 16);
- sp[2] = (byte)(i >>> 8);
- sp[3] = (byte)(i >>> 0);
- }
-
- /**
- * mask generator function, as described in PKCS1v2.
- */
- private byte[] maskGeneratorFunction1(
- byte[] Z,
- int zOff,
- int zLen,
- int length)
- {
- byte[] mask = new byte[length];
- byte[] hashBuf = new byte[mgfhLen];
- byte[] C = new byte[4];
- int counter = 0;
-
- mgfDigest.reset();
-
- while (counter < (length / mgfhLen))
- {
- ItoOSP(counter, C);
-
- mgfDigest.update(Z, zOff, zLen);
- mgfDigest.update(C, 0, C.length);
- mgfDigest.doFinal(hashBuf, 0);
-
- System.arraycopy(hashBuf, 0, mask, counter * mgfhLen, mgfhLen);
-
- counter++;
- }
-
- if ((counter * mgfhLen) < length)
- {
- ItoOSP(counter, C);
-
- mgfDigest.update(Z, zOff, zLen);
- mgfDigest.update(C, 0, C.length);
- mgfDigest.doFinal(hashBuf, 0);
-
- System.arraycopy(hashBuf, 0, mask, counter * mgfhLen, mask.length - (counter * mgfhLen));
- }
-
- return mask;
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java b/core/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java
deleted file mode 100644
index f34b18c2..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/RSADigestSigner.java
+++ /dev/null
@@ -1,240 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.io.IOException;
-import java.util.Hashtable;
-
-import org.bouncycastle.asn1.ASN1Encoding;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.DERNull;
-import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.DigestInfo;
-import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
-import org.bouncycastle.crypto.AsymmetricBlockCipher;
-import org.bouncycastle.crypto.CipherParameters;
-import org.bouncycastle.crypto.CryptoException;
-import org.bouncycastle.crypto.DataLengthException;
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.Signer;
-import org.bouncycastle.crypto.encodings.PKCS1Encoding;
-import org.bouncycastle.crypto.engines.RSABlindedEngine;
-import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
-import org.bouncycastle.crypto.params.ParametersWithRandom;
-import org.bouncycastle.util.Arrays;
-
-public class RSADigestSigner
- implements Signer
-{
- private final AsymmetricBlockCipher rsaEngine = new PKCS1Encoding(new RSABlindedEngine());
- private final AlgorithmIdentifier algId;
- private final Digest digest;
- private boolean forSigning;
-
- private static final Hashtable oidMap = new Hashtable();
-
- /*
- * Load OID table.
- */
- static
- {
- oidMap.put("RIPEMD128", TeleTrusTObjectIdentifiers.ripemd128);
- oidMap.put("RIPEMD160", TeleTrusTObjectIdentifiers.ripemd160);
- oidMap.put("RIPEMD256", TeleTrusTObjectIdentifiers.ripemd256);
-
- oidMap.put("SHA-1", X509ObjectIdentifiers.id_SHA1);
- oidMap.put("SHA-224", NISTObjectIdentifiers.id_sha224);
- oidMap.put("SHA-256", NISTObjectIdentifiers.id_sha256);
- oidMap.put("SHA-384", NISTObjectIdentifiers.id_sha384);
- oidMap.put("SHA-512", NISTObjectIdentifiers.id_sha512);
- oidMap.put("SHA-512/224", NISTObjectIdentifiers.id_sha512_224);
- oidMap.put("SHA-512/256", NISTObjectIdentifiers.id_sha512_256);
-
- oidMap.put("MD2", PKCSObjectIdentifiers.md2);
- oidMap.put("MD4", PKCSObjectIdentifiers.md4);
- oidMap.put("MD5", PKCSObjectIdentifiers.md5);
- }
-
- public RSADigestSigner(
- Digest digest)
- {
- this(digest, (ASN1ObjectIdentifier)oidMap.get(digest.getAlgorithmName()));
- }
-
- public RSADigestSigner(
- Digest digest,
- ASN1ObjectIdentifier digestOid)
- {
- this.digest = digest;
- this.algId = new AlgorithmIdentifier(digestOid, DERNull.INSTANCE);
- }
-
- /**
- * @deprecated
- */
- public String getAlgorithmName()
- {
- return digest.getAlgorithmName() + "withRSA";
- }
-
- /**
- * initialise the signer for signing or verification.
- *
- * @param forSigning
- * true if for signing, false otherwise
- * @param parameters
- * necessary parameters.
- */
- public void init(
- boolean forSigning,
- CipherParameters parameters)
- {
- this.forSigning = forSigning;
- AsymmetricKeyParameter k;
-
- if (parameters instanceof ParametersWithRandom)
- {
- k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters();
- }
- else
- {
- k = (AsymmetricKeyParameter)parameters;
- }
-
- if (forSigning && !k.isPrivate())
- {
- throw new IllegalArgumentException("signing requires private key");
- }
-
- if (!forSigning && k.isPrivate())
- {
- throw new IllegalArgumentException("verification requires public key");
- }
-
- reset();
-
- rsaEngine.init(forSigning, parameters);
- }
-
- /**
- * update the internal digest with the byte b
- */
- public void update(
- byte input)
- {
- digest.update(input);
- }
-
- /**
- * update the internal digest with the byte array in
- */
- public void update(
- byte[] input,
- int inOff,
- int length)
- {
- digest.update(input, inOff, length);
- }
-
- /**
- * Generate a signature for the message we've been loaded with using the key
- * we were initialised with.
- */
- public byte[] generateSignature()
- throws CryptoException, DataLengthException
- {
- if (!forSigning)
- {
- throw new IllegalStateException("RSADigestSigner not initialised for signature generation.");
- }
-
- byte[] hash = new byte[digest.getDigestSize()];
- digest.doFinal(hash, 0);
-
- try
- {
- byte[] data = derEncode(hash);
- return rsaEngine.processBlock(data, 0, data.length);
- }
- catch (IOException e)
- {
- throw new CryptoException("unable to encode signature: " + e.getMessage(), e);
- }
- }
-
- /**
- * return true if the internal state represents the signature described in
- * the passed in array.
- */
- public boolean verifySignature(
- byte[] signature)
- {
- if (forSigning)
- {
- throw new IllegalStateException("RSADigestSigner not initialised for verification");
- }
-
- byte[] hash = new byte[digest.getDigestSize()];
-
- digest.doFinal(hash, 0);
-
- byte[] sig;
- byte[] expected;
-
- try
- {
- sig = rsaEngine.processBlock(signature, 0, signature.length);
- expected = derEncode(hash);
- }
- catch (Exception e)
- {
- return false;
- }
-
- if (sig.length == expected.length)
- {
- return Arrays.constantTimeAreEqual(sig, expected);
- }
- else if (sig.length == expected.length - 2) // NULL left out
- {
- int sigOffset = sig.length - hash.length - 2;
- int expectedOffset = expected.length - hash.length - 2;
-
- expected[1] -= 2; // adjust lengths
- expected[3] -= 2;
-
- int nonEqual = 0;
-
- for (int i = 0; i < hash.length; i++)
- {
- nonEqual |= (sig[sigOffset + i] ^ expected[expectedOffset + i]);
- }
-
- for (int i = 0; i < sigOffset; i++)
- {
- nonEqual |= (sig[i] ^ expected[i]); // check header less NULL
- }
-
- return nonEqual == 0;
- }
- else
- {
- return false;
- }
- }
-
- public void reset()
- {
- digest.reset();
- }
-
- private byte[] derEncode(
- byte[] hash)
- throws IOException
- {
- DigestInfo dInfo = new DigestInfo(algId, hash);
-
- return dInfo.getEncoded(ASN1Encoding.DER);
- }
-}
diff --git a/core/src/main/java/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java b/core/src/main/java/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java
deleted file mode 100644
index bbd8cda6..00000000
--- a/core/src/main/java/org/bouncycastle/crypto/signers/RandomDSAKCalculator.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.bouncycastle.crypto.signers;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-class RandomDSAKCalculator
- implements DSAKCalculator
-{
- private static final BigInteger ZERO = BigInteger.valueOf(0);
-
- private BigInteger q;
- private SecureRandom random;
-
- public boolean isDeterministic()
- {
- return false;
- }
-
- public void init(BigInteger n, SecureRandom random)
- {
- this.q = n;
- this.random = random;
- }
-
- public void init(BigInteger n, BigInteger d, byte[] message)
- {
- throw new IllegalStateException("Operation not supported");
- }
-
- public BigInteger nextK()
- {
- int qBitLength = q.bitLength();
-
- BigInteger k;
- do
- {
- k = new BigInteger(qBitLength, random);
- }
- while (k.equals(ZERO) || k.compareTo(q) >= 0);
-
- return k;
- }
-}