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 }