Skip to content

Commit

Permalink
Comments and harmless renames
Browse files Browse the repository at this point in the history
  • Loading branch information
asn-d6 committed Aug 16, 2024
1 parent e3ef368 commit d779cd4
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 44 deletions.
35 changes: 18 additions & 17 deletions src/eip7594/eip7594.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,13 @@ static const char *RANDOM_CHALLENGE_DOMAIN_VERIFY_CELL_KZG_PROOF_BATCH = "RCKZGC
////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Given a blob, get all of its cells and proofs.
* Given a blob, compute all of its cells and proofs.
*
* @param[out] cells An array of CELLS_PER_EXT_BLOB cells
* @param[out] proofs An array of CELLS_PER_EXT_BLOB proofs
* @param[in] blob The blob to get cells/proofs for
* @param[in] s The trusted setup
*
* @remark Up to half of these cells may be lost.
* @remark Use recover_cells_and_kzg_proofs for recovery.
* @remark If cells is NULL, they won't be computed.
* @remark If proofs is NULL, they won't be computed.
* @remark Will return an error if both cells & proofs are NULL.
Expand All @@ -81,8 +79,9 @@ C_KZG_RET compute_cells_and_kzg_proofs(

/*
* Convert the blob to a polynomial in lagrange form. Note that only the first 4096 fields of
* the polynomial will be set. The upper 4096 fields will remain zero. This is required because
* the polynomial will be evaluated with 8192 roots of unity.
* the polynomial will be set. The upper 4096 fields will remain zero. The extra space is
* required because the polynomial will be evaluated to the extended domain (8192 roots of
* unity).
*/
ret = blob_to_polynomial(poly_lagrange, blob);
if (ret != C_KZG_OK) goto out;
Expand Down Expand Up @@ -155,9 +154,9 @@ C_KZG_RET compute_cells_and_kzg_proofs(
*
* @param[out] recovered_cells An array of CELLS_PER_EXT_BLOB cells
* @param[out] recovered_proofs An array of CELLS_PER_EXT_BLOB proofs
* @param[in] cell_indices The cell indices for the cells
* @param[in] cells The cells to check
* @param[in] num_cells The number of cells provided
* @param[in] cell_indices The cell indices for the available cells
* @param[in] cells The available cells we recover from
* @param[in] num_cells The number of available cells provided
* @param[in] s The trusted setup
*
* @remark Recovery is faster if there are fewer missing cells.
Expand Down Expand Up @@ -206,25 +205,25 @@ C_KZG_RET recover_cells_and_kzg_proofs(
recovered_cells_fr[i] = FR_NULL;
}

/* Update with existing cells */
/* Populate recovered_cells_fr with available cells at the right places */
for (size_t i = 0; i < num_cells; i++) {
size_t index = cell_indices[i] * FIELD_ELEMENTS_PER_CELL;
for (size_t j = 0; j < FIELD_ELEMENTS_PER_CELL; j++) {
fr_t *field = &recovered_cells_fr[index + j];
fr_t *ptr = &recovered_cells_fr[index + j];

/*
* Check if the field has already been set. If it has, there was a duplicate cell index
* and we can return an error. The compiler will optimize this and the overhead is
* practically zero.
*/
if (!fr_is_null(field)) {
if (!fr_is_null(ptr)) {
ret = C_KZG_BADARGS;
goto out;
}

/* Convert the untrusted bytes to a field element */
/* Convert the untrusted input bytes to a field element */
size_t offset = j * BYTES_PER_FIELD_ELEMENT;
ret = bytes_to_bls_field(field, (const Bytes32 *)&cells[i].bytes[offset]);
ret = bytes_to_bls_field(ptr, (const Bytes32 *)&cells[i].bytes[offset]);
if (ret != C_KZG_OK) goto out;
}
}
Expand Down Expand Up @@ -630,13 +629,15 @@ C_KZG_RET verify_cell_kzg_proof_batch(
/* Scale each cell's data points */
for (size_t i = 0; i < num_cells; i++) {
for (size_t j = 0; j < FIELD_ELEMENTS_PER_CELL; j++) {
fr_t field, scaled;
fr_t cell_fr, scaled_fr;
size_t offset = j * BYTES_PER_FIELD_ELEMENT;
ret = bytes_to_bls_field(&field, (const Bytes32 *)&cells[i].bytes[offset]);
ret = bytes_to_bls_field(&cell_fr, (const Bytes32 *)&cells[i].bytes[offset]);
if (ret != C_KZG_OK) goto out;
blst_fr_mul(&scaled, &field, &r_powers[i]);
blst_fr_mul(&scaled_fr, &cell_fr, &r_powers[i]);
size_t index = cell_indices[i] * FIELD_ELEMENTS_PER_CELL + j;
blst_fr_add(&aggregated_column_cells[index], &aggregated_column_cells[index], &scaled);
blst_fr_add(
&aggregated_column_cells[index], &aggregated_column_cells[index], &scaled_fr
);

/* Mark the cell as being used */
is_cell_used[index] = true;
Expand Down
9 changes: 5 additions & 4 deletions src/eip7594/poly.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ void shift_poly(fr_t *p, size_t len, const fr_t *shift_factor) {
/**
* Bit reverses and converts a polynomial in lagrange form to monomial form.
*
* @param[out] monomial The result, an array of `len` fields
* @param[in] lagrange The input poly, an array of `len` fields
* @param[in] len The length of both polynomials
* @param[in] s The trusted setup
* @param[out] monomial_out The result, an array of `len` fields
* @param[in] lagrange The input poly, an array of `len` fields
* @param[in] len The length of both polynomials
* @param[in] s The trusted setup
*
* @remark `monomial_out` and `lagrange` can point to the same memory.
* @remark This method converts a lagrange-form polynomial to a monomial-form polynomial, by inverse
* FFTing the bit-reverse-permuted lagrange polynomial.
*/
Expand Down
62 changes: 39 additions & 23 deletions src/eip7594/recovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,9 @@
* @param[in,out] poly_len The length of poly
* @param[in] roots The array of roots
* @param[in] roots_len The number of roots
* @param[in] s The trusted setup
*
* @remark These do not have to be roots of unity. They are roots of a polynomial.
* @remark `poly_len` must be at least `roots_len + 1` in length.
* @remark The `poly` array must be at least `roots_len + 1` in length.
*/
static C_KZG_RET compute_vanishing_polynomial_from_roots(
fr_t *poly, size_t *poly_len, const fr_t *roots, size_t roots_len
Expand Down Expand Up @@ -83,7 +82,7 @@ static C_KZG_RET compute_vanishing_polynomial_from_roots(
* then the i'th root of unity from `roots_of_unity` will be zero on the polynomial
* computed, along with every `CELLS_PER_EXT_BLOB` spaced root of unity in the domain.
*
* @param[in,out] vanishing_poly The vanishing polynomial
* @param[in,out] vanishing_poly The output vanishing polynomial
* @param[in] missing_cell_indices The array of missing cell indices
* @param[in] len_missing_cells The number of missing cell indices
* @param[in] s The trusted setup
Expand Down Expand Up @@ -135,7 +134,7 @@ static C_KZG_RET vanishing_polynomial_for_missing_cells(
);
if (ret != C_KZG_OK) goto out;

/* Zero out all the coefficients */
/* Zero out all the coefficients of the output poly */
for (size_t i = 0; i < FIELD_ELEMENTS_PER_EXT_BLOB; i++) {
vanishing_poly[i] = FR_ZERO;
}
Expand Down Expand Up @@ -188,18 +187,19 @@ static bool is_in_array(const uint64_t *arr, size_t arr_size, uint64_t value) {
}

/**
* Given a dataset with up to half the entries missing, return the reconstructed original. Assumes
* that the inverse FFT of the original data has the upper half of its values equal to zero.
* Given a set of cells with up to half the entries missing, return the reconstructed
* original. Assumes that the inverse FFT of the original data has the upper half of its values
* equal to zero.
*
* @param[out] reconstructed_data_out Preallocated array for recovered cells
* @param[in] cell_indices The cell indices you have
* @param[in] num_cells The number of cells that you have
* @param[in] cells The cells that you have
* @param[out] reconstructed_data_out Array of size FIELD_ELEMENTS_PER_EXT_BLOB to recover cells
* @param[in] cell_indices An array with the avaibable cell indices we have
* @param[in] num_cells The size of the `cell_indices` array
* @param[in] cells An array of size FIELD_ELEMENTS_PER_EXT_BLOB with the cells
* @param[in] s The trusted setup
*
* @remark `recovered` and `cells` can point to the same memory.
* @remark The array of cells must be 2n length and in the correct order.
* @remark Missing cells should be equal to FR_NULL.
* @remark `reconstructed_data_out` and `cells` can point to the same memory.
* @remark The array `cells` must be in the correct order (according to cell_indices)
* @remark Missing cells in `cells` should be equal to FR_NULL.
*/
C_KZG_RET recover_cells(
fr_t *reconstructed_data_out,
Expand Down Expand Up @@ -260,7 +260,10 @@ C_KZG_RET recover_cells(
/* Check that we have enough cells */
assert(len_missing <= CELLS_PER_EXT_BLOB / 2);

/* Compute Z(x) in monomial form */
/*
* Compute Z(x) in monomial form.
* Z(x) is the polynomial which vanishes on all of the evaluations which are missing.
*/
ret = vanishing_polynomial_for_missing_cells(
vanishing_poly_coeff, missing_cell_indices, len_missing, s
);
Expand All @@ -270,7 +273,12 @@ C_KZG_RET recover_cells(
ret = fr_fft(vanishing_poly_eval, vanishing_poly_coeff, FIELD_ELEMENTS_PER_EXT_BLOB, s);
if (ret != C_KZG_OK) goto out;

/* Compute (E*Z)(x) = E(x) * Z(x) in evaluation form over the FFT domain */
/*
* Compute (E*Z)(x) = E(x) * Z(x) in evaluation form over the FFT domain.
*
* Note: over the FFT domain, the polynomials (E*Z)(x) and (P*Z)(x) agree, where
* P(x) is the polynomial we want to reconstruct (degree FIELD_ELEMENTS_PER_BLOB - 1).
*/
for (size_t i = 0; i < FIELD_ELEMENTS_PER_EXT_BLOB; i++) {
if (fr_is_null(&cells_brp[i])) {
extended_evaluation_times_zero[i] = FR_ZERO;
Expand All @@ -279,7 +287,14 @@ C_KZG_RET recover_cells(
}
}

/* Convert (E*Z)(x) to monomial form */
/*
* Convert (E*Z)(x) to monomial form.
*
* We know that (E*Z)(x) and (P*Z)(x) agree over the FFT domain,
* and we know that (P*Z)(x) has degree at most FIELD_ELEMENTS_PER_EXT_BLOB - 1.
* Thus, an inverse FFT of the evaluations of (E*Z)(x) (= evaluations of (P*Z)(x))
* yields the coefficient form of (P*Z)(x).
*/
ret = fr_ifft(
extended_evaluation_times_zero_coeffs,
extended_evaluation_times_zero,
Expand All @@ -289,10 +304,10 @@ C_KZG_RET recover_cells(
if (ret != C_KZG_OK) goto out;

/*
* Polynomial division by convolution: Q3 = Q1 / Q2 where
* Q1 = (D * Z_r,I)(k * x)
* Q2 = Z_r,I(k * x)
* Q3 = D(k * x)
* Next step is to divide the polynomial (P*Z)(x) by polynomial Z(x) to get P(x).
* We do this in evaluation form over a coset of the FFT domain to avoid division by 0.
*
* Convert (P*Z)(x) to evaluation form over a coset of the FFT domain.
*/
ret = coset_fft(
extended_evaluations_over_coset,
Expand All @@ -302,12 +317,13 @@ C_KZG_RET recover_cells(
);
if (ret != C_KZG_OK) goto out;

/* Convert Z(x) to evaluation form over a coset of the FFT domain */
ret = coset_fft(
vanishing_poly_over_coset, vanishing_poly_coeff, FIELD_ELEMENTS_PER_EXT_BLOB, s
);
if (ret != C_KZG_OK) goto out;

/* The result of the division is Q3 */
/* Compute P(x) = (P*Z)(x) / Z(x) in evaluation form over a coset of the FFT domain */
for (size_t i = 0; i < FIELD_ELEMENTS_PER_EXT_BLOB; i++) {
fr_div(
&extended_evaluations_over_coset[i],
Expand All @@ -321,14 +337,14 @@ C_KZG_RET recover_cells(
* polynomial as reconstructed_poly_over_coset in the spec.
*/

/* Convert the evaluations back to coefficents */
/* Convert P(x) to coefficient form */
ret = coset_ifft(
reconstructed_poly_coeff, extended_evaluations_over_coset, FIELD_ELEMENTS_PER_EXT_BLOB, s
);
if (ret != C_KZG_OK) goto out;

/*
* After unscaling the reconstructed polynomial, we have D(x) which evaluates to our original
* After unscaling the reconstructed polynomial, we have P(x) which evaluates to our original
* data at the roots of unity. Next, we evaluate the polynomial to get the original data.
*/
ret = fr_fft(reconstructed_data_out, reconstructed_poly_coeff, FIELD_ELEMENTS_PER_EXT_BLOB, s);
Expand Down

0 comments on commit d779cd4

Please sign in to comment.