github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/fr/sumcheck/sumcheck_test.go (about) 1 // Copyright 2020 Consensys Software Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Code generated by consensys/gnark-crypto DO NOT EDIT 16 17 package sumcheck 18 19 import ( 20 "fmt" 21 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" 22 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/polynomial" 23 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr/test_vector_utils" 24 fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" 25 "github.com/stretchr/testify/assert" 26 "hash" 27 "math/bits" 28 "strings" 29 "testing" 30 ) 31 32 type singleMultilinClaim struct { 33 g polynomial.MultiLin 34 } 35 36 func (c singleMultilinClaim) ProveFinalEval(r []fr.Element) interface{} { 37 return nil // verifier can compute the final eval itself 38 } 39 40 func (c singleMultilinClaim) VarsNum() int { 41 return bits.TrailingZeros(uint(len(c.g))) 42 } 43 44 func (c singleMultilinClaim) ClaimsNum() int { 45 return 1 46 } 47 48 func sumForX1One(g polynomial.MultiLin) polynomial.Polynomial { 49 sum := g[len(g)/2] 50 for i := len(g)/2 + 1; i < len(g); i++ { 51 sum.Add(&sum, &g[i]) 52 } 53 return []fr.Element{sum} 54 } 55 56 func (c singleMultilinClaim) Combine(fr.Element) polynomial.Polynomial { 57 return sumForX1One(c.g) 58 } 59 60 func (c *singleMultilinClaim) Next(r fr.Element) polynomial.Polynomial { 61 c.g.Fold(r) 62 return sumForX1One(c.g) 63 } 64 65 type singleMultilinLazyClaim struct { 66 g polynomial.MultiLin 67 claimedSum fr.Element 68 } 69 70 func (c singleMultilinLazyClaim) VerifyFinalEval(r []fr.Element, combinationCoeff fr.Element, purportedValue fr.Element, proof interface{}) error { 71 val := c.g.Evaluate(r, nil) 72 if val.Equal(&purportedValue) { 73 return nil 74 } 75 return fmt.Errorf("mismatch") 76 } 77 78 func (c singleMultilinLazyClaim) CombinedSum(combinationCoeffs fr.Element) fr.Element { 79 return c.claimedSum 80 } 81 82 func (c singleMultilinLazyClaim) Degree(i int) int { 83 return 1 84 } 85 86 func (c singleMultilinLazyClaim) ClaimsNum() int { 87 return 1 88 } 89 90 func (c singleMultilinLazyClaim) VarsNum() int { 91 return bits.TrailingZeros(uint(len(c.g))) 92 } 93 94 func testSumcheckSingleClaimMultilin(polyInt []uint64, hashGenerator func() hash.Hash) error { 95 poly := make(polynomial.MultiLin, len(polyInt)) 96 for i, n := range polyInt { 97 poly[i].SetUint64(n) 98 } 99 100 claim := singleMultilinClaim{g: poly.Clone()} 101 102 proof, err := Prove(&claim, fiatshamir.WithHash(hashGenerator())) 103 if err != nil { 104 return err 105 } 106 107 var sb strings.Builder 108 for _, p := range proof.PartialSumPolys { 109 110 sb.WriteString("\t{") 111 for i := 0; i < len(p); i++ { 112 sb.WriteString(p[i].String()) 113 if i+1 < len(p) { 114 sb.WriteString(", ") 115 } 116 } 117 sb.WriteString("}\n") 118 } 119 120 lazyClaim := singleMultilinLazyClaim{g: poly, claimedSum: poly.Sum()} 121 if err = Verify(lazyClaim, proof, fiatshamir.WithHash(hashGenerator())); err != nil { 122 return err 123 } 124 125 proof.PartialSumPolys[0][0].Add(&proof.PartialSumPolys[0][0], test_vector_utils.ToElement(1)) 126 lazyClaim = singleMultilinLazyClaim{g: poly, claimedSum: poly.Sum()} 127 if Verify(lazyClaim, proof, fiatshamir.WithHash(hashGenerator())) == nil { 128 return fmt.Errorf("bad proof accepted") 129 } 130 return nil 131 } 132 133 func TestSumcheckDeterministicHashSingleClaimMultilin(t *testing.T) { 134 //printMsws(36) 135 136 polys := [][]uint64{ 137 {1, 2, 3, 4}, // 1 + 2X₁ + X₂ 138 {1, 2, 3, 4, 5, 6, 7, 8}, // 1 + 4X₁ + 2X₂ + X₃ 139 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, // 1 + 8X₁ + 4X₂ + 2X₃ + X₄ 140 } 141 142 const MaxStep = 4 143 const MaxStart = 4 144 hashGens := make([]func() hash.Hash, 0, MaxStart*MaxStep) 145 146 for step := 0; step < MaxStep; step++ { 147 for startState := 0; startState < MaxStart; startState++ { 148 if step == 0 && startState == 1 { // unlucky case where a bad proof would be accepted 149 continue 150 } 151 hashGens = append(hashGens, test_vector_utils.NewMessageCounterGenerator(startState, step)) 152 } 153 } 154 155 for _, poly := range polys { 156 for _, hashGen := range hashGens { 157 assert.NoError(t, testSumcheckSingleClaimMultilin(poly, hashGen), 158 "failed with poly %v and hashGen %v", poly, hashGen()) 159 } 160 } 161 }