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

package org.bouncycastle.pqc.crypto.crystals.dilithium;

import org.bouncycastle.crypto.digests.SHAKEDigest;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.modes.SICBlockCipher;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.StreamCipher;

abstract class Symmetric
{
    final int stream128BlockBytes;
    final int stream256BlockBytes;
    
    Symmetric(final int stream128BlockBytes, final int stream256BlockBytes) {
        this.stream128BlockBytes = stream128BlockBytes;
        this.stream256BlockBytes = stream256BlockBytes;
    }
    
    abstract void stream128init(final byte[] p0, final short p1);
    
    abstract void stream256init(final byte[] p0, final short p1);
    
    abstract void stream128squeezeBlocks(final byte[] p0, final int p1, final int p2);
    
    abstract void stream256squeezeBlocks(final byte[] p0, final int p1, final int p2);
    
    @Deprecated
    static class AesSymmetric extends Symmetric
    {
        private final StreamCipher cipher;
        
        AesSymmetric() {
            super(64, 64);
            this.cipher = SICBlockCipher.newInstance(AESEngine.newInstance());
        }
        
        private void aes128(final byte[] array, final int n, final int n2) {
            this.cipher.processBytes(new byte[n2], 0, n2, array, n);
        }
        
        private void streamInit(final byte[] array, final short n) {
            final byte[] array2 = new byte[12];
            array2[0] = (byte)n;
            array2[1] = (byte)(n >> 8);
            this.cipher.init(true, new ParametersWithIV(new KeyParameter(array, 0, 32), array2));
        }
        
        @Override
        void stream128init(final byte[] array, final short n) {
            this.streamInit(array, n);
        }
        
        @Override
        void stream256init(final byte[] array, final short n) {
            this.streamInit(array, n);
        }
        
        @Override
        void stream128squeezeBlocks(final byte[] array, final int n, final int n2) {
            this.aes128(array, n, n2);
        }
        
        @Override
        void stream256squeezeBlocks(final byte[] array, final int n, final int n2) {
            this.aes128(array, n, n2);
        }
    }
    
    static class ShakeSymmetric extends Symmetric
    {
        private final SHAKEDigest digest128;
        private final SHAKEDigest digest256;
        
        ShakeSymmetric() {
            super(168, 136);
            this.digest128 = new SHAKEDigest(128);
            this.digest256 = new SHAKEDigest(256);
        }
        
        private void streamInit(final SHAKEDigest shakeDigest, final byte[] array, final short n) {
            shakeDigest.reset();
            final byte[] array2 = { (byte)n, (byte)(n >> 8) };
            shakeDigest.update(array, 0, array.length);
            shakeDigest.update(array2, 0, array2.length);
        }
        
        @Override
        void stream128init(final byte[] array, final short n) {
            this.streamInit(this.digest128, array, n);
        }
        
        @Override
        void stream256init(final byte[] array, final short n) {
            this.streamInit(this.digest256, array, n);
        }
        
        @Override
        void stream128squeezeBlocks(final byte[] array, final int n, final int n2) {
            this.digest128.doOutput(array, n, n2);
        }
        
        @Override
        void stream256squeezeBlocks(final byte[] array, final int n, final int n2) {
            this.digest256.doOutput(array, n, n2);
        }
    }
}
