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 }