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

package org.bouncycastle.pqc.crypto.rainbow;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.Digest;
import java.security.SecureRandom;

class RainbowDRBG extends SecureRandom
{
    private byte[] seed;
    private byte[] key;
    private byte[] v;
    private Digest hashAlgo;
    
    public RainbowDRBG(final byte[] seed, final Digest hashAlgo) {
        this.seed = seed;
        this.hashAlgo = hashAlgo;
        this.init(256);
    }
    
    private void init(final int n) {
        if (this.seed.length >= 48) {
            this.randombytes_init(this.seed, n);
        }
        else {
            this.randombytes_init(Arrays.concatenate(this.seed, RainbowUtil.hash(this.hashAlgo, this.seed, 48 - this.seed.length)), n);
        }
    }
    
    @Override
    public void nextBytes(final byte[] array) {
        final byte[] array2 = new byte[16];
        int n = 0;
        int i = array.length;
        while (i > 0) {
            for (int j = 15; j >= 0; --j) {
                if ((this.v[j] & 0xFF) != 0xFF) {
                    final byte[] v = this.v;
                    final int n2 = j;
                    ++v[n2];
                    break;
                }
                this.v[j] = 0;
            }
            this.AES256_ECB(this.key, this.v, array2, 0);
            if (i > 15) {
                System.arraycopy(array2, 0, array, n, array2.length);
                n += 16;
                i -= 16;
            }
            else {
                System.arraycopy(array2, 0, array, n, i);
                i = 0;
            }
        }
        this.AES256_CTR_DRBG_Update(null, this.key, this.v);
    }
    
    private void AES256_ECB(final byte[] array, final byte[] array2, final byte[] array3, final int n) {
        try {
            final AESEngine aesEngine = new AESEngine();
            aesEngine.init(true, new KeyParameter(array));
            for (int i = 0; i != array2.length; i += 16) {
                aesEngine.processBlock(array2, i, array3, n + i);
            }
        }
        catch (final Throwable cause) {
            throw new IllegalStateException("drbg failure: " + cause.getMessage(), cause);
        }
    }
    
    private void AES256_CTR_DRBG_Update(final byte[] array, final byte[] array2, final byte[] array3) {
        final byte[] array4 = new byte[48];
        for (int i = 0; i < 3; ++i) {
            for (int j = 15; j >= 0; --j) {
                if ((array3[j] & 0xFF) != 0xFF) {
                    final int n = j;
                    ++array3[n];
                    break;
                }
                array3[j] = 0;
            }
            this.AES256_ECB(array2, array3, array4, 16 * i);
        }
        if (array != null) {
            for (int k = 0; k < 48; ++k) {
                final byte[] array5 = array4;
                final int n2 = k;
                array5[n2] ^= array[k];
            }
        }
        System.arraycopy(array4, 0, array2, 0, array2.length);
        System.arraycopy(array4, 32, array3, 0, array3.length);
    }
    
    private void randombytes_init(final byte[] array, final int n) {
        final byte[] array2 = new byte[48];
        System.arraycopy(array, 0, array2, 0, array2.length);
        this.key = new byte[32];
        this.v = new byte[16];
        this.AES256_CTR_DRBG_Update(array2, this.key, this.v);
    }
}
