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

package com.nimbusds.jose.crypto;

import java.util.Arrays;
import com.nimbusds.jose.crypto.impl.ECDH;
import com.nimbusds.jose.jwk.JWK;
import com.nimbusds.jose.util.Base64URL;
import java.security.InvalidKeyException;
import com.google.crypto.tink.subtle.X25519;
import com.nimbusds.jose.crypto.impl.AAD;
import com.nimbusds.jose.JWECryptoParts;
import com.nimbusds.jose.JWEHeader;
import java.util.Collections;
import java.util.Set;
import com.nimbusds.jose.jwk.Curve;
import com.nimbusds.jose.JOSEException;
import javax.crypto.SecretKey;
import com.nimbusds.jose.jwk.OctetKeyPair;
import com.nimbusds.jose.shaded.jcip.ThreadSafe;
import com.nimbusds.jose.JWEEncrypter;
import com.nimbusds.jose.crypto.impl.ECDHCryptoProvider;

@ThreadSafe
public class X25519Encrypter extends ECDHCryptoProvider implements JWEEncrypter
{
    private final OctetKeyPair publicKey;
    
    public X25519Encrypter(final OctetKeyPair publicKey) throws JOSEException {
        this(publicKey, null);
    }
    
    public X25519Encrypter(final OctetKeyPair publicKey, final SecretKey contentEncryptionKey) throws JOSEException {
        super(publicKey.getCurve(), contentEncryptionKey);
        if (!Curve.X25519.equals(publicKey.getCurve())) {
            throw new JOSEException("X25519Encrypter only supports OctetKeyPairs with crv=X25519");
        }
        if (publicKey.isPrivate()) {
            throw new JOSEException("X25519Encrypter requires a public key, use OctetKeyPair.toPublicJWK()");
        }
        this.publicKey = publicKey;
    }
    
    @Override
    public Set<Curve> supportedEllipticCurves() {
        return Collections.singleton(Curve.X25519);
    }
    
    public OctetKeyPair getPublicKey() {
        return this.publicKey;
    }
    
    @Deprecated
    public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText) throws JOSEException {
        return this.encrypt(header, clearText, AAD.compute(header));
    }
    
    @Override
    public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText, final byte[] aad) throws JOSEException {
        final byte[] ephemeralPrivateKeyBytes = X25519.generatePrivateKey();
        byte[] ephemeralPublicKeyBytes;
        try {
            ephemeralPublicKeyBytes = X25519.publicFromPrivate(ephemeralPrivateKeyBytes);
        }
        catch (final InvalidKeyException e) {
            throw new JOSEException(e.getMessage(), e);
        }
        final OctetKeyPair ephemeralPrivateKey = new OctetKeyPair.Builder(this.getCurve(), Base64URL.encode(ephemeralPublicKeyBytes)).d(Base64URL.encode(ephemeralPrivateKeyBytes)).build();
        final OctetKeyPair ephemeralPublicKey = ephemeralPrivateKey.toPublicJWK();
        final JWEHeader updatedHeader = new JWEHeader.Builder(header).ephemeralPublicKey(ephemeralPublicKey).build();
        final SecretKey Z = ECDH.deriveSharedSecret(this.publicKey, ephemeralPrivateKey);
        final byte[] updatedAAD = Arrays.equals(AAD.compute(header), aad) ? AAD.compute(updatedHeader) : aad;
        return this.encryptWithZ(updatedHeader, Z, clearText, updatedAAD);
    }
}
