github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/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-381/fr"
    24  	"github.com/consensys/gnark-crypto/ecc/bls12-381/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  }