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

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

import java.security.spec.ECPoint;
import com.google.crypto.tink.subtle.EllipticCurves;
import com.google.crypto.tink.subtle.Bytes;
import com.google.crypto.tink.AccessesPartialKey;
import com.google.crypto.tink.hybrid.HpkeParameters;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.hybrid.HpkePublicKey;
import com.google.errorprone.annotations.Immutable;

@Immutable
public final class AuthHpkeHelperForAndroidKeystore
{
    private static final byte[] EMPTY_ASSOCIATED_DATA;
    private final HpkeKem kem;
    private final HpkeKdf kdf;
    private final HpkeAead aead;
    private final byte[] ourPublicKeyByteArray;
    private final byte[] theirPublicKeyByteArray;
    
    private AuthHpkeHelperForAndroidKeystore(final HpkeKem kem, final HpkeKdf kdf, final HpkeAead aead, final byte[] ourPublicKeyByteArray, final byte[] theirPublicKeyByteArray) {
        this.kem = kem;
        this.kdf = kdf;
        this.aead = aead;
        this.ourPublicKeyByteArray = ourPublicKeyByteArray;
        this.theirPublicKeyByteArray = theirPublicKeyByteArray;
    }
    
    @AccessesPartialKey
    public static AuthHpkeHelperForAndroidKeystore create(final HpkePublicKey ourPublicKey, final HpkePublicKey theirPublicKey) throws GeneralSecurityException {
        if (!ourPublicKey.getParameters().equals(theirPublicKey.getParameters())) {
            throw new GeneralSecurityException("ourPublicKey.getParameters() must be equal to theirPublicKey.getParameters()");
        }
        final HpkeParameters parameters = ourPublicKey.getParameters();
        validateParameters(parameters);
        final HpkeKem kem = HpkePrimitiveFactory.createKem(parameters.getKemId());
        final HpkeKdf kdf = HpkePrimitiveFactory.createKdf(parameters.getKdfId());
        final HpkeAead aead = HpkePrimitiveFactory.createAead(parameters.getAeadId());
        return new AuthHpkeHelperForAndroidKeystore(kem, kdf, aead, ourPublicKey.getPublicKeyBytes().toByteArray(), theirPublicKey.getPublicKeyBytes().toByteArray());
    }
    
    private static void validateParameters(final HpkeParameters parameters) throws GeneralSecurityException {
        if (!parameters.getKemId().equals(HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256)) {
            throw new GeneralSecurityException("AuthHpkeHelperForAndroidKeystore currently only supports KemId.DHKEM_P256_HKDF_SHA256.");
        }
        if (!parameters.getKdfId().equals(HpkeParameters.KdfId.HKDF_SHA256)) {
            throw new GeneralSecurityException("AuthHpkeHelperForAndroidKeystore currently only supports KdfId.HKDF_SHA256.");
        }
        if (!parameters.getAeadId().equals(HpkeParameters.AeadId.AES_128_GCM) && !parameters.getAeadId().equals(HpkeParameters.AeadId.AES_256_GCM)) {
            throw new GeneralSecurityException("AuthHpkeHelperForAndroidKeystore currently only supports AeadId.AES_128_GCM and AeadId.AES_256_GCM.");
        }
        if (!parameters.getVariant().equals(HpkeParameters.Variant.NO_PREFIX)) {
            throw new GeneralSecurityException("AuthHpkeHelperForAndroidKeystore currently only supports Variant.NO_PREFIX");
        }
    }
    
    public byte[] decryptAuthenticatedWithEncapsulatedKeyAndP256SharedSecret(final byte[] encapsulatedKey, final byte[] dhSharedSecret1, final byte[] dhSharedSecret2, final byte[] ciphertext, final int ciphertextOffset, final byte[] info) throws GeneralSecurityException {
        final byte[] dhSharedSecret3 = Bytes.concat(new byte[][] { dhSharedSecret1, dhSharedSecret2 });
        final byte[] derivedSharedSecret = NistCurvesHpkeKem.fromCurve(EllipticCurves.CurveType.NIST_P256).deriveKemSharedSecret(dhSharedSecret3, encapsulatedKey, this.ourPublicKeyByteArray, this.theirPublicKeyByteArray);
        final HpkeContext context = HpkeContext.createContext(HpkeUtil.AUTH_MODE, encapsulatedKey, derivedSharedSecret, this.kem, this.kdf, this.aead, info);
        return context.open(ciphertext, ciphertextOffset, AuthHpkeHelperForAndroidKeystore.EMPTY_ASSOCIATED_DATA);
    }
    
    public byte[] encryptAuthenticatedWithEncapsulatedKeyAndP256SharedSecret(final ECPoint emphemeralPublicKey, final byte[] dhSharedSecret1, final byte[] dhSharedSecret2, final byte[] plaintext, final byte[] contextInfo) throws GeneralSecurityException {
        final byte[] emphemeralPublicKeyByteArray = EllipticCurves.pointEncode(EllipticCurves.CurveType.NIST_P256, EllipticCurves.PointFormatType.UNCOMPRESSED, emphemeralPublicKey);
        final byte[] dhSharedSecret3 = Bytes.concat(new byte[][] { dhSharedSecret1, dhSharedSecret2 });
        final byte[] derivedSharedSecret = NistCurvesHpkeKem.fromCurve(EllipticCurves.CurveType.NIST_P256).deriveKemSharedSecret(dhSharedSecret3, emphemeralPublicKeyByteArray, this.theirPublicKeyByteArray, this.ourPublicKeyByteArray);
        final HpkeContext context = HpkeContext.createContext(HpkeUtil.AUTH_MODE, emphemeralPublicKeyByteArray, derivedSharedSecret, this.kem, this.kdf, this.aead, contextInfo);
        return Bytes.concat(new byte[][] { emphemeralPublicKeyByteArray, context.seal(plaintext, AuthHpkeHelperForAndroidKeystore.EMPTY_ASSOCIATED_DATA) });
    }
    
    static {
        EMPTY_ASSOCIATED_DATA = new byte[0];
    }
}
