1 package org.bouncycastle.asn1.misc;
2 
3 import java.math.BigInteger;
4 
5 import org.bouncycastle.asn1.ASN1EncodableVector;
6 import org.bouncycastle.asn1.ASN1Integer;
7 import org.bouncycastle.asn1.ASN1Object;
8 import org.bouncycastle.asn1.ASN1OctetString;
9 import org.bouncycastle.asn1.ASN1Primitive;
10 import org.bouncycastle.asn1.ASN1Sequence;
11 import org.bouncycastle.asn1.DEROctetString;
12 import org.bouncycastle.asn1.DERSequence;
13 import org.bouncycastle.util.Arrays;
14 
15 /**
16  * RFC 7914 scrypt parameters.
17  *
18  * <pre>
19  * scrypt-params ::= SEQUENCE {
20  *      salt OCTET STRING,
21  *      costParameter INTEGER (1..MAX),
22  *      blockSize INTEGER (1..MAX),
23  *      parallelizationParameter INTEGER (1..MAX),
24  *      keyLength INTEGER (1..MAX) OPTIONAL
25  * }
26  * </pre>
27  */
28 public class ScryptParams
29     extends ASN1Object
30 {
31     private final byte[] salt;
32     private final BigInteger costParameter;
33     private final BigInteger blockSize;
34     private final BigInteger parallelizationParameter;
35     private final BigInteger keyLength;
36 
ScryptParams(byte[] salt, int costParameter, int blockSize, int parallelizationParameter)37     public ScryptParams(byte[] salt, int costParameter, int blockSize, int parallelizationParameter)
38     {
39         this(salt, BigInteger.valueOf(costParameter), BigInteger.valueOf(blockSize), BigInteger.valueOf(parallelizationParameter), null);
40     }
41 
ScryptParams(byte[] salt, int costParameter, int blockSize, int parallelizationParameter, int keyLength)42     public ScryptParams(byte[] salt, int costParameter, int blockSize, int parallelizationParameter, int keyLength)
43     {
44         this(salt, BigInteger.valueOf(costParameter), BigInteger.valueOf(blockSize), BigInteger.valueOf(parallelizationParameter), BigInteger.valueOf(keyLength));
45     }
46 
47     /**
48      * Base constructor.
49      *
50      * @param salt salt value
51      * @param costParameter specifies the CPU/Memory cost parameter N
52      * @param blockSize block size parameter r
53      * @param parallelizationParameter parallelization parameter
54      * @param keyLength length of key to be derived (in octects)
55      */
ScryptParams(byte[] salt, BigInteger costParameter, BigInteger blockSize, BigInteger parallelizationParameter, BigInteger keyLength)56     public ScryptParams(byte[] salt, BigInteger costParameter, BigInteger blockSize, BigInteger parallelizationParameter, BigInteger keyLength)
57     {
58         this.salt = Arrays.clone(salt);
59         this.costParameter = costParameter;
60         this.blockSize = blockSize;
61         this.parallelizationParameter = parallelizationParameter;
62         this.keyLength = keyLength;
63     }
64 
getInstance( Object o)65     public static ScryptParams getInstance(
66         Object  o)
67     {
68         if (o instanceof ScryptParams)
69         {
70             return (ScryptParams)o;
71         }
72         else if (o != null)
73         {
74             return new ScryptParams(ASN1Sequence.getInstance(o));
75         }
76 
77         return null;
78     }
79 
ScryptParams(ASN1Sequence seq)80     private ScryptParams(ASN1Sequence seq)
81     {
82         if (seq.size() != 4 && seq.size() != 5)
83         {
84             throw new IllegalArgumentException("invalid sequence: size = " + seq.size());
85         }
86 
87         this.salt = Arrays.clone(ASN1OctetString.getInstance(seq.getObjectAt(0)).getOctets());
88         this.costParameter = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
89         this.blockSize = ASN1Integer.getInstance(seq.getObjectAt(2)).getValue();
90         this.parallelizationParameter = ASN1Integer.getInstance(seq.getObjectAt(3)).getValue();
91 
92         if (seq.size() == 5)
93         {
94             this.keyLength = ASN1Integer.getInstance(seq.getObjectAt(4)).getValue();
95         }
96         else
97         {
98             this.keyLength = null;
99         }
100     }
101 
getSalt()102     public byte[] getSalt()
103     {
104         return Arrays.clone(salt);
105     }
106 
getCostParameter()107     public BigInteger getCostParameter()
108     {
109         return costParameter;
110     }
111 
getBlockSize()112     public BigInteger getBlockSize()
113     {
114         return blockSize;
115     }
116 
getParallelizationParameter()117     public BigInteger getParallelizationParameter()
118     {
119         return parallelizationParameter;
120     }
121 
122     /**
123      * Return the length in octets for the derived key.
124      *
125      * @return length for key to be derived (in octets)
126      */
getKeyLength()127     public BigInteger getKeyLength()
128     {
129         return keyLength;
130     }
131 
toASN1Primitive()132     public ASN1Primitive toASN1Primitive()
133     {
134         ASN1EncodableVector v = new ASN1EncodableVector(5);
135 
136         v.add(new DEROctetString(salt));
137         v.add(new ASN1Integer(costParameter));
138         v.add(new ASN1Integer(blockSize));
139         v.add(new ASN1Integer(parallelizationParameter));
140         if (keyLength != null)
141         {
142             v.add(new ASN1Integer(keyLength));
143         }
144 
145         return new DERSequence(v);
146     }
147 }
148