Welcome to mirror list, hosted at ThFree Co, Russian Federation.

JPAKEPrimeOrderGroup.java « jpake « agreement « crypto « spongycastle « org « jdk1.1 « main « src « core - gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 59e93385ce4e8b14ad253306cf3097a04345b4ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package org.spongycastle.crypto.agreement.jpake;

import java.math.BigInteger;

/**
 * A pre-computed prime order group for use during a J-PAKE exchange.
 * <p/>
 * <p/>
 * Typically a Schnorr group is used.  In general, J-PAKE can use any prime order group
 * that is suitable for public key cryptography, including elliptic curve cryptography.
 * <p/>
 * <p/>
 * See {@link JPAKEPrimeOrderGroups} for convenient standard groups.
 * <p/>
 * <p/>
 * NIST <a href="http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/DSA2_All.pdf">publishes</a>
 * many groups that can be used for the desired level of security.
 */
public class JPAKEPrimeOrderGroup
{
    private BigInteger p;
    private BigInteger q;
    private BigInteger g;

    /**
     * Constructs a new {@link JPAKEPrimeOrderGroup}.
     * <p/>
     * <p/>
     * In general, you should use one of the pre-approved groups from
     * {@link JPAKEPrimeOrderGroups}, rather than manually constructing one.
     * <p/>
     * <p/>
     * The following basic checks are performed:
     * <ul>
     * <li>p-1 must be evenly divisible by q</li>
     * <li>g must be in [2, p-1]</li>
     * <li>g^q mod p must equal 1</li>
     * <li>p must be prime (within reasonably certainty)</li>
     * <li>q must be prime (within reasonably certainty)</li>
     * </ul>
     * <p/>
     * <p/>
     * The prime checks are performed using {@link BigInteger#isProbablePrime(int)},
     * and are therefore subject to the same probability guarantees.
     * <p/>
     * <p/>
     * These checks prevent trivial mistakes.
     * However, due to the small uncertainties if p and q are not prime,
     * advanced attacks are not prevented.
     * Use it at your own risk.
     *
     * @throws NullPointerException if any argument is null
     * @throws IllegalArgumentException if any of the above validations fail
     */
    public JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g)
    {
        /*
         * Don't skip the checks on user-specified groups.
         */
        this(p, q, g, false);
    }

    /**
     * Internal package-private constructor used by the pre-approved
     * groups in {@link JPAKEPrimeOrderGroups}.
     * These pre-approved groups can avoid the expensive checks.
     */
    JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, boolean skipChecks)
    {
        JPAKEUtil.validateNotNull(p, "p");
        JPAKEUtil.validateNotNull(q, "q");
        JPAKEUtil.validateNotNull(g, "g");

        if (!skipChecks)
        {
            if (!p.subtract(JPAKEUtil.ONE).mod(q).equals(JPAKEUtil.ZERO))
            {
                throw new IllegalArgumentException("p-1 must be evenly divisible by q");
            }
            if (g.compareTo(BigInteger.valueOf(2)) == -1 || g.compareTo(p.subtract(JPAKEUtil.ONE)) == 1)
            {
                throw new IllegalArgumentException("g must be in [2, p-1]");
            }
            if (!g.modPow(q, p).equals(JPAKEUtil.ONE))
            {
                throw new IllegalArgumentException("g^q mod p must equal 1");
            }
            /*
             * Note that these checks do not guarantee that p and q are prime.
             * We just have reasonable certainty that they are prime.
             */
            if (!p.isProbablePrime(20))
            {
                throw new IllegalArgumentException("p must be prime");
            }
            if (!q.isProbablePrime(20))
            {
                throw new IllegalArgumentException("q must be prime");
            }
        }

        this.p = p;
        this.q = q;
        this.g = g;
    }

    public BigInteger getP()
    {
        return p;
    }

    public BigInteger getQ()
    {
        return q;
    }

    public BigInteger getG()
    {
        return g;
    }

}