github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-377/fr/iop/quotient_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 iop 18 19 import ( 20 "testing" 21 22 "github.com/consensys/gnark-crypto/ecc" 23 "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" 24 "github.com/consensys/gnark-crypto/ecc/bls12-377/fr/fft" 25 ) 26 27 // computes x₃ in h(x₁,x₂,x₃) = x₁^{2}*x₂ + x₃ - x₁^{3} 28 // from x₁ and x₂. 29 func computex3(x []fr.Element) fr.Element { 30 31 var a, b fr.Element 32 a.Square(&x[0]).Mul(&a, &x[1]) 33 b.Square(&x[0]).Mul(&b, &x[0]) 34 a.Sub(&b, &a) 35 return a 36 37 } 38 39 func buildPoly(size int, form Form) *Polynomial { 40 v := make([]fr.Element, size) 41 return NewPolynomial(&v, form) 42 } 43 44 func TestDivideByXMinusOne(t *testing.T) { 45 46 f := func(_ int, x ...fr.Element) fr.Element { 47 var a, b fr.Element 48 a.Square(&x[0]).Mul(&a, &x[1]).Add(&a, &x[2]) 49 b.Square(&x[0]).Mul(&b, &x[0]) 50 a.Sub(&a, &b) 51 return a 52 } 53 54 // create the multivariate polynomial h 55 // h(x₁,x₂,x₃) = x₁^{2}*x₂ + x₃ - x₁^{3} 56 nbEntries := 3 57 58 // create an instance (f_i) where h holds 59 sizeSystem := 8 60 61 form := Form{Basis: Lagrange, Layout: Regular} 62 63 entries := make([]*Polynomial, nbEntries) 64 entries[0] = buildPoly(sizeSystem, form) 65 entries[1] = buildPoly(sizeSystem, form) 66 entries[2] = buildPoly(sizeSystem, form) 67 68 for i := 0; i < sizeSystem; i++ { 69 70 entries[0].Coefficients()[i].SetRandom() 71 entries[1].Coefficients()[i].SetRandom() 72 tmp := computex3( 73 []fr.Element{entries[0].Coefficients()[i], 74 entries[1].Coefficients()[i]}) 75 entries[2].Coefficients()[i].Set(&tmp) 76 77 x := []fr.Element{ 78 entries[0].GetCoeff(i), 79 entries[1].GetCoeff(i), 80 entries[2].GetCoeff(i), 81 } 82 a := f(0, x...) 83 if !a.IsZero() { 84 t.Fatal("system does not vanish on x^n-1") 85 } 86 } 87 88 // compute the quotient where the entries are in Regular layout 89 var domains [2]*fft.Domain 90 domains[0] = fft.NewDomain(uint64(sizeSystem)) 91 domains[1] = fft.NewDomain(ecc.NextPowerOfTwo(uint64(3 * sizeSystem))) 92 93 entries[0].ToCanonical(domains[0]). 94 ToRegular(). 95 ToLagrangeCoset(domains[1]). 96 ToRegular() 97 98 entries[1].ToCanonical(domains[0]). 99 ToRegular(). 100 ToLagrangeCoset(domains[1]). 101 ToRegular() 102 103 entries[2].ToCanonical(domains[0]). 104 ToRegular(). 105 ToLagrangeCoset(domains[1]). 106 ToRegular() 107 108 expectedForm := Form{Layout: BitReverse, Basis: LagrangeCoset} 109 h, err := Evaluate(f, nil, expectedForm, entries...) 110 if err != nil { 111 t.Fatal(err) 112 } 113 114 q, err := DivideByXMinusOne(h, domains) 115 if err != nil { 116 t.Fatal(err) 117 } 118 119 // evaluate the quotient at a random point and check that 120 // the relation holds. 121 var x fr.Element 122 x.SetRandom() 123 qx := q.Evaluate(x) 124 entries[0].ToCanonical(domains[1]) 125 entries[1].ToCanonical(domains[1]) 126 entries[2].ToCanonical(domains[1]) 127 ax := entries[0].Evaluate(x) 128 bx := entries[1].Evaluate(x) 129 cx := entries[2].Evaluate(x) 130 hx := f(0, ax, bx, cx) 131 132 var xnminusone, one fr.Element 133 one.SetOne() 134 xnminusone.Set(&x). 135 Square(&xnminusone). 136 Square(&xnminusone). 137 Square(&xnminusone). 138 Sub(&xnminusone, &one) 139 qx.Mul(&qx, &xnminusone) 140 if !qx.Equal(&hx) { 141 t.Fatal("error computing quotient") 142 } 143 }