github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/polynomials_test.go (about)

     1  package privacy
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"testing"
     7  )
     8  
     9  func TestConvert(t *testing.T) {
    10  
    11  	L1 := RandomScalar()
    12  	L2 := RandomScalar()
    13  	L3 := RandomScalar()
    14  	LRes := new(Scalar).Sub(L1, L2)
    15  	LRes.Sub(LRes, L3)
    16  	fmt.Println(LRes)
    17  
    18  	I1 := ScalarToBigInt(L1)
    19  	I2 := ScalarToBigInt(L2)
    20  	I3 := ScalarToBigInt(L3)
    21  
    22  	tmp := new(big.Int).Sub(I1, I2)
    23  	tmp = tmp.Sub(tmp, I3)
    24  	IRes := tmp.Mod(tmp, LInt)
    25  	LResPrime := BigIntToScalar(IRes)
    26  	fmt.Println(LResPrime)
    27  
    28  }
    29  
    30  func TestPrettyPrint(t *testing.T) {
    31  	cases := []struct {
    32  		p   Poly
    33  		ans string
    34  	}{
    35  		{
    36  			newPoly(0),
    37  			"[0]",
    38  		},
    39  		{
    40  			newPoly(5, -4, 3, 3),
    41  			"[3x^3 + 3x^2 - 4x + 5]",
    42  		},
    43  		{
    44  			newPoly(5, 6, 2),
    45  			"[2x^2 + 6x + 5]",
    46  		},
    47  		{
    48  			newPoly(5, -2, 0, 2, 1, 3),
    49  			"[3x^5 + x^4 + 2x^3 - 2x + 5]",
    50  		},
    51  		{
    52  			newPoly(2, 1, 0, -1, -2),
    53  			"[-2x^4 - x^3 + x + 2]",
    54  		},
    55  	}
    56  	for _, c := range cases {
    57  		s := fmt.Sprintf("%v", c.p)
    58  		if s != c.ans {
    59  			t.Errorf("Stringify %v should be %v", s, c.ans)
    60  		}
    61  	}
    62  
    63  }
    64  
    65  func TestTrim(t *testing.T) {
    66  	cases := []struct {
    67  		p   Poly
    68  		ans Poly
    69  	}{
    70  		{
    71  			newPoly(0),
    72  			newPoly(0),
    73  		},
    74  		{
    75  			newPoly(5, -4, 3, 3, 0),
    76  			newPoly(5, -4, 3, 3),
    77  		},
    78  		{
    79  			newPoly(5, 6, 2, 0, 0),
    80  			newPoly(5, 6, 2),
    81  		},
    82  		{
    83  			newPoly(5, -2, 0, 2, 1, 3, 0, 0, 0),
    84  			newPoly(5, -2, 0, 2, 1, 3),
    85  		},
    86  		{
    87  			newPoly(4),
    88  			newPoly(4),
    89  		},
    90  		{
    91  			newPoly(1, 2, 3),
    92  			newPoly(1, 2, 3),
    93  		},
    94  	}
    95  	for _, c := range cases {
    96  		tmp := (c.p).clone(0)
    97  		(c.p).trim()
    98  		if (c.p).compare(&c.ans) != 0 {
    99  			t.Errorf("TRIM(%v) != %v (your answer was %v)\n", tmp, c.ans, c.p)
   100  		}
   101  	}
   102  }
   103  
   104  func TestClone(t *testing.T) {
   105  	cases := []struct {
   106  		p   Poly
   107  		d   int
   108  		ans Poly
   109  	}{
   110  		{
   111  			newPoly(-2, -1, 0, 1, 2),
   112  			-2,
   113  			newPoly(0),
   114  		},
   115  		{
   116  			newPoly(-2, -1, 0, 1, 2),
   117  			0,
   118  			newPoly(-2, -1, 0, 1, 2),
   119  		},
   120  		{
   121  			newPoly(-2, -1, 0, 1, 2),
   122  			1,
   123  			newPoly(0, -2, -1, 0, 1, 2),
   124  		},
   125  		{
   126  			newPoly(-2, -1, 0, 1, 2),
   127  			3,
   128  			newPoly(0, 0, 0, -2, -1, 0, 1, 2),
   129  		},
   130  	}
   131  	for _, c := range cases {
   132  		q := c.p.clone(c.d)
   133  		if q.compare(&c.ans) != 0 {
   134  			t.Errorf("Cloning %v with %v adjust != %v", c.p, c.d, c.ans)
   135  		}
   136  	}
   137  }
   138  
   139  func TestAdd(t *testing.T) {
   140  	cases := []struct {
   141  		p   Poly
   142  		q   Poly
   143  		m   *big.Int
   144  		ans Poly
   145  	}{
   146  		{
   147  			newPoly(1, 1, 0, 2, 2, 1),
   148  			newPoly(1, 1, 1),
   149  			nil,
   150  			newPoly(2, 2, 1, 2, 2, 1),
   151  		},
   152  		{
   153  			newPoly(5, -4, 3, 3),
   154  			newPoly(-4, 1, -2, 1),
   155  			nil,
   156  			newPoly(1, -3, 1, 4),
   157  		},
   158  		{
   159  			newPoly(0),
   160  			newPoly(0),
   161  			nil,
   162  			newPoly(0),
   163  		},
   164  		{
   165  			newPoly(0),
   166  			newPoly(0),
   167  			big.NewInt(2),
   168  			newPoly(0),
   169  		},
   170  		{
   171  			newPoly(5, 6, 2),
   172  			newPoly(-1, -2, 3),
   173  			nil,
   174  			newPoly(4, 4, 5),
   175  		},
   176  		{
   177  			newPoly(5, -2, 0, 2, 1, 3),
   178  			newPoly(2, 7, 0, 3, 0, 2),
   179  			nil,
   180  			newPoly(7, 5, 0, 5, 1, 5),
   181  		},
   182  		{
   183  			newPoly(2, 5, 3, 1),
   184  			newPoly(14, 0, 3, 4),
   185  			nil,
   186  			newPoly(16, 5, 6, 5),
   187  		},
   188  		{
   189  			newPoly(12, 0, 3, 2, 5),
   190  			newPoly(3, 0, 4, 7),
   191  			nil,
   192  			newPoly(15, 0, 7, 9, 5),
   193  		},
   194  		{
   195  			newPoly(4, 0, 0, 3, 0, 1),
   196  			newPoly(0, 0, 0, 4, 0, 0, 6),
   197  			nil,
   198  			newPoly(4, 0, 0, 7, 0, 1, 6),
   199  		},
   200  		{
   201  			newPoly(4, 0, 0, 3, 0, 1),
   202  			newPoly(0, 0, 0, 4, 0, 0, 6),
   203  			big.NewInt(11),
   204  			newPoly(4, 0, 0, 7, 0, 1, 6),
   205  		},
   206  	}
   207  	for _, c := range cases {
   208  		res := (c.p).add(c.q, c.m)
   209  		if res.compare(&c.ans) != 0 {
   210  			t.Errorf("%v + %v != %v (your answer was %v)\n", c.p, c.q, c.ans, res)
   211  		}
   212  	}
   213  }
   214  
   215  func ExampleRandPoly() {
   216  	p := randomPoly(10, 128) // 계수의 크기가 0~2^128인 임의의 10차 다항식 생성
   217  	fmt.Println(p)
   218  }
   219  
   220  func TestRandomPoly(t *testing.T) {
   221  	p := randomPoly(10, 128)
   222  	if p.GetDegree() != 10 {
   223  		t.Errorf("Polynomial %v should have %v degrees", p, p.GetDegree())
   224  	}
   225  	for i := 0; i < p.GetDegree(); i++ {
   226  		if p[i].BitLen() > 128 {
   227  			t.Errorf("Polynomial %v has too large coefficient (%v bits)", p, p[i].BitLen())
   228  		}
   229  	}
   230  }
   231  
   232  func BenchmarkAddTwoIntCoeffPolynomial(b *testing.B) {
   233  	p := newPoly(4, 0, 0, 3, 0, 1)
   234  	q := newPoly(0, 0, 0, 4, 0, 0, 6)
   235  	m := big.NewInt(11)
   236  	b.ResetTimer()
   237  	for i := 0; i < b.N; i++ {
   238  		p.add(q, m)
   239  	}
   240  }
   241  
   242  //func BenchmarkAddTwoBigInt128bitCoeffPolynomial(b *testing.B) {
   243  //	p := RandomPoly(10, 128)
   244  //	q := RandomPoly(10, 128)
   245  //	m := RandomBigInt(128)
   246  //	b.ResetTimer()
   247  //	for i := 0; i < b.N; i++ {
   248  //		p.Add(q, m)
   249  //	}
   250  //}
   251  
   252  func TestSub(t *testing.T) {
   253  	cases := []struct {
   254  		p   Poly
   255  		q   Poly
   256  		m   *big.Int
   257  		ans Poly
   258  	}{
   259  		{
   260  			newPoly(0),
   261  			newPoly(0),
   262  			nil,
   263  			newPoly(0),
   264  		},
   265  		{
   266  			newPoly(0),
   267  			newPoly(0),
   268  			big.NewInt(2),
   269  			newPoly(0),
   270  		},
   271  		{
   272  			newPoly(-9, 2, 5),
   273  			newPoly(-3, 2, 2),
   274  			nil,
   275  			newPoly(-6, 0, 3),
   276  		},
   277  		{
   278  			newPoly(5, -2, 0, 2, 1, 3),
   279  			newPoly(2, 7, 0, 3, 0, 2),
   280  			nil,
   281  			newPoly(3, -9, 0, -1, 1, 1),
   282  		},
   283  		{
   284  			newPoly(12, 0, 3, 2, 0, 0, 0, 12),
   285  			newPoly(4, 0, 4, -11),
   286  			nil,
   287  			newPoly(8, 0, -1, 13, 0, 0, 0, 12),
   288  		},
   289  		{
   290  			newPoly(4, 0, 0, 3, 0, 1),
   291  			newPoly(0, 0, 0, 4, 0, 0, 6),
   292  			nil,
   293  			newPoly(4, 0, 0, -1, 0, 1, -6),
   294  		},
   295  		{
   296  			newPoly(4, 0, 0, 3, 0, 1),
   297  			newPoly(0, 0, 0, 4, 0, 0, 6),
   298  			big.NewInt(11),
   299  			newPoly(4, 0, 0, 10, 0, 1, 5),
   300  		},
   301  	}
   302  	for _, c := range cases {
   303  		res := (c.p).Sub(c.q, c.m)
   304  		if res.compare(&c.ans) != 0 {
   305  			t.Errorf("%v + %v != %v (your answer was %v)\n", c.p, c.q, c.ans, res)
   306  		}
   307  	}
   308  }
   309  
   310  func BenchmarkSub(b *testing.B) {
   311  	p := newPoly(4, 0, 0, 3, 0, 1)
   312  	q := newPoly(0, 0, 0, 4, 0, 0, 6)
   313  	m := big.NewInt(11)
   314  	b.ResetTimer()
   315  	for i := 0; i < b.N; i++ {
   316  		p.Sub(q, m)
   317  	}
   318  }
   319  
   320  func TestMuliply(t *testing.T) {
   321  	cases := []struct {
   322  		p   Poly
   323  		q   Poly
   324  		m   *big.Int
   325  		ans Poly
   326  	}{
   327  		{
   328  			newPoly(0),
   329  			newPoly(0),
   330  			nil,
   331  			newPoly(0),
   332  		},
   333  		{
   334  			newPoly(0),
   335  			newPoly(0),
   336  			big.NewInt(2),
   337  			newPoly(0),
   338  		},
   339  		{
   340  			newPoly(4, 0, 0, 3, 0, 1),
   341  			newPoly(0, 0, 0, 4, 0, 0, 6),
   342  			nil,
   343  			newPoly(0, 0, 0, 16, 0, 0, 36, 0, 4, 18, 0, 6),
   344  		},
   345  		{
   346  			newPoly(4, 0, 0, 3, 0, 1),
   347  			newPoly(0, 0, 0, 4, 0, 0, 6),
   348  			big.NewInt(11),
   349  			newPoly(0, 0, 0, 5, 0, 0, 3, 0, 4, 7, 0, 6),
   350  		},
   351  	}
   352  	for _, c := range cases {
   353  		res := (c.p).Mul(c.q, c.m)
   354  		if res.compare(&c.ans) != 0 {
   355  			t.Errorf("%v + %v != %v (your answer was %v)\n", c.p, c.q, c.ans, res)
   356  		}
   357  	}
   358  }
   359  
   360  func BenchmarkMultiply(b *testing.B) {
   361  	p := newPoly(4, 0, 0, 3, 0, 1)
   362  	q := newPoly(0, 0, 0, 4, 0, 0, 6)
   363  	m := big.NewInt(11)
   364  	b.ResetTimer()
   365  	for i := 0; i < b.N; i++ {
   366  		p.Mul(q, m)
   367  	}
   368  }
   369  
   370  func TestDivide(t *testing.T) {
   371  	cases := []struct {
   372  		p, q     Poly
   373  		m        *big.Int
   374  		quo, rem Poly
   375  	}{
   376  		{
   377  			newPoly(0),
   378  			newPoly(0),
   379  			nil,
   380  			newPoly(0),
   381  			newPoly(0),
   382  		},
   383  		{
   384  			newPoly(0),
   385  			newPoly(0),
   386  			big.NewInt(2),
   387  			newPoly(0),
   388  			newPoly(0),
   389  		},
   390  		{
   391  			newPoly(0, 0, 0, 16, 0, 0, 36, 0, 4, 18, 0, 6),
   392  			newPoly(4, 0, 0, 3, 0, 1),
   393  			nil,
   394  			newPoly(0, 0, 0, 4, 0, 0, 6),
   395  			newPoly(0),
   396  		},
   397  		{
   398  			newPoly(5, 0, 0, 4, 7, 0, 3),
   399  			newPoly(4, 0, 0, 3, 1),
   400  			nil,
   401  			newPoly(34, -9, 3),
   402  			newPoly(-131, 36, -12, -98),
   403  		},
   404  		{
   405  			newPoly(2, 0, 2, 1),
   406  			newPoly(1, 0, 1),
   407  			big.NewInt(3),
   408  			newPoly(2, 1),
   409  			newPoly(0, 2),
   410  		},
   411  		{
   412  			newPoly(5, 0, 0, 4, 7, 0, 3),
   413  			newPoly(4, 0, 0, 3, 1),
   414  			big.NewInt(11),
   415  			newPoly(1, 2, 3),
   416  			newPoly(1, 3, 10, 1),
   417  		},
   418  		// [161x^17 + 43x^16 + 113x^15 + 14x^14 + 258x^13 + 64x^12 + 164x^10 + 250x^9 + 288x^8 + 268x^7 + 13x^6 + 245x^5 + 39x^4 + 234x^2 + 187x + 184]
   419  		{
   420  			newPoly(184, 187, 234, 0, 39, 245, 13, 268, 288, 250, 164, 0, 64, 258, 14, 113, 43, 161),
   421  			newPoly(48, 0, 43, 22, 56, 84, 45, 67, 0, 34, 53),
   422  			big.NewInt(307),
   423  			newPoly(98, 35, 0, 0, 23, 55, 44, 32),
   424  			newPoly(85, 42, 11, 23, 45),
   425  		},
   426  		{
   427  			newPoly(-1, 0, 0, 1),
   428  			newPoly(2, 1),
   429  			nil,
   430  			newPoly(4, -2, 1),
   431  			newPoly(-9),
   432  		},
   433  		{
   434  			newPoly(-15, 3, -5, 1),
   435  			newPoly(-5, 1),
   436  			nil,
   437  			newPoly(3, 0, 1),
   438  			newPoly(0),
   439  		},
   440  		{
   441  			newPoly(4, 0, 0, 0, 1),
   442  			newPoly(-5, 0, 1),
   443  			nil,
   444  			newPoly(5, 0, 1),
   445  			newPoly(29),
   446  		},
   447  		{
   448  			newPoly(-3, 5, -3, 1),
   449  			newPoly(-1, 1),
   450  			nil,
   451  			newPoly(3, -2, 1),
   452  			newPoly(0),
   453  		},
   454  		{
   455  			newPoly(4, -7, 1),
   456  			newPoly(-1, 0, -5, 1),
   457  			nil,
   458  			newPoly(0),
   459  			newPoly(4, -7, 1),
   460  		},
   461  		// 정수 배로 나눠지지 않는 경우에 대한 (몫의 계수가 분수가 되는) 테스트 케이스
   462  		{
   463  			newPoly(-4, 0, 0, 1),
   464  			newPoly(5, 2),
   465  			nil,
   466  			newPoly(0),
   467  			newPoly(-4, 0, 0, 1),
   468  		},
   469  		{
   470  			newPoly(4, 0, 0, 1),
   471  			newPoly(3, 1, 4, 1),
   472  			nil,
   473  			newPoly(1),
   474  			newPoly(1, -1, -4),
   475  		},
   476  		{
   477  			newPoly(4, 0, 0, 1),
   478  			newPoly(3, 1, 4, 1),
   479  			big.NewInt(7),
   480  			newPoly(1),
   481  			newPoly(1, 6, 3),
   482  		},
   483  	}
   484  	for _, c := range cases {
   485  		q, r := (c.p).div(c.q, c.m)
   486  		if q.compare(&c.quo) != 0 || r.compare(&c.rem) != 0 {
   487  			t.Errorf("%v / %v != %v (%v) (your answer was %v (%v))\n", c.p, c.q, c.quo, c.rem, q, r)
   488  		}
   489  	}
   490  }
   491  
   492  func TestGcd(t *testing.T) {
   493  	cases := []struct {
   494  		p   Poly
   495  		q   Poly
   496  		m   *big.Int
   497  		ans Poly
   498  	}{
   499  		{
   500  			newPoly(0),
   501  			newPoly(0),
   502  			nil,
   503  			newPoly(0),
   504  		},
   505  		{
   506  			newPoly(0),
   507  			newPoly(0),
   508  			big.NewInt(2),
   509  			newPoly(0),
   510  		},
   511  		{
   512  			newPoly(4, 0, 0, 1),
   513  			newPoly(3, 1, 4, 1),
   514  			big.NewInt(7),
   515  			newPoly(1),
   516  		},
   517  		// 결과가 상수가 무시되어서 3x^2 + 3이 아니라 x^2 + 1로 나오는데, 이유는 아직 알지 못했다.
   518  		// 우선 x^2 + 1도 CD긴 하기 때문에 넘어간다.
   519  		{
   520  			newPoly(3, 0, 3).Mul(newPoly(4, 5, 6, 7), big.NewInt(13)),
   521  			newPoly(3, 0, 3).Mul(newPoly(5, 6, 7, 8, 9), big.NewInt(13)),
   522  			big.NewInt(13),
   523  			// NewPolyInts(3, 0, 3),
   524  			newPoly(1, 0, 1),
   525  		},
   526  	}
   527  	for _, c := range cases {
   528  		res := (c.p).gcd(c.q, c.m)
   529  		if res.compare(&c.ans) != 0 {
   530  			t.Errorf("GCD(%v, %v) != %v (your answer was %v)\n", c.p, c.q, c.ans, res)
   531  		}
   532  	}
   533  }
   534  
   535  func TestSanitize(t *testing.T) {
   536  	cases := []struct {
   537  		p   Poly
   538  		m   *big.Int
   539  		ans Poly
   540  	}{
   541  		{
   542  			newPoly(1, 2, 3, 4),
   543  			nil,
   544  			newPoly(1, 2, 3, 4),
   545  		},
   546  		{
   547  			newPoly(1, 2, 3, 4),
   548  			big.NewInt(1),
   549  			newPoly(0),
   550  		},
   551  		{
   552  			newPoly(1, 2, 3, 4),
   553  			big.NewInt(2),
   554  			newPoly(1, 0, 1),
   555  		},
   556  	}
   557  	for _, c := range cases {
   558  		q := (c.p).clone(0)
   559  		q.sanitize(c.m)
   560  		if q.compare(&c.ans) != 0 {
   561  			t.Errorf("Sanitized %v with %v != %v", c.p, c.m, c.ans)
   562  		}
   563  	}
   564  }
   565  
   566  func TestEval(t *testing.T) {
   567  	cases := []struct {
   568  		p         Poly
   569  		x, m, ans *big.Int
   570  	}{
   571  		{
   572  			newPoly(0),
   573  			big.NewInt(0),
   574  			nil,
   575  			big.NewInt(0),
   576  		},
   577  		{
   578  			newPoly(0),
   579  			big.NewInt(9),
   580  			nil,
   581  			big.NewInt(0),
   582  		},
   583  		{
   584  			newPoly(0),
   585  			big.NewInt(0),
   586  			big.NewInt(2),
   587  			big.NewInt(0),
   588  		},
   589  		{
   590  			newPoly(0),
   591  			big.NewInt(1),
   592  			big.NewInt(2),
   593  			big.NewInt(0),
   594  		},
   595  		{
   596  			newPoly(1, -4, 1),
   597  			big.NewInt(3),
   598  			nil,
   599  			big.NewInt(-2),
   600  		},
   601  		{
   602  			newPoly(1, -4, 1),
   603  			big.NewInt(-5),
   604  			nil,
   605  			big.NewInt(46),
   606  		},
   607  		{
   608  			newPoly(6, 2, 0, 4, 1),
   609  			big.NewInt(2),
   610  			nil,
   611  			big.NewInt(58),
   612  		},
   613  		{
   614  			newPoly(6, 2, 0, 4, 1),
   615  			big.NewInt(2),
   616  			big.NewInt(10),
   617  			big.NewInt(8),
   618  		},
   619  		{
   620  			newPoly(-9, -5, 0, 3, 1),
   621  			big.NewInt(2),
   622  			nil,
   623  			big.NewInt(21),
   624  		},
   625  		{
   626  			newPoly(1, -1, 2, -3),
   627  			big.NewInt(4),
   628  			nil,
   629  			big.NewInt(-163),
   630  		},
   631  		{
   632  			newPoly(-105, -2, -8, -7, 12),
   633  			big.NewInt(3),
   634  			nil,
   635  			big.NewInt(600),
   636  		},
   637  		{
   638  			newPoly(45545, 343424, 5545, 3445435, 0, 343434, 4665, 5452, 34344, 534556, 4345345, 5656, 434525, 53333, 36645),
   639  			big.NewInt(394),
   640  			big.NewInt(1046527),
   641  			big.NewInt(636194),
   642  		},
   643  	}
   644  	for _, c := range cases {
   645  		res := (c.p).eval(c.x, c.m)
   646  		if res.Cmp(c.ans) != 0 {
   647  			t.Errorf("f(x) = %v, f(%v) != %v (your answer was %v)\n", c.p, c.x, c.ans, res)
   648  		}
   649  	}
   650  }