Current section
Files
Jump to
Current section
Files
lib/kzg_elixir.ex
defmodule KzgElixir do
@moduledoc """
Ethereum EIP-4844 KZG trusted setup verification NIF bindings.
This module provides NIF bindings to `c-kzg-4844` for verifying KZG proofs,
implementing the cryptographic primitives required for EIP-4844 (Proto-Danksharding).
"""
@on_load :load_nif
@type blob :: binary()
@type commitment :: binary()
@type proof :: binary()
@type field_element :: binary()
@type cell :: binary()
@doc false
def load_nif do
path = :code.priv_dir(:kzg_elixir)
:erlang.load_nif(Path.join(path, "kzg_nif"), 0)
end
@doc """
Loads the KZG trusted setup from a file.
## Arguments
* `file`: Path to the trusted setup configuration file from `c-kzg-4844`.
## Returns
* `:ok` on success.
* `{:error, reason}` on failure (e.g., file not found, bad format).
"""
@spec load_trusted_setup(String.t()) :: :ok | {:error, term()}
def load_trusted_setup(_file), do: :erlang.nif_error(:nif_not_loaded)
@doc """
Computes the KZG commitment for a given blob.
## Arguments
* `blob`: The data blob (4096 field elements, 131072 bytes).
## Returns
* `{:ok, commitment}`: The 48-byte KZG commitment.
* `{:error, reason}`: If computation fails.
"""
@spec blob_to_kzg_commitment(blob()) :: {:ok, commitment()} | {:error, term()}
def blob_to_kzg_commitment(_blob), do: :erlang.nif_error(:nif_not_loaded)
@doc """
Computes a KZG proof for a blob at a given evaluation point `z`.
## Arguments
* `blob`: The data blob.
* `z`: The evaluation point (32 bytes).
## Returns
* `{:ok, {proof, y}}`: Tuple containing the 48-byte proof and the evaluation result `y`.
* `{:error, reason}`: If computation fails.
"""
@spec compute_kzg_proof(blob(), field_element()) :: {:ok, {proof(), field_element()}} | {:error, term()}
def compute_kzg_proof(_blob, _z), do: :erlang.nif_error(:nif_not_loaded)
@doc """
Verifies a KZG proof.
## Arguments
* `commitment`: The 48-byte KZG commitment.
* `z`: The evaluation point (32 bytes).
* `y`: The evaluation result (32 bytes).
* `proof`: The 48-byte proof.
## Returns
* `{:ok, true}` if valid.
* `{:ok, false}` if invalid.
* `{:error, reason}` on error.
"""
@spec verify_kzg_proof(commitment(), field_element(), field_element(), proof()) :: {:ok, boolean()} | {:error, term()}
def verify_kzg_proof(_commitment, _z, _y, _proof), do: :erlang.nif_error(:nif_not_loaded)
@doc """
Verifies a KZG proof for a blob.
## Arguments
* `blob`: The data blob.
* `commitment`: The 48-byte KZG commitment.
* `proof`: The 48-byte proof.
## Returns
* `{:ok, true}` if valid.
* `{:ok, false}` if invalid.
* `{:error, reason}` on error.
"""
@spec verify_blob_kzg_proof(blob(), commitment(), proof()) :: {:ok, boolean()} | {:error, term()}
def verify_blob_kzg_proof(_blob, _commitment, _proof), do: :erlang.nif_error(:nif_not_loaded)
@doc """
Computes a blob KZG proof for a given blob and commitment.
This matches `c-kzg-4844`'s `compute_blob_kzg_proof`.
## Returns
* `{:ok, proof}` on success.
* `{:error, reason}` on failure.
"""
@spec compute_blob_kzg_proof(blob(), commitment()) :: {:ok, proof()} | {:error, term()}
def compute_blob_kzg_proof(_blob, _commitment), do: :erlang.nif_error(:nif_not_loaded)
@doc """
Verifies a batch of blob KZG proofs.
This matches `c-kzg-4844`'s `verify_blob_kzg_proof_batch`.
## Returns
* `{:ok, true}` if the batch is valid.
* `{:ok, false}` if the batch is invalid.
* `{:error, reason}` on error.
"""
@spec verify_blob_kzg_proof_batch([blob()], [commitment()], [proof()]) :: {:ok, boolean()} | {:error, term()}
def verify_blob_kzg_proof_batch(_blobs, _commitments, _proofs), do: :erlang.nif_error(:nif_not_loaded)
@doc """
Computes the Fiat–Shamir challenge used in blob verification.
This wraps the internal `c-kzg-4844` helper `compute_challenge`.
"""
@spec compute_challenge(blob(), commitment()) :: {:ok, field_element()} | {:error, term()}
def compute_challenge(_blob, _commitment), do: :erlang.nif_error(:nif_not_loaded)
@doc """
EIP-7594: Compute cells and corresponding KZG proofs for a blob.
"""
@spec compute_cells_and_kzg_proofs(blob()) :: {:ok, {list(cell()), list(proof())}} | {:error, term()}
def compute_cells_and_kzg_proofs(_blob), do: :erlang.nif_error(:nif_not_loaded)
@doc """
EIP-7594: Recover missing cells and proofs given a partial set.
"""
@spec recover_cells_and_kzg_proofs([non_neg_integer()], list(cell())) ::
{:ok, {list(cell()), list(proof())}} | {:error, term()}
def recover_cells_and_kzg_proofs(_cell_indices, _cells), do: :erlang.nif_error(:nif_not_loaded)
@doc """
EIP-7594: Verify a batch of cell KZG proofs.
"""
@spec verify_cell_kzg_proof_batch([commitment()], [non_neg_integer()], list(cell()), [proof()]) ::
{:ok, boolean()} | {:error, term()}
def verify_cell_kzg_proof_batch(_commitments, _cell_indices, _cells, _proofs),
do: :erlang.nif_error(:nif_not_loaded)
@doc """
EIP-7594: Compute the challenge used by `verify_cell_kzg_proof_batch`.
Exposed for test vectors.
"""
@spec compute_verify_cell_kzg_proof_batch_challenge(
[commitment()],
[non_neg_integer()],
[non_neg_integer()],
list(cell()),
[proof()]
) :: {:ok, field_element()} | {:error, term()}
def compute_verify_cell_kzg_proof_batch_challenge(
_commitments,
_commitment_indices,
_cell_indices,
_cells,
_proofs
),
do: :erlang.nif_error(:nif_not_loaded)
end