// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.jcajce.provider.kdf.scrypt;

import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.generators.SCrypt;
import org.bouncycastle.crypto.PasswordConverter;
import org.bouncycastle.jcajce.spec.ScryptKeySpec;
import org.bouncycastle.jcajce.spec.ScryptParameterSpec;
import java.security.NoSuchAlgorithmException;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.SecretKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import javax.crypto.KDFParameters;
import javax.crypto.KDFSpi;

class ScryptSpi extends KDFSpi
{
    protected ScryptSpi(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
        super(requireNull(kdfParameters, "Scrypt does not support parameters"));
    }
    
    protected KDFParameters engineGetParameters() {
        return null;
    }
    
    protected SecretKey engineDeriveKey(final String algorithm, final AlgorithmParameterSpec algorithmParameterSpec) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
        return new SecretKeySpec(this.engineDeriveData(algorithmParameterSpec), algorithm);
    }
    
    protected byte[] engineDeriveData(final AlgorithmParameterSpec algorithmParameterSpec) throws InvalidAlgorithmParameterException {
        if (!(algorithmParameterSpec instanceof ScryptParameterSpec)) {
            throw new InvalidAlgorithmParameterException("SCrypt requires an SCryptParameterSpec as derivation parameters");
        }
        final ScryptKeySpec scryptKeySpec = (ScryptKeySpec)algorithmParameterSpec;
        final char[] password = scryptKeySpec.getPassword();
        final byte[] salt = scryptKeySpec.getSalt();
        final int costParameter = scryptKeySpec.getCostParameter();
        final int blockSize = scryptKeySpec.getBlockSize();
        final int parallelizationParameter = scryptKeySpec.getParallelizationParameter();
        final int keyLength = scryptKeySpec.getKeyLength();
        if (salt == null) {
            throw new InvalidAlgorithmParameterException("Salt S must be provided.");
        }
        if (costParameter <= 1) {
            throw new InvalidAlgorithmParameterException("Cost parameter N must be > 1.");
        }
        if (keyLength <= 0) {
            throw new InvalidAlgorithmParameterException("positive key length required: " + keyLength);
        }
        final byte[] generate = SCrypt.generate(PasswordConverter.UTF8.convert(password), salt, costParameter, blockSize, parallelizationParameter, keyLength / 8);
        Arrays.clear(password);
        return generate;
    }
    
    private static KDFParameters requireNull(final KDFParameters kdfParameters, final String msg) throws InvalidAlgorithmParameterException {
        if (kdfParameters != null) {
            throw new InvalidAlgorithmParameterException(msg);
        }
        return null;
    }
    
    public static class ScryptWithUTF8 extends ScryptSpi
    {
        public ScryptWithUTF8(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters);
        }
    }
}
