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

package org.bouncycastle.pqc.crypto.ntruprime;

import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.EncapsulatedSecretExtractor;

public class NTRULPRimeKEMExtractor implements EncapsulatedSecretExtractor
{
    private final NTRULPRimePrivateKeyParameters privateKey;
    
    public NTRULPRimeKEMExtractor(final NTRULPRimePrivateKeyParameters privateKey) {
        this.privateKey = privateKey;
    }
    
    @Override
    public byte[] extractSecret(final byte[] array) {
        final NTRULPRimeParameters parameters = this.privateKey.getParameters();
        final int p = parameters.getP();
        final int q = parameters.getQ();
        final int w = parameters.getW();
        final int roundedPolynomialBytes = parameters.getRoundedPolynomialBytes();
        final int tau0 = parameters.getTau0();
        final int tau2 = parameters.getTau1();
        final int tau3 = parameters.getTau2();
        final int tau4 = parameters.getTau3();
        final byte[] array2 = new byte[p];
        Utils.getDecodedSmallPolynomial(array2, this.privateKey.getEncoded(), p);
        final byte[] array3 = new byte[roundedPolynomialBytes];
        System.arraycopy(array, 0, array3, 0, roundedPolynomialBytes);
        final short[] array4 = new short[p];
        Utils.getRoundedDecodedPolynomial(array4, array3, p, q);
        final byte[] array5 = new byte[128];
        System.arraycopy(array, roundedPolynomialBytes, array5, 0, array5.length);
        final byte[] array6 = new byte[256];
        Utils.getTopDecodedPolynomial(array6, array5);
        final short[] array7 = new short[p];
        Utils.multiplicationInRQ(array7, array4, array2, p, q);
        final byte[] array8 = new byte[256];
        Utils.right(array8, array7, array6, q, w, tau3, tau4);
        final byte[] array9 = new byte[32];
        Utils.getEncodedInputs(array9, array8);
        final byte[] array10 = new byte[parameters.getPublicKeyBytes() - 32];
        System.arraycopy(this.privateKey.getPk(), 32, array10, 0, array10.length);
        final short[] array11 = new short[p];
        Utils.getRoundedDecodedPolynomial(array11, array10, p, q);
        final byte[] array12 = new byte[32];
        System.arraycopy(this.privateKey.getPk(), 0, array12, 0, array12.length);
        final short[] array13 = new short[p];
        Utils.generatePolynomialInRQFromSeed(array13, array12, p, q);
        final byte[] hashWithPrefix = Utils.getHashWithPrefix(new byte[] { 5 }, array9);
        final byte[] copyOfRange = Arrays.copyOfRange(hashWithPrefix, 0, hashWithPrefix.length / 2);
        final int[] array14 = new int[p];
        Utils.expand(array14, copyOfRange);
        final byte[] array15 = new byte[p];
        Utils.sortGenerateShortPolynomial(array15, array14, p, w);
        final short[] array16 = new short[p];
        Utils.multiplicationInRQ(array16, array13, array15, p, q);
        final short[] array17 = new short[p];
        Utils.roundPolynomial(array17, array16);
        Utils.getRoundedEncodedPolynomial(new byte[roundedPolynomialBytes], array17, p, q);
        final short[] array18 = new short[p];
        Utils.multiplicationInRQ(array18, array11, array15, p, q);
        Utils.top(new byte[256], array18, array8, q, tau0, tau2);
        Utils.getTopEncodedPolynomial(new byte[128], array6);
        final byte[] array19 = new byte[array9.length + this.privateKey.getHash().length];
        System.arraycopy(array9, 0, array19, 0, array9.length);
        System.arraycopy(this.privateKey.getHash(), 0, array19, array9.length, this.privateKey.getHash().length);
        final byte[] hashWithPrefix2 = Utils.getHashWithPrefix(new byte[] { 2 }, array19);
        final byte[] array20 = new byte[array3.length + array5.length + hashWithPrefix2.length / 2];
        System.arraycopy(array3, 0, array20, 0, array3.length);
        System.arraycopy(array5, 0, array20, array3.length, array5.length);
        System.arraycopy(hashWithPrefix2, 0, array20, array3.length + array5.length, hashWithPrefix2.length / 2);
        Utils.updateDiffMask(array9, this.privateKey.getRho(), Arrays.areEqual(array, array20) ? 0 : -1);
        final byte[] array21 = new byte[array9.length + array20.length];
        System.arraycopy(array9, 0, array21, 0, array9.length);
        System.arraycopy(array20, 0, array21, array9.length, array20.length);
        return Arrays.copyOfRange(Utils.getHashWithPrefix(new byte[] { 1 }, array21), 0, parameters.getSessionKeySize() / 8);
    }
    
    @Override
    public int getEncapsulationLength() {
        return this.privateKey.getParameters().getRoundedPolynomialBytes() + 128 + 32;
    }
}
