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