1package org.bouncycastle.crypto.agreement; 2 3import java.math.BigInteger; 4 5import org.bouncycastle.crypto.BasicAgreement; 6import org.bouncycastle.crypto.CipherParameters; 7import org.bouncycastle.crypto.params.AsymmetricKeyParameter; 8import org.bouncycastle.crypto.params.DHParameters; 9import org.bouncycastle.crypto.params.DHPrivateKeyParameters; 10import org.bouncycastle.crypto.params.DHPublicKeyParameters; 11import org.bouncycastle.crypto.params.ParametersWithRandom; 12 13/** 14 * a Diffie-Hellman key agreement class. 15 * <p> 16 * note: This is only the basic algorithm, it doesn't take advantage of 17 * long term public keys if they are available. See the DHAgreement class 18 * for a "better" implementation. 19 */ 20public class DHBasicAgreement 21 implements BasicAgreement 22{ 23 private static final BigInteger ONE = BigInteger.valueOf(1); 24 25 private DHPrivateKeyParameters key; 26 private DHParameters dhParams; 27 28 public void init( 29 CipherParameters param) 30 { 31 AsymmetricKeyParameter kParam; 32 33 if (param instanceof ParametersWithRandom) 34 { 35 ParametersWithRandom rParam = (ParametersWithRandom)param; 36 kParam = (AsymmetricKeyParameter)rParam.getParameters(); 37 } 38 else 39 { 40 kParam = (AsymmetricKeyParameter)param; 41 } 42 43 if (!(kParam instanceof DHPrivateKeyParameters)) 44 { 45 throw new IllegalArgumentException("DHEngine expects DHPrivateKeyParameters"); 46 } 47 48 this.key = (DHPrivateKeyParameters)kParam; 49 this.dhParams = key.getParameters(); 50 } 51 52 public int getFieldSize() 53 { 54 return (key.getParameters().getP().bitLength() + 7) / 8; 55 } 56 57 /** 58 * given a short term public key from a given party calculate the next 59 * message in the agreement sequence. 60 */ 61 public BigInteger calculateAgreement( 62 CipherParameters pubKey) 63 { 64 DHPublicKeyParameters pub = (DHPublicKeyParameters)pubKey; 65 66 if (!pub.getParameters().equals(dhParams)) 67 { 68 throw new IllegalArgumentException("Diffie-Hellman public key has wrong parameters."); 69 } 70 71 BigInteger result = pub.getY().modPow(key.getX(), dhParams.getP()); 72 if (result.compareTo(ONE) == 0) 73 { 74 throw new IllegalStateException("Shared key can't be 1"); 75 } 76 77 return result; 78 } 79} 80