Skip to content

Commit

Permalink
chore: revert minimal changes (#57)
Browse files Browse the repository at this point in the history
* Revert "chore: Make minimal config easier to run (#55)"

This reverts commit 689a7c3.

* Revert "feat: Add minimal configurations (#53)"

This reverts commit f8f4038.

* Revert "chore: Make Blob be variable size (#52)"

This reverts commit 5c8cf1a.
  • Loading branch information
kevaundray authored Oct 9, 2023
1 parent 689a7c3 commit 1f338ec
Show file tree
Hide file tree
Showing 15 changed files with 59 additions and 218 deletions.
42 changes: 9 additions & 33 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package gokzg4844

import (
"encoding/json"
"fmt"

"github.com/crate-crypto/go-kzg-4844/internal/kzg"
)
Expand Down Expand Up @@ -40,26 +39,28 @@ var PointAtInfinity = [48]byte{0xc0}
// methods. "4096" denotes that we will only be able to commit to polynomials with at most 4096 evaluations. "Insecure"
// denotes that this method should not be used in production since the secret (1337) is known.
func NewContext4096Insecure1337() (*Context, error) {
if MainnetScalarsPerBlob != 4096 {
if ScalarsPerBlob != 4096 {
// This is a library bug and so we panic.
panic("this method is named `NewContext4096Insecure1337` we expect SCALARS_PER_BLOB to be 4096")
}

parsedSetup := JSONTrustedSetup{}

err := json.Unmarshal([]byte(testMainnetKzgSetupStr), &parsedSetup)
err := json.Unmarshal([]byte(testKzgSetupStr), &parsedSetup)
if err != nil {
return nil, err
}

if MainnetScalarsPerBlob != len(parsedSetup.SetupG1) {
if ScalarsPerBlob != len(parsedSetup.SetupG1) {
// This is a library method and so we panic
panic("this method is named `NewContext4096Insecure1337` we expect the number of G1 elements in the trusted setup to be 4096")
}
return NewContext4096(&parsedSetup)
}

// NewContext creates a new context object which will hold the state needed for one to use the EIP-4844 methods.
// NewContext4096 creates a new context object which will hold the state needed for one to use the EIP-4844 methods. The
// 4096 represents the fact that without extra changes to the code, this context will only handle polynomials with 4096
// evaluations (degree 4095).
//
// Note: The G2 points do not have a fixed size. Technically, we could specify it to be 2, as this is the number of G2
// points that are required for KZG. However, the trusted setup in Ethereum has 65 since they want to use it for a
Expand All @@ -74,7 +75,7 @@ func NewContext4096Insecure1337() (*Context, error) {
// - Lagrange G1Points = {L_0(alpha^0) * G, L_1(alpha) * G, L_2(alpha^2) * G, ..., L_n(alpha^n) * G}
//
// [Full Danksharding]: https://notes.ethereum.org/@dankrad/new_sharding
func newContext(trustedSetup *JSONTrustedSetup, scalarsPerBlob uint64) (*Context, error) {
func NewContext4096(trustedSetup *JSONTrustedSetup) (*Context, error) {
// This should not happen for the ETH protocol
// However since it's a public method, we add the check.
if len(trustedSetup.SetupG2) < 2 {
Expand All @@ -87,15 +88,11 @@ func newContext(trustedSetup *JSONTrustedSetup, scalarsPerBlob uint64) (*Context
return nil, err
}

numG1Points := uint64(len(setupLagrangeG1Points))
if numG1Points != scalarsPerBlob {
return nil, fmt.Errorf("the number of G1 points in the trusted setup is %d whereas we expected %d", numG1Points, scalarsPerBlob)
}

// Get the generator points and the degree-1 element for G2 points
// The generators are the degree-0 elements in the trusted setup
//
// This will never panic as we checked the minimum SRS size is >= 2
// and `ScalarsPerBlob` is 4096
genG2 := setupG2Points[0]
alphaGenG2 := setupG2Points[1]

Expand All @@ -108,7 +105,7 @@ func newContext(trustedSetup *JSONTrustedSetup, scalarsPerBlob uint64) (*Context
AlphaG2: alphaGenG2,
}

domain := kzg.NewDomain(scalarsPerBlob)
domain := kzg.NewDomain(ScalarsPerBlob)
// Bit-Reverse the roots and the trusted setup according to the specs
// The bit reversal is not needed for simple KZG however it was
// implemented to make the step for full dank-sharding easier.
Expand All @@ -121,24 +118,3 @@ func newContext(trustedSetup *JSONTrustedSetup, scalarsPerBlob uint64) (*Context
openKey: &openingKey,
}, nil
}

// NewContext4096 creates a new context object which will hold the state needed for one to use the EIP-4844 methods on mainnet.
// The 4096 represents the fact that this context will only handle polynomials with 4096
// evaluations (degree 4095).
func NewContext4096(trustedSetup *JSONTrustedSetup) (*Context, error) {
return newContext(trustedSetup, MainnetScalarsPerBlob)
}

// NewContext4Insecure1337 creates a new context object which will hold the state needed for one to use the EIP-4844 methods using minimal configurations.
// The 4 represents the fact that this context will only handle polynomials with 4
// evaluations (degree 3).
// "Insecure" denotes that this method should not be used in production since the secret (1337) is known.
func NewContext4Insecure1337() (*Context, error) {
parsedSetup := JSONTrustedSetup{}

err := json.Unmarshal([]byte(testMinimalKzgSetupStr), &parsedSetup)
if err != nil {
return nil, err
}
return newContext(&parsedSetup, MinimalScalarsPerBlob)
}
6 changes: 3 additions & 3 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ func TestNonCanonicalScalar(t *testing.T) {
}

func TestNonCanonicalSmoke(t *testing.T) {
blobGood := GetRandMainnetBlob(123456789)
blobBad := GetRandMainnetBlob(123456789)
blobGood := GetRandBlob(123456789)
blobBad := GetRandBlob(123456789)
unreducedScalar := nonCanonicalScalar(123445)
modifyBlob(&blobBad, unreducedScalar, 0)

Expand Down Expand Up @@ -81,7 +81,7 @@ func TestNonCanonicalSmoke(t *testing.T) {
// Below are helper methods which allow us to change a serialized element into
// its non-canonical counterpart by adding the modulus
func modifyBlob(blob *gokzg4844.Blob, newValue gokzg4844.Scalar, index int) {
copy((*blob)[index:], newValue[:])
copy(blob[index:index+gokzg4844.SerializedScalarSize], newValue[:])
}

func nonCanonicalScalar(seed int64) gokzg4844.Scalar {
Expand Down
16 changes: 4 additions & 12 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,9 @@ func GetRandFieldElement(seed int64) [32]byte {
return gokzg4844.SerializeScalar(r)
}

func GetRandMainnetBlob(seed int64) gokzg4844.Blob {
return getRandBlob(seed, gokzg4844.MainnetScalarsPerBlob)
}

func GetRandMinimalBlob(seed int64) gokzg4844.Blob {
return getRandBlob(seed, gokzg4844.MinimalScalarsPerBlob)
}

func getRandBlob(seed int64, scalarsPerBlob int) gokzg4844.Blob {
bytesPerBlob := scalarsPerBlob * gokzg4844.SerializedScalarSize
blob := make(gokzg4844.Blob, bytesPerBlob)
func GetRandBlob(seed int64) gokzg4844.Blob {
var blob gokzg4844.Blob
bytesPerBlob := gokzg4844.ScalarsPerBlob * gokzg4844.SerializedScalarSize
for i := 0; i < bytesPerBlob; i += gokzg4844.SerializedScalarSize {
fieldElementBytes := GetRandFieldElement(seed + int64(i))
copy(blob[i:i+gokzg4844.SerializedScalarSize], fieldElementBytes[:])
Expand All @@ -53,7 +45,7 @@ func Benchmark(b *testing.B) {
fields := make([]gokzg4844.Scalar, length)

for i := 0; i < length; i++ {
blob := GetRandMainnetBlob(int64(i))
blob := GetRandBlob(int64(i))
commitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines)
require.NoError(b, err)
proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines)
Expand Down
11 changes: 6 additions & 5 deletions consensus_specs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,15 +356,16 @@ func TestVerifyBlobKZGProofBatch(t *testing.T) {
}

func hexStrToBlob(hexStr string) (gokzg4844.Blob, error) {
var blob gokzg4844.Blob
byts, err := hexStrToBytes(hexStr)
if err != nil {
return nil, err
return blob, err
}
if len(byts) != gokzg4844.MainnetNumBytesPerBlob {
return nil, fmt.Errorf("blob does not have the correct length, %d ", len(byts))

if len(blob) != len(byts) {
return blob, fmt.Errorf("blob does not have the correct length, %d ", len(byts))
}
blob := make(gokzg4844.Blob, len(byts))
copy(blob, byts)
copy(blob[:], byts)
return blob, nil
}

Expand Down
21 changes: 4 additions & 17 deletions examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@ import (
)

// Globally initialize a ctx for tests.
var (
ctx, _ = gokzg4844.NewContext4096Insecure1337()
ctxMinimal, _ = gokzg4844.NewContext4Insecure1337()
)
var ctx, _ = gokzg4844.NewContext4096Insecure1337()

func TestBlobProveVerifyRandomPointIntegration(t *testing.T) {
blob := GetRandMainnetBlob(123)
blob := GetRandBlob(123)
commitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines)
require.NoError(t, err)
proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines)
Expand All @@ -23,18 +20,8 @@ func TestBlobProveVerifyRandomPointIntegration(t *testing.T) {
require.NoError(t, err)
}

func TestBlobProveVerifyRandomPointIntegrationMinimal(t *testing.T) {
blob := GetRandMinimalBlob(123)
commitment, err := ctxMinimal.BlobToKZGCommitment(blob, NumGoRoutines)
require.NoError(t, err)
proof, err := ctxMinimal.ComputeBlobKZGProof(blob, commitment, NumGoRoutines)
require.NoError(t, err)
err = ctxMinimal.VerifyBlobKZGProof(blob, commitment, proof)
require.NoError(t, err)
}

func TestBlobProveVerifySpecifiedPointIntegration(t *testing.T) {
blob := GetRandMainnetBlob(123)
blob := GetRandBlob(123)
commitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines)
require.NoError(t, err)
inputPoint := GetRandFieldElement(123)
Expand All @@ -51,7 +38,7 @@ func TestBlobProveVerifyBatchIntegration(t *testing.T) {
proofs := make([]gokzg4844.KZGProof, batchSize)

for i := 0; i < batchSize; i++ {
blob := GetRandMainnetBlob(int64(i))
blob := GetRandBlob(int64(i))
commitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines)
require.NoError(t, err)
proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines)
Expand Down
4 changes: 2 additions & 2 deletions fiatshamir.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const DomSepProtocol = "FSBLOBVERIFY_V1_"
// computeChallenge is provided to match the spec at [compute_challenge].
//
// [compute_challenge]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#compute_challenge
func computeChallenge(blob Blob, commitment KZGCommitment, scalarsPerBlob uint64) fr.Element {
polyDegreeBytes := u64ToByteArray16(scalarsPerBlob)
func computeChallenge(blob Blob, commitment KZGCommitment) fr.Element {
polyDegreeBytes := u64ToByteArray16(ScalarsPerBlob)
data := append([]byte(DomSepProtocol), polyDegreeBytes...)
data = append(data, blob[:]...)
data = append(data, commitment[:]...)
Expand Down
4 changes: 2 additions & 2 deletions fiatshamir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (
// If the way computeChallenge is computed is updated
// then this test will fail
func TestComputeChallengeInterop(t *testing.T) {
blob := make(Blob, 4096*32)
blob := Blob{}
commitment := SerializeG1Point(bls12381.G1Affine{})
challenge := computeChallenge(blob, KZGCommitment(commitment), 4096)
challenge := computeChallenge(blob, KZGCommitment(commitment))
expected := []byte{
0x04, 0xb7, 0xb2, 0x2a, 0xf6, 0x3d, 0x2b, 0x2f,
0x1c, 0xed, 0x8d, 0x55, 0x05, 0x60, 0xe5, 0xd1,
Expand Down
9 changes: 4 additions & 5 deletions prove.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func (c *Context) BlobToKZGCommitment(blob Blob, numGoRoutines int) (KZGCommitme
// 1. Deserialization
//
// Deserialize blob into polynomial
polynomial, err := DeserializeBlob(blob, c.domain.Cardinality)
polynomial, err := DeserializeBlob(blob)
if err != nil {
return KZGCommitment{}, err
}
Expand Down Expand Up @@ -46,7 +46,7 @@ func (c *Context) BlobToKZGCommitment(blob Blob, numGoRoutines int) (KZGCommitme
func (c *Context) ComputeBlobKZGProof(blob Blob, blobCommitment KZGCommitment, numGoRoutines int) (KZGProof, error) {
// 1. Deserialization
//
polynomial, err := DeserializeBlob(blob, c.domain.Cardinality)
polynomial, err := DeserializeBlob(blob)
if err != nil {
return KZGProof{}, err
}
Expand All @@ -60,8 +60,7 @@ func (c *Context) ComputeBlobKZGProof(blob Blob, blobCommitment KZGCommitment, n
}

// 2. Compute Fiat-Shamir challenge
blobDegree := uint64(len(c.domain.Roots))
evaluationChallenge := computeChallenge(blob, blobCommitment, blobDegree)
evaluationChallenge := computeChallenge(blob, blobCommitment)

// 3. Create opening proof
openingProof, err := kzg.Open(c.domain, polynomial, evaluationChallenge, c.commitKey, numGoRoutines)
Expand All @@ -86,7 +85,7 @@ func (c *Context) ComputeBlobKZGProof(blob Blob, blobCommitment KZGCommitment, n
func (c *Context) ComputeKZGProof(blob Blob, inputPointBytes Scalar, numGoRoutines int) (KZGProof, Scalar, error) {
// 1. Deserialization
//
polynomial, err := DeserializeBlob(blob, c.domain.Cardinality)
polynomial, err := DeserializeBlob(blob)
if err != nil {
return KZGProof{}, [32]byte{}, err
}
Expand Down
32 changes: 9 additions & 23 deletions serialization.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const CompressedG2Size = 96
// [BYTES_PER_FIELD_ELEMENT]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#constants
const SerializedScalarSize = 32

// MainnetScalarsPerBlob is the number of serialized scalars in a blob for mainnet.
// ScalarsPerBlob is the number of serialized scalars in a blob.
//
// It matches [FIELD_ELEMENTS_PER_BLOB] in the spec.
//
Expand All @@ -30,18 +30,7 @@ const SerializedScalarSize = 32
//
// [BLS_MODULUS]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#constants
// [FIELD_ELEMENTS_PER_BLOB]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#blob
const MainnetScalarsPerBlob = 4096

// The number of bytes needed to represent a blob on mainnet.
const MainnetNumBytesPerBlob = MainnetScalarsPerBlob * SerializedScalarSize

// MinimalScalarsPerBlob is the number of serialized scalars in a blob for what is known as
// minimal configuration. This configuration is used for testing, prototyping and in some
// consumers, end to end tests.
const MinimalScalarsPerBlob = 4

// The number of bytes needed to represent a blob using minimal configurations.
const MinimalNumBytesPerBlob = MainnetScalarsPerBlob * SerializedScalarSize
const ScalarsPerBlob = 4096

type (
// G1Point matches [G1Point] in the spec.
Expand All @@ -61,12 +50,10 @@ type (

// Blob is a flattened representation of a serialized polynomial.
//
// Note: A blob in the specifications is a fixed size array.
// This datatype does not have a fixed size as we want to support
// two different sizes of Blobs.
// It matches [Blob] in the spec.
//
// [Blob]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#custom-types
Blob []byte
Blob [ScalarsPerBlob * SerializedScalarSize]byte

// KZGProof is a serialized commitment to the quotient polynomial.
//
Expand Down Expand Up @@ -120,9 +107,9 @@ func DeserializeKZGProof(proof KZGProof) (bls12381.G1Affine, error) {
// DeserializeBlob implements [blob_to_polynomial].
//
// [blob_to_polynomial]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#blob_to_polynomial
func DeserializeBlob(blob Blob, scalarsPerBlob uint64) (kzg.Polynomial, error) {
poly := make(kzg.Polynomial, int(scalarsPerBlob))
for i := 0; i < int(scalarsPerBlob); i++ {
func DeserializeBlob(blob Blob) (kzg.Polynomial, error) {
poly := make(kzg.Polynomial, ScalarsPerBlob)
for i := 0; i < ScalarsPerBlob; i++ {
chunk := blob[i*SerializedScalarSize : (i+1)*SerializedScalarSize]
serScalar := (*Scalar)(chunk)
scalar, err := DeserializeScalar(*serScalar)
Expand Down Expand Up @@ -157,9 +144,8 @@ func SerializeScalar(element fr.Element) Scalar {
// Note: This method is never used in the API because we always expect a byte array and will never receive deserialized
// field elements. We include it so that upstream fuzzers do not need to reimplement it.
func SerializePoly(poly kzg.Polynomial) Blob {
scalarsPerBlob := len(poly)
blob := make(Blob, scalarsPerBlob*SerializedScalarSize)
for i := 0; i < scalarsPerBlob; i++ {
var blob Blob
for i := 0; i < ScalarsPerBlob; i++ {
chunk := blob[i*SerializedScalarSize : (i+1)*SerializedScalarSize]
serScalar := SerializeScalar(poly[i])
copy(chunk, serScalar[:])
Expand Down
7 changes: 4 additions & 3 deletions serialization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ func TestSerializePolyNotZero(t *testing.T) {

poly := randPoly4096()
blob := gokzg4844.SerializePoly(poly)
zeroBlob := make(gokzg4844.Blob, len(blob))

var zeroBlob gokzg4844.Blob
if bytes.Equal(blob[:], zeroBlob[:]) {
t.Error("blobs are all zeroes, which can only happen with negligible probability")
}
Expand All @@ -43,11 +44,11 @@ func TestSerializePolyRoundTrip(t *testing.T) {
blobA := gokzg4844.SerializePoly(expectedPolyA)
blobB := gokzg4844.SerializePoly(expectedPolyB)

gotPolyA, err := gokzg4844.DeserializeBlob(blobA, 4096)
gotPolyA, err := gokzg4844.DeserializeBlob(blobA)
if err != nil {
t.Error(err)
}
gotPolyB, err := gokzg4844.DeserializeBlob(blobB, 4096)
gotPolyB, err := gokzg4844.DeserializeBlob(blobB)
if err != nil {
t.Error(err)
}
Expand Down
Loading

0 comments on commit 1f338ec

Please sign in to comment.