mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-06 22:23:56 -05:00
* Ran gopls modernize to fix everything go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./... * Override rules_go provided dependency for golang.org/x/tools to v0.38.0. To update this, checked out rules_go, then ran `bazel run //go/tools/releaser -- upgrade-dep -mirror=false org_golang_x_tools` and copied the patches. * Fix buildtag violations and ignore buildtag violations in external * Introduce modernize analyzer package. * Add modernize "any" analyzer. * Fix violations of any analyzer * Add modernize "appendclipped" analyzer. * Fix violations of appendclipped * Add modernize "bloop" analyzer. * Add modernize "fmtappendf" analyzer. * Add modernize "forvar" analyzer. * Add modernize "mapsloop" analyzer. * Add modernize "minmax" analyzer. * Fix violations of minmax analyzer * Add modernize "omitzero" analyzer. * Add modernize "rangeint" analyzer. * Fix violations of rangeint. * Add modernize "reflecttypefor" analyzer. * Fix violations of reflecttypefor analyzer. * Add modernize "slicescontains" analyzer. * Add modernize "slicessort" analyzer. * Add modernize "slicesdelete" analyzer. This is disabled by default for now. See https://go.dev/issue/73686. * Add modernize "stringscutprefix" analyzer. * Add modernize "stringsbuilder" analyzer. * Fix violations of stringsbuilder analyzer. * Add modernize "stringsseq" analyzer. * Add modernize "testingcontext" analyzer. * Add modernize "waitgroup" analyzer. * Changelog fragment * gofmt * gazelle * Add modernize "newexpr" analyzer. * Disable newexpr until go1.26 * Add more details in WORKSPACE on how to update the override * @nalepae feedback on min() * gofmt * Fix violations of forvar
478 lines
15 KiB
Go
478 lines
15 KiB
Go
package kzg
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/blocks"
|
|
"github.com/OffchainLabs/prysm/v7/crypto/random"
|
|
"github.com/OffchainLabs/prysm/v7/testing/require"
|
|
GoKZG "github.com/crate-crypto/go-kzg-4844"
|
|
)
|
|
|
|
func GenerateCommitmentAndProof(blob GoKZG.Blob) (GoKZG.KZGCommitment, GoKZG.KZGProof, error) {
|
|
commitment, err := kzgContext.BlobToKZGCommitment(&blob, 0)
|
|
if err != nil {
|
|
return GoKZG.KZGCommitment{}, GoKZG.KZGProof{}, err
|
|
}
|
|
proof, err := kzgContext.ComputeBlobKZGProof(&blob, commitment, 0)
|
|
if err != nil {
|
|
return GoKZG.KZGCommitment{}, GoKZG.KZGProof{}, err
|
|
}
|
|
return commitment, proof, err
|
|
}
|
|
|
|
func TestVerify(t *testing.T) {
|
|
blobSidecars := make([]blocks.ROBlob, 0)
|
|
require.NoError(t, Verify(blobSidecars...))
|
|
}
|
|
|
|
func TestBytesToAny(t *testing.T) {
|
|
bytes := []byte{0x01, 0x02}
|
|
blob := GoKZG.Blob{0x01, 0x02}
|
|
commitment := GoKZG.KZGCommitment{0x01, 0x02}
|
|
proof := GoKZG.KZGProof{0x01, 0x02}
|
|
require.DeepEqual(t, blob, *bytesToBlob(bytes))
|
|
require.DeepEqual(t, commitment, bytesToCommitment(bytes))
|
|
require.DeepEqual(t, proof, bytesToKZGProof(bytes))
|
|
}
|
|
|
|
func TestGenerateCommitmentAndProof(t *testing.T) {
|
|
require.NoError(t, Start())
|
|
blob := random.GetRandBlob(123)
|
|
commitment, proof, err := GenerateCommitmentAndProof(blob)
|
|
require.NoError(t, err)
|
|
expectedCommitment := GoKZG.KZGCommitment{180, 218, 156, 194, 59, 20, 10, 189, 186, 254, 132, 93, 7, 127, 104, 172, 238, 240, 237, 70, 83, 89, 1, 152, 99, 0, 165, 65, 143, 62, 20, 215, 230, 14, 205, 95, 28, 245, 54, 25, 160, 16, 178, 31, 232, 207, 38, 85}
|
|
expectedProof := GoKZG.KZGProof{128, 110, 116, 170, 56, 111, 126, 87, 229, 234, 211, 42, 110, 150, 129, 206, 73, 142, 167, 243, 90, 149, 240, 240, 236, 204, 143, 182, 229, 249, 81, 27, 153, 171, 83, 70, 144, 250, 42, 1, 188, 215, 71, 235, 30, 7, 175, 86}
|
|
require.Equal(t, expectedCommitment, commitment)
|
|
require.Equal(t, expectedProof, proof)
|
|
}
|
|
|
|
func TestVerifyBlobKZGProofBatch(t *testing.T) {
|
|
// Initialize KZG for testing
|
|
require.NoError(t, Start())
|
|
|
|
t.Run("valid single blob batch", func(t *testing.T) {
|
|
blob := random.GetRandBlob(123)
|
|
commitment, proof, err := GenerateCommitmentAndProof(blob)
|
|
require.NoError(t, err)
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{commitment[:]}
|
|
proofs := [][]byte{proof[:]}
|
|
|
|
err = VerifyBlobKZGProofBatch(blobs, commitments, proofs)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("valid multiple blob batch", func(t *testing.T) {
|
|
blobCount := 3
|
|
blobs := make([][]byte, blobCount)
|
|
commitments := make([][]byte, blobCount)
|
|
proofs := make([][]byte, blobCount)
|
|
|
|
for i := range blobCount {
|
|
blob := random.GetRandBlob(int64(i))
|
|
commitment, proof, err := GenerateCommitmentAndProof(blob)
|
|
require.NoError(t, err)
|
|
|
|
blobs[i] = blob[:]
|
|
commitments[i] = commitment[:]
|
|
proofs[i] = proof[:]
|
|
}
|
|
|
|
err := VerifyBlobKZGProofBatch(blobs, commitments, proofs)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("empty inputs should pass", func(t *testing.T) {
|
|
err := VerifyBlobKZGProofBatch([][]byte{}, [][]byte{}, [][]byte{})
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("mismatched input lengths", func(t *testing.T) {
|
|
blob := random.GetRandBlob(123)
|
|
commitment, proof, err := GenerateCommitmentAndProof(blob)
|
|
require.NoError(t, err)
|
|
|
|
// Test different mismatch scenarios
|
|
err = VerifyBlobKZGProofBatch(
|
|
[][]byte{blob[:]},
|
|
[][]byte{},
|
|
[][]byte{proof[:]},
|
|
)
|
|
require.ErrorContains(t, "number of blobs (1), commitments (0), and proofs (1) must match", err)
|
|
|
|
err = VerifyBlobKZGProofBatch(
|
|
[][]byte{blob[:], blob[:]},
|
|
[][]byte{commitment[:]},
|
|
[][]byte{proof[:], proof[:]},
|
|
)
|
|
require.ErrorContains(t, "number of blobs (2), commitments (1), and proofs (2) must match", err)
|
|
})
|
|
|
|
t.Run("invalid commitment should fail", func(t *testing.T) {
|
|
blob := random.GetRandBlob(123)
|
|
_, proof, err := GenerateCommitmentAndProof(blob)
|
|
require.NoError(t, err)
|
|
|
|
// Use a different blob's commitment (mismatch)
|
|
differentBlob := random.GetRandBlob(456)
|
|
wrongCommitment, _, err := GenerateCommitmentAndProof(differentBlob)
|
|
require.NoError(t, err)
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{wrongCommitment[:]}
|
|
proofs := [][]byte{proof[:]}
|
|
|
|
err = VerifyBlobKZGProofBatch(blobs, commitments, proofs)
|
|
// Single blob optimization uses different error message
|
|
require.ErrorContains(t, "can't verify opening proof", err)
|
|
})
|
|
|
|
t.Run("invalid proof should fail", func(t *testing.T) {
|
|
blob := random.GetRandBlob(123)
|
|
commitment, _, err := GenerateCommitmentAndProof(blob)
|
|
require.NoError(t, err)
|
|
|
|
// Use wrong proof
|
|
invalidProof := make([]byte, 48) // All zeros
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{commitment[:]}
|
|
proofs := [][]byte{invalidProof}
|
|
|
|
err = VerifyBlobKZGProofBatch(blobs, commitments, proofs)
|
|
require.ErrorContains(t, "short buffer", err)
|
|
})
|
|
|
|
t.Run("mixed valid and invalid proofs should fail", func(t *testing.T) {
|
|
// First blob - valid
|
|
blob1 := random.GetRandBlob(123)
|
|
commitment1, proof1, err := GenerateCommitmentAndProof(blob1)
|
|
require.NoError(t, err)
|
|
|
|
// Second blob - invalid proof
|
|
blob2 := random.GetRandBlob(456)
|
|
commitment2, _, err := GenerateCommitmentAndProof(blob2)
|
|
require.NoError(t, err)
|
|
invalidProof := make([]byte, 48) // All zeros
|
|
|
|
blobs := [][]byte{blob1[:], blob2[:]}
|
|
commitments := [][]byte{commitment1[:], commitment2[:]}
|
|
proofs := [][]byte{proof1[:], invalidProof}
|
|
|
|
err = VerifyBlobKZGProofBatch(blobs, commitments, proofs)
|
|
require.ErrorContains(t, "batch verification", err)
|
|
})
|
|
|
|
t.Run("batch KZG proof verification failed", func(t *testing.T) {
|
|
// Create multiple blobs with mismatched commitments and proofs to trigger batch verification failure
|
|
blob1 := random.GetRandBlob(123)
|
|
blob2 := random.GetRandBlob(456)
|
|
|
|
// Generate valid proof for blob1
|
|
commitment1, proof1, err := GenerateCommitmentAndProof(blob1)
|
|
require.NoError(t, err)
|
|
|
|
// Generate valid proof for blob2 but use wrong commitment (from blob1)
|
|
_, proof2, err := GenerateCommitmentAndProof(blob2)
|
|
require.NoError(t, err)
|
|
|
|
// Use blob2 data with blob1's commitment and blob2's proof - this should cause batch verification to fail
|
|
blobs := [][]byte{blob1[:], blob2[:]}
|
|
commitments := [][]byte{commitment1[:], commitment1[:]} // Wrong commitment for blob2
|
|
proofs := [][]byte{proof1[:], proof2[:]}
|
|
|
|
err = VerifyBlobKZGProofBatch(blobs, commitments, proofs)
|
|
require.ErrorContains(t, "batch KZG proof verification failed", err)
|
|
})
|
|
}
|
|
|
|
func TestVerifyCellKZGProofBatchFromBlobData(t *testing.T) {
|
|
// Initialize KZG for testing
|
|
require.NoError(t, Start())
|
|
|
|
t.Run("valid single blob cell verification", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
|
|
// Generate blob and commitment
|
|
randBlob := random.GetRandBlob(123)
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
commitment, err := BlobToKZGCommitment(&blob)
|
|
require.NoError(t, err)
|
|
|
|
// Compute cells and proofs
|
|
_, proofs, err := ComputeCellsAndKZGProofs(&blob)
|
|
require.NoError(t, err)
|
|
|
|
// Create flattened cell proofs (like execution client format)
|
|
cellProofs := make([][]byte, numberOfColumns)
|
|
for i := range numberOfColumns {
|
|
cellProofs[i] = proofs[i][:]
|
|
}
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{commitment[:]}
|
|
|
|
err = VerifyCellKZGProofBatchFromBlobData(blobs, commitments, cellProofs, numberOfColumns)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("valid multiple blob cell verification", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
blobCount := 2
|
|
|
|
blobs := make([][]byte, blobCount)
|
|
commitments := make([][]byte, blobCount)
|
|
var allCellProofs [][]byte
|
|
|
|
for i := range blobCount {
|
|
// Generate blob and commitment
|
|
randBlob := random.GetRandBlob(int64(i))
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
commitment, err := BlobToKZGCommitment(&blob)
|
|
require.NoError(t, err)
|
|
|
|
// Compute cells and proofs
|
|
_, proofs, err := ComputeCellsAndKZGProofs(&blob)
|
|
require.NoError(t, err)
|
|
|
|
blobs[i] = blob[:]
|
|
commitments[i] = commitment[:]
|
|
|
|
// Add cell proofs for this blob
|
|
for j := range numberOfColumns {
|
|
allCellProofs = append(allCellProofs, proofs[j][:])
|
|
}
|
|
}
|
|
|
|
err := VerifyCellKZGProofBatchFromBlobData(blobs, commitments, allCellProofs, numberOfColumns)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("empty inputs should pass", func(t *testing.T) {
|
|
err := VerifyCellKZGProofBatchFromBlobData([][]byte{}, [][]byte{}, [][]byte{}, 128)
|
|
require.NoError(t, err)
|
|
})
|
|
|
|
t.Run("mismatched blob and commitment count", func(t *testing.T) {
|
|
randBlob := random.GetRandBlob(123)
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
|
|
err := VerifyCellKZGProofBatchFromBlobData(
|
|
[][]byte{blob[:]},
|
|
[][]byte{}, // Empty commitments
|
|
[][]byte{},
|
|
128,
|
|
)
|
|
require.ErrorContains(t, "expected 128 cell proofs", err)
|
|
})
|
|
|
|
t.Run("wrong cell proof count", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
|
|
randBlob := random.GetRandBlob(123)
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
commitment, err := BlobToKZGCommitment(&blob)
|
|
require.NoError(t, err)
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{commitment[:]}
|
|
|
|
// Wrong number of cell proofs - should be 128 for 1 blob, but provide 10
|
|
wrongCellProofs := make([][]byte, 10)
|
|
|
|
err = VerifyCellKZGProofBatchFromBlobData(blobs, commitments, wrongCellProofs, numberOfColumns)
|
|
require.ErrorContains(t, "expected 128 cell proofs, got 10", err)
|
|
})
|
|
|
|
t.Run("invalid cell proofs should fail", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
|
|
randBlob := random.GetRandBlob(123)
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
commitment, err := BlobToKZGCommitment(&blob)
|
|
require.NoError(t, err)
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{commitment[:]}
|
|
|
|
// Create invalid cell proofs (all zeros)
|
|
invalidCellProofs := make([][]byte, numberOfColumns)
|
|
for i := range numberOfColumns {
|
|
invalidCellProofs[i] = make([]byte, 48) // All zeros
|
|
}
|
|
|
|
err = VerifyCellKZGProofBatchFromBlobData(blobs, commitments, invalidCellProofs, numberOfColumns)
|
|
require.ErrorContains(t, "cell batch verification", err)
|
|
})
|
|
|
|
t.Run("mismatched commitment should fail", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
|
|
// Generate blob and correct cell proofs
|
|
randBlob := random.GetRandBlob(123)
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
_, proofs, err := ComputeCellsAndKZGProofs(&blob)
|
|
require.NoError(t, err)
|
|
|
|
// Generate wrong commitment from different blob
|
|
randBlob2 := random.GetRandBlob(456)
|
|
var differentBlob Blob
|
|
copy(differentBlob[:], randBlob2[:])
|
|
wrongCommitment, err := BlobToKZGCommitment(&differentBlob)
|
|
require.NoError(t, err)
|
|
|
|
cellProofs := make([][]byte, numberOfColumns)
|
|
for i := range numberOfColumns {
|
|
cellProofs[i] = proofs[i][:]
|
|
}
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{wrongCommitment[:]}
|
|
|
|
err = VerifyCellKZGProofBatchFromBlobData(blobs, commitments, cellProofs, numberOfColumns)
|
|
require.ErrorContains(t, "cell KZG proof batch verification failed", err)
|
|
})
|
|
|
|
t.Run("invalid blob data that should cause ComputeCells to fail", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
|
|
// Create invalid blob (not properly formatted)
|
|
invalidBlobData := make([]byte, 10) // Too short
|
|
commitment := make([]byte, 48) // Dummy commitment
|
|
cellProofs := make([][]byte, numberOfColumns)
|
|
for i := range numberOfColumns {
|
|
cellProofs[i] = make([]byte, 48)
|
|
}
|
|
|
|
blobs := [][]byte{invalidBlobData}
|
|
commitments := [][]byte{commitment}
|
|
|
|
err := VerifyCellKZGProofBatchFromBlobData(blobs, commitments, cellProofs, numberOfColumns)
|
|
require.NotNil(t, err)
|
|
require.ErrorContains(t, "blobs len (10) differs from expected (131072)", err)
|
|
})
|
|
|
|
t.Run("invalid commitment size should fail", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
|
|
randBlob := random.GetRandBlob(123)
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
|
|
// Create invalid commitment (wrong size)
|
|
invalidCommitment := make([]byte, 32) // Should be 48 bytes
|
|
cellProofs := make([][]byte, numberOfColumns)
|
|
for i := range numberOfColumns {
|
|
cellProofs[i] = make([]byte, 48)
|
|
}
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{invalidCommitment}
|
|
|
|
err := VerifyCellKZGProofBatchFromBlobData(blobs, commitments, cellProofs, numberOfColumns)
|
|
require.ErrorContains(t, "commitments len (32) differs from expected (48)", err)
|
|
})
|
|
|
|
t.Run("invalid cell proof size should fail", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
|
|
randBlob := random.GetRandBlob(123)
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
commitment, err := BlobToKZGCommitment(&blob)
|
|
require.NoError(t, err)
|
|
|
|
// Create invalid cell proofs (wrong size)
|
|
invalidCellProofs := make([][]byte, numberOfColumns)
|
|
for i := range numberOfColumns {
|
|
if i == 0 {
|
|
invalidCellProofs[i] = make([]byte, 32) // Wrong size - should be 48
|
|
} else {
|
|
invalidCellProofs[i] = make([]byte, 48)
|
|
}
|
|
}
|
|
|
|
blobs := [][]byte{blob[:]}
|
|
commitments := [][]byte{commitment[:]}
|
|
|
|
err = VerifyCellKZGProofBatchFromBlobData(blobs, commitments, invalidCellProofs, numberOfColumns)
|
|
require.ErrorContains(t, "proofs len (32) differs from expected (48)", err)
|
|
})
|
|
|
|
t.Run("multiple blobs with mixed invalid commitments", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
blobCount := 2
|
|
|
|
blobs := make([][]byte, blobCount)
|
|
commitments := make([][]byte, blobCount)
|
|
var allCellProofs [][]byte
|
|
|
|
// First blob - valid
|
|
randBlob1 := random.GetRandBlob(123)
|
|
var blob1 Blob
|
|
copy(blob1[:], randBlob1[:])
|
|
commitment1, err := BlobToKZGCommitment(&blob1)
|
|
require.NoError(t, err)
|
|
blobs[0] = blob1[:]
|
|
commitments[0] = commitment1[:]
|
|
|
|
// Second blob - use invalid commitment size
|
|
randBlob2 := random.GetRandBlob(456)
|
|
var blob2 Blob
|
|
copy(blob2[:], randBlob2[:])
|
|
blobs[1] = blob2[:]
|
|
commitments[1] = make([]byte, 32) // Wrong size
|
|
|
|
// Add cell proofs for both blobs
|
|
for range blobCount {
|
|
for range numberOfColumns {
|
|
allCellProofs = append(allCellProofs, make([]byte, 48))
|
|
}
|
|
}
|
|
|
|
err = VerifyCellKZGProofBatchFromBlobData(blobs, commitments, allCellProofs, numberOfColumns)
|
|
require.ErrorContains(t, "commitments len (32) differs from expected (48)", err)
|
|
})
|
|
|
|
t.Run("multiple blobs with mixed invalid cell proof sizes", func(t *testing.T) {
|
|
numberOfColumns := uint64(128)
|
|
blobCount := 2
|
|
|
|
blobs := make([][]byte, blobCount)
|
|
commitments := make([][]byte, blobCount)
|
|
var allCellProofs [][]byte
|
|
|
|
for i := range blobCount {
|
|
randBlob := random.GetRandBlob(int64(i))
|
|
var blob Blob
|
|
copy(blob[:], randBlob[:])
|
|
commitment, err := BlobToKZGCommitment(&blob)
|
|
require.NoError(t, err)
|
|
|
|
blobs[i] = blob[:]
|
|
commitments[i] = commitment[:]
|
|
|
|
// Add cell proofs - make some invalid in the second blob
|
|
for j := range numberOfColumns {
|
|
if i == 1 && j == 64 {
|
|
// Invalid proof size in middle of second blob's proofs
|
|
allCellProofs = append(allCellProofs, make([]byte, 20))
|
|
} else {
|
|
allCellProofs = append(allCellProofs, make([]byte, 48))
|
|
}
|
|
}
|
|
}
|
|
|
|
err := VerifyCellKZGProofBatchFromBlobData(blobs, commitments, allCellProofs, numberOfColumns)
|
|
require.ErrorContains(t, "proofs len (20) differs from expected (48)", err)
|
|
})
|
|
}
|