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

package com.google.crypto.tink.hybrid.internal;

import com.google.crypto.tink.AccessesPartialKey;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.hybrid.HpkeParameters;
import com.google.crypto.tink.hybrid.HpkePublicKey;
import com.google.crypto.tink.util.Bytes;
import com.google.errorprone.annotations.Immutable;
import com.google.crypto.tink.HybridEncrypt;

@Immutable
public final class HpkeEncrypt implements HybridEncrypt
{
    private static final byte[] EMPTY_ASSOCIATED_DATA;
    private final byte[] recipientPublicKey;
    private final HpkeKem kem;
    private final HpkeKdf kdf;
    private final HpkeAead aead;
    private final byte[] outputPrefix;
    
    private HpkeEncrypt(final Bytes recipientPublicKey, final HpkeKem kem, final HpkeKdf kdf, final HpkeAead aead, final Bytes outputPrefix) {
        this.recipientPublicKey = recipientPublicKey.toByteArray();
        this.kem = kem;
        this.kdf = kdf;
        this.aead = aead;
        this.outputPrefix = outputPrefix.toByteArray();
    }
    
    @AccessesPartialKey
    public static HybridEncrypt create(final HpkePublicKey key) throws GeneralSecurityException {
        final HpkeParameters parameters = key.getParameters();
        return new HpkeEncrypt(key.getPublicKeyBytes(), HpkePrimitiveFactory.createKem(parameters.getKemId()), HpkePrimitiveFactory.createKdf(parameters.getKdfId()), HpkePrimitiveFactory.createAead(parameters.getAeadId()), key.getOutputPrefix());
    }
    
    @Override
    public byte[] encrypt(final byte[] plaintext, final byte[] contextInfo) throws GeneralSecurityException {
        byte[] info = contextInfo;
        if (info == null) {
            info = new byte[0];
        }
        final HpkeContext context = HpkeContext.createSenderContext(this.recipientPublicKey, this.kem, this.kdf, this.aead, info);
        final byte[] encapsulatedKey = context.getEncapsulatedKey();
        final int ciphertextOffset = this.outputPrefix.length + encapsulatedKey.length;
        final byte[] ciphertextWithPrefix = context.seal(plaintext, ciphertextOffset, HpkeEncrypt.EMPTY_ASSOCIATED_DATA);
        System.arraycopy(this.outputPrefix, 0, ciphertextWithPrefix, 0, this.outputPrefix.length);
        System.arraycopy(encapsulatedKey, 0, ciphertextWithPrefix, this.outputPrefix.length, encapsulatedKey.length);
        return ciphertextWithPrefix;
    }
    
    static {
        EMPTY_ASSOCIATED_DATA = new byte[0];
    }
}
