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

package com.google.crypto.tink.aead.subtle;

import javax.annotation.Nullable;
import com.google.crypto.tink.subtle.EngineFactory;
import com.google.crypto.tink.aead.AesGcmSivParameters;
import com.google.crypto.tink.util.SecretBytes;
import com.google.crypto.tink.InsecureSecretKeyAccess;
import com.google.crypto.tink.AccessesPartialKey;
import com.google.crypto.tink.aead.AesGcmSivKey;
import java.security.GeneralSecurityException;
import javax.crypto.Cipher;
import com.google.crypto.tink.annotations.Alpha;
import com.google.crypto.tink.Aead;

@Alpha
public final class AesGcmSiv implements Aead
{
    private static final ThreadLocal<Cipher> localAesGcmSivCipher;
    private final Aead aead;
    
    private static Cipher cipherSupplier() throws GeneralSecurityException {
        try {
            final Cipher cipher = AesGcmSiv.localAesGcmSivCipher.get();
            if (cipher == null) {
                throw new GeneralSecurityException("AES GCM SIV cipher is invalid.");
            }
            return cipher;
        }
        catch (final IllegalStateException ex) {
            throw new GeneralSecurityException("AES GCM SIV cipher is not available or is invalid.", ex);
        }
    }
    
    @AccessesPartialKey
    public static Aead create(final AesGcmSivKey key) throws GeneralSecurityException {
        return com.google.crypto.tink.aead.internal.AesGcmSiv.create(key, AesGcmSiv::cipherSupplier);
    }
    
    @AccessesPartialKey
    private static Aead createFromRawKey(final byte[] key) throws GeneralSecurityException {
        return com.google.crypto.tink.aead.internal.AesGcmSiv.create(AesGcmSivKey.builder().setKeyBytes(SecretBytes.copyFrom(key, InsecureSecretKeyAccess.get())).setParameters(AesGcmSivParameters.builder().setKeySizeBytes(key.length).setVariant(AesGcmSivParameters.Variant.NO_PREFIX).build()).build(), AesGcmSiv::cipherSupplier);
    }
    
    private AesGcmSiv(final Aead aead) {
        this.aead = aead;
    }
    
    public AesGcmSiv(final byte[] key) throws GeneralSecurityException {
        this(createFromRawKey(key));
    }
    
    @Override
    public byte[] encrypt(final byte[] plaintext, final byte[] associatedData) throws GeneralSecurityException {
        return this.aead.encrypt(plaintext, associatedData);
    }
    
    @Override
    public byte[] decrypt(final byte[] ciphertext, final byte[] associatedData) throws GeneralSecurityException {
        return this.aead.decrypt(ciphertext, associatedData);
    }
    
    static {
        localAesGcmSivCipher = new ThreadLocal<Cipher>() {
            @Nullable
            @Override
            protected Cipher initialValue() {
                try {
                    final Cipher cipher = EngineFactory.CIPHER.getInstance("AES/GCM-SIV/NoPadding");
                    if (!com.google.crypto.tink.aead.internal.AesGcmSiv.isAesGcmSivCipher(cipher)) {
                        return null;
                    }
                    return cipher;
                }
                catch (final GeneralSecurityException ex) {
                    throw new IllegalStateException(ex);
                }
            }
        };
    }
}
