diff --git a/ecc/bls12-377/fr/polynomial/kzg/doc.go b/ecc/bls12-377/fr/kzg/doc.go similarity index 100% rename from ecc/bls12-377/fr/polynomial/kzg/doc.go rename to ecc/bls12-377/fr/kzg/doc.go diff --git a/ecc/bls12-377/fr/polynomial/kzg/fuzz.go b/ecc/bls12-377/fr/kzg/fuzz.go similarity index 77% rename from ecc/bls12-377/fr/polynomial/kzg/fuzz.go rename to ecc/bls12-377/fr/kzg/fuzz.go index 0b33dd550..8a3eb2715 100644 --- a/ecc/bls12-377/fr/polynomial/kzg/fuzz.go +++ b/ecc/bls12-377/fr/kzg/fuzz.go @@ -21,8 +21,7 @@ package kzg import ( "bytes" "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" - bls12377_pol "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" ) const ( @@ -48,15 +47,14 @@ func Fuzz(data []byte) int { // create polynomials f := make([]polynomial.Polynomial, size/2) for i := 0; i < len(f); i++ { - _f := make(bls12377_pol.Polynomial, size) - for j := 0; j < len(_f); j++ { - _f[j].SetRawBytes(r) + f[i] = make(polynomial.Polynomial, size) + for j := 0; j < len(f[i]); j++ { + f[i][j].SetRawBytes(r) } - f[i] = &_f } // commit the polynomials - digests := make([]polynomial.Digest, size/2) + digests := make([]Digest, size/2) for i := 0; i < len(digests); i++ { digests[i], _ = s.Commit(f[i]) @@ -68,16 +66,15 @@ func Fuzz(data []byte) int { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < len(f); i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { panic("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { panic(err) } diff --git a/ecc/bls12-377/fr/polynomial/kzg/fuzz_test.go b/ecc/bls12-377/fr/kzg/fuzz_test.go similarity index 100% rename from ecc/bls12-377/fr/polynomial/kzg/fuzz_test.go rename to ecc/bls12-377/fr/kzg/fuzz_test.go diff --git a/ecc/bls12-377/fr/polynomial/kzg/kzg.go b/ecc/bls12-377/fr/kzg/kzg.go similarity index 61% rename from ecc/bls12-377/fr/polynomial/kzg/kzg.go rename to ecc/bls12-377/fr/kzg/kzg.go index c4d007521..4d1acdebd 100644 --- a/ecc/bls12-377/fr/polynomial/kzg/kzg.go +++ b/ecc/bls12-377/fr/kzg/kzg.go @@ -20,69 +20,56 @@ import ( "errors" "io" "math/big" + "math/bits" "github.com/consensys/gnark-crypto/ecc/bls12-377" "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/fft" - bls12377_pol "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" - fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" + "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" + "github.com/consensys/gnark-crypto/fiat-shamir" "github.com/consensys/gnark-crypto/internal/parallel" - "github.com/consensys/gnark-crypto/polynomial" ) var ( - errNbDigestsNeqNbPolynomials = errors.New("number of digests is not the same as the number of polynomials") - errUnsupportedSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") - errDigestNotInG1 = errors.New("the digest is not in G1") - errProofNotInG1 = errors.New("the proof is not in G1") + ErrInvalidNbDigests = errors.New("number of digests is not the same as the number of polynomials") + ErrInvalidSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") + ErrVerifyOpeningProof = errors.New("can't verify opening proof") + ErrVerifyBatchOpeningSinglePoint = errors.New("can't verify batch opening proof at single point") ) -// Digest commitment of a polynomial +// Digest commitment of a polynomial. type Digest = bls12377.G1Affine // Scheme stores KZG data type Scheme struct { - // Domain to perform polynomial division. The size of the domain is the lowest power of 2 greater than Size. - Domain fft.Domain + Domain *fft.Domain // SRS stores the result of the MPC - SRS struct { - G1 []bls12377.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] - G2 [2]bls12377.G2Affine // [gen, [alpha]gen ] - } + SRS *SRS } -// Proof KZG proof for opening at a single point. -type Proof struct { - - // Point at which the polynomial is evaluated - Point fr.Element - - // ClaimedValue purported value - ClaimedValue fr.Element - - // H quotient polynomial (f - f(z))/(x-z) - H bls12377.G1Affine +// SRS stores the result of the MPC +// len(SRS.G1) can be larger than domain size +type SRS struct { + G1 []bls12377.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] + G2 [2]bls12377.G2Affine // [gen, [alpha]gen ] } -// NewScheme returns a new KZG scheme. -// This should be used for testing purpose only. -func NewScheme(size int, alpha fr.Element) *Scheme { - - s := &Scheme{} - - d := fft.NewDomain(uint64(size), 0, false) - s.Domain = *d - s.SRS.G1 = make([]bls12377.G1Affine, size) +// NewSRS returns a new SRS using alpha as randomness source +// +// In production, a SRS generated through MPC should be used. +func NewSRS(size int, bAlpha *big.Int) *SRS { + var srs SRS + srs.G1 = make([]bls12377.G1Affine, size) - var bAlpha big.Int - alpha.ToBigIntRegular(&bAlpha) + var alpha fr.Element + alpha.SetBigInt(bAlpha) _, _, gen1Aff, gen2Aff := bls12377.Generators() - s.SRS.G1[0] = gen1Aff - s.SRS.G2[0] = gen2Aff - s.SRS.G2[1].ScalarMultiplication(&gen2Aff, &bAlpha) + srs.G1[0] = gen1Aff + srs.G2[0] = gen2Aff + srs.G2[1].ScalarMultiplication(&gen2Aff, bAlpha) alphas := make([]fr.Element, size-1) alphas[0] = alpha @@ -93,9 +80,22 @@ func NewScheme(size int, alpha fr.Element) *Scheme { alphas[i].FromMont() } g1s := bls12377.BatchScalarMultiplicationG1(&gen1Aff, alphas) - copy(s.SRS.G1[1:], g1s) + copy(srs.G1[1:], g1s) - return s + return &srs +} + +// Proof KZG proof for opening at a single point. +type Proof struct { + + // Point at which the polynomial is evaluated + Point fr.Element + + // ClaimedValue purported value + ClaimedValue fr.Element + + // H quotient polynomial (f - f(z))/(x-z) + H bls12377.G1Affine } // Marshal serializes a proof as H||point||claimed_value. @@ -145,158 +145,123 @@ func (p *BatchProofsSinglePoint) Marshal() []byte { } return res - } -// WriteTo writes binary encoding of the scheme data. -// It writes only the SRS, the fft fomain is reconstructed -// from it. -func (s *Scheme) WriteTo(w io.Writer) (int64, error) { - - // encode the fft - n, err := s.Domain.WriteTo(w) - if err != nil { - return n, err - } - +// WriteTo writes binary encoding of the SRS +func (srs *SRS) WriteTo(w io.Writer) (int64, error) { // encode the SRS enc := bls12377.NewEncoder(w) toEncode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + srs.G1, } for _, v := range toEncode { if err := enc.Encode(v); err != nil { - return n + enc.BytesWritten(), err + return enc.BytesWritten(), err } } - return n + enc.BytesWritten(), nil + return enc.BytesWritten(), nil } -// ReadFrom decodes KZG data from reader. -// The kzg data should have been encoded using WriteTo. -// Only the points from the SRS are actually encoded in the -// reader, the fft domain is reconstructed from it. -func (s *Scheme) ReadFrom(r io.Reader) (int64, error) { - - // decode the fft - n, err := s.Domain.ReadFrom(r) - if err != nil { - return n, err - } - +// ReadFrom decodes SRS data from reader. +func (srs *SRS) ReadFrom(r io.Reader) (int64, error) { // decode the SRS dec := bls12377.NewDecoder(r) toDecode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - &s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + &srs.G1, } for _, v := range toDecode { if err := dec.Decode(v); err != nil { - return n + dec.BytesRead(), err + return dec.BytesRead(), err } } - return n + dec.BytesRead(), nil - + return dec.BytesRead(), nil } // Commit commits to a polynomial using a multi exponentiation with the SRS. // It is assumed that the polynomial is in canonical form, in Montgomery form. -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { +func (s *Scheme) Commit(p polynomial.Polynomial) (Digest, error) { if p.Degree() >= s.Domain.Cardinality { - return nil, errUnsupportedSize + return Digest{}, ErrInvalidSize } - var res Digest - _p := p.(*bls12377_pol.Polynomial) + var res bls12377.G1Affine // ensure we don't modify p - pCopy := make(bls12377_pol.Polynomial, s.Domain.Cardinality) - copy(pCopy, *_p) + pCopy := make(polynomial.Polynomial, s.Domain.Cardinality) + copy(pCopy, p) - parallel.Execute(len(*_p), func(start, end int) { + parallel.Execute(len(p), func(start, end int) { for i := start; i < end; i++ { pCopy[i].FromMont() } }) res.MultiExp(s.SRS.G1, pCopy) - return &res, nil + return res, nil } -// Open computes an opening proof of _p at _val. +// Open computes an opening proof of p at _val. // Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { +func (s *Scheme) Open(point *fr.Element, p polynomial.Polynomial) (Proof, error) { if p.Degree() >= s.Domain.Cardinality { panic("[Open] Size of polynomial exceeds the size supported by the scheme") } // build the proof - var res Proof - claimedValue := p.Eval(point) - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(claimedValue) + res := Proof{ + Point: *point, + ClaimedValue: p.Eval(point), + } // compute H - _p := p.(*bls12377_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_p, res.ClaimedValue, res.Point) + + h := dividePolyByXminusA(s.Domain, p, res.ClaimedValue, res.Point) // commit to H - c, err := s.Commit(&h) + c, err := s.Commit(h) if err != nil { - return nil, err + return Proof{}, err } - res.H.Set(c.(*bls12377.G1Affine)) + res.H.Set(&c) - return &res, nil + return res, nil } // Verify verifies a KZG opening proof at a single point -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - - _commitment := commitment.(*bls12377.G1Affine) - _proof := proof.(*Proof) - - // verify that the committed quotient and the commitment are in the correct subgroup - subgroupCheck := _proof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 - } - subgroupCheck = _commitment.IsInSubGroup() - if !subgroupCheck { - return errDigestNotInG1 - } +func (s *Scheme) Verify(commitment *Digest, proof *Proof) error { // comm(f(a)) var claimedValueG1Aff bls12377.G1Affine var claimedValueBigInt big.Int - _proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) + proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) claimedValueG1Aff.ScalarMultiplication(&s.SRS.G1[0], &claimedValueBigInt) // [f(alpha) - f(a)]G1Jac var fminusfaG1Jac, tmpG1Jac bls12377.G1Jac - fminusfaG1Jac.FromAffine(_commitment) + fminusfaG1Jac.FromAffine(commitment) tmpG1Jac.FromAffine(&claimedValueG1Aff) fminusfaG1Jac.SubAssign(&tmpG1Jac) // [-H(alpha)]G1Aff var negH bls12377.G1Affine - negH.Neg(&_proof.H) + negH.Neg(&proof.H) // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bls12377.G2Jac var pointBigInt big.Int - _proof.Point.ToBigIntRegular(&pointBigInt) + proof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -320,17 +285,21 @@ func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningPr return err } if !check { - return polynomial.ErrVerifyOpeningProof + return ErrVerifyOpeningProof } return nil } -// BatchOpenSinglePoint creates a batch opening proof of several polynomials at a single point -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { +// BatchOpenSinglePoint creates a batch opening proof at _val of a list of polynomials. +// It's an interactive protocol, made non interactive using Fiat Shamir. +// point is the point at which the polynomials are opened. +// digests is the list of committed polynomials to open, need to derive the challenge using Fiat Shamir. +// polynomials is the list of polynomials to open. +func (s *Scheme) BatchOpenSinglePoint(point *fr.Element, digests []Digest, polynomials []polynomial.Polynomial) (BatchProofsSinglePoint, error) { nbDigests := len(digests) if nbDigests != len(polynomials) { - return nil, errNbDigestsNeqNbPolynomials + return BatchProofsSinglePoint{}, ErrInvalidNbDigests } var res BatchProofsSinglePoint @@ -338,25 +307,25 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di // compute the purported values res.ClaimedValues = make([]fr.Element, len(polynomials)) for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i] = polynomials[i].Eval(point).(fr.Element) + res.ClaimedValues[i] = polynomials[i].Eval(point) } // set the point at which the evaluation is done - res.Point.SetInterface(point) + res.Point.Set(point) // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") if err := fs.Bind("gamma", res.Point.Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } for i := 0; i < len(digests); i++ { if err := fs.Bind("gamma", digests[i].Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } } gammaByte, err := fs.ComputeChallenge("gamma") if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } var gamma fr.Element gamma.SetBytes(gammaByte) @@ -373,45 +342,34 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di } // compute H - _sumGammaiTimesPol := sumGammaiTimesPol.(*bls12377_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_sumGammaiTimesPol, sumGammaiTimesEval, res.Point) - c, err := s.Commit(&h) + h := dividePolyByXminusA(s.Domain, sumGammaiTimesPol, sumGammaiTimesEval, res.Point) + c, err := s.Commit(h) if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } - res.H.Set(c.(*bls12377.G1Affine)) - return &res, nil + res.H.Set(&c) + + return res, nil } -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { +// BatchVerifySinglePoint verifies a batched opening proof at a single point of a list of polynomials. +// point: point at which the polynomials are evaluated +// claimedValues: claimed values of the polynomials at _val +// commitments: list of commitments to the polynomials which are opened +// batchOpeningProof: the batched opening proof at a single point of the polynomials. +func (s *Scheme) BatchVerifySinglePoint(digests []Digest, batchOpeningProof *BatchProofsSinglePoint) error { nbDigests := len(digests) - _batchOpeningProof := batchOpeningProof.(*BatchProofsSinglePoint) - // check consistancy between numbers of claims vs number of digests - if len(digests) != len(_batchOpeningProof.ClaimedValues) { - return errNbDigestsNeqNbPolynomials - } - - // subgroup checks for digests and the proof - subgroupCheck := true - for i := 0; i < len(digests); i++ { - _digest := digests[i].(*bls12377.G1Affine) - subgroupCheck = subgroupCheck && _digest.IsInSubGroup() - } - if !subgroupCheck { - return errDigestNotInG1 - } - subgroupCheck = subgroupCheck && _batchOpeningProof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 + if len(digests) != len(batchOpeningProof.ClaimedValues) { + return ErrInvalidNbDigests } // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") - err := fs.Bind("gamma", _batchOpeningProof.Point.Marshal()) + err := fs.Bind("gamma", batchOpeningProof.Point.Marshal()) if err != nil { return err } @@ -429,10 +387,10 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin gamma.SetBytes(gammaByte) var sumGammaiTimesEval fr.Element - sumGammaiTimesEval.Set(&_batchOpeningProof.ClaimedValues[nbDigests-1]) + sumGammaiTimesEval.Set(&batchOpeningProof.ClaimedValues[nbDigests-1]) for i := nbDigests - 2; i >= 0; i-- { sumGammaiTimesEval.Mul(&sumGammaiTimesEval, &gamma). - Add(&sumGammaiTimesEval, &_batchOpeningProof.ClaimedValues[i]) + Add(&sumGammaiTimesEval, &batchOpeningProof.ClaimedValues[i]) } var sumGammaiTimesEvalBigInt big.Int @@ -451,7 +409,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin var sumGammaiTimesDigestsG1Aff bls12377.G1Affine _digests := make([]bls12377.G1Affine, len(digests)) for i := 0; i < len(digests); i++ { - _digests[i].Set(digests[i].(*bls12377.G1Affine)) + _digests[i].Set(&digests[i]) } sumGammaiTimesDigestsG1Aff.MultiExp(_digests, gammai) @@ -467,7 +425,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bls12377.G2Jac var pointBigInt big.Int - _batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) + batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -480,7 +438,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [-H(alpha)]G1Aff var negH bls12377.G1Affine - negH.Neg(&_batchOpeningProof.H) + negH.Neg(&batchOpeningProof.H) // check the pairing equation check, err := bls12377.PairingCheck( @@ -491,7 +449,41 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin return err } if !check { - return polynomial.ErrVerifyBatchOpeningSinglePoint + return ErrVerifyBatchOpeningSinglePoint } return nil } + +// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form +func dividePolyByXminusA(d *fft.Domain, f polynomial.Polynomial, fa, a fr.Element) polynomial.Polynomial { + + // padd f so it has size d.Cardinality + _f := make([]fr.Element, d.Cardinality) + copy(_f, f) + + // compute the quotient (f-f(a))/(x-a) + d.FFT(_f, fft.DIF, 0) + + // bit reverse shift + bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) + + accumulator := fr.One() + + s := make([]fr.Element, len(_f)) + for i := 0; i < len(s); i++ { + irev := bits.Reverse64(uint64(i)) >> bShift + s[irev].Sub(&accumulator, &a) + accumulator.Mul(&accumulator, &d.Generator) + } + s = fr.BatchInvert(s) + + for i := 0; i < len(_f); i++ { + _f[i].Sub(&_f[i], &fa) + _f[i].Mul(&_f[i], &s[i]) + } + + d.FFTInverse(_f, fft.DIT, 0) + + // the result is of degree deg(f)-1 + return _f[:len(f)-1] +} diff --git a/ecc/bls12-377/fr/polynomial/kzg/kzg_test.go b/ecc/bls12-377/fr/kzg/kzg_test.go similarity index 68% rename from ecc/bls12-377/fr/polynomial/kzg/kzg_test.go rename to ecc/bls12-377/fr/kzg/kzg_test.go index c2613f473..f3fd722ee 100644 --- a/ecc/bls12-377/fr/polynomial/kzg/kzg_test.go +++ b/ecc/bls12-377/fr/kzg/kzg_test.go @@ -25,19 +25,21 @@ import ( "github.com/consensys/gnark-crypto/ecc/bls12-377" "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/fft" - bls12377_pol "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" ) -var _alphaSetup fr.Element - -func init() { - //_alphaSetup.SetRandom() - _alphaSetup.SetString("1234") +// NewScheme returns a new KZG scheme. +// This should be used for testing purpose only +// it creates a new FFT domain and a new SRS without randomness +func NewScheme(size int) *Scheme { + return &Scheme{ + SRS: NewSRS(size, new(big.Int).SetInt64(42)), + Domain: fft.NewDomain(uint64(size), 0, false), + } } -func randomPolynomial(size int) bls12377_pol.Polynomial { - f := make(bls12377_pol.Polynomial, size) +func randomPolynomial(size int) polynomial.Polynomial { + f := make(polynomial.Polynomial, size) for i := 0; i < size; i++ { f[i].SetRandom() } @@ -51,7 +53,7 @@ func TestDividePolyByXminusA(t *testing.T) { domain := fft.NewDomain(uint64(sizePol), 0, false) // build random polynomial - pol := make(bls12377_pol.Polynomial, sizePol) + pol := make(polynomial.Polynomial, sizePol) for i := 0; i < sizePol; i++ { pol[i].SetRandom() } @@ -59,10 +61,10 @@ func TestDividePolyByXminusA(t *testing.T) { // evaluate the polynomial at a random point var point fr.Element point.SetRandom() - evaluation := pol.Eval(&point).(fr.Element) + evaluation := pol.Eval(&point) // compute f-f(a)/x-a - h := dividePolyByXminusA(*domain, pol, evaluation, point) + h := dividePolyByXminusA(domain, pol, evaluation, point) if len(h) != 229 { t.Fatal("inconsistant size of quotient") @@ -72,10 +74,10 @@ func TestDividePolyByXminusA(t *testing.T) { var randPoint, xminusa fr.Element randPoint.SetRandom() - polRandpoint := pol.Eval(&randPoint).(fr.Element) + polRandpoint := pol.Eval(&randPoint) polRandpoint.Sub(&polRandpoint, &evaluation) // f(rand)-f(point) - hRandPoint := h.Eval(&randPoint).(fr.Element) + hRandPoint := h.Eval(&randPoint) xminusa.Sub(&randPoint, &point) // rand-point // f(rand)-f(point) ==? h(rand)*(rand-point) @@ -89,24 +91,24 @@ func TestDividePolyByXminusA(t *testing.T) { func TestSerialization(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + srs := NewSRS(64, new(big.Int).SetInt64(42)) // serialize it... var buf bytes.Buffer - _, err := s.WriteTo(&buf) + _, err := srs.WriteTo(&buf) if err != nil { t.Fatal(err) } // reconstruct the scheme - var _s Scheme - _, err = _s.ReadFrom(&buf) + var _srs SRS + _, err = _srs.ReadFrom(&buf) if err != nil { t.Fatal(err) } // compare - if !reflect.DeepEqual(s, &_s) { + if !reflect.DeepEqual(srs, &_srs) { t.Fatal("scheme serialization failed") } @@ -115,26 +117,26 @@ func TestSerialization(t *testing.T) { func TestCommit(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial - f := make(bls12377_pol.Polynomial, 60) + f := make(polynomial.Polynomial, 60) for i := 0; i < 60; i++ { f[i].SetRandom() } // commit using the method from KZG - _kzgCommit, err := s.Commit(&f) + _kzgCommit, err := s.Commit(f) if err != nil { t.Fatal(err) } var kzgCommit bls12377.G1Affine - kzgCommit.Set(_kzgCommit.(*bls12377.G1Affine)) + kzgCommit.Unmarshal(_kzgCommit.Marshal()) // check commitment using manual commit var x fr.Element - x.SetString("1234") - fx := f.Eval(&x).(fr.Element) + x.SetString("42") + fx := f.Eval(&x) var fxbi big.Int fx.ToBigIntRegular(&fxbi) var manualCommit bls12377.G1Affine @@ -151,13 +153,13 @@ func TestCommit(t *testing.T) { func TestVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial f := randomPolynomial(60) // commit the polynomial - digest, err := s.Commit(&f) + digest, err := s.Commit(f) if err != nil { t.Fatal(err) } @@ -165,28 +167,26 @@ func TestVerifySinglePoint(t *testing.T) { // compute opening proof at a random point var point fr.Element point.SetString("4321") - proof, err := s.Open(&point, &f) + proof, err := s.Open(&point, f) if err != nil { t.Fatal(err) } // verify the claimed valued - _proof := proof.(*Proof) - expected := f.Eval(point).(fr.Element) - if !_proof.ClaimedValue.Equal(&expected) { + expected := f.Eval(&point) + if !proof.ClaimedValue.Equal(&expected) { t.Fatal("inconsistant claimed value") } // verify correct proof - err = s.Verify(digest, proof) + err = s.Verify(&digest, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof = proof.(*Proof) - _proof.ClaimedValue.Double(&_proof.ClaimedValue) - err = s.Verify(digest, _proof) + proof.ClaimedValue.Double(&proof.ClaimedValue) + err = s.Verify(&digest, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -195,17 +195,16 @@ func TestVerifySinglePoint(t *testing.T) { func TestBatchVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create polynomials f := make([]polynomial.Polynomial, 10) for i := 0; i < 10; i++ { - _f := randomPolynomial(60) - f[i] = &_f + f[i] = randomPolynomial(60) } // commit the polynomials - digests := make([]polynomial.Digest, 10) + digests := make([]Digest, 10) for i := 0; i < 10; i++ { digests[i], _ = s.Commit(f[i]) @@ -220,23 +219,22 @@ func TestBatchVerifySinglePoint(t *testing.T) { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { t.Fatal("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof.ClaimedValues[0].Double(&_proof.ClaimedValues[0]) - err = s.BatchVerifySinglePoint(digests, _proof) + proof.ClaimedValues[0].Double(&proof.ClaimedValues[0]) + err = s.BatchVerifySinglePoint(digests, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -247,20 +245,20 @@ const benchSize = 1 << 16 func BenchmarkKZGCommit(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Commit(&p) + _, _ = s.Commit(p) } } func BenchmarkKZGOpen(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -269,13 +267,13 @@ func BenchmarkKZGOpen(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Open(r, &p) + _, _ = s.Open(&r, p) } } func BenchmarkKZGVerify(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -283,36 +281,35 @@ func BenchmarkKZGVerify(b *testing.B) { r.SetRandom() // commit - comm, err := s.Commit(&p) + comm, err := s.Commit(p) if err != nil { b.Fatal(err) } // open - openingProof, err := s.Open(r, &p) + openingProof, err := s.Open(&r, p) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.Verify(comm, openingProof) + s.Verify(&comm, &openingProof) } } func BenchmarkKZGBatchOpen10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -322,23 +319,22 @@ func BenchmarkKZGBatchOpen10(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) } } func BenchmarkKZGBatchVerify10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -346,13 +342,13 @@ func BenchmarkKZGBatchVerify10(b *testing.B) { var r fr.Element r.SetRandom() - proof, err := s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + proof, err := s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchVerifySinglePoint(commitments[:], proof) + s.BatchVerifySinglePoint(commitments[:], &proof) } } diff --git a/ecc/bls12-377/fr/polynomial/kzg/util.go b/ecc/bls12-377/fr/polynomial/kzg/util.go deleted file mode 100644 index 6a36eda26..000000000 --- a/ecc/bls12-377/fr/polynomial/kzg/util.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package kzg - -import ( - "math/bits" - - "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" - "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/fft" - bls12377_pol "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" -) - -// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form -func dividePolyByXminusA(d fft.Domain, f bls12377_pol.Polynomial, fa, a fr.Element) bls12377_pol.Polynomial { - - // padd f so it has size d.Cardinality - _f := make([]fr.Element, d.Cardinality) - copy(_f, f) - - // compute the quotient (f-f(a))/(x-a) - d.FFT(_f, fft.DIF, 0) - - // bit reverse shift - bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) - - accumulator := fr.One() - - s := make([]fr.Element, len(_f)) - for i := 0; i < len(s); i++ { - irev := bits.Reverse64(uint64(i)) >> bShift - s[irev].Sub(&accumulator, &a) - accumulator.Mul(&accumulator, &d.Generator) - } - s = fr.BatchInvert(s) - - for i := 0; i < len(_f); i++ { - _f[i].Sub(&_f[i], &fa) - _f[i].Mul(&_f[i], &s[i]) - } - - d.FFTInverse(_f, fft.DIT, 0) - - // the result is of degree deg(f)-1 - return _f[:len(f)-1] -} diff --git a/ecc/bls12-377/fr/polynomial/mockcommitment/doc.go b/ecc/bls12-377/fr/polynomial/mockcommitment/doc.go deleted file mode 100644 index 5473a4d43..000000000 --- a/ecc/bls12-377/fr/polynomial/mockcommitment/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -// Package mockcommitment provides a mock commitment scheme, for development and test purposes. -package mockcommitment diff --git a/ecc/bls12-377/fr/polynomial/mockcommitment/mock.go b/ecc/bls12-377/fr/polynomial/mockcommitment/mock.go deleted file mode 100644 index c61658de2..000000000 --- a/ecc/bls12-377/fr/polynomial/mockcommitment/mock.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "io" - - "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" - bls12377 "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -// Scheme mock commitment, useful for testing polynomial based IOP -// like PLONK, where the scheme should not depend on which polynomial commitment scheme -// is used. -type Scheme struct{} - -// WriteTo panics -func (s *Scheme) WriteTo(w io.Writer) (n int64, err error) { - panic("not implemented") -} - -// ReadFrom panics -func (s *Scheme) ReadFrom(r io.Reader) (n int64, err error) { - panic("not implemented") -} - -// Commit returns the first coefficient of p -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { - _p := p.(*bls12377.Polynomial) - var res fr.Element - res.SetInterface((*_p)[0]) - return &res, nil -} - -// Open computes an opening proof of _p at _val. -// Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { - - res := MockProof{} - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(p.Eval(point)) - - return &res, nil -} - -// Verify mock implementation of verify -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - return nil -} - -// BatchOpenSinglePoint computes a batch opening proof for _p at _val. -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { - - var res MockBatchProofsSinglePoint - res.ClaimedValues = make([]fr.Element, len(polynomials)) - res.Point.SetInterface(point) - - for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i].SetInterface(polynomials[i].Eval(point)) - } - - return &res, nil -} - -// BatchVerifySinglePoint computes a batch opening proof for -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { - - return nil - -} diff --git a/ecc/bls12-377/fr/polynomial/mockcommitment/mock_test.go b/ecc/bls12-377/fr/polynomial/mockcommitment/mock_test.go deleted file mode 100644 index 0ede1212f..000000000 --- a/ecc/bls12-377/fr/polynomial/mockcommitment/mock_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "testing" - - "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" - bls12377_pol "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -func TestCommit(t *testing.T) { - - size := 60 - f := make(bls12377_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var _c fr.Element - _c.SetInterface(c) - - if !_c.Equal(&f[0]) { - t.Fatal("err mock commitment (commit)") - } -} - -func TestVerifySinglePoint(t *testing.T) { - - size := 60 - f := make(bls12377_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var point fr.Element - point.SetRandom() - - o, err := s.Open(point, &f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed valued - res := o.(*MockProof) - expected := f.Eval(point).(fr.Element) - if !res.ClaimedValue.Equal(&expected) { - t.Fatal("err mock commitment (open)") - } - - err = s.Verify(c, o) - if err != nil { - t.Fatal(err) - } - -} - -func TestBatchVerifySinglePoint(t *testing.T) { - - // create polynomials - size := 60 - f := make([]polynomial.Polynomial, 10) - for i := 0; i < 10; i++ { - _f := make(bls12377_pol.Polynomial, size) - for i := 0; i < size; i++ { - _f[i].SetRandom() - } - f[i] = &_f - } - - var s Scheme - - // commit the polynomials - digests := make([]polynomial.Digest, 10) - for i := 0; i < 10; i++ { - digests[i], _ = s.Commit(f[i]) - } - - var point fr.Element - point.SetRandom() - - proof, err := s.BatchOpenSinglePoint(&point, digests, f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed values - _proof := proof.(*MockBatchProofsSinglePoint) - for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { - t.Fatal("inconsistant claimed values") - } - } - - // verify the proof - err = s.BatchVerifySinglePoint(digests, proof) - if err != nil { - t.Fatal(err) - } - -} diff --git a/ecc/bls12-377/fr/polynomial/mockcommitment/proof.go b/ecc/bls12-377/fr/polynomial/mockcommitment/proof.go deleted file mode 100644 index 812e7e6c8..000000000 --- a/ecc/bls12-377/fr/polynomial/mockcommitment/proof.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" - -// MockProof empty struct -type MockProof struct { - Point fr.Element - ClaimedValue fr.Element -} - -func (mp *MockProof) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bls12-377/fr/polynomial/mockcommitment/proof_single_point.go b/ecc/bls12-377/fr/polynomial/mockcommitment/proof_single_point.go deleted file mode 100644 index d8b5c7b31..000000000 --- a/ecc/bls12-377/fr/polynomial/mockcommitment/proof_single_point.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" - -// MockBatchProofsSinglePoint empty struct -type MockBatchProofsSinglePoint struct { - Point fr.Element - ClaimedValues []fr.Element -} - -func (mp *MockBatchProofsSinglePoint) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bls12-377/fr/polynomial/polynomial.go b/ecc/bls12-377/fr/polynomial/polynomial.go index 750669eeb..1c381b458 100644 --- a/ecc/bls12-377/fr/polynomial/polynomial.go +++ b/ecc/bls12-377/fr/polynomial/polynomial.go @@ -18,7 +18,6 @@ package polynomial import ( "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" - "github.com/consensys/gnark-crypto/polynomial" ) // Polynomial polynomial represented by coefficients bn254 fr field. @@ -31,13 +30,11 @@ func (p *Polynomial) Degree() uint64 { // Eval evaluates p at v // returns a fr.Element -func (p *Polynomial) Eval(v interface{}) interface{} { - var _v fr.Element - _v.SetInterface(v) +func (p *Polynomial) Eval(v *fr.Element) fr.Element { res := (*p)[len(*p)-1] for i := len(*p) - 2; i >= 0; i-- { - res.Mul(&res, &_v) + res.Mul(&res, v) res.Add(&res, &(*p)[i]) } @@ -45,48 +42,39 @@ func (p *Polynomial) Eval(v interface{}) interface{} { } // Clone returns a copy of the polynomial -func (p *Polynomial) Clone() polynomial.Polynomial { +func (p *Polynomial) Clone() Polynomial { _p := make(Polynomial, len(*p)) copy(_p, *p) - return &_p + return _p } // AddConstantInPlace adds a constant to the polynomial, modifying p -func (p *Polynomial) AddConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) AddConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Add(&(*p)[i], &_c) + (*p)[i].Add(&(*p)[i], c) } } // SubConstantInPlace subs a constant to the polynomial, modifying p -func (p *Polynomial) SubConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) SubConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Sub(&(*p)[i], &_c) + (*p)[i].Sub(&(*p)[i], c) } } // ScaleInPlace multiplies p by v, modifying p -func (p *Polynomial) ScaleInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) ScaleInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Mul(&(*p)[i], &_c) + (*p)[i].Mul(&(*p)[i], c) } } // Add adds p1 to p2 // This function allocates a new slice unless p == p1 or p == p2 -func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { +func (p *Polynomial) Add(p1, p2 Polynomial) *Polynomial { - bigger := *(p1.(*Polynomial)) - smaller := *(p2.(*Polynomial)) + bigger := p1 + smaller := p2 if len(bigger) < len(smaller) { bigger, smaller = smaller, bigger } @@ -116,18 +104,17 @@ func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { } // Equal checks equality between two polynomials -func (p *Polynomial) Equal(p1 polynomial.Polynomial) bool { - _p1 := *(p1.(*Polynomial)) - if (p == nil) != (_p1 == nil) { +func (p *Polynomial) Equal(p1 Polynomial) bool { + if (*p == nil) != (p1 == nil) { return false } - if len(*p) != len(_p1) { + if len(*p) != len(p1) { return false } - for i := range _p1 { - if !(*p)[i].Equal(&_p1[i]) { + for i := range p1 { + if !(*p)[i].Equal(&p1[i]) { return false } } diff --git a/ecc/bls12-377/fr/polynomial/polynomial_test.go b/ecc/bls12-377/fr/polynomial/polynomial_test.go index f256d4a9b..f1d623be8 100644 --- a/ecc/bls12-377/fr/polynomial/polynomial_test.go +++ b/ecc/bls12-377/fr/polynomial/polynomial_test.go @@ -46,7 +46,7 @@ func TestPolynomialEval(t *testing.T) { expectedEval.Div(&expectedEval, &den) // compute purported evaluation - purportedEval := f.Eval(&point).(fr.Element) + purportedEval := f.Eval(&point) // check if !purportedEval.Equal(&expectedEval) { @@ -160,27 +160,27 @@ func TestPolynomialAdd(t *testing.T) { // caller is empty var g Polynomial - g.Add(&f1, &f2) - if !g.Equal(&expectedSum) { + g.Add(f1, f2) + if !g.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } // all operands are distincts _f1 := f1.Clone() - _f1.Add(&f1, &f2) - if !_f1.Equal(&expectedSum) { + _f1.Add(f1, f2) + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } @@ -188,10 +188,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 := f2.Clone() _f1.Add(_f1, _f2) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } @@ -199,10 +199,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 = f2.Clone() _f1.Add(_f2, _f1) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } } diff --git a/ecc/bls12-377/g1.go b/ecc/bls12-377/g1.go index c01318e63..df1d9f505 100644 --- a/ecc/bls12-377/g1.go +++ b/ecc/bls12-377/g1.go @@ -59,6 +59,30 @@ func (p *G1Affine) ScalarMultiplication(a *G1Affine, s *big.Int) *G1Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G1Affine) Equal(a *G1Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bls12-377/g2.go b/ecc/bls12-377/g2.go index 30571e08e..f15a3a4b8 100644 --- a/ecc/bls12-377/g2.go +++ b/ecc/bls12-377/g2.go @@ -64,6 +64,30 @@ func (p *G2Affine) ScalarMultiplication(a *G2Affine, s *big.Int) *G2Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G2Affine) Equal(a *G2Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bls12-381/fr/polynomial/kzg/doc.go b/ecc/bls12-381/fr/kzg/doc.go similarity index 100% rename from ecc/bls12-381/fr/polynomial/kzg/doc.go rename to ecc/bls12-381/fr/kzg/doc.go diff --git a/ecc/bls12-381/fr/polynomial/kzg/fuzz.go b/ecc/bls12-381/fr/kzg/fuzz.go similarity index 77% rename from ecc/bls12-381/fr/polynomial/kzg/fuzz.go rename to ecc/bls12-381/fr/kzg/fuzz.go index 8e241b5ca..d90a93722 100644 --- a/ecc/bls12-381/fr/polynomial/kzg/fuzz.go +++ b/ecc/bls12-381/fr/kzg/fuzz.go @@ -21,8 +21,7 @@ package kzg import ( "bytes" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - bls12381_pol "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" ) const ( @@ -48,15 +47,14 @@ func Fuzz(data []byte) int { // create polynomials f := make([]polynomial.Polynomial, size/2) for i := 0; i < len(f); i++ { - _f := make(bls12381_pol.Polynomial, size) - for j := 0; j < len(_f); j++ { - _f[j].SetRawBytes(r) + f[i] = make(polynomial.Polynomial, size) + for j := 0; j < len(f[i]); j++ { + f[i][j].SetRawBytes(r) } - f[i] = &_f } // commit the polynomials - digests := make([]polynomial.Digest, size/2) + digests := make([]Digest, size/2) for i := 0; i < len(digests); i++ { digests[i], _ = s.Commit(f[i]) @@ -68,16 +66,15 @@ func Fuzz(data []byte) int { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < len(f); i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { panic("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { panic(err) } diff --git a/ecc/bls12-381/fr/polynomial/kzg/fuzz_test.go b/ecc/bls12-381/fr/kzg/fuzz_test.go similarity index 100% rename from ecc/bls12-381/fr/polynomial/kzg/fuzz_test.go rename to ecc/bls12-381/fr/kzg/fuzz_test.go diff --git a/ecc/bls12-381/fr/polynomial/kzg/kzg.go b/ecc/bls12-381/fr/kzg/kzg.go similarity index 61% rename from ecc/bls12-381/fr/polynomial/kzg/kzg.go rename to ecc/bls12-381/fr/kzg/kzg.go index 4bd3568a5..70f5e97e0 100644 --- a/ecc/bls12-381/fr/polynomial/kzg/kzg.go +++ b/ecc/bls12-381/fr/kzg/kzg.go @@ -20,69 +20,56 @@ import ( "errors" "io" "math/big" + "math/bits" "github.com/consensys/gnark-crypto/ecc/bls12-381" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/fft" - bls12381_pol "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" - fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" + "github.com/consensys/gnark-crypto/fiat-shamir" "github.com/consensys/gnark-crypto/internal/parallel" - "github.com/consensys/gnark-crypto/polynomial" ) var ( - errNbDigestsNeqNbPolynomials = errors.New("number of digests is not the same as the number of polynomials") - errUnsupportedSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") - errDigestNotInG1 = errors.New("the digest is not in G1") - errProofNotInG1 = errors.New("the proof is not in G1") + ErrInvalidNbDigests = errors.New("number of digests is not the same as the number of polynomials") + ErrInvalidSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") + ErrVerifyOpeningProof = errors.New("can't verify opening proof") + ErrVerifyBatchOpeningSinglePoint = errors.New("can't verify batch opening proof at single point") ) -// Digest commitment of a polynomial +// Digest commitment of a polynomial. type Digest = bls12381.G1Affine // Scheme stores KZG data type Scheme struct { - // Domain to perform polynomial division. The size of the domain is the lowest power of 2 greater than Size. - Domain fft.Domain + Domain *fft.Domain // SRS stores the result of the MPC - SRS struct { - G1 []bls12381.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] - G2 [2]bls12381.G2Affine // [gen, [alpha]gen ] - } + SRS *SRS } -// Proof KZG proof for opening at a single point. -type Proof struct { - - // Point at which the polynomial is evaluated - Point fr.Element - - // ClaimedValue purported value - ClaimedValue fr.Element - - // H quotient polynomial (f - f(z))/(x-z) - H bls12381.G1Affine +// SRS stores the result of the MPC +// len(SRS.G1) can be larger than domain size +type SRS struct { + G1 []bls12381.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] + G2 [2]bls12381.G2Affine // [gen, [alpha]gen ] } -// NewScheme returns a new KZG scheme. -// This should be used for testing purpose only. -func NewScheme(size int, alpha fr.Element) *Scheme { - - s := &Scheme{} - - d := fft.NewDomain(uint64(size), 0, false) - s.Domain = *d - s.SRS.G1 = make([]bls12381.G1Affine, size) +// NewSRS returns a new SRS using alpha as randomness source +// +// In production, a SRS generated through MPC should be used. +func NewSRS(size int, bAlpha *big.Int) *SRS { + var srs SRS + srs.G1 = make([]bls12381.G1Affine, size) - var bAlpha big.Int - alpha.ToBigIntRegular(&bAlpha) + var alpha fr.Element + alpha.SetBigInt(bAlpha) _, _, gen1Aff, gen2Aff := bls12381.Generators() - s.SRS.G1[0] = gen1Aff - s.SRS.G2[0] = gen2Aff - s.SRS.G2[1].ScalarMultiplication(&gen2Aff, &bAlpha) + srs.G1[0] = gen1Aff + srs.G2[0] = gen2Aff + srs.G2[1].ScalarMultiplication(&gen2Aff, bAlpha) alphas := make([]fr.Element, size-1) alphas[0] = alpha @@ -93,9 +80,22 @@ func NewScheme(size int, alpha fr.Element) *Scheme { alphas[i].FromMont() } g1s := bls12381.BatchScalarMultiplicationG1(&gen1Aff, alphas) - copy(s.SRS.G1[1:], g1s) + copy(srs.G1[1:], g1s) - return s + return &srs +} + +// Proof KZG proof for opening at a single point. +type Proof struct { + + // Point at which the polynomial is evaluated + Point fr.Element + + // ClaimedValue purported value + ClaimedValue fr.Element + + // H quotient polynomial (f - f(z))/(x-z) + H bls12381.G1Affine } // Marshal serializes a proof as H||point||claimed_value. @@ -145,158 +145,123 @@ func (p *BatchProofsSinglePoint) Marshal() []byte { } return res - } -// WriteTo writes binary encoding of the scheme data. -// It writes only the SRS, the fft fomain is reconstructed -// from it. -func (s *Scheme) WriteTo(w io.Writer) (int64, error) { - - // encode the fft - n, err := s.Domain.WriteTo(w) - if err != nil { - return n, err - } - +// WriteTo writes binary encoding of the SRS +func (srs *SRS) WriteTo(w io.Writer) (int64, error) { // encode the SRS enc := bls12381.NewEncoder(w) toEncode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + srs.G1, } for _, v := range toEncode { if err := enc.Encode(v); err != nil { - return n + enc.BytesWritten(), err + return enc.BytesWritten(), err } } - return n + enc.BytesWritten(), nil + return enc.BytesWritten(), nil } -// ReadFrom decodes KZG data from reader. -// The kzg data should have been encoded using WriteTo. -// Only the points from the SRS are actually encoded in the -// reader, the fft domain is reconstructed from it. -func (s *Scheme) ReadFrom(r io.Reader) (int64, error) { - - // decode the fft - n, err := s.Domain.ReadFrom(r) - if err != nil { - return n, err - } - +// ReadFrom decodes SRS data from reader. +func (srs *SRS) ReadFrom(r io.Reader) (int64, error) { // decode the SRS dec := bls12381.NewDecoder(r) toDecode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - &s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + &srs.G1, } for _, v := range toDecode { if err := dec.Decode(v); err != nil { - return n + dec.BytesRead(), err + return dec.BytesRead(), err } } - return n + dec.BytesRead(), nil - + return dec.BytesRead(), nil } // Commit commits to a polynomial using a multi exponentiation with the SRS. // It is assumed that the polynomial is in canonical form, in Montgomery form. -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { +func (s *Scheme) Commit(p polynomial.Polynomial) (Digest, error) { if p.Degree() >= s.Domain.Cardinality { - return nil, errUnsupportedSize + return Digest{}, ErrInvalidSize } - var res Digest - _p := p.(*bls12381_pol.Polynomial) + var res bls12381.G1Affine // ensure we don't modify p - pCopy := make(bls12381_pol.Polynomial, s.Domain.Cardinality) - copy(pCopy, *_p) + pCopy := make(polynomial.Polynomial, s.Domain.Cardinality) + copy(pCopy, p) - parallel.Execute(len(*_p), func(start, end int) { + parallel.Execute(len(p), func(start, end int) { for i := start; i < end; i++ { pCopy[i].FromMont() } }) res.MultiExp(s.SRS.G1, pCopy) - return &res, nil + return res, nil } -// Open computes an opening proof of _p at _val. +// Open computes an opening proof of p at _val. // Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { +func (s *Scheme) Open(point *fr.Element, p polynomial.Polynomial) (Proof, error) { if p.Degree() >= s.Domain.Cardinality { panic("[Open] Size of polynomial exceeds the size supported by the scheme") } // build the proof - var res Proof - claimedValue := p.Eval(point) - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(claimedValue) + res := Proof{ + Point: *point, + ClaimedValue: p.Eval(point), + } // compute H - _p := p.(*bls12381_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_p, res.ClaimedValue, res.Point) + + h := dividePolyByXminusA(s.Domain, p, res.ClaimedValue, res.Point) // commit to H - c, err := s.Commit(&h) + c, err := s.Commit(h) if err != nil { - return nil, err + return Proof{}, err } - res.H.Set(c.(*bls12381.G1Affine)) + res.H.Set(&c) - return &res, nil + return res, nil } // Verify verifies a KZG opening proof at a single point -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - - _commitment := commitment.(*bls12381.G1Affine) - _proof := proof.(*Proof) - - // verify that the committed quotient and the commitment are in the correct subgroup - subgroupCheck := _proof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 - } - subgroupCheck = _commitment.IsInSubGroup() - if !subgroupCheck { - return errDigestNotInG1 - } +func (s *Scheme) Verify(commitment *Digest, proof *Proof) error { // comm(f(a)) var claimedValueG1Aff bls12381.G1Affine var claimedValueBigInt big.Int - _proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) + proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) claimedValueG1Aff.ScalarMultiplication(&s.SRS.G1[0], &claimedValueBigInt) // [f(alpha) - f(a)]G1Jac var fminusfaG1Jac, tmpG1Jac bls12381.G1Jac - fminusfaG1Jac.FromAffine(_commitment) + fminusfaG1Jac.FromAffine(commitment) tmpG1Jac.FromAffine(&claimedValueG1Aff) fminusfaG1Jac.SubAssign(&tmpG1Jac) // [-H(alpha)]G1Aff var negH bls12381.G1Affine - negH.Neg(&_proof.H) + negH.Neg(&proof.H) // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bls12381.G2Jac var pointBigInt big.Int - _proof.Point.ToBigIntRegular(&pointBigInt) + proof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -320,17 +285,21 @@ func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningPr return err } if !check { - return polynomial.ErrVerifyOpeningProof + return ErrVerifyOpeningProof } return nil } -// BatchOpenSinglePoint creates a batch opening proof of several polynomials at a single point -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { +// BatchOpenSinglePoint creates a batch opening proof at _val of a list of polynomials. +// It's an interactive protocol, made non interactive using Fiat Shamir. +// point is the point at which the polynomials are opened. +// digests is the list of committed polynomials to open, need to derive the challenge using Fiat Shamir. +// polynomials is the list of polynomials to open. +func (s *Scheme) BatchOpenSinglePoint(point *fr.Element, digests []Digest, polynomials []polynomial.Polynomial) (BatchProofsSinglePoint, error) { nbDigests := len(digests) if nbDigests != len(polynomials) { - return nil, errNbDigestsNeqNbPolynomials + return BatchProofsSinglePoint{}, ErrInvalidNbDigests } var res BatchProofsSinglePoint @@ -338,25 +307,25 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di // compute the purported values res.ClaimedValues = make([]fr.Element, len(polynomials)) for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i] = polynomials[i].Eval(point).(fr.Element) + res.ClaimedValues[i] = polynomials[i].Eval(point) } // set the point at which the evaluation is done - res.Point.SetInterface(point) + res.Point.Set(point) // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") if err := fs.Bind("gamma", res.Point.Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } for i := 0; i < len(digests); i++ { if err := fs.Bind("gamma", digests[i].Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } } gammaByte, err := fs.ComputeChallenge("gamma") if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } var gamma fr.Element gamma.SetBytes(gammaByte) @@ -373,45 +342,34 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di } // compute H - _sumGammaiTimesPol := sumGammaiTimesPol.(*bls12381_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_sumGammaiTimesPol, sumGammaiTimesEval, res.Point) - c, err := s.Commit(&h) + h := dividePolyByXminusA(s.Domain, sumGammaiTimesPol, sumGammaiTimesEval, res.Point) + c, err := s.Commit(h) if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } - res.H.Set(c.(*bls12381.G1Affine)) - return &res, nil + res.H.Set(&c) + + return res, nil } -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { +// BatchVerifySinglePoint verifies a batched opening proof at a single point of a list of polynomials. +// point: point at which the polynomials are evaluated +// claimedValues: claimed values of the polynomials at _val +// commitments: list of commitments to the polynomials which are opened +// batchOpeningProof: the batched opening proof at a single point of the polynomials. +func (s *Scheme) BatchVerifySinglePoint(digests []Digest, batchOpeningProof *BatchProofsSinglePoint) error { nbDigests := len(digests) - _batchOpeningProof := batchOpeningProof.(*BatchProofsSinglePoint) - // check consistancy between numbers of claims vs number of digests - if len(digests) != len(_batchOpeningProof.ClaimedValues) { - return errNbDigestsNeqNbPolynomials - } - - // subgroup checks for digests and the proof - subgroupCheck := true - for i := 0; i < len(digests); i++ { - _digest := digests[i].(*bls12381.G1Affine) - subgroupCheck = subgroupCheck && _digest.IsInSubGroup() - } - if !subgroupCheck { - return errDigestNotInG1 - } - subgroupCheck = subgroupCheck && _batchOpeningProof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 + if len(digests) != len(batchOpeningProof.ClaimedValues) { + return ErrInvalidNbDigests } // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") - err := fs.Bind("gamma", _batchOpeningProof.Point.Marshal()) + err := fs.Bind("gamma", batchOpeningProof.Point.Marshal()) if err != nil { return err } @@ -429,10 +387,10 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin gamma.SetBytes(gammaByte) var sumGammaiTimesEval fr.Element - sumGammaiTimesEval.Set(&_batchOpeningProof.ClaimedValues[nbDigests-1]) + sumGammaiTimesEval.Set(&batchOpeningProof.ClaimedValues[nbDigests-1]) for i := nbDigests - 2; i >= 0; i-- { sumGammaiTimesEval.Mul(&sumGammaiTimesEval, &gamma). - Add(&sumGammaiTimesEval, &_batchOpeningProof.ClaimedValues[i]) + Add(&sumGammaiTimesEval, &batchOpeningProof.ClaimedValues[i]) } var sumGammaiTimesEvalBigInt big.Int @@ -451,7 +409,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin var sumGammaiTimesDigestsG1Aff bls12381.G1Affine _digests := make([]bls12381.G1Affine, len(digests)) for i := 0; i < len(digests); i++ { - _digests[i].Set(digests[i].(*bls12381.G1Affine)) + _digests[i].Set(&digests[i]) } sumGammaiTimesDigestsG1Aff.MultiExp(_digests, gammai) @@ -467,7 +425,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bls12381.G2Jac var pointBigInt big.Int - _batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) + batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -480,7 +438,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [-H(alpha)]G1Aff var negH bls12381.G1Affine - negH.Neg(&_batchOpeningProof.H) + negH.Neg(&batchOpeningProof.H) // check the pairing equation check, err := bls12381.PairingCheck( @@ -491,7 +449,41 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin return err } if !check { - return polynomial.ErrVerifyBatchOpeningSinglePoint + return ErrVerifyBatchOpeningSinglePoint } return nil } + +// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form +func dividePolyByXminusA(d *fft.Domain, f polynomial.Polynomial, fa, a fr.Element) polynomial.Polynomial { + + // padd f so it has size d.Cardinality + _f := make([]fr.Element, d.Cardinality) + copy(_f, f) + + // compute the quotient (f-f(a))/(x-a) + d.FFT(_f, fft.DIF, 0) + + // bit reverse shift + bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) + + accumulator := fr.One() + + s := make([]fr.Element, len(_f)) + for i := 0; i < len(s); i++ { + irev := bits.Reverse64(uint64(i)) >> bShift + s[irev].Sub(&accumulator, &a) + accumulator.Mul(&accumulator, &d.Generator) + } + s = fr.BatchInvert(s) + + for i := 0; i < len(_f); i++ { + _f[i].Sub(&_f[i], &fa) + _f[i].Mul(&_f[i], &s[i]) + } + + d.FFTInverse(_f, fft.DIT, 0) + + // the result is of degree deg(f)-1 + return _f[:len(f)-1] +} diff --git a/ecc/bls12-381/fr/polynomial/kzg/kzg_test.go b/ecc/bls12-381/fr/kzg/kzg_test.go similarity index 68% rename from ecc/bls12-381/fr/polynomial/kzg/kzg_test.go rename to ecc/bls12-381/fr/kzg/kzg_test.go index d3776ceca..780fc9a06 100644 --- a/ecc/bls12-381/fr/polynomial/kzg/kzg_test.go +++ b/ecc/bls12-381/fr/kzg/kzg_test.go @@ -25,19 +25,21 @@ import ( "github.com/consensys/gnark-crypto/ecc/bls12-381" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/fft" - bls12381_pol "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" ) -var _alphaSetup fr.Element - -func init() { - //_alphaSetup.SetRandom() - _alphaSetup.SetString("1234") +// NewScheme returns a new KZG scheme. +// This should be used for testing purpose only +// it creates a new FFT domain and a new SRS without randomness +func NewScheme(size int) *Scheme { + return &Scheme{ + SRS: NewSRS(size, new(big.Int).SetInt64(42)), + Domain: fft.NewDomain(uint64(size), 0, false), + } } -func randomPolynomial(size int) bls12381_pol.Polynomial { - f := make(bls12381_pol.Polynomial, size) +func randomPolynomial(size int) polynomial.Polynomial { + f := make(polynomial.Polynomial, size) for i := 0; i < size; i++ { f[i].SetRandom() } @@ -51,7 +53,7 @@ func TestDividePolyByXminusA(t *testing.T) { domain := fft.NewDomain(uint64(sizePol), 0, false) // build random polynomial - pol := make(bls12381_pol.Polynomial, sizePol) + pol := make(polynomial.Polynomial, sizePol) for i := 0; i < sizePol; i++ { pol[i].SetRandom() } @@ -59,10 +61,10 @@ func TestDividePolyByXminusA(t *testing.T) { // evaluate the polynomial at a random point var point fr.Element point.SetRandom() - evaluation := pol.Eval(&point).(fr.Element) + evaluation := pol.Eval(&point) // compute f-f(a)/x-a - h := dividePolyByXminusA(*domain, pol, evaluation, point) + h := dividePolyByXminusA(domain, pol, evaluation, point) if len(h) != 229 { t.Fatal("inconsistant size of quotient") @@ -72,10 +74,10 @@ func TestDividePolyByXminusA(t *testing.T) { var randPoint, xminusa fr.Element randPoint.SetRandom() - polRandpoint := pol.Eval(&randPoint).(fr.Element) + polRandpoint := pol.Eval(&randPoint) polRandpoint.Sub(&polRandpoint, &evaluation) // f(rand)-f(point) - hRandPoint := h.Eval(&randPoint).(fr.Element) + hRandPoint := h.Eval(&randPoint) xminusa.Sub(&randPoint, &point) // rand-point // f(rand)-f(point) ==? h(rand)*(rand-point) @@ -89,24 +91,24 @@ func TestDividePolyByXminusA(t *testing.T) { func TestSerialization(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + srs := NewSRS(64, new(big.Int).SetInt64(42)) // serialize it... var buf bytes.Buffer - _, err := s.WriteTo(&buf) + _, err := srs.WriteTo(&buf) if err != nil { t.Fatal(err) } // reconstruct the scheme - var _s Scheme - _, err = _s.ReadFrom(&buf) + var _srs SRS + _, err = _srs.ReadFrom(&buf) if err != nil { t.Fatal(err) } // compare - if !reflect.DeepEqual(s, &_s) { + if !reflect.DeepEqual(srs, &_srs) { t.Fatal("scheme serialization failed") } @@ -115,26 +117,26 @@ func TestSerialization(t *testing.T) { func TestCommit(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial - f := make(bls12381_pol.Polynomial, 60) + f := make(polynomial.Polynomial, 60) for i := 0; i < 60; i++ { f[i].SetRandom() } // commit using the method from KZG - _kzgCommit, err := s.Commit(&f) + _kzgCommit, err := s.Commit(f) if err != nil { t.Fatal(err) } var kzgCommit bls12381.G1Affine - kzgCommit.Set(_kzgCommit.(*bls12381.G1Affine)) + kzgCommit.Unmarshal(_kzgCommit.Marshal()) // check commitment using manual commit var x fr.Element - x.SetString("1234") - fx := f.Eval(&x).(fr.Element) + x.SetString("42") + fx := f.Eval(&x) var fxbi big.Int fx.ToBigIntRegular(&fxbi) var manualCommit bls12381.G1Affine @@ -151,13 +153,13 @@ func TestCommit(t *testing.T) { func TestVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial f := randomPolynomial(60) // commit the polynomial - digest, err := s.Commit(&f) + digest, err := s.Commit(f) if err != nil { t.Fatal(err) } @@ -165,28 +167,26 @@ func TestVerifySinglePoint(t *testing.T) { // compute opening proof at a random point var point fr.Element point.SetString("4321") - proof, err := s.Open(&point, &f) + proof, err := s.Open(&point, f) if err != nil { t.Fatal(err) } // verify the claimed valued - _proof := proof.(*Proof) - expected := f.Eval(point).(fr.Element) - if !_proof.ClaimedValue.Equal(&expected) { + expected := f.Eval(&point) + if !proof.ClaimedValue.Equal(&expected) { t.Fatal("inconsistant claimed value") } // verify correct proof - err = s.Verify(digest, proof) + err = s.Verify(&digest, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof = proof.(*Proof) - _proof.ClaimedValue.Double(&_proof.ClaimedValue) - err = s.Verify(digest, _proof) + proof.ClaimedValue.Double(&proof.ClaimedValue) + err = s.Verify(&digest, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -195,17 +195,16 @@ func TestVerifySinglePoint(t *testing.T) { func TestBatchVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create polynomials f := make([]polynomial.Polynomial, 10) for i := 0; i < 10; i++ { - _f := randomPolynomial(60) - f[i] = &_f + f[i] = randomPolynomial(60) } // commit the polynomials - digests := make([]polynomial.Digest, 10) + digests := make([]Digest, 10) for i := 0; i < 10; i++ { digests[i], _ = s.Commit(f[i]) @@ -220,23 +219,22 @@ func TestBatchVerifySinglePoint(t *testing.T) { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { t.Fatal("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof.ClaimedValues[0].Double(&_proof.ClaimedValues[0]) - err = s.BatchVerifySinglePoint(digests, _proof) + proof.ClaimedValues[0].Double(&proof.ClaimedValues[0]) + err = s.BatchVerifySinglePoint(digests, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -247,20 +245,20 @@ const benchSize = 1 << 16 func BenchmarkKZGCommit(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Commit(&p) + _, _ = s.Commit(p) } } func BenchmarkKZGOpen(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -269,13 +267,13 @@ func BenchmarkKZGOpen(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Open(r, &p) + _, _ = s.Open(&r, p) } } func BenchmarkKZGVerify(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -283,36 +281,35 @@ func BenchmarkKZGVerify(b *testing.B) { r.SetRandom() // commit - comm, err := s.Commit(&p) + comm, err := s.Commit(p) if err != nil { b.Fatal(err) } // open - openingProof, err := s.Open(r, &p) + openingProof, err := s.Open(&r, p) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.Verify(comm, openingProof) + s.Verify(&comm, &openingProof) } } func BenchmarkKZGBatchOpen10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -322,23 +319,22 @@ func BenchmarkKZGBatchOpen10(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) } } func BenchmarkKZGBatchVerify10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -346,13 +342,13 @@ func BenchmarkKZGBatchVerify10(b *testing.B) { var r fr.Element r.SetRandom() - proof, err := s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + proof, err := s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchVerifySinglePoint(commitments[:], proof) + s.BatchVerifySinglePoint(commitments[:], &proof) } } diff --git a/ecc/bls12-381/fr/polynomial/kzg/util.go b/ecc/bls12-381/fr/polynomial/kzg/util.go deleted file mode 100644 index 59708fe4f..000000000 --- a/ecc/bls12-381/fr/polynomial/kzg/util.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package kzg - -import ( - "math/bits" - - "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/fft" - bls12381_pol "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" -) - -// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form -func dividePolyByXminusA(d fft.Domain, f bls12381_pol.Polynomial, fa, a fr.Element) bls12381_pol.Polynomial { - - // padd f so it has size d.Cardinality - _f := make([]fr.Element, d.Cardinality) - copy(_f, f) - - // compute the quotient (f-f(a))/(x-a) - d.FFT(_f, fft.DIF, 0) - - // bit reverse shift - bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) - - accumulator := fr.One() - - s := make([]fr.Element, len(_f)) - for i := 0; i < len(s); i++ { - irev := bits.Reverse64(uint64(i)) >> bShift - s[irev].Sub(&accumulator, &a) - accumulator.Mul(&accumulator, &d.Generator) - } - s = fr.BatchInvert(s) - - for i := 0; i < len(_f); i++ { - _f[i].Sub(&_f[i], &fa) - _f[i].Mul(&_f[i], &s[i]) - } - - d.FFTInverse(_f, fft.DIT, 0) - - // the result is of degree deg(f)-1 - return _f[:len(f)-1] -} diff --git a/ecc/bls12-381/fr/polynomial/mockcommitment/doc.go b/ecc/bls12-381/fr/polynomial/mockcommitment/doc.go deleted file mode 100644 index 5473a4d43..000000000 --- a/ecc/bls12-381/fr/polynomial/mockcommitment/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -// Package mockcommitment provides a mock commitment scheme, for development and test purposes. -package mockcommitment diff --git a/ecc/bls12-381/fr/polynomial/mockcommitment/mock.go b/ecc/bls12-381/fr/polynomial/mockcommitment/mock.go deleted file mode 100644 index 4d4aa1e95..000000000 --- a/ecc/bls12-381/fr/polynomial/mockcommitment/mock.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "io" - - "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -// Scheme mock commitment, useful for testing polynomial based IOP -// like PLONK, where the scheme should not depend on which polynomial commitment scheme -// is used. -type Scheme struct{} - -// WriteTo panics -func (s *Scheme) WriteTo(w io.Writer) (n int64, err error) { - panic("not implemented") -} - -// ReadFrom panics -func (s *Scheme) ReadFrom(r io.Reader) (n int64, err error) { - panic("not implemented") -} - -// Commit returns the first coefficient of p -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { - _p := p.(*bls12381.Polynomial) - var res fr.Element - res.SetInterface((*_p)[0]) - return &res, nil -} - -// Open computes an opening proof of _p at _val. -// Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { - - res := MockProof{} - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(p.Eval(point)) - - return &res, nil -} - -// Verify mock implementation of verify -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - return nil -} - -// BatchOpenSinglePoint computes a batch opening proof for _p at _val. -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { - - var res MockBatchProofsSinglePoint - res.ClaimedValues = make([]fr.Element, len(polynomials)) - res.Point.SetInterface(point) - - for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i].SetInterface(polynomials[i].Eval(point)) - } - - return &res, nil -} - -// BatchVerifySinglePoint computes a batch opening proof for -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { - - return nil - -} diff --git a/ecc/bls12-381/fr/polynomial/mockcommitment/mock_test.go b/ecc/bls12-381/fr/polynomial/mockcommitment/mock_test.go deleted file mode 100644 index 475f02bd9..000000000 --- a/ecc/bls12-381/fr/polynomial/mockcommitment/mock_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "testing" - - "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - bls12381_pol "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -func TestCommit(t *testing.T) { - - size := 60 - f := make(bls12381_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var _c fr.Element - _c.SetInterface(c) - - if !_c.Equal(&f[0]) { - t.Fatal("err mock commitment (commit)") - } -} - -func TestVerifySinglePoint(t *testing.T) { - - size := 60 - f := make(bls12381_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var point fr.Element - point.SetRandom() - - o, err := s.Open(point, &f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed valued - res := o.(*MockProof) - expected := f.Eval(point).(fr.Element) - if !res.ClaimedValue.Equal(&expected) { - t.Fatal("err mock commitment (open)") - } - - err = s.Verify(c, o) - if err != nil { - t.Fatal(err) - } - -} - -func TestBatchVerifySinglePoint(t *testing.T) { - - // create polynomials - size := 60 - f := make([]polynomial.Polynomial, 10) - for i := 0; i < 10; i++ { - _f := make(bls12381_pol.Polynomial, size) - for i := 0; i < size; i++ { - _f[i].SetRandom() - } - f[i] = &_f - } - - var s Scheme - - // commit the polynomials - digests := make([]polynomial.Digest, 10) - for i := 0; i < 10; i++ { - digests[i], _ = s.Commit(f[i]) - } - - var point fr.Element - point.SetRandom() - - proof, err := s.BatchOpenSinglePoint(&point, digests, f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed values - _proof := proof.(*MockBatchProofsSinglePoint) - for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { - t.Fatal("inconsistant claimed values") - } - } - - // verify the proof - err = s.BatchVerifySinglePoint(digests, proof) - if err != nil { - t.Fatal(err) - } - -} diff --git a/ecc/bls12-381/fr/polynomial/mockcommitment/proof.go b/ecc/bls12-381/fr/polynomial/mockcommitment/proof.go deleted file mode 100644 index faadf91e1..000000000 --- a/ecc/bls12-381/fr/polynomial/mockcommitment/proof.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - -// MockProof empty struct -type MockProof struct { - Point fr.Element - ClaimedValue fr.Element -} - -func (mp *MockProof) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bls12-381/fr/polynomial/mockcommitment/proof_single_point.go b/ecc/bls12-381/fr/polynomial/mockcommitment/proof_single_point.go deleted file mode 100644 index fb385d910..000000000 --- a/ecc/bls12-381/fr/polynomial/mockcommitment/proof_single_point.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - -// MockBatchProofsSinglePoint empty struct -type MockBatchProofsSinglePoint struct { - Point fr.Element - ClaimedValues []fr.Element -} - -func (mp *MockBatchProofsSinglePoint) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bls12-381/fr/polynomial/polynomial.go b/ecc/bls12-381/fr/polynomial/polynomial.go index 2a20d24a0..db153e56d 100644 --- a/ecc/bls12-381/fr/polynomial/polynomial.go +++ b/ecc/bls12-381/fr/polynomial/polynomial.go @@ -18,7 +18,6 @@ package polynomial import ( "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - "github.com/consensys/gnark-crypto/polynomial" ) // Polynomial polynomial represented by coefficients bn254 fr field. @@ -31,13 +30,11 @@ func (p *Polynomial) Degree() uint64 { // Eval evaluates p at v // returns a fr.Element -func (p *Polynomial) Eval(v interface{}) interface{} { - var _v fr.Element - _v.SetInterface(v) +func (p *Polynomial) Eval(v *fr.Element) fr.Element { res := (*p)[len(*p)-1] for i := len(*p) - 2; i >= 0; i-- { - res.Mul(&res, &_v) + res.Mul(&res, v) res.Add(&res, &(*p)[i]) } @@ -45,48 +42,39 @@ func (p *Polynomial) Eval(v interface{}) interface{} { } // Clone returns a copy of the polynomial -func (p *Polynomial) Clone() polynomial.Polynomial { +func (p *Polynomial) Clone() Polynomial { _p := make(Polynomial, len(*p)) copy(_p, *p) - return &_p + return _p } // AddConstantInPlace adds a constant to the polynomial, modifying p -func (p *Polynomial) AddConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) AddConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Add(&(*p)[i], &_c) + (*p)[i].Add(&(*p)[i], c) } } // SubConstantInPlace subs a constant to the polynomial, modifying p -func (p *Polynomial) SubConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) SubConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Sub(&(*p)[i], &_c) + (*p)[i].Sub(&(*p)[i], c) } } // ScaleInPlace multiplies p by v, modifying p -func (p *Polynomial) ScaleInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) ScaleInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Mul(&(*p)[i], &_c) + (*p)[i].Mul(&(*p)[i], c) } } // Add adds p1 to p2 // This function allocates a new slice unless p == p1 or p == p2 -func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { +func (p *Polynomial) Add(p1, p2 Polynomial) *Polynomial { - bigger := *(p1.(*Polynomial)) - smaller := *(p2.(*Polynomial)) + bigger := p1 + smaller := p2 if len(bigger) < len(smaller) { bigger, smaller = smaller, bigger } @@ -116,18 +104,17 @@ func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { } // Equal checks equality between two polynomials -func (p *Polynomial) Equal(p1 polynomial.Polynomial) bool { - _p1 := *(p1.(*Polynomial)) - if (p == nil) != (_p1 == nil) { +func (p *Polynomial) Equal(p1 Polynomial) bool { + if (*p == nil) != (p1 == nil) { return false } - if len(*p) != len(_p1) { + if len(*p) != len(p1) { return false } - for i := range _p1 { - if !(*p)[i].Equal(&_p1[i]) { + for i := range p1 { + if !(*p)[i].Equal(&p1[i]) { return false } } diff --git a/ecc/bls12-381/fr/polynomial/polynomial_test.go b/ecc/bls12-381/fr/polynomial/polynomial_test.go index 4a06a271a..0376d294c 100644 --- a/ecc/bls12-381/fr/polynomial/polynomial_test.go +++ b/ecc/bls12-381/fr/polynomial/polynomial_test.go @@ -46,7 +46,7 @@ func TestPolynomialEval(t *testing.T) { expectedEval.Div(&expectedEval, &den) // compute purported evaluation - purportedEval := f.Eval(&point).(fr.Element) + purportedEval := f.Eval(&point) // check if !purportedEval.Equal(&expectedEval) { @@ -160,27 +160,27 @@ func TestPolynomialAdd(t *testing.T) { // caller is empty var g Polynomial - g.Add(&f1, &f2) - if !g.Equal(&expectedSum) { + g.Add(f1, f2) + if !g.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } // all operands are distincts _f1 := f1.Clone() - _f1.Add(&f1, &f2) - if !_f1.Equal(&expectedSum) { + _f1.Add(f1, f2) + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } @@ -188,10 +188,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 := f2.Clone() _f1.Add(_f1, _f2) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } @@ -199,10 +199,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 = f2.Clone() _f1.Add(_f2, _f1) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } } diff --git a/ecc/bls12-381/g1.go b/ecc/bls12-381/g1.go index d257adf34..af92abc03 100644 --- a/ecc/bls12-381/g1.go +++ b/ecc/bls12-381/g1.go @@ -59,6 +59,30 @@ func (p *G1Affine) ScalarMultiplication(a *G1Affine, s *big.Int) *G1Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G1Affine) Equal(a *G1Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bls12-381/g2.go b/ecc/bls12-381/g2.go index eb7115444..e694bd5e0 100644 --- a/ecc/bls12-381/g2.go +++ b/ecc/bls12-381/g2.go @@ -64,6 +64,30 @@ func (p *G2Affine) ScalarMultiplication(a *G2Affine, s *big.Int) *G2Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G2Affine) Equal(a *G2Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bls24-315/fr/polynomial/kzg/doc.go b/ecc/bls24-315/fr/kzg/doc.go similarity index 100% rename from ecc/bls24-315/fr/polynomial/kzg/doc.go rename to ecc/bls24-315/fr/kzg/doc.go diff --git a/ecc/bls24-315/fr/polynomial/kzg/fuzz.go b/ecc/bls24-315/fr/kzg/fuzz.go similarity index 77% rename from ecc/bls24-315/fr/polynomial/kzg/fuzz.go rename to ecc/bls24-315/fr/kzg/fuzz.go index 1019559d9..0be56a765 100644 --- a/ecc/bls24-315/fr/polynomial/kzg/fuzz.go +++ b/ecc/bls24-315/fr/kzg/fuzz.go @@ -21,8 +21,7 @@ package kzg import ( "bytes" "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" - bls24315_pol "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" ) const ( @@ -48,15 +47,14 @@ func Fuzz(data []byte) int { // create polynomials f := make([]polynomial.Polynomial, size/2) for i := 0; i < len(f); i++ { - _f := make(bls24315_pol.Polynomial, size) - for j := 0; j < len(_f); j++ { - _f[j].SetRawBytes(r) + f[i] = make(polynomial.Polynomial, size) + for j := 0; j < len(f[i]); j++ { + f[i][j].SetRawBytes(r) } - f[i] = &_f } // commit the polynomials - digests := make([]polynomial.Digest, size/2) + digests := make([]Digest, size/2) for i := 0; i < len(digests); i++ { digests[i], _ = s.Commit(f[i]) @@ -68,16 +66,15 @@ func Fuzz(data []byte) int { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < len(f); i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { panic("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { panic(err) } diff --git a/ecc/bls24-315/fr/polynomial/kzg/fuzz_test.go b/ecc/bls24-315/fr/kzg/fuzz_test.go similarity index 100% rename from ecc/bls24-315/fr/polynomial/kzg/fuzz_test.go rename to ecc/bls24-315/fr/kzg/fuzz_test.go diff --git a/ecc/bls24-315/fr/polynomial/kzg/kzg.go b/ecc/bls24-315/fr/kzg/kzg.go similarity index 61% rename from ecc/bls24-315/fr/polynomial/kzg/kzg.go rename to ecc/bls24-315/fr/kzg/kzg.go index a36c2d629..c86718831 100644 --- a/ecc/bls24-315/fr/polynomial/kzg/kzg.go +++ b/ecc/bls24-315/fr/kzg/kzg.go @@ -20,69 +20,56 @@ import ( "errors" "io" "math/big" + "math/bits" "github.com/consensys/gnark-crypto/ecc/bls24-315" "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/fft" - bls24315_pol "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" - fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" + "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" + "github.com/consensys/gnark-crypto/fiat-shamir" "github.com/consensys/gnark-crypto/internal/parallel" - "github.com/consensys/gnark-crypto/polynomial" ) var ( - errNbDigestsNeqNbPolynomials = errors.New("number of digests is not the same as the number of polynomials") - errUnsupportedSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") - errDigestNotInG1 = errors.New("the digest is not in G1") - errProofNotInG1 = errors.New("the proof is not in G1") + ErrInvalidNbDigests = errors.New("number of digests is not the same as the number of polynomials") + ErrInvalidSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") + ErrVerifyOpeningProof = errors.New("can't verify opening proof") + ErrVerifyBatchOpeningSinglePoint = errors.New("can't verify batch opening proof at single point") ) -// Digest commitment of a polynomial +// Digest commitment of a polynomial. type Digest = bls24315.G1Affine // Scheme stores KZG data type Scheme struct { - // Domain to perform polynomial division. The size of the domain is the lowest power of 2 greater than Size. - Domain fft.Domain + Domain *fft.Domain // SRS stores the result of the MPC - SRS struct { - G1 []bls24315.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] - G2 [2]bls24315.G2Affine // [gen, [alpha]gen ] - } + SRS *SRS } -// Proof KZG proof for opening at a single point. -type Proof struct { - - // Point at which the polynomial is evaluated - Point fr.Element - - // ClaimedValue purported value - ClaimedValue fr.Element - - // H quotient polynomial (f - f(z))/(x-z) - H bls24315.G1Affine +// SRS stores the result of the MPC +// len(SRS.G1) can be larger than domain size +type SRS struct { + G1 []bls24315.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] + G2 [2]bls24315.G2Affine // [gen, [alpha]gen ] } -// NewScheme returns a new KZG scheme. -// This should be used for testing purpose only. -func NewScheme(size int, alpha fr.Element) *Scheme { - - s := &Scheme{} - - d := fft.NewDomain(uint64(size), 0, false) - s.Domain = *d - s.SRS.G1 = make([]bls24315.G1Affine, size) +// NewSRS returns a new SRS using alpha as randomness source +// +// In production, a SRS generated through MPC should be used. +func NewSRS(size int, bAlpha *big.Int) *SRS { + var srs SRS + srs.G1 = make([]bls24315.G1Affine, size) - var bAlpha big.Int - alpha.ToBigIntRegular(&bAlpha) + var alpha fr.Element + alpha.SetBigInt(bAlpha) _, _, gen1Aff, gen2Aff := bls24315.Generators() - s.SRS.G1[0] = gen1Aff - s.SRS.G2[0] = gen2Aff - s.SRS.G2[1].ScalarMultiplication(&gen2Aff, &bAlpha) + srs.G1[0] = gen1Aff + srs.G2[0] = gen2Aff + srs.G2[1].ScalarMultiplication(&gen2Aff, bAlpha) alphas := make([]fr.Element, size-1) alphas[0] = alpha @@ -93,9 +80,22 @@ func NewScheme(size int, alpha fr.Element) *Scheme { alphas[i].FromMont() } g1s := bls24315.BatchScalarMultiplicationG1(&gen1Aff, alphas) - copy(s.SRS.G1[1:], g1s) + copy(srs.G1[1:], g1s) - return s + return &srs +} + +// Proof KZG proof for opening at a single point. +type Proof struct { + + // Point at which the polynomial is evaluated + Point fr.Element + + // ClaimedValue purported value + ClaimedValue fr.Element + + // H quotient polynomial (f - f(z))/(x-z) + H bls24315.G1Affine } // Marshal serializes a proof as H||point||claimed_value. @@ -145,158 +145,123 @@ func (p *BatchProofsSinglePoint) Marshal() []byte { } return res - } -// WriteTo writes binary encoding of the scheme data. -// It writes only the SRS, the fft fomain is reconstructed -// from it. -func (s *Scheme) WriteTo(w io.Writer) (int64, error) { - - // encode the fft - n, err := s.Domain.WriteTo(w) - if err != nil { - return n, err - } - +// WriteTo writes binary encoding of the SRS +func (srs *SRS) WriteTo(w io.Writer) (int64, error) { // encode the SRS enc := bls24315.NewEncoder(w) toEncode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + srs.G1, } for _, v := range toEncode { if err := enc.Encode(v); err != nil { - return n + enc.BytesWritten(), err + return enc.BytesWritten(), err } } - return n + enc.BytesWritten(), nil + return enc.BytesWritten(), nil } -// ReadFrom decodes KZG data from reader. -// The kzg data should have been encoded using WriteTo. -// Only the points from the SRS are actually encoded in the -// reader, the fft domain is reconstructed from it. -func (s *Scheme) ReadFrom(r io.Reader) (int64, error) { - - // decode the fft - n, err := s.Domain.ReadFrom(r) - if err != nil { - return n, err - } - +// ReadFrom decodes SRS data from reader. +func (srs *SRS) ReadFrom(r io.Reader) (int64, error) { // decode the SRS dec := bls24315.NewDecoder(r) toDecode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - &s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + &srs.G1, } for _, v := range toDecode { if err := dec.Decode(v); err != nil { - return n + dec.BytesRead(), err + return dec.BytesRead(), err } } - return n + dec.BytesRead(), nil - + return dec.BytesRead(), nil } // Commit commits to a polynomial using a multi exponentiation with the SRS. // It is assumed that the polynomial is in canonical form, in Montgomery form. -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { +func (s *Scheme) Commit(p polynomial.Polynomial) (Digest, error) { if p.Degree() >= s.Domain.Cardinality { - return nil, errUnsupportedSize + return Digest{}, ErrInvalidSize } - var res Digest - _p := p.(*bls24315_pol.Polynomial) + var res bls24315.G1Affine // ensure we don't modify p - pCopy := make(bls24315_pol.Polynomial, s.Domain.Cardinality) - copy(pCopy, *_p) + pCopy := make(polynomial.Polynomial, s.Domain.Cardinality) + copy(pCopy, p) - parallel.Execute(len(*_p), func(start, end int) { + parallel.Execute(len(p), func(start, end int) { for i := start; i < end; i++ { pCopy[i].FromMont() } }) res.MultiExp(s.SRS.G1, pCopy) - return &res, nil + return res, nil } -// Open computes an opening proof of _p at _val. +// Open computes an opening proof of p at _val. // Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { +func (s *Scheme) Open(point *fr.Element, p polynomial.Polynomial) (Proof, error) { if p.Degree() >= s.Domain.Cardinality { panic("[Open] Size of polynomial exceeds the size supported by the scheme") } // build the proof - var res Proof - claimedValue := p.Eval(point) - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(claimedValue) + res := Proof{ + Point: *point, + ClaimedValue: p.Eval(point), + } // compute H - _p := p.(*bls24315_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_p, res.ClaimedValue, res.Point) + + h := dividePolyByXminusA(s.Domain, p, res.ClaimedValue, res.Point) // commit to H - c, err := s.Commit(&h) + c, err := s.Commit(h) if err != nil { - return nil, err + return Proof{}, err } - res.H.Set(c.(*bls24315.G1Affine)) + res.H.Set(&c) - return &res, nil + return res, nil } // Verify verifies a KZG opening proof at a single point -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - - _commitment := commitment.(*bls24315.G1Affine) - _proof := proof.(*Proof) - - // verify that the committed quotient and the commitment are in the correct subgroup - subgroupCheck := _proof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 - } - subgroupCheck = _commitment.IsInSubGroup() - if !subgroupCheck { - return errDigestNotInG1 - } +func (s *Scheme) Verify(commitment *Digest, proof *Proof) error { // comm(f(a)) var claimedValueG1Aff bls24315.G1Affine var claimedValueBigInt big.Int - _proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) + proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) claimedValueG1Aff.ScalarMultiplication(&s.SRS.G1[0], &claimedValueBigInt) // [f(alpha) - f(a)]G1Jac var fminusfaG1Jac, tmpG1Jac bls24315.G1Jac - fminusfaG1Jac.FromAffine(_commitment) + fminusfaG1Jac.FromAffine(commitment) tmpG1Jac.FromAffine(&claimedValueG1Aff) fminusfaG1Jac.SubAssign(&tmpG1Jac) // [-H(alpha)]G1Aff var negH bls24315.G1Affine - negH.Neg(&_proof.H) + negH.Neg(&proof.H) // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bls24315.G2Jac var pointBigInt big.Int - _proof.Point.ToBigIntRegular(&pointBigInt) + proof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -320,17 +285,21 @@ func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningPr return err } if !check { - return polynomial.ErrVerifyOpeningProof + return ErrVerifyOpeningProof } return nil } -// BatchOpenSinglePoint creates a batch opening proof of several polynomials at a single point -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { +// BatchOpenSinglePoint creates a batch opening proof at _val of a list of polynomials. +// It's an interactive protocol, made non interactive using Fiat Shamir. +// point is the point at which the polynomials are opened. +// digests is the list of committed polynomials to open, need to derive the challenge using Fiat Shamir. +// polynomials is the list of polynomials to open. +func (s *Scheme) BatchOpenSinglePoint(point *fr.Element, digests []Digest, polynomials []polynomial.Polynomial) (BatchProofsSinglePoint, error) { nbDigests := len(digests) if nbDigests != len(polynomials) { - return nil, errNbDigestsNeqNbPolynomials + return BatchProofsSinglePoint{}, ErrInvalidNbDigests } var res BatchProofsSinglePoint @@ -338,25 +307,25 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di // compute the purported values res.ClaimedValues = make([]fr.Element, len(polynomials)) for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i] = polynomials[i].Eval(point).(fr.Element) + res.ClaimedValues[i] = polynomials[i].Eval(point) } // set the point at which the evaluation is done - res.Point.SetInterface(point) + res.Point.Set(point) // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") if err := fs.Bind("gamma", res.Point.Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } for i := 0; i < len(digests); i++ { if err := fs.Bind("gamma", digests[i].Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } } gammaByte, err := fs.ComputeChallenge("gamma") if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } var gamma fr.Element gamma.SetBytes(gammaByte) @@ -373,45 +342,34 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di } // compute H - _sumGammaiTimesPol := sumGammaiTimesPol.(*bls24315_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_sumGammaiTimesPol, sumGammaiTimesEval, res.Point) - c, err := s.Commit(&h) + h := dividePolyByXminusA(s.Domain, sumGammaiTimesPol, sumGammaiTimesEval, res.Point) + c, err := s.Commit(h) if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } - res.H.Set(c.(*bls24315.G1Affine)) - return &res, nil + res.H.Set(&c) + + return res, nil } -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { +// BatchVerifySinglePoint verifies a batched opening proof at a single point of a list of polynomials. +// point: point at which the polynomials are evaluated +// claimedValues: claimed values of the polynomials at _val +// commitments: list of commitments to the polynomials which are opened +// batchOpeningProof: the batched opening proof at a single point of the polynomials. +func (s *Scheme) BatchVerifySinglePoint(digests []Digest, batchOpeningProof *BatchProofsSinglePoint) error { nbDigests := len(digests) - _batchOpeningProof := batchOpeningProof.(*BatchProofsSinglePoint) - // check consistancy between numbers of claims vs number of digests - if len(digests) != len(_batchOpeningProof.ClaimedValues) { - return errNbDigestsNeqNbPolynomials - } - - // subgroup checks for digests and the proof - subgroupCheck := true - for i := 0; i < len(digests); i++ { - _digest := digests[i].(*bls24315.G1Affine) - subgroupCheck = subgroupCheck && _digest.IsInSubGroup() - } - if !subgroupCheck { - return errDigestNotInG1 - } - subgroupCheck = subgroupCheck && _batchOpeningProof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 + if len(digests) != len(batchOpeningProof.ClaimedValues) { + return ErrInvalidNbDigests } // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") - err := fs.Bind("gamma", _batchOpeningProof.Point.Marshal()) + err := fs.Bind("gamma", batchOpeningProof.Point.Marshal()) if err != nil { return err } @@ -429,10 +387,10 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin gamma.SetBytes(gammaByte) var sumGammaiTimesEval fr.Element - sumGammaiTimesEval.Set(&_batchOpeningProof.ClaimedValues[nbDigests-1]) + sumGammaiTimesEval.Set(&batchOpeningProof.ClaimedValues[nbDigests-1]) for i := nbDigests - 2; i >= 0; i-- { sumGammaiTimesEval.Mul(&sumGammaiTimesEval, &gamma). - Add(&sumGammaiTimesEval, &_batchOpeningProof.ClaimedValues[i]) + Add(&sumGammaiTimesEval, &batchOpeningProof.ClaimedValues[i]) } var sumGammaiTimesEvalBigInt big.Int @@ -451,7 +409,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin var sumGammaiTimesDigestsG1Aff bls24315.G1Affine _digests := make([]bls24315.G1Affine, len(digests)) for i := 0; i < len(digests); i++ { - _digests[i].Set(digests[i].(*bls24315.G1Affine)) + _digests[i].Set(&digests[i]) } sumGammaiTimesDigestsG1Aff.MultiExp(_digests, gammai) @@ -467,7 +425,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bls24315.G2Jac var pointBigInt big.Int - _batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) + batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -480,7 +438,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [-H(alpha)]G1Aff var negH bls24315.G1Affine - negH.Neg(&_batchOpeningProof.H) + negH.Neg(&batchOpeningProof.H) // check the pairing equation check, err := bls24315.PairingCheck( @@ -491,7 +449,41 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin return err } if !check { - return polynomial.ErrVerifyBatchOpeningSinglePoint + return ErrVerifyBatchOpeningSinglePoint } return nil } + +// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form +func dividePolyByXminusA(d *fft.Domain, f polynomial.Polynomial, fa, a fr.Element) polynomial.Polynomial { + + // padd f so it has size d.Cardinality + _f := make([]fr.Element, d.Cardinality) + copy(_f, f) + + // compute the quotient (f-f(a))/(x-a) + d.FFT(_f, fft.DIF, 0) + + // bit reverse shift + bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) + + accumulator := fr.One() + + s := make([]fr.Element, len(_f)) + for i := 0; i < len(s); i++ { + irev := bits.Reverse64(uint64(i)) >> bShift + s[irev].Sub(&accumulator, &a) + accumulator.Mul(&accumulator, &d.Generator) + } + s = fr.BatchInvert(s) + + for i := 0; i < len(_f); i++ { + _f[i].Sub(&_f[i], &fa) + _f[i].Mul(&_f[i], &s[i]) + } + + d.FFTInverse(_f, fft.DIT, 0) + + // the result is of degree deg(f)-1 + return _f[:len(f)-1] +} diff --git a/ecc/bls24-315/fr/polynomial/kzg/kzg_test.go b/ecc/bls24-315/fr/kzg/kzg_test.go similarity index 68% rename from ecc/bls24-315/fr/polynomial/kzg/kzg_test.go rename to ecc/bls24-315/fr/kzg/kzg_test.go index 16bc80016..f9932f89a 100644 --- a/ecc/bls24-315/fr/polynomial/kzg/kzg_test.go +++ b/ecc/bls24-315/fr/kzg/kzg_test.go @@ -25,19 +25,21 @@ import ( "github.com/consensys/gnark-crypto/ecc/bls24-315" "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/fft" - bls24315_pol "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" ) -var _alphaSetup fr.Element - -func init() { - //_alphaSetup.SetRandom() - _alphaSetup.SetString("1234") +// NewScheme returns a new KZG scheme. +// This should be used for testing purpose only +// it creates a new FFT domain and a new SRS without randomness +func NewScheme(size int) *Scheme { + return &Scheme{ + SRS: NewSRS(size, new(big.Int).SetInt64(42)), + Domain: fft.NewDomain(uint64(size), 0, false), + } } -func randomPolynomial(size int) bls24315_pol.Polynomial { - f := make(bls24315_pol.Polynomial, size) +func randomPolynomial(size int) polynomial.Polynomial { + f := make(polynomial.Polynomial, size) for i := 0; i < size; i++ { f[i].SetRandom() } @@ -51,7 +53,7 @@ func TestDividePolyByXminusA(t *testing.T) { domain := fft.NewDomain(uint64(sizePol), 0, false) // build random polynomial - pol := make(bls24315_pol.Polynomial, sizePol) + pol := make(polynomial.Polynomial, sizePol) for i := 0; i < sizePol; i++ { pol[i].SetRandom() } @@ -59,10 +61,10 @@ func TestDividePolyByXminusA(t *testing.T) { // evaluate the polynomial at a random point var point fr.Element point.SetRandom() - evaluation := pol.Eval(&point).(fr.Element) + evaluation := pol.Eval(&point) // compute f-f(a)/x-a - h := dividePolyByXminusA(*domain, pol, evaluation, point) + h := dividePolyByXminusA(domain, pol, evaluation, point) if len(h) != 229 { t.Fatal("inconsistant size of quotient") @@ -72,10 +74,10 @@ func TestDividePolyByXminusA(t *testing.T) { var randPoint, xminusa fr.Element randPoint.SetRandom() - polRandpoint := pol.Eval(&randPoint).(fr.Element) + polRandpoint := pol.Eval(&randPoint) polRandpoint.Sub(&polRandpoint, &evaluation) // f(rand)-f(point) - hRandPoint := h.Eval(&randPoint).(fr.Element) + hRandPoint := h.Eval(&randPoint) xminusa.Sub(&randPoint, &point) // rand-point // f(rand)-f(point) ==? h(rand)*(rand-point) @@ -89,24 +91,24 @@ func TestDividePolyByXminusA(t *testing.T) { func TestSerialization(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + srs := NewSRS(64, new(big.Int).SetInt64(42)) // serialize it... var buf bytes.Buffer - _, err := s.WriteTo(&buf) + _, err := srs.WriteTo(&buf) if err != nil { t.Fatal(err) } // reconstruct the scheme - var _s Scheme - _, err = _s.ReadFrom(&buf) + var _srs SRS + _, err = _srs.ReadFrom(&buf) if err != nil { t.Fatal(err) } // compare - if !reflect.DeepEqual(s, &_s) { + if !reflect.DeepEqual(srs, &_srs) { t.Fatal("scheme serialization failed") } @@ -115,26 +117,26 @@ func TestSerialization(t *testing.T) { func TestCommit(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial - f := make(bls24315_pol.Polynomial, 60) + f := make(polynomial.Polynomial, 60) for i := 0; i < 60; i++ { f[i].SetRandom() } // commit using the method from KZG - _kzgCommit, err := s.Commit(&f) + _kzgCommit, err := s.Commit(f) if err != nil { t.Fatal(err) } var kzgCommit bls24315.G1Affine - kzgCommit.Set(_kzgCommit.(*bls24315.G1Affine)) + kzgCommit.Unmarshal(_kzgCommit.Marshal()) // check commitment using manual commit var x fr.Element - x.SetString("1234") - fx := f.Eval(&x).(fr.Element) + x.SetString("42") + fx := f.Eval(&x) var fxbi big.Int fx.ToBigIntRegular(&fxbi) var manualCommit bls24315.G1Affine @@ -151,13 +153,13 @@ func TestCommit(t *testing.T) { func TestVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial f := randomPolynomial(60) // commit the polynomial - digest, err := s.Commit(&f) + digest, err := s.Commit(f) if err != nil { t.Fatal(err) } @@ -165,28 +167,26 @@ func TestVerifySinglePoint(t *testing.T) { // compute opening proof at a random point var point fr.Element point.SetString("4321") - proof, err := s.Open(&point, &f) + proof, err := s.Open(&point, f) if err != nil { t.Fatal(err) } // verify the claimed valued - _proof := proof.(*Proof) - expected := f.Eval(point).(fr.Element) - if !_proof.ClaimedValue.Equal(&expected) { + expected := f.Eval(&point) + if !proof.ClaimedValue.Equal(&expected) { t.Fatal("inconsistant claimed value") } // verify correct proof - err = s.Verify(digest, proof) + err = s.Verify(&digest, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof = proof.(*Proof) - _proof.ClaimedValue.Double(&_proof.ClaimedValue) - err = s.Verify(digest, _proof) + proof.ClaimedValue.Double(&proof.ClaimedValue) + err = s.Verify(&digest, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -195,17 +195,16 @@ func TestVerifySinglePoint(t *testing.T) { func TestBatchVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create polynomials f := make([]polynomial.Polynomial, 10) for i := 0; i < 10; i++ { - _f := randomPolynomial(60) - f[i] = &_f + f[i] = randomPolynomial(60) } // commit the polynomials - digests := make([]polynomial.Digest, 10) + digests := make([]Digest, 10) for i := 0; i < 10; i++ { digests[i], _ = s.Commit(f[i]) @@ -220,23 +219,22 @@ func TestBatchVerifySinglePoint(t *testing.T) { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { t.Fatal("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof.ClaimedValues[0].Double(&_proof.ClaimedValues[0]) - err = s.BatchVerifySinglePoint(digests, _proof) + proof.ClaimedValues[0].Double(&proof.ClaimedValues[0]) + err = s.BatchVerifySinglePoint(digests, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -247,20 +245,20 @@ const benchSize = 1 << 16 func BenchmarkKZGCommit(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Commit(&p) + _, _ = s.Commit(p) } } func BenchmarkKZGOpen(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -269,13 +267,13 @@ func BenchmarkKZGOpen(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Open(r, &p) + _, _ = s.Open(&r, p) } } func BenchmarkKZGVerify(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -283,36 +281,35 @@ func BenchmarkKZGVerify(b *testing.B) { r.SetRandom() // commit - comm, err := s.Commit(&p) + comm, err := s.Commit(p) if err != nil { b.Fatal(err) } // open - openingProof, err := s.Open(r, &p) + openingProof, err := s.Open(&r, p) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.Verify(comm, openingProof) + s.Verify(&comm, &openingProof) } } func BenchmarkKZGBatchOpen10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -322,23 +319,22 @@ func BenchmarkKZGBatchOpen10(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) } } func BenchmarkKZGBatchVerify10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -346,13 +342,13 @@ func BenchmarkKZGBatchVerify10(b *testing.B) { var r fr.Element r.SetRandom() - proof, err := s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + proof, err := s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchVerifySinglePoint(commitments[:], proof) + s.BatchVerifySinglePoint(commitments[:], &proof) } } diff --git a/ecc/bls24-315/fr/polynomial/kzg/util.go b/ecc/bls24-315/fr/polynomial/kzg/util.go deleted file mode 100644 index aea1d2252..000000000 --- a/ecc/bls24-315/fr/polynomial/kzg/util.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package kzg - -import ( - "math/bits" - - "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" - "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/fft" - bls24315_pol "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" -) - -// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form -func dividePolyByXminusA(d fft.Domain, f bls24315_pol.Polynomial, fa, a fr.Element) bls24315_pol.Polynomial { - - // padd f so it has size d.Cardinality - _f := make([]fr.Element, d.Cardinality) - copy(_f, f) - - // compute the quotient (f-f(a))/(x-a) - d.FFT(_f, fft.DIF, 0) - - // bit reverse shift - bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) - - accumulator := fr.One() - - s := make([]fr.Element, len(_f)) - for i := 0; i < len(s); i++ { - irev := bits.Reverse64(uint64(i)) >> bShift - s[irev].Sub(&accumulator, &a) - accumulator.Mul(&accumulator, &d.Generator) - } - s = fr.BatchInvert(s) - - for i := 0; i < len(_f); i++ { - _f[i].Sub(&_f[i], &fa) - _f[i].Mul(&_f[i], &s[i]) - } - - d.FFTInverse(_f, fft.DIT, 0) - - // the result is of degree deg(f)-1 - return _f[:len(f)-1] -} diff --git a/ecc/bls24-315/fr/polynomial/mockcommitment/doc.go b/ecc/bls24-315/fr/polynomial/mockcommitment/doc.go deleted file mode 100644 index 5473a4d43..000000000 --- a/ecc/bls24-315/fr/polynomial/mockcommitment/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -// Package mockcommitment provides a mock commitment scheme, for development and test purposes. -package mockcommitment diff --git a/ecc/bls24-315/fr/polynomial/mockcommitment/mock.go b/ecc/bls24-315/fr/polynomial/mockcommitment/mock.go deleted file mode 100644 index fddf7fe91..000000000 --- a/ecc/bls24-315/fr/polynomial/mockcommitment/mock.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "io" - - "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" - bls24315 "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -// Scheme mock commitment, useful for testing polynomial based IOP -// like PLONK, where the scheme should not depend on which polynomial commitment scheme -// is used. -type Scheme struct{} - -// WriteTo panics -func (s *Scheme) WriteTo(w io.Writer) (n int64, err error) { - panic("not implemented") -} - -// ReadFrom panics -func (s *Scheme) ReadFrom(r io.Reader) (n int64, err error) { - panic("not implemented") -} - -// Commit returns the first coefficient of p -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { - _p := p.(*bls24315.Polynomial) - var res fr.Element - res.SetInterface((*_p)[0]) - return &res, nil -} - -// Open computes an opening proof of _p at _val. -// Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { - - res := MockProof{} - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(p.Eval(point)) - - return &res, nil -} - -// Verify mock implementation of verify -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - return nil -} - -// BatchOpenSinglePoint computes a batch opening proof for _p at _val. -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { - - var res MockBatchProofsSinglePoint - res.ClaimedValues = make([]fr.Element, len(polynomials)) - res.Point.SetInterface(point) - - for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i].SetInterface(polynomials[i].Eval(point)) - } - - return &res, nil -} - -// BatchVerifySinglePoint computes a batch opening proof for -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { - - return nil - -} diff --git a/ecc/bls24-315/fr/polynomial/mockcommitment/mock_test.go b/ecc/bls24-315/fr/polynomial/mockcommitment/mock_test.go deleted file mode 100644 index 1549398ea..000000000 --- a/ecc/bls24-315/fr/polynomial/mockcommitment/mock_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "testing" - - "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" - bls24315_pol "github.com/consensys/gnark-crypto/ecc/bls24-315/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -func TestCommit(t *testing.T) { - - size := 60 - f := make(bls24315_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var _c fr.Element - _c.SetInterface(c) - - if !_c.Equal(&f[0]) { - t.Fatal("err mock commitment (commit)") - } -} - -func TestVerifySinglePoint(t *testing.T) { - - size := 60 - f := make(bls24315_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var point fr.Element - point.SetRandom() - - o, err := s.Open(point, &f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed valued - res := o.(*MockProof) - expected := f.Eval(point).(fr.Element) - if !res.ClaimedValue.Equal(&expected) { - t.Fatal("err mock commitment (open)") - } - - err = s.Verify(c, o) - if err != nil { - t.Fatal(err) - } - -} - -func TestBatchVerifySinglePoint(t *testing.T) { - - // create polynomials - size := 60 - f := make([]polynomial.Polynomial, 10) - for i := 0; i < 10; i++ { - _f := make(bls24315_pol.Polynomial, size) - for i := 0; i < size; i++ { - _f[i].SetRandom() - } - f[i] = &_f - } - - var s Scheme - - // commit the polynomials - digests := make([]polynomial.Digest, 10) - for i := 0; i < 10; i++ { - digests[i], _ = s.Commit(f[i]) - } - - var point fr.Element - point.SetRandom() - - proof, err := s.BatchOpenSinglePoint(&point, digests, f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed values - _proof := proof.(*MockBatchProofsSinglePoint) - for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { - t.Fatal("inconsistant claimed values") - } - } - - // verify the proof - err = s.BatchVerifySinglePoint(digests, proof) - if err != nil { - t.Fatal(err) - } - -} diff --git a/ecc/bls24-315/fr/polynomial/mockcommitment/proof.go b/ecc/bls24-315/fr/polynomial/mockcommitment/proof.go deleted file mode 100644 index afcb4473f..000000000 --- a/ecc/bls24-315/fr/polynomial/mockcommitment/proof.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" - -// MockProof empty struct -type MockProof struct { - Point fr.Element - ClaimedValue fr.Element -} - -func (mp *MockProof) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bls24-315/fr/polynomial/mockcommitment/proof_single_point.go b/ecc/bls24-315/fr/polynomial/mockcommitment/proof_single_point.go deleted file mode 100644 index f021b34c0..000000000 --- a/ecc/bls24-315/fr/polynomial/mockcommitment/proof_single_point.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" - -// MockBatchProofsSinglePoint empty struct -type MockBatchProofsSinglePoint struct { - Point fr.Element - ClaimedValues []fr.Element -} - -func (mp *MockBatchProofsSinglePoint) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bls24-315/fr/polynomial/polynomial.go b/ecc/bls24-315/fr/polynomial/polynomial.go index 1ab9c44f0..4ec875f52 100644 --- a/ecc/bls24-315/fr/polynomial/polynomial.go +++ b/ecc/bls24-315/fr/polynomial/polynomial.go @@ -18,7 +18,6 @@ package polynomial import ( "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" - "github.com/consensys/gnark-crypto/polynomial" ) // Polynomial polynomial represented by coefficients bn254 fr field. @@ -31,13 +30,11 @@ func (p *Polynomial) Degree() uint64 { // Eval evaluates p at v // returns a fr.Element -func (p *Polynomial) Eval(v interface{}) interface{} { - var _v fr.Element - _v.SetInterface(v) +func (p *Polynomial) Eval(v *fr.Element) fr.Element { res := (*p)[len(*p)-1] for i := len(*p) - 2; i >= 0; i-- { - res.Mul(&res, &_v) + res.Mul(&res, v) res.Add(&res, &(*p)[i]) } @@ -45,48 +42,39 @@ func (p *Polynomial) Eval(v interface{}) interface{} { } // Clone returns a copy of the polynomial -func (p *Polynomial) Clone() polynomial.Polynomial { +func (p *Polynomial) Clone() Polynomial { _p := make(Polynomial, len(*p)) copy(_p, *p) - return &_p + return _p } // AddConstantInPlace adds a constant to the polynomial, modifying p -func (p *Polynomial) AddConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) AddConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Add(&(*p)[i], &_c) + (*p)[i].Add(&(*p)[i], c) } } // SubConstantInPlace subs a constant to the polynomial, modifying p -func (p *Polynomial) SubConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) SubConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Sub(&(*p)[i], &_c) + (*p)[i].Sub(&(*p)[i], c) } } // ScaleInPlace multiplies p by v, modifying p -func (p *Polynomial) ScaleInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) ScaleInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Mul(&(*p)[i], &_c) + (*p)[i].Mul(&(*p)[i], c) } } // Add adds p1 to p2 // This function allocates a new slice unless p == p1 or p == p2 -func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { +func (p *Polynomial) Add(p1, p2 Polynomial) *Polynomial { - bigger := *(p1.(*Polynomial)) - smaller := *(p2.(*Polynomial)) + bigger := p1 + smaller := p2 if len(bigger) < len(smaller) { bigger, smaller = smaller, bigger } @@ -116,18 +104,17 @@ func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { } // Equal checks equality between two polynomials -func (p *Polynomial) Equal(p1 polynomial.Polynomial) bool { - _p1 := *(p1.(*Polynomial)) - if (p == nil) != (_p1 == nil) { +func (p *Polynomial) Equal(p1 Polynomial) bool { + if (*p == nil) != (p1 == nil) { return false } - if len(*p) != len(_p1) { + if len(*p) != len(p1) { return false } - for i := range _p1 { - if !(*p)[i].Equal(&_p1[i]) { + for i := range p1 { + if !(*p)[i].Equal(&p1[i]) { return false } } diff --git a/ecc/bls24-315/fr/polynomial/polynomial_test.go b/ecc/bls24-315/fr/polynomial/polynomial_test.go index 6bcb4a186..c23d86197 100644 --- a/ecc/bls24-315/fr/polynomial/polynomial_test.go +++ b/ecc/bls24-315/fr/polynomial/polynomial_test.go @@ -46,7 +46,7 @@ func TestPolynomialEval(t *testing.T) { expectedEval.Div(&expectedEval, &den) // compute purported evaluation - purportedEval := f.Eval(&point).(fr.Element) + purportedEval := f.Eval(&point) // check if !purportedEval.Equal(&expectedEval) { @@ -160,27 +160,27 @@ func TestPolynomialAdd(t *testing.T) { // caller is empty var g Polynomial - g.Add(&f1, &f2) - if !g.Equal(&expectedSum) { + g.Add(f1, f2) + if !g.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } // all operands are distincts _f1 := f1.Clone() - _f1.Add(&f1, &f2) - if !_f1.Equal(&expectedSum) { + _f1.Add(f1, f2) + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } @@ -188,10 +188,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 := f2.Clone() _f1.Add(_f1, _f2) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } @@ -199,10 +199,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 = f2.Clone() _f1.Add(_f2, _f1) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } } diff --git a/ecc/bls24-315/g1.go b/ecc/bls24-315/g1.go index f1d23570c..9a9f20713 100644 --- a/ecc/bls24-315/g1.go +++ b/ecc/bls24-315/g1.go @@ -59,6 +59,30 @@ func (p *G1Affine) ScalarMultiplication(a *G1Affine, s *big.Int) *G1Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G1Affine) Equal(a *G1Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bls24-315/g2.go b/ecc/bls24-315/g2.go index e5f2841d7..9bc9930ac 100644 --- a/ecc/bls24-315/g2.go +++ b/ecc/bls24-315/g2.go @@ -64,6 +64,30 @@ func (p *G2Affine) ScalarMultiplication(a *G2Affine, s *big.Int) *G2Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G2Affine) Equal(a *G2Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bn254/fr/polynomial/kzg/doc.go b/ecc/bn254/fr/kzg/doc.go similarity index 100% rename from ecc/bn254/fr/polynomial/kzg/doc.go rename to ecc/bn254/fr/kzg/doc.go diff --git a/ecc/bn254/fr/polynomial/kzg/fuzz.go b/ecc/bn254/fr/kzg/fuzz.go similarity index 77% rename from ecc/bn254/fr/polynomial/kzg/fuzz.go rename to ecc/bn254/fr/kzg/fuzz.go index f8a86dae0..62803e3be 100644 --- a/ecc/bn254/fr/polynomial/kzg/fuzz.go +++ b/ecc/bn254/fr/kzg/fuzz.go @@ -21,8 +21,7 @@ package kzg import ( "bytes" "github.com/consensys/gnark-crypto/ecc/bn254/fr" - bn254_pol "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" ) const ( @@ -48,15 +47,14 @@ func Fuzz(data []byte) int { // create polynomials f := make([]polynomial.Polynomial, size/2) for i := 0; i < len(f); i++ { - _f := make(bn254_pol.Polynomial, size) - for j := 0; j < len(_f); j++ { - _f[j].SetRawBytes(r) + f[i] = make(polynomial.Polynomial, size) + for j := 0; j < len(f[i]); j++ { + f[i][j].SetRawBytes(r) } - f[i] = &_f } // commit the polynomials - digests := make([]polynomial.Digest, size/2) + digests := make([]Digest, size/2) for i := 0; i < len(digests); i++ { digests[i], _ = s.Commit(f[i]) @@ -68,16 +66,15 @@ func Fuzz(data []byte) int { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < len(f); i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { panic("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { panic(err) } diff --git a/ecc/bn254/fr/polynomial/kzg/fuzz_test.go b/ecc/bn254/fr/kzg/fuzz_test.go similarity index 100% rename from ecc/bn254/fr/polynomial/kzg/fuzz_test.go rename to ecc/bn254/fr/kzg/fuzz_test.go diff --git a/ecc/bn254/fr/polynomial/kzg/kzg.go b/ecc/bn254/fr/kzg/kzg.go similarity index 61% rename from ecc/bn254/fr/polynomial/kzg/kzg.go rename to ecc/bn254/fr/kzg/kzg.go index 540d62711..249491a1b 100644 --- a/ecc/bn254/fr/polynomial/kzg/kzg.go +++ b/ecc/bn254/fr/kzg/kzg.go @@ -20,69 +20,56 @@ import ( "errors" "io" "math/big" + "math/bits" "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254/fr" "github.com/consensys/gnark-crypto/ecc/bn254/fr/fft" - bn254_pol "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" - fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" + "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" + "github.com/consensys/gnark-crypto/fiat-shamir" "github.com/consensys/gnark-crypto/internal/parallel" - "github.com/consensys/gnark-crypto/polynomial" ) var ( - errNbDigestsNeqNbPolynomials = errors.New("number of digests is not the same as the number of polynomials") - errUnsupportedSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") - errDigestNotInG1 = errors.New("the digest is not in G1") - errProofNotInG1 = errors.New("the proof is not in G1") + ErrInvalidNbDigests = errors.New("number of digests is not the same as the number of polynomials") + ErrInvalidSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") + ErrVerifyOpeningProof = errors.New("can't verify opening proof") + ErrVerifyBatchOpeningSinglePoint = errors.New("can't verify batch opening proof at single point") ) -// Digest commitment of a polynomial +// Digest commitment of a polynomial. type Digest = bn254.G1Affine // Scheme stores KZG data type Scheme struct { - // Domain to perform polynomial division. The size of the domain is the lowest power of 2 greater than Size. - Domain fft.Domain + Domain *fft.Domain // SRS stores the result of the MPC - SRS struct { - G1 []bn254.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] - G2 [2]bn254.G2Affine // [gen, [alpha]gen ] - } + SRS *SRS } -// Proof KZG proof for opening at a single point. -type Proof struct { - - // Point at which the polynomial is evaluated - Point fr.Element - - // ClaimedValue purported value - ClaimedValue fr.Element - - // H quotient polynomial (f - f(z))/(x-z) - H bn254.G1Affine +// SRS stores the result of the MPC +// len(SRS.G1) can be larger than domain size +type SRS struct { + G1 []bn254.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] + G2 [2]bn254.G2Affine // [gen, [alpha]gen ] } -// NewScheme returns a new KZG scheme. -// This should be used for testing purpose only. -func NewScheme(size int, alpha fr.Element) *Scheme { - - s := &Scheme{} - - d := fft.NewDomain(uint64(size), 0, false) - s.Domain = *d - s.SRS.G1 = make([]bn254.G1Affine, size) +// NewSRS returns a new SRS using alpha as randomness source +// +// In production, a SRS generated through MPC should be used. +func NewSRS(size int, bAlpha *big.Int) *SRS { + var srs SRS + srs.G1 = make([]bn254.G1Affine, size) - var bAlpha big.Int - alpha.ToBigIntRegular(&bAlpha) + var alpha fr.Element + alpha.SetBigInt(bAlpha) _, _, gen1Aff, gen2Aff := bn254.Generators() - s.SRS.G1[0] = gen1Aff - s.SRS.G2[0] = gen2Aff - s.SRS.G2[1].ScalarMultiplication(&gen2Aff, &bAlpha) + srs.G1[0] = gen1Aff + srs.G2[0] = gen2Aff + srs.G2[1].ScalarMultiplication(&gen2Aff, bAlpha) alphas := make([]fr.Element, size-1) alphas[0] = alpha @@ -93,9 +80,22 @@ func NewScheme(size int, alpha fr.Element) *Scheme { alphas[i].FromMont() } g1s := bn254.BatchScalarMultiplicationG1(&gen1Aff, alphas) - copy(s.SRS.G1[1:], g1s) + copy(srs.G1[1:], g1s) - return s + return &srs +} + +// Proof KZG proof for opening at a single point. +type Proof struct { + + // Point at which the polynomial is evaluated + Point fr.Element + + // ClaimedValue purported value + ClaimedValue fr.Element + + // H quotient polynomial (f - f(z))/(x-z) + H bn254.G1Affine } // Marshal serializes a proof as H||point||claimed_value. @@ -145,158 +145,123 @@ func (p *BatchProofsSinglePoint) Marshal() []byte { } return res - } -// WriteTo writes binary encoding of the scheme data. -// It writes only the SRS, the fft fomain is reconstructed -// from it. -func (s *Scheme) WriteTo(w io.Writer) (int64, error) { - - // encode the fft - n, err := s.Domain.WriteTo(w) - if err != nil { - return n, err - } - +// WriteTo writes binary encoding of the SRS +func (srs *SRS) WriteTo(w io.Writer) (int64, error) { // encode the SRS enc := bn254.NewEncoder(w) toEncode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + srs.G1, } for _, v := range toEncode { if err := enc.Encode(v); err != nil { - return n + enc.BytesWritten(), err + return enc.BytesWritten(), err } } - return n + enc.BytesWritten(), nil + return enc.BytesWritten(), nil } -// ReadFrom decodes KZG data from reader. -// The kzg data should have been encoded using WriteTo. -// Only the points from the SRS are actually encoded in the -// reader, the fft domain is reconstructed from it. -func (s *Scheme) ReadFrom(r io.Reader) (int64, error) { - - // decode the fft - n, err := s.Domain.ReadFrom(r) - if err != nil { - return n, err - } - +// ReadFrom decodes SRS data from reader. +func (srs *SRS) ReadFrom(r io.Reader) (int64, error) { // decode the SRS dec := bn254.NewDecoder(r) toDecode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - &s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + &srs.G1, } for _, v := range toDecode { if err := dec.Decode(v); err != nil { - return n + dec.BytesRead(), err + return dec.BytesRead(), err } } - return n + dec.BytesRead(), nil - + return dec.BytesRead(), nil } // Commit commits to a polynomial using a multi exponentiation with the SRS. // It is assumed that the polynomial is in canonical form, in Montgomery form. -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { +func (s *Scheme) Commit(p polynomial.Polynomial) (Digest, error) { if p.Degree() >= s.Domain.Cardinality { - return nil, errUnsupportedSize + return Digest{}, ErrInvalidSize } - var res Digest - _p := p.(*bn254_pol.Polynomial) + var res bn254.G1Affine // ensure we don't modify p - pCopy := make(bn254_pol.Polynomial, s.Domain.Cardinality) - copy(pCopy, *_p) + pCopy := make(polynomial.Polynomial, s.Domain.Cardinality) + copy(pCopy, p) - parallel.Execute(len(*_p), func(start, end int) { + parallel.Execute(len(p), func(start, end int) { for i := start; i < end; i++ { pCopy[i].FromMont() } }) res.MultiExp(s.SRS.G1, pCopy) - return &res, nil + return res, nil } -// Open computes an opening proof of _p at _val. +// Open computes an opening proof of p at _val. // Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { +func (s *Scheme) Open(point *fr.Element, p polynomial.Polynomial) (Proof, error) { if p.Degree() >= s.Domain.Cardinality { panic("[Open] Size of polynomial exceeds the size supported by the scheme") } // build the proof - var res Proof - claimedValue := p.Eval(point) - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(claimedValue) + res := Proof{ + Point: *point, + ClaimedValue: p.Eval(point), + } // compute H - _p := p.(*bn254_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_p, res.ClaimedValue, res.Point) + + h := dividePolyByXminusA(s.Domain, p, res.ClaimedValue, res.Point) // commit to H - c, err := s.Commit(&h) + c, err := s.Commit(h) if err != nil { - return nil, err + return Proof{}, err } - res.H.Set(c.(*bn254.G1Affine)) + res.H.Set(&c) - return &res, nil + return res, nil } // Verify verifies a KZG opening proof at a single point -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - - _commitment := commitment.(*bn254.G1Affine) - _proof := proof.(*Proof) - - // verify that the committed quotient and the commitment are in the correct subgroup - subgroupCheck := _proof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 - } - subgroupCheck = _commitment.IsInSubGroup() - if !subgroupCheck { - return errDigestNotInG1 - } +func (s *Scheme) Verify(commitment *Digest, proof *Proof) error { // comm(f(a)) var claimedValueG1Aff bn254.G1Affine var claimedValueBigInt big.Int - _proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) + proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) claimedValueG1Aff.ScalarMultiplication(&s.SRS.G1[0], &claimedValueBigInt) // [f(alpha) - f(a)]G1Jac var fminusfaG1Jac, tmpG1Jac bn254.G1Jac - fminusfaG1Jac.FromAffine(_commitment) + fminusfaG1Jac.FromAffine(commitment) tmpG1Jac.FromAffine(&claimedValueG1Aff) fminusfaG1Jac.SubAssign(&tmpG1Jac) // [-H(alpha)]G1Aff var negH bn254.G1Affine - negH.Neg(&_proof.H) + negH.Neg(&proof.H) // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bn254.G2Jac var pointBigInt big.Int - _proof.Point.ToBigIntRegular(&pointBigInt) + proof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -320,17 +285,21 @@ func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningPr return err } if !check { - return polynomial.ErrVerifyOpeningProof + return ErrVerifyOpeningProof } return nil } -// BatchOpenSinglePoint creates a batch opening proof of several polynomials at a single point -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { +// BatchOpenSinglePoint creates a batch opening proof at _val of a list of polynomials. +// It's an interactive protocol, made non interactive using Fiat Shamir. +// point is the point at which the polynomials are opened. +// digests is the list of committed polynomials to open, need to derive the challenge using Fiat Shamir. +// polynomials is the list of polynomials to open. +func (s *Scheme) BatchOpenSinglePoint(point *fr.Element, digests []Digest, polynomials []polynomial.Polynomial) (BatchProofsSinglePoint, error) { nbDigests := len(digests) if nbDigests != len(polynomials) { - return nil, errNbDigestsNeqNbPolynomials + return BatchProofsSinglePoint{}, ErrInvalidNbDigests } var res BatchProofsSinglePoint @@ -338,25 +307,25 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di // compute the purported values res.ClaimedValues = make([]fr.Element, len(polynomials)) for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i] = polynomials[i].Eval(point).(fr.Element) + res.ClaimedValues[i] = polynomials[i].Eval(point) } // set the point at which the evaluation is done - res.Point.SetInterface(point) + res.Point.Set(point) // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") if err := fs.Bind("gamma", res.Point.Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } for i := 0; i < len(digests); i++ { if err := fs.Bind("gamma", digests[i].Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } } gammaByte, err := fs.ComputeChallenge("gamma") if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } var gamma fr.Element gamma.SetBytes(gammaByte) @@ -373,45 +342,34 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di } // compute H - _sumGammaiTimesPol := sumGammaiTimesPol.(*bn254_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_sumGammaiTimesPol, sumGammaiTimesEval, res.Point) - c, err := s.Commit(&h) + h := dividePolyByXminusA(s.Domain, sumGammaiTimesPol, sumGammaiTimesEval, res.Point) + c, err := s.Commit(h) if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } - res.H.Set(c.(*bn254.G1Affine)) - return &res, nil + res.H.Set(&c) + + return res, nil } -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { +// BatchVerifySinglePoint verifies a batched opening proof at a single point of a list of polynomials. +// point: point at which the polynomials are evaluated +// claimedValues: claimed values of the polynomials at _val +// commitments: list of commitments to the polynomials which are opened +// batchOpeningProof: the batched opening proof at a single point of the polynomials. +func (s *Scheme) BatchVerifySinglePoint(digests []Digest, batchOpeningProof *BatchProofsSinglePoint) error { nbDigests := len(digests) - _batchOpeningProof := batchOpeningProof.(*BatchProofsSinglePoint) - // check consistancy between numbers of claims vs number of digests - if len(digests) != len(_batchOpeningProof.ClaimedValues) { - return errNbDigestsNeqNbPolynomials - } - - // subgroup checks for digests and the proof - subgroupCheck := true - for i := 0; i < len(digests); i++ { - _digest := digests[i].(*bn254.G1Affine) - subgroupCheck = subgroupCheck && _digest.IsInSubGroup() - } - if !subgroupCheck { - return errDigestNotInG1 - } - subgroupCheck = subgroupCheck && _batchOpeningProof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 + if len(digests) != len(batchOpeningProof.ClaimedValues) { + return ErrInvalidNbDigests } // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") - err := fs.Bind("gamma", _batchOpeningProof.Point.Marshal()) + err := fs.Bind("gamma", batchOpeningProof.Point.Marshal()) if err != nil { return err } @@ -429,10 +387,10 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin gamma.SetBytes(gammaByte) var sumGammaiTimesEval fr.Element - sumGammaiTimesEval.Set(&_batchOpeningProof.ClaimedValues[nbDigests-1]) + sumGammaiTimesEval.Set(&batchOpeningProof.ClaimedValues[nbDigests-1]) for i := nbDigests - 2; i >= 0; i-- { sumGammaiTimesEval.Mul(&sumGammaiTimesEval, &gamma). - Add(&sumGammaiTimesEval, &_batchOpeningProof.ClaimedValues[i]) + Add(&sumGammaiTimesEval, &batchOpeningProof.ClaimedValues[i]) } var sumGammaiTimesEvalBigInt big.Int @@ -451,7 +409,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin var sumGammaiTimesDigestsG1Aff bn254.G1Affine _digests := make([]bn254.G1Affine, len(digests)) for i := 0; i < len(digests); i++ { - _digests[i].Set(digests[i].(*bn254.G1Affine)) + _digests[i].Set(&digests[i]) } sumGammaiTimesDigestsG1Aff.MultiExp(_digests, gammai) @@ -467,7 +425,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bn254.G2Jac var pointBigInt big.Int - _batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) + batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -480,7 +438,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [-H(alpha)]G1Aff var negH bn254.G1Affine - negH.Neg(&_batchOpeningProof.H) + negH.Neg(&batchOpeningProof.H) // check the pairing equation check, err := bn254.PairingCheck( @@ -491,7 +449,41 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin return err } if !check { - return polynomial.ErrVerifyBatchOpeningSinglePoint + return ErrVerifyBatchOpeningSinglePoint } return nil } + +// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form +func dividePolyByXminusA(d *fft.Domain, f polynomial.Polynomial, fa, a fr.Element) polynomial.Polynomial { + + // padd f so it has size d.Cardinality + _f := make([]fr.Element, d.Cardinality) + copy(_f, f) + + // compute the quotient (f-f(a))/(x-a) + d.FFT(_f, fft.DIF, 0) + + // bit reverse shift + bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) + + accumulator := fr.One() + + s := make([]fr.Element, len(_f)) + for i := 0; i < len(s); i++ { + irev := bits.Reverse64(uint64(i)) >> bShift + s[irev].Sub(&accumulator, &a) + accumulator.Mul(&accumulator, &d.Generator) + } + s = fr.BatchInvert(s) + + for i := 0; i < len(_f); i++ { + _f[i].Sub(&_f[i], &fa) + _f[i].Mul(&_f[i], &s[i]) + } + + d.FFTInverse(_f, fft.DIT, 0) + + // the result is of degree deg(f)-1 + return _f[:len(f)-1] +} diff --git a/ecc/bn254/fr/polynomial/kzg/kzg_test.go b/ecc/bn254/fr/kzg/kzg_test.go similarity index 68% rename from ecc/bn254/fr/polynomial/kzg/kzg_test.go rename to ecc/bn254/fr/kzg/kzg_test.go index 5b1392562..65667e115 100644 --- a/ecc/bn254/fr/polynomial/kzg/kzg_test.go +++ b/ecc/bn254/fr/kzg/kzg_test.go @@ -25,19 +25,21 @@ import ( "github.com/consensys/gnark-crypto/ecc/bn254" "github.com/consensys/gnark-crypto/ecc/bn254/fr" "github.com/consensys/gnark-crypto/ecc/bn254/fr/fft" - bn254_pol "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" ) -var _alphaSetup fr.Element - -func init() { - //_alphaSetup.SetRandom() - _alphaSetup.SetString("1234") +// NewScheme returns a new KZG scheme. +// This should be used for testing purpose only +// it creates a new FFT domain and a new SRS without randomness +func NewScheme(size int) *Scheme { + return &Scheme{ + SRS: NewSRS(size, new(big.Int).SetInt64(42)), + Domain: fft.NewDomain(uint64(size), 0, false), + } } -func randomPolynomial(size int) bn254_pol.Polynomial { - f := make(bn254_pol.Polynomial, size) +func randomPolynomial(size int) polynomial.Polynomial { + f := make(polynomial.Polynomial, size) for i := 0; i < size; i++ { f[i].SetRandom() } @@ -51,7 +53,7 @@ func TestDividePolyByXminusA(t *testing.T) { domain := fft.NewDomain(uint64(sizePol), 0, false) // build random polynomial - pol := make(bn254_pol.Polynomial, sizePol) + pol := make(polynomial.Polynomial, sizePol) for i := 0; i < sizePol; i++ { pol[i].SetRandom() } @@ -59,10 +61,10 @@ func TestDividePolyByXminusA(t *testing.T) { // evaluate the polynomial at a random point var point fr.Element point.SetRandom() - evaluation := pol.Eval(&point).(fr.Element) + evaluation := pol.Eval(&point) // compute f-f(a)/x-a - h := dividePolyByXminusA(*domain, pol, evaluation, point) + h := dividePolyByXminusA(domain, pol, evaluation, point) if len(h) != 229 { t.Fatal("inconsistant size of quotient") @@ -72,10 +74,10 @@ func TestDividePolyByXminusA(t *testing.T) { var randPoint, xminusa fr.Element randPoint.SetRandom() - polRandpoint := pol.Eval(&randPoint).(fr.Element) + polRandpoint := pol.Eval(&randPoint) polRandpoint.Sub(&polRandpoint, &evaluation) // f(rand)-f(point) - hRandPoint := h.Eval(&randPoint).(fr.Element) + hRandPoint := h.Eval(&randPoint) xminusa.Sub(&randPoint, &point) // rand-point // f(rand)-f(point) ==? h(rand)*(rand-point) @@ -89,24 +91,24 @@ func TestDividePolyByXminusA(t *testing.T) { func TestSerialization(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + srs := NewSRS(64, new(big.Int).SetInt64(42)) // serialize it... var buf bytes.Buffer - _, err := s.WriteTo(&buf) + _, err := srs.WriteTo(&buf) if err != nil { t.Fatal(err) } // reconstruct the scheme - var _s Scheme - _, err = _s.ReadFrom(&buf) + var _srs SRS + _, err = _srs.ReadFrom(&buf) if err != nil { t.Fatal(err) } // compare - if !reflect.DeepEqual(s, &_s) { + if !reflect.DeepEqual(srs, &_srs) { t.Fatal("scheme serialization failed") } @@ -115,26 +117,26 @@ func TestSerialization(t *testing.T) { func TestCommit(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial - f := make(bn254_pol.Polynomial, 60) + f := make(polynomial.Polynomial, 60) for i := 0; i < 60; i++ { f[i].SetRandom() } // commit using the method from KZG - _kzgCommit, err := s.Commit(&f) + _kzgCommit, err := s.Commit(f) if err != nil { t.Fatal(err) } var kzgCommit bn254.G1Affine - kzgCommit.Set(_kzgCommit.(*bn254.G1Affine)) + kzgCommit.Unmarshal(_kzgCommit.Marshal()) // check commitment using manual commit var x fr.Element - x.SetString("1234") - fx := f.Eval(&x).(fr.Element) + x.SetString("42") + fx := f.Eval(&x) var fxbi big.Int fx.ToBigIntRegular(&fxbi) var manualCommit bn254.G1Affine @@ -151,13 +153,13 @@ func TestCommit(t *testing.T) { func TestVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial f := randomPolynomial(60) // commit the polynomial - digest, err := s.Commit(&f) + digest, err := s.Commit(f) if err != nil { t.Fatal(err) } @@ -165,28 +167,26 @@ func TestVerifySinglePoint(t *testing.T) { // compute opening proof at a random point var point fr.Element point.SetString("4321") - proof, err := s.Open(&point, &f) + proof, err := s.Open(&point, f) if err != nil { t.Fatal(err) } // verify the claimed valued - _proof := proof.(*Proof) - expected := f.Eval(point).(fr.Element) - if !_proof.ClaimedValue.Equal(&expected) { + expected := f.Eval(&point) + if !proof.ClaimedValue.Equal(&expected) { t.Fatal("inconsistant claimed value") } // verify correct proof - err = s.Verify(digest, proof) + err = s.Verify(&digest, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof = proof.(*Proof) - _proof.ClaimedValue.Double(&_proof.ClaimedValue) - err = s.Verify(digest, _proof) + proof.ClaimedValue.Double(&proof.ClaimedValue) + err = s.Verify(&digest, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -195,17 +195,16 @@ func TestVerifySinglePoint(t *testing.T) { func TestBatchVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create polynomials f := make([]polynomial.Polynomial, 10) for i := 0; i < 10; i++ { - _f := randomPolynomial(60) - f[i] = &_f + f[i] = randomPolynomial(60) } // commit the polynomials - digests := make([]polynomial.Digest, 10) + digests := make([]Digest, 10) for i := 0; i < 10; i++ { digests[i], _ = s.Commit(f[i]) @@ -220,23 +219,22 @@ func TestBatchVerifySinglePoint(t *testing.T) { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { t.Fatal("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof.ClaimedValues[0].Double(&_proof.ClaimedValues[0]) - err = s.BatchVerifySinglePoint(digests, _proof) + proof.ClaimedValues[0].Double(&proof.ClaimedValues[0]) + err = s.BatchVerifySinglePoint(digests, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -247,20 +245,20 @@ const benchSize = 1 << 16 func BenchmarkKZGCommit(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Commit(&p) + _, _ = s.Commit(p) } } func BenchmarkKZGOpen(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -269,13 +267,13 @@ func BenchmarkKZGOpen(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Open(r, &p) + _, _ = s.Open(&r, p) } } func BenchmarkKZGVerify(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -283,36 +281,35 @@ func BenchmarkKZGVerify(b *testing.B) { r.SetRandom() // commit - comm, err := s.Commit(&p) + comm, err := s.Commit(p) if err != nil { b.Fatal(err) } // open - openingProof, err := s.Open(r, &p) + openingProof, err := s.Open(&r, p) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.Verify(comm, openingProof) + s.Verify(&comm, &openingProof) } } func BenchmarkKZGBatchOpen10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -322,23 +319,22 @@ func BenchmarkKZGBatchOpen10(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) } } func BenchmarkKZGBatchVerify10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -346,13 +342,13 @@ func BenchmarkKZGBatchVerify10(b *testing.B) { var r fr.Element r.SetRandom() - proof, err := s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + proof, err := s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchVerifySinglePoint(commitments[:], proof) + s.BatchVerifySinglePoint(commitments[:], &proof) } } diff --git a/ecc/bn254/fr/polynomial/kzg/util.go b/ecc/bn254/fr/polynomial/kzg/util.go deleted file mode 100644 index 12d474237..000000000 --- a/ecc/bn254/fr/polynomial/kzg/util.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package kzg - -import ( - "math/bits" - - "github.com/consensys/gnark-crypto/ecc/bn254/fr" - "github.com/consensys/gnark-crypto/ecc/bn254/fr/fft" - bn254_pol "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" -) - -// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form -func dividePolyByXminusA(d fft.Domain, f bn254_pol.Polynomial, fa, a fr.Element) bn254_pol.Polynomial { - - // padd f so it has size d.Cardinality - _f := make([]fr.Element, d.Cardinality) - copy(_f, f) - - // compute the quotient (f-f(a))/(x-a) - d.FFT(_f, fft.DIF, 0) - - // bit reverse shift - bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) - - accumulator := fr.One() - - s := make([]fr.Element, len(_f)) - for i := 0; i < len(s); i++ { - irev := bits.Reverse64(uint64(i)) >> bShift - s[irev].Sub(&accumulator, &a) - accumulator.Mul(&accumulator, &d.Generator) - } - s = fr.BatchInvert(s) - - for i := 0; i < len(_f); i++ { - _f[i].Sub(&_f[i], &fa) - _f[i].Mul(&_f[i], &s[i]) - } - - d.FFTInverse(_f, fft.DIT, 0) - - // the result is of degree deg(f)-1 - return _f[:len(f)-1] -} diff --git a/ecc/bn254/fr/polynomial/mockcommitment/doc.go b/ecc/bn254/fr/polynomial/mockcommitment/doc.go deleted file mode 100644 index 5473a4d43..000000000 --- a/ecc/bn254/fr/polynomial/mockcommitment/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -// Package mockcommitment provides a mock commitment scheme, for development and test purposes. -package mockcommitment diff --git a/ecc/bn254/fr/polynomial/mockcommitment/mock.go b/ecc/bn254/fr/polynomial/mockcommitment/mock.go deleted file mode 100644 index ddbd8cf99..000000000 --- a/ecc/bn254/fr/polynomial/mockcommitment/mock.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "io" - - "github.com/consensys/gnark-crypto/ecc/bn254/fr" - bn254 "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -// Scheme mock commitment, useful for testing polynomial based IOP -// like PLONK, where the scheme should not depend on which polynomial commitment scheme -// is used. -type Scheme struct{} - -// WriteTo panics -func (s *Scheme) WriteTo(w io.Writer) (n int64, err error) { - panic("not implemented") -} - -// ReadFrom panics -func (s *Scheme) ReadFrom(r io.Reader) (n int64, err error) { - panic("not implemented") -} - -// Commit returns the first coefficient of p -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { - _p := p.(*bn254.Polynomial) - var res fr.Element - res.SetInterface((*_p)[0]) - return &res, nil -} - -// Open computes an opening proof of _p at _val. -// Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { - - res := MockProof{} - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(p.Eval(point)) - - return &res, nil -} - -// Verify mock implementation of verify -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - return nil -} - -// BatchOpenSinglePoint computes a batch opening proof for _p at _val. -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { - - var res MockBatchProofsSinglePoint - res.ClaimedValues = make([]fr.Element, len(polynomials)) - res.Point.SetInterface(point) - - for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i].SetInterface(polynomials[i].Eval(point)) - } - - return &res, nil -} - -// BatchVerifySinglePoint computes a batch opening proof for -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { - - return nil - -} diff --git a/ecc/bn254/fr/polynomial/mockcommitment/mock_test.go b/ecc/bn254/fr/polynomial/mockcommitment/mock_test.go deleted file mode 100644 index 44d942989..000000000 --- a/ecc/bn254/fr/polynomial/mockcommitment/mock_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "testing" - - "github.com/consensys/gnark-crypto/ecc/bn254/fr" - bn254_pol "github.com/consensys/gnark-crypto/ecc/bn254/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -func TestCommit(t *testing.T) { - - size := 60 - f := make(bn254_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var _c fr.Element - _c.SetInterface(c) - - if !_c.Equal(&f[0]) { - t.Fatal("err mock commitment (commit)") - } -} - -func TestVerifySinglePoint(t *testing.T) { - - size := 60 - f := make(bn254_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var point fr.Element - point.SetRandom() - - o, err := s.Open(point, &f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed valued - res := o.(*MockProof) - expected := f.Eval(point).(fr.Element) - if !res.ClaimedValue.Equal(&expected) { - t.Fatal("err mock commitment (open)") - } - - err = s.Verify(c, o) - if err != nil { - t.Fatal(err) - } - -} - -func TestBatchVerifySinglePoint(t *testing.T) { - - // create polynomials - size := 60 - f := make([]polynomial.Polynomial, 10) - for i := 0; i < 10; i++ { - _f := make(bn254_pol.Polynomial, size) - for i := 0; i < size; i++ { - _f[i].SetRandom() - } - f[i] = &_f - } - - var s Scheme - - // commit the polynomials - digests := make([]polynomial.Digest, 10) - for i := 0; i < 10; i++ { - digests[i], _ = s.Commit(f[i]) - } - - var point fr.Element - point.SetRandom() - - proof, err := s.BatchOpenSinglePoint(&point, digests, f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed values - _proof := proof.(*MockBatchProofsSinglePoint) - for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { - t.Fatal("inconsistant claimed values") - } - } - - // verify the proof - err = s.BatchVerifySinglePoint(digests, proof) - if err != nil { - t.Fatal(err) - } - -} diff --git a/ecc/bn254/fr/polynomial/mockcommitment/proof.go b/ecc/bn254/fr/polynomial/mockcommitment/proof.go deleted file mode 100644 index a7fbb5c88..000000000 --- a/ecc/bn254/fr/polynomial/mockcommitment/proof.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bn254/fr" - -// MockProof empty struct -type MockProof struct { - Point fr.Element - ClaimedValue fr.Element -} - -func (mp *MockProof) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bn254/fr/polynomial/mockcommitment/proof_single_point.go b/ecc/bn254/fr/polynomial/mockcommitment/proof_single_point.go deleted file mode 100644 index 58a850689..000000000 --- a/ecc/bn254/fr/polynomial/mockcommitment/proof_single_point.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bn254/fr" - -// MockBatchProofsSinglePoint empty struct -type MockBatchProofsSinglePoint struct { - Point fr.Element - ClaimedValues []fr.Element -} - -func (mp *MockBatchProofsSinglePoint) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bn254/fr/polynomial/polynomial.go b/ecc/bn254/fr/polynomial/polynomial.go index 66206062e..4fe785940 100644 --- a/ecc/bn254/fr/polynomial/polynomial.go +++ b/ecc/bn254/fr/polynomial/polynomial.go @@ -18,7 +18,6 @@ package polynomial import ( "github.com/consensys/gnark-crypto/ecc/bn254/fr" - "github.com/consensys/gnark-crypto/polynomial" ) // Polynomial polynomial represented by coefficients bn254 fr field. @@ -31,13 +30,11 @@ func (p *Polynomial) Degree() uint64 { // Eval evaluates p at v // returns a fr.Element -func (p *Polynomial) Eval(v interface{}) interface{} { - var _v fr.Element - _v.SetInterface(v) +func (p *Polynomial) Eval(v *fr.Element) fr.Element { res := (*p)[len(*p)-1] for i := len(*p) - 2; i >= 0; i-- { - res.Mul(&res, &_v) + res.Mul(&res, v) res.Add(&res, &(*p)[i]) } @@ -45,48 +42,39 @@ func (p *Polynomial) Eval(v interface{}) interface{} { } // Clone returns a copy of the polynomial -func (p *Polynomial) Clone() polynomial.Polynomial { +func (p *Polynomial) Clone() Polynomial { _p := make(Polynomial, len(*p)) copy(_p, *p) - return &_p + return _p } // AddConstantInPlace adds a constant to the polynomial, modifying p -func (p *Polynomial) AddConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) AddConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Add(&(*p)[i], &_c) + (*p)[i].Add(&(*p)[i], c) } } // SubConstantInPlace subs a constant to the polynomial, modifying p -func (p *Polynomial) SubConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) SubConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Sub(&(*p)[i], &_c) + (*p)[i].Sub(&(*p)[i], c) } } // ScaleInPlace multiplies p by v, modifying p -func (p *Polynomial) ScaleInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) ScaleInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Mul(&(*p)[i], &_c) + (*p)[i].Mul(&(*p)[i], c) } } // Add adds p1 to p2 // This function allocates a new slice unless p == p1 or p == p2 -func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { +func (p *Polynomial) Add(p1, p2 Polynomial) *Polynomial { - bigger := *(p1.(*Polynomial)) - smaller := *(p2.(*Polynomial)) + bigger := p1 + smaller := p2 if len(bigger) < len(smaller) { bigger, smaller = smaller, bigger } @@ -116,18 +104,17 @@ func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { } // Equal checks equality between two polynomials -func (p *Polynomial) Equal(p1 polynomial.Polynomial) bool { - _p1 := *(p1.(*Polynomial)) - if (p == nil) != (_p1 == nil) { +func (p *Polynomial) Equal(p1 Polynomial) bool { + if (*p == nil) != (p1 == nil) { return false } - if len(*p) != len(_p1) { + if len(*p) != len(p1) { return false } - for i := range _p1 { - if !(*p)[i].Equal(&_p1[i]) { + for i := range p1 { + if !(*p)[i].Equal(&p1[i]) { return false } } diff --git a/ecc/bn254/fr/polynomial/polynomial_test.go b/ecc/bn254/fr/polynomial/polynomial_test.go index f96991e70..2664c30e2 100644 --- a/ecc/bn254/fr/polynomial/polynomial_test.go +++ b/ecc/bn254/fr/polynomial/polynomial_test.go @@ -46,7 +46,7 @@ func TestPolynomialEval(t *testing.T) { expectedEval.Div(&expectedEval, &den) // compute purported evaluation - purportedEval := f.Eval(&point).(fr.Element) + purportedEval := f.Eval(&point) // check if !purportedEval.Equal(&expectedEval) { @@ -160,27 +160,27 @@ func TestPolynomialAdd(t *testing.T) { // caller is empty var g Polynomial - g.Add(&f1, &f2) - if !g.Equal(&expectedSum) { + g.Add(f1, f2) + if !g.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } // all operands are distincts _f1 := f1.Clone() - _f1.Add(&f1, &f2) - if !_f1.Equal(&expectedSum) { + _f1.Add(f1, f2) + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } @@ -188,10 +188,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 := f2.Clone() _f1.Add(_f1, _f2) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } @@ -199,10 +199,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 = f2.Clone() _f1.Add(_f2, _f1) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } } diff --git a/ecc/bn254/g1.go b/ecc/bn254/g1.go index 11eca08f7..b92e8bb0a 100644 --- a/ecc/bn254/g1.go +++ b/ecc/bn254/g1.go @@ -59,6 +59,30 @@ func (p *G1Affine) ScalarMultiplication(a *G1Affine, s *big.Int) *G1Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G1Affine) Equal(a *G1Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bn254/g2.go b/ecc/bn254/g2.go index bdd53a471..8cd7322e6 100644 --- a/ecc/bn254/g2.go +++ b/ecc/bn254/g2.go @@ -64,6 +64,30 @@ func (p *G2Affine) ScalarMultiplication(a *G2Affine, s *big.Int) *G2Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G2Affine) Equal(a *G2Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bw6-761/fr/polynomial/kzg/doc.go b/ecc/bw6-761/fr/kzg/doc.go similarity index 100% rename from ecc/bw6-761/fr/polynomial/kzg/doc.go rename to ecc/bw6-761/fr/kzg/doc.go diff --git a/ecc/bw6-761/fr/polynomial/kzg/fuzz.go b/ecc/bw6-761/fr/kzg/fuzz.go similarity index 77% rename from ecc/bw6-761/fr/polynomial/kzg/fuzz.go rename to ecc/bw6-761/fr/kzg/fuzz.go index cbca850c7..31effd3d2 100644 --- a/ecc/bw6-761/fr/polynomial/kzg/fuzz.go +++ b/ecc/bw6-761/fr/kzg/fuzz.go @@ -21,8 +21,7 @@ package kzg import ( "bytes" "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" - bw6761_pol "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" ) const ( @@ -48,15 +47,14 @@ func Fuzz(data []byte) int { // create polynomials f := make([]polynomial.Polynomial, size/2) for i := 0; i < len(f); i++ { - _f := make(bw6761_pol.Polynomial, size) - for j := 0; j < len(_f); j++ { - _f[j].SetRawBytes(r) + f[i] = make(polynomial.Polynomial, size) + for j := 0; j < len(f[i]); j++ { + f[i][j].SetRawBytes(r) } - f[i] = &_f } // commit the polynomials - digests := make([]polynomial.Digest, size/2) + digests := make([]Digest, size/2) for i := 0; i < len(digests); i++ { digests[i], _ = s.Commit(f[i]) @@ -68,16 +66,15 @@ func Fuzz(data []byte) int { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < len(f); i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { panic("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { panic(err) } diff --git a/ecc/bw6-761/fr/polynomial/kzg/fuzz_test.go b/ecc/bw6-761/fr/kzg/fuzz_test.go similarity index 100% rename from ecc/bw6-761/fr/polynomial/kzg/fuzz_test.go rename to ecc/bw6-761/fr/kzg/fuzz_test.go diff --git a/ecc/bw6-761/fr/polynomial/kzg/kzg.go b/ecc/bw6-761/fr/kzg/kzg.go similarity index 61% rename from ecc/bw6-761/fr/polynomial/kzg/kzg.go rename to ecc/bw6-761/fr/kzg/kzg.go index c349e40f8..717cb453d 100644 --- a/ecc/bw6-761/fr/polynomial/kzg/kzg.go +++ b/ecc/bw6-761/fr/kzg/kzg.go @@ -20,69 +20,56 @@ import ( "errors" "io" "math/big" + "math/bits" "github.com/consensys/gnark-crypto/ecc/bw6-761" "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/fft" - bw6761_pol "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" - fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" + "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" + "github.com/consensys/gnark-crypto/fiat-shamir" "github.com/consensys/gnark-crypto/internal/parallel" - "github.com/consensys/gnark-crypto/polynomial" ) var ( - errNbDigestsNeqNbPolynomials = errors.New("number of digests is not the same as the number of polynomials") - errUnsupportedSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") - errDigestNotInG1 = errors.New("the digest is not in G1") - errProofNotInG1 = errors.New("the proof is not in G1") + ErrInvalidNbDigests = errors.New("number of digests is not the same as the number of polynomials") + ErrInvalidSize = errors.New("the size of the polynomials exceeds the capacity of the SRS") + ErrVerifyOpeningProof = errors.New("can't verify opening proof") + ErrVerifyBatchOpeningSinglePoint = errors.New("can't verify batch opening proof at single point") ) -// Digest commitment of a polynomial +// Digest commitment of a polynomial. type Digest = bw6761.G1Affine // Scheme stores KZG data type Scheme struct { - // Domain to perform polynomial division. The size of the domain is the lowest power of 2 greater than Size. - Domain fft.Domain + Domain *fft.Domain // SRS stores the result of the MPC - SRS struct { - G1 []bw6761.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] - G2 [2]bw6761.G2Affine // [gen, [alpha]gen ] - } + SRS *SRS } -// Proof KZG proof for opening at a single point. -type Proof struct { - - // Point at which the polynomial is evaluated - Point fr.Element - - // ClaimedValue purported value - ClaimedValue fr.Element - - // H quotient polynomial (f - f(z))/(x-z) - H bw6761.G1Affine +// SRS stores the result of the MPC +// len(SRS.G1) can be larger than domain size +type SRS struct { + G1 []bw6761.G1Affine // [gen [alpha]gen , [alpha**2]gen, ... ] + G2 [2]bw6761.G2Affine // [gen, [alpha]gen ] } -// NewScheme returns a new KZG scheme. -// This should be used for testing purpose only. -func NewScheme(size int, alpha fr.Element) *Scheme { - - s := &Scheme{} - - d := fft.NewDomain(uint64(size), 0, false) - s.Domain = *d - s.SRS.G1 = make([]bw6761.G1Affine, size) +// NewSRS returns a new SRS using alpha as randomness source +// +// In production, a SRS generated through MPC should be used. +func NewSRS(size int, bAlpha *big.Int) *SRS { + var srs SRS + srs.G1 = make([]bw6761.G1Affine, size) - var bAlpha big.Int - alpha.ToBigIntRegular(&bAlpha) + var alpha fr.Element + alpha.SetBigInt(bAlpha) _, _, gen1Aff, gen2Aff := bw6761.Generators() - s.SRS.G1[0] = gen1Aff - s.SRS.G2[0] = gen2Aff - s.SRS.G2[1].ScalarMultiplication(&gen2Aff, &bAlpha) + srs.G1[0] = gen1Aff + srs.G2[0] = gen2Aff + srs.G2[1].ScalarMultiplication(&gen2Aff, bAlpha) alphas := make([]fr.Element, size-1) alphas[0] = alpha @@ -93,9 +80,22 @@ func NewScheme(size int, alpha fr.Element) *Scheme { alphas[i].FromMont() } g1s := bw6761.BatchScalarMultiplicationG1(&gen1Aff, alphas) - copy(s.SRS.G1[1:], g1s) + copy(srs.G1[1:], g1s) - return s + return &srs +} + +// Proof KZG proof for opening at a single point. +type Proof struct { + + // Point at which the polynomial is evaluated + Point fr.Element + + // ClaimedValue purported value + ClaimedValue fr.Element + + // H quotient polynomial (f - f(z))/(x-z) + H bw6761.G1Affine } // Marshal serializes a proof as H||point||claimed_value. @@ -145,158 +145,123 @@ func (p *BatchProofsSinglePoint) Marshal() []byte { } return res - } -// WriteTo writes binary encoding of the scheme data. -// It writes only the SRS, the fft fomain is reconstructed -// from it. -func (s *Scheme) WriteTo(w io.Writer) (int64, error) { - - // encode the fft - n, err := s.Domain.WriteTo(w) - if err != nil { - return n, err - } - +// WriteTo writes binary encoding of the SRS +func (srs *SRS) WriteTo(w io.Writer) (int64, error) { // encode the SRS enc := bw6761.NewEncoder(w) toEncode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + srs.G1, } for _, v := range toEncode { if err := enc.Encode(v); err != nil { - return n + enc.BytesWritten(), err + return enc.BytesWritten(), err } } - return n + enc.BytesWritten(), nil + return enc.BytesWritten(), nil } -// ReadFrom decodes KZG data from reader. -// The kzg data should have been encoded using WriteTo. -// Only the points from the SRS are actually encoded in the -// reader, the fft domain is reconstructed from it. -func (s *Scheme) ReadFrom(r io.Reader) (int64, error) { - - // decode the fft - n, err := s.Domain.ReadFrom(r) - if err != nil { - return n, err - } - +// ReadFrom decodes SRS data from reader. +func (srs *SRS) ReadFrom(r io.Reader) (int64, error) { // decode the SRS dec := bw6761.NewDecoder(r) toDecode := []interface{}{ - &s.SRS.G2[0], - &s.SRS.G2[1], - &s.SRS.G1, + &srs.G2[0], + &srs.G2[1], + &srs.G1, } for _, v := range toDecode { if err := dec.Decode(v); err != nil { - return n + dec.BytesRead(), err + return dec.BytesRead(), err } } - return n + dec.BytesRead(), nil - + return dec.BytesRead(), nil } // Commit commits to a polynomial using a multi exponentiation with the SRS. // It is assumed that the polynomial is in canonical form, in Montgomery form. -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { +func (s *Scheme) Commit(p polynomial.Polynomial) (Digest, error) { if p.Degree() >= s.Domain.Cardinality { - return nil, errUnsupportedSize + return Digest{}, ErrInvalidSize } - var res Digest - _p := p.(*bw6761_pol.Polynomial) + var res bw6761.G1Affine // ensure we don't modify p - pCopy := make(bw6761_pol.Polynomial, s.Domain.Cardinality) - copy(pCopy, *_p) + pCopy := make(polynomial.Polynomial, s.Domain.Cardinality) + copy(pCopy, p) - parallel.Execute(len(*_p), func(start, end int) { + parallel.Execute(len(p), func(start, end int) { for i := start; i < end; i++ { pCopy[i].FromMont() } }) res.MultiExp(s.SRS.G1, pCopy) - return &res, nil + return res, nil } -// Open computes an opening proof of _p at _val. +// Open computes an opening proof of p at _val. // Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { +func (s *Scheme) Open(point *fr.Element, p polynomial.Polynomial) (Proof, error) { if p.Degree() >= s.Domain.Cardinality { panic("[Open] Size of polynomial exceeds the size supported by the scheme") } // build the proof - var res Proof - claimedValue := p.Eval(point) - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(claimedValue) + res := Proof{ + Point: *point, + ClaimedValue: p.Eval(point), + } // compute H - _p := p.(*bw6761_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_p, res.ClaimedValue, res.Point) + + h := dividePolyByXminusA(s.Domain, p, res.ClaimedValue, res.Point) // commit to H - c, err := s.Commit(&h) + c, err := s.Commit(h) if err != nil { - return nil, err + return Proof{}, err } - res.H.Set(c.(*bw6761.G1Affine)) + res.H.Set(&c) - return &res, nil + return res, nil } // Verify verifies a KZG opening proof at a single point -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - - _commitment := commitment.(*bw6761.G1Affine) - _proof := proof.(*Proof) - - // verify that the committed quotient and the commitment are in the correct subgroup - subgroupCheck := _proof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 - } - subgroupCheck = _commitment.IsInSubGroup() - if !subgroupCheck { - return errDigestNotInG1 - } +func (s *Scheme) Verify(commitment *Digest, proof *Proof) error { // comm(f(a)) var claimedValueG1Aff bw6761.G1Affine var claimedValueBigInt big.Int - _proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) + proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) claimedValueG1Aff.ScalarMultiplication(&s.SRS.G1[0], &claimedValueBigInt) // [f(alpha) - f(a)]G1Jac var fminusfaG1Jac, tmpG1Jac bw6761.G1Jac - fminusfaG1Jac.FromAffine(_commitment) + fminusfaG1Jac.FromAffine(commitment) tmpG1Jac.FromAffine(&claimedValueG1Aff) fminusfaG1Jac.SubAssign(&tmpG1Jac) // [-H(alpha)]G1Aff var negH bw6761.G1Affine - negH.Neg(&_proof.H) + negH.Neg(&proof.H) // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bw6761.G2Jac var pointBigInt big.Int - _proof.Point.ToBigIntRegular(&pointBigInt) + proof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -320,17 +285,21 @@ func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningPr return err } if !check { - return polynomial.ErrVerifyOpeningProof + return ErrVerifyOpeningProof } return nil } -// BatchOpenSinglePoint creates a batch opening proof of several polynomials at a single point -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { +// BatchOpenSinglePoint creates a batch opening proof at _val of a list of polynomials. +// It's an interactive protocol, made non interactive using Fiat Shamir. +// point is the point at which the polynomials are opened. +// digests is the list of committed polynomials to open, need to derive the challenge using Fiat Shamir. +// polynomials is the list of polynomials to open. +func (s *Scheme) BatchOpenSinglePoint(point *fr.Element, digests []Digest, polynomials []polynomial.Polynomial) (BatchProofsSinglePoint, error) { nbDigests := len(digests) if nbDigests != len(polynomials) { - return nil, errNbDigestsNeqNbPolynomials + return BatchProofsSinglePoint{}, ErrInvalidNbDigests } var res BatchProofsSinglePoint @@ -338,25 +307,25 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di // compute the purported values res.ClaimedValues = make([]fr.Element, len(polynomials)) for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i] = polynomials[i].Eval(point).(fr.Element) + res.ClaimedValues[i] = polynomials[i].Eval(point) } // set the point at which the evaluation is done - res.Point.SetInterface(point) + res.Point.Set(point) // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") if err := fs.Bind("gamma", res.Point.Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } for i := 0; i < len(digests); i++ { if err := fs.Bind("gamma", digests[i].Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } } gammaByte, err := fs.ComputeChallenge("gamma") if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } var gamma fr.Element gamma.SetBytes(gammaByte) @@ -373,45 +342,34 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di } // compute H - _sumGammaiTimesPol := sumGammaiTimesPol.(*bw6761_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_sumGammaiTimesPol, sumGammaiTimesEval, res.Point) - c, err := s.Commit(&h) + h := dividePolyByXminusA(s.Domain, sumGammaiTimesPol, sumGammaiTimesEval, res.Point) + c, err := s.Commit(h) if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } - res.H.Set(c.(*bw6761.G1Affine)) - return &res, nil + res.H.Set(&c) + + return res, nil } -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { +// BatchVerifySinglePoint verifies a batched opening proof at a single point of a list of polynomials. +// point: point at which the polynomials are evaluated +// claimedValues: claimed values of the polynomials at _val +// commitments: list of commitments to the polynomials which are opened +// batchOpeningProof: the batched opening proof at a single point of the polynomials. +func (s *Scheme) BatchVerifySinglePoint(digests []Digest, batchOpeningProof *BatchProofsSinglePoint) error { nbDigests := len(digests) - _batchOpeningProof := batchOpeningProof.(*BatchProofsSinglePoint) - // check consistancy between numbers of claims vs number of digests - if len(digests) != len(_batchOpeningProof.ClaimedValues) { - return errNbDigestsNeqNbPolynomials - } - - // subgroup checks for digests and the proof - subgroupCheck := true - for i := 0; i < len(digests); i++ { - _digest := digests[i].(*bw6761.G1Affine) - subgroupCheck = subgroupCheck && _digest.IsInSubGroup() - } - if !subgroupCheck { - return errDigestNotInG1 - } - subgroupCheck = subgroupCheck && _batchOpeningProof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 + if len(digests) != len(batchOpeningProof.ClaimedValues) { + return ErrInvalidNbDigests } // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") - err := fs.Bind("gamma", _batchOpeningProof.Point.Marshal()) + err := fs.Bind("gamma", batchOpeningProof.Point.Marshal()) if err != nil { return err } @@ -429,10 +387,10 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin gamma.SetBytes(gammaByte) var sumGammaiTimesEval fr.Element - sumGammaiTimesEval.Set(&_batchOpeningProof.ClaimedValues[nbDigests-1]) + sumGammaiTimesEval.Set(&batchOpeningProof.ClaimedValues[nbDigests-1]) for i := nbDigests - 2; i >= 0; i-- { sumGammaiTimesEval.Mul(&sumGammaiTimesEval, &gamma). - Add(&sumGammaiTimesEval, &_batchOpeningProof.ClaimedValues[i]) + Add(&sumGammaiTimesEval, &batchOpeningProof.ClaimedValues[i]) } var sumGammaiTimesEvalBigInt big.Int @@ -451,7 +409,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin var sumGammaiTimesDigestsG1Aff bw6761.G1Affine _digests := make([]bw6761.G1Affine, len(digests)) for i := 0; i < len(digests); i++ { - _digests[i].Set(digests[i].(*bw6761.G1Affine)) + _digests[i].Set(&digests[i]) } sumGammaiTimesDigestsG1Aff.MultiExp(_digests, gammai) @@ -467,7 +425,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac bw6761.G2Jac var pointBigInt big.Int - _batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) + batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -480,7 +438,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [-H(alpha)]G1Aff var negH bw6761.G1Affine - negH.Neg(&_batchOpeningProof.H) + negH.Neg(&batchOpeningProof.H) // check the pairing equation check, err := bw6761.PairingCheck( @@ -491,7 +449,41 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin return err } if !check { - return polynomial.ErrVerifyBatchOpeningSinglePoint + return ErrVerifyBatchOpeningSinglePoint } return nil } + +// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form +func dividePolyByXminusA(d *fft.Domain, f polynomial.Polynomial, fa, a fr.Element) polynomial.Polynomial { + + // padd f so it has size d.Cardinality + _f := make([]fr.Element, d.Cardinality) + copy(_f, f) + + // compute the quotient (f-f(a))/(x-a) + d.FFT(_f, fft.DIF, 0) + + // bit reverse shift + bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) + + accumulator := fr.One() + + s := make([]fr.Element, len(_f)) + for i := 0; i < len(s); i++ { + irev := bits.Reverse64(uint64(i)) >> bShift + s[irev].Sub(&accumulator, &a) + accumulator.Mul(&accumulator, &d.Generator) + } + s = fr.BatchInvert(s) + + for i := 0; i < len(_f); i++ { + _f[i].Sub(&_f[i], &fa) + _f[i].Mul(&_f[i], &s[i]) + } + + d.FFTInverse(_f, fft.DIT, 0) + + // the result is of degree deg(f)-1 + return _f[:len(f)-1] +} diff --git a/ecc/bw6-761/fr/polynomial/kzg/kzg_test.go b/ecc/bw6-761/fr/kzg/kzg_test.go similarity index 68% rename from ecc/bw6-761/fr/polynomial/kzg/kzg_test.go rename to ecc/bw6-761/fr/kzg/kzg_test.go index 374bd60f2..6929787d9 100644 --- a/ecc/bw6-761/fr/polynomial/kzg/kzg_test.go +++ b/ecc/bw6-761/fr/kzg/kzg_test.go @@ -25,19 +25,21 @@ import ( "github.com/consensys/gnark-crypto/ecc/bw6-761" "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/fft" - bw6761_pol "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" ) -var _alphaSetup fr.Element - -func init() { - //_alphaSetup.SetRandom() - _alphaSetup.SetString("1234") +// NewScheme returns a new KZG scheme. +// This should be used for testing purpose only +// it creates a new FFT domain and a new SRS without randomness +func NewScheme(size int) *Scheme { + return &Scheme{ + SRS: NewSRS(size, new(big.Int).SetInt64(42)), + Domain: fft.NewDomain(uint64(size), 0, false), + } } -func randomPolynomial(size int) bw6761_pol.Polynomial { - f := make(bw6761_pol.Polynomial, size) +func randomPolynomial(size int) polynomial.Polynomial { + f := make(polynomial.Polynomial, size) for i := 0; i < size; i++ { f[i].SetRandom() } @@ -51,7 +53,7 @@ func TestDividePolyByXminusA(t *testing.T) { domain := fft.NewDomain(uint64(sizePol), 0, false) // build random polynomial - pol := make(bw6761_pol.Polynomial, sizePol) + pol := make(polynomial.Polynomial, sizePol) for i := 0; i < sizePol; i++ { pol[i].SetRandom() } @@ -59,10 +61,10 @@ func TestDividePolyByXminusA(t *testing.T) { // evaluate the polynomial at a random point var point fr.Element point.SetRandom() - evaluation := pol.Eval(&point).(fr.Element) + evaluation := pol.Eval(&point) // compute f-f(a)/x-a - h := dividePolyByXminusA(*domain, pol, evaluation, point) + h := dividePolyByXminusA(domain, pol, evaluation, point) if len(h) != 229 { t.Fatal("inconsistant size of quotient") @@ -72,10 +74,10 @@ func TestDividePolyByXminusA(t *testing.T) { var randPoint, xminusa fr.Element randPoint.SetRandom() - polRandpoint := pol.Eval(&randPoint).(fr.Element) + polRandpoint := pol.Eval(&randPoint) polRandpoint.Sub(&polRandpoint, &evaluation) // f(rand)-f(point) - hRandPoint := h.Eval(&randPoint).(fr.Element) + hRandPoint := h.Eval(&randPoint) xminusa.Sub(&randPoint, &point) // rand-point // f(rand)-f(point) ==? h(rand)*(rand-point) @@ -89,24 +91,24 @@ func TestDividePolyByXminusA(t *testing.T) { func TestSerialization(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + srs := NewSRS(64, new(big.Int).SetInt64(42)) // serialize it... var buf bytes.Buffer - _, err := s.WriteTo(&buf) + _, err := srs.WriteTo(&buf) if err != nil { t.Fatal(err) } // reconstruct the scheme - var _s Scheme - _, err = _s.ReadFrom(&buf) + var _srs SRS + _, err = _srs.ReadFrom(&buf) if err != nil { t.Fatal(err) } // compare - if !reflect.DeepEqual(s, &_s) { + if !reflect.DeepEqual(srs, &_srs) { t.Fatal("scheme serialization failed") } @@ -115,26 +117,26 @@ func TestSerialization(t *testing.T) { func TestCommit(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial - f := make(bw6761_pol.Polynomial, 60) + f := make(polynomial.Polynomial, 60) for i := 0; i < 60; i++ { f[i].SetRandom() } // commit using the method from KZG - _kzgCommit, err := s.Commit(&f) + _kzgCommit, err := s.Commit(f) if err != nil { t.Fatal(err) } var kzgCommit bw6761.G1Affine - kzgCommit.Set(_kzgCommit.(*bw6761.G1Affine)) + kzgCommit.Unmarshal(_kzgCommit.Marshal()) // check commitment using manual commit var x fr.Element - x.SetString("1234") - fx := f.Eval(&x).(fr.Element) + x.SetString("42") + fx := f.Eval(&x) var fxbi big.Int fx.ToBigIntRegular(&fxbi) var manualCommit bw6761.G1Affine @@ -151,13 +153,13 @@ func TestCommit(t *testing.T) { func TestVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial f := randomPolynomial(60) // commit the polynomial - digest, err := s.Commit(&f) + digest, err := s.Commit(f) if err != nil { t.Fatal(err) } @@ -165,28 +167,26 @@ func TestVerifySinglePoint(t *testing.T) { // compute opening proof at a random point var point fr.Element point.SetString("4321") - proof, err := s.Open(&point, &f) + proof, err := s.Open(&point, f) if err != nil { t.Fatal(err) } // verify the claimed valued - _proof := proof.(*Proof) - expected := f.Eval(point).(fr.Element) - if !_proof.ClaimedValue.Equal(&expected) { + expected := f.Eval(&point) + if !proof.ClaimedValue.Equal(&expected) { t.Fatal("inconsistant claimed value") } // verify correct proof - err = s.Verify(digest, proof) + err = s.Verify(&digest, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof = proof.(*Proof) - _proof.ClaimedValue.Double(&_proof.ClaimedValue) - err = s.Verify(digest, _proof) + proof.ClaimedValue.Double(&proof.ClaimedValue) + err = s.Verify(&digest, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -195,17 +195,16 @@ func TestVerifySinglePoint(t *testing.T) { func TestBatchVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create polynomials f := make([]polynomial.Polynomial, 10) for i := 0; i < 10; i++ { - _f := randomPolynomial(60) - f[i] = &_f + f[i] = randomPolynomial(60) } // commit the polynomials - digests := make([]polynomial.Digest, 10) + digests := make([]Digest, 10) for i := 0; i < 10; i++ { digests[i], _ = s.Commit(f[i]) @@ -220,23 +219,22 @@ func TestBatchVerifySinglePoint(t *testing.T) { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { t.Fatal("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof.ClaimedValues[0].Double(&_proof.ClaimedValues[0]) - err = s.BatchVerifySinglePoint(digests, _proof) + proof.ClaimedValues[0].Double(&proof.ClaimedValues[0]) + err = s.BatchVerifySinglePoint(digests, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -247,20 +245,20 @@ const benchSize = 1 << 16 func BenchmarkKZGCommit(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Commit(&p) + _, _ = s.Commit(p) } } func BenchmarkKZGOpen(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -269,13 +267,13 @@ func BenchmarkKZGOpen(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = s.Open(r, &p) + _, _ = s.Open(&r, p) } } func BenchmarkKZGVerify(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) @@ -283,36 +281,35 @@ func BenchmarkKZGVerify(b *testing.B) { r.SetRandom() // commit - comm, err := s.Commit(&p) + comm, err := s.Commit(p) if err != nil { b.Fatal(err) } // open - openingProof, err := s.Open(r, &p) + openingProof, err := s.Open(&r, p) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.Verify(comm, openingProof) + s.Verify(&comm, &openingProof) } } func BenchmarkKZGBatchOpen10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -322,23 +319,22 @@ func BenchmarkKZGBatchOpen10(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) } } func BenchmarkKZGBatchVerify10(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // 10 random polynomials var ps [10]polynomial.Polynomial for i := 0; i < 10; i++ { - _p := randomPolynomial(benchSize / 2) - ps[i] = &_p + ps[i] = randomPolynomial(benchSize / 2) } // commitments - var commitments [10]polynomial.Digest + var commitments [10]Digest for i := 0; i < 10; i++ { commitments[i], _ = s.Commit(ps[i]) } @@ -346,13 +342,13 @@ func BenchmarkKZGBatchVerify10(b *testing.B) { var r fr.Element r.SetRandom() - proof, err := s.BatchOpenSinglePoint(r, commitments[:], ps[:]) + proof, err := s.BatchOpenSinglePoint(&r, commitments[:], ps[:]) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { - s.BatchVerifySinglePoint(commitments[:], proof) + s.BatchVerifySinglePoint(commitments[:], &proof) } } diff --git a/ecc/bw6-761/fr/polynomial/kzg/util.go b/ecc/bw6-761/fr/polynomial/kzg/util.go deleted file mode 100644 index d9c678272..000000000 --- a/ecc/bw6-761/fr/polynomial/kzg/util.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package kzg - -import ( - "math/bits" - - "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" - "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/fft" - bw6761_pol "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" -) - -// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form -func dividePolyByXminusA(d fft.Domain, f bw6761_pol.Polynomial, fa, a fr.Element) bw6761_pol.Polynomial { - - // padd f so it has size d.Cardinality - _f := make([]fr.Element, d.Cardinality) - copy(_f, f) - - // compute the quotient (f-f(a))/(x-a) - d.FFT(_f, fft.DIF, 0) - - // bit reverse shift - bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) - - accumulator := fr.One() - - s := make([]fr.Element, len(_f)) - for i := 0; i < len(s); i++ { - irev := bits.Reverse64(uint64(i)) >> bShift - s[irev].Sub(&accumulator, &a) - accumulator.Mul(&accumulator, &d.Generator) - } - s = fr.BatchInvert(s) - - for i := 0; i < len(_f); i++ { - _f[i].Sub(&_f[i], &fa) - _f[i].Mul(&_f[i], &s[i]) - } - - d.FFTInverse(_f, fft.DIT, 0) - - // the result is of degree deg(f)-1 - return _f[:len(f)-1] -} diff --git a/ecc/bw6-761/fr/polynomial/mockcommitment/doc.go b/ecc/bw6-761/fr/polynomial/mockcommitment/doc.go deleted file mode 100644 index 5473a4d43..000000000 --- a/ecc/bw6-761/fr/polynomial/mockcommitment/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -// Package mockcommitment provides a mock commitment scheme, for development and test purposes. -package mockcommitment diff --git a/ecc/bw6-761/fr/polynomial/mockcommitment/mock.go b/ecc/bw6-761/fr/polynomial/mockcommitment/mock.go deleted file mode 100644 index 3c0d43419..000000000 --- a/ecc/bw6-761/fr/polynomial/mockcommitment/mock.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "io" - - "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" - bw6761 "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -// Scheme mock commitment, useful for testing polynomial based IOP -// like PLONK, where the scheme should not depend on which polynomial commitment scheme -// is used. -type Scheme struct{} - -// WriteTo panics -func (s *Scheme) WriteTo(w io.Writer) (n int64, err error) { - panic("not implemented") -} - -// ReadFrom panics -func (s *Scheme) ReadFrom(r io.Reader) (n int64, err error) { - panic("not implemented") -} - -// Commit returns the first coefficient of p -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { - _p := p.(*bw6761.Polynomial) - var res fr.Element - res.SetInterface((*_p)[0]) - return &res, nil -} - -// Open computes an opening proof of _p at _val. -// Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { - - res := MockProof{} - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(p.Eval(point)) - - return &res, nil -} - -// Verify mock implementation of verify -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - return nil -} - -// BatchOpenSinglePoint computes a batch opening proof for _p at _val. -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { - - var res MockBatchProofsSinglePoint - res.ClaimedValues = make([]fr.Element, len(polynomials)) - res.Point.SetInterface(point) - - for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i].SetInterface(polynomials[i].Eval(point)) - } - - return &res, nil -} - -// BatchVerifySinglePoint computes a batch opening proof for -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { - - return nil - -} diff --git a/ecc/bw6-761/fr/polynomial/mockcommitment/mock_test.go b/ecc/bw6-761/fr/polynomial/mockcommitment/mock_test.go deleted file mode 100644 index cd19a42e5..000000000 --- a/ecc/bw6-761/fr/polynomial/mockcommitment/mock_test.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import ( - "testing" - - "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" - bw6761_pol "github.com/consensys/gnark-crypto/ecc/bw6-761/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -func TestCommit(t *testing.T) { - - size := 60 - f := make(bw6761_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var _c fr.Element - _c.SetInterface(c) - - if !_c.Equal(&f[0]) { - t.Fatal("err mock commitment (commit)") - } -} - -func TestVerifySinglePoint(t *testing.T) { - - size := 60 - f := make(bw6761_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var point fr.Element - point.SetRandom() - - o, err := s.Open(point, &f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed valued - res := o.(*MockProof) - expected := f.Eval(point).(fr.Element) - if !res.ClaimedValue.Equal(&expected) { - t.Fatal("err mock commitment (open)") - } - - err = s.Verify(c, o) - if err != nil { - t.Fatal(err) - } - -} - -func TestBatchVerifySinglePoint(t *testing.T) { - - // create polynomials - size := 60 - f := make([]polynomial.Polynomial, 10) - for i := 0; i < 10; i++ { - _f := make(bw6761_pol.Polynomial, size) - for i := 0; i < size; i++ { - _f[i].SetRandom() - } - f[i] = &_f - } - - var s Scheme - - // commit the polynomials - digests := make([]polynomial.Digest, 10) - for i := 0; i < 10; i++ { - digests[i], _ = s.Commit(f[i]) - } - - var point fr.Element - point.SetRandom() - - proof, err := s.BatchOpenSinglePoint(&point, digests, f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed values - _proof := proof.(*MockBatchProofsSinglePoint) - for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { - t.Fatal("inconsistant claimed values") - } - } - - // verify the proof - err = s.BatchVerifySinglePoint(digests, proof) - if err != nil { - t.Fatal(err) - } - -} diff --git a/ecc/bw6-761/fr/polynomial/mockcommitment/proof.go b/ecc/bw6-761/fr/polynomial/mockcommitment/proof.go deleted file mode 100644 index 5ac2d6e36..000000000 --- a/ecc/bw6-761/fr/polynomial/mockcommitment/proof.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" - -// MockProof empty struct -type MockProof struct { - Point fr.Element - ClaimedValue fr.Element -} - -func (mp *MockProof) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bw6-761/fr/polynomial/mockcommitment/proof_single_point.go b/ecc/bw6-761/fr/polynomial/mockcommitment/proof_single_point.go deleted file mode 100644 index fc1ddc2b2..000000000 --- a/ecc/bw6-761/fr/polynomial/mockcommitment/proof_single_point.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by consensys/gnark-crypto DO NOT EDIT - -package mockcommitment - -import "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" - -// MockBatchProofsSinglePoint empty struct -type MockBatchProofsSinglePoint struct { - Point fr.Element - ClaimedValues []fr.Element -} - -func (mp *MockBatchProofsSinglePoint) Marshal() []byte { - panic("not implemented") -} diff --git a/ecc/bw6-761/fr/polynomial/polynomial.go b/ecc/bw6-761/fr/polynomial/polynomial.go index 325a0ad40..002ba542d 100644 --- a/ecc/bw6-761/fr/polynomial/polynomial.go +++ b/ecc/bw6-761/fr/polynomial/polynomial.go @@ -18,7 +18,6 @@ package polynomial import ( "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" - "github.com/consensys/gnark-crypto/polynomial" ) // Polynomial polynomial represented by coefficients bn254 fr field. @@ -31,13 +30,11 @@ func (p *Polynomial) Degree() uint64 { // Eval evaluates p at v // returns a fr.Element -func (p *Polynomial) Eval(v interface{}) interface{} { - var _v fr.Element - _v.SetInterface(v) +func (p *Polynomial) Eval(v *fr.Element) fr.Element { res := (*p)[len(*p)-1] for i := len(*p) - 2; i >= 0; i-- { - res.Mul(&res, &_v) + res.Mul(&res, v) res.Add(&res, &(*p)[i]) } @@ -45,48 +42,39 @@ func (p *Polynomial) Eval(v interface{}) interface{} { } // Clone returns a copy of the polynomial -func (p *Polynomial) Clone() polynomial.Polynomial { +func (p *Polynomial) Clone() Polynomial { _p := make(Polynomial, len(*p)) copy(_p, *p) - return &_p + return _p } // AddConstantInPlace adds a constant to the polynomial, modifying p -func (p *Polynomial) AddConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) AddConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Add(&(*p)[i], &_c) + (*p)[i].Add(&(*p)[i], c) } } // SubConstantInPlace subs a constant to the polynomial, modifying p -func (p *Polynomial) SubConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) SubConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Sub(&(*p)[i], &_c) + (*p)[i].Sub(&(*p)[i], c) } } // ScaleInPlace multiplies p by v, modifying p -func (p *Polynomial) ScaleInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) ScaleInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Mul(&(*p)[i], &_c) + (*p)[i].Mul(&(*p)[i], c) } } // Add adds p1 to p2 // This function allocates a new slice unless p == p1 or p == p2 -func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { +func (p *Polynomial) Add(p1, p2 Polynomial) *Polynomial { - bigger := *(p1.(*Polynomial)) - smaller := *(p2.(*Polynomial)) + bigger := p1 + smaller := p2 if len(bigger) < len(smaller) { bigger, smaller = smaller, bigger } @@ -116,18 +104,17 @@ func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { } // Equal checks equality between two polynomials -func (p *Polynomial) Equal(p1 polynomial.Polynomial) bool { - _p1 := *(p1.(*Polynomial)) - if (p == nil) != (_p1 == nil) { +func (p *Polynomial) Equal(p1 Polynomial) bool { + if (*p == nil) != (p1 == nil) { return false } - if len(*p) != len(_p1) { + if len(*p) != len(p1) { return false } - for i := range _p1 { - if !(*p)[i].Equal(&_p1[i]) { + for i := range p1 { + if !(*p)[i].Equal(&p1[i]) { return false } } diff --git a/ecc/bw6-761/fr/polynomial/polynomial_test.go b/ecc/bw6-761/fr/polynomial/polynomial_test.go index c01bc531c..8a00a1daa 100644 --- a/ecc/bw6-761/fr/polynomial/polynomial_test.go +++ b/ecc/bw6-761/fr/polynomial/polynomial_test.go @@ -46,7 +46,7 @@ func TestPolynomialEval(t *testing.T) { expectedEval.Div(&expectedEval, &den) // compute purported evaluation - purportedEval := f.Eval(&point).(fr.Element) + purportedEval := f.Eval(&point) // check if !purportedEval.Equal(&expectedEval) { @@ -160,27 +160,27 @@ func TestPolynomialAdd(t *testing.T) { // caller is empty var g Polynomial - g.Add(&f1, &f2) - if !g.Equal(&expectedSum) { + g.Add(f1, f2) + if !g.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } // all operands are distincts _f1 := f1.Clone() - _f1.Add(&f1, &f2) - if !_f1.Equal(&expectedSum) { + _f1.Add(f1, f2) + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } @@ -188,10 +188,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 := f2.Clone() _f1.Add(_f1, _f2) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } @@ -199,10 +199,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 = f2.Clone() _f1.Add(_f2, _f1) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } } diff --git a/ecc/bw6-761/g1.go b/ecc/bw6-761/g1.go index b33c58f69..0a62b9763 100644 --- a/ecc/bw6-761/g1.go +++ b/ecc/bw6-761/g1.go @@ -59,6 +59,30 @@ func (p *G1Affine) ScalarMultiplication(a *G1Affine, s *big.Int) *G1Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Add(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G1Affine) Sub(a, b *G1Affine) *G1Affine { + var p1, p2 G1Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G1Affine) Equal(a *G1Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/ecc/bw6-761/g2.go b/ecc/bw6-761/g2.go index 92ddefa31..a14a3ff85 100644 --- a/ecc/bw6-761/g2.go +++ b/ecc/bw6-761/g2.go @@ -64,6 +64,30 @@ func (p *G2Affine) ScalarMultiplication(a *G2Affine, s *big.Int) *G2Affine { return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Add(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *G2Affine) Sub(a, b *G2Affine) *G2Affine { + var p1, p2 G2Jac + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} + // Equal tests if two points (in Affine coordinates) are equal func (p *G2Affine) Equal(a *G2Affine) bool { return p.X.Equal(&a.X) && p.Y.Equal(&a.Y) diff --git a/internal/generator/ecc/template/point.go.tmpl b/internal/generator/ecc/template/point.go.tmpl index 3d20fece0..05849a34c 100644 --- a/internal/generator/ecc/template/point.go.tmpl +++ b/internal/generator/ecc/template/point.go.tmpl @@ -61,6 +61,29 @@ func (p *{{ $TAffine }}) ScalarMultiplication(a *{{ $TAffine }}, s *big.Int) *{{ return p } +// Add adds two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *{{ $TAffine }}) Add(a, b *{{ $TAffine }}) *{{ $TAffine }} { + var p1, p2 {{ $TJacobian }} + p1.FromAffine(a) + p2.FromAffine(b) + p1.AddAssign(&p2) + p.FromJacobian(&p1) + return p +} + +// Sub subs two point in affine coordinates. +// This should rarely be used as it is very inneficient compared to Jacobian +// TODO implement affine addition formula +func (p *{{ $TAffine }}) Sub(a, b *{{ $TAffine }}) *{{ $TAffine }} { + var p1, p2 {{ $TJacobian }} + p1.FromAffine(a) + p2.FromAffine(b) + p1.SubAssign(&p2) + p.FromJacobian(&p1) + return p +} // Equal tests if two points (in Affine coordinates) are equal diff --git a/internal/generator/kzg/generate.go b/internal/generator/kzg/generate.go new file mode 100644 index 000000000..8f8ed4201 --- /dev/null +++ b/internal/generator/kzg/generate.go @@ -0,0 +1,23 @@ +package kzg + +import ( + "path/filepath" + + "github.com/consensys/bavard" + "github.com/consensys/gnark-crypto/internal/generator/config" +) + +func Generate(conf config.Curve, baseDir string, bgen *bavard.BatchGenerator) error { + + // kzg commitment scheme + conf.Package = "kzg" + entries := []bavard.Entry{ + {File: filepath.Join(baseDir, "doc.go"), Templates: []string{"doc.go.tmpl"}}, + {File: filepath.Join(baseDir, "kzg.go"), Templates: []string{"kzg.go.tmpl"}}, + {File: filepath.Join(baseDir, "kzg_test.go"), Templates: []string{"kzg.test.go.tmpl"}}, + {File: filepath.Join(baseDir, "fuzz.go"), Templates: []string{"fuzz.go.tmpl"}, BuildTag: "gofuzz"}, + {File: filepath.Join(baseDir, "fuzz_test.go"), Templates: []string{"fuzz.test.go.tmpl"}, BuildTag: "gofuzz"}, + } + return bgen.Generate(conf, conf.Package, "./kzg/template/", entries...) + +} diff --git a/internal/generator/polynomial/template/commitment_kzg/doc.go.tmpl b/internal/generator/kzg/template/doc.go.tmpl similarity index 100% rename from internal/generator/polynomial/template/commitment_kzg/doc.go.tmpl rename to internal/generator/kzg/template/doc.go.tmpl diff --git a/internal/generator/polynomial/template/commitment_kzg/fuzz.go.tmpl b/internal/generator/kzg/template/fuzz.go.tmpl similarity index 66% rename from internal/generator/polynomial/template/commitment_kzg/fuzz.go.tmpl rename to internal/generator/kzg/template/fuzz.go.tmpl index cddad7b64..9ee81d02f 100644 --- a/internal/generator/polynomial/template/commitment_kzg/fuzz.go.tmpl +++ b/internal/generator/kzg/template/fuzz.go.tmpl @@ -1,8 +1,7 @@ import ( "bytes" "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" - {{ .CurvePackage }}_pol "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr/polynomial" ) const ( @@ -28,15 +27,14 @@ func Fuzz(data []byte) int { // create polynomials f := make([]polynomial.Polynomial, size /2 ) for i := 0; i < len(f); i++ { - _f := make({{ .CurvePackage }}_pol.Polynomial, size) - for j:=0;j= s.Domain.Cardinality { - return nil, errUnsupportedSize + return Digest{}, ErrInvalidSize } - var res Digest - _p := p.(*{{ .CurvePackage }}_pol.Polynomial) + var res {{ .CurvePackage }}.G1Affine + // ensure we don't modify p - pCopy := make({{ .CurvePackage }}_pol.Polynomial, s.Domain.Cardinality) - copy(pCopy, *_p) + pCopy := make(polynomial.Polynomial, s.Domain.Cardinality) + copy(pCopy, p) - parallel.Execute(len(*_p), func(start, end int) { + parallel.Execute(len(p), func(start, end int) { for i := start; i < end; i++ { pCopy[i].FromMont() } }) res.MultiExp(s.SRS.G1, pCopy) - return &res, nil + return res, nil } -// Open computes an opening proof of _p at _val. +// Open computes an opening proof of p at _val. // Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { +func (s *Scheme) Open(point *fr.Element, p polynomial.Polynomial) (Proof, error) { if p.Degree() >= s.Domain.Cardinality { panic("[Open] Size of polynomial exceeds the size supported by the scheme") } // build the proof - var res Proof - claimedValue := p.Eval(point) - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(claimedValue) + res := Proof{ + Point: *point, + ClaimedValue: p.Eval(point), + } // compute H - _p := p.(*{{ .CurvePackage }}_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_p, res.ClaimedValue, res.Point) + + h := dividePolyByXminusA(s.Domain, p, res.ClaimedValue, res.Point) // commit to H - c, err := s.Commit(&h) + c, err := s.Commit(h) if err != nil { - return nil, err + return Proof{}, err } - res.H.Set(c.(*{{ .CurvePackage }}.G1Affine)) + res.H.Set(&c) - return &res, nil + return res, nil } // Verify verifies a KZG opening proof at a single point -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - - _commitment := commitment.(*{{ .CurvePackage }}.G1Affine) - _proof := proof.(*Proof) - - // verify that the committed quotient and the commitment are in the correct subgroup - subgroupCheck := _proof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 - } - subgroupCheck = _commitment.IsInSubGroup() - if !subgroupCheck { - return errDigestNotInG1 - } +func (s *Scheme) Verify(commitment *Digest, proof *Proof) error { // comm(f(a)) var claimedValueG1Aff {{ .CurvePackage }}.G1Affine var claimedValueBigInt big.Int - _proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) + proof.ClaimedValue.ToBigIntRegular(&claimedValueBigInt) claimedValueG1Aff.ScalarMultiplication(&s.SRS.G1[0], &claimedValueBigInt) // [f(alpha) - f(a)]G1Jac var fminusfaG1Jac, tmpG1Jac {{ .CurvePackage }}.G1Jac - fminusfaG1Jac.FromAffine(_commitment) + fminusfaG1Jac.FromAffine(commitment) tmpG1Jac.FromAffine(&claimedValueG1Aff) fminusfaG1Jac.SubAssign(&tmpG1Jac) // [-H(alpha)]G1Aff var negH {{ .CurvePackage }}.G1Affine - negH.Neg(&_proof.H) + negH.Neg(&proof.H) // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac {{ .CurvePackage }}.G2Jac var pointBigInt big.Int - _proof.Point.ToBigIntRegular(&pointBigInt) + proof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -303,17 +269,21 @@ func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningPr return err } if !check { - return polynomial.ErrVerifyOpeningProof + return ErrVerifyOpeningProof } return nil } -// BatchOpenSinglePoint creates a batch opening proof of several polynomials at a single point -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { +// BatchOpenSinglePoint creates a batch opening proof at _val of a list of polynomials. +// It's an interactive protocol, made non interactive using Fiat Shamir. +// point is the point at which the polynomials are opened. +// digests is the list of committed polynomials to open, need to derive the challenge using Fiat Shamir. +// polynomials is the list of polynomials to open. +func (s *Scheme) BatchOpenSinglePoint(point *fr.Element, digests []Digest, polynomials []polynomial.Polynomial) (BatchProofsSinglePoint, error) { nbDigests := len(digests) if nbDigests != len(polynomials) { - return nil, errNbDigestsNeqNbPolynomials + return BatchProofsSinglePoint{}, ErrInvalidNbDigests } var res BatchProofsSinglePoint @@ -321,25 +291,25 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di // compute the purported values res.ClaimedValues = make([]fr.Element, len(polynomials)) for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i] = polynomials[i].Eval(point).(fr.Element) + res.ClaimedValues[i] = polynomials[i].Eval(point) } // set the point at which the evaluation is done - res.Point.SetInterface(point) + res.Point.Set(point) // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") if err := fs.Bind("gamma", res.Point.Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } for i := 0; i < len(digests); i++ { if err := fs.Bind("gamma", digests[i].Marshal()); err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } } gammaByte, err := fs.ComputeChallenge("gamma") if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } var gamma fr.Element gamma.SetBytes(gammaByte) @@ -356,45 +326,35 @@ func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Di } // compute H - _sumGammaiTimesPol := sumGammaiTimesPol.(*{{ .CurvePackage }}_pol.Polynomial) - h := dividePolyByXminusA(s.Domain, *_sumGammaiTimesPol, sumGammaiTimesEval, res.Point) - c, err := s.Commit(&h) + h := dividePolyByXminusA(s.Domain, sumGammaiTimesPol, sumGammaiTimesEval, res.Point) + c, err := s.Commit(h) if err != nil { - return nil, err + return BatchProofsSinglePoint{}, err } - res.H.Set(c.(*{{ .CurvePackage }}.G1Affine)) - return &res, nil + res.H.Set(&c) + + return res, nil } -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { +// BatchVerifySinglePoint verifies a batched opening proof at a single point of a list of polynomials. +// point: point at which the polynomials are evaluated +// claimedValues: claimed values of the polynomials at _val +// commitments: list of commitments to the polynomials which are opened +// batchOpeningProof: the batched opening proof at a single point of the polynomials. +func (s *Scheme) BatchVerifySinglePoint(digests []Digest, batchOpeningProof *BatchProofsSinglePoint) error { nbDigests := len(digests) - _batchOpeningProof := batchOpeningProof.(*BatchProofsSinglePoint) // check consistancy between numbers of claims vs number of digests - if len(digests) != len(_batchOpeningProof.ClaimedValues) { - return errNbDigestsNeqNbPolynomials - } - - // subgroup checks for digests and the proof - subgroupCheck := true - for i := 0; i < len(digests); i++ { - _digest := digests[i].(*{{ .CurvePackage }}.G1Affine) - subgroupCheck = subgroupCheck && _digest.IsInSubGroup() - } - if !subgroupCheck { - return errDigestNotInG1 - } - subgroupCheck = subgroupCheck && _batchOpeningProof.H.IsInSubGroup() - if !subgroupCheck { - return errProofNotInG1 + if len(digests) != len(batchOpeningProof.ClaimedValues) { + return ErrInvalidNbDigests } // derive the challenge gamma, binded to the point and the commitments fs := fiatshamir.NewTranscript(fiatshamir.SHA256, "gamma") - err := fs.Bind("gamma", _batchOpeningProof.Point.Marshal()) + err := fs.Bind("gamma", batchOpeningProof.Point.Marshal()) if err != nil { return err } @@ -412,10 +372,10 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin gamma.SetBytes(gammaByte) var sumGammaiTimesEval fr.Element - sumGammaiTimesEval.Set(&_batchOpeningProof.ClaimedValues[nbDigests-1]) + sumGammaiTimesEval.Set(&batchOpeningProof.ClaimedValues[nbDigests-1]) for i := nbDigests - 2; i >= 0; i-- { sumGammaiTimesEval.Mul(&sumGammaiTimesEval, &gamma). - Add(&sumGammaiTimesEval, &_batchOpeningProof.ClaimedValues[i]) + Add(&sumGammaiTimesEval, &batchOpeningProof.ClaimedValues[i]) } var sumGammaiTimesEvalBigInt big.Int @@ -434,7 +394,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin var sumGammaiTimesDigestsG1Aff {{ .CurvePackage }}.G1Affine _digests := make([]{{ .CurvePackage }}.G1Affine, len(digests)) for i := 0; i < len(digests); i++ { - _digests[i].Set(digests[i].(*{{ .CurvePackage }}.G1Affine)) + _digests[i].Set(&digests[i]) } sumGammaiTimesDigestsG1Aff.MultiExp(_digests, gammai) @@ -450,7 +410,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [alpha-a]G2Jac var alphaMinusaG2Jac, genG2Jac, alphaG2Jac {{ .CurvePackage }}.G2Jac var pointBigInt big.Int - _batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) + batchOpeningProof.Point.ToBigIntRegular(&pointBigInt) genG2Jac.FromAffine(&s.SRS.G2[0]) alphaG2Jac.FromAffine(&s.SRS.G2[1]) alphaMinusaG2Jac.ScalarMultiplication(&genG2Jac, &pointBigInt). @@ -463,7 +423,7 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin // [-H(alpha)]G1Aff var negH {{ .CurvePackage }}.G1Affine - negH.Neg(&_batchOpeningProof.H) + negH.Neg(&batchOpeningProof.H) // check the pairing equation check, err := {{ .CurvePackage }}.PairingCheck( @@ -474,7 +434,43 @@ func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpenin return err } if !check { - return polynomial.ErrVerifyBatchOpeningSinglePoint + return ErrVerifyBatchOpeningSinglePoint } return nil } + + +// dividePolyByXminusA computes (f-f(a))/(x-a), in canonical basis, in regular form +func dividePolyByXminusA(d *fft.Domain, f polynomial.Polynomial, fa, a fr.Element) polynomial.Polynomial { + + // padd f so it has size d.Cardinality + _f := make([]fr.Element, d.Cardinality) + copy(_f, f) + + // compute the quotient (f-f(a))/(x-a) + d.FFT(_f, fft.DIF, 0) + + + // bit reverse shift + bShift := uint64(64 - bits.TrailingZeros64(d.Cardinality)) + + accumulator := fr.One() + + s := make([]fr.Element, len(_f)) + for i := 0; i < len(s); i++ { + irev := bits.Reverse64(uint64(i)) >> bShift + s[irev].Sub(&accumulator, &a) + accumulator.Mul(&accumulator, &d.Generator) + } + s = fr.BatchInvert(s) + + for i := 0; i < len(_f); i++ { + _f[i].Sub(&_f[i], &fa) + _f[i].Mul(&_f[i], &s[i]) + } + + d.FFTInverse(_f, fft.DIT, 0) + + // the result is of degree deg(f)-1 + return _f[:len(f)-1] +} diff --git a/internal/generator/polynomial/template/commitment_kzg/kzg.test.go.tmpl b/internal/generator/kzg/template/kzg.test.go.tmpl similarity index 59% rename from internal/generator/polynomial/template/commitment_kzg/kzg.test.go.tmpl rename to internal/generator/kzg/template/kzg.test.go.tmpl index dc16bcf4e..a86155d57 100644 --- a/internal/generator/polynomial/template/commitment_kzg/kzg.test.go.tmpl +++ b/internal/generator/kzg/template/kzg.test.go.tmpl @@ -7,21 +7,21 @@ import ( "github.com/consensys/gnark-crypto/ecc/{{ .Name }}" "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr/fft" - {{ .CurvePackage }}_pol "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" + "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr/polynomial" ) - -var _alphaSetup fr.Element - -func init() { - //_alphaSetup.SetRandom() - _alphaSetup.SetString("1234") +// NewScheme returns a new KZG scheme. +// This should be used for testing purpose only +// it creates a new FFT domain and a new SRS without randomness +func NewScheme(size int) *Scheme { + return &Scheme{ + SRS: NewSRS(size, new(big.Int).SetInt64(42)), + Domain: fft.NewDomain(uint64(size), 0, false), + } } - -func randomPolynomial(size int) {{ .CurvePackage }}_pol.Polynomial { - f := make({{ .CurvePackage }}_pol.Polynomial, size) +func randomPolynomial(size int) polynomial.Polynomial { + f := make(polynomial.Polynomial, size) for i := 0; i < size; i++ { f[i].SetRandom() } @@ -35,7 +35,7 @@ func TestDividePolyByXminusA(t *testing.T) { domain := fft.NewDomain(uint64(sizePol), 0, false) // build random polynomial - pol := make({{ .CurvePackage }}_pol.Polynomial, sizePol) + pol := make(polynomial.Polynomial, sizePol) for i := 0; i < sizePol; i++ { pol[i].SetRandom() } @@ -43,10 +43,10 @@ func TestDividePolyByXminusA(t *testing.T) { // evaluate the polynomial at a random point var point fr.Element point.SetRandom() - evaluation := pol.Eval(&point).(fr.Element) + evaluation := pol.Eval(&point) // compute f-f(a)/x-a - h := dividePolyByXminusA(*domain, pol, evaluation, point) + h := dividePolyByXminusA(domain, pol, evaluation, point) if len(h) != 229 { t.Fatal("inconsistant size of quotient") @@ -55,12 +55,12 @@ func TestDividePolyByXminusA(t *testing.T) { // probabilistic test (using Schwartz Zippel lemma, evaluation at one point is enough) var randPoint, xminusa fr.Element randPoint.SetRandom() - - polRandpoint := pol.Eval(&randPoint).(fr.Element) + + polRandpoint := pol.Eval(&randPoint) polRandpoint.Sub(&polRandpoint, &evaluation) // f(rand)-f(point) - - hRandPoint := h.Eval(&randPoint).(fr.Element) - xminusa.Sub(&randPoint, &point) // rand-point + + hRandPoint := h.Eval(&randPoint) + xminusa.Sub(&randPoint, &point) // rand-point // f(rand)-f(point) ==? h(rand)*(rand-point) hRandPoint.Mul(&hRandPoint, &xminusa) @@ -73,24 +73,24 @@ func TestDividePolyByXminusA(t *testing.T) { func TestSerialization(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + srs := NewSRS(64, new(big.Int).SetInt64(42)) // serialize it... var buf bytes.Buffer - _, err := s.WriteTo(&buf) + _, err := srs.WriteTo(&buf) if err != nil { t.Fatal(err) } // reconstruct the scheme - var _s Scheme - _, err = _s.ReadFrom(&buf) + var _srs SRS + _, err = _srs.ReadFrom(&buf) if err != nil { t.Fatal(err) } // compare - if !reflect.DeepEqual(s, &_s) { + if !reflect.DeepEqual(srs, &_srs) { t.Fatal("scheme serialization failed") } @@ -99,26 +99,26 @@ func TestSerialization(t *testing.T) { func TestCommit(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial - f := make({{ .CurvePackage }}_pol.Polynomial, 60) + f := make(polynomial.Polynomial, 60) for i := 0; i < 60; i++ { f[i].SetRandom() } // commit using the method from KZG - _kzgCommit, err := s.Commit(&f) + _kzgCommit, err := s.Commit(f) if err != nil { t.Fatal(err) } var kzgCommit {{ .CurvePackage }}.G1Affine - kzgCommit.Set(_kzgCommit.(*{{ .CurvePackage }}.G1Affine)) + kzgCommit.Unmarshal(_kzgCommit.Marshal()) // check commitment using manual commit - var x fr.Element - x.SetString("1234") - fx := f.Eval(&x).(fr.Element) + var x fr.Element + x.SetString("42") + fx := f.Eval(&x) var fxbi big.Int fx.ToBigIntRegular(&fxbi) var manualCommit {{ .CurvePackage }}.G1Affine @@ -132,18 +132,16 @@ func TestCommit(t *testing.T) { } - - func TestVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create a polynomial f := randomPolynomial(60) // commit the polynomial - digest, err := s.Commit(&f) + digest, err := s.Commit(f) if err != nil { t.Fatal(err) } @@ -151,28 +149,26 @@ func TestVerifySinglePoint(t *testing.T) { // compute opening proof at a random point var point fr.Element point.SetString("4321") - proof, err := s.Open(&point, &f) + proof, err := s.Open(&point, f) if err != nil { t.Fatal(err) } // verify the claimed valued - _proof := proof.(*Proof) - expected := f.Eval(point).(fr.Element) - if !_proof.ClaimedValue.Equal(&expected) { + expected := f.Eval(&point) + if !proof.ClaimedValue.Equal(&expected) { t.Fatal("inconsistant claimed value") } // verify correct proof - err = s.Verify(digest, proof) + err = s.Verify(&digest, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof = proof.(*Proof) - _proof.ClaimedValue.Double(&_proof.ClaimedValue) - err = s.Verify(digest, _proof) + proof.ClaimedValue.Double(&proof.ClaimedValue) + err = s.Verify(&digest, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -181,17 +177,16 @@ func TestVerifySinglePoint(t *testing.T) { func TestBatchVerifySinglePoint(t *testing.T) { // create a KZG scheme - s := NewScheme(64, _alphaSetup) + s := NewScheme(64) // create polynomials f := make([]polynomial.Polynomial, 10) for i := 0; i < 10; i++ { - _f := randomPolynomial(60) - f[i] = &_f + f[i] = randomPolynomial(60) } // commit the polynomials - digests := make([]polynomial.Digest, 10) + digests := make([]Digest, 10) for i := 0; i < 10; i++ { digests[i], _ = s.Commit(f[i]) @@ -206,23 +201,22 @@ func TestBatchVerifySinglePoint(t *testing.T) { } // verify the claimed values - _proof := proof.(*BatchProofsSinglePoint) for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { + expectedClaim := f[i].Eval(&point) + if !expectedClaim.Equal(&proof.ClaimedValues[i]) { t.Fatal("inconsistant claimed values") } } // verify correct proof - err = s.BatchVerifySinglePoint(digests, proof) + err = s.BatchVerifySinglePoint(digests, &proof) if err != nil { t.Fatal(err) } // verify wrong proof - _proof.ClaimedValues[0].Double(&_proof.ClaimedValues[0]) - err = s.BatchVerifySinglePoint(digests, _proof) + proof.ClaimedValues[0].Double(&proof.ClaimedValues[0]) + err = s.BatchVerifySinglePoint(digests, &proof) if err == nil { t.Fatal("verifying wrong proof should have failed") } @@ -233,115 +227,110 @@ const benchSize = 1 << 16 func BenchmarkKZGCommit(b *testing.B) { // kzg scheme - s := NewScheme(benchSize, _alphaSetup) + s := NewScheme(benchSize) // random polynomial p := randomPolynomial(benchSize / 2) b.ResetTimer() - for i:=0;i> bShift - s[irev].Sub(&accumulator, &a) - accumulator.Mul(&accumulator, &d.Generator) - } - s = fr.BatchInvert(s) - - for i := 0; i < len(_f); i++ { - _f[i].Sub(&_f[i], &fa) - _f[i].Mul(&_f[i], &s[i]) - } - - d.FFTInverse(_f, fft.DIT, 0) - - // the result is of degree deg(f)-1 - return _f[:len(f)-1] -} diff --git a/internal/generator/polynomial/template/commitment_mock/doc.go.tmpl b/internal/generator/polynomial/template/commitment_mock/doc.go.tmpl deleted file mode 100644 index b117dd97e..000000000 --- a/internal/generator/polynomial/template/commitment_mock/doc.go.tmpl +++ /dev/null @@ -1,2 +0,0 @@ -// Package {{.Package}} provides a mock commitment scheme, for development and test purposes. -package {{.Package}} \ No newline at end of file diff --git a/internal/generator/polynomial/template/commitment_mock/mock.go.tmpl b/internal/generator/polynomial/template/commitment_mock/mock.go.tmpl deleted file mode 100644 index 5bebe0a0b..000000000 --- a/internal/generator/polynomial/template/commitment_mock/mock.go.tmpl +++ /dev/null @@ -1,67 +0,0 @@ -import ( - "io" - - "github.com/consensys/gnark-crypto/polynomial" - "github.com/consensys/gnark-crypto/ecc/{{.Name}}/fr" - {{toLower .CurvePackage}} "github.com/consensys/gnark-crypto/ecc/{{.Name}}/fr/polynomial" -) - -// Scheme mock commitment, useful for testing polynomial based IOP -// like PLONK, where the scheme should not depend on which polynomial commitment scheme -// is used. -type Scheme struct{} - -// WriteTo panics -func (s *Scheme) WriteTo(w io.Writer) (n int64, err error) { - panic("not implemented") -} - -// ReadFrom panics -func (s *Scheme) ReadFrom(r io.Reader) (n int64, err error) { - panic("not implemented") -} - -// Commit returns the first coefficient of p -func (s *Scheme) Commit(p polynomial.Polynomial) (polynomial.Digest, error) { - _p := p.(*{{ .CurvePackage }}.Polynomial) - var res fr.Element - res.SetInterface((*_p)[0]) - return &res, nil -} - -// Open computes an opening proof of _p at _val. -// Returns a MockProof, which is an empty interface. -func (s *Scheme) Open(point interface{}, p polynomial.Polynomial) (polynomial.OpeningProof, error) { - - res := MockProof{} - res.Point.SetInterface(point) - res.ClaimedValue.SetInterface(p.Eval(point)) - - return &res, nil -} - -// Verify mock implementation of verify -func (s *Scheme) Verify(commitment polynomial.Digest, proof polynomial.OpeningProof) error { - return nil -} - -// BatchOpenSinglePoint computes a batch opening proof for _p at _val. -func (s *Scheme) BatchOpenSinglePoint(point interface{}, digests []polynomial.Digest, polynomials []polynomial.Polynomial) (polynomial.BatchOpeningProofSinglePoint, error) { - - var res MockBatchProofsSinglePoint - res.ClaimedValues = make([]fr.Element, len(polynomials)) - res.Point.SetInterface(point) - - for i := 0; i < len(polynomials); i++ { - res.ClaimedValues[i].SetInterface(polynomials[i].Eval(point)) - } - - return &res, nil -} - -// BatchVerifySinglePoint computes a batch opening proof for -func (s *Scheme) BatchVerifySinglePoint(digests []polynomial.Digest, batchOpeningProof polynomial.BatchOpeningProofSinglePoint) error { - - return nil - -} \ No newline at end of file diff --git a/internal/generator/polynomial/template/commitment_mock/mock.test.go.tmpl b/internal/generator/polynomial/template/commitment_mock/mock.test.go.tmpl deleted file mode 100644 index c38608954..000000000 --- a/internal/generator/polynomial/template/commitment_mock/mock.test.go.tmpl +++ /dev/null @@ -1,113 +0,0 @@ -import ( - "testing" - - "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" - {{ .CurvePackage }}_pol "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr/polynomial" - "github.com/consensys/gnark-crypto/polynomial" -) - -func TestCommit(t *testing.T) { - - size := 60 - f := make({{ .CurvePackage }}_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var _c fr.Element - _c.SetInterface(c) - - if !_c.Equal(&f[0]) { - t.Fatal("err mock commitment (commit)") - } -} - -func TestVerifySinglePoint(t *testing.T) { - - size := 60 - f := make({{ .CurvePackage }}_pol.Polynomial, size) - for i := 0; i < size; i++ { - f[i].SetRandom() - } - - var s Scheme - - c, err := s.Commit(&f) - if err != nil { - t.Fatal(err) - } - - var point fr.Element - point.SetRandom() - - o, err := s.Open(point, &f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed valued - res := o.(*MockProof) - expected := f.Eval(point).(fr.Element) - if !res.ClaimedValue.Equal(&expected) { - t.Fatal("err mock commitment (open)") - } - - err = s.Verify(c, o) - if err != nil { - t.Fatal(err) - } - -} - -func TestBatchVerifySinglePoint(t *testing.T) { - - // create polynomials - size := 60 - f := make([]polynomial.Polynomial, 10) - for i := 0; i < 10; i++ { - _f := make({{ .CurvePackage }}_pol.Polynomial, size) - for i := 0; i < size; i++ { - _f[i].SetRandom() - } - f[i] = &_f - } - - var s Scheme - - // commit the polynomials - digests := make([]polynomial.Digest, 10) - for i := 0; i < 10; i++ { - digests[i], _ = s.Commit(f[i]) - } - - var point fr.Element - point.SetRandom() - - proof, err := s.BatchOpenSinglePoint(&point, digests, f) - if err != nil { - t.Fatal(err) - } - - // verify the claimed values - _proof := proof.(*MockBatchProofsSinglePoint) - for i := 0; i < 10; i++ { - expectedClaim := f[i].Eval(point).(fr.Element) - if !expectedClaim.Equal(&_proof.ClaimedValues[i]) { - t.Fatal("inconsistant claimed values") - } - } - - // verify the proof - err = s.BatchVerifySinglePoint(digests, proof) - if err != nil { - t.Fatal(err) - } - -} diff --git a/internal/generator/polynomial/template/commitment_mock/proof.go.tmpl b/internal/generator/polynomial/template/commitment_mock/proof.go.tmpl deleted file mode 100644 index 7e5e1fc94..000000000 --- a/internal/generator/polynomial/template/commitment_mock/proof.go.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -import "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" - -// MockProof empty struct -type MockProof struct { - Point fr.Element - ClaimedValue fr.Element -} - -func (mp *MockProof) Marshal() []byte { - panic("not implemented") -} - diff --git a/internal/generator/polynomial/template/commitment_mock/proof.single.point.go.tmpl b/internal/generator/polynomial/template/commitment_mock/proof.single.point.go.tmpl deleted file mode 100644 index 7b8862d48..000000000 --- a/internal/generator/polynomial/template/commitment_mock/proof.single.point.go.tmpl +++ /dev/null @@ -1,11 +0,0 @@ -import "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" - -// MockBatchProofsSinglePoint empty struct -type MockBatchProofsSinglePoint struct { - Point fr.Element - ClaimedValues []fr.Element -} - -func (mp *MockBatchProofsSinglePoint) Marshal() []byte { - panic("not implemented") -} \ No newline at end of file diff --git a/internal/generator/polynomial/template/polynomial.go.tmpl b/internal/generator/polynomial/template/polynomial.go.tmpl index ae705fd8d..4e4317218 100644 --- a/internal/generator/polynomial/template/polynomial.go.tmpl +++ b/internal/generator/polynomial/template/polynomial.go.tmpl @@ -1,6 +1,5 @@ import ( "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" - "github.com/consensys/gnark-crypto/polynomial" ) // Polynomial polynomial represented by coefficients bn254 fr field. @@ -13,13 +12,11 @@ func (p *Polynomial) Degree() uint64 { // Eval evaluates p at v // returns a fr.Element -func (p *Polynomial) Eval(v interface{}) interface{} { - var _v fr.Element - _v.SetInterface(v) +func (p *Polynomial) Eval(v *fr.Element) fr.Element { res := (*p)[len(*p) - 1] for i := len(*p) - 2; i >= 0; i-- { - res.Mul(&res, &_v) + res.Mul(&res, v) res.Add(&res, &(*p)[i]) } @@ -27,48 +24,39 @@ func (p *Polynomial) Eval(v interface{}) interface{} { } // Clone returns a copy of the polynomial -func (p *Polynomial) Clone() polynomial.Polynomial { +func (p *Polynomial) Clone() Polynomial { _p := make(Polynomial, len(*p)) copy(_p, *p) - return &_p + return _p } // AddConstantInPlace adds a constant to the polynomial, modifying p -func (p *Polynomial) AddConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) AddConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Add(&(*p)[i], &_c) + (*p)[i].Add(&(*p)[i], c) } } // SubConstantInPlace subs a constant to the polynomial, modifying p -func (p *Polynomial) SubConstantInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) SubConstantInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Sub(&(*p)[i], &_c) + (*p)[i].Sub(&(*p)[i], c) } } // ScaleInPlace multiplies p by v, modifying p -func (p *Polynomial) ScaleInPlace(c interface{}) { - var _c fr.Element - _c.SetInterface(c) - +func (p *Polynomial) ScaleInPlace(c *fr.Element) { for i := 0; i < len(*p); i++ { - (*p)[i].Mul(&(*p)[i], &_c) + (*p)[i].Mul(&(*p)[i], c) } } // Add adds p1 to p2 // This function allocates a new slice unless p == p1 or p == p2 -func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { +func (p *Polynomial) Add(p1, p2 Polynomial) *Polynomial { - bigger := *(p1.(*Polynomial)) - smaller := *(p2.(*Polynomial)) + bigger := p1 + smaller := p2 if len(bigger) < len(smaller) { bigger, smaller = smaller, bigger } @@ -98,18 +86,17 @@ func (p *Polynomial) Add(p1, p2 polynomial.Polynomial) polynomial.Polynomial { } // Equal checks equality between two polynomials -func (p *Polynomial) Equal(p1 polynomial.Polynomial) bool { - _p1 := *(p1.(*Polynomial)) - if (p == nil) != (_p1 == nil) { +func (p *Polynomial) Equal(p1 Polynomial) bool { + if (*p == nil) != (p1 == nil) { return false } - if len(*p) != len(_p1) { + if len(*p) != len(p1) { return false } - for i := range _p1 { - if !(*p)[i].Equal(&_p1[i]) { + for i := range p1 { + if !(*p)[i].Equal(&p1[i]) { return false } } diff --git a/internal/generator/polynomial/template/polynomial.test.go.tmpl b/internal/generator/polynomial/template/polynomial.test.go.tmpl index eb227e2ea..6a96e77ad 100644 --- a/internal/generator/polynomial/template/polynomial.test.go.tmpl +++ b/internal/generator/polynomial/template/polynomial.test.go.tmpl @@ -28,7 +28,7 @@ func TestPolynomialEval(t *testing.T) { expectedEval.Div(&expectedEval, &den) // compute purported evaluation - purportedEval := f.Eval(&point).(fr.Element) + purportedEval := f.Eval(&point) // check if !purportedEval.Equal(&expectedEval) { @@ -142,27 +142,27 @@ func TestPolynomialAdd(t *testing.T) { // caller is empty var g Polynomial - g.Add(&f1, &f2) - if !g.Equal(&expectedSum) { + g.Add(f1, f2) + if !g.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } // all operands are distincts _f1 := f1.Clone() - _f1.Add(&f1, &f2) - if !_f1.Equal(&expectedSum) { + _f1.Add(f1, f2) + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !f1.Equal(&f1Backup) { + if !f1.Equal(f1Backup) { t.Fatal("side effect, f1 should not have been modified") } - if !f2.Equal(&f2Backup) { + if !f2.Equal(f2Backup) { t.Fatal("side effect, f2 should not have been modified") } @@ -170,10 +170,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 := f2.Clone() _f1.Add(_f1, _f2) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } @@ -181,10 +181,10 @@ func TestPolynomialAdd(t *testing.T) { _f1 = f1.Clone() _f2 = f2.Clone() _f1.Add(_f2, _f1) - if !_f1.Equal(&expectedSum) { + if !_f1.Equal(expectedSum) { t.Fatal("add polynomials fails") } - if !_f2.Equal(&f2Backup) { + if !_f2.Equal(f2Backup) { t.Fatal("side effect, _f2 should not have been modified") } } \ No newline at end of file diff --git a/polynomial/commitment.go b/polynomial/commitment.go deleted file mode 100644 index c342f778b..000000000 --- a/polynomial/commitment.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package polynomial provides interfaces for polynomial and polynomial commitment schemes defined in gnark-crypto/ecc/.../fr. -package polynomial - -import ( - "errors" - "io" -) - -var ( - ErrVerifyOpeningProof = errors.New("error verifying opening proof") - ErrVerifyBatchOpeningSinglePoint = errors.New("error verifying batch opening proof at single point") -) - -// Digest interface that a polynomial commitment should implement -type Digest interface { - Marshal() []byte -} - -// OpeningProof interface that an opening proof -// should implement. -type OpeningProof interface { - Marshal() []byte -} - -// BatchOpeningProofSinglePoint interface that a bacth opening proof (single point) -// should implement. -type BatchOpeningProofSinglePoint interface { - Marshal() []byte -} - -// CommitmentScheme interface for an additively homomorphic -// polynomial commitment scheme. -// The function BatchOpenSinglePoint is proper to an additively -// homomorphic commitment scheme. -type CommitmentScheme interface { - io.WriterTo - io.ReaderFrom - - Commit(p Polynomial) (Digest, error) - - Open(point interface{}, p Polynomial) (OpeningProof, error) - - // Verify verifies an opening proof of commitment at point - Verify(commitment Digest, proof OpeningProof) error - - // BatchOpenSinglePoint creates a batch opening proof at _val of a list of polynomials. - // It's an interactive protocol, made non interactive using Fiat Shamir. - // point is the point at which the polynomials are opened. - // digests is the list of committed polynomials to open, need to derive the challenge using Fiat Shamir. - // polynomials is the list of polynomials to open. - BatchOpenSinglePoint(point interface{}, digests []Digest, polynomials []Polynomial) (BatchOpeningProofSinglePoint, error) - - // BatchVerifySinglePoint verifies a batched opening proof at a single point of a list of polynomials. - // point: point at which the polynomials are evaluated - // claimedValues: claimed values of the polynomials at _val - // commitments: list of commitments to the polynomials which are opened - // batchOpeningProof: the batched opening proof at a single point of the polynomials. - BatchVerifySinglePoint(digests []Digest, batchOpeningProof BatchOpeningProofSinglePoint) error -} diff --git a/polynomial/polynomial.go b/polynomial/polynomial.go deleted file mode 100644 index 3f63aa9d3..000000000 --- a/polynomial/polynomial.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2020 ConsenSys Software Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package polynomial provides interfaces for polynomial commitment schemes defined in gnark-crypto/ecc/.../fr. -package polynomial - -// Polynomial interface that a polynomial should implement -type Polynomial interface { - - // Degree returns the degree of the polynomial - Degree() uint64 - - // Eval computes the evaluation of the polynomial at v - Eval(v interface{}) interface{} - - // Returns a copy of the polynomial - Clone() Polynomial - - // Add adds p1 to p, modifying p - Add(p1, p2 Polynomial) Polynomial - - // AddConstantInPlace adds a constant to the polynomial, modifying p - AddConstantInPlace(c interface{}) - - // AddConstantInPlace subs a constant to the polynomial, modifying p - SubConstantInPlace(c interface{}) - - // ScaleInPlace multiplies the polynomial by a constant c, modifying p - ScaleInPlace(c interface{}) - - // Equal checks equality between two polynomials - Equal(p1 Polynomial) bool -}