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

package org.bouncycastle.pqc.crypto.xwing;

import org.bouncycastle.util.Strings;
import org.bouncycastle.crypto.digests.SHA3Digest;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.agreement.X25519Agreement;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters;
import org.bouncycastle.pqc.crypto.util.SecretWithEncapsulationImpl;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.params.X25519KeyGenerationParameters;
import org.bouncycastle.crypto.generators.X25519KeyPairGenerator;
import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator;
import org.bouncycastle.crypto.SecretWithEncapsulation;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import java.security.SecureRandom;
import org.bouncycastle.crypto.EncapsulatedSecretGenerator;

public class XWingKEMGenerator implements EncapsulatedSecretGenerator
{
    private final SecureRandom random;
    private static final byte[] XWING_LABEL;
    
    public XWingKEMGenerator(final SecureRandom random) {
        this.random = random;
    }
    
    @Override
    public SecretWithEncapsulation generateEncapsulated(final AsymmetricKeyParameter asymmetricKeyParameter) {
        final XWingPublicKeyParameters xWingPublicKeyParameters = (XWingPublicKeyParameters)asymmetricKeyParameter;
        final MLKEMPublicKeyParameters kyberPublicKey = xWingPublicKeyParameters.getKyberPublicKey();
        final X25519PublicKeyParameters xdhPublicKey = xWingPublicKeyParameters.getXDHPublicKey();
        final byte[] encoded = xdhPublicKey.getEncoded();
        final SecretWithEncapsulation generateEncapsulated = new MLKEMGenerator(this.random).generateEncapsulated(kyberPublicKey);
        final byte[] encapsulation = generateEncapsulated.getEncapsulation();
        final X25519KeyPairGenerator x25519KeyPairGenerator = new X25519KeyPairGenerator();
        x25519KeyPairGenerator.init(new X25519KeyGenerationParameters(this.random));
        final AsymmetricCipherKeyPair generateKeyPair = x25519KeyPairGenerator.generateKeyPair();
        final byte[] encoded2 = ((X25519PublicKeyParameters)generateKeyPair.getPublic()).getEncoded();
        final byte[] computeSSX = computeSSX(xdhPublicKey, (X25519PrivateKeyParameters)generateKeyPair.getPrivate());
        final byte[] computeSharedSecret = computeSharedSecret(encoded, generateEncapsulated.getSecret(), encoded2, computeSSX);
        Arrays.clear(computeSSX);
        return new SecretWithEncapsulationImpl(computeSharedSecret, Arrays.concatenate(encapsulation, encoded2));
    }
    
    static byte[] computeSSX(final X25519PublicKeyParameters x25519PublicKeyParameters, final X25519PrivateKeyParameters x25519PrivateKeyParameters) {
        final X25519Agreement x25519Agreement = new X25519Agreement();
        x25519Agreement.init(x25519PrivateKeyParameters);
        final byte[] array = new byte[x25519Agreement.getAgreementSize()];
        x25519Agreement.calculateAgreement(x25519PublicKeyParameters, array, 0);
        return array;
    }
    
    static byte[] computeSharedSecret(final byte[] array, final byte[] array2, final byte[] array3, final byte[] array4) {
        final SHA3Digest sha3Digest = new SHA3Digest(256);
        sha3Digest.update(array2, 0, array2.length);
        sha3Digest.update(array4, 0, array4.length);
        sha3Digest.update(array3, 0, array3.length);
        sha3Digest.update(array, 0, array.length);
        sha3Digest.update(XWingKEMGenerator.XWING_LABEL, 0, XWingKEMGenerator.XWING_LABEL.length);
        final byte[] array5 = new byte[32];
        sha3Digest.doFinal(array5, 0);
        return array5;
    }
    
    static {
        XWING_LABEL = Strings.toByteArray("\\.//^\\");
    }
}
