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

package org.bouncycastle.pqc.crypto.ntru;

import org.bouncycastle.pqc.math.ntru.parameters.NTRUParameterSet;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.digests.SHA3Digest;
import org.bouncycastle.crypto.EncapsulatedSecretExtractor;

public class NTRUKEMExtractor implements EncapsulatedSecretExtractor
{
    private final NTRUPrivateKeyParameters ntruPrivateKey;
    
    public NTRUKEMExtractor(final NTRUPrivateKeyParameters ntruPrivateKey) {
        if (ntruPrivateKey == null) {
            throw new NullPointerException("'ntruPrivateKey' cannot be null");
        }
        this.ntruPrivateKey = ntruPrivateKey;
    }
    
    @Override
    public byte[] extractSecret(final byte[] array) {
        final NTRUParameterSet parameterSet = this.ntruPrivateKey.getParameters().getParameterSet();
        if (array == null) {
            throw new NullPointerException("'encapsulation' cannot be null");
        }
        if (array.length != parameterSet.ntruCiphertextBytes()) {
            throw new IllegalArgumentException("encapsulation");
        }
        final byte[] privateKey = this.ntruPrivateKey.privateKey;
        final OWCPADecryptResult decrypt = new NTRUOWCPA(parameterSet).decrypt(array, privateKey);
        final byte[] rm = decrypt.rm;
        final int fail = decrypt.fail;
        final SHA3Digest sha3Digest = new SHA3Digest(256);
        final byte[] array2 = new byte[sha3Digest.getDigestSize()];
        sha3Digest.update(rm, 0, rm.length);
        sha3Digest.doFinal(array2, 0);
        sha3Digest.update(privateKey, parameterSet.owcpaSecretKeyBytes(), parameterSet.prfKeyBytes());
        sha3Digest.update(array, 0, array.length);
        sha3Digest.doFinal(rm, 0);
        this.cmov(array2, rm, (byte)fail);
        final byte[] copyOfRange = Arrays.copyOfRange(array2, 0, parameterSet.sharedKeyBytes());
        Arrays.clear(array2);
        return copyOfRange;
    }
    
    private void cmov(final byte[] array, final byte[] array2, final byte b) {
        final byte b2 = (byte)(~b + 1);
        for (int i = 0; i < array.length; ++i) {
            final int n = i;
            array[n] ^= (byte)(b2 & (array2[i] ^ array[i]));
        }
    }
    
    @Override
    public int getEncapsulationLength() {
        return this.ntruPrivateKey.getParameters().getParameterSet().ntruCiphertextBytes();
    }
}
