1 package org.bouncycastle.jcajce.provider.asymmetric.elgamal; 2 3 import java.io.IOException; 4 import java.io.ObjectInputStream; 5 import java.io.ObjectOutputStream; 6 import java.math.BigInteger; 7 8 import javax.crypto.interfaces.DHPublicKey; 9 import javax.crypto.spec.DHParameterSpec; 10 import javax.crypto.spec.DHPublicKeySpec; 11 12 import org.bouncycastle.asn1.ASN1Encoding; 13 import org.bouncycastle.asn1.ASN1Integer; 14 import org.bouncycastle.asn1.oiw.ElGamalParameter; 15 import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; 16 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 17 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 18 import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters; 19 import org.bouncycastle.jce.interfaces.ElGamalPublicKey; 20 import org.bouncycastle.jce.spec.ElGamalParameterSpec; 21 import org.bouncycastle.jce.spec.ElGamalPublicKeySpec; 22 23 public class BCElGamalPublicKey 24 implements ElGamalPublicKey, DHPublicKey 25 { 26 static final long serialVersionUID = 8712728417091216948L; 27 28 private BigInteger y; 29 private transient ElGamalParameterSpec elSpec; 30 BCElGamalPublicKey( ElGamalPublicKeySpec spec)31 BCElGamalPublicKey( 32 ElGamalPublicKeySpec spec) 33 { 34 this.y = spec.getY(); 35 this.elSpec = new ElGamalParameterSpec(spec.getParams().getP(), spec.getParams().getG()); 36 } 37 BCElGamalPublicKey( DHPublicKeySpec spec)38 BCElGamalPublicKey( 39 DHPublicKeySpec spec) 40 { 41 this.y = spec.getY(); 42 this.elSpec = new ElGamalParameterSpec(spec.getP(), spec.getG()); 43 } 44 BCElGamalPublicKey( ElGamalPublicKey key)45 BCElGamalPublicKey( 46 ElGamalPublicKey key) 47 { 48 this.y = key.getY(); 49 this.elSpec = key.getParameters(); 50 } 51 BCElGamalPublicKey( DHPublicKey key)52 BCElGamalPublicKey( 53 DHPublicKey key) 54 { 55 this.y = key.getY(); 56 this.elSpec = new ElGamalParameterSpec(key.getParams().getP(), key.getParams().getG()); 57 } 58 BCElGamalPublicKey( ElGamalPublicKeyParameters params)59 BCElGamalPublicKey( 60 ElGamalPublicKeyParameters params) 61 { 62 this.y = params.getY(); 63 this.elSpec = new ElGamalParameterSpec(params.getParameters().getP(), params.getParameters().getG()); 64 } 65 BCElGamalPublicKey( BigInteger y, ElGamalParameterSpec elSpec)66 BCElGamalPublicKey( 67 BigInteger y, 68 ElGamalParameterSpec elSpec) 69 { 70 this.y = y; 71 this.elSpec = elSpec; 72 } 73 BCElGamalPublicKey( SubjectPublicKeyInfo info)74 BCElGamalPublicKey( 75 SubjectPublicKeyInfo info) 76 { 77 ElGamalParameter params = ElGamalParameter.getInstance(info.getAlgorithm().getParameters()); 78 ASN1Integer derY = null; 79 80 try 81 { 82 derY = (ASN1Integer)info.parsePublicKey(); 83 } 84 catch (IOException e) 85 { 86 throw new IllegalArgumentException("invalid info structure in DSA public key"); 87 } 88 89 this.y = derY.getValue(); 90 this.elSpec = new ElGamalParameterSpec(params.getP(), params.getG()); 91 } 92 getAlgorithm()93 public String getAlgorithm() 94 { 95 return "ElGamal"; 96 } 97 getFormat()98 public String getFormat() 99 { 100 return "X.509"; 101 } 102 getEncoded()103 public byte[] getEncoded() 104 { 105 try 106 { 107 SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(OIWObjectIdentifiers.elGamalAlgorithm, new ElGamalParameter(elSpec.getP(), elSpec.getG())), new ASN1Integer(y)); 108 109 return info.getEncoded(ASN1Encoding.DER); 110 } 111 catch (IOException e) 112 { 113 return null; 114 } 115 } 116 getParameters()117 public ElGamalParameterSpec getParameters() 118 { 119 return elSpec; 120 } 121 getParams()122 public DHParameterSpec getParams() 123 { 124 return new DHParameterSpec(elSpec.getP(), elSpec.getG()); 125 } 126 getY()127 public BigInteger getY() 128 { 129 return y; 130 } 131 hashCode()132 public int hashCode() 133 { 134 return this.getY().hashCode() ^ this.getParams().getG().hashCode() 135 ^ this.getParams().getP().hashCode() ^ this.getParams().getL(); 136 } 137 equals( Object o)138 public boolean equals( 139 Object o) 140 { 141 if (!(o instanceof DHPublicKey)) 142 { 143 return false; 144 } 145 146 DHPublicKey other = (DHPublicKey)o; 147 148 return this.getY().equals(other.getY()) 149 && this.getParams().getG().equals(other.getParams().getG()) 150 && this.getParams().getP().equals(other.getParams().getP()) 151 && this.getParams().getL() == other.getParams().getL(); 152 } 153 readObject( ObjectInputStream in)154 private void readObject( 155 ObjectInputStream in) 156 throws IOException, ClassNotFoundException 157 { 158 in.defaultReadObject(); 159 160 this.elSpec = new ElGamalParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject()); 161 } 162 writeObject( ObjectOutputStream out)163 private void writeObject( 164 ObjectOutputStream out) 165 throws IOException 166 { 167 out.defaultWriteObject(); 168 169 out.writeObject(elSpec.getP()); 170 out.writeObject(elSpec.getG()); 171 } 172 } 173