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

package com.nimbusds.jose.crypto;

import com.nimbusds.jose.crypto.impl.ECDH;
import com.nimbusds.jose.crypto.impl.AAD;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jose.JWEHeader;
import java.util.Collections;
import com.nimbusds.jose.jwk.Curve;
import javax.crypto.SecretKey;
import com.nimbusds.jose.JOSEException;
import java.util.Set;
import com.nimbusds.jose.crypto.impl.CriticalHeaderParamsDeferral;
import com.nimbusds.jose.jwk.OctetKeyPair;
import com.nimbusds.jose.CriticalHeaderParamsAware;
import com.nimbusds.jose.JWEDecrypter;
import com.nimbusds.jose.crypto.impl.ECDHCryptoProvider;

public class X25519Decrypter extends ECDHCryptoProvider implements JWEDecrypter, CriticalHeaderParamsAware
{
    private final OctetKeyPair privateKey;
    private final CriticalHeaderParamsDeferral critPolicy;
    
    public X25519Decrypter(final OctetKeyPair privateKey) throws JOSEException {
        this(privateKey, null);
    }
    
    public X25519Decrypter(final OctetKeyPair privateKey, final Set<String> defCritHeaders) throws JOSEException {
        super(privateKey.getCurve(), null);
        this.critPolicy = new CriticalHeaderParamsDeferral();
        if (!Curve.X25519.equals(privateKey.getCurve())) {
            throw new JOSEException("X25519Decrypter only supports OctetKeyPairs with crv=X25519");
        }
        if (!privateKey.isPrivate()) {
            throw new JOSEException("The OctetKeyPair doesn't contain a private part");
        }
        this.privateKey = privateKey;
        this.critPolicy.setDeferredCriticalHeaderParams(defCritHeaders);
    }
    
    @Override
    public Set<Curve> supportedEllipticCurves() {
        return Collections.singleton(Curve.X25519);
    }
    
    public OctetKeyPair getPrivateKey() {
        return this.privateKey;
    }
    
    @Override
    public Set<String> getProcessedCriticalHeaderParams() {
        return this.critPolicy.getProcessedCriticalHeaderParams();
    }
    
    @Override
    public Set<String> getDeferredCriticalHeaderParams() {
        return this.critPolicy.getProcessedCriticalHeaderParams();
    }
    
    @Deprecated
    public byte[] decrypt(final JWEHeader header, final Base64URL encryptedKey, final Base64URL iv, final Base64URL cipherText, final Base64URL authTag) throws JOSEException {
        return this.decrypt(header, encryptedKey, iv, cipherText, authTag, AAD.compute(header));
    }
    
    @Override
    public byte[] decrypt(final JWEHeader header, final Base64URL encryptedKey, final Base64URL iv, final Base64URL cipherText, final Base64URL authTag, final byte[] aad) throws JOSEException {
        this.critPolicy.ensureHeaderPasses(header);
        final OctetKeyPair ephemeralPublicKey = (OctetKeyPair)header.getEphemeralPublicKey();
        if (ephemeralPublicKey == null) {
            throw new JOSEException("Missing ephemeral public key epk JWE header parameter");
        }
        if (!this.privateKey.getCurve().equals(ephemeralPublicKey.getCurve())) {
            throw new JOSEException("Curve of ephemeral public key does not match curve of private key");
        }
        final SecretKey Z = ECDH.deriveSharedSecret(ephemeralPublicKey, this.privateKey);
        return this.decryptWithZ(header, aad, Z, encryptedKey, iv, cipherText, authTag);
    }
}
