github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/fr/polynomial/multilin_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 polynomial 18 19 import ( 20 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" 21 "github.com/leanovate/gopter" 22 "github.com/leanovate/gopter/gen" 23 "github.com/leanovate/gopter/prop" 24 "github.com/stretchr/testify/assert" 25 "testing" 26 ) 27 28 // TODO: Property based tests? 29 func TestFoldBilinear(t *testing.T) { 30 31 for i := 0; i < 100; i++ { 32 33 // f = c₀ + c₁ X₁ + c₂ X₂ + c₃ X₁ X₂ 34 var coefficients [4]fr.Element 35 for i := 0; i < 4; i++ { 36 if _, err := coefficients[i].SetRandom(); err != nil { 37 t.Error(err) 38 } 39 } 40 41 var r fr.Element 42 if _, err := r.SetRandom(); err != nil { 43 t.Error(err) 44 } 45 46 // interpolate at {0,1}²: 47 m := make(MultiLin, 4) 48 m[0] = coefficients[0] 49 m[1].Add(&coefficients[0], &coefficients[2]) 50 m[2].Add(&coefficients[0], &coefficients[1]) 51 m[3]. 52 Add(&m[1], &coefficients[1]). 53 Add(&m[3], &coefficients[3]) 54 55 m.Fold(r) 56 57 // interpolate at {r}×{0,1}: 58 var expected0, expected1 fr.Element 59 expected0. 60 Mul(&r, &coefficients[1]). 61 Add(&expected0, &coefficients[0]) 62 63 expected1. 64 Mul(&r, &coefficients[3]). 65 Add(&expected1, &coefficients[2]). 66 Add(&expected0, &expected1) 67 68 if !m[0].Equal(&expected0) || !m[1].Equal(&expected1) { 69 t.Fail() 70 } 71 } 72 } 73 74 func TestPrecomputeLagrange(t *testing.T) { 75 76 testForDomainSize := func(domainSize uint8) bool { 77 polys := computeLagrangeBasis(domainSize) 78 79 for l := uint8(0); l < domainSize; l++ { 80 for i := uint8(0); i < domainSize; i++ { 81 var I fr.Element 82 I.SetUint64(uint64(i)) 83 y := polys[l].Eval(&I) 84 85 if i == l && !y.IsOne() || i != l && !y.IsZero() { 86 t.Errorf("domainSize = %d: p_%d(%d) = %s", domainSize, l, i, y.Text(10)) 87 return false 88 } 89 } 90 } 91 return true 92 } 93 94 t.Parallel() 95 parameters := gopter.DefaultTestParameters() 96 97 parameters.MinSuccessfulTests = int(maxLagrangeDomainSize) 98 99 properties := gopter.NewProperties(parameters) 100 101 properties.Property("l'th lagrange polynomials must evaluate to 1 on l and 0 on other values in the domain", prop.ForAll( 102 testForDomainSize, 103 gen.UInt8Range(2, maxLagrangeDomainSize), 104 )) 105 106 properties.TestingRun(t, gopter.ConsoleReporter(false)) 107 } 108 109 // TODO: Benchmark folding? Algorithms is pretty straightforward; unless we want to measure how well memory management is working 110 111 func TestFoldedEqTable(t *testing.T) { 112 q := make([]fr.Element, 2) 113 q[0].SetInt64(2) 114 q[1].SetInt64(3) 115 116 m := make(MultiLin, 4) 117 m[0].SetOne() 118 m.Eq(q) 119 120 eq := make([]fr.Element, 4) 121 p := make([]fr.Element, 2) 122 123 var one fr.Element 124 one.SetOne() 125 126 for p0 := 0; p0 < 2; p0++ { 127 p[1].SetZero() 128 for p1 := 0; p1 < 2; p1++ { 129 eq[p0*2+p1] = EvalEq(q, p) 130 p[1].Add(&p[1], &one) 131 } 132 p[0].Add(&p[0], &one) 133 } 134 135 for i := 0; i < 4; i++ { 136 assert.Equal(t, eq[i], m[i], "folded table disagrees with EqEval", i) 137 } 138 139 }