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

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

import com.google.crypto.tink.subtle.EllipticCurves;
import com.google.crypto.tink.hybrid.HpkeParameters;
import com.google.crypto.tink.internal.Util;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.subtle.Bytes;

public final class HpkeUtil
{
    public static final byte[] BASE_MODE;
    public static final byte[] AUTH_MODE;
    public static final byte[] X25519_HKDF_SHA256_KEM_ID;
    public static final byte[] P256_HKDF_SHA256_KEM_ID;
    public static final byte[] P384_HKDF_SHA384_KEM_ID;
    public static final byte[] P521_HKDF_SHA512_KEM_ID;
    public static final byte[] HKDF_SHA256_KDF_ID;
    public static final byte[] HKDF_SHA384_KDF_ID;
    public static final byte[] HKDF_SHA512_KDF_ID;
    public static final byte[] AES_128_GCM_AEAD_ID;
    public static final byte[] AES_256_GCM_AEAD_ID;
    public static final byte[] CHACHA20_POLY1305_AEAD_ID;
    public static final byte[] EMPTY_SALT;
    private static final byte[] KEM;
    private static final byte[] HPKE;
    private static final byte[] HPKE_V1;
    
    public static byte[] intToByteArray(final int capacity, final int value) {
        if (capacity > 4 || capacity < 0) {
            throw new IllegalArgumentException("capacity must be between 0 and 4");
        }
        if (value < 0 || (capacity < 4 && value >= 1 << 8 * capacity)) {
            throw new IllegalArgumentException("value too large");
        }
        final byte[] result = new byte[capacity];
        for (int i = 0; i < capacity; ++i) {
            result[i] = (byte)(value >> 8 * (capacity - i - 1) & 0xFF);
        }
        return result;
    }
    
    static byte[] kemSuiteId(final byte[] kemId) throws GeneralSecurityException {
        return Bytes.concat(new byte[][] { HpkeUtil.KEM, kemId });
    }
    
    static byte[] hpkeSuiteId(final byte[] kemId, final byte[] kdfId, final byte[] aeadId) throws GeneralSecurityException {
        return Bytes.concat(new byte[][] { HpkeUtil.HPKE, kemId, kdfId, aeadId });
    }
    
    static byte[] labelIkm(final String label, final byte[] ikm, final byte[] suiteId) throws GeneralSecurityException {
        return Bytes.concat(new byte[][] { HpkeUtil.HPKE_V1, suiteId, label.getBytes(Util.UTF_8), ikm });
    }
    
    static byte[] labelInfo(final String label, final byte[] info, final byte[] suiteId, final int length) throws GeneralSecurityException {
        return Bytes.concat(new byte[][] { intToByteArray(2, length), HpkeUtil.HPKE_V1, suiteId, label.getBytes(Util.UTF_8), info });
    }
    
    static EllipticCurves.CurveType nistHpkeKemToCurve(final HpkeParameters.KemId kemId) throws GeneralSecurityException {
        if (kemId == HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) {
            return EllipticCurves.CurveType.NIST_P256;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P384_HKDF_SHA384) {
            return EllipticCurves.CurveType.NIST_P384;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P521_HKDF_SHA512) {
            return EllipticCurves.CurveType.NIST_P521;
        }
        throw new GeneralSecurityException("Unrecognized NIST HPKE KEM identifier");
    }
    
    public static int getEncodedPublicKeyLength(final HpkeParameters.KemId kemId) throws GeneralSecurityException {
        if (kemId == HpkeParameters.KemId.DHKEM_X25519_HKDF_SHA256) {
            return 32;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) {
            return 65;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P384_HKDF_SHA384) {
            return 97;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P521_HKDF_SHA512) {
            return 133;
        }
        throw new GeneralSecurityException("Unrecognized HPKE KEM identifier");
    }
    
    public static int encodingSizeInBytes(final HpkeParameters.KemId kemId) {
        if (kemId == HpkeParameters.KemId.DHKEM_X25519_HKDF_SHA256) {
            return 32;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) {
            return 65;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P384_HKDF_SHA384) {
            return 97;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P521_HKDF_SHA512) {
            return 133;
        }
        throw new IllegalArgumentException("Unable to determine KEM-encoding length for " + kemId);
    }
    
    public static int getEncodedPrivateKeyLength(final HpkeParameters.KemId kemId) throws GeneralSecurityException {
        if (kemId == HpkeParameters.KemId.DHKEM_X25519_HKDF_SHA256) {
            return 32;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P256_HKDF_SHA256) {
            return 32;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P384_HKDF_SHA384) {
            return 48;
        }
        if (kemId == HpkeParameters.KemId.DHKEM_P521_HKDF_SHA512) {
            return 66;
        }
        throw new GeneralSecurityException("Unrecognized HPKE KEM identifier");
    }
    
    private HpkeUtil() {
    }
    
    static {
        BASE_MODE = intToByteArray(1, 0);
        AUTH_MODE = intToByteArray(1, 2);
        X25519_HKDF_SHA256_KEM_ID = intToByteArray(2, 32);
        P256_HKDF_SHA256_KEM_ID = intToByteArray(2, 16);
        P384_HKDF_SHA384_KEM_ID = intToByteArray(2, 17);
        P521_HKDF_SHA512_KEM_ID = intToByteArray(2, 18);
        HKDF_SHA256_KDF_ID = intToByteArray(2, 1);
        HKDF_SHA384_KDF_ID = intToByteArray(2, 2);
        HKDF_SHA512_KDF_ID = intToByteArray(2, 3);
        AES_128_GCM_AEAD_ID = intToByteArray(2, 1);
        AES_256_GCM_AEAD_ID = intToByteArray(2, 2);
        CHACHA20_POLY1305_AEAD_ID = intToByteArray(2, 3);
        EMPTY_SALT = new byte[0];
        KEM = "KEM".getBytes(Util.UTF_8);
        HPKE = "HPKE".getBytes(Util.UTF_8);
        HPKE_V1 = "HPKE-v1".getBytes(Util.UTF_8);
    }
}
