From 6c556bdfe6bd1432868e8e23f51c527667ca62ef Mon Sep 17 00:00:00 2001
From: Roberto Bayardo <bayardo@alum.mit.edu>
Date: Sun, 6 Nov 2022 12:39:30 -0800
Subject: [PATCH] remove legacy kzg verification, put all initialization on top
 (#44)

---
 crypto/kzg/kzg.go       | 113 ++++++++--------------------------------
 tests/kzg_bench_test.go |  14 -----
 2 files changed, 23 insertions(+), 104 deletions(-)

diff --git a/crypto/kzg/kzg.go b/crypto/kzg/kzg.go
index 8116f09721c4..9036fea3f78b 100644
--- a/crypto/kzg/kzg.go
+++ b/crypto/kzg/kzg.go
@@ -22,6 +22,29 @@ var kzgSetupLagrange []bls.G1Point
 // KZG CRS for G1 (only used in tests (for proof creation))
 var KzgSetupG1 []bls.G1Point
 
+type JSONTrustedSetup struct {
+	SetupG1       []bls.G1Point
+	SetupG2       []bls.G2Point
+	SetupLagrange []bls.G1Point
+}
+
+// Initialize KZG subsystem (load the trusted setup data)
+func init() {
+	var parsedSetup = JSONTrustedSetup{}
+
+	// TODO: This is dirty. KZG setup should be loaded using an actual config file directive
+	err := json.Unmarshal([]byte(KZGSetupStr), &parsedSetup)
+	if err != nil {
+		panic(err)
+	}
+
+	kzgSetupG2 = parsedSetup.SetupG2
+	kzgSetupLagrange = bitReversalPermutation(parsedSetup.SetupLagrange)
+	KzgSetupG1 = parsedSetup.SetupG1
+
+	initDomain()
+}
+
 // Convert polynomial in evaluation form to KZG commitment
 func BlobToKzg(eval []bls.Fr) *bls.G1Point {
 	return bls.LinCombG1(kzgSetupLagrange, eval)
@@ -99,73 +122,6 @@ func (batch *BlobsBatch) Verify() error {
 	return nil
 }
 
-// Verify that the list of `commitments` maps to the list of `blobs`
-//
-// This is an optimization over the naive approach (found in the EIP) of iteratively checking each blob against each
-// commitment.  The naive approach requires n*l scalar multiplications where `n` is the number of blobs and `l` is
-// FIELD_ELEMENTS_PER_BLOB to compute the commitments for all blobs.
-//
-// A more efficient approach is to build a linear combination of all blobs and commitments and check all of them in a
-// single multi-scalar multiplication.
-//
-// The MSM would look like this (for three blobs with two field elements each):
-//     r_0(b0_0*L_0 + b0_1*L_1) + r_1(b1_0*L_0 + b1_1*L_1) + r_2(b2_0*L_0 + b2_1*L_1)
-// which we would need to check against the linear combination of commitments: r_0*C_0 + r_1*C_1 + r_2*C_2
-// In the above, `r` are the random scalars of the linear combination, `b0` is the zero blob, `L` are the elements
-// of the KZG_SETUP_LAGRANGE and `C` are the commitments provided.
-//
-// By regrouping the above equation around the `L` points we can reduce the length of the MSM further
-// (down to just `n` scalar multiplications) by making it look like this:
-//     (r_0*b0_0 + r_1*b1_0 + r_2*b2_0) * L_0 + (r_0*b0_1 + r_1*b1_1 + r_2*b2_1) * L_1
-func VerifyBlobsLegacy(commitments []*bls.G1Point, blobs [][]bls.Fr) error {
-	// Prepare objects to hold our two MSMs
-	lPoints := make([]bls.G1Point, params.FieldElementsPerBlob)
-	lScalars := make([]bls.Fr, params.FieldElementsPerBlob)
-	rPoints := make([]bls.G1Point, len(commitments))
-	rScalars := make([]bls.Fr, len(commitments))
-
-	// Generate list of random scalars for lincomb
-	rList := make([]bls.Fr, len(blobs))
-	for i := 0; i < len(blobs); i++ {
-		bls.CopyFr(&rList[i], bls.RandomFr())
-	}
-
-	// Build left-side MSM:
-	//   (r_0*b0_0 + r_1*b1_0 + r_2*b2_0) * L_0 + (r_0*b0_1 + r_1*b1_1 + r_2*b2_1) * L_1
-	for c := 0; c < params.FieldElementsPerBlob; c++ {
-		var sum bls.Fr
-		for i := 0; i < len(blobs); i++ {
-			var tmp bls.Fr
-
-			r := rList[i]
-			blob := blobs[i]
-
-			bls.MulModFr(&tmp, &r, &blob[c])
-			bls.AddModFr(&sum, &sum, &tmp)
-		}
-		lScalars[c] = sum
-		lPoints[c] = kzgSetupLagrange[c]
-	}
-
-	// Build right-side MSM: r_0 * C_0 + r_1 * C_1 + r_2 * C_2 + ...
-	for i, commitment := range commitments {
-		rScalars[i] = rList[i]
-		rPoints[i] = *commitment
-	}
-
-	// Compute both MSMs and check equality
-	lResult := bls.LinCombG1(lPoints, lScalars)
-	rResult := bls.LinCombG1(rPoints, rScalars)
-	if !bls.EqualG1(lResult, rResult) {
-		return errors.New("VerifyBlobs failed")
-	}
-
-	// TODO: Potential improvement is to unify both MSMs into a single MSM, but you would need to batch-invert the `r`s
-	// of the right-side MSM to effectively pull them to the left side.
-
-	return nil
-}
-
 // Bit-reversal permutation helper functions
 
 // Check if `value` is a power of two integer.
@@ -239,26 +195,3 @@ func ComputeProof(eval []bls.Fr, z *bls.Fr) (*bls.G1Point, error) {
 	}
 	return bls.LinCombG1(kzgSetupLagrange, quotientPoly[:]), nil
 }
-
-type JSONTrustedSetup struct {
-	SetupG1       []bls.G1Point
-	SetupG2       []bls.G2Point
-	SetupLagrange []bls.G1Point
-}
-
-// Initialize KZG subsystem (load the trusted setup data)
-func init() {
-	var parsedSetup = JSONTrustedSetup{}
-
-	// TODO: This is dirty. KZG setup should be loaded using an actual config file directive
-	err := json.Unmarshal([]byte(KZGSetupStr), &parsedSetup)
-	if err != nil {
-		panic(err)
-	}
-
-	kzgSetupG2 = parsedSetup.SetupG2
-	kzgSetupLagrange = bitReversalPermutation(parsedSetup.SetupLagrange)
-	KzgSetupG1 = parsedSetup.SetupG1
-
-	initDomain()
-}
diff --git a/tests/kzg_bench_test.go b/tests/kzg_bench_test.go
index 3295d35fdc83..ecef998dead1 100644
--- a/tests/kzg_bench_test.go
+++ b/tests/kzg_bench_test.go
@@ -31,20 +31,6 @@ func BenchmarkBlobToKzg(b *testing.B) {
 	}
 }
 
-func BenchmarkVerifyBlobsWithoutKZGProof(b *testing.B) {
-	var blobs [][]bls.Fr
-	var commitments []*bls.G1Point
-	for i := 0; i < 16; i++ {
-		blob := randomBlob()
-		blobs = append(blobs, blob)
-		commitments = append(commitments, kzg.BlobToKzg(blob))
-	}
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		kzg.VerifyBlobsLegacy(commitments, blobs)
-	}
-}
-
 func BenchmarkVerifyBlobs(b *testing.B) {
 	blobs := make([]types.Blob, params.MaxBlobsPerBlock)
 	var commitments []types.KZGCommitment