Skip to content

split protocols and encoding

currently, we need to manipulate fec::Shards in order to use any of the protocols from Komodo

💡 Note

in the snippets below, the following will be ommitted

  • function bodies (and type generics will be at the bottom of each section for brevity)
  • non-public functions and struct fields
  • the pub keyword

Semi-AVID

struct Block<F, G> { shard: fec::Shard<F> }

fn recode<F, G>(blocks: &[Block<F, G>], rng: &mut impl RngCore) -> Result<Option<Block<F, G>>, KomodoError>
fn prove<F, G, P>(bytes: &[u8], powers: &Powers<F, G>, k: usize) -> Result<Vec<Commitment<F, G>>, KomodoError>
fn build<F, G, P>(shards: &[fec::Shard<F>], proof: &[Commitment<F, G>]) -> Vec<Block<F, G>>
fn verify<F, G, P>(block: &Block<F, G>, verifier_key: &Powers<F, G>) -> Result<bool, KomodoError>

where

F: PrimeField,
G: CurveGroup<ScalarField = F>,
P: DenseUVPolynomial<F>,
for<'a, 'b> &'a P: Div<&'b P, Output = P>,

KZG

struct Block<E> { shard: fec::Shard<E::ScalarField> }

fn prove<E, P>(
    commits: Vec<kzg10::Commitment<E>>,
    polynomials: Vec<P>,
    shards: Vec<fec::Shard<E::ScalarField>>,
    points: Vec<E::ScalarField>,
    powers: kzg10::Powers<E>,
) -> Result<Vec<Block<E>>, KomodoError>
fn verify<E, P>(
    block: &Block<E>,
    pt: E::ScalarField,
    verifier_key: &kzg10::VerifierKey<E>,
) -> bool
fn batch_verify<E, P>(
    blocks: &[Block<E>],
    pts: &[E::ScalarField],
    verifier_key: &kzg10::VerifierKey<E>,
) -> Result<bool, SerializationError>

where

E: Pairing,
P: DenseUVPolynomial<E::ScalarField, Point = E::ScalarField>,
for<'a, 'b> &'a P: Div<&'b P, Output = P>,

aPlonK

struct Block<E> { shard: fec::Shard<E::ScalarField> }
struct Commitment<E, P>
struct SetupParams<E> {
    kzg: kzg10::UniversalParams<E>,
    ipa: ipa::Params<E>,
}
struct VerifierKey<E> {
    vk_psi: kzg10::VerifierKey<E>,
    tau_1: E::G1,
    g1: E::G1,
    g2: E::G2,
}

fn setup<E, P>(
    degree_bound: usize,
    nb_polynomials: usize,
) -> Result<SetupParams<E>, ark_poly_commit::Error>
fn commit<E, P>(
    polynomials: Vec<P>,
    setup: SetupParams<E>,
) -> Result<(Vec<E::G1>, PairingOutput<E>), KomodoError>
fn prove<E, P>(
    commit: (Vec<E::G1>, PairingOutput<E>),
    polynomials: Vec<P>,
    shards: Vec<fec::Shard<E::ScalarField>>,
    points: Vec<E::ScalarField>,
    params: SetupParams<E>,
) -> Result<Vec<Block<E>>, KomodoError>
fn verify<E, P>(
    block: &Block<E>,
    pt: E::ScalarField,
    vk_psi: &kzg10::VerifierKey<E>,
    tau_1: E::G1,
    g_1: E::G1,
    g_2: E::G2,
) -> Result<bool, KomodoError>

where

E: Pairing,
P: DenseUVPolynomial<E::ScalarField, Point = E::ScalarField>,
for<'a, 'b> &'a P: Div<&'b P, Output = P>,

FRI

struct Block<F: PrimeField, H: Hasher> {
    shard: fec::Shard<F>,
    proof: MerkleProof<H>,
    commit: Rc<FridaCommitment<F, H>>,
}

fn evaluate<F>(bytes: &[u8], k: usize, n: usize) -> Vec<Vec<F>>
fn encode<F>(
    bytes: &[u8],
    evaluations: Vec<Vec<F>>,
    k: usize,
) -> Vec<fec::Shard<F>>
fn prove<N, F, H, P>(
    evaluations: Vec<Vec<F>>,
    shards: Vec<fec::Shard<F>>,
    blowup_factor: usize,
    remainder_plus_one: usize,
    nb_queries: usize,
) -> Result<Vec<Block<F, H>>, KomodoError>
fn verify<N, F, H, P>(
    block: Block<F, H>,
    domain_size: usize,
    nb_queries: usize,
) -> Result<(), KomodoError>
fn decode<F, H>(blocks: Vec<Block<F, H>>, n: usize) -> Vec<u8>

where

const N: usize
F: PrimeField
H: Hasher
P: DenseUVPolynomial<F>,
for<'a, 'b> &'a P: Div<&'b P, Output = P>,
<H as rs_merkle::Hasher>::Hash: AsRef<[u8]>,

is this a good idea?

in the end, Semi-AVID only applies to any polynomials and their linear combination.

maybe we could have Komodo provide protocols as standalone bricks, i.e. without uses of fec::Shard, through the current features, e.g. kzg, and provide a "FEC" layer on top, on demand