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

package org.bouncycastle.pqc.crypto.rainbow;

import java.security.SecureRandom;
import org.bouncycastle.util.Arrays;

class RainbowPublicMap
{
    private ComputeInField cf;
    private RainbowParameters params;
    private final int num_gf_elements = 256;
    
    public RainbowPublicMap(final RainbowParameters params) {
        this.cf = new ComputeInField();
        this.params = params;
    }
    
    private short[][] compute_accumulator(final short[] array, final short[] array2, final short[][][] array3, final int n) {
        final short[][] array4 = new short[256][n];
        if (array2.length != array3[0].length || array.length != array3[0][0].length || array3.length != n) {
            throw new RuntimeException("Accumulator calculation not possible!");
        }
        for (int i = 0; i < array2.length; ++i) {
            final short[] multVect = this.cf.multVect(array2[i], array);
            for (int j = 0; j < array.length; ++j) {
                for (int k = 0; k < array3.length; ++k) {
                    final short n2 = multVect[j];
                    if (n2 != 0) {
                        array4[n2][k] = GF2Field.addElem(array4[n2][k], array3[k][i][j]);
                    }
                }
            }
        }
        return array4;
    }
    
    private short[] add_and_reduce(final short[][] array) {
        final int m = this.params.getM();
        short[] addVect = new short[m];
        for (int i = 0; i < 8; ++i) {
            final int n = (int)Math.pow(2.0, i);
            short[] addVect2 = new short[m];
            for (int j = n; j < 256; j += n * 2) {
                for (int k = 0; k < n; ++k) {
                    addVect2 = this.cf.addVect(addVect2, array[j + k]);
                }
            }
            addVect = this.cf.addVect(addVect, this.cf.multVect((short)n, addVect2));
        }
        return addVect;
    }
    
    public short[] publicMap(final RainbowPublicKeyParameters rainbowPublicKeyParameters, final short[] array) {
        return this.add_and_reduce(this.compute_accumulator(array, array, rainbowPublicKeyParameters.pk, this.params.getM()));
    }
    
    public short[] publicMap_cyclic(final RainbowPublicKeyParameters rainbowPublicKeyParameters, final short[] array) {
        final int v1 = this.params.getV1();
        final int o1 = this.params.getO1();
        final int o2 = this.params.getO2();
        final short[][] array2 = new short[256][o1 + o2];
        final short[] copyOfRange = Arrays.copyOfRange(array, 0, v1);
        final short[] copyOfRange2 = Arrays.copyOfRange(array, v1, v1 + o1);
        final short[] copyOfRange3 = Arrays.copyOfRange(array, v1 + o1, array.length);
        final RainbowDRBG rainbowDRBG = new RainbowDRBG(rainbowPublicKeyParameters.pk_seed, rainbowPublicKeyParameters.getParameters().getHash_algo());
        final short[][] addMatrix = this.cf.addMatrix(this.cf.addMatrix(this.cf.addMatrix(this.cf.addMatrix(this.cf.addMatrix(this.compute_accumulator(copyOfRange, copyOfRange, RainbowUtil.generate_random(rainbowDRBG, o1, v1, v1, true), o1), this.compute_accumulator(copyOfRange2, copyOfRange, RainbowUtil.generate_random(rainbowDRBG, o1, v1, o1, false), o1)), this.compute_accumulator(copyOfRange3, copyOfRange, rainbowPublicKeyParameters.l1_Q3, o1)), this.compute_accumulator(copyOfRange2, copyOfRange2, rainbowPublicKeyParameters.l1_Q5, o1)), this.compute_accumulator(copyOfRange3, copyOfRange2, rainbowPublicKeyParameters.l1_Q6, o1)), this.compute_accumulator(copyOfRange3, copyOfRange3, rainbowPublicKeyParameters.l1_Q9, o1));
        final short[][] addMatrix2 = this.cf.addMatrix(this.cf.addMatrix(this.cf.addMatrix(this.cf.addMatrix(this.cf.addMatrix(this.compute_accumulator(copyOfRange, copyOfRange, RainbowUtil.generate_random(rainbowDRBG, o2, v1, v1, true), o2), this.compute_accumulator(copyOfRange2, copyOfRange, RainbowUtil.generate_random(rainbowDRBG, o2, v1, o1, false), o2)), this.compute_accumulator(copyOfRange3, copyOfRange, RainbowUtil.generate_random(rainbowDRBG, o2, v1, o2, false), o2)), this.compute_accumulator(copyOfRange2, copyOfRange2, RainbowUtil.generate_random(rainbowDRBG, o2, o1, o1, true), o2)), this.compute_accumulator(copyOfRange3, copyOfRange2, RainbowUtil.generate_random(rainbowDRBG, o2, o1, o2, false), o2)), this.compute_accumulator(copyOfRange3, copyOfRange3, rainbowPublicKeyParameters.l2_Q9, o2));
        for (int i = 0; i < 256; ++i) {
            array2[i] = Arrays.concatenate(addMatrix[i], addMatrix2[i]);
        }
        return this.add_and_reduce(array2);
    }
}
