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.DHParameters;
8import org.bouncycastle.crypto.params.DHPublicKeyParameters;
9import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
10import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
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 DHPrivateKeyParameters  key;
24    private DHParameters            dhParams;
25
26    public void init(
27        CipherParameters    param)
28    {
29        AsymmetricKeyParameter  kParam;
30
31        if (param instanceof ParametersWithRandom)
32        {
33            ParametersWithRandom rParam = (ParametersWithRandom)param;
34            kParam = (AsymmetricKeyParameter)rParam.getParameters();
35        }
36        else
37        {
38            kParam = (AsymmetricKeyParameter)param;
39        }
40
41        if (!(kParam instanceof DHPrivateKeyParameters))
42        {
43            throw new IllegalArgumentException("DHEngine expects DHPrivateKeyParameters");
44        }
45
46        this.key = (DHPrivateKeyParameters)kParam;
47        this.dhParams = key.getParameters();
48    }
49
50    /**
51     * given a short term public key from a given party calculate the next
52     * message in the agreement sequence.
53     */
54    public BigInteger calculateAgreement(
55        CipherParameters   pubKey)
56    {
57        DHPublicKeyParameters   pub = (DHPublicKeyParameters)pubKey;
58
59        if (!pub.getParameters().equals(dhParams))
60        {
61            throw new IllegalArgumentException("Diffie-Hellman public key has wrong parameters.");
62        }
63
64        return pub.getY().modPow(key.getX(), dhParams.getP());
65    }
66}
67