github.com/consensys/gnark-crypto@v0.14.0/internal/generator/sumcheck/test_vectors/main.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 fiatshamir "github.com/consensys/gnark-crypto/fiat-shamir" 7 "github.com/consensys/gnark-crypto/internal/generator/test_vector_utils/small_rational" 8 "github.com/consensys/gnark-crypto/internal/generator/test_vector_utils/small_rational/polynomial" 9 "github.com/consensys/gnark-crypto/internal/generator/test_vector_utils/small_rational/sumcheck" 10 "github.com/consensys/gnark-crypto/internal/generator/test_vector_utils/small_rational/test_vector_utils" 11 "hash" 12 "math/bits" 13 "os" 14 "path/filepath" 15 ) 16 17 func runMultilin(testCaseInfo *TestCaseInfo) error { 18 19 var poly polynomial.MultiLin 20 if v, err := test_vector_utils.SliceToElementSlice(testCaseInfo.Values); err == nil { 21 poly = v 22 } else { 23 return err 24 } 25 26 var hsh hash.Hash 27 var err error 28 if hsh, err = test_vector_utils.HashFromDescription(testCaseInfo.Hash); err != nil { 29 return err 30 } 31 32 proof, err := sumcheck.Prove( 33 &singleMultilinClaim{poly}, fiatshamir.WithHash(hsh)) 34 if err != nil { 35 return err 36 } 37 testCaseInfo.Proof = toPrintableProof(proof) 38 39 // Verification 40 if v, _err := test_vector_utils.SliceToElementSlice(testCaseInfo.Values); _err == nil { 41 poly = v 42 } else { 43 return _err 44 } 45 var claimedSum small_rational.SmallRational 46 if _, err = claimedSum.SetInterface(testCaseInfo.ClaimedSum); err != nil { 47 return err 48 } 49 50 if err = sumcheck.Verify(singleMultilinLazyClaim{g: poly, claimedSum: claimedSum}, proof, fiatshamir.WithHash(hsh)); err != nil { 51 return fmt.Errorf("proof rejected: %v", err) 52 } 53 54 proof.PartialSumPolys[0][0].Add(&proof.PartialSumPolys[0][0], test_vector_utils.ToElement(1)) 55 if err = sumcheck.Verify(singleMultilinLazyClaim{g: poly, claimedSum: claimedSum}, proof, fiatshamir.WithHash(hsh)); err == nil { 56 return fmt.Errorf("bad proof accepted") 57 } 58 return nil 59 } 60 61 func run(testCaseInfo *TestCaseInfo) error { 62 switch testCaseInfo.Type { 63 case "multilin": 64 return runMultilin(testCaseInfo) 65 default: 66 return fmt.Errorf("type \"%s\" unrecognized", testCaseInfo.Type) 67 } 68 } 69 70 func runAll(relPath string) error { 71 var filename string 72 var err error 73 if filename, err = filepath.Abs(relPath); err != nil { 74 return err 75 } 76 77 var bytes []byte 78 79 if bytes, err = os.ReadFile(filename); err != nil { 80 return err 81 } 82 83 var testCasesInfo TestCasesInfo 84 if err = json.Unmarshal(bytes, &testCasesInfo); err != nil { 85 return err 86 } 87 88 failed := false 89 for name, testCase := range testCasesInfo { 90 if err = run(testCase); err != nil { 91 fmt.Println(name, ":", err) 92 failed = true 93 } 94 } 95 96 if failed { 97 return fmt.Errorf("test case failed") 98 } 99 100 if bytes, err = json.MarshalIndent(testCasesInfo, "", "\t"); err != nil { 101 return err 102 } 103 104 return os.WriteFile(filename, bytes, 0) 105 } 106 107 func main() { 108 if err := runAll("sumcheck/test_vectors/vectors.json"); err != nil { 109 fmt.Println(err) 110 os.Exit(-1) 111 } 112 } 113 114 type TestCasesInfo map[string]*TestCaseInfo 115 116 type TestCaseInfo struct { 117 Type string `json:"type"` 118 Hash test_vector_utils.HashDescription `json:"hash"` 119 Values []interface{} `json:"values"` 120 Description string `json:"description"` 121 Proof PrintableProof `json:"proof"` 122 ClaimedSum interface{} `json:"claimedSum"` 123 } 124 125 type PrintableProof struct { 126 PartialSumPolys [][]interface{} `json:"partialSumPolys"` 127 FinalEvalProof interface{} `json:"finalEvalProof"` 128 } 129 130 func toPrintableProof(proof sumcheck.Proof) (printable PrintableProof) { 131 if proof.FinalEvalProof != nil { 132 panic("null expected") 133 } 134 printable.FinalEvalProof = struct{}{} 135 printable.PartialSumPolys = test_vector_utils.ElementSliceSliceToInterfaceSliceSlice(proof.PartialSumPolys) 136 return 137 } 138 139 type singleMultilinClaim struct { 140 g polynomial.MultiLin 141 } 142 143 func (c singleMultilinClaim) ProveFinalEval([]small_rational.SmallRational) interface{} { 144 return nil // verifier can compute the final eval itself 145 } 146 147 func (c singleMultilinClaim) VarsNum() int { 148 return bits.TrailingZeros(uint(len(c.g))) 149 } 150 151 func (c singleMultilinClaim) ClaimsNum() int { 152 return 1 153 } 154 155 func sumForX1One(g polynomial.MultiLin) polynomial.Polynomial { 156 sum := g[len(g)/2] 157 for i := len(g)/2 + 1; i < len(g); i++ { 158 sum.Add(&sum, &g[i]) 159 } 160 return []small_rational.SmallRational{sum} 161 } 162 163 func (c singleMultilinClaim) Combine(small_rational.SmallRational) polynomial.Polynomial { 164 return sumForX1One(c.g) 165 } 166 167 func (c *singleMultilinClaim) Next(r small_rational.SmallRational) polynomial.Polynomial { 168 c.g.Fold(r) 169 return sumForX1One(c.g) 170 } 171 172 type singleMultilinLazyClaim struct { 173 g polynomial.MultiLin 174 claimedSum small_rational.SmallRational 175 } 176 177 func (c singleMultilinLazyClaim) VerifyFinalEval(r []small_rational.SmallRational, _ small_rational.SmallRational, purportedValue small_rational.SmallRational, _ interface{}) error { 178 val := c.g.Evaluate(r, nil) 179 if val.Equal(&purportedValue) { 180 return nil 181 } 182 return fmt.Errorf("mismatch") 183 } 184 185 func (c singleMultilinLazyClaim) CombinedSum(small_rational.SmallRational) small_rational.SmallRational { 186 return c.claimedSum 187 } 188 189 func (c singleMultilinLazyClaim) Degree(int) int { 190 return 1 191 } 192 193 func (c singleMultilinLazyClaim) ClaimsNum() int { 194 return 1 195 } 196 197 func (c singleMultilinLazyClaim) VarsNum() int { 198 return bits.TrailingZeros(uint(len(c.g))) 199 }