Home | History | Annotate | Download | only in x9
      1 package org.bouncycastle.asn1.x9;
      2 
      3 import java.math.BigInteger;
      4 import java.util.Enumeration;
      5 
      6 import org.bouncycastle.asn1.ASN1Encodable;
      7 import org.bouncycastle.asn1.ASN1EncodableVector;
      8 import org.bouncycastle.asn1.ASN1Integer;
      9 import org.bouncycastle.asn1.ASN1Object;
     10 import org.bouncycastle.asn1.ASN1Primitive;
     11 import org.bouncycastle.asn1.ASN1Sequence;
     12 import org.bouncycastle.asn1.ASN1TaggedObject;
     13 import org.bouncycastle.asn1.DERSequence;
     14 
     15 /**
     16  * X9.44 Diffie-Hellman domain parameters.
     17  * <pre>
     18  *    DomainParameters ::= SEQUENCE {
     19  *       p                INTEGER,           -- odd prime, p=jq +1
     20  *       g                INTEGER,           -- generator, g
     21  *       q                INTEGER,           -- factor of p-1
     22  *       j                INTEGER OPTIONAL,  -- subgroup factor, j>= 2
     23  *       validationParams  ValidationParams OPTIONAL
     24  *    }
     25  * </pre>
     26  */
     27 public class DomainParameters
     28     extends ASN1Object
     29 {
     30     private final ASN1Integer p, g, q, j;
     31     private final ValidationParams validationParams;
     32 
     33     /**
     34      * Return a DomainParameters object from the passed in tagged object.
     35      *
     36      * @param obj a tagged object.
     37      * @param explicit true if the contents of the object is explictly tagged, false otherwise.
     38      * @return a DomainParameters
     39      */
     40     public static DomainParameters getInstance(ASN1TaggedObject obj, boolean explicit)
     41     {
     42         return getInstance(ASN1Sequence.getInstance(obj, explicit));
     43     }
     44 
     45     /**
     46      * Return a DomainParameters object from the passed in object.
     47      *
     48      * @param obj an object for conversion or a byte[].
     49      * @return a DomainParameters
     50      */
     51     public static DomainParameters getInstance(Object obj)
     52     {
     53         if (obj instanceof DomainParameters)
     54         {
     55             return (DomainParameters)obj;
     56         }
     57         else if (obj != null)
     58         {
     59             return new DomainParameters(ASN1Sequence.getInstance(obj));
     60         }
     61 
     62         return null;
     63     }
     64 
     65     /**
     66      * Base constructor - the full domain parameter set.
     67      *
     68      * @param p the prime p defining the Galois field.
     69      * @param g the generator of the multiplicative subgroup of order g.
     70      * @param q specifies the prime factor of p - 1
     71      * @param j optionally specifies the value that satisfies the equation p = jq+1
     72      * @param validationParams parameters for validating these domain parameters.
     73      */
     74     public DomainParameters(BigInteger p, BigInteger g, BigInteger q, BigInteger j,
     75                             ValidationParams validationParams)
     76     {
     77         if (p == null)
     78         {
     79             throw new IllegalArgumentException("'p' cannot be null");
     80         }
     81         if (g == null)
     82         {
     83             throw new IllegalArgumentException("'g' cannot be null");
     84         }
     85         if (q == null)
     86         {
     87             throw new IllegalArgumentException("'q' cannot be null");
     88         }
     89 
     90         this.p = new ASN1Integer(p);
     91         this.g = new ASN1Integer(g);
     92         this.q = new ASN1Integer(q);
     93 
     94         if (j != null)
     95         {
     96             this.j = new ASN1Integer(j);
     97         }
     98         else
     99         {
    100             this.j = null;
    101         }
    102         this.validationParams = validationParams;
    103     }
    104 
    105     private DomainParameters(ASN1Sequence seq)
    106     {
    107         if (seq.size() < 3 || seq.size() > 5)
    108         {
    109             throw new IllegalArgumentException("Bad sequence size: " + seq.size());
    110         }
    111 
    112         Enumeration e = seq.getObjects();
    113         this.p = ASN1Integer.getInstance(e.nextElement());
    114         this.g = ASN1Integer.getInstance(e.nextElement());
    115         this.q = ASN1Integer.getInstance(e.nextElement());
    116 
    117         ASN1Encodable next = getNext(e);
    118 
    119         if (next != null && next instanceof ASN1Integer)
    120         {
    121             this.j = ASN1Integer.getInstance(next);
    122             next = getNext(e);
    123         }
    124         else
    125         {
    126             this.j = null;
    127         }
    128 
    129         if (next != null)
    130         {
    131             this.validationParams = ValidationParams.getInstance(next.toASN1Primitive());
    132         }
    133         else
    134         {
    135             this.validationParams = null;
    136         }
    137     }
    138 
    139     private static ASN1Encodable getNext(Enumeration e)
    140     {
    141         return e.hasMoreElements() ? (ASN1Encodable)e.nextElement() : null;
    142     }
    143 
    144     /**
    145      * Return the prime p defining the Galois field.
    146      *
    147      * @return the prime p.
    148      */
    149     public BigInteger getP()
    150     {
    151         return this.p.getPositiveValue();
    152     }
    153 
    154     /**
    155      * Return the generator of the multiplicative subgroup of order g.
    156      *
    157      * @return the generator g.
    158      */
    159     public BigInteger getG()
    160     {
    161         return this.g.getPositiveValue();
    162     }
    163 
    164     /**
    165      * Return q, the prime factor of p - 1
    166      *
    167      * @return q value
    168      */
    169     public BigInteger getQ()
    170     {
    171         return this.q.getPositiveValue();
    172     }
    173 
    174     /**
    175      * Return the value that satisfies the equation p = jq+1 (if present).
    176      *
    177      * @return j value or null.
    178      */
    179     public BigInteger getJ()
    180     {
    181         if (this.j == null)
    182         {
    183             return null;
    184         }
    185 
    186         return this.j.getPositiveValue();
    187     }
    188 
    189     /**
    190      * Return the validation parameters for this set (if present).
    191      *
    192      * @return validation parameters, or null if absent.
    193      */
    194     public ValidationParams getValidationParams()
    195     {
    196         return this.validationParams;
    197     }
    198 
    199     /**
    200      * Return an ASN.1 primitive representation of this object.
    201      *
    202      * @return a DERSequence containing the parameter values.
    203      */
    204     public ASN1Primitive toASN1Primitive()
    205     {
    206         ASN1EncodableVector v = new ASN1EncodableVector();
    207         v.add(this.p);
    208         v.add(this.g);
    209         v.add(this.q);
    210 
    211         if (this.j != null)
    212         {
    213             v.add(this.j);
    214         }
    215 
    216         if (this.validationParams != null)
    217         {
    218             v.add(this.validationParams);
    219         }
    220 
    221         return new DERSequence(v);
    222     }
    223 }