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

package org.bouncycastle.pqc.crypto.frodo;

import org.bouncycastle.crypto.digests.SHAKEDigest;
import org.bouncycastle.util.Pack;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.engines.AESEngine;

abstract class FrodoMatrixGenerator
{
    int n;
    int q;
    
    public FrodoMatrixGenerator(final int n, final int q) {
        this.n = n;
        this.q = q;
    }
    
    abstract short[] genMatrix(final byte[] p0);
    
    static class Aes128MatrixGenerator extends FrodoMatrixGenerator
    {
        public Aes128MatrixGenerator(final int n, final int n2) {
            super(n, n2);
        }
        
        @Override
        short[] genMatrix(final byte[] array) {
            final short[] array2 = new short[this.n * this.n];
            final byte[] array3 = new byte[16];
            final byte[] array4 = new byte[16];
            final AESEngine aesEngine = new AESEngine();
            aesEngine.init(true, new KeyParameter(array));
            for (int i = 0; i < this.n; ++i) {
                Pack.shortToLittleEndian((short)i, array3, 0);
                for (int j = 0; j < this.n; j += 8) {
                    Pack.shortToLittleEndian((short)j, array3, 2);
                    aesEngine.processBlock(array3, 0, array4, 0);
                    for (int k = 0; k < 8; ++k) {
                        array2[i * this.n + j + k] = (short)(Pack.littleEndianToShort(array4, 2 * k) & this.q - 1);
                    }
                }
            }
            return array2;
        }
    }
    
    static class Shake128MatrixGenerator extends FrodoMatrixGenerator
    {
        public Shake128MatrixGenerator(final int n, final int n2) {
            super(n, n2);
        }
        
        @Override
        short[] genMatrix(final byte[] array) {
            final short[] array2 = new short[this.n * this.n];
            final byte[] array3 = new byte[16 * this.n / 8];
            final byte[] array4 = new byte[2 + array.length];
            System.arraycopy(array, 0, array4, 2, array.length);
            final SHAKEDigest shakeDigest = new SHAKEDigest(128);
            for (short n = 0; n < this.n; ++n) {
                Pack.shortToLittleEndian(n, array4, 0);
                shakeDigest.update(array4, 0, array4.length);
                shakeDigest.doFinal(array3, 0, array3.length);
                for (int i = 0; i < this.n; i = (short)(i + 1)) {
                    array2[n * this.n + i] = (short)(Pack.littleEndianToShort(array3, 2 * i) & this.q - 1);
                }
            }
            return array2;
        }
    }
}
