package no.zyon.shade.crypto

/**
 * Platform-agnostic crypto primitives. Mirror @shade/core/crypto.ts.
 *
 * All implementations must produce byte-identical output to the
 * TypeScript version for the same inputs.
 */
interface CryptoProvider {
    // ─── X25519 ────────────────────────────────────────────────

    /** Generate an X25519 keypair (32-byte public + 32-byte private) */
    fun generateX25519KeyPair(): Pair<ByteArray, ByteArray> // (public, private)

    /** X25519 Diffie-Hellman: returns 32-byte shared secret */
    fun x25519(privateKey: ByteArray, publicKey: ByteArray): ByteArray

    // ─── Ed25519 ───────────────────────────────────────────────

    /** Generate an Ed25519 keypair */
    fun generateEd25519KeyPair(): Pair<ByteArray, ByteArray>

    /** Sign message with Ed25519 — returns 64-byte signature */
    fun sign(privateKey: ByteArray, message: ByteArray): ByteArray

    /** Verify Ed25519 signature — returns true if valid */
    fun verify(publicKey: ByteArray, message: ByteArray, signature: ByteArray): Boolean

    // ─── AES-256-GCM ──────────────────────────────────────────

    /** Encrypt with AES-256-GCM. Generates random 12-byte nonce. */
    fun aesGcmEncrypt(
        key: ByteArray,
        plaintext: ByteArray,
        aad: ByteArray? = null,
    ): Pair<ByteArray, ByteArray> // (ciphertext, nonce)

    /** Decrypt AES-256-GCM. Throws on authentication failure. */
    fun aesGcmDecrypt(
        key: ByteArray,
        ciphertext: ByteArray,
        nonce: ByteArray,
        aad: ByteArray? = null,
    ): ByteArray

    // ─── Key Derivation ────────────────────────────────────────

    /** HKDF-SHA256: derive `length` bytes */
    fun hkdf(ikm: ByteArray, salt: ByteArray, info: ByteArray, length: Int): ByteArray

    /** HMAC-SHA256: 32-byte MAC */
    fun hmacSha256(key: ByteArray, data: ByteArray): ByteArray

    // ─── Random ────────────────────────────────────────────────

    fun randomBytes(length: Int): ByteArray

    fun randomUint32(): Int

    // ─── Hardening ─────────────────────────────────────────────

    /** Constant-time byte array comparison */
    fun constantTimeEqual(a: ByteArray, b: ByteArray): Boolean

    /** Overwrite a buffer with zeros */
    fun zeroize(buf: ByteArray)
}
