diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-06-21 12:16:37 +0400 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-06-21 12:16:37 +0400 |
commit | 2e05e49616ffaea79bcde9d578486b51408718a4 (patch) | |
tree | f9cb0ee6d49487d70fad72cb60e36115c3454078 /core/src/main/java/org/bouncycastle/crypto | |
parent | 17a8e3bd2d36580e8f49484341960137f724a3e7 (diff) | |
parent | a51207405bebf737c2dcae501dd8c02c9c2cd88a (diff) |
Merge branch 'master' of https://github.com/franziskuskiefer/bc-java into franziskuskiefer-master
Conflicts:
.gitignore
Diffstat (limited to 'core/src/main/java/org/bouncycastle/crypto')
9 files changed, 823 insertions, 0 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCiphertext.java b/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCiphertext.java new file mode 100644 index 00000000..1e43eb2a --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCiphertext.java @@ -0,0 +1,162 @@ +package org.bouncycastle.crypto.engines; + +import java.math.BigInteger; + +/** + * + * Class, holding Cramer Shoup ciphertexts (u1, u2, e, v) + * + */ +public class CramerShoupCiphertext { + + BigInteger u1, u2, e, v; + + public CramerShoupCiphertext() { + + } + + public CramerShoupCiphertext(BigInteger u1, BigInteger u2, BigInteger e, BigInteger v){ + this.u1 = u1; + this.u2 = u2; + this.e = e; + this.v = v; + } + + public CramerShoupCiphertext(byte[] c){ + int off = 0, s; + byte[] size = new byte[4]; + byte[] tmp; + + System.arraycopy(c, off, size, 0, 4); + s = byteArrayToInt(size); + tmp = new byte[s]; + off += 4; + System.arraycopy(c, off, tmp, 0, s); + off += s; + u1 = new BigInteger(tmp); + + System.arraycopy(c, off, size, 0, 4); + s = byteArrayToInt(size); + tmp = new byte[s]; + off += 4; + System.arraycopy(c, off, tmp, 0, s); + off += s; + u2 = new BigInteger(tmp); + + System.arraycopy(c, off, size, 0, 4); + s = byteArrayToInt(size); + tmp = new byte[s]; + off += 4; + System.arraycopy(c, off, tmp, 0, s); + off += s; + e = new BigInteger(tmp); + + System.arraycopy(c, off, size, 0, 4); + s = byteArrayToInt(size); + tmp = new byte[s]; + off += 4; + System.arraycopy(c, off, tmp, 0, s); + off += s; + v = new BigInteger(tmp); + } + + public BigInteger getU1() { + return u1; + } + + public void setU1(BigInteger u1) { + this.u1 = u1; + } + + public BigInteger getU2() { + return u2; + } + + public void setU2(BigInteger u2) { + this.u2 = u2; + } + + public BigInteger getE() { + return e; + } + + public void setE(BigInteger e) { + this.e = e; + } + + public BigInteger getV() { + return v; + } + + public void setV(BigInteger v) { + this.v = v; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + + result.append("u1: "+u1.toString()); + result.append("\nu2: "+u2.toString()); + result.append("\ne: "+e.toString()); + result.append("\nv: "+v.toString()); + + return result.toString(); + } + + /** + * convert the cipher-text in a byte array, + * prepending them with 4 Bytes for their length + * + * @return + */ + public byte[] toByteArray(){ + + byte[] u1Bytes = u1.toByteArray(); + int u1Length = u1Bytes.length; + byte[] u2Bytes = u2.toByteArray(); + int u2Length = u2Bytes.length; + byte[] eBytes = e.toByteArray(); + int eLength = eBytes.length; + byte[] vBytes = v.toByteArray(); + int vLength = vBytes.length; + + int off = 0; + byte[] result = new byte[u1Length+u2Length+eLength+vLength+4*4]; + System.arraycopy(intToByteArray(u1Length), 0, result, 0, 4); + off += 4; + System.arraycopy(u1Bytes, 0, result, off, u1Length); + off += u1Length; + System.arraycopy(intToByteArray(u2Length), 0, result, off, 4); + off += 4; + System.arraycopy(u2Bytes, 0, result, off , u2Length); + off += u2Length; + System.arraycopy(intToByteArray(eLength), 0, result, off, 4); + off += 4; + System.arraycopy(eBytes, 0, result, off, eLength); + off += eLength; + System.arraycopy(intToByteArray(vLength), 0, result, off, 4); + off += 4; + System.arraycopy(vBytes, 0, result, off, vLength); + + return result; + } + + private byte[] intToByteArray(int in){ + byte[] bytes = new byte[4]; + for (int i = 0; i < 4; i++) { + bytes[3-i] = (byte)(in >>> (i * 8)); + } + return bytes; + } + + private int byteArrayToInt(byte[] in){ + if (in.length != 4) + return -1; + int r = 0; + for (int i = 3; i >= 0; i--) { + r += (int)in[i] << ((3-i) * 8); + } + return r; + } +}
\ No newline at end of file diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCoreEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCoreEngine.java new file mode 100644 index 00000000..71cab278 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/engines/CramerShoupCoreEngine.java @@ -0,0 +1,266 @@ +package org.bouncycastle.crypto.engines; + +import java.math.BigInteger; +import java.security.SecureRandom; + +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.params.CramerShoupKeyParameters; +import org.bouncycastle.crypto.params.CramerShoupPrivateKeyParameters; +import org.bouncycastle.crypto.params.CramerShoupPublicKeyParameters; +import org.bouncycastle.crypto.params.ParametersWithRandom; +import org.bouncycastle.util.BigIntegers; + +/** + * + * Essentially the Cramer-Shoup encryption / decryption algorithms according to + * "A practical public key cryptosystem provably secure against adaptive chosen ciphertext attack." (Crypto 1998) + * + */ +public class CramerShoupCoreEngine { + + private static final BigInteger ONE = BigInteger.ONE; + + private CramerShoupKeyParameters key; + private boolean forEncryption; + private String label = null; + + /** + * initialise the CramerShoup engine. + * + * @param enc + * whether this engine should encrypt or decrypt + * @param param + * the necessary CramerShoup key parameters. + * @param label + * the label for labelled CS as {@link String} + */ + public void init(boolean enc, CipherParameters param, String label) { + init(enc, param); + + this.label = label; + } + + /** + * initialise the CramerShoup engine. + * + * @param enc + * whether this engine should encrypt or decrypt + * @param param + * the necessary CramerShoup key parameters. + */ + public void init(boolean enc, CipherParameters param) { + if (param instanceof ParametersWithRandom) { + ParametersWithRandom rParam = (ParametersWithRandom) param; + + key = (CramerShoupKeyParameters) rParam.getParameters(); + } else { + key = (CramerShoupKeyParameters) param; + } + + this.forEncryption = enc; + } + + /** + * Return the maximum size for an input block to this engine. For Cramer + * Shoup this is always one byte less than the key size on encryption, and + * the same length as the key size on decryption. + * + * @return maximum size for an input block. + * + * TODO: correct? + */ + public int getInputBlockSize() { + int bitSize = key.getParameters().getP().bitLength(); + + if (forEncryption) { + return (bitSize + 7) / 8 - 1; + } else { + return (bitSize + 7) / 8; + } + } + + /** + * Return the maximum size for an output block to this engine. For Cramer + * Shoup this is always one byte less than the key size on decryption, and + * the same length as the key size on encryption. + * + * @return maximum size for an output block. + * + * TODO: correct? + */ + public int getOutputBlockSize() { + int bitSize = key.getParameters().getP().bitLength(); + + if (forEncryption) { + return (bitSize + 7) / 8; + } else { + return (bitSize + 7) / 8 - 1; + } + } + + public BigInteger convertInput(byte[] in, int inOff, int inLen) { + if (inLen > (getInputBlockSize() + 1)) { + throw new DataLengthException("input too large for Cramer Shoup cipher."); + } else if (inLen == (getInputBlockSize() + 1) && !forEncryption) { + throw new DataLengthException("input too large for Cramer Shoup cipher."); + } + + byte[] block; + + if (inOff != 0 || inLen != in.length) { + block = new byte[inLen]; + + System.arraycopy(in, inOff, block, 0, inLen); + } else { + block = in; + } + + BigInteger res = new BigInteger(1, block); + if (res.compareTo(key.getParameters().getP()) >= 0) { + throw new DataLengthException("input too large for Cramer Shoup cipher."); + } + + return res; + } + + public byte[] convertOutput(BigInteger result) { + byte[] output = result.toByteArray(); + + if (forEncryption) { + if (output[0] == 0 && output.length > getOutputBlockSize()) { // have ended up with an extra zero byte, copy down. + byte[] tmp = new byte[output.length - 1]; + + System.arraycopy(output, 1, tmp, 0, tmp.length); + + return tmp; + } + + if (output.length < getOutputBlockSize()) {// have ended up with less bytes than normal, lengthen + byte[] tmp = new byte[getOutputBlockSize()]; + + System.arraycopy(output, 0, tmp, tmp.length - output.length, output.length); + + return tmp; + } + } else { + if (output[0] == 0) { // have ended up with an extra zero byte, copy down. + byte[] tmp = new byte[output.length - 1]; + + System.arraycopy(output, 1, tmp, 0, tmp.length); + + return tmp; + } + } + + return output; + } + + public CramerShoupCiphertext encryptBlock(BigInteger input) { + + CramerShoupCiphertext result = null; + + + if (!key.isPrivate() && !this.forEncryption && key instanceof CramerShoupPublicKeyParameters) { + CramerShoupPublicKeyParameters pk = (CramerShoupPublicKeyParameters)key; + BigInteger p = pk.getParameters().getP(); + BigInteger g1 = pk.getParameters().getG1(); + BigInteger g2 = pk.getParameters().getG2(); + + BigInteger h = pk.getH(); + + if (!isValidMessage(input, p)) + return result; + + BigInteger r = generateRandomElement(p, new SecureRandom()); + + BigInteger u1, u2, v, e, a; + + u1 = g1.modPow(r, p); + u2 = g2.modPow(r, p); + e = h.modPow(r, p).multiply(input).mod(p); + + Digest digest = pk.getParameters().getH(); + byte[] u1Bytes = u1.toByteArray(); + digest.update(u1Bytes, 0, u1Bytes.length); + byte[] u2Bytes = u2.toByteArray(); + digest.update(u2Bytes, 0, u2Bytes.length); + byte[] eBytes = e.toByteArray(); + digest.update(eBytes, 0, eBytes.length); + if (this.label != null){ + byte[] lBytes = this.label.getBytes(); + digest.update(lBytes, 0, lBytes.length); + } + byte[] out = new byte[digest.getDigestSize()]; + digest.doFinal(out , 0); + a = new BigInteger(1, out); + + v = pk.getC().modPow(r, p).multiply(pk.getD().modPow(r.multiply(a), p)).mod(p); + + result = new CramerShoupCiphertext(u1, u2, e, v); + } + return result; + } + + public BigInteger decryptBlock(CramerShoupCiphertext input) throws CramerShoupCiphertextException { + + BigInteger result = null; + + if (key.isPrivate() && this.forEncryption && key instanceof CramerShoupPrivateKeyParameters) { + CramerShoupPrivateKeyParameters sk = (CramerShoupPrivateKeyParameters)key; + + BigInteger p = sk.getParameters().getP(); + + Digest digest = sk.getParameters().getH(); + byte[] u1Bytes = input.getU1().toByteArray(); + digest.update(u1Bytes, 0, u1Bytes.length); + byte[] u2Bytes = input.getU2().toByteArray(); + digest.update(u2Bytes, 0, u2Bytes.length); + byte[] eBytes = input.getE().toByteArray(); + digest.update(eBytes, 0, eBytes.length); + if (this.label != null){ + byte[] lBytes = this.label.getBytes(); + digest.update(lBytes, 0, lBytes.length); + } + byte[] out = new byte[digest.getDigestSize()]; + digest.doFinal(out , 0); + + BigInteger a = new BigInteger(1, out); + BigInteger v = input.u1.modPow(sk.getX1().add(sk.getY1().multiply(a)), p). + multiply(input.u2.modPow(sk.getX2().add(sk.getY2().multiply(a)), p)).mod(p); + + // check correctness of ciphertext + if (input.v.equals(v)){ + result = input.e.multiply(input.u1.modPow(sk.getZ(), p).modInverse(p)).mod(p); + } else { + throw new CramerShoupCiphertextException("Sorry, that ciphertext is not correct"); + } + } + return result; + } + + private BigInteger generateRandomElement(BigInteger p, SecureRandom random) { + return BigIntegers.createRandomInRange(ONE, p.subtract(ONE), random); + } + + /** + * just checking whether the message m is actually less than the group order p + */ + private boolean isValidMessage(BigInteger m, BigInteger p){ + return m.compareTo(p) < 0; + } + + /** + * CS exception for wrong cipher-texts + */ + public class CramerShoupCiphertextException extends Exception { + + private static final long serialVersionUID = -6360977166495345076L; + + public CramerShoupCiphertextException(String msg) { + super(msg); + } + + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupKeyPairGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupKeyPairGenerator.java new file mode 100644 index 00000000..8fcdf858 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupKeyPairGenerator.java @@ -0,0 +1,63 @@ +package org.bouncycastle.crypto.generators; + +import java.math.BigInteger; +import java.security.SecureRandom; + +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; +import org.bouncycastle.crypto.KeyGenerationParameters; +import org.bouncycastle.crypto.params.CramerShoupKeyGenerationParameters; +import org.bouncycastle.crypto.params.CramerShoupParameters; +import org.bouncycastle.crypto.params.CramerShoupPrivateKeyParameters; +import org.bouncycastle.crypto.params.CramerShoupPublicKeyParameters; +import org.bouncycastle.util.BigIntegers; + +/** + * a Cramer Shoup key pair generator + * + */ +public class CramerShoupKeyPairGenerator implements AsymmetricCipherKeyPairGenerator { + + private static final BigInteger ONE = BigInteger.valueOf(1); + + private CramerShoupKeyGenerationParameters param; + + public void init(KeyGenerationParameters param) { + this.param = (CramerShoupKeyGenerationParameters) param; + } + + public AsymmetricCipherKeyPair generateKeyPair() { + CramerShoupParameters csParams = param.getParameters(); + + CramerShoupPrivateKeyParameters sk = generatePrivateKey(param.getRandom(), csParams); + CramerShoupPublicKeyParameters pk = calculatePublicKey(csParams, sk); + sk.setPk(pk); + + return new AsymmetricCipherKeyPair(pk, sk); + } + + private BigInteger generateRandomElement(BigInteger p, SecureRandom random) { + return BigIntegers.createRandomInRange(ONE, p.subtract(ONE), random); + } + + private CramerShoupPrivateKeyParameters generatePrivateKey(SecureRandom random, CramerShoupParameters csParams){ + BigInteger p = csParams.getP(); + CramerShoupPrivateKeyParameters key = new CramerShoupPrivateKeyParameters(csParams, + generateRandomElement(p, random), generateRandomElement(p, random), + generateRandomElement(p, random), generateRandomElement(p, random), + generateRandomElement(p, random)); + return key; + } + + private CramerShoupPublicKeyParameters calculatePublicKey(CramerShoupParameters csParams, CramerShoupPrivateKeyParameters sk) { + BigInteger g1 = csParams.getG1(); + BigInteger g2 = csParams.getG2(); + BigInteger p = csParams.getP(); + + BigInteger c = g1.modPow(sk.getX1(), p).multiply(g2.modPow(sk.getX2(), p)); + BigInteger d = g1.modPow(sk.getY1(), p).multiply(g2.modPow(sk.getY2(), p)); + BigInteger h = g1.modPow(sk.getZ(), p); + + return new CramerShoupPublicKeyParameters(csParams, c, d, h); + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java new file mode 100644 index 00000000..704b1de4 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/generators/CramerShoupParametersGenerator.java @@ -0,0 +1,112 @@ +package org.bouncycastle.crypto.generators; + +import java.math.BigInteger; +import java.security.SecureRandom; + +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.params.CramerShoupParameters; +import org.bouncycastle.crypto.params.DHParameters; +import org.bouncycastle.util.BigIntegers; + +public class CramerShoupParametersGenerator { + + private int size; + private int certainty; + private SecureRandom random; + + /** + * Initialise the parameters generator. + * + * @param size + * bit length for the prime p + * @param certainty + * a measure of the uncertainty that the caller is willing to tolerate: + * the probability that the generated modulus is prime exceeds (1 - 1/2^certainty). + * The execution time of this method is proportional to the value of this parameter. + * @param random + * a source of randomness + */ + public void init(int size, int certainty, SecureRandom random) { + this.size = size; + this.certainty = certainty; + this.random = random; + } + + /** + * which generates the p and g values from the given parameters, returning + * the CramerShoupParameters object. + * <p> + * Note: can take a while... + */ + public CramerShoupParameters generateParameters() { + // + // find a safe prime p where p = 2*q + 1, where p and q are prime. + // + BigInteger[] safePrimes = ParametersHelper.generateSafePrimes(size, certainty, random); + +// BigInteger p = safePrimes[0]; + BigInteger q = safePrimes[1]; + BigInteger g1 = ParametersHelper.selectGenerator(q, random); + BigInteger g2 = ParametersHelper.selectGenerator(q, random); + while(g1.equals(g2)){ + g2 = ParametersHelper.selectGenerator(q, random); + } + + return new CramerShoupParameters(q, g1, g2, new SHA256Digest()); + } + + public CramerShoupParameters generateParameters(DHParameters dhParams){ + BigInteger p = dhParams.getP(); + BigInteger g1 = dhParams.getG(); + + // now we just need a second generator + BigInteger g2 = ParametersHelper.selectGenerator(p, random); + while(g1.equals(g2)){ + g2 = ParametersHelper.selectGenerator(p, random); + } + + return new CramerShoupParameters(p, g1, g2, new SHA256Digest()); + } + + private static class ParametersHelper { + + private static final BigInteger TWO = BigInteger.valueOf(2); + + /* + * Finds a pair of prime BigInteger's {p, q: p = 2q + 1} + * + * (see: Handbook of Applied Cryptography 4.86) + */ + static BigInteger[] generateSafePrimes(int size, int certainty, SecureRandom random) { + BigInteger p, q; + int qLength = size - 1; + + for (;;) { + q = new BigInteger(qLength, 2, random); + p = q.shiftLeft(1).add(BigInteger.ONE); + if (p.isProbablePrime(certainty) && (certainty <= 2 || q.isProbablePrime(certainty))) { + break; + } + } + + return new BigInteger[] { p, q }; + } + + static BigInteger selectGenerator(BigInteger p, SecureRandom random) { + BigInteger pMinusTwo = p.subtract(TWO); + BigInteger g; + + /* + * RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81) + */ + do { + BigInteger h = BigIntegers.createRandomInRange(TWO, pMinusTwo, random); + + g = h.modPow(TWO, p); + } while (g.equals(BigInteger.ONE)); + + return g; + } + } + +} diff --git a/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupKeyGenerationParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupKeyGenerationParameters.java new file mode 100644 index 00000000..15b6d6a5 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupKeyGenerationParameters.java @@ -0,0 +1,24 @@ +package org.bouncycastle.crypto.params; + +import java.security.SecureRandom; + +import org.bouncycastle.crypto.KeyGenerationParameters; + +public class CramerShoupKeyGenerationParameters extends KeyGenerationParameters { + + private CramerShoupParameters params; + + public CramerShoupKeyGenerationParameters(SecureRandom random, CramerShoupParameters params) { + super(random, getStrength(params)); + + this.params = params; + } + + public CramerShoupParameters getParameters() { + return params; + } + + static int getStrength(CramerShoupParameters params) { + return params.getP().bitLength(); + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupKeyParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupKeyParameters.java new file mode 100644 index 00000000..9e4219c8 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupKeyParameters.java @@ -0,0 +1,40 @@ +package org.bouncycastle.crypto.params; + +public class CramerShoupKeyParameters extends AsymmetricKeyParameter { + + private CramerShoupParameters params; + + protected CramerShoupKeyParameters(boolean isPrivate, CramerShoupParameters params) { + super(isPrivate); + + this.params = params; + } + + public CramerShoupParameters getParameters() { + return params; + } + + public boolean equals(Object obj) { + if (!(obj instanceof CramerShoupKeyParameters)) { + return false; + } + + CramerShoupKeyParameters csKey = (CramerShoupKeyParameters) obj; + + if (params == null) { + return csKey.getParameters() == null; + } else { + return params.equals(csKey.getParameters()); + } + } + + public int hashCode() { + int code = isPrivate() ? 0 : 1; + + if (params != null) { + code ^= params.hashCode(); + } + + return code; + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupParameters.java new file mode 100644 index 00000000..24264b6c --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupParameters.java @@ -0,0 +1,53 @@ +package org.bouncycastle.crypto.params; + +import java.math.BigInteger; + +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.Digest; + +public class CramerShoupParameters implements CipherParameters { + + private BigInteger p; // prime order of G + private BigInteger g1, g2; // generate G + + private Digest H; // hash function + + public CramerShoupParameters(BigInteger p, BigInteger g1, BigInteger g2, Digest H) { + this.p = p; + this.g1 = g1; + this.g2 = g2; + this.H = H; + } + + public boolean equals(Object obj) { + if (!(obj instanceof DSAParameters)) { + return false; + } + + CramerShoupParameters pm = (CramerShoupParameters) obj; + + return (pm.getP().equals(p) && pm.getG1().equals(g1) && pm.getG2().equals(g2)); + } + + public int hashCode() { + return getP().hashCode() ^ getG1().hashCode() ^ getG2().hashCode(); + } + + public BigInteger getG1() { + return g1; + } + + public BigInteger getG2() { + return g2; + } + + public BigInteger getP() { + return p; + } + + public Digest getH() { + H.reset(); + return H; + } + +} diff --git a/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupPrivateKeyParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupPrivateKeyParameters.java new file mode 100644 index 00000000..79de46ad --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupPrivateKeyParameters.java @@ -0,0 +1,61 @@ +package org.bouncycastle.crypto.params; + +import java.math.BigInteger; + +public class CramerShoupPrivateKeyParameters extends CramerShoupKeyParameters { + + private BigInteger x1, x2, y1, y2, z; // Z_p + private CramerShoupPublicKeyParameters pk; // public key + + public CramerShoupPrivateKeyParameters(CramerShoupParameters params, BigInteger x1, BigInteger x2, BigInteger y1, BigInteger y2, BigInteger z) { + super(true, params); + + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; + this.z = z; + } + + public BigInteger getX1() { + return x1; + } + + public BigInteger getX2() { + return x2; + } + + public BigInteger getY1() { + return y1; + } + + public BigInteger getY2() { + return y2; + } + + public BigInteger getZ() { + return z; + } + + public void setPk(CramerShoupPublicKeyParameters pk) { + this.pk = pk; + } + + public CramerShoupPublicKeyParameters getPk() { + return pk; + } + + public int hashCode() { + return x1.hashCode() ^ x2.hashCode() ^ y1.hashCode() ^ y2.hashCode() ^ z.hashCode() ^ super.hashCode(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof CramerShoupPrivateKeyParameters)) { + return false; + } + + CramerShoupPrivateKeyParameters other = (CramerShoupPrivateKeyParameters) obj; + + return other.getX1().equals(this.x1) && other.getX2().equals(this.x2) && other.getY1().equals(this.y1) && other.getY2().equals(this.y2) && other.getZ().equals(this.z) && super.equals(obj); + } +} diff --git a/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupPublicKeyParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupPublicKeyParameters.java new file mode 100644 index 00000000..341149c1 --- /dev/null +++ b/core/src/main/java/org/bouncycastle/crypto/params/CramerShoupPublicKeyParameters.java @@ -0,0 +1,42 @@ +package org.bouncycastle.crypto.params; + +import java.math.BigInteger; + +public class CramerShoupPublicKeyParameters extends CramerShoupKeyParameters { + + private BigInteger c, d, h; // public key group elements + + public CramerShoupPublicKeyParameters(CramerShoupParameters params, BigInteger c, BigInteger d, BigInteger h) { + super(false, params); + + this.c = c; + this.d = d; + this.h = h; + } + + public BigInteger getC() { + return c; + } + + public BigInteger getD() { + return d; + } + + public BigInteger getH() { + return h; + } + + public int hashCode() { + return c.hashCode() ^ d.hashCode() ^ h.hashCode() ^ super.hashCode(); + } + + public boolean equals(Object obj) { + if (!(obj instanceof CramerShoupPublicKeyParameters)) { + return false; + } + + CramerShoupPublicKeyParameters other = (CramerShoupPublicKeyParameters) obj; + + return other.getC().equals(c) && other.getD().equals(d) && other.getH().equals(h) && super.equals(obj); + } +} |