github.com/consensys/gnark-crypto@v0.14.0/ecc/bls24-317/fr/iop/polynomial_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/bls24-317/fr"
    23  	"github.com/consensys/gnark-crypto/ecc/bls24-317/fr/fft"
    24  
    25  	"github.com/stretchr/testify/require"
    26  
    27  	"bytes"
    28  	"reflect"
    29  )
    30  
    31  func TestEvaluation(t *testing.T) {
    32  
    33  	size := 8
    34  	shift := 2
    35  	d := fft.NewDomain(uint64(size))
    36  	c := randomVector(size)
    37  	wp := NewPolynomial(c, Form{Basis: Canonical, Layout: Regular})
    38  	wps := wp.ShallowClone().Shift(shift)
    39  	ref := wp.Clone()
    40  	ref.ToLagrange(d).ToRegular()
    41  
    42  	// regular layout
    43  	a := wp.Evaluate(d.Generator)
    44  	b := wps.Evaluate(d.Generator)
    45  	if !a.Equal(&ref.Coefficients()[1]) {
    46  		t.Fatal("error evaluation")
    47  	}
    48  	if !b.Equal(&ref.Coefficients()[1+shift]) {
    49  		t.Fatal("error evaluation shifted")
    50  	}
    51  
    52  	// bit reversed layout
    53  	wp.ToBitReverse()
    54  	wps.ToBitReverse()
    55  	a = wp.Evaluate(d.Generator)
    56  	b = wps.Evaluate(d.Generator)
    57  	if !a.Equal(&ref.Coefficients()[1]) {
    58  		t.Fatal("error evaluation")
    59  	}
    60  	if !b.Equal(&ref.Coefficients()[1+shift]) {
    61  		t.Fatal("error evaluation shifted")
    62  	}
    63  
    64  }
    65  
    66  func randomVector(size int) *[]fr.Element {
    67  
    68  	r := make([]fr.Element, size)
    69  	for i := 0; i < size; i++ {
    70  		r[i].SetRandom()
    71  	}
    72  	return &r
    73  }
    74  
    75  func TestGetCoeff(t *testing.T) {
    76  
    77  	size := 8
    78  	v := make([]fr.Element, size)
    79  	for i := 0; i < size; i++ {
    80  		v[i].SetUint64(uint64(i))
    81  	}
    82  	wp := NewPolynomial(&v, Form{Layout: Regular, Basis: Canonical})
    83  	wsp := wp.ShallowClone().Shift(1)
    84  
    85  	var aa, bb fr.Element
    86  
    87  	// regular layout
    88  	for i := 0; i < size; i++ {
    89  
    90  		a := wp.GetCoeff(i)
    91  		b := wsp.GetCoeff(i)
    92  		aa.SetUint64(uint64(i))
    93  		bb.SetUint64(uint64((i + 1) % size))
    94  		if !a.Equal(&aa) {
    95  			t.Fatal("error GetCoeff")
    96  		}
    97  		if !b.Equal(&bb) {
    98  			t.Fatal("error GetCoeff")
    99  		}
   100  	}
   101  
   102  	// bit reverse + bitReverse and shifted
   103  	wp.ToBitReverse()
   104  	wsp.ToBitReverse()
   105  	for i := 0; i < size; i++ {
   106  
   107  		a := wp.GetCoeff(i)
   108  		b := wsp.GetCoeff(i)
   109  		aa.SetUint64(uint64(i))
   110  		bb.SetUint64(uint64((i + 1) % size))
   111  		if !a.Equal(&aa) {
   112  			t.Fatal("error GetCoeff")
   113  		}
   114  		if !b.Equal(&bb) {
   115  			t.Fatal("error GetCoeff")
   116  		}
   117  	}
   118  
   119  }
   120  
   121  func TestRoundTrip(t *testing.T) {
   122  	assert := require.New(t)
   123  	var buf bytes.Buffer
   124  
   125  	size := 8
   126  	d := fft.NewDomain(uint64(8))
   127  	blindingOrder := 2
   128  
   129  	p := NewPolynomial(randomVector(size), Form{Basis: Lagrange, Layout: Regular}).ToCanonical(d).ToRegular()
   130  	p.Blind(blindingOrder)
   131  
   132  	// serialize
   133  	written, err := p.WriteTo(&buf)
   134  	assert.NoError(err)
   135  
   136  	// deserialize
   137  	var reconstructed Polynomial
   138  	read, err := reconstructed.ReadFrom(&buf)
   139  	assert.NoError(err)
   140  
   141  	assert.Equal(read, written, "number of bytes written != number of bytes read")
   142  
   143  	// compare
   144  	assert.Equal(p.Basis, reconstructed.Basis)
   145  	assert.Equal(p.Layout, reconstructed.Layout)
   146  	assert.Equal(p.shift, reconstructed.shift)
   147  	assert.Equal(p.size, reconstructed.size)
   148  	assert.Equal(p.blindedSize, reconstructed.blindedSize)
   149  	c1, c2 := p.Coefficients(), reconstructed.Coefficients()
   150  	assert.True(reflect.DeepEqual(c1, c2))
   151  }
   152  
   153  func TestBlinding(t *testing.T) {
   154  
   155  	size := 8
   156  	d := fft.NewDomain(uint64(8))
   157  	blindingOrder := 2
   158  
   159  	// generate a random polynomial in Lagrange form for the moment
   160  	// to check that an error is raised when the polynomial is not
   161  	// in canonical form.
   162  	wp := NewPolynomial(randomVector(size), Form{Basis: Lagrange, Layout: Regular})
   163  
   164  	// checks the blinding is correct: the evaluation of the blinded polynomial
   165  	// should be the same as the original on d's domain
   166  	wp.Basis = Canonical
   167  	wt := wp.Clone()
   168  	wt.Blind(blindingOrder)
   169  	if wt.coefficients.Len() != blindingOrder+size+1 {
   170  		t.Fatal("size of blinded polynomial is incorrect")
   171  	}
   172  	if wt.blindedSize != size+blindingOrder+1 {
   173  		t.Fatal("Size field of blinded polynomial is incorrect")
   174  	}
   175  	if wt.size != size {
   176  		t.Fatal("the size should not have been modified")
   177  	}
   178  	x := make([]fr.Element, size)
   179  	x[0].SetOne()
   180  	for i := 1; i < size; i++ {
   181  		x[i].Mul(&x[i-1], &d.Generator)
   182  	}
   183  	var a, b fr.Element
   184  	for i := 0; i < size; i++ {
   185  		a = wt.Evaluate(x[i])
   186  		b = wp.Evaluate(x[i])
   187  		if a != b {
   188  			t.Fatal("polynomial and its blinded version should be equal on V(X^{n}-1)")
   189  		}
   190  	}
   191  
   192  }
   193  
   194  // list of functions to turn a polynomial in Lagrange-regular form
   195  // to all different forms in ordered using this encoding:
   196  // int(p.Basis)*4 + int(p.Layout)*2 + int(p.Status)
   197  // p is in Lagrange/Regular here. This function is for testing purpose
   198  // only.
   199  type TransfoTest func(p polynomial, d *fft.Domain) polynomial
   200  
   201  // CANONICAL REGULAR
   202  func fromLagrange0(p *Polynomial, d *fft.Domain) *Polynomial {
   203  	r := p.Clone()
   204  	r.Basis = Canonical
   205  	r.Layout = Regular
   206  	d.FFTInverse(r.Coefficients(), fft.DIF)
   207  	fft.BitReverse(r.Coefficients())
   208  	return r
   209  }
   210  
   211  // CANONICAL BITREVERSE
   212  func fromLagrange1(p *Polynomial, d *fft.Domain) *Polynomial {
   213  	r := p.Clone()
   214  	r.Basis = Canonical
   215  	r.Layout = BitReverse
   216  	d.FFTInverse(r.Coefficients(), fft.DIF)
   217  	return r
   218  }
   219  
   220  // LAGRANGE REGULAR
   221  func fromLagrange2(p *Polynomial, d *fft.Domain) *Polynomial {
   222  	r := p.Clone()
   223  	r.Basis = Lagrange
   224  	r.Layout = Regular
   225  	return r
   226  }
   227  
   228  // LAGRANGE BITREVERSE
   229  func fromLagrange3(p *Polynomial, d *fft.Domain) *Polynomial {
   230  	r := p.Clone()
   231  	r.Basis = Lagrange
   232  	r.Layout = BitReverse
   233  	fft.BitReverse(r.Coefficients())
   234  	return r
   235  }
   236  
   237  // LAGRANGE_COSET REGULAR
   238  func fromLagrange4(p *Polynomial, d *fft.Domain) *Polynomial {
   239  	r := p.Clone()
   240  	r.Basis = LagrangeCoset
   241  	r.Layout = Regular
   242  	d.FFTInverse(r.Coefficients(), fft.DIF)
   243  	d.FFT(r.Coefficients(), fft.DIT, fft.OnCoset())
   244  	return r
   245  }
   246  
   247  // LAGRANGE_COSET BITREVERSE
   248  func fromLagrange5(p *Polynomial, d *fft.Domain) *Polynomial {
   249  	r := p.Clone()
   250  	r.Basis = LagrangeCoset
   251  	r.Layout = BitReverse
   252  	d.FFTInverse(r.Coefficients(), fft.DIF)
   253  	d.FFT(r.Coefficients(), fft.DIT, fft.OnCoset())
   254  	fft.BitReverse(r.Coefficients())
   255  	return r
   256  }
   257  
   258  func fromLagrange(p *Polynomial, d *fft.Domain) *Polynomial {
   259  	id := p.Form
   260  	switch id {
   261  	case canonicalRegular:
   262  		return fromLagrange0(p, d)
   263  	case canonicalBitReverse:
   264  		return fromLagrange1(p, d)
   265  	case lagrangeRegular:
   266  		return fromLagrange2(p, d)
   267  	case lagrangeBitReverse:
   268  		return fromLagrange3(p, d)
   269  	case lagrangeCosetRegular:
   270  		return fromLagrange4(p, d)
   271  	case lagrangeCosetBitReverse:
   272  		return fromLagrange5(p, d)
   273  	default:
   274  		panic("unknown id")
   275  	}
   276  }
   277  
   278  func cmpCoefficents(p, q *fr.Vector) bool {
   279  	if p.Len() != q.Len() {
   280  		return false
   281  	}
   282  	for i := 0; i < p.Len(); i++ {
   283  		if !((*p)[i].Equal(&(*q)[i])) {
   284  			return false
   285  		}
   286  	}
   287  	return true
   288  }
   289  
   290  func TestPutInLagrangeForm(t *testing.T) {
   291  
   292  	size := 64
   293  	domain := fft.NewDomain(uint64(size))
   294  
   295  	// reference vector in Lagrange-regular form
   296  	c := randomVector(size)
   297  	p := NewPolynomial(c, Form{Basis: Canonical, Layout: Regular})
   298  
   299  	// CANONICAL REGULAR
   300  	{
   301  		_p := fromLagrange(p, domain)
   302  		q := _p.Clone()
   303  		q.ToLagrange(domain)
   304  		if q.Basis != Lagrange {
   305  			t.Fatal("expected basis is Lagrange")
   306  		}
   307  		if q.Layout != BitReverse {
   308  			t.Fatal("expected layout is BitReverse")
   309  		}
   310  		fft.BitReverse(q.Coefficients())
   311  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   312  			t.Fatal("wrong coefficients")
   313  		}
   314  	}
   315  
   316  	// CANONICAL BITREVERSE
   317  	{
   318  		_p := fromLagrange1(p, domain)
   319  		q := _p.Clone()
   320  		q.ToLagrange(domain)
   321  		if q.Basis != Lagrange {
   322  			t.Fatal("expected basis is Lagrange")
   323  		}
   324  		if q.Layout != Regular {
   325  			t.Fatal("expected layout is Regular")
   326  		}
   327  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   328  			t.Fatal("wrong coefficients")
   329  		}
   330  	}
   331  
   332  	// LAGRANGE REGULAR
   333  	{
   334  		_p := fromLagrange2(p, domain)
   335  		q := _p.Clone()
   336  		q.ToLagrange(domain)
   337  
   338  		if q.Basis != Lagrange {
   339  			t.Fatal("expected basis is Lagrange")
   340  		}
   341  		if q.Layout != Regular {
   342  			t.Fatal("expected layout is Regular")
   343  		}
   344  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   345  			t.Fatal("wrong coefficients")
   346  		}
   347  	}
   348  
   349  	// LAGRANGE BITREVERSE
   350  	{
   351  		_p := fromLagrange3(p, domain)
   352  		q := _p.Clone()
   353  		q.ToLagrange(domain)
   354  		if q.Basis != Lagrange {
   355  			t.Fatal("expected basis is Lagrange")
   356  		}
   357  		if q.Layout != BitReverse {
   358  			t.Fatal("expected layout is BitReverse")
   359  		}
   360  		fft.BitReverse(q.Coefficients())
   361  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   362  			t.Fatal("wrong coefficients")
   363  		}
   364  	}
   365  
   366  	// LAGRANGE_COSET REGULAR
   367  	{
   368  		_p := fromLagrange4(p, domain)
   369  		q := _p.Clone()
   370  		q.ToLagrange(domain)
   371  		if q.Basis != Lagrange {
   372  			t.Fatal("expected basis is Lagrange")
   373  		}
   374  		if q.Layout != Regular {
   375  			t.Fatal("expected layout is Regular")
   376  		}
   377  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   378  			t.Fatal("wrong coefficients")
   379  		}
   380  	}
   381  
   382  	// LAGRANGE_COSET BITREVERSE
   383  	{
   384  		_p := fromLagrange5(p, domain)
   385  		q := _p.Clone()
   386  		q.ToLagrange(domain)
   387  		if q.Basis != Lagrange {
   388  			t.Fatal("expected basis is Lagrange")
   389  		}
   390  		if q.Layout != BitReverse {
   391  			t.Fatal("expected layout is BitReverse")
   392  		}
   393  		fft.BitReverse(q.Coefficients())
   394  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   395  			t.Fatal("wrong coefficients")
   396  		}
   397  	}
   398  
   399  }
   400  
   401  // CANONICAL REGULAR
   402  func fromCanonical0(p *Polynomial, d *fft.Domain) *Polynomial {
   403  	_p := p.Clone()
   404  	_p.Basis = Canonical
   405  	_p.Layout = Regular
   406  	return _p
   407  }
   408  
   409  // CANONICAL BITREVERSE
   410  func fromCanonical1(p *Polynomial, d *fft.Domain) *Polynomial {
   411  	_p := p.Clone()
   412  	_p.Basis = Canonical
   413  	_p.Layout = BitReverse
   414  	return _p
   415  }
   416  
   417  // LAGRANGE REGULAR
   418  func fromCanonical2(p *Polynomial, d *fft.Domain) *Polynomial {
   419  	_p := p.Clone()
   420  	_p.Basis = Lagrange
   421  	_p.Layout = Regular
   422  	d.FFT(_p.Coefficients(), fft.DIF)
   423  	fft.BitReverse(_p.Coefficients())
   424  	return _p
   425  }
   426  
   427  // LAGRANGE BITREVERSE
   428  func fromCanonical3(p *Polynomial, d *fft.Domain) *Polynomial {
   429  	_p := p.Clone()
   430  	_p.Basis = Lagrange
   431  	_p.Layout = BitReverse
   432  	d.FFT(_p.Coefficients(), fft.DIF)
   433  	return _p
   434  }
   435  
   436  // LAGRANGE_COSET REGULAR
   437  func fromCanonical4(p *Polynomial, d *fft.Domain) *Polynomial {
   438  	_p := p.Clone()
   439  	_p.Basis = LagrangeCoset
   440  	_p.Layout = Regular
   441  	d.FFT(_p.Coefficients(), fft.DIF, fft.OnCoset())
   442  	fft.BitReverse(_p.Coefficients())
   443  	return _p
   444  }
   445  
   446  // LAGRANGE_COSET BITREVERSE
   447  func fromCanonical5(p *Polynomial, d *fft.Domain) *Polynomial {
   448  	_p := p.Clone()
   449  	_p.Basis = LagrangeCoset
   450  	_p.Layout = BitReverse
   451  	d.FFT(_p.Coefficients(), fft.DIF, fft.OnCoset())
   452  	return _p
   453  }
   454  
   455  func TestPutInCanonicalForm(t *testing.T) {
   456  
   457  	size := 64
   458  	domain := fft.NewDomain(uint64(size))
   459  
   460  	// reference vector in canonical-regular form
   461  	c := randomVector(size)
   462  	p := NewPolynomial(c, Form{Basis: Canonical, Layout: Regular})
   463  
   464  	// CANONICAL REGULAR
   465  	{
   466  		_p := fromCanonical0(p, domain)
   467  		q := _p.Clone()
   468  		q.ToCanonical(domain)
   469  		if q.Basis != Canonical {
   470  			t.Fatal("expected basis is canonical")
   471  		}
   472  		if q.Layout != Regular {
   473  			t.Fatal("expected layout is regular")
   474  		}
   475  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   476  			t.Fatal("wrong coefficients")
   477  		}
   478  	}
   479  
   480  	// CANONICAL BITREVERSE
   481  	{
   482  		_p := fromCanonical1(p, domain)
   483  		q := _p.Clone()
   484  		q.ToCanonical(domain)
   485  		if q.Basis != Canonical {
   486  			t.Fatal("expected basis is canonical")
   487  		}
   488  		if q.Layout != BitReverse {
   489  			t.Fatal("expected layout is bitReverse")
   490  		}
   491  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   492  			t.Fatal("wrong coefficients")
   493  		}
   494  	}
   495  
   496  	// LAGRANGE REGULAR
   497  	{
   498  		_p := fromCanonical2(p, domain)
   499  		q := _p.Clone()
   500  		q.ToCanonical(domain)
   501  		if q.Basis != Canonical {
   502  			t.Fatal("expected basis is canonical")
   503  		}
   504  		if q.Layout != BitReverse {
   505  			t.Fatal("expected layout is bitReverse")
   506  		}
   507  		fft.BitReverse(q.Coefficients())
   508  		if !cmpCoefficents(p.coefficients, q.coefficients) {
   509  			t.Fatal("wrong coefficients")
   510  		}
   511  	}
   512  
   513  	// LAGRANGE BITREVERSE
   514  	{
   515  		_p := fromCanonical3(p, domain)
   516  		q := _p.Clone()
   517  		q.ToCanonical(domain)
   518  		if q.Basis != Canonical {
   519  			t.Fatal("expected basis is canonical")
   520  		}
   521  		if q.Layout != Regular {
   522  			t.Fatal("expected layout is regular")
   523  		}
   524  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   525  			t.Fatal("wrong coefficients")
   526  		}
   527  	}
   528  
   529  	// LAGRANGE_COSET REGULAR
   530  	{
   531  		_p := fromCanonical4(p, domain)
   532  		q := _p.Clone()
   533  		q.ToCanonical(domain)
   534  		if q.Basis != Canonical {
   535  			t.Fatal("expected basis is canonical")
   536  		}
   537  		if q.Layout != BitReverse {
   538  			t.Fatal("expected layout is BitReverse")
   539  		}
   540  		fft.BitReverse(q.Coefficients())
   541  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   542  			t.Fatal("wrong coefficients")
   543  		}
   544  	}
   545  
   546  	// LAGRANGE_COSET BITREVERSE
   547  	{
   548  		_p := fromCanonical5(p, domain)
   549  		q := _p.Clone()
   550  		q.ToCanonical(domain)
   551  		if q.Basis != Canonical {
   552  			t.Fatal("expected basis is canonical")
   553  		}
   554  		if q.Layout != Regular {
   555  			t.Fatal("expected layout is regular")
   556  		}
   557  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   558  			t.Fatal("wrong coefficients")
   559  		}
   560  	}
   561  
   562  }
   563  
   564  // CANONICAL REGULAR
   565  func fromLagrangeCoset0(p *Polynomial, d *fft.Domain) *Polynomial {
   566  	_p := p.Clone()
   567  	_p.Basis = Canonical
   568  	_p.Layout = Regular
   569  	d.FFTInverse(_p.Coefficients(), fft.DIF, fft.OnCoset())
   570  	fft.BitReverse(_p.Coefficients())
   571  	return _p
   572  }
   573  
   574  // CANONICAL BITREVERSE
   575  func fromLagrangeCoset1(p *Polynomial, d *fft.Domain) *Polynomial {
   576  	_p := p.Clone()
   577  	_p.Basis = Canonical
   578  	_p.Layout = BitReverse
   579  	d.FFTInverse(_p.Coefficients(), fft.DIF, fft.OnCoset())
   580  	return _p
   581  }
   582  
   583  // LAGRANGE REGULAR
   584  func fromLagrangeCoset2(p *Polynomial, d *fft.Domain) *Polynomial {
   585  	_p := p.Clone()
   586  	_p.Basis = Lagrange
   587  	_p.Layout = Regular
   588  	d.FFTInverse(_p.Coefficients(), fft.DIF, fft.OnCoset())
   589  	d.FFT(_p.Coefficients(), fft.DIT)
   590  	return _p
   591  }
   592  
   593  // LAGRANGE BITREVERSE
   594  func fromLagrangeCoset3(p *Polynomial, d *fft.Domain) *Polynomial {
   595  	_p := p.Clone()
   596  	_p.Basis = Lagrange
   597  	_p.Layout = BitReverse
   598  	d.FFTInverse(_p.Coefficients(), fft.DIF, fft.OnCoset())
   599  	d.FFT(_p.Coefficients(), fft.DIT)
   600  	fft.BitReverse(_p.Coefficients())
   601  	return _p
   602  }
   603  
   604  // LAGRANGE_COSET REGULAR
   605  func fromLagrangeCoset4(p *Polynomial, d *fft.Domain) *Polynomial {
   606  	_p := p.Clone()
   607  	_p.Basis = LagrangeCoset
   608  	_p.Layout = Regular
   609  	return _p
   610  }
   611  
   612  // LAGRANGE_COSET BITREVERSE
   613  func fromLagrangeCoset5(p *Polynomial, d *fft.Domain) *Polynomial {
   614  	_p := p.Clone()
   615  	_p.Basis = LagrangeCoset
   616  	_p.Layout = BitReverse
   617  	fft.BitReverse(p.Coefficients())
   618  	return _p
   619  }
   620  
   621  func TestPutInLagrangeCosetForm(t *testing.T) {
   622  
   623  	size := 64
   624  	domain := fft.NewDomain(uint64(size))
   625  
   626  	// reference vector in canonical-regular form
   627  	c := randomVector(size)
   628  	p := NewPolynomial(c, Form{Basis: LagrangeCoset, Layout: Regular})
   629  
   630  	// CANONICAL REGULAR
   631  	{
   632  		_p := fromLagrangeCoset0(p, domain)
   633  		q := _p.Clone()
   634  		q.ToLagrangeCoset(domain)
   635  		if q.Basis != LagrangeCoset {
   636  			t.Fatal("expected basis is lagrange coset")
   637  		}
   638  		if q.Layout != BitReverse {
   639  			t.Fatal("expected layout is bit reverse")
   640  		}
   641  		fft.BitReverse(q.Coefficients())
   642  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   643  			t.Fatal("wrong coefficients")
   644  		}
   645  	}
   646  
   647  	// CANONICAL BITREVERSE
   648  	{
   649  		_p := fromLagrangeCoset1(p, domain)
   650  		q := _p.Clone()
   651  		q.ToLagrangeCoset(domain)
   652  		if q.Basis != LagrangeCoset {
   653  			t.Fatal("expected basis is lagrange coset")
   654  		}
   655  		if q.Layout != Regular {
   656  			t.Fatal("expected layout is regular")
   657  		}
   658  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   659  			t.Fatal("wrong coefficients")
   660  		}
   661  	}
   662  
   663  	// LAGRANGE REGULAR
   664  	{
   665  		_p := fromLagrangeCoset2(p, domain)
   666  		q := _p.Clone()
   667  		q.ToLagrangeCoset(domain)
   668  		if q.Basis != LagrangeCoset {
   669  			t.Fatal("expected basis is lagrange coset")
   670  		}
   671  		if q.Layout != Regular {
   672  			t.Fatal("expected layout is regular")
   673  		}
   674  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   675  			t.Fatal("wrong coefficients")
   676  		}
   677  	}
   678  
   679  	// LAGRANGE BITREVERSE
   680  	{
   681  		_p := fromLagrangeCoset3(p, domain)
   682  		q := _p.Clone()
   683  		q.ToLagrangeCoset(domain)
   684  		if q.Basis != LagrangeCoset {
   685  			t.Fatal("expected basis is lagrange coset")
   686  		}
   687  		if q.Layout != BitReverse {
   688  			t.Fatal("expected layout is bit reverse")
   689  		}
   690  		fft.BitReverse(q.Coefficients())
   691  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   692  			t.Fatal("wrong coefficients")
   693  		}
   694  	}
   695  
   696  	// LAGRANGE_COSET REGULAR
   697  	{
   698  		_p := fromLagrangeCoset4(p, domain)
   699  		q := _p.Clone()
   700  		q.ToLagrangeCoset(domain)
   701  		if q.Basis != LagrangeCoset {
   702  			t.Fatal("expected basis is lagrange coset")
   703  		}
   704  		if q.Layout != Regular {
   705  			t.Fatal("expected layout is regular")
   706  		}
   707  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   708  			t.Fatal("wrong coefficients")
   709  		}
   710  	}
   711  
   712  	// LAGRANGE_COSET BITREVERSE
   713  	{
   714  		_p := fromLagrangeCoset5(p, domain)
   715  		q := _p.Clone()
   716  		q.ToLagrangeCoset(domain)
   717  		if q.Basis != LagrangeCoset {
   718  			t.Fatal("expected basis is lagrange coset")
   719  		}
   720  		if q.Layout != BitReverse {
   721  			t.Fatal("expected layout is bit reverse")
   722  		}
   723  		fft.BitReverse(q.Coefficients())
   724  		if !cmpCoefficents(q.coefficients, p.coefficients) {
   725  			t.Fatal("wrong coefficients")
   726  		}
   727  	}
   728  
   729  }