mirror of
https://github.com/status-im/c-kzg-4844.git
synced 2025-02-20 13:58:14 +00:00
Refactor use of MSM around the base code (#159)
* Separate naive MSM and fast MSM into separate functions * Use naive MSM in batch verify, and fast MSM when points are trusted
This commit is contained in:
parent
6b2ee20102
commit
94198b5c18
@ -752,6 +752,28 @@ static void compute_challenge(
|
|||||||
* Calculates `[coeffs_0]p_0 + [coeffs_1]p_1 + ... + [coeffs_n]p_n`
|
* Calculates `[coeffs_0]p_0 + [coeffs_1]p_1 + ... + [coeffs_n]p_n`
|
||||||
* where `n` is `len - 1`.
|
* where `n` is `len - 1`.
|
||||||
*
|
*
|
||||||
|
* This function computes the result naively without using Pippenger's
|
||||||
|
* algorithm.
|
||||||
|
*/
|
||||||
|
static void g1_lincomb_naive(
|
||||||
|
g1_t *out, const g1_t *p, const fr_t *coeffs, uint64_t len
|
||||||
|
) {
|
||||||
|
g1_t tmp;
|
||||||
|
*out = G1_IDENTITY;
|
||||||
|
for (uint64_t i = 0; i < len; i++) {
|
||||||
|
g1_mul(&tmp, &p[i], &coeffs[i]);
|
||||||
|
blst_p1_add_or_double(out, out, &tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate a linear combination of G1 group elements.
|
||||||
|
*
|
||||||
|
* Calculates `[coeffs_0]p_0 + [coeffs_1]p_1 + ... + [coeffs_n]p_n`
|
||||||
|
* where `n` is `len - 1`.
|
||||||
|
*
|
||||||
|
* @remark This function MUST NOT be called with the point at infinity in `p`.
|
||||||
|
|
||||||
* @param[out] out The resulting sum-product
|
* @param[out] out The resulting sum-product
|
||||||
* @param[in] p Array of G1 group elements, length @p len
|
* @param[in] p Array of G1 group elements, length @p len
|
||||||
* @param[in] coeffs Array of field elements, length @p len
|
* @param[in] coeffs Array of field elements, length @p len
|
||||||
@ -768,7 +790,7 @@ static void compute_challenge(
|
|||||||
*
|
*
|
||||||
* We do the second of these to save memory here.
|
* We do the second of these to save memory here.
|
||||||
*/
|
*/
|
||||||
static C_KZG_RET g1_lincomb(
|
static C_KZG_RET g1_lincomb_fast(
|
||||||
g1_t *out, const g1_t *p, const fr_t *coeffs, uint64_t len
|
g1_t *out, const g1_t *p, const fr_t *coeffs, uint64_t len
|
||||||
) {
|
) {
|
||||||
C_KZG_RET ret;
|
C_KZG_RET ret;
|
||||||
@ -778,13 +800,7 @@ static C_KZG_RET g1_lincomb(
|
|||||||
|
|
||||||
// Tunable parameter: must be at least 2 since Blst fails for 0 or 1
|
// Tunable parameter: must be at least 2 since Blst fails for 0 or 1
|
||||||
if (len < 8) {
|
if (len < 8) {
|
||||||
// Direct approach
|
g1_lincomb_naive(out, p, coeffs, len);
|
||||||
g1_t tmp;
|
|
||||||
*out = G1_IDENTITY;
|
|
||||||
for (uint64_t i = 0; i < len; i++) {
|
|
||||||
g1_mul(&tmp, &p[i], &coeffs[i]);
|
|
||||||
blst_p1_add_or_double(out, out, &tmp);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Blst's implementation of the Pippenger method
|
// Blst's implementation of the Pippenger method
|
||||||
size_t scratch_size = blst_p1s_mult_pippenger_scratch_sizeof(len);
|
size_t scratch_size = blst_p1s_mult_pippenger_scratch_sizeof(len);
|
||||||
@ -910,7 +926,7 @@ out:
|
|||||||
static C_KZG_RET poly_to_kzg_commitment(
|
static C_KZG_RET poly_to_kzg_commitment(
|
||||||
g1_t *out, const Polynomial *p, const KZGSettings *s
|
g1_t *out, const Polynomial *p, const KZGSettings *s
|
||||||
) {
|
) {
|
||||||
return g1_lincomb(
|
return g1_lincomb_fast(
|
||||||
out, s->g1_values, (const fr_t *)(&p->evals), FIELD_ELEMENTS_PER_BLOB
|
out, s->g1_values, (const fr_t *)(&p->evals), FIELD_ELEMENTS_PER_BLOB
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1139,7 +1155,7 @@ static C_KZG_RET compute_kzg_proof_impl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
g1_t out_g1;
|
g1_t out_g1;
|
||||||
ret = g1_lincomb(
|
ret = g1_lincomb_fast(
|
||||||
&out_g1, s->g1_values, (const fr_t *)(&q.evals), FIELD_ELEMENTS_PER_BLOB
|
&out_g1, s->g1_values, (const fr_t *)(&q.evals), FIELD_ELEMENTS_PER_BLOB
|
||||||
);
|
);
|
||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
@ -1353,8 +1369,7 @@ static C_KZG_RET verify_kzg_proof_batch(
|
|||||||
if (ret != C_KZG_OK) goto out;
|
if (ret != C_KZG_OK) goto out;
|
||||||
|
|
||||||
/* Compute \sum r^i * Proof_i */
|
/* Compute \sum r^i * Proof_i */
|
||||||
ret = g1_lincomb(&proof_lincomb, proofs_g1, r_powers, n);
|
g1_lincomb_naive(&proof_lincomb, proofs_g1, r_powers, n);
|
||||||
if (ret != C_KZG_OK) goto out;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
g1_t ys_encrypted;
|
g1_t ys_encrypted;
|
||||||
@ -1368,11 +1383,9 @@ static C_KZG_RET verify_kzg_proof_batch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get \sum r^i z_i Proof_i */
|
/* Get \sum r^i z_i Proof_i */
|
||||||
ret = g1_lincomb(&proof_z_lincomb, proofs_g1, r_times_z, n);
|
g1_lincomb_naive(&proof_z_lincomb, proofs_g1, r_times_z, n);
|
||||||
if (ret != C_KZG_OK) goto out;
|
|
||||||
/* Get \sum r^i (C_i - [y_i]) */
|
/* Get \sum r^i (C_i - [y_i]) */
|
||||||
ret = g1_lincomb(&C_minus_y_lincomb, C_minus_y, r_powers, n);
|
g1_lincomb_naive(&C_minus_y_lincomb, C_minus_y, r_powers, n);
|
||||||
if (ret != C_KZG_OK) goto out;
|
|
||||||
|
|
||||||
/* Get C_minus_y_lincomb + proof_z_lincomb */
|
/* Get C_minus_y_lincomb + proof_z_lincomb */
|
||||||
blst_p1_add_or_double(&rhs_g1, &C_minus_y_lincomb, &proof_z_lincomb);
|
blst_p1_add_or_double(&rhs_g1, &C_minus_y_lincomb, &proof_z_lincomb);
|
||||||
|
@ -898,23 +898,21 @@ static void test_compute_powers__succeeds_expected_powers(void) {
|
|||||||
|
|
||||||
static void test_g1_lincomb__verify_consistent(void) {
|
static void test_g1_lincomb__verify_consistent(void) {
|
||||||
C_KZG_RET ret;
|
C_KZG_RET ret;
|
||||||
g1_t points[128], out, check, tmp;
|
g1_t points[128], out, check;
|
||||||
fr_t scalars[128];
|
fr_t scalars[128];
|
||||||
|
|
||||||
check = G1_IDENTITY;
|
check = G1_IDENTITY;
|
||||||
for (size_t i = 0; i < 128; i++) {
|
for (size_t i = 0; i < 128; i++) {
|
||||||
get_rand_fr(&scalars[i]);
|
get_rand_fr(&scalars[i]);
|
||||||
get_rand_g1(&points[i]);
|
get_rand_g1(&points[i]);
|
||||||
g1_mul(&tmp, &points[i], &scalars[i]);
|
|
||||||
blst_p1_add(&check, &check, &tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = g1_lincomb(&out, points, scalars, 128);
|
g1_lincomb_naive(&check, points, scalars, 128);
|
||||||
|
|
||||||
|
ret = g1_lincomb_fast(&out, points, scalars, 128);
|
||||||
ASSERT_EQUALS(ret, C_KZG_OK);
|
ASSERT_EQUALS(ret, C_KZG_OK);
|
||||||
|
|
||||||
ASSERT(
|
ASSERT("pippenger matches naive MSM", blst_p1_is_equal(&out, &check));
|
||||||
"lincomb matches direct multiplication", blst_p1_is_equal(&out, &check)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user