public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter key) { /* * Process DH private key. * The value for L was set to zero implicitly. * This is the same action as found in JCEDHPrivateKey getEncoded method. */ if (key is ElGamalPrivateKeyParameters) { ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)key; PrivateKeyInfo info = new PrivateKeyInfo( new AlgorithmIdentifier( OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter( _key.getParameters().getP(), _key.getParameters().getG()).toASN1Object()), new DERInteger(_key.getX())); return(info); } if (key is DSAPrivateKeyParameters) { DSAPrivateKeyParameters _key = (DSAPrivateKeyParameters)key; PrivateKeyInfo info = new PrivateKeyInfo( new AlgorithmIdentifier( X9ObjectIdentifiers.id_dsa, new DSAParameter( _key.getParameters().getP(), _key.getParameters().getQ(), _key.getParameters().getG()).toASN1Object()), new DERInteger(_key.getX())); return(info); } if (key is DHPrivateKeyParameters) { DHPrivateKeyParameters _key = (DHPrivateKeyParameters)key; PrivateKeyInfo info = new PrivateKeyInfo( new AlgorithmIdentifier( PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter( _key.getParameters().getP(), _key.getParameters().getG(), 0 ).toASN1Object() ) , new DERInteger(_key.getX())); return(info); } if (key is RSAPrivateCrtKeyParameters) { RSAPrivateCrtKeyParameters _key = (RSAPrivateCrtKeyParameters)key; PrivateKeyInfo info = new PrivateKeyInfo( new AlgorithmIdentifier( PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new RSAPrivateKeyStructure( _key.getModulus(), _key.getPublicExponent(), _key.getExponent(), _key.getP(), _key.getQ(), _key.getDP(), _key.getDQ(), _key.getQInv()).toASN1Object()); return(info); } if (key is ECPrivateKeyParameters) { ECPrivateKeyParameters _key = (ECPrivateKeyParameters)key; X9ECParameters ecP = new X9ECParameters( _key.getParameters().getCurve(), _key.getParameters().getG(), _key.getParameters().getN(), _key.getParameters().getH(), _key.getParameters().getSeed()); X962Parameters x962 = new X962Parameters(ecP); PrivateKeyInfo info = new PrivateKeyInfo( new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, x962.toASN1Object()), new ECPrivateKeyStructure(_key.getD()).toASN1Object()); return(info); } throw (new Exception("Class provided is not convertable:" + key.GetType())); }
/** * Process a single block using the basic ElGamal algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param inLen the length of the data to be processed. * @return the result of the ElGamal process. * @exception DataLengthException the input block is too large. */ public byte[] processBlock( byte[] inBytes, int inOff, int inLen) { if (inLen > (getInputBlockSize() + 1)) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } else if (inLen == (getInputBlockSize() + 1) && (inBytes[inOff] & 0x80) != 0) { throw new DataLengthException("input too large for ElGamal cipher.\n"); } byte[] block; if (inOff != 0 || inLen != inBytes.Length) { block = new byte[inLen]; Array.Copy(inBytes, inOff, block, 0, inLen); } else { block = inBytes; } BigInteger input = new BigInteger(1, block); BigInteger g = key.getParameters().getG(); BigInteger p = key.getParameters().getP(); if (typeof(ElGamalPrivateKeyParameters).IsInstanceOfType(key)) { byte[] in1 = new byte[inBytes.Length / 2]; byte[] in2 = new byte[inBytes.Length / 2]; Array.Copy(inBytes, 0, in1, 0, in1.Length); Array.Copy(inBytes, in1.Length, in2, 0, in2.Length); BigInteger gamma = new BigInteger(1, in1); BigInteger phi = new BigInteger(1, in2); ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)key; BigInteger m = gamma.modPow(p.subtract(ONE).subtract(priv.getX()), p).multiply(phi).mod(p); byte[] outBytes = m.toByteArray(); if (outBytes[0] != 0) { return(outBytes); } else { byte[] output = new byte[outBytes.Length - 1]; Array.Copy(outBytes, 1, output, 0, output.Length); return(output); } } else { ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)key; BigInteger k = new BigInteger(p.bitLength(), random); while (k.Equals(ZERO) || (k.compareTo(p.subtract(TWO)) > 0)) { k = new BigInteger(p.bitLength(), random); } BigInteger gamma = g.modPow(k, p); BigInteger phi = input.multiply(pub.getY().modPow(k, p)).mod(p); byte[] out1 = gamma.toByteArray(); byte[] out2 = phi.toByteArray(); byte[] output = new byte[this.getOutputBlockSize()]; if (out1[0] == 0) { Array.Copy(out1, 1, output, output.Length / 2 - (out1.Length - 1), out1.Length - 1); } else { Array.Copy(out1, 0, output, output.Length / 2 - out1.Length, out1.Length); } if (out2[0] == 0) { Array.Copy(out2, 1, output, output.Length - (out2.Length - 1), out2.Length - 1); } else { Array.Copy(out2, 0, output, output.Length - out2.Length, out2.Length); } return(output); } }