From fd243a2566ce5f96ccd2852d41d9b10843757156 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bossuat Date: Thu, 5 Oct 2023 14:03:01 +0200 Subject: [PATCH] [utils/buffer]: added equality checks [ring.Poly]: removed .Buff (not needed anymore) --- bgv/evaluator.go | 4 +- circuits/blindrotation/evaluator.go | 4 +- .../bootstrapping/bootstrapper.go | 1 - circuits/linear_transformation_evaluator.go | 13 +- ckks/bridge.go | 2 +- ckks/encoder.go | 2 +- ckks/evaluator.go | 8 +- drlwe/keygen_evk.go | 2 +- drlwe/keygen_relin.go | 2 +- drlwe/keyswitch_pk.go | 2 +- drlwe/keyswitch_sk.go | 2 +- .../ckks/advanced/scheme_switching/main.go | 2 - rgsw/encryptor.go | 3 +- rgsw/evaluator.go | 4 +- ring/interpolation.go | 2 +- ring/ntt_test.go | 104 +++++------ ring/poly.go | 163 ++++-------------- ring/ring.go | 2 +- ring/ring_benchmark_test.go | 54 +++--- ring/scaling.go | 20 +-- rlwe/decryptor.go | 2 +- rlwe/element.go | 1 - rlwe/evaluator_evaluationkey.go | 2 +- rlwe/evaluator_gadget_product.go | 8 +- rlwe/gadgetciphertext.go | 4 +- rlwe/inner_sum.go | 12 +- rlwe/keygenerator.go | 2 +- rlwe/ringqp/operations.go | 3 +- rlwe/ringqp/poly.go | 77 ++------- utils/buffer/utils.go | 117 +++++++++++++ utils/structs/matrix.go | 14 +- utils/structs/vector.go | 17 +- 32 files changed, 320 insertions(+), 335 deletions(-) diff --git a/bgv/evaluator.go b/bgv/evaluator.go index 5dd740f1..fb4830ae 100644 --- a/bgv/evaluator.go +++ b/bgv/evaluator.go @@ -201,7 +201,7 @@ func (eval Evaluator) Add(op0 *rlwe.Ciphertext, op1 rlwe.Operand, opOut *rlwe.Ci if op0 != opOut { for i := 1; i < op0.Degree()+1; i++ { - ring.Copy(op0.Value[i], opOut.Value[i]) + opOut.Value[i].CopyLvl(level, op0.Value[i]) } } @@ -253,7 +253,7 @@ func (eval Evaluator) evaluateInPlace(level int, el0 *rlwe.Ciphertext, el1 *rlwe // If the inputs degrees differ, it copies the remaining degree on the receiver. if largest != nil && largest != elOut.El() { // checks to avoid unnecessary work. for i := smallest.Degree() + 1; i < largest.Degree()+1; i++ { - elOut.Value[i].Copy(largest.Value[i]) + elOut.Value[i].CopyLvl(level, largest.Value[i]) } } } diff --git a/circuits/blindrotation/evaluator.go b/circuits/blindrotation/evaluator.go index 7f4d309c..9f960945 100644 --- a/circuits/blindrotation/evaluator.go +++ b/circuits/blindrotation/evaluator.go @@ -94,8 +94,8 @@ func (eval *Evaluator) Evaluate(ct *rlwe.Ciphertext, testPolyWithSlotIndex map[i ringQLWE.INTT(ct.Value[0], acc.Value[0]) ringQLWE.INTT(ct.Value[1], acc.Value[1]) } else { - ring.CopyLvl(ct.Level(), ct.Value[0], acc.Value[0]) - ring.CopyLvl(ct.Level(), ct.Value[1], acc.Value[1]) + acc.Value[0].CopyLvl(ct.Level(), ct.Value[0]) + acc.Value[1].CopyLvl(ct.Level(), ct.Value[1]) } // Switch modulus from Q to 2N and ensure they are odd diff --git a/circuits/float/bootstrapper/bootstrapping/bootstrapper.go b/circuits/float/bootstrapper/bootstrapping/bootstrapper.go index 72c9b51e..a4634524 100644 --- a/circuits/float/bootstrapper/bootstrapping/bootstrapper.go +++ b/circuits/float/bootstrapper/bootstrapping/bootstrapper.go @@ -156,7 +156,6 @@ func (btp Bootstrapper) ShallowCopy() *Bootstrapper { bootstrapperBase: btp.bootstrapperBase, //DFTEvaluator: btp.DFTEvaluator.ShallowCopy(), //Mod1Evaluator: btp.Mod1Evaluator.ShallowCopy(), - } } diff --git a/circuits/linear_transformation_evaluator.go b/circuits/linear_transformation_evaluator.go index a7051c9a..2c9314de 100644 --- a/circuits/linear_transformation_evaluator.go +++ b/circuits/linear_transformation_evaluator.go @@ -132,8 +132,9 @@ func MultiplyByDiagMatrix(eval EvaluatorForLinearTransformation, ctIn *rlwe.Ciph cQP.MetaData = &rlwe.MetaData{} cQP.MetaData.IsNTT = true - ring.Copy(ctIn.Value[0], BuffCt.Value[0]) - ring.Copy(ctIn.Value[1], BuffCt.Value[1]) + BuffCt.Value[0].CopyLvl(levelQ, ctIn.Value[0]) + BuffCt.Value[1].CopyLvl(levelQ, ctIn.Value[1]) + ctInTmp0, ctInTmp1 := BuffCt.Value[0], BuffCt.Value[1] ringQ.MulScalarBigint(ctInTmp0, ringP.ModulusAtLevel[levelP], ct0TimesP) // P*c0 @@ -241,8 +242,8 @@ func MultiplyByDiagMatrixBSGS(eval EvaluatorForLinearTransformation, ctIn *rlwe. // Computes the N2 rotations indexes of the non-zero rows of the diagonalized DFT matrix for the baby-step giant-step algorithm index, _, rotN2 := BSGSIndex(utils.GetKeys(matrix.Vec), 1< c1.Degree() && &tmp0.Element != opOut.El() { for i := minDegree + 1; i < maxDegree+1; i++ { - ring.Copy(tmp0.Value[i], opOut.El().Value[i]) + opOut.El().Value[i].CopyLvl(level, tmp0.Value[i]) } } else if c1.Degree() > c0.Degree() && &tmp1.Element != opOut.El() { for i := minDegree + 1; i < maxDegree+1; i++ { - ring.Copy(tmp1.Value[i], opOut.El().Value[i]) + opOut.El().Value[i].CopyLvl(level, tmp1.Value[i]) } } } diff --git a/drlwe/keygen_evk.go b/drlwe/keygen_evk.go index 533b19ba..c5c42823 100644 --- a/drlwe/keygen_evk.go +++ b/drlwe/keygen_evk.go @@ -132,7 +132,7 @@ func (evkg EvaluationKeyGenProtocol) GenShare(skIn, skOut *rlwe.SecretKey, crp E ringQ.MulScalarBigint(skIn.Value.Q, ringQP.RingP.ModulusAtLevel[levelP], evkg.buff[0].Q) } else { levelP = 0 - ring.CopyLvl(levelQ, skIn.Value.Q, evkg.buff[0].Q) + evkg.buff[0].Q.CopyLvl(levelQ, skIn.Value.Q) } m := shareOut.Value diff --git a/drlwe/keygen_relin.go b/drlwe/keygen_relin.go index 2affe4e3..dd5cb56e 100644 --- a/drlwe/keygen_relin.go +++ b/drlwe/keygen_relin.go @@ -133,7 +133,7 @@ func (ekg RelinearizationKeyGenProtocol) GenShareRoundOne(sk *rlwe.SecretKey, cr ringQ.MulScalarBigint(sk.Value.Q, ringQP.RingP.ModulusAtLevel[levelP], ekg.buf[0].Q) } else { levelP = 0 - ring.CopyLvl(levelQ, sk.Value.Q, ekg.buf[0].Q) + ekg.buf[0].Q.CopyLvl(levelQ, sk.Value.Q) } ringQ.IMForm(ekg.buf[0].Q, ekg.buf[0].Q) diff --git a/drlwe/keyswitch_pk.go b/drlwe/keyswitch_pk.go index b14dacc5..67f570ac 100644 --- a/drlwe/keyswitch_pk.go +++ b/drlwe/keyswitch_pk.go @@ -128,7 +128,7 @@ func (pcks PublicKeySwitchProtocol) KeySwitch(ctIn *rlwe.Ciphertext, combined Pu pcks.params.RingQ().AtLevel(level).Add(ctIn.Value[0], combined.Value[0], opOut.Value[0]) - ring.CopyLvl(level, combined.Value[1], opOut.Value[1]) + opOut.Value[1].CopyLvl(level, combined.Value[1]) } // ShallowCopy creates a shallow copy of PublicKeySwitchProtocol in which all the read-only data-structures are diff --git a/drlwe/keyswitch_sk.go b/drlwe/keyswitch_sk.go index 710f20ac..4a000277 100644 --- a/drlwe/keyswitch_sk.go +++ b/drlwe/keyswitch_sk.go @@ -161,7 +161,7 @@ func (cks KeySwitchProtocol) KeySwitch(ctIn *rlwe.Ciphertext, combined KeySwitch opOut.Resize(ctIn.Degree(), level) - ring.CopyLvl(level, ctIn.Value[1], opOut.Value[1]) + opOut.Value[1].CopyLvl(level, ctIn.Value[1]) *opOut.MetaData = *ctIn.MetaData } diff --git a/examples/ckks/advanced/scheme_switching/main.go b/examples/ckks/advanced/scheme_switching/main.go index 3ca5d1e0..296e767a 100644 --- a/examples/ckks/advanced/scheme_switching/main.go +++ b/examples/ckks/advanced/scheme_switching/main.go @@ -221,8 +221,6 @@ func main() { ctN12.LogDimensions = paramsN12.LogMaxDimensions() ctN12.Scale = paramsN12.DefaultScale() - fmt.Println(ctN12.MetaData) - fmt.Printf("Homomorphic Encoding... ") now = time.Now() // Homomorphic Encoding: [BR(a), BR(c), BR(b), BR(d)] -> [(BR(a)+BR(b)i), (BR(c)+BR(d)i)] diff --git a/rgsw/encryptor.go b/rgsw/encryptor.go index 68dcddce..9a942fbb 100644 --- a/rgsw/encryptor.go +++ b/rgsw/encryptor.go @@ -1,7 +1,6 @@ package rgsw import ( - "github.com/tuneinsight/lattigo/v4/ring" "github.com/tuneinsight/lattigo/v4/rlwe" "github.com/tuneinsight/lattigo/v4/rlwe/ringqp" ) @@ -52,7 +51,7 @@ func (enc Encryptor) Encrypt(pt *rlwe.Plaintext, ct interface{}) (err error) { if !pt.IsMontgomery { ringQ.MForm(pt.Value, enc.buffQP.Q) } else { - ring.CopyLvl(levelQ, enc.buffQP.Q, pt.Value) + pt.Value.CopyLvl(levelQ, enc.buffQP.Q) } } diff --git a/rgsw/evaluator.go b/rgsw/evaluator.go index 7b42d4ac..8dee7d1f 100644 --- a/rgsw/evaluator.go +++ b/rgsw/evaluator.go @@ -67,8 +67,8 @@ func (eval Evaluator) ExternalProduct(op0 *rlwe.Ciphertext, op1 *Ciphertext, opO eval.BasisExtender.ModDownQPtoQNTT(levelQ, levelP, c0QP.Q, c0QP.P, opOut.Value[0]) eval.BasisExtender.ModDownQPtoQNTT(levelQ, levelP, c1QP.Q, c1QP.P, opOut.Value[1]) } else { - opOut.Value[0].CopyValues(c0QP.Q) - opOut.Value[1].CopyValues(c1QP.Q) + opOut.Value[0].CopyLvl(levelQ, c0QP.Q) + opOut.Value[1].CopyLvl(levelQ, c1QP.Q) } } } else { diff --git a/ring/interpolation.go b/ring/interpolation.go index 6a5d44dd..c6f57f41 100644 --- a/ring/interpolation.go +++ b/ring/interpolation.go @@ -97,7 +97,7 @@ func (itp *Interpolator) Lagrange(x, y []uint64) (coeffs []uint64, err error) { for i := 0; i < len(x); i++ { - copy(tmp.Buff, basis.Buff) + tmp.Copy(basis) // If x[i] is a root of X^{N} + 1 mod T then it is not part // of the Lagrange basis pre-computation, so all we need is diff --git a/ring/ntt_test.go b/ring/ntt_test.go index 253e2037..39ff04ad 100644 --- a/ring/ntt_test.go +++ b/ring/ntt_test.go @@ -11,80 +11,80 @@ var testVector = []struct { N int Qis []uint64 - Buff []uint64 - BuffNTT []uint64 + poly Poly + polyNTT Poly }{ { 16, []uint64{576460752303439873, 576460752303702017}, - []uint64{ - 29335002291498019, 74733314878908829, 345757914625392883, 424592696763883150, 305098757618029540, 315880659253740539, 566291353020324899, 381879490285643315, 34642655966258078, 436368737741273744, 422320479487058982, 251503834452711492, 379754966293786644, 266993967580766257, 265441209649369663, 479048496297441983, - 229005636957624603, 39991394218169426, 168047666046761487, 148360907414915405, 73259769245767872, 16981974422312794, 496977853225992141, 166066041724987771, 264052080009592093, 298274702686123828, 35777507392976624, 357559017452722394, 314515717429384298, 162821044855043426, 109977030677147798, 81303063671114932, - }, - []uint64{ - 478709994917861263, 384523361984839039, 85280178929118517, 97236771105538581, 405398446277957930, 212032954159995430, 422470404160315474, 554803939008707088, 548834797847219388, 77555291080479046, 395019082584063204, 199181437220481637, 117237287301343342, 288680759037675256, 399758453229973389, 414322896245918704, - 48052203194603178, 560437377430510021, 51924270083317129, 254030332439706305, 520426933791709415, 443676955646482348, 405741025864202685, 70579349438930370, 187051495725458514, 84142641467084820, 194371127241444851, 191269223870154261, 109044160236534164, 304031719544775780, 243823945337031160, 571948182313750664, - }, + Poly{[][]uint64{ + {29335002291498019, 74733314878908829, 345757914625392883, 424592696763883150, 305098757618029540, 315880659253740539, 566291353020324899, 381879490285643315, 34642655966258078, 436368737741273744, 422320479487058982, 251503834452711492, 379754966293786644, 266993967580766257, 265441209649369663, 479048496297441983}, + {229005636957624603, 39991394218169426, 168047666046761487, 148360907414915405, 73259769245767872, 16981974422312794, 496977853225992141, 166066041724987771, 264052080009592093, 298274702686123828, 35777507392976624, 357559017452722394, 314515717429384298, 162821044855043426, 109977030677147798, 81303063671114932}, + }}, + Poly{[][]uint64{ + {478709994917861263, 384523361984839039, 85280178929118517, 97236771105538581, 405398446277957930, 212032954159995430, 422470404160315474, 554803939008707088, 548834797847219388, 77555291080479046, 395019082584063204, 199181437220481637, 117237287301343342, 288680759037675256, 399758453229973389, 414322896245918704}, + {48052203194603178, 560437377430510021, 51924270083317129, 254030332439706305, 520426933791709415, 443676955646482348, 405741025864202685, 70579349438930370, 187051495725458514, 84142641467084820, 194371127241444851, 191269223870154261, 109044160236534164, 304031719544775780, 243823945337031160, 571948182313750664}, + }}, }, { 32, []uint64{576460752303439873, 576460752303702017}, - []uint64{ - 446676853741266417, 411151928268544268, 316113499321051454, 27913108070624651, 51540830435645164, 521237542860943234, 101357399788904570, 131954578061054846, 426126842924748251, 418549260400713113, 16929507722000238, 412590707346441087, 343413419380971676, 78123437644360389, 30202291605923289, 329950404030012174, 45809159977851154, 292606195202689259, 268750103924286497, 568368279163389962, 560909223127878875, 558588607179710396, 493655028901461669, 414111978138777740, 278535078066275616, 113588009827879193, 209261052212448452, 353135346479001399, 346341023042671234, 483982790455356668, 119949406999259397, 254260032891895980, - 143927002157429972, 24687919550176982, 314055826394969007, 189484637018701066, 313366156770460233, 178292577188569981, 542374777815210606, 223556795824542649, 223980592075583470, 423163811223366723, 99190341137476711, 272695567426262689, 266242884542649103, 358056736827572199, 506440945724186274, 334549312617977133, 60514885744437720, 349916159272998893, 91437024533871091, 338072583033829561, 542244024826568584, 363246992092632200, 282873928030797178, 160788901878102755, 254652546645801685, 71233877720226874, 469157444405012905, 541544586457299924, 220088038037539754, 478604268230087801, 70363296523078985, 551543086249836966, - }, - []uint64{ - 137060663770328093, 375023471258971655, 544605838678798786, 171413387990566357, 251152313881280483, 732940359141970, 248105265573021143, 375764270042034794, 334418511524926027, 409224254943060001, 531835442854955749, 268053902549857631, 472427523610083482, 513001774296219269, 89272726349069419, 341799844389716427, 452664419230461269, 475846714013328459, 23638687787168199, 563679077257994351, 501913295240650091, 201362599267133459, 134655194250590929, 539789510912220196, 559584782042897252, 391776092055273537, 479853685312671506, 531912061345838428, 310897563741463711, 430304163842393712, 536402798438763190, 213182781392446404, - 385609543039092107, 98729129892941648, 329153938426401810, 160953615178476141, 151016379459627133, 524736304031292540, 465643194968706978, 187115479287854957, 391680866044038671, 140834657643642928, 574058782286598786, 448304021418840978, 209574484307591910, 572532001944664625, 172479804513191158, 420091611466992599, 119558459469039893, 356435460777079045, 108103374368876106, 503743455397931477, 69380493560432256, 431530551369021053, 186779901639661695, 73454606420882002, 213952214441851970, 519290813869281302, 470443363479802469, 88580125424727240, 251802327334165314, 335123979831683196, 206282586561789865, 50374559611195388, - }, + Poly{[][]uint64{ + {446676853741266417, 411151928268544268, 316113499321051454, 27913108070624651, 51540830435645164, 521237542860943234, 101357399788904570, 131954578061054846, 426126842924748251, 418549260400713113, 16929507722000238, 412590707346441087, 343413419380971676, 78123437644360389, 30202291605923289, 329950404030012174, 45809159977851154, 292606195202689259, 268750103924286497, 568368279163389962, 560909223127878875, 558588607179710396, 493655028901461669, 414111978138777740, 278535078066275616, 113588009827879193, 209261052212448452, 353135346479001399, 346341023042671234, 483982790455356668, 119949406999259397, 254260032891895980}, + {143927002157429972, 24687919550176982, 314055826394969007, 189484637018701066, 313366156770460233, 178292577188569981, 542374777815210606, 223556795824542649, 223980592075583470, 423163811223366723, 99190341137476711, 272695567426262689, 266242884542649103, 358056736827572199, 506440945724186274, 334549312617977133, 60514885744437720, 349916159272998893, 91437024533871091, 338072583033829561, 542244024826568584, 363246992092632200, 282873928030797178, 160788901878102755, 254652546645801685, 71233877720226874, 469157444405012905, 541544586457299924, 220088038037539754, 478604268230087801, 70363296523078985, 551543086249836966}, + }}, + Poly{[][]uint64{ + {137060663770328093, 375023471258971655, 544605838678798786, 171413387990566357, 251152313881280483, 732940359141970, 248105265573021143, 375764270042034794, 334418511524926027, 409224254943060001, 531835442854955749, 268053902549857631, 472427523610083482, 513001774296219269, 89272726349069419, 341799844389716427, 452664419230461269, 475846714013328459, 23638687787168199, 563679077257994351, 501913295240650091, 201362599267133459, 134655194250590929, 539789510912220196, 559584782042897252, 391776092055273537, 479853685312671506, 531912061345838428, 310897563741463711, 430304163842393712, 536402798438763190, 213182781392446404}, + {385609543039092107, 98729129892941648, 329153938426401810, 160953615178476141, 151016379459627133, 524736304031292540, 465643194968706978, 187115479287854957, 391680866044038671, 140834657643642928, 574058782286598786, 448304021418840978, 209574484307591910, 572532001944664625, 172479804513191158, 420091611466992599, 119558459469039893, 356435460777079045, 108103374368876106, 503743455397931477, 69380493560432256, 431530551369021053, 186779901639661695, 73454606420882002, 213952214441851970, 519290813869281302, 470443363479802469, 88580125424727240, 251802327334165314, 335123979831683196, 206282586561789865, 50374559611195388}, + }}, }, { 64, []uint64{576460752303439873, 576460752303702017}, - []uint64{ - 262736013155910555, 134399205275389356, 21914580535790772, 345426000281969043, 251565806300980784, 545370777294757504, 456789672662601734, 420510177617190772, 520650099498412352, 53342176101504322, 266011788449623707, 503030216973029469, 480930369980293997, 321987454665202318, 466721383455395734, 273836137940657795, 409636357248453562, 433469171519178997, 320344646407259980, 141246220203596710, 344797697712039737, 504331654488444275, 539202700550645523, 186179085054939372, 562602814568645298, 543444580531283077, 160169461121173935, 350784691042899162, 32678121466372997, 569786794724914756, 256355426620994401, 3484126615551694, 405840730157601369, 376838154071216457, 373508366771649401, 124731802589699282, 71094821924776811, 306103433799179447, 175750785469731641, 65474140500066740, 371084983783298888, 18142029106380172, 329736515853421422, 132480713678162489, 221251451891618621, 4310502425227271, 363433004803519551, 65796095961889023, 384438118323192470, 274546334934457714, 290850422752767846, 57088190015495864, 40220816835480310, 568564503356230570, 231229810660195894, 81629682680720432, 522733560147139162, 98603219285448603, 83840849230837754, 549213886521809048, 111942201345539170, 187981118119470865, 505358403753068879, 449509564212143658, - 315563096049493706, 286332252766718888, 157584939926698546, 188556064680622140, 362346978677543649, 33141704184747042, 466278349989829991, 217680314197813676, 433045295628943700, 54643309984639923, 520927393042275616, 494539823213582711, 534074936279609670, 30356247676684042, 390039321385674108, 558936758351380586, 374424348267536751, 333003601211472366, 492094016058380509, 489969109220547235, 518904961471759346, 542040069155845363, 533783285422810649, 528578706503018303, 79313562296466244, 57124514167542590, 568476751311349902, 556687943355501029, 154784346549824067, 343793100609373579, 224113348415193184, 122576507003655459, 259944454834590834, 130015234738825441, 523596193693605695, 284717290862492787, 368997453644200803, 204076026471479293, 539397747320010409, 419921142963716925, 552874859521723465, 279937732415513261, 72857419145886547, 146595529257037525, 196777875321712164, 518476909977358962, 290724912693894122, 359188212216346799, 449236428207562273, 320023205841552252, 261698759369002521, 427713683951239679, 387729587142487162, 153540267215424145, 247037912180918548, 100686811633196283, 246517550529399413, 447008318598530981, 222485032549971087, 524469457919726638, 118421467808057284, 354531050174351229, 173072752611467865, 252333998483157087, - }, - []uint64{ - 321518699167648100, 417881319568932369, 230555884338172310, 561831601230838020, 62007425346769512, 447092424612548431, 512502140803857146, 75621680689690000, 382694839073952907, 318607664233993930, 483064334690838999, 221096253615521839, 280196160665220281, 471847866388018856, 131701726817409548, 369959988834814323, 288968454985367497, 327076957002935454, 88423739355957937, 407565851335124222, 555060644108399599, 380495900643829618, 160566237744776480, 60778823305665464, 357931449208419185, 528807315243089409, 533820948251252055, 188157797621304948, 133867446235985518, 421573907993140047, 178857864031357204, 556262544877832945, 536492340226343121, 506894664446621918, 576135288812969955, 407347449908315924, 111848763197334520, 307173437158786090, 116329383774254859, 294490215051904836, 236226507111899091, 76501981671984199, 429852729171957903, 371178100003685567, 412024164717997702, 279335696499888758, 427254685516918570, 529789818950898592, 238711537105549077, 107378873938309514, 99694397370517245, 241162149171422311, 545895879214808028, 516323182030807189, 149803985722268106, 476650002159286016, 179164621851181463, 447940755549723717, 78394092720640890, 189503579058519682, 272017066509510505, 494627433185057558, 353274121069186028, 384517313201141544, - 69861911001200639, 143389998318318571, 343625082217054353, 7187136398219168, 396831517601705732, 152375071740746717, 395864994503611269, 264219981008901846, 334124939535910642, 11136803465188710, 189522479437540624, 258909730001412486, 451619844826507525, 52603901921495475, 140112979349178546, 166887826651010921, 60494535967193849, 522630044587800175, 445249572480018005, 496866786422545760, 142192489017116616, 57224027687618832, 543545371816655579, 182388660010474901, 175934723809254852, 465597801322691571, 129531219899556545, 102222958768734430, 295370372940454186, 390715973324513795, 1105426387445339, 102536906845185018, 268388592020711618, 572351706682694187, 339297510726126351, 456886671308123505, 416822535270988929, 46633807062075381, 31298035199716340, 163416866941300722, 234121726310952657, 77007562713851313, 219264019724753957, 377512342278490701, 555517589494354969, 314128337943076429, 566072226659696563, 223815419652912371, 419004177092870472, 450393143683136850, 14799555274469005, 496596709406778389, 337341506742711794, 296704116716776470, 441263880478669428, 135749193445630877, 313404701892415617, 2883423790615640, 328569093894954878, 473825634302423967, 192163137798299897, 122493010573834389, 487186504536045891, 446940576764364865, - }, + Poly{[][]uint64{ + {262736013155910555, 134399205275389356, 21914580535790772, 345426000281969043, 251565806300980784, 545370777294757504, 456789672662601734, 420510177617190772, 520650099498412352, 53342176101504322, 266011788449623707, 503030216973029469, 480930369980293997, 321987454665202318, 466721383455395734, 273836137940657795, 409636357248453562, 433469171519178997, 320344646407259980, 141246220203596710, 344797697712039737, 504331654488444275, 539202700550645523, 186179085054939372, 562602814568645298, 543444580531283077, 160169461121173935, 350784691042899162, 32678121466372997, 569786794724914756, 256355426620994401, 3484126615551694, 405840730157601369, 376838154071216457, 373508366771649401, 124731802589699282, 71094821924776811, 306103433799179447, 175750785469731641, 65474140500066740, 371084983783298888, 18142029106380172, 329736515853421422, 132480713678162489, 221251451891618621, 4310502425227271, 363433004803519551, 65796095961889023, 384438118323192470, 274546334934457714, 290850422752767846, 57088190015495864, 40220816835480310, 568564503356230570, 231229810660195894, 81629682680720432, 522733560147139162, 98603219285448603, 83840849230837754, 549213886521809048, 111942201345539170, 187981118119470865, 505358403753068879, 449509564212143658}, + {315563096049493706, 286332252766718888, 157584939926698546, 188556064680622140, 362346978677543649, 33141704184747042, 466278349989829991, 217680314197813676, 433045295628943700, 54643309984639923, 520927393042275616, 494539823213582711, 534074936279609670, 30356247676684042, 390039321385674108, 558936758351380586, 374424348267536751, 333003601211472366, 492094016058380509, 489969109220547235, 518904961471759346, 542040069155845363, 533783285422810649, 528578706503018303, 79313562296466244, 57124514167542590, 568476751311349902, 556687943355501029, 154784346549824067, 343793100609373579, 224113348415193184, 122576507003655459, 259944454834590834, 130015234738825441, 523596193693605695, 284717290862492787, 368997453644200803, 204076026471479293, 539397747320010409, 419921142963716925, 552874859521723465, 279937732415513261, 72857419145886547, 146595529257037525, 196777875321712164, 518476909977358962, 290724912693894122, 359188212216346799, 449236428207562273, 320023205841552252, 261698759369002521, 427713683951239679, 387729587142487162, 153540267215424145, 247037912180918548, 100686811633196283, 246517550529399413, 447008318598530981, 222485032549971087, 524469457919726638, 118421467808057284, 354531050174351229, 173072752611467865, 252333998483157087}, + }}, + Poly{[][]uint64{ + {321518699167648100, 417881319568932369, 230555884338172310, 561831601230838020, 62007425346769512, 447092424612548431, 512502140803857146, 75621680689690000, 382694839073952907, 318607664233993930, 483064334690838999, 221096253615521839, 280196160665220281, 471847866388018856, 131701726817409548, 369959988834814323, 288968454985367497, 327076957002935454, 88423739355957937, 407565851335124222, 555060644108399599, 380495900643829618, 160566237744776480, 60778823305665464, 357931449208419185, 528807315243089409, 533820948251252055, 188157797621304948, 133867446235985518, 421573907993140047, 178857864031357204, 556262544877832945, 536492340226343121, 506894664446621918, 576135288812969955, 407347449908315924, 111848763197334520, 307173437158786090, 116329383774254859, 294490215051904836, 236226507111899091, 76501981671984199, 429852729171957903, 371178100003685567, 412024164717997702, 279335696499888758, 427254685516918570, 529789818950898592, 238711537105549077, 107378873938309514, 99694397370517245, 241162149171422311, 545895879214808028, 516323182030807189, 149803985722268106, 476650002159286016, 179164621851181463, 447940755549723717, 78394092720640890, 189503579058519682, 272017066509510505, 494627433185057558, 353274121069186028, 384517313201141544}, + {69861911001200639, 143389998318318571, 343625082217054353, 7187136398219168, 396831517601705732, 152375071740746717, 395864994503611269, 264219981008901846, 334124939535910642, 11136803465188710, 189522479437540624, 258909730001412486, 451619844826507525, 52603901921495475, 140112979349178546, 166887826651010921, 60494535967193849, 522630044587800175, 445249572480018005, 496866786422545760, 142192489017116616, 57224027687618832, 543545371816655579, 182388660010474901, 175934723809254852, 465597801322691571, 129531219899556545, 102222958768734430, 295370372940454186, 390715973324513795, 1105426387445339, 102536906845185018, 268388592020711618, 572351706682694187, 339297510726126351, 456886671308123505, 416822535270988929, 46633807062075381, 31298035199716340, 163416866941300722, 234121726310952657, 77007562713851313, 219264019724753957, 377512342278490701, 555517589494354969, 314128337943076429, 566072226659696563, 223815419652912371, 419004177092870472, 450393143683136850, 14799555274469005, 496596709406778389, 337341506742711794, 296704116716776470, 441263880478669428, 135749193445630877, 313404701892415617, 2883423790615640, 328569093894954878, 473825634302423967, 192163137798299897, 122493010573834389, 487186504536045891, 446940576764364865}, + }}, }, { 128, []uint64{576460752303439873, 576460752303702017}, - []uint64{ - 97732016371625438, 90768199974818125, 23595849830835302, 478885422499237042, 108996286465591924, 475187600246601432, 491862716203655119, 159494203428590386, 86298953356657350, 562114463189719728, 200463004724829630, 523789537205137887, 358995880112345509, 483181203531047114, 270633690098963155, 354018226577377124, 457293484161180612, 4615070116282965, 89459508929019723, 47424445852716043, 90594396247637010, 220111823443415078, 257662573392555331, 502494312437583514, 239879529475689626, 573425983720437055, 516328497942190233, 228663585981915908, 31044209238476914, 103470471392535057, 511388702304518149, 368899608972931801, 145476378422114825, 487262323843288386, 107904745054496760, 88055034521401925, 56585434150885177, 196640462806491624, 136389981623754630, 429337945796009696, 368859988541736714, 430274662842064152, 187928167741063748, 515688314389444158, 403417439106566136, 551094781411023532, 323717266029565895, 558937870392389567, 471754223137848230, 41053112627320707, 280533529583595517, 513722745774380872, 122792603074984110, 46622279786089013, 307230109495809753, 59398079011321018, 96457491398020385, 522373512965930643, 8560103407636529, 399697130543641477, 163636408069114136, 270181995836089240, 470799398781980823, 275862023179614714, 352934896842508278, 76973525847723882, 145264024520135017, 513578871346663476, 207519258128969955, 180610806482892131, 461696011787411799, 313495326350009735, 455144377938354572, 125456045208300616, 119966309744057302, 164454584908665862, 331495774348203429, 503156457433729559, 224062317175947469, 567379598288969077, 135959695035619135, 407153599237326557, 198495743808852847, 113534930252141126, 343789218154206875, 3536564937496768, 37424743627994872, 185027368201141995, 155102784974317747, 191680471691569560, 346628585379348841, 478656761196971099, 139118882313817063, 522846289453610841, 492511851016521522, 555208706527151560, 410495078507399525, 448119356082867571, 99933424485220448, 18602605096800085, 60813036047339118, 241899471610186315, 508576447179129535, 464311473803216558, 376985485353552299, 239126669625602378, 484890106499930913, 94939585375821378, 80566418815363468, 490783670982964035, 202632215947649374, 514965375573062123, 531658123827987081, 398194612767608601, 167284358022337077, 531200074879119802, 439500922768541044, 42776946772722161, 433950184511881293, 557187760642244054, 367933961962701903, 151252559982192845, 64408658886973264, 165626879680944478, 365121108911502794, 1552455093220708, 312347871244871475, 347988306135829908, - 398325085722957575, 329775632531456153, 419176454810781333, 259937617551217697, 168500600223530210, 151991690267387269, 108860511285852494, 45741234805662376, 139917031016975860, 524887574760494778, 456240251042665404, 357023454064000667, 485419448343485916, 76854250369626110, 138909574696165490, 428300086221527047, 206522109314116153, 416925041524789351, 402338246510218858, 39806089199464004, 527614768682258248, 574893639685684494, 500993191228169112, 127983788845553249, 440445520034505118, 74475689070015151, 185211026392384160, 78934254197671055, 279682947346739718, 459087668183506315, 257522726248787837, 85291729968626743, 534585784542715713, 208501964419456912, 332491554969316625, 101721118577979452, 77664248727406705, 184164738988359648, 199710223874186074, 375497967959109926, 179420421015350027, 347007106866446799, 104358682824513902, 285605186360092113, 397873432062930046, 350037900669692725, 159359547494754313, 199729241503021082, 270069020491584608, 420621341744767039, 269150993153950854, 207250053606859043, 388553805955139286, 387186932455512145, 375209872382342182, 161757868733703791, 83288241797297825, 430781647438061446, 193565764711147478, 331750101095272425, 270533223103528663, 246009907947098927, 343596153028940734, 325898328206707924, 526485725493468223, 172528870139112397, 148568946473212136, 118895199068665142, 322183228352808472, 271896751765022794, 364251788081298995, 534166364914271936, 571618495915067346, 463812786889394282, 518524875893781751, 225131790231435031, 230023644297893272, 554198378733268210, 341712025345093378, 212897004176108418, 535697298396097846, 575062050199044406, 404250801270051723, 402057744956922363, 449356218260922361, 333032020782675401, 264784053187607519, 535989260425479141, 538613991494063131, 248707100973686405, 29483832982946595, 50678302117586245, 43263373547418327, 162310563421216118, 95549268923304352, 464518846394694345, 568796153451158330, 499148699826992835, 145821429333245536, 192103152734448584, 462547665762975217, 429060964353116857, 360409893865808917, 451593016220747239, 428362680887466034, 41562968920252920, 371921593701190324, 127075237563276843, 332550010392063718, 279653483682341866, 88936091802481033, 435718773071155969, 131566660099340997, 539543265431320625, 457822377013041147, 573431249779504794, 46774508266591229, 470110573782201612, 242443964863556512, 160533015839175984, 536768099298381324, 243520971791183842, 97485067228223196, 368135663894970265, 397912296323528731, 141091266428462082, 226544164367975752, 184962850955815430, - }, - []uint64{ - 420394463054031650, 569564913731132411, 7057936446468550, 474894849814977477, 104678765359006719, 63897100090302365, 84121548734801645, 29071657980539859, 312596562485814435, 412937401936786180, 255257031480403127, 7954441083802149, 383137992395740056, 263179780928838968, 71559693313454193, 241150603986790194, 112021833841841863, 402837912814282410, 163195346721764893, 339922115031537058, 212981876804802784, 272484675678019595, 404139696441572034, 238170859930359182, 265087401475289832, 391654177782298160, 55829892839968113, 11083746841596170, 477308324356115308, 568054672469371605, 36532226228264539, 313725744411706325, 9205398466664202, 554914639381349993, 273406334607418338, 285270414346177715, 77400150553269002, 448037320165398537, 398904348730917196, 542238686444242620, 424754247816805340, 351483429648832946, 268732552757971248, 250858329812420953, 429317269468409603, 357637259336138504, 123440164854999304, 412723441100850157, 414183923232445449, 369129588506345250, 220206638297796406, 411773441140903109, 142859436910095988, 363257751306364036, 423763047801616368, 413455954860582187, 26168831060195759, 156430718382048772, 116862499252544339, 256516924193897994, 432715869016470822, 400902550031355359, 435553003688250244, 499632169879153552, 485312530067933633, 199828651328794629, 115599539431833135, 155740454982452370, 496837040069892246, 26178608757790613, 313075946181464189, 240731251011491927, 122895835658026575, 414309979961717300, 312515917992525827, 155868573432355125, 138411469573519916, 232922453352193395, 335537085375139194, 92565317781012948, 334301378788565569, 76053694488653081, 438479195569076226, 176428169858642714, 175654452412013639, 302142274752911669, 462766248076079193, 40892045918643330, 79945034714230644, 500232219493329437, 226789253246325774, 208357051761240693, 527523756193329312, 259517406028706401, 445806625286133944, 162461403807387406, 306958040428516002, 473734267232060231, 369953297613195627, 460452828881732036, 569521811633374454, 23392459013483784, 367551559650156239, 561330873032173980, 227465568538238479, 10740125677661565, 279503700143722802, 216362260817857472, 569252656743366550, 75142729955336655, 390695696714765580, 393322591120964327, 200428133408090059, 420909031056172921, 249590947554721395, 151404599367306180, 330502270882464896, 443897791820404714, 475930689244570144, 65631591225342649, 255812264546586573, 330817802134085624, 161146042895115481, 242176965644128670, 89312118193433621, 467015686828527150, 458242814111589255, 568948029306362420, - 191355180928732030, 405357855540537711, 472927423077770114, 549874186985995240, 326823672950218846, 155973286068119857, 408724741674811938, 172208815389299773, 423805038662923104, 333492957710024622, 554486910827107859, 127188220592734687, 531323916087995009, 252077847248100239, 99987234324021569, 37191920143169163, 82937957257410595, 121825521269906453, 339720235218275102, 82789691138534154, 425678228162255303, 494256497063916840, 219582791064837858, 9559459273209693, 177337141404602187, 379331609069569764, 107093807891530473, 119523163322577748, 459581307420743870, 282148383829631456, 344343045771611716, 24166687307241327, 37316153013415913, 542011859596250179, 206329854132876090, 483596897261725805, 494598841991799896, 100225529614506735, 556652301184968611, 262533079300114250, 165762036858858306, 283282416185982281, 48917092271879162, 153594204595882408, 164999600818396832, 99781589091822615, 568067300891789921, 212231385931676268, 465760063245818847, 384695568870808781, 275592609453711831, 285490744001541593, 284493524356424200, 481275463997528269, 64511424442958191, 219978603493132882, 450671120569820905, 538946822064907493, 337304810634702201, 426112725187050881, 338627112439947447, 236150737669507353, 357853806256580240, 548273148624116717, 487275573354804641, 260851638257950504, 247163476136898923, 106461829485094150, 169412788497852852, 282631340341724567, 122221750848179066, 368358750009096263, 250069651722932461, 197763641174247023, 427702227431958631, 210420618628839161, 322428844515049129, 263186465048597744, 343588880726368135, 54678492781491008, 293657697519745641, 236902581815693581, 183205458128341716, 495581739903641563, 472828323354088111, 477996537264977452, 532879355473615148, 64191215950082819, 24432169963705807, 249741571578066401, 7216087568430740, 301372045319276471, 180182075657619845, 2899796465083139, 55792268823198307, 377657792165889326, 441573275497649103, 535471908346744537, 156753996238540302, 508732520354600520, 263725942421718348, 423484844600235916, 321747420070707273, 326325949676532560, 306120346771484630, 432933829874452142, 230155096410032141, 70826888908207334, 210386294609771016, 419311966073912181, 353568115339419853, 413292013674492880, 38192400669035339, 504814848704775633, 440796553634633412, 296473450641927044, 428244252966201208, 376856794738996291, 232567180260004555, 342068816828263509, 10335916813882108, 407606833092021190, 472964373757334560, 464189013609431132, 128203702699855167, 396702136759435423, 535122256056664571, 378398880812001603, - }, + Poly{[][]uint64{ + {97732016371625438, 90768199974818125, 23595849830835302, 478885422499237042, 108996286465591924, 475187600246601432, 491862716203655119, 159494203428590386, 86298953356657350, 562114463189719728, 200463004724829630, 523789537205137887, 358995880112345509, 483181203531047114, 270633690098963155, 354018226577377124, 457293484161180612, 4615070116282965, 89459508929019723, 47424445852716043, 90594396247637010, 220111823443415078, 257662573392555331, 502494312437583514, 239879529475689626, 573425983720437055, 516328497942190233, 228663585981915908, 31044209238476914, 103470471392535057, 511388702304518149, 368899608972931801, 145476378422114825, 487262323843288386, 107904745054496760, 88055034521401925, 56585434150885177, 196640462806491624, 136389981623754630, 429337945796009696, 368859988541736714, 430274662842064152, 187928167741063748, 515688314389444158, 403417439106566136, 551094781411023532, 323717266029565895, 558937870392389567, 471754223137848230, 41053112627320707, 280533529583595517, 513722745774380872, 122792603074984110, 46622279786089013, 307230109495809753, 59398079011321018, 96457491398020385, 522373512965930643, 8560103407636529, 399697130543641477, 163636408069114136, 270181995836089240, 470799398781980823, 275862023179614714, 352934896842508278, 76973525847723882, 145264024520135017, 513578871346663476, 207519258128969955, 180610806482892131, 461696011787411799, 313495326350009735, 455144377938354572, 125456045208300616, 119966309744057302, 164454584908665862, 331495774348203429, 503156457433729559, 224062317175947469, 567379598288969077, 135959695035619135, 407153599237326557, 198495743808852847, 113534930252141126, 343789218154206875, 3536564937496768, 37424743627994872, 185027368201141995, 155102784974317747, 191680471691569560, 346628585379348841, 478656761196971099, 139118882313817063, 522846289453610841, 492511851016521522, 555208706527151560, 410495078507399525, 448119356082867571, 99933424485220448, 18602605096800085, 60813036047339118, 241899471610186315, 508576447179129535, 464311473803216558, 376985485353552299, 239126669625602378, 484890106499930913, 94939585375821378, 80566418815363468, 490783670982964035, 202632215947649374, 514965375573062123, 531658123827987081, 398194612767608601, 167284358022337077, 531200074879119802, 439500922768541044, 42776946772722161, 433950184511881293, 557187760642244054, 367933961962701903, 151252559982192845, 64408658886973264, 165626879680944478, 365121108911502794, 1552455093220708, 312347871244871475, 347988306135829908}, + {398325085722957575, 329775632531456153, 419176454810781333, 259937617551217697, 168500600223530210, 151991690267387269, 108860511285852494, 45741234805662376, 139917031016975860, 524887574760494778, 456240251042665404, 357023454064000667, 485419448343485916, 76854250369626110, 138909574696165490, 428300086221527047, 206522109314116153, 416925041524789351, 402338246510218858, 39806089199464004, 527614768682258248, 574893639685684494, 500993191228169112, 127983788845553249, 440445520034505118, 74475689070015151, 185211026392384160, 78934254197671055, 279682947346739718, 459087668183506315, 257522726248787837, 85291729968626743, 534585784542715713, 208501964419456912, 332491554969316625, 101721118577979452, 77664248727406705, 184164738988359648, 199710223874186074, 375497967959109926, 179420421015350027, 347007106866446799, 104358682824513902, 285605186360092113, 397873432062930046, 350037900669692725, 159359547494754313, 199729241503021082, 270069020491584608, 420621341744767039, 269150993153950854, 207250053606859043, 388553805955139286, 387186932455512145, 375209872382342182, 161757868733703791, 83288241797297825, 430781647438061446, 193565764711147478, 331750101095272425, 270533223103528663, 246009907947098927, 343596153028940734, 325898328206707924, 526485725493468223, 172528870139112397, 148568946473212136, 118895199068665142, 322183228352808472, 271896751765022794, 364251788081298995, 534166364914271936, 571618495915067346, 463812786889394282, 518524875893781751, 225131790231435031, 230023644297893272, 554198378733268210, 341712025345093378, 212897004176108418, 535697298396097846, 575062050199044406, 404250801270051723, 402057744956922363, 449356218260922361, 333032020782675401, 264784053187607519, 535989260425479141, 538613991494063131, 248707100973686405, 29483832982946595, 50678302117586245, 43263373547418327, 162310563421216118, 95549268923304352, 464518846394694345, 568796153451158330, 499148699826992835, 145821429333245536, 192103152734448584, 462547665762975217, 429060964353116857, 360409893865808917, 451593016220747239, 428362680887466034, 41562968920252920, 371921593701190324, 127075237563276843, 332550010392063718, 279653483682341866, 88936091802481033, 435718773071155969, 131566660099340997, 539543265431320625, 457822377013041147, 573431249779504794, 46774508266591229, 470110573782201612, 242443964863556512, 160533015839175984, 536768099298381324, 243520971791183842, 97485067228223196, 368135663894970265, 397912296323528731, 141091266428462082, 226544164367975752, 184962850955815430}, + }}, + Poly{[][]uint64{ + {420394463054031650, 569564913731132411, 7057936446468550, 474894849814977477, 104678765359006719, 63897100090302365, 84121548734801645, 29071657980539859, 312596562485814435, 412937401936786180, 255257031480403127, 7954441083802149, 383137992395740056, 263179780928838968, 71559693313454193, 241150603986790194, 112021833841841863, 402837912814282410, 163195346721764893, 339922115031537058, 212981876804802784, 272484675678019595, 404139696441572034, 238170859930359182, 265087401475289832, 391654177782298160, 55829892839968113, 11083746841596170, 477308324356115308, 568054672469371605, 36532226228264539, 313725744411706325, 9205398466664202, 554914639381349993, 273406334607418338, 285270414346177715, 77400150553269002, 448037320165398537, 398904348730917196, 542238686444242620, 424754247816805340, 351483429648832946, 268732552757971248, 250858329812420953, 429317269468409603, 357637259336138504, 123440164854999304, 412723441100850157, 414183923232445449, 369129588506345250, 220206638297796406, 411773441140903109, 142859436910095988, 363257751306364036, 423763047801616368, 413455954860582187, 26168831060195759, 156430718382048772, 116862499252544339, 256516924193897994, 432715869016470822, 400902550031355359, 435553003688250244, 499632169879153552, 485312530067933633, 199828651328794629, 115599539431833135, 155740454982452370, 496837040069892246, 26178608757790613, 313075946181464189, 240731251011491927, 122895835658026575, 414309979961717300, 312515917992525827, 155868573432355125, 138411469573519916, 232922453352193395, 335537085375139194, 92565317781012948, 334301378788565569, 76053694488653081, 438479195569076226, 176428169858642714, 175654452412013639, 302142274752911669, 462766248076079193, 40892045918643330, 79945034714230644, 500232219493329437, 226789253246325774, 208357051761240693, 527523756193329312, 259517406028706401, 445806625286133944, 162461403807387406, 306958040428516002, 473734267232060231, 369953297613195627, 460452828881732036, 569521811633374454, 23392459013483784, 367551559650156239, 561330873032173980, 227465568538238479, 10740125677661565, 279503700143722802, 216362260817857472, 569252656743366550, 75142729955336655, 390695696714765580, 393322591120964327, 200428133408090059, 420909031056172921, 249590947554721395, 151404599367306180, 330502270882464896, 443897791820404714, 475930689244570144, 65631591225342649, 255812264546586573, 330817802134085624, 161146042895115481, 242176965644128670, 89312118193433621, 467015686828527150, 458242814111589255, 568948029306362420}, + {191355180928732030, 405357855540537711, 472927423077770114, 549874186985995240, 326823672950218846, 155973286068119857, 408724741674811938, 172208815389299773, 423805038662923104, 333492957710024622, 554486910827107859, 127188220592734687, 531323916087995009, 252077847248100239, 99987234324021569, 37191920143169163, 82937957257410595, 121825521269906453, 339720235218275102, 82789691138534154, 425678228162255303, 494256497063916840, 219582791064837858, 9559459273209693, 177337141404602187, 379331609069569764, 107093807891530473, 119523163322577748, 459581307420743870, 282148383829631456, 344343045771611716, 24166687307241327, 37316153013415913, 542011859596250179, 206329854132876090, 483596897261725805, 494598841991799896, 100225529614506735, 556652301184968611, 262533079300114250, 165762036858858306, 283282416185982281, 48917092271879162, 153594204595882408, 164999600818396832, 99781589091822615, 568067300891789921, 212231385931676268, 465760063245818847, 384695568870808781, 275592609453711831, 285490744001541593, 284493524356424200, 481275463997528269, 64511424442958191, 219978603493132882, 450671120569820905, 538946822064907493, 337304810634702201, 426112725187050881, 338627112439947447, 236150737669507353, 357853806256580240, 548273148624116717, 487275573354804641, 260851638257950504, 247163476136898923, 106461829485094150, 169412788497852852, 282631340341724567, 122221750848179066, 368358750009096263, 250069651722932461, 197763641174247023, 427702227431958631, 210420618628839161, 322428844515049129, 263186465048597744, 343588880726368135, 54678492781491008, 293657697519745641, 236902581815693581, 183205458128341716, 495581739903641563, 472828323354088111, 477996537264977452, 532879355473615148, 64191215950082819, 24432169963705807, 249741571578066401, 7216087568430740, 301372045319276471, 180182075657619845, 2899796465083139, 55792268823198307, 377657792165889326, 441573275497649103, 535471908346744537, 156753996238540302, 508732520354600520, 263725942421718348, 423484844600235916, 321747420070707273, 326325949676532560, 306120346771484630, 432933829874452142, 230155096410032141, 70826888908207334, 210386294609771016, 419311966073912181, 353568115339419853, 413292013674492880, 38192400669035339, 504814848704775633, 440796553634633412, 296473450641927044, 428244252966201208, 376856794738996291, 232567180260004555, 342068816828263509, 10335916813882108, 407606833092021190, 472964373757334560, 464189013609431132, 128203702699855167, 396702136759435423, 535122256056664571, 378398880812001603}, + }}, }, { 256, []uint64{576460752303439873, 576460752303702017}, - []uint64{ - 42095160184191000, 109101595944152791, 490530386447891500, 171393827246485763, 110066244758193925, 413440073288790893, 253681535583379831, 511102234531820997, 106435434329997370, 183403433702896376, 311359441342055641, 221719924066175751, 505010381164697913, 38455312130442060, 281909799692314474, 402305504287088226, 500164147660483358, 414314304330256017, 132065090934975693, 404346546548112940, 158409908441754836, 433457066568118999, 141755316783727143, 282541307859821168, 224917229807049984, 290631930283612638, 272532647916209017, 138458337514237703, 354181256135944589, 175208090049028319, 482027769823559570, 223188243069432430, 342635721857832851, 224091616177813417, 453357531624640918, 321102614631377362, 254890405696764061, 415542557926396570, 568360094162080701, 144890852887622912, 395843700531424678, 446257592060263881, 285666389722628531, 74216204189607313, 354597507719852127, 59365746891320294, 136783141570697408, 317721434520531089, 143270676462505953, 464765483621648927, 576100813526367849, 428897244487554806, 555202077615358328, 1118640504721798, 447441771294283992, 373514785797509738, 68260550619114810, 101055759353303002, 168695834573790944, 296078415630821900, 375109959789366892, 49120763705053158, 119138071806041863, 446275089288716164, 477235143992470955, 41140098073621558, 219575705399502446, 143115084384016282, 414091277018708128, 42907353338498586, 214857307631643856, 390861284062543671, 505723008283008911, 34718168101536049, 221294945918905446, 16480829279690232, 340050113253715474, 297527848625908756, 403134122946882893, 82925442740832597, 218001989160574916, 72181603721849961, 469692366598574494, 114691768354584879, 169087336081420619, 377543756453981149, 76114442184171873, 32614552908826520, 292986841750829378, 400553556847944265, 561202132487905836, 39502044093572447, 453485916966755059, 370519733979222474, 391909390346229646, 290789750336523877, 239674582921592825, 58773791812475502, 244726911467017287, 172632505562997584, 162471182882668503, 199313229952675728, 270090408962296077, 110806856688729838, 130042004855178137, 149575204127098828, 504010106716522724, 532033355825339464, 434748323387128334, 150925693127442121, 84185731522507367, 129444981333730569, 378582347355952974, 327999288851923860, 271141701027232697, 151548415894965517, 52042318852554145, 39572856504735093, 324819094404321437, 320425818788696121, 149668269633022161, 223914593491690507, 75516351444637887, 495423309708630673, 482266571176917986, 256725859922264266, 545312652490136114, 427931270165449918, 269546602914647900, 231294584508865490, 477908582353219179, 451007695513934983, 170761942014601681, 38769511583578705, 465059377903516857, 399494122252914730, 418566400189546569, 452421231121962208, 269769793790549794, 479550566668440029, 305098899397494455, 499345041000781302, 544933826734100820, 75127817669661127, 364548385491999782, 128061976515363153, 285468625521793188, 105151831678752224, 187847280420256196, 298890141588403066, 494477757230600967, 576271026411553984, 396802250316269560, 161417424164405155, 369356761514252968, 393303600092423304, 481316118790208624, 139884366159272722, 275416529581728349, 267353162828239771, 302172837522223228, 293833235014017326, 43240964572265380, 383076704502018817, 116582168312681937, 461936290145643571, 498407564943578062, 224332901212239694, 46041774682936653, 504966370988506014, 435030051955717661, 406909309228098464, 38004516362021717, 159486942099202560, 282489967857058119, 343698342810914671, 545049917977963325, 202915328715475754, 139708103671758502, 194686971420973342, 423240869540423291, 59658536488735488, 2173743062549785, 438988899357490895, 460642788622320370, 336524309568430599, 438966169609715032, 415102773586753626, 308742914778230283, 536290974484555410, 162447487779786800, 260642931312522096, 381630136254177076, 247318909606758737, 157162909883115922, 542183189837652739, 191363918036388022, 511421578978915816, 155289566189272746, 474643826816753309, 282384869793380335, 303495759249360883, 544086828773329727, 223609247280629081, 179938137573415822, 73454685303433194, 423300613036699254, 264566591005031818, 438669694391669160, 458812077765198307, 197987594379189501, 531493751250075326, 358592844839950556, 452956070736604204, 192891297407597414, 103642895263710177, 73357442156405111, 511442708062650304, 112431036110854468, 253712893432734789, 281333891072346804, 481379892629981665, 340113313507355936, 561605362196202798, 399684792219746040, 184346988374227074, 249508322266560187, 546155683122114420, 389361249960108326, 512092961001210228, 406247585968781480, 111659389464777842, 451513713237682854, 256380466618677357, 483200397019642190, 15836568063995494, 4743510619301532, 550773698467534918, 203117385120991553, 441977035355301742, 344073917441478448, 430232310037595356, 372259494064077314, 51174529221651528, 259011216293149348, 167685132132967610, 205634545095293698, 521208430360029185, 247714295723670540, 215181531976043968, 295152622066067294, 91537131024755956, 433585203463688765, 427545441130862653, 421241715290760485, 49292291716570307, - 438374079923311408, 151871225000496280, 165490415952193415, 522881568787105855, 36374894333704923, 269982211477284085, 88517474106497880, 515153623835117885, 733130356621373, 522805170603975632, 107078018493783679, 170805418557284752, 138423831533518810, 11034275853485810, 11233467300215081, 422885813851017592, 423947764850803718, 167390123076436879, 235377630525523241, 42004027801445773, 136144817282271289, 470352744814720880, 251060196273723094, 467298502067495119, 268519609438488785, 119599681706482127, 353490853305360867, 38289179009319859, 385846258549538228, 392342244944969068, 314658921800917237, 420918755451390776, 178855629118933307, 569355817429455235, 273806823343357993, 316680332101990374, 500079278160820228, 108457819994853199, 537863397798939048, 79361762498464675, 63162502763174308, 16283885757587140, 507298692262438380, 523659720536621853, 98417649894355803, 106474132144814944, 455397768304575748, 457042069241188378, 388370019102546906, 220803563888461490, 333150349836751502, 228407529700780707, 208642537155428790, 407329668459419432, 520696492869119053, 445095301460633809, 542703106475933867, 214936712509960888, 163082455286029846, 443442316550747828, 256820606313500140, 183779793576925130, 366196012280169192, 363229854560350969, 107477986206315830, 251477541394054972, 111236039976311875, 285145169153116235, 554652150268589124, 72687953537031470, 486812332379737643, 148681257217061898, 152064031653944667, 286309440252081212, 405633493567400926, 457688641338310689, 276341392127817855, 185302683967219110, 225622054839114028, 216395984228346698, 190175892719312110, 122428859679701124, 40882151520859909, 264981204486729686, 458614000867786793, 364990983485586793, 428081893773536975, 220069494819961279, 168885902294474096, 86078230691140650, 325228274286538712, 358007621955930, 399555289040732189, 297884936626978455, 168234425609076513, 265384114349611699, 126934854461956946, 112121012707107665, 225440203209834333, 136028286584260516, 230525319375803967, 150972772427181231, 22208097738400617, 281762400222670220, 436622750040836967, 333898151588389667, 99056287217213919, 563093741248231929, 337060085442606637, 281788951773006014, 134731035525600259, 535656922686363283, 136491233346242323, 535320754798296843, 237265923006068074, 426830010752826876, 305723647276639232, 150722151409138685, 97089744439964852, 496927154968869817, 400102703139245285, 132822370587985550, 366025949131468290, 531495565238433533, 71164889923959401, 166427098759126682, 117070099686703019, 293773064870361263, 573417900647239041, 407308643121250375, 369960143573050718, 536116434056842074, 80841203252698886, 401054811478765343, 474758682648269165, 530626897040482187, 352061327377598790, 403671262828650487, 158151377948777897, 553713350004834331, 417923400425827185, 316567146170698076, 12576508386705328, 357480477764326584, 29112903284401295, 107629048775537217, 525393354158079036, 214537399568531046, 167658412364557630, 321648389321312353, 469366305788064601, 33407383718738610, 440262400626763643, 209672037072956107, 64908494015551581, 110567275144257239, 357216922555514710, 229667147816038358, 247282547492043835, 111719371911355255, 95253480903670755, 333186733358808993, 239393651253448537, 145417273422324014, 148362193019605513, 370833859151328863, 407002300064570532, 131087043323355832, 53849312492062398, 481830700823584990, 258536652743636015, 420397979939671260, 347665750812598169, 543696561907371157, 512334250516405603, 308164065166453277, 119012028433735704, 551883964943518273, 182935178261089087, 238841136170274915, 88333507146103821, 331758579405713647, 345685851194730117, 136454258722123543, 406097219592408783, 437318349362164895, 411505921450126339, 333343310848662971, 35994437704538912, 55865647364230075, 478339409437900214, 108077472941608600, 82714472134664508, 518432368345935435, 447765746559718468, 395443194116628701, 446622261967094684, 53684991760284855, 531998427286233184, 277279719584419176, 528098262174261941, 118358852234620113, 283543211158663639, 561165515612370208, 172594565512727479, 262686943116580648, 44055602050243476, 76350781930416594, 131179299042115405, 566519337177013965, 99266541098759746, 131325658890483070, 154975066658623313, 472783319139290132, 238731997419179272, 241460952476788274, 174504811499336743, 234550099979288246, 322204355955622110, 78934200094653384, 254498991004487279, 318178349068844855, 139159150976171248, 270732342221664832, 31904671983518729, 1100745834824478, 357462621593724734, 30593891889121841, 430506947873667140, 171304948801765569, 313155301989235709, 520489190168724055, 95377385270785471, 97680931624385533, 435475457795949562, 573747055445900046, 292756317642577656, 306583520152022872, 405880325977863201, 278751083849767849, 523204570955123616, 547636268381344087, 196942936787428169, 279923994922621153, 399554591066591782, 322120175749227817, 218068820571191915, 298598319400913252, 412281257441713547, 402157633807623434, 128308786147750049, 363702136535218999, 100779271334970249, 16619101977999813, 341889113861022873, 150595312585620805, - }, - []uint64{ - 25539180957916247, 134576910680253174, 475363799372172620, 28098986814455855, 274716161371720394, 312179856793930138, 164377263132000736, 142008666615288623, 182735566456326871, 10866356083886021, 208090517816132918, 52878905204697439, 91648973731241697, 574991989957693552, 500536710584824592, 358944371207232906, 523477132322162594, 548193187974410427, 235886312841325678, 150731728017218454, 281797201443117083, 563294233426118731, 289732758013117188, 570620768676577299, 398615831645796041, 97428788315228353, 102871409071546815, 532774000551509196, 360827243328873706, 535362656854269158, 535059407809998454, 241346422338253426, 24536225847950339, 187719898399036285, 208087398158017137, 549455574829620242, 228473756573465231, 125101592748151531, 485669259184335899, 314907593061345725, 261963958161490446, 525546180420182151, 22554511326833137, 376466522385895002, 369473114047926329, 303203901068497041, 574674676229664439, 527504934235112472, 168298047449962932, 6959731275881451, 301905062208822778, 35729762669654407, 20493061307934269, 131432970048788868, 520631529780789195, 301752544003086126, 516394549566453450, 161796946742173945, 363730488537718291, 10381192361222532, 257478649793918421, 460797117008135956, 239533633719433201, 393571089242275604, 3025580076213915, 564788969263356003, 52926550336486024, 385158042964444234, 558404729092018644, 273273984521467187, 336829236901536149, 136259161339784794, 165972191001738739, 471195471629941990, 186627813815902895, 456559165377063043, 166026756416732478, 188754579842951634, 507086289889700319, 240511770516592994, 572903766245421175, 220419217563396790, 79394335226244850, 177831146025370705, 543848533539555140, 434815340316821821, 518688466567666280, 391830584516654655, 30933794264219615, 161405910933666617, 113452875623048931, 313941012128973161, 340599144874841662, 111666143698454306, 231072651334712398, 155616342986526411, 385563544154691802, 244056537020624835, 487068683308690119, 36993212127766784, 502465771527461487, 142390985028631718, 126906895255600475, 261239512512479410, 21161876464410161, 187947661511159557, 233535577934386038, 312138394777933399, 110643166062619700, 145206386746299120, 553028679425068984, 140706971970880894, 407939191362266539, 37289166785375282, 508157176141245827, 551706527909310995, 186458252254574880, 128706071973384520, 182994710910888687, 411552050321037567, 547771777360445370, 404363457914024452, 70844599449300401, 217316763159908291, 513423675799578835, 79684810495498019, 486613676201445617, 41145886242735629, 244328374970552507, 555498041402474309, 193097096277950439, 193322820485223642, 278098841963886377, 446088133563104331, 150368262197327810, 57814225182172893, 398900050623878621, 182682427176814874, 92318944605526269, 492708910209069566, 420268440336995572, 145657280705904455, 343314692203719814, 307422559616350551, 44164989486021902, 214443534430470015, 296999464537290595, 43462846506271095, 216208877773345992, 563303440845370321, 348258372473146442, 397062819065434969, 153146538498376426, 254290911314356679, 132001547094349104, 364547972914370422, 19707992960332453, 140039763791528979, 556377762570493749, 402149051732693816, 140253667944514421, 337563373862946670, 374978005797593455, 189126997987002783, 417283864907300551, 136506305103680265, 175982684712968603, 547282725480307214, 216604131378799933, 301976393125085872, 221095440783864307, 433607819548180555, 447740292619155239, 403534477140159291, 405040738050507824, 3415154835862812, 143391176700890182, 286719766792058075, 53303431082522763, 31901773118684527, 232475810483024708, 384962764956909578, 47050371056891006, 494242028238355208, 199516451799148501, 286660269856407413, 144867723385532441, 305631527286204929, 564731806991992075, 123358856332573195, 307667212210298256, 293075170888354570, 174908206112234882, 129089751003290360, 474375508153621337, 183608558781373932, 444232557414546029, 263358914639985593, 271259612067651959, 324488002261909057, 525442980499421281, 342722666680451556, 461946597276054625, 271762493639233455, 290502006389591490, 313211662042179852, 12257852953623893, 18787810968673210, 125914252484836784, 189437221511680189, 400657183087768110, 311040266109793939, 228204108229580419, 149782056579785096, 162526192005070423, 398015975429587692, 253216106124630717, 329756581376514000, 225447746805029464, 156966782898480045, 486360406929135337, 198540927585903828, 445404412810388420, 232006240862884241, 447700714943003583, 224634965652784343, 410634304584122048, 512823303344584600, 130972449347622764, 431618391706465191, 400658951067291848, 389050390523422608, 26121738213936139, 497382085969742655, 77565734253027774, 493536528715434320, 244029356101575008, 197760024591534648, 169810260685743310, 413572371974577702, 44943371344227053, 342037367697811921, 574608314263527686, 491240089951929483, 74820066611494113, 205738823101341462, 211835392589657488, 185392954748001361, 491682849059049131, 282290383290792071, 238680569454837425, 489904800548920901, 439977546850826561, 162263651720776212, 232613675637076929, 9824498340588603, - 145262921017258530, 509093843511663073, 69280768158594495, 476975569887795922, 200578418001088989, 511954582967998215, 81004975188137317, 434563516464118473, 3742487127533537, 148853904131153735, 74250494922324744, 342102325202151178, 216224407082221091, 293496062152831898, 136490810673202468, 339428511849083731, 104048513922313017, 475425927213645945, 488518960243328468, 492132661995355315, 568869884521887731, 525754896308909538, 308757899760222748, 543052554698889604, 127011667295243721, 143951070705256545, 333924117897825325, 468824765157795015, 536375648731223460, 500143443529480066, 378489507927363322, 279125852150864901, 281030498504685879, 168745392570902508, 539413237674932832, 250602279388059960, 200993615157345610, 92881688160082790, 475445572000753331, 426044792013466179, 336290989081788700, 475122233276581982, 571860618885320337, 100964993358312625, 372984491119389868, 344569715565410746, 60242051153217051, 88469947602760817, 371439217449124235, 82865000924762212, 533773493545592846, 283571462528268311, 8050888500210530, 548686786463874881, 500956635065080289, 206216378852994063, 216220061258450222, 18289119905402672, 520780087101851718, 458244492867167112, 477330924013911956, 27986645549973413, 398017447689976420, 72499293099358184, 15661124530407527, 436483150471732051, 105655592136018165, 250794382657150445, 502230204109251559, 15902090664674169, 24128985185766359, 576339228734293097, 380943101080030564, 317679187729245422, 291821169074489762, 263753517262679069, 500813118120459206, 5907313506942712, 568798513863161214, 568006665966008790, 463900981809306760, 569323025022789054, 531030207503205866, 548067340028132440, 216123285147297852, 95879880056442795, 228011300554486051, 5622793593072754, 162958380973089483, 144297612561770555, 503945874230219663, 510213895744613944, 427370607720726159, 485146245914886276, 512916632692748009, 125006578501399088, 291231141910373887, 34629924131612135, 172483273858493350, 191078353494166299, 337889874121201580, 39069074983148686, 43844758560188396, 274933702252441871, 212961990507164718, 31952093639076407, 38148544443399351, 81177593602577738, 573173862197834520, 147438384745255134, 522225120977990761, 128293858134848977, 179376240238201377, 229390590519503455, 448982237341985904, 428431412426973447, 444523050934342371, 161540441021111816, 344327418634019499, 538632796364184769, 286241785850763117, 540885238416105908, 199039391238087947, 398173855569002898, 443657369837614220, 521436485927088249, 350958660678604668, 531550026478083390, 292329282653892802, 249865445848442004, 334844977362494761, 253735217175168864, 136440994953492269, 347988625988330869, 78855725766197923, 6886427804107858, 50323489907205385, 58723685908139964, 363721068166739517, 115361456607105021, 430865188649593152, 306506558745397883, 16347848324091673, 554960316053659212, 545770074143278266, 33128127278684866, 105772739927473782, 48870139210473549, 58794748087836674, 474712978371384419, 19565336952072949, 545102013246715960, 284794162160562258, 534046768243604871, 515139885978567640, 75943870618151495, 284478323301965809, 211393418778887787, 489917114612131538, 188837273741590513, 543734395403836874, 296728025656446498, 255513679081425658, 140034757922212665, 125105027344710076, 376805120950157646, 487762543330067162, 73771023075742516, 263612713835667176, 70916292187027797, 521041078726186979, 63072561940441183, 391041648541819815, 561191955917166645, 484383301426882619, 524939240614839600, 467905925305918463, 106615952246108837, 283645178526878518, 28844359403488479, 147243109816115707, 135557950651844021, 114531164825658671, 328546338419561676, 343928718523665033, 265711254649598556, 70610661045066165, 427057141155416534, 276055042511001360, 231708851502383818, 295639172412693425, 287750111926231800, 406212266070789998, 36740714235231076, 474250293682940522, 435581687227388193, 196309786272732675, 507185714491123044, 87854256637724473, 520719983214989992, 309761945023637181, 512005901530248566, 49779398819269784, 382269384917273187, 168582591020161001, 545252104333691897, 496452821607793877, 416516492420337001, 340944168282202371, 408719995683740029, 456885247723827471, 338637400820834302, 451239483358210867, 56871254144936084, 561207652586726183, 8053350254065332, 334280587965584003, 327702914397759466, 87572048046481558, 490378938312633310, 495270055649375258, 33600534065660095, 331477468756018874, 144608221167985876, 284139694548925586, 314889468034604849, 416733161198210068, 159979018438447742, 239314906816503442, 141394866156749784, 8215297667275886, 144926935976350507, 475011371483347491, 530765618252712380, 17739432276654581, 228304617638032389, 75037080049003521, 528668068991034981, 144850219018031660, 237897487839865383, 216386763675580863, 46440500047230549, 287813643373639666, 400047078833455375, 387196340896419108, 306127222070311235, 134096648470839873, 450899972818645458, 116213931387898665, 283965153430444480, 131430617068404218, 390867652280397264, 58206120712600131, 5314128460251204, 417802652644041302, 464476082998386550, - }, + Poly{[][]uint64{ + {42095160184191000, 109101595944152791, 490530386447891500, 171393827246485763, 110066244758193925, 413440073288790893, 253681535583379831, 511102234531820997, 106435434329997370, 183403433702896376, 311359441342055641, 221719924066175751, 505010381164697913, 38455312130442060, 281909799692314474, 402305504287088226, 500164147660483358, 414314304330256017, 132065090934975693, 404346546548112940, 158409908441754836, 433457066568118999, 141755316783727143, 282541307859821168, 224917229807049984, 290631930283612638, 272532647916209017, 138458337514237703, 354181256135944589, 175208090049028319, 482027769823559570, 223188243069432430, 342635721857832851, 224091616177813417, 453357531624640918, 321102614631377362, 254890405696764061, 415542557926396570, 568360094162080701, 144890852887622912, 395843700531424678, 446257592060263881, 285666389722628531, 74216204189607313, 354597507719852127, 59365746891320294, 136783141570697408, 317721434520531089, 143270676462505953, 464765483621648927, 576100813526367849, 428897244487554806, 555202077615358328, 1118640504721798, 447441771294283992, 373514785797509738, 68260550619114810, 101055759353303002, 168695834573790944, 296078415630821900, 375109959789366892, 49120763705053158, 119138071806041863, 446275089288716164, 477235143992470955, 41140098073621558, 219575705399502446, 143115084384016282, 414091277018708128, 42907353338498586, 214857307631643856, 390861284062543671, 505723008283008911, 34718168101536049, 221294945918905446, 16480829279690232, 340050113253715474, 297527848625908756, 403134122946882893, 82925442740832597, 218001989160574916, 72181603721849961, 469692366598574494, 114691768354584879, 169087336081420619, 377543756453981149, 76114442184171873, 32614552908826520, 292986841750829378, 400553556847944265, 561202132487905836, 39502044093572447, 453485916966755059, 370519733979222474, 391909390346229646, 290789750336523877, 239674582921592825, 58773791812475502, 244726911467017287, 172632505562997584, 162471182882668503, 199313229952675728, 270090408962296077, 110806856688729838, 130042004855178137, 149575204127098828, 504010106716522724, 532033355825339464, 434748323387128334, 150925693127442121, 84185731522507367, 129444981333730569, 378582347355952974, 327999288851923860, 271141701027232697, 151548415894965517, 52042318852554145, 39572856504735093, 324819094404321437, 320425818788696121, 149668269633022161, 223914593491690507, 75516351444637887, 495423309708630673, 482266571176917986, 256725859922264266, 545312652490136114, 427931270165449918, 269546602914647900, 231294584508865490, 477908582353219179, 451007695513934983, 170761942014601681, 38769511583578705, 465059377903516857, 399494122252914730, 418566400189546569, 452421231121962208, 269769793790549794, 479550566668440029, 305098899397494455, 499345041000781302, 544933826734100820, 75127817669661127, 364548385491999782, 128061976515363153, 285468625521793188, 105151831678752224, 187847280420256196, 298890141588403066, 494477757230600967, 576271026411553984, 396802250316269560, 161417424164405155, 369356761514252968, 393303600092423304, 481316118790208624, 139884366159272722, 275416529581728349, 267353162828239771, 302172837522223228, 293833235014017326, 43240964572265380, 383076704502018817, 116582168312681937, 461936290145643571, 498407564943578062, 224332901212239694, 46041774682936653, 504966370988506014, 435030051955717661, 406909309228098464, 38004516362021717, 159486942099202560, 282489967857058119, 343698342810914671, 545049917977963325, 202915328715475754, 139708103671758502, 194686971420973342, 423240869540423291, 59658536488735488, 2173743062549785, 438988899357490895, 460642788622320370, 336524309568430599, 438966169609715032, 415102773586753626, 308742914778230283, 536290974484555410, 162447487779786800, 260642931312522096, 381630136254177076, 247318909606758737, 157162909883115922, 542183189837652739, 191363918036388022, 511421578978915816, 155289566189272746, 474643826816753309, 282384869793380335, 303495759249360883, 544086828773329727, 223609247280629081, 179938137573415822, 73454685303433194, 423300613036699254, 264566591005031818, 438669694391669160, 458812077765198307, 197987594379189501, 531493751250075326, 358592844839950556, 452956070736604204, 192891297407597414, 103642895263710177, 73357442156405111, 511442708062650304, 112431036110854468, 253712893432734789, 281333891072346804, 481379892629981665, 340113313507355936, 561605362196202798, 399684792219746040, 184346988374227074, 249508322266560187, 546155683122114420, 389361249960108326, 512092961001210228, 406247585968781480, 111659389464777842, 451513713237682854, 256380466618677357, 483200397019642190, 15836568063995494, 4743510619301532, 550773698467534918, 203117385120991553, 441977035355301742, 344073917441478448, 430232310037595356, 372259494064077314, 51174529221651528, 259011216293149348, 167685132132967610, 205634545095293698, 521208430360029185, 247714295723670540, 215181531976043968, 295152622066067294, 91537131024755956, 433585203463688765, 427545441130862653, 421241715290760485, 49292291716570307}, + {438374079923311408, 151871225000496280, 165490415952193415, 522881568787105855, 36374894333704923, 269982211477284085, 88517474106497880, 515153623835117885, 733130356621373, 522805170603975632, 107078018493783679, 170805418557284752, 138423831533518810, 11034275853485810, 11233467300215081, 422885813851017592, 423947764850803718, 167390123076436879, 235377630525523241, 42004027801445773, 136144817282271289, 470352744814720880, 251060196273723094, 467298502067495119, 268519609438488785, 119599681706482127, 353490853305360867, 38289179009319859, 385846258549538228, 392342244944969068, 314658921800917237, 420918755451390776, 178855629118933307, 569355817429455235, 273806823343357993, 316680332101990374, 500079278160820228, 108457819994853199, 537863397798939048, 79361762498464675, 63162502763174308, 16283885757587140, 507298692262438380, 523659720536621853, 98417649894355803, 106474132144814944, 455397768304575748, 457042069241188378, 388370019102546906, 220803563888461490, 333150349836751502, 228407529700780707, 208642537155428790, 407329668459419432, 520696492869119053, 445095301460633809, 542703106475933867, 214936712509960888, 163082455286029846, 443442316550747828, 256820606313500140, 183779793576925130, 366196012280169192, 363229854560350969, 107477986206315830, 251477541394054972, 111236039976311875, 285145169153116235, 554652150268589124, 72687953537031470, 486812332379737643, 148681257217061898, 152064031653944667, 286309440252081212, 405633493567400926, 457688641338310689, 276341392127817855, 185302683967219110, 225622054839114028, 216395984228346698, 190175892719312110, 122428859679701124, 40882151520859909, 264981204486729686, 458614000867786793, 364990983485586793, 428081893773536975, 220069494819961279, 168885902294474096, 86078230691140650, 325228274286538712, 358007621955930, 399555289040732189, 297884936626978455, 168234425609076513, 265384114349611699, 126934854461956946, 112121012707107665, 225440203209834333, 136028286584260516, 230525319375803967, 150972772427181231, 22208097738400617, 281762400222670220, 436622750040836967, 333898151588389667, 99056287217213919, 563093741248231929, 337060085442606637, 281788951773006014, 134731035525600259, 535656922686363283, 136491233346242323, 535320754798296843, 237265923006068074, 426830010752826876, 305723647276639232, 150722151409138685, 97089744439964852, 496927154968869817, 400102703139245285, 132822370587985550, 366025949131468290, 531495565238433533, 71164889923959401, 166427098759126682, 117070099686703019, 293773064870361263, 573417900647239041, 407308643121250375, 369960143573050718, 536116434056842074, 80841203252698886, 401054811478765343, 474758682648269165, 530626897040482187, 352061327377598790, 403671262828650487, 158151377948777897, 553713350004834331, 417923400425827185, 316567146170698076, 12576508386705328, 357480477764326584, 29112903284401295, 107629048775537217, 525393354158079036, 214537399568531046, 167658412364557630, 321648389321312353, 469366305788064601, 33407383718738610, 440262400626763643, 209672037072956107, 64908494015551581, 110567275144257239, 357216922555514710, 229667147816038358, 247282547492043835, 111719371911355255, 95253480903670755, 333186733358808993, 239393651253448537, 145417273422324014, 148362193019605513, 370833859151328863, 407002300064570532, 131087043323355832, 53849312492062398, 481830700823584990, 258536652743636015, 420397979939671260, 347665750812598169, 543696561907371157, 512334250516405603, 308164065166453277, 119012028433735704, 551883964943518273, 182935178261089087, 238841136170274915, 88333507146103821, 331758579405713647, 345685851194730117, 136454258722123543, 406097219592408783, 437318349362164895, 411505921450126339, 333343310848662971, 35994437704538912, 55865647364230075, 478339409437900214, 108077472941608600, 82714472134664508, 518432368345935435, 447765746559718468, 395443194116628701, 446622261967094684, 53684991760284855, 531998427286233184, 277279719584419176, 528098262174261941, 118358852234620113, 283543211158663639, 561165515612370208, 172594565512727479, 262686943116580648, 44055602050243476, 76350781930416594, 131179299042115405, 566519337177013965, 99266541098759746, 131325658890483070, 154975066658623313, 472783319139290132, 238731997419179272, 241460952476788274, 174504811499336743, 234550099979288246, 322204355955622110, 78934200094653384, 254498991004487279, 318178349068844855, 139159150976171248, 270732342221664832, 31904671983518729, 1100745834824478, 357462621593724734, 30593891889121841, 430506947873667140, 171304948801765569, 313155301989235709, 520489190168724055, 95377385270785471, 97680931624385533, 435475457795949562, 573747055445900046, 292756317642577656, 306583520152022872, 405880325977863201, 278751083849767849, 523204570955123616, 547636268381344087, 196942936787428169, 279923994922621153, 399554591066591782, 322120175749227817, 218068820571191915, 298598319400913252, 412281257441713547, 402157633807623434, 128308786147750049, 363702136535218999, 100779271334970249, 16619101977999813, 341889113861022873, 150595312585620805}, + }}, + Poly{[][]uint64{ + {25539180957916247, 134576910680253174, 475363799372172620, 28098986814455855, 274716161371720394, 312179856793930138, 164377263132000736, 142008666615288623, 182735566456326871, 10866356083886021, 208090517816132918, 52878905204697439, 91648973731241697, 574991989957693552, 500536710584824592, 358944371207232906, 523477132322162594, 548193187974410427, 235886312841325678, 150731728017218454, 281797201443117083, 563294233426118731, 289732758013117188, 570620768676577299, 398615831645796041, 97428788315228353, 102871409071546815, 532774000551509196, 360827243328873706, 535362656854269158, 535059407809998454, 241346422338253426, 24536225847950339, 187719898399036285, 208087398158017137, 549455574829620242, 228473756573465231, 125101592748151531, 485669259184335899, 314907593061345725, 261963958161490446, 525546180420182151, 22554511326833137, 376466522385895002, 369473114047926329, 303203901068497041, 574674676229664439, 527504934235112472, 168298047449962932, 6959731275881451, 301905062208822778, 35729762669654407, 20493061307934269, 131432970048788868, 520631529780789195, 301752544003086126, 516394549566453450, 161796946742173945, 363730488537718291, 10381192361222532, 257478649793918421, 460797117008135956, 239533633719433201, 393571089242275604, 3025580076213915, 564788969263356003, 52926550336486024, 385158042964444234, 558404729092018644, 273273984521467187, 336829236901536149, 136259161339784794, 165972191001738739, 471195471629941990, 186627813815902895, 456559165377063043, 166026756416732478, 188754579842951634, 507086289889700319, 240511770516592994, 572903766245421175, 220419217563396790, 79394335226244850, 177831146025370705, 543848533539555140, 434815340316821821, 518688466567666280, 391830584516654655, 30933794264219615, 161405910933666617, 113452875623048931, 313941012128973161, 340599144874841662, 111666143698454306, 231072651334712398, 155616342986526411, 385563544154691802, 244056537020624835, 487068683308690119, 36993212127766784, 502465771527461487, 142390985028631718, 126906895255600475, 261239512512479410, 21161876464410161, 187947661511159557, 233535577934386038, 312138394777933399, 110643166062619700, 145206386746299120, 553028679425068984, 140706971970880894, 407939191362266539, 37289166785375282, 508157176141245827, 551706527909310995, 186458252254574880, 128706071973384520, 182994710910888687, 411552050321037567, 547771777360445370, 404363457914024452, 70844599449300401, 217316763159908291, 513423675799578835, 79684810495498019, 486613676201445617, 41145886242735629, 244328374970552507, 555498041402474309, 193097096277950439, 193322820485223642, 278098841963886377, 446088133563104331, 150368262197327810, 57814225182172893, 398900050623878621, 182682427176814874, 92318944605526269, 492708910209069566, 420268440336995572, 145657280705904455, 343314692203719814, 307422559616350551, 44164989486021902, 214443534430470015, 296999464537290595, 43462846506271095, 216208877773345992, 563303440845370321, 348258372473146442, 397062819065434969, 153146538498376426, 254290911314356679, 132001547094349104, 364547972914370422, 19707992960332453, 140039763791528979, 556377762570493749, 402149051732693816, 140253667944514421, 337563373862946670, 374978005797593455, 189126997987002783, 417283864907300551, 136506305103680265, 175982684712968603, 547282725480307214, 216604131378799933, 301976393125085872, 221095440783864307, 433607819548180555, 447740292619155239, 403534477140159291, 405040738050507824, 3415154835862812, 143391176700890182, 286719766792058075, 53303431082522763, 31901773118684527, 232475810483024708, 384962764956909578, 47050371056891006, 494242028238355208, 199516451799148501, 286660269856407413, 144867723385532441, 305631527286204929, 564731806991992075, 123358856332573195, 307667212210298256, 293075170888354570, 174908206112234882, 129089751003290360, 474375508153621337, 183608558781373932, 444232557414546029, 263358914639985593, 271259612067651959, 324488002261909057, 525442980499421281, 342722666680451556, 461946597276054625, 271762493639233455, 290502006389591490, 313211662042179852, 12257852953623893, 18787810968673210, 125914252484836784, 189437221511680189, 400657183087768110, 311040266109793939, 228204108229580419, 149782056579785096, 162526192005070423, 398015975429587692, 253216106124630717, 329756581376514000, 225447746805029464, 156966782898480045, 486360406929135337, 198540927585903828, 445404412810388420, 232006240862884241, 447700714943003583, 224634965652784343, 410634304584122048, 512823303344584600, 130972449347622764, 431618391706465191, 400658951067291848, 389050390523422608, 26121738213936139, 497382085969742655, 77565734253027774, 493536528715434320, 244029356101575008, 197760024591534648, 169810260685743310, 413572371974577702, 44943371344227053, 342037367697811921, 574608314263527686, 491240089951929483, 74820066611494113, 205738823101341462, 211835392589657488, 185392954748001361, 491682849059049131, 282290383290792071, 238680569454837425, 489904800548920901, 439977546850826561, 162263651720776212, 232613675637076929, 9824498340588603}, + {145262921017258530, 509093843511663073, 69280768158594495, 476975569887795922, 200578418001088989, 511954582967998215, 81004975188137317, 434563516464118473, 3742487127533537, 148853904131153735, 74250494922324744, 342102325202151178, 216224407082221091, 293496062152831898, 136490810673202468, 339428511849083731, 104048513922313017, 475425927213645945, 488518960243328468, 492132661995355315, 568869884521887731, 525754896308909538, 308757899760222748, 543052554698889604, 127011667295243721, 143951070705256545, 333924117897825325, 468824765157795015, 536375648731223460, 500143443529480066, 378489507927363322, 279125852150864901, 281030498504685879, 168745392570902508, 539413237674932832, 250602279388059960, 200993615157345610, 92881688160082790, 475445572000753331, 426044792013466179, 336290989081788700, 475122233276581982, 571860618885320337, 100964993358312625, 372984491119389868, 344569715565410746, 60242051153217051, 88469947602760817, 371439217449124235, 82865000924762212, 533773493545592846, 283571462528268311, 8050888500210530, 548686786463874881, 500956635065080289, 206216378852994063, 216220061258450222, 18289119905402672, 520780087101851718, 458244492867167112, 477330924013911956, 27986645549973413, 398017447689976420, 72499293099358184, 15661124530407527, 436483150471732051, 105655592136018165, 250794382657150445, 502230204109251559, 15902090664674169, 24128985185766359, 576339228734293097, 380943101080030564, 317679187729245422, 291821169074489762, 263753517262679069, 500813118120459206, 5907313506942712, 568798513863161214, 568006665966008790, 463900981809306760, 569323025022789054, 531030207503205866, 548067340028132440, 216123285147297852, 95879880056442795, 228011300554486051, 5622793593072754, 162958380973089483, 144297612561770555, 503945874230219663, 510213895744613944, 427370607720726159, 485146245914886276, 512916632692748009, 125006578501399088, 291231141910373887, 34629924131612135, 172483273858493350, 191078353494166299, 337889874121201580, 39069074983148686, 43844758560188396, 274933702252441871, 212961990507164718, 31952093639076407, 38148544443399351, 81177593602577738, 573173862197834520, 147438384745255134, 522225120977990761, 128293858134848977, 179376240238201377, 229390590519503455, 448982237341985904, 428431412426973447, 444523050934342371, 161540441021111816, 344327418634019499, 538632796364184769, 286241785850763117, 540885238416105908, 199039391238087947, 398173855569002898, 443657369837614220, 521436485927088249, 350958660678604668, 531550026478083390, 292329282653892802, 249865445848442004, 334844977362494761, 253735217175168864, 136440994953492269, 347988625988330869, 78855725766197923, 6886427804107858, 50323489907205385, 58723685908139964, 363721068166739517, 115361456607105021, 430865188649593152, 306506558745397883, 16347848324091673, 554960316053659212, 545770074143278266, 33128127278684866, 105772739927473782, 48870139210473549, 58794748087836674, 474712978371384419, 19565336952072949, 545102013246715960, 284794162160562258, 534046768243604871, 515139885978567640, 75943870618151495, 284478323301965809, 211393418778887787, 489917114612131538, 188837273741590513, 543734395403836874, 296728025656446498, 255513679081425658, 140034757922212665, 125105027344710076, 376805120950157646, 487762543330067162, 73771023075742516, 263612713835667176, 70916292187027797, 521041078726186979, 63072561940441183, 391041648541819815, 561191955917166645, 484383301426882619, 524939240614839600, 467905925305918463, 106615952246108837, 283645178526878518, 28844359403488479, 147243109816115707, 135557950651844021, 114531164825658671, 328546338419561676, 343928718523665033, 265711254649598556, 70610661045066165, 427057141155416534, 276055042511001360, 231708851502383818, 295639172412693425, 287750111926231800, 406212266070789998, 36740714235231076, 474250293682940522, 435581687227388193, 196309786272732675, 507185714491123044, 87854256637724473, 520719983214989992, 309761945023637181, 512005901530248566, 49779398819269784, 382269384917273187, 168582591020161001, 545252104333691897, 496452821607793877, 416516492420337001, 340944168282202371, 408719995683740029, 456885247723827471, 338637400820834302, 451239483358210867, 56871254144936084, 561207652586726183, 8053350254065332, 334280587965584003, 327702914397759466, 87572048046481558, 490378938312633310, 495270055649375258, 33600534065660095, 331477468756018874, 144608221167985876, 284139694548925586, 314889468034604849, 416733161198210068, 159979018438447742, 239314906816503442, 141394866156749784, 8215297667275886, 144926935976350507, 475011371483347491, 530765618252712380, 17739432276654581, 228304617638032389, 75037080049003521, 528668068991034981, 144850219018031660, 237897487839865383, 216386763675580863, 46440500047230549, 287813643373639666, 400047078833455375, 387196340896419108, 306127222070311235, 134096648470839873, 450899972818645458, 116213931387898665, 283965153430444480, 131430617068404218, 390867652280397264, 58206120712600131, 5314128460251204, 417802652644041302, 464476082998386550}, + }}, }, { 512, []uint64{576460752303439873, 576460752303702017}, - []uint64{ - 557490301533673314, 272478040807030062, 323997898229412233, 230154686261526555, 386977147040001350, 129208283483059419, 509444220797007972, 407362574928022172, 547237840149679784, 110246410215449860, 479791418542096835, 345136546013704730, 30948025931372932, 184976084223695185, 210035512773314536, 2060203918566681, 190951841167672185, 259105295360391414, 432607309802851146, 105866100419664308, 164325190978681854, 85696381731465753, 313248832641540830, 349224647130544164, 42925700639673923, 554542639781785039, 467144640641245603, 84665300143106027, 274519666153261180, 286110725016354362, 105452798776685172, 408773017665700185, 125093517815287021, 456218668181429898, 530001249817903723, 444940428344167147, 515132895095424745, 113454702344812066, 272749922312694697, 127632903554820035, 355920821224850979, 88278798644375593, 73241803572121116, 490636053092508905, 202142676309429003, 192612630651819395, 441621934345569786, 89320338944623106, 495282226325265316, 566456069998293614, 29209121084775686, 373454291237516895, 515134296804225746, 239054781024002827, 14264766525248124, 246959731868608773, 477569547364374928, 402135790236845561, 193955667578413978, 126093680728516382, 405951233091436359, 123408314527996567, 287608755040663542, 32048005521408586, 306540328128153793, 520159789821553968, 320538362718105467, 252639628411067701, 227554637589356022, 21966406476007377, 395496858581335183, 229278298861945672, 538964119893039344, 507610559646855807, 250873447067240140, 117854879511155947, 518603883095562023, 132870310810721700, 450893847047509578, 207008435967994841, 88302253226639716, 263979541243908654, 464376952346154731, 408910730638527961, 314030233133260627, 138561002445096168, 399208815294633991, 179687509205964187, 185454476398230266, 121917703774013198, 393079087806009463, 315070740156456288, 43020004098805282, 501738724327505802, 467928035726350128, 304088124250758671, 28360018864815121, 53023705220803868, 480653659313589472, 418194265332946013, 200221383950134460, 106676267279571316, 539554359984177353, 418672909564498228, 392935868235717610, 463435621976039736, 511300830340285001, 54614335123535575, 386713344259457976, 166990712726550704, 391151205863018379, 469544985938154767, 120632688673649109, 538182046295602848, 507783099649644282, 177490194097584186, 330618660963401476, 500291381914109856, 213718662444323177, 378343336683863422, 355846172201890208, 129974819025571124, 488275135531633464, 131436443024091118, 442897401941641220, 85043659894223283, 17859876289692985, 16910321515814294, 505591406495770322, 476728917802930298, 64842907706028320, 382174918426363547, 257241311398409500, 205634350976037139, 299670370699372047, 330550218633483751, 380536414331365285, 466540664700213398, 498820832297045308, 333346516899595761, 239137362793073364, 331926896252527353, 139314324446406052, 108489243794381161, 406954431407536165, 29769084589897683, 460493541804212623, 532262093358196019, 454132812354860034, 165023661813826956, 457138100111878088, 360070876925458795, 137483632701512705, 342770037561208847, 65595351898115841, 313191903472244953, 5202820788420803, 92959819062693258, 104874211835290168, 84682185578538203, 94058011920589810, 311057655110824363, 363911364257080440, 87824521034598346, 479246910605994262, 478746594118424704, 65901315298037859, 452311430496766296, 264584825377462406, 338870497690366950, 415851993763659751, 233046350270462312, 393155644304656043, 129046993171028137, 20754222432173464, 381835443209246519, 551725269163620425, 218875050611569112, 408228426801740813, 170395923335134339, 298180793604863806, 535386472133725969, 14438469291243631, 350576518772666013, 228663232754751915, 330650997531810770, 537450908457437211, 536617562153988366, 185561771699015603, 176350803001925822, 248726635741542942, 487946971239518439, 336969549628280907, 196816170611906923, 58765622940726096, 481934318794686310, 410987215409265027, 89516446002399938, 505042520330034710, 553979696392897725, 179482843130847003, 277987133116179490, 145184276182453483, 556961316905068776, 532652828334104789, 136038514589291601, 182973879814072052, 99307564264006151, 44581672068777622, 470760588956064847, 314731147849952638, 427010029393374870, 126038946742772403, 266521425010320931, 110437270373293809, 337838123965530783, 3906092887452513, 316772530276479621, 271924864585105886, 501317112590507015, 303719111506326246, 205501743519376769, 338943617872317787, 473108411205569963, 439120290368755869, 230610948840879726, 548479902003212655, 275990704054647692, 80397783162401674, 327528041885275488, 575710734465893850, 515180838563507395, 512041870874525831, 512755121274048539, 564714707260415406, 124829112930786971, 214582322122084618, 78491922754264540, 13347808896737870, 565112504124605234, 470263824801395359, 163999667259731851, 176812012733881583, 537460589394692599, 62714993820691083, 396063166255092087, 231764675589118723, 186648941027258274, 494268071700547099, 239550410573797208, 244365421291153978, 574374367280497623, 431795344839867646, 493093603356531449, 382534243731220210, 373969630189549370, 385719119618149659, 171106308509929900, 348284360142112665, 512275354628478794, 382374668514040338, 410278172052391697, 23714496200284576, 282652139352063686, 254619268976414631, 312314232451608346, 123553089265651416, 348998600244700162, 119933450470073687, 100271791548752280, 401010824120657248, 392283709210157279, 129434484815792363, 333999420352410709, 370082491582060857, 399944845702126745, 64449757278997975, 61751998772146552, 424036028467531771, 257022064168656719, 90537259894073141, 187927513479060430, 249077653100457234, 466072399102762885, 509345847138804252, 374353845394153707, 164413195730216000, 96739694779095261, 114568078572269199, 310806858923191502, 34560694720455476, 194085791501122302, 326479358302817780, 200031254435511275, 142668333843800961, 130581912187492957, 515034385533124126, 535063831983446552, 511636834088306083, 379869090352621725, 570027437647085424, 342836511132921808, 275881893388602921, 561487798569356692, 419146480695748967, 296251059883086565, 332201952189511025, 18835904418364924, 390424770852573528, 291651481960837554, 262880828508134166, 411011078611104745, 270742319503665560, 500677356538815139, 192826694546727612, 398079700015920726, 245387725681672240, 519877629435750915, 178690594820975429, 364274434184073223, 413548665103265887, 472221567769224519, 134992665632896284, 18535625694833302, 363193253429588611, 36817716369641543, 424765004242837549, 107982309746682250, 144998328029516980, 264372002206282860, 408027095312580391, 211135592236772321, 350702658567932080, 341143761003316534, 298639365270346798, 89006569688803577, 10913633547366469, 64003065177068939, 289392002811926412, 439937234173762355, 545199151527025628, 27596127742648792, 557681387504425942, 237904068468940788, 408177474987022670, 152686545689770026, 268424345834165524, 368630733152584845, 6824210222658716, 441683072929161793, 262731420185399454, 63685156480719001, 535548885426696783, 220206006193494932, 527828995980834412, 545325502345470928, 377228292064768688, 51299151655853904, 343440034906444326, 404428973428996350, 340610652115112721, 567035695547567725, 329897725860595513, 337213329398604721, 478784477516105630, 461183761895050618, 526167603667774479, 35307339483360609, 405918398958970301, 38123785103191064, 328796998540364737, 388695752174166040, 502465655595727560, 264168102357550318, 85603246549657005, 570353855602988721, 195156537426903551, 210578743342658741, 427673717873786118, 553931009520642418, 212868829289276227, 11778125781293102, 29830651091499043, 68279583077741525, 420569822771301557, 423320539252007241, 538572202211846253, 458976548403426870, 219382466380000437, 366418798167431134, 220678153545816272, 197144587448617412, 75815380228699482, 193570454768792760, 423105178775692874, 454914779008836635, 465322681575742285, 463361115366276709, 360765297196882385, 494105783968485680, 107129428358053557, 167705476112617649, 412155408791229633, 179287037162043096, 561010571208365485, 509799060530116724, 437901051745181649, 85886789145098014, 252246193500558429, 104601532032985439, 361852655391687317, 339066103921902354, 562166973828815823, 309483099730090044, 374493391249987429, 46575349050609970, 574121013990814559, 326280550431455197, 529864982718223616, 389934276421783575, 43026966029925368, 489513960430003424, 75044280502644924, 563269024397435798, 56967255377194262, 224832049109504236, 356153252419992068, 534444072162816175, 246093136843912730, 527127962116361951, 567258716466839714, 84165083495059927, 472010005735578693, 177786519363028258, 268144865942374814, 91080525608873259, 497821242832774854, 53586109523845220, 541783871810233475, 65097051729174442, 522717037697262950, 523489565287868411, 345323097550914067, 54451128105760354, 171783641667664079, 225814261291471563, 393202377294779970, 555127985748594447, 348442480603014834, 73446039423441958, 407437882039197808, 548812886959167082, 335136827017993462, 259188929429524898, 210729709454198462, 292957350008923355, 115226682251610826, 231300849417504181, 19709965359087106, 286510684106938120, 261444858784051954, 174901577994600338, 237735867646994252, 438771401308209408, 205351596795139716, 323369995002206829, 107335359237333694, 523216206272226598, 342942979739660651, 204579435250699248, 173622751862918724, 422994803444508944, 484318784546013367, 449297561662973553, 410298649571875309, 569109442986747183, 150105585215894724, 209333007830769491, 160325549046195505, 231061179002820065, 333499977504885987, 238960296991525701, 255758428314726375, 567175430135930613, 270539368460931133, 21305066364331955, 238704567898027100, 154981457140430110, 290443355379837545, 562280269050082217, 74659335006449948, 301117613125547674, 406053261224231703, 27389407060473636, 422837480652381442, 387921086858023551, 127870194186381496, 523477664249474916, 155641166416451218, 66528142831595651, 361705446113071036, 242943917801105210, 110381981864240143, 207990415732493793, 21173476739250143, 141764412413134260, 323053786668388274, 524136176791736535, 290124985312462639, 483037088868718877, 256240426064989372, 54241758443961650, - 246188165153484219, 534450067081683844, 221265595354776979, 187788234786691363, 535261953617571266, 187857889357125741, 390440897099563531, 183259487083480990, 70783572632473589, 132901784228154782, 485470090877835666, 240448779070091616, 8176820885266246, 9306174492034177, 125339640889596387, 562343387776097804, 451012734388049371, 443594138732154811, 557523547279969033, 467955252661475051, 31223376248844295, 251637956474462020, 165932997334734943, 524650596060987818, 340222271309927071, 219458112189275389, 178449563223067865, 157123420409416518, 510219040580259455, 32763691659457373, 337827451787623098, 113982740474733937, 470410913874122646, 544527787957620948, 481721720337221119, 134791267384796603, 562700371406972809, 554794744715811585, 41765064767273925, 384787058554833142, 104280441602389995, 379307998395969752, 379593309935323348, 394777199066490236, 566317865562943323, 46452186807396972, 325652912871346886, 71866863164505638, 346632477893784809, 137918085894968101, 258421710140155464, 394369107212563484, 569306699190246449, 201141440210259501, 41841443225157724, 377083340321286879, 18031261589877959, 9065365756915148, 247019429524567302, 117444276115424448, 213013994315091295, 142581569898143237, 506025371400928120, 379762118723920956, 487773487285642014, 101612821854926930, 495776466870675661, 199701418511082461, 258157216374087591, 143480651835309364, 84624326044523707, 545754604092170212, 52300789125811461, 357832810069463276, 8226616433362476, 454673384095273066, 117648425882692416, 335446052646648702, 20312654627941864, 369518234418585130, 219898596792234362, 351824354568426579, 560958561344534824, 553151349162931075, 515373691597243605, 143790750419382242, 533842856043902158, 390025721831345909, 362257547225920580, 542616117895277939, 3079721966050867, 91423210591649073, 460571869802892769, 438343455514056058, 148553538764571643, 536826577197499276, 463227158876379276, 536407995183575386, 418178879917486348, 106059765751120663, 428036358951905464, 476179460320944404, 245590614676291577, 272481674618128394, 142403271813746080, 417972524986125317, 135634414127465679, 299570287434350478, 61581565854279737, 525808499195877706, 50152564669772961, 197367984186557142, 383573942255760506, 229497718222976552, 485790108904456757, 572271473459931656, 219048871899726181, 332218191213051501, 543696021402309458, 339968420149097065, 332758684427245556, 258370264938560581, 418938439087235173, 6997646041831998, 36775833499513789, 518946558233534712, 365657177055233816, 354061744301918219, 309017142671106093, 77424875566701960, 15213719853959433, 539973712751591986, 89873822980141071, 66077199383566874, 123471992917740784, 407257819786774038, 135733358061427654, 554742995533961652, 229794411764252617, 404921464922796101, 122756616844815736, 378531789801666225, 124353583630641178, 262337827207719416, 131923127310886162, 154340263237342569, 158238462398564504, 509478254963129658, 509967683146773656, 48448090343399283, 372794379691531939, 482347583779456487, 84122423349614029, 525616402035363929, 301486985640164074, 482697977541532707, 59855756010300350, 197796518959569099, 203165069857990911, 422381866887337274, 542937204603822824, 326084777793391341, 56059000603930373, 366490682688959827, 434921820155010339, 222428035032500210, 358859519440716167, 436978321742269410, 350492674399239025, 445390083103537928, 74990249024767204, 38071884943329561, 323659576239733460, 428980880905509258, 472986143344934863, 165498401232087786, 479069503817053063, 527393000400392988, 264983920232727612, 356718000838347131, 337750240406123120, 279406292443421674, 26898159184521542, 149184643377473056, 219082075391734340, 1763942611822333, 244192342364977402, 555710924281816897, 378873237962841914, 151130945277547679, 292554654675538389, 312576271474121067, 460455023866882105, 218691566968289823, 189845748983684276, 151698934452993769, 32818590660130705, 151314174702533178, 126737059896961172, 282392717439214939, 456895273092211255, 91772905648712384, 492313771958046597, 92074579902895062, 509399499113472707, 25971450109409498, 548547376505564930, 113468823911186871, 555597776397739689, 77538025167142161, 286941362502408868, 38673034272568715, 388238044100597538, 158086311837932173, 524663714768807995, 298621670256059434, 550655129894597900, 519184587317053596, 40595474409525176, 563548195829520550, 423546767928077397, 400245826871686174, 440251716808193651, 266863486461521769, 372007100047582295, 126788035615217119, 489689604413370927, 526902884580660674, 358488996108700491, 418502478874188972, 559498896750753614, 227954444895003890, 12160941460295567, 292848691440054555, 194704308018107809, 288120918425609456, 139181069492663527, 329976563631716203, 223668534634686891, 207262617966532326, 515030478173408190, 153426926443547064, 231593633619503418, 251537327775072472, 107282475611565527, 56561224883884965, 84297825030590418, 213036767709411467, 425783459528607800, 548262843888561036, 253013952989625426, 10238343656680653, 231856993074233434, 13092391257221657, 257425332087036844, 37076907481128612, 32475936008232323, 479054494814575764, 316365688466594058, 24901959355078511, 54925715124012347, 136609697697661647, 48992648532971041, 9652759378611463, 18944529925464988, 260300905662223692, 370716970492691685, 161032895531304854, 19602195926932583, 286241432389915003, 122333097676740353, 256243606074076912, 298469600501451514, 323392287137490133, 96942352029609537, 387297348178795814, 398480880187994045, 114714485818264699, 147418601589336420, 417213615800724863, 96484181343850675, 288238316979762203, 112215919781942041, 396117760323981802, 270878743100013250, 409662365010208362, 139644154014355102, 420597110756161322, 22889839893842827, 395721232609319151, 446753186230801888, 405787617377267839, 40770721303800011, 270303046441735313, 299834832307203482, 62219342863251647, 376319417745761158, 528177751203621995, 483825695946052012, 52129684794122396, 272186479267396815, 63326085267172994, 261208035326022888, 507860115132856994, 21543818926738969, 351601187080751326, 57563237050262813, 291536075345480129, 318558289865506436, 283622290900394122, 524281774245582319, 54495864754944005, 441353588048325507, 51154130117118354, 269160374572749191, 430570837856716024, 395291161200686351, 450851559796130848, 185892481422631415, 250633073742359209, 434780828708376245, 82563444887001267, 468763271566444092, 24498342842671292, 350999946451127531, 425441199077717278, 50478451217305137, 531470863815951593, 34561582991037415, 42585931440795084, 93967745485010227, 243731147702796952, 109342519037488467, 547850797674285456, 338061344889600727, 201976092714469369, 450258778930056784, 517798596958895191, 93103775192094033, 132471403845873966, 307953682018444138, 305946566700496201, 569579584238641857, 67406080562303566, 85770788601215361, 59568039767837680, 192122218786247088, 447777648099499514, 200083585306408461, 117085096703943995, 2784049277375653, 389837891365782357, 186539321131116762, 298641885293870802, 112000239209080747, 13412766141677789, 115834153665423136, 491813883876906717, 98594957295411001, 363369342414649785, 571831655883330771, 181326406513983348, 345138182555201348, 286882228957060337, 310165587109628228, 263116001914311004, 356529860341297043, 14418974761944020, 72559347011675087, 41702549006423207, 144154270204150471, 280442177110788977, 8624692368844465, 151612115785195588, 266795024990051282, 465494994399268376, 291962393562581608, 108028957772583295, 126113865702699988, 392217230899066018, 285709203818173889, 55400201367394067, 507855477171070252, 126884095204631701, 335722111414726002, 169765846065177320, 506522245808499300, 88565574204888991, 157552857688739131, 307595891846239503, 143127040775708028, 257888373869997801, 520545588557800967, 102144138705513358, 546097870553386894, 533978563211226950, 70915534931938272, 152648441140369354, 387362156827657663, 515457442706086245, 159174561776062179, 52481761497406720, 419219358117792205, 317001788365054907, 138343407612123691, 110771755904445691, 304557344775094466, 462959116433055898, 457665429464670795, 442543699203961651, 163692605712390294, 107196060992848458, 369172039399526760, 323548403867607287, 224657891255460898, 59332779744718163, 251667944551154863, 192320775257387930, 543818721737008123, 268893827800722561, 120556021072780148, 253568625251225834, 467122806135914243, 333481850561504409, 164170638301562282, 522657254349760476, 109563919332590491, 266804944594522192, 112387876009041456, 483249262595555251, 202803248406333417, 365647787237677578, 260741252292428437, 20564027982572248, 49387728131302536, 500034042130061970, 536893877713278048, 345511689890878543, 132637523927712126, 1668343926292550, 442491308620880640, 360876639801645358, 536398088736617164, 297872620295684534, 173165554681983217, 541513725083900254, 242224459111958021, 326354460369042841, 352608694211600117, 183505490305744945, 90192927844654688, 101132228355387823, 481226433212736257, 394169671607721980, 226298947009678454, 372617684458127264, 407730877182750198, 163761896190785638, 233808110040798733, 319367247913848560, 278177743729794516, 423614826121352536, 198464273764422058, 164526334303846259, 406853854276881396, 27912324655559939, 121736015367615016, 330928583003062417, 497286456358516482, 475750895464243201, 267457366550016498, 518671023441108910, 430440109603497141, 554029895879525626, 503529199965985162, 2836827418089596, 390830871228931294, 431723540972230372, 391170724443953250, 568961403158755292, 151734730152085424, 338622268631974604, 513410280210859109, 209596246278511712, 142758210698488700, 133106616625698155, 214054105512050048, 345579594765991826, 489526945830964194, 218048789522669490, 416435540735106317, 377440890698733043, 365853354964274590, 30929477460363406, 269007974291645412, 229826057878159803, 32936846715162921, 499763038608550443, 513634354694875352, 474285134620011521, 381663948870105288, 332642970077996614, 315806015209148619, 363040890258784913, 321863527604990348, 450190749366924520, 198001086250604402, 468856832587879244, 124474780330969371, 534501401385761300, 454609717012138064, 395647746004002526, - }, - []uint64{ - 377375692533819303, 96042522392580111, 317259146287346598, 137376012927733965, 415306747163540233, 490340161363226367, 330039373022726997, 571264302149327910, 219591562616992998, 407619565441801898, 151835231682797397, 566724849297668643, 571154469443007093, 227143861461416474, 415458473569889282, 527044257594250146, 106857222947543974, 346212426139721965, 197311223402831746, 529909318782600257, 35502198459059883, 520485532054272255, 402583824618296978, 136415002723606950, 118925770221146499, 183778487611340114, 256476739326187154, 248592444542778855, 317660816802406744, 324547652341405511, 292103982801274532, 569055293206978072, 331182913106524398, 413926721549106828, 406040093115701575, 43718761677164005, 129637747026068274, 544779479045891379, 166875330355015660, 26193651401132289, 352411088260385752, 25850192591010376, 472008152703844413, 297707829831692966, 341196969590035030, 377971427470149957, 510885285207508844, 193276049333997722, 575329523161531747, 373942099935654974, 551843812232517737, 94966847377267862, 83210354813273121, 378226227004730657, 322261505106315523, 297227006720040634, 463720039062939364, 367510714252085101, 88296839925613166, 426572588616151002, 69758444506219779, 149084691654525794, 391307001444157388, 567981892705475381, 425657609162379296, 41297695518763032, 93957975936343269, 205585588905426666, 177955168587827776, 79731536843757707, 181109216097857240, 474917996295529371, 484381429795358116, 493774180643443184, 222988563987548527, 213132578778947974, 119056050508184574, 232319155245528944, 530871646935835365, 104701037680690567, 571484428048864986, 1730992313718990, 392359800509627985, 180523168032403659, 161736918677753845, 550119453550263000, 364842161801778834, 517184337578385175, 379254023664605743, 552540428025664556, 288513194422872036, 168939224642320394, 399559127568629459, 161566020197680026, 114724856380958907, 19948435630928626, 473078817169058144, 302230993073258797, 559605480634735199, 344717364998230163, 427597155231897012, 126031441411296200, 181379889996913823, 219807385508268476, 19703327242245679, 539493784334724861, 555971281185750789, 147888867710390202, 571955485529041423, 334994706930636693, 73997199783742341, 160820669974940472, 266517658615143599, 331171762319250887, 294590729340228854, 36144117312231740, 31027462670221098, 475371688494719880, 135561753340776531, 423424809082370971, 350881865115568331, 148460956121817560, 304320959085283379, 483979563792033399, 189606449925027523, 542703343218898644, 21231604361649939, 126793588122798523, 255993249795046940, 25734222634623828, 111134567854459477, 141494977869068633, 475039589956777863, 550008844388777734, 219852951234184864, 188561162205663830, 13783865035690631, 14618119150858126, 565282114902876621, 514251490606919060, 216100636335880360, 393082303210225254, 267939581203198332, 77189745237824983, 42791179039368499, 3418584569932510, 169097121666213405, 513124220201262416, 430679593552627295, 423769329801309384, 108288466131214288, 260119361328891541, 294843234368118211, 347542539107972780, 104019847517396285, 404045520204175395, 484995695374574126, 259926588400743394, 60441900619125279, 501785989550591000, 196717414042250004, 283815300911332482, 306878575339671368, 201655570468075275, 21396503689493069, 551592680977066007, 48668533071578272, 34120024171107429, 17276314832219699, 11988355912840846, 348032877954281307, 233774210217173740, 274715600678249388, 407541059579021034, 326759238244731645, 260623610528652121, 156860663706260594, 452852046439264424, 116882794278540727, 429699372520750224, 464536705646748347, 315779670376437621, 302671044846383348, 199265959353230943, 470411062945950797, 22720414864624877, 537303905943378753, 259729396669010127, 448372106760398434, 545856703638493908, 297094985726245160, 510904393622146939, 553145298418297775, 35135868625156453, 490205475864349002, 524062149889824872, 320420910265923914, 327405535484890100, 318048349307047936, 410136284159911460, 296932531679305793, 361488657718526982, 126959259010752741, 53000267853100727, 74461958970920907, 243863182774128675, 122651803020546048, 187266749183026665, 174923025608680122, 318688649308795777, 309806501105889478, 81120994685221135, 83792974580420991, 526212368243039732, 434894680461252442, 431606768347172729, 224359771825741857, 246326778987784288, 83830939687362839, 265740120931394107, 326764911782522600, 486426542385087791, 251252724294525956, 87483704852449070, 46011843047667307, 174626587648137554, 424593668369166641, 41637957064450046, 193246137518342653, 432317515170361644, 245394074460521474, 418138840203732141, 455148389610593677, 492768772251109507, 497280239114315619, 34869598267190021, 296528750997490074, 175053309374893977, 415489357231674552, 181256877434378360, 425311891003143535, 112982403137046010, 375654969155071147, 363025383733187902, 135689801617196180, 68288703430133187, 379146883450004429, 142524821685472881, 112454925863771235, 320014801392235936, 384022922988066790, 251268075163460042, 420909870442277698, 537883121188626484, 21251996073869450, 524967339846403450, 154160978899257400, 499354661990354626, 154057090474654749, 102426081601932301, 178611395127321957, 333508042858991170, 301113001243279803, 170063007128992320, 352001455766320924, 427015845720512154, 422242883802457810, 574071350103865137, 272534824502343329, 200600582804524520, 518689680910833597, 56359342117135943, 322028190286255294, 410056867805089172, 248106680039449966, 559915503968675171, 325851616287589140, 530964321418311690, 72331831075558471, 200865554085219723, 244592115211132375, 183144772604455438, 498607624543832294, 576047094637903750, 76989223152036907, 405631706687511644, 441416474377456099, 153715792917927452, 465981950773737892, 417563329400329859, 297634223667077905, 248430573333647398, 269508814689795398, 434085648420826250, 352629382482611845, 135243176962337111, 11112634420223179, 227133431824127922, 551540163357690675, 322773751785254480, 91859181211416070, 408520996944382256, 461737515054703471, 216649273011463814, 489756154748978966, 304686401959958957, 187093208165297732, 571064112869702272, 483030872037334823, 231208485611976792, 47353167468848188, 220859583967685215, 368791081133506503, 448311434611922228, 11553114033975114, 285880008370673919, 464533331939697806, 250937078568932514, 22493928003895211, 19886615847961270, 524275225434617801, 436418416215785332, 449039215994924755, 195953129418859475, 57551104007934524, 281725799643162096, 48735499166402590, 461699867859813907, 67148210475218788, 543905922728157026, 182226495938922595, 550796496214243613, 191471383351463406, 451757520819077733, 287973802393304697, 551239005008419983, 2088186958798437, 208912411390605397, 198028987282627803, 188736697036049709, 414811519513909375, 477017385587557210, 310757820335969146, 495677794841369251, 84966518519838157, 417413281419232843, 524191040376032585, 172165758595012516, 330270444072059584, 487290023472023529, 287067496070434968, 120245446498493384, 517029628092507616, 146812275273192818, 134523269250962957, 134677175537836959, 176136326962319788, 424799833197667132, 103818595323478580, 223851388626867373, 121439995771647755, 242807308105295658, 150405395853889224, 498412122969935086, 218278857810216868, 208104474970536122, 260221378297549002, 316654686934686699, 30929480163385957, 208198729328663099, 335053023971247599, 562148606183273036, 410536004642549589, 212714257373256468, 103538202285776947, 143832116309273417, 30456322549076849, 86714866437621545, 309564082328786292, 377785962901287154, 272386054544072171, 190311330266192750, 351573784737171748, 352959370189797177, 3827364096388907, 200619906395194508, 542995428548734667, 18702807860278304, 171833939003818968, 227296369242809839, 135726318195433881, 209069986924360244, 393872424531497807, 339663565357057843, 297913425595462606, 437981007656088948, 538602343970248756, 212235339944700832, 211912601341285304, 442783807090235330, 254508593209532514, 224990827065343439, 482109591999300260, 555039280584388850, 126458971256647369, 168556735687900444, 279575156479008612, 565396698992489037, 11549010806200261, 394373488025751232, 419322928436105602, 365294698803403081, 544507796167299908, 230576658402485295, 555433168120863625, 430841505029632093, 194878346529601409, 459971850624033240, 285724118500519407, 193182186076824526, 541111882843089541, 403623419211700395, 317292145774192827, 565745482569156010, 567183177595683829, 412324127964923027, 424070678779344286, 383893710539160088, 79909480744106553, 135317551424476694, 569471794627931742, 341951140321658033, 82328797821410773, 411565860857526708, 321355848454700982, 75126226501014249, 503199356762562838, 302690739615128091, 501265052014414658, 454007627578292409, 317976993312768297, 59895650370837554, 381408048391356716, 81640799388082245, 465634528132834186, 326958541719178539, 410161099408037658, 490579859412689260, 425838442418793789, 1508695588127817, 359963433317418045, 157378769386843229, 480523164440799516, 180144835228005127, 160825291421506582, 359604206030521250, 562833513585114035, 445058912984313512, 288103179412561502, 423443836992136052, 193385142337300526, 534649015391602536, 72577693672868286, 142685760351568760, 97821588438303471, 550478311787984617, 70818771851821037, 258233136873228764, 554088899431500047, 539186318918648282, 325425805459836993, 495914204486223505, 162172224173758922, 236866818298761456, 391080277784028464, 61712296624710490, 161793043170955012, 267423931457620087, 540671913197314373, 98341162388471968, 228286403833826200, 518375967652135127, 56085383489534938, 490055315590720729, 516073932216751232, 369040856736265168, 134780449470695769, 382918318936764072, 143140170583580740, 445408790369445811, 116598228935045038, 175900743630821911, 357223750468405311, 433323211587079812, 496033720069994061, 116960908284347135, 559411137225705475, 107317757053487615, 161704620752076908, 348335260566288056, 173832709061112133, 279480304155135690, 294668652196144909, 251994706183508869, 43004770424611718, 219390200322664008, 326837094723508074, 11038984010640734, 270257516382849480, 124610653289748517, 71200529678388458, 218694178225172333, - 466271146838164828, 345997737129306449, 396131031422226107, 116937133495041013, 470307369269241327, 372054853593177419, 461194759000203265, 95494996142674216, 296023655354651067, 388561538148330633, 136509946607324730, 97739337225681828, 250474766728238664, 199817794407702265, 179849674100089761, 147712868893473570, 384743230576170026, 323122056426363984, 279964353457368318, 138269675968568711, 127269820131034178, 386046661002048324, 156513367294373255, 378164427720748777, 66095750145279521, 223647012617699896, 296076782617087632, 292460357233706710, 174258923985980557, 46418703090745051, 201100662765574923, 34357221312246651, 105729294181785494, 531737109043801360, 23284441999400353, 560892495742057628, 214174623837839052, 270620859218969900, 114530421649658713, 148277655531181731, 107523630557556833, 381411727632323894, 517738773903320710, 64582714847065129, 56380818575545847, 394793300888262419, 491726049753852459, 431953147634931175, 12729890545215490, 407219403967799925, 494550336713636809, 510531964780906558, 145277482662646831, 120251342113548904, 366558554003566925, 569206546183799622, 17120674021865232, 545549761193429004, 474177731516146612, 504908903018918434, 180222850445718752, 165529884151818797, 433051388176544889, 317589215194447986, 367750654542128615, 350516710654757521, 536510283843822169, 122982904789732385, 555951782547180810, 154900121799960199, 554070850240132404, 192943220014834097, 182002032841832181, 474783212054666171, 560276189954185439, 65665372613331910, 44559631918261371, 62123835124561949, 397079860200017142, 375686386344671012, 325032138763584465, 521867309277341483, 208780799634964117, 103171876387775244, 238130877980292195, 57229872046420951, 430987964548734062, 217085238418230917, 504333912300381504, 425326127782881717, 219172947177223313, 327820696845371053, 414658397273406224, 148040631456141259, 486574959906123934, 121927334317712333, 157668935816710273, 404059031364737330, 165270792150604282, 498885177679994077, 144308111226178369, 176553054880913321, 14101972432915027, 432048471992214931, 126670844387119394, 369159614029378795, 205835200620335595, 11170576026552067, 545124795329650607, 111575454289328226, 440485700344570770, 378801759313392230, 15375506415674646, 558584858623022991, 485130247429239680, 101188836654026154, 264262908316435494, 544349473021042648, 397966082653351654, 210988680650958497, 70988190965937178, 145231291726678069, 238249293696427075, 62034706383252518, 54359013526972008, 424332775154368330, 408418378889307845, 452074936151327047, 85143952432131397, 97719075454291809, 109756567464440943, 215207311530598533, 360816487017851165, 176987217770935548, 88870881399916479, 396419418010155962, 56692460489005625, 201000384706966543, 160927502776586738, 458270030909164757, 395687385485434060, 204607869744071934, 480591906920653728, 229841137060657299, 22956853527789765, 252633384775033685, 14937813478318, 186252030574290570, 350977525255924426, 333284065572366438, 147879717739049820, 472875196275123170, 187179421358092876, 353007469735872106, 526894680292775206, 396174143623321801, 461400545081644867, 496611428475520665, 159274749531192068, 421297899723816458, 96251478272942596, 91188796138456557, 324761852083930624, 542042142024938958, 14179361708260415, 280563944918866135, 255054216368021586, 265422910470798600, 100350834747080409, 476968409202196098, 440153656756277578, 117652243087566517, 553270163748812057, 400885033423307111, 379938607704180061, 457358341089032818, 337837439998305490, 50741340844579070, 459800497249241704, 516274529016745669, 433412884898516172, 190369684621859261, 86239887933174233, 330949199735020874, 558170523373344908, 349209065426802518, 126386900794317269, 139762440266565498, 555796712934466764, 212516932974533684, 516072908479735953, 523150007430540858, 392872325201783914, 283772059382488947, 421374429984116561, 437313502940197471, 322354260197714379, 348085815297191726, 224263599432613588, 31348908904294929, 28616413379325209, 400081352308273621, 418408237629079966, 569077243235319562, 411412223506778698, 385173626138540426, 206520802580080304, 250114503258247730, 529190928290451569, 369219452017396617, 198707331022894256, 206910771415201462, 328349597469889601, 338643866244221429, 450666422080420972, 473567975236898027, 469575485918696903, 183053463197491334, 539640810084103270, 104081722471888903, 241885715480038404, 461880307967768440, 364035592642160360, 147584304614914707, 227297810490094860, 485343280770459207, 153134372305381865, 197435690034151445, 557369686477903272, 397029989611140044, 422284336765314899, 149019753920050359, 260940908146300638, 155092035839799334, 552933182353675536, 183350458647647372, 92806092482483431, 535606885305465070, 286505492809367415, 570069566423372568, 390218330990052622, 467129265621217161, 96956837922110035, 392691768404553185, 349155711592619894, 35214581029746228, 324692261733801539, 270562204886079604, 479519574820212928, 247141196922117346, 6501617166335209, 67031103314214317, 573347971184853932, 5107358710419612, 284010223254113821, 442748896127333283, 281952435677906572, 469641501151084272, 115784128671418848, 469548629381070445, 574555565277555716, 423260478587457471, 384871183849668027, 187098140840923540, 288989864589933865, 342999273978988809, 325733446046738638, 174129640994603724, 261892251668720415, 523036120235525932, 146110573010641454, 497012569068900968, 344234410572230000, 73351393642599373, 64494858336553019, 166940977537337324, 284811071734085598, 364307780745943132, 108942309296533881, 487925645090242720, 144304832233090110, 317152048823243323, 196840401584140857, 79253535328194197, 111754856371159418, 121351044799192409, 196453861485940759, 121813174194232409, 342453081976621890, 11434051624784284, 167697860686816093, 233528705256860827, 465068771923204650, 508688747066213295, 246541519401282567, 266272367112714005, 141293236272439653, 409300570584623214, 569686175558317371, 111662920525006666, 223978446146668561, 218209100648039207, 187382725057537322, 47610767262038889, 96602599284086181, 540632473712363131, 420569058611113125, 43192704522208469, 194125334293975903, 77905386944703817, 97895461773513108, 481799180084097557, 353221013904420600, 14714254363761205, 5872589680407296, 300960681599396269, 170216946604815755, 341186713112889462, 71216939394905485, 491972105932592514, 229419515485398596, 126976249808813518, 179412006695471785, 57403131563047446, 148832052726389176, 124204975353010264, 24130594458303779, 301044196622036976, 108480807311394813, 387398695760878003, 470793459909824624, 274565242175326363, 215549376988427975, 493529759866923382, 414158644512585082, 448232921329203322, 279397864287379368, 385921328000591571, 510803162528851695, 555250923277537883, 556365641961705086, 561981551241207103, 200151213531697127, 326020176181735345, 348927170412172200, 426080585300993963, 489229518822211887, 463182136949111471, 257180473660938448, 417636541678466864, 567212374615025817, 118656760864016921, 182350302216369058, 510953747581147011, 476243800549349531, 472784868841691998, 1859629731208576, 545876001998533822, 126839511235733174, 491710720960582551, 905807527389075, 455345462594802075, 541991300664323245, 170944695324732089, 319137172939860059, 441207306778395303, 235893604708258320, 187756510098277534, 548789333110747016, 473083391264904964, 281610682150903753, 362202931681116777, 552363674076296763, 362516495075315452, 477495854878598355, 83227382076754502, 288715706663209883, 17149401505382573, 142188092975845092, 145511149175846974, 487263249631970725, 379579040691835762, 444361856595697538, 251901411776729981, 519421968809331630, 564594051088515530, 214831332322826267, 477489365776262086, 503404569497105678, 525950699404797475, 211663800152941048, 544504415437890273, 82703882773163155, 215883002493891024, 228206415465367662, 262405671296729818, 552919762067589595, 275282707229127204, 506862872415810722, 223051532741182696, 248520929795284496, 251374539617081468, 459496143812729680, 544259681167706164, 513455149821051369, 153338889223626777, 552553512392463917, 345532237443658967, 276613035962259959, 76052831423776229, 27638414740821390, 468766331039522867, 462504914336801108, 504260205236931059, 153260787175953363, 249603626061351444, 462048919949765548, 325825983710082099, 349570698183439144, 467814558281048838, 319075842483329949, 494782675075346860, 136779850697638520, 550189000585042743, 158778420396589586, 553341782111330506, 108400733792223445, 399256538215209069, 373094641019970380, 243138034856802011, 284711146084351060, 278491248589657095, 405803616347773860, 144010079623340352, 242564151102210173, 304325658359166453, 24224471624104594, 312013094909905962, 102950534848587037, 156646216976992137, 554868615338424708, 356065313504408037, 566554900875042237, 95142308262512631, 330327806567307709, 369314998024605662, 153925071799269127, 56849208511968834, 97675248685366110, 492807069950337980, 505011383316691507, 107137368831333805, 95244666943819810, 558236562180487130, 381134552288649201, 279126085896895435, 226859758644230092, 332926241878417490, 59053186182861837, 153807718980788405, 306658731457151854, 257745138960216484, 472599985235421104, 544827907149369897, 251310520271446155, 358012352843338841, 438215357442019565, 483543526837670693, 158580553055555394, 352654285881331198, 388025798341012870, 338586088212445186, 155117276797284440, 378829719982032, 216312860078349289, 183297139494101146, 356588527437434108, 490284293282429686, 213259456861909560, 359979054012642350, 59403241158934888, 88584374442351305, 149035080700868987, 561415063327994800, 197705271185242657, 153600123134508289, 341557397762112196, 563343428623464997, 421138288411921131, 37404886685863830, 399174946308648257, 226458419633193851, 63022668308744462, 365156258184484613, 494367543361132635, 556015298352559479, 509534126231315064, 341150199135062270, 291235481860477466, 331441313502873095, 108946546082309778, 302268753853175947, 293244050322880997, 174023385589118716, 358845414981291318, 503278587016997718, 65545998668302565, 130388228257893042, 216748567070515186, 456177830619431315, 95337524348576070, 371268046380703332, - }, + Poly{[][]uint64{ + {557490301533673314, 272478040807030062, 323997898229412233, 230154686261526555, 386977147040001350, 129208283483059419, 509444220797007972, 407362574928022172, 547237840149679784, 110246410215449860, 479791418542096835, 345136546013704730, 30948025931372932, 184976084223695185, 210035512773314536, 2060203918566681, 190951841167672185, 259105295360391414, 432607309802851146, 105866100419664308, 164325190978681854, 85696381731465753, 313248832641540830, 349224647130544164, 42925700639673923, 554542639781785039, 467144640641245603, 84665300143106027, 274519666153261180, 286110725016354362, 105452798776685172, 408773017665700185, 125093517815287021, 456218668181429898, 530001249817903723, 444940428344167147, 515132895095424745, 113454702344812066, 272749922312694697, 127632903554820035, 355920821224850979, 88278798644375593, 73241803572121116, 490636053092508905, 202142676309429003, 192612630651819395, 441621934345569786, 89320338944623106, 495282226325265316, 566456069998293614, 29209121084775686, 373454291237516895, 515134296804225746, 239054781024002827, 14264766525248124, 246959731868608773, 477569547364374928, 402135790236845561, 193955667578413978, 126093680728516382, 405951233091436359, 123408314527996567, 287608755040663542, 32048005521408586, 306540328128153793, 520159789821553968, 320538362718105467, 252639628411067701, 227554637589356022, 21966406476007377, 395496858581335183, 229278298861945672, 538964119893039344, 507610559646855807, 250873447067240140, 117854879511155947, 518603883095562023, 132870310810721700, 450893847047509578, 207008435967994841, 88302253226639716, 263979541243908654, 464376952346154731, 408910730638527961, 314030233133260627, 138561002445096168, 399208815294633991, 179687509205964187, 185454476398230266, 121917703774013198, 393079087806009463, 315070740156456288, 43020004098805282, 501738724327505802, 467928035726350128, 304088124250758671, 28360018864815121, 53023705220803868, 480653659313589472, 418194265332946013, 200221383950134460, 106676267279571316, 539554359984177353, 418672909564498228, 392935868235717610, 463435621976039736, 511300830340285001, 54614335123535575, 386713344259457976, 166990712726550704, 391151205863018379, 469544985938154767, 120632688673649109, 538182046295602848, 507783099649644282, 177490194097584186, 330618660963401476, 500291381914109856, 213718662444323177, 378343336683863422, 355846172201890208, 129974819025571124, 488275135531633464, 131436443024091118, 442897401941641220, 85043659894223283, 17859876289692985, 16910321515814294, 505591406495770322, 476728917802930298, 64842907706028320, 382174918426363547, 257241311398409500, 205634350976037139, 299670370699372047, 330550218633483751, 380536414331365285, 466540664700213398, 498820832297045308, 333346516899595761, 239137362793073364, 331926896252527353, 139314324446406052, 108489243794381161, 406954431407536165, 29769084589897683, 460493541804212623, 532262093358196019, 454132812354860034, 165023661813826956, 457138100111878088, 360070876925458795, 137483632701512705, 342770037561208847, 65595351898115841, 313191903472244953, 5202820788420803, 92959819062693258, 104874211835290168, 84682185578538203, 94058011920589810, 311057655110824363, 363911364257080440, 87824521034598346, 479246910605994262, 478746594118424704, 65901315298037859, 452311430496766296, 264584825377462406, 338870497690366950, 415851993763659751, 233046350270462312, 393155644304656043, 129046993171028137, 20754222432173464, 381835443209246519, 551725269163620425, 218875050611569112, 408228426801740813, 170395923335134339, 298180793604863806, 535386472133725969, 14438469291243631, 350576518772666013, 228663232754751915, 330650997531810770, 537450908457437211, 536617562153988366, 185561771699015603, 176350803001925822, 248726635741542942, 487946971239518439, 336969549628280907, 196816170611906923, 58765622940726096, 481934318794686310, 410987215409265027, 89516446002399938, 505042520330034710, 553979696392897725, 179482843130847003, 277987133116179490, 145184276182453483, 556961316905068776, 532652828334104789, 136038514589291601, 182973879814072052, 99307564264006151, 44581672068777622, 470760588956064847, 314731147849952638, 427010029393374870, 126038946742772403, 266521425010320931, 110437270373293809, 337838123965530783, 3906092887452513, 316772530276479621, 271924864585105886, 501317112590507015, 303719111506326246, 205501743519376769, 338943617872317787, 473108411205569963, 439120290368755869, 230610948840879726, 548479902003212655, 275990704054647692, 80397783162401674, 327528041885275488, 575710734465893850, 515180838563507395, 512041870874525831, 512755121274048539, 564714707260415406, 124829112930786971, 214582322122084618, 78491922754264540, 13347808896737870, 565112504124605234, 470263824801395359, 163999667259731851, 176812012733881583, 537460589394692599, 62714993820691083, 396063166255092087, 231764675589118723, 186648941027258274, 494268071700547099, 239550410573797208, 244365421291153978, 574374367280497623, 431795344839867646, 493093603356531449, 382534243731220210, 373969630189549370, 385719119618149659, 171106308509929900, 348284360142112665, 512275354628478794, 382374668514040338, 410278172052391697, 23714496200284576, 282652139352063686, 254619268976414631, 312314232451608346, 123553089265651416, 348998600244700162, 119933450470073687, 100271791548752280, 401010824120657248, 392283709210157279, 129434484815792363, 333999420352410709, 370082491582060857, 399944845702126745, 64449757278997975, 61751998772146552, 424036028467531771, 257022064168656719, 90537259894073141, 187927513479060430, 249077653100457234, 466072399102762885, 509345847138804252, 374353845394153707, 164413195730216000, 96739694779095261, 114568078572269199, 310806858923191502, 34560694720455476, 194085791501122302, 326479358302817780, 200031254435511275, 142668333843800961, 130581912187492957, 515034385533124126, 535063831983446552, 511636834088306083, 379869090352621725, 570027437647085424, 342836511132921808, 275881893388602921, 561487798569356692, 419146480695748967, 296251059883086565, 332201952189511025, 18835904418364924, 390424770852573528, 291651481960837554, 262880828508134166, 411011078611104745, 270742319503665560, 500677356538815139, 192826694546727612, 398079700015920726, 245387725681672240, 519877629435750915, 178690594820975429, 364274434184073223, 413548665103265887, 472221567769224519, 134992665632896284, 18535625694833302, 363193253429588611, 36817716369641543, 424765004242837549, 107982309746682250, 144998328029516980, 264372002206282860, 408027095312580391, 211135592236772321, 350702658567932080, 341143761003316534, 298639365270346798, 89006569688803577, 10913633547366469, 64003065177068939, 289392002811926412, 439937234173762355, 545199151527025628, 27596127742648792, 557681387504425942, 237904068468940788, 408177474987022670, 152686545689770026, 268424345834165524, 368630733152584845, 6824210222658716, 441683072929161793, 262731420185399454, 63685156480719001, 535548885426696783, 220206006193494932, 527828995980834412, 545325502345470928, 377228292064768688, 51299151655853904, 343440034906444326, 404428973428996350, 340610652115112721, 567035695547567725, 329897725860595513, 337213329398604721, 478784477516105630, 461183761895050618, 526167603667774479, 35307339483360609, 405918398958970301, 38123785103191064, 328796998540364737, 388695752174166040, 502465655595727560, 264168102357550318, 85603246549657005, 570353855602988721, 195156537426903551, 210578743342658741, 427673717873786118, 553931009520642418, 212868829289276227, 11778125781293102, 29830651091499043, 68279583077741525, 420569822771301557, 423320539252007241, 538572202211846253, 458976548403426870, 219382466380000437, 366418798167431134, 220678153545816272, 197144587448617412, 75815380228699482, 193570454768792760, 423105178775692874, 454914779008836635, 465322681575742285, 463361115366276709, 360765297196882385, 494105783968485680, 107129428358053557, 167705476112617649, 412155408791229633, 179287037162043096, 561010571208365485, 509799060530116724, 437901051745181649, 85886789145098014, 252246193500558429, 104601532032985439, 361852655391687317, 339066103921902354, 562166973828815823, 309483099730090044, 374493391249987429, 46575349050609970, 574121013990814559, 326280550431455197, 529864982718223616, 389934276421783575, 43026966029925368, 489513960430003424, 75044280502644924, 563269024397435798, 56967255377194262, 224832049109504236, 356153252419992068, 534444072162816175, 246093136843912730, 527127962116361951, 567258716466839714, 84165083495059927, 472010005735578693, 177786519363028258, 268144865942374814, 91080525608873259, 497821242832774854, 53586109523845220, 541783871810233475, 65097051729174442, 522717037697262950, 523489565287868411, 345323097550914067, 54451128105760354, 171783641667664079, 225814261291471563, 393202377294779970, 555127985748594447, 348442480603014834, 73446039423441958, 407437882039197808, 548812886959167082, 335136827017993462, 259188929429524898, 210729709454198462, 292957350008923355, 115226682251610826, 231300849417504181, 19709965359087106, 286510684106938120, 261444858784051954, 174901577994600338, 237735867646994252, 438771401308209408, 205351596795139716, 323369995002206829, 107335359237333694, 523216206272226598, 342942979739660651, 204579435250699248, 173622751862918724, 422994803444508944, 484318784546013367, 449297561662973553, 410298649571875309, 569109442986747183, 150105585215894724, 209333007830769491, 160325549046195505, 231061179002820065, 333499977504885987, 238960296991525701, 255758428314726375, 567175430135930613, 270539368460931133, 21305066364331955, 238704567898027100, 154981457140430110, 290443355379837545, 562280269050082217, 74659335006449948, 301117613125547674, 406053261224231703, 27389407060473636, 422837480652381442, 387921086858023551, 127870194186381496, 523477664249474916, 155641166416451218, 66528142831595651, 361705446113071036, 242943917801105210, 110381981864240143, 207990415732493793, 21173476739250143, 141764412413134260, 323053786668388274, 524136176791736535, 290124985312462639, 483037088868718877, 256240426064989372, 54241758443961650}, + {246188165153484219, 534450067081683844, 221265595354776979, 187788234786691363, 535261953617571266, 187857889357125741, 390440897099563531, 183259487083480990, 70783572632473589, 132901784228154782, 485470090877835666, 240448779070091616, 8176820885266246, 9306174492034177, 125339640889596387, 562343387776097804, 451012734388049371, 443594138732154811, 557523547279969033, 467955252661475051, 31223376248844295, 251637956474462020, 165932997334734943, 524650596060987818, 340222271309927071, 219458112189275389, 178449563223067865, 157123420409416518, 510219040580259455, 32763691659457373, 337827451787623098, 113982740474733937, 470410913874122646, 544527787957620948, 481721720337221119, 134791267384796603, 562700371406972809, 554794744715811585, 41765064767273925, 384787058554833142, 104280441602389995, 379307998395969752, 379593309935323348, 394777199066490236, 566317865562943323, 46452186807396972, 325652912871346886, 71866863164505638, 346632477893784809, 137918085894968101, 258421710140155464, 394369107212563484, 569306699190246449, 201141440210259501, 41841443225157724, 377083340321286879, 18031261589877959, 9065365756915148, 247019429524567302, 117444276115424448, 213013994315091295, 142581569898143237, 506025371400928120, 379762118723920956, 487773487285642014, 101612821854926930, 495776466870675661, 199701418511082461, 258157216374087591, 143480651835309364, 84624326044523707, 545754604092170212, 52300789125811461, 357832810069463276, 8226616433362476, 454673384095273066, 117648425882692416, 335446052646648702, 20312654627941864, 369518234418585130, 219898596792234362, 351824354568426579, 560958561344534824, 553151349162931075, 515373691597243605, 143790750419382242, 533842856043902158, 390025721831345909, 362257547225920580, 542616117895277939, 3079721966050867, 91423210591649073, 460571869802892769, 438343455514056058, 148553538764571643, 536826577197499276, 463227158876379276, 536407995183575386, 418178879917486348, 106059765751120663, 428036358951905464, 476179460320944404, 245590614676291577, 272481674618128394, 142403271813746080, 417972524986125317, 135634414127465679, 299570287434350478, 61581565854279737, 525808499195877706, 50152564669772961, 197367984186557142, 383573942255760506, 229497718222976552, 485790108904456757, 572271473459931656, 219048871899726181, 332218191213051501, 543696021402309458, 339968420149097065, 332758684427245556, 258370264938560581, 418938439087235173, 6997646041831998, 36775833499513789, 518946558233534712, 365657177055233816, 354061744301918219, 309017142671106093, 77424875566701960, 15213719853959433, 539973712751591986, 89873822980141071, 66077199383566874, 123471992917740784, 407257819786774038, 135733358061427654, 554742995533961652, 229794411764252617, 404921464922796101, 122756616844815736, 378531789801666225, 124353583630641178, 262337827207719416, 131923127310886162, 154340263237342569, 158238462398564504, 509478254963129658, 509967683146773656, 48448090343399283, 372794379691531939, 482347583779456487, 84122423349614029, 525616402035363929, 301486985640164074, 482697977541532707, 59855756010300350, 197796518959569099, 203165069857990911, 422381866887337274, 542937204603822824, 326084777793391341, 56059000603930373, 366490682688959827, 434921820155010339, 222428035032500210, 358859519440716167, 436978321742269410, 350492674399239025, 445390083103537928, 74990249024767204, 38071884943329561, 323659576239733460, 428980880905509258, 472986143344934863, 165498401232087786, 479069503817053063, 527393000400392988, 264983920232727612, 356718000838347131, 337750240406123120, 279406292443421674, 26898159184521542, 149184643377473056, 219082075391734340, 1763942611822333, 244192342364977402, 555710924281816897, 378873237962841914, 151130945277547679, 292554654675538389, 312576271474121067, 460455023866882105, 218691566968289823, 189845748983684276, 151698934452993769, 32818590660130705, 151314174702533178, 126737059896961172, 282392717439214939, 456895273092211255, 91772905648712384, 492313771958046597, 92074579902895062, 509399499113472707, 25971450109409498, 548547376505564930, 113468823911186871, 555597776397739689, 77538025167142161, 286941362502408868, 38673034272568715, 388238044100597538, 158086311837932173, 524663714768807995, 298621670256059434, 550655129894597900, 519184587317053596, 40595474409525176, 563548195829520550, 423546767928077397, 400245826871686174, 440251716808193651, 266863486461521769, 372007100047582295, 126788035615217119, 489689604413370927, 526902884580660674, 358488996108700491, 418502478874188972, 559498896750753614, 227954444895003890, 12160941460295567, 292848691440054555, 194704308018107809, 288120918425609456, 139181069492663527, 329976563631716203, 223668534634686891, 207262617966532326, 515030478173408190, 153426926443547064, 231593633619503418, 251537327775072472, 107282475611565527, 56561224883884965, 84297825030590418, 213036767709411467, 425783459528607800, 548262843888561036, 253013952989625426, 10238343656680653, 231856993074233434, 13092391257221657, 257425332087036844, 37076907481128612, 32475936008232323, 479054494814575764, 316365688466594058, 24901959355078511, 54925715124012347, 136609697697661647, 48992648532971041, 9652759378611463, 18944529925464988, 260300905662223692, 370716970492691685, 161032895531304854, 19602195926932583, 286241432389915003, 122333097676740353, 256243606074076912, 298469600501451514, 323392287137490133, 96942352029609537, 387297348178795814, 398480880187994045, 114714485818264699, 147418601589336420, 417213615800724863, 96484181343850675, 288238316979762203, 112215919781942041, 396117760323981802, 270878743100013250, 409662365010208362, 139644154014355102, 420597110756161322, 22889839893842827, 395721232609319151, 446753186230801888, 405787617377267839, 40770721303800011, 270303046441735313, 299834832307203482, 62219342863251647, 376319417745761158, 528177751203621995, 483825695946052012, 52129684794122396, 272186479267396815, 63326085267172994, 261208035326022888, 507860115132856994, 21543818926738969, 351601187080751326, 57563237050262813, 291536075345480129, 318558289865506436, 283622290900394122, 524281774245582319, 54495864754944005, 441353588048325507, 51154130117118354, 269160374572749191, 430570837856716024, 395291161200686351, 450851559796130848, 185892481422631415, 250633073742359209, 434780828708376245, 82563444887001267, 468763271566444092, 24498342842671292, 350999946451127531, 425441199077717278, 50478451217305137, 531470863815951593, 34561582991037415, 42585931440795084, 93967745485010227, 243731147702796952, 109342519037488467, 547850797674285456, 338061344889600727, 201976092714469369, 450258778930056784, 517798596958895191, 93103775192094033, 132471403845873966, 307953682018444138, 305946566700496201, 569579584238641857, 67406080562303566, 85770788601215361, 59568039767837680, 192122218786247088, 447777648099499514, 200083585306408461, 117085096703943995, 2784049277375653, 389837891365782357, 186539321131116762, 298641885293870802, 112000239209080747, 13412766141677789, 115834153665423136, 491813883876906717, 98594957295411001, 363369342414649785, 571831655883330771, 181326406513983348, 345138182555201348, 286882228957060337, 310165587109628228, 263116001914311004, 356529860341297043, 14418974761944020, 72559347011675087, 41702549006423207, 144154270204150471, 280442177110788977, 8624692368844465, 151612115785195588, 266795024990051282, 465494994399268376, 291962393562581608, 108028957772583295, 126113865702699988, 392217230899066018, 285709203818173889, 55400201367394067, 507855477171070252, 126884095204631701, 335722111414726002, 169765846065177320, 506522245808499300, 88565574204888991, 157552857688739131, 307595891846239503, 143127040775708028, 257888373869997801, 520545588557800967, 102144138705513358, 546097870553386894, 533978563211226950, 70915534931938272, 152648441140369354, 387362156827657663, 515457442706086245, 159174561776062179, 52481761497406720, 419219358117792205, 317001788365054907, 138343407612123691, 110771755904445691, 304557344775094466, 462959116433055898, 457665429464670795, 442543699203961651, 163692605712390294, 107196060992848458, 369172039399526760, 323548403867607287, 224657891255460898, 59332779744718163, 251667944551154863, 192320775257387930, 543818721737008123, 268893827800722561, 120556021072780148, 253568625251225834, 467122806135914243, 333481850561504409, 164170638301562282, 522657254349760476, 109563919332590491, 266804944594522192, 112387876009041456, 483249262595555251, 202803248406333417, 365647787237677578, 260741252292428437, 20564027982572248, 49387728131302536, 500034042130061970, 536893877713278048, 345511689890878543, 132637523927712126, 1668343926292550, 442491308620880640, 360876639801645358, 536398088736617164, 297872620295684534, 173165554681983217, 541513725083900254, 242224459111958021, 326354460369042841, 352608694211600117, 183505490305744945, 90192927844654688, 101132228355387823, 481226433212736257, 394169671607721980, 226298947009678454, 372617684458127264, 407730877182750198, 163761896190785638, 233808110040798733, 319367247913848560, 278177743729794516, 423614826121352536, 198464273764422058, 164526334303846259, 406853854276881396, 27912324655559939, 121736015367615016, 330928583003062417, 497286456358516482, 475750895464243201, 267457366550016498, 518671023441108910, 430440109603497141, 554029895879525626, 503529199965985162, 2836827418089596, 390830871228931294, 431723540972230372, 391170724443953250, 568961403158755292, 151734730152085424, 338622268631974604, 513410280210859109, 209596246278511712, 142758210698488700, 133106616625698155, 214054105512050048, 345579594765991826, 489526945830964194, 218048789522669490, 416435540735106317, 377440890698733043, 365853354964274590, 30929477460363406, 269007974291645412, 229826057878159803, 32936846715162921, 499763038608550443, 513634354694875352, 474285134620011521, 381663948870105288, 332642970077996614, 315806015209148619, 363040890258784913, 321863527604990348, 450190749366924520, 198001086250604402, 468856832587879244, 124474780330969371, 534501401385761300, 454609717012138064, 395647746004002526}, + }}, + Poly{[][]uint64{ + {377375692533819303, 96042522392580111, 317259146287346598, 137376012927733965, 415306747163540233, 490340161363226367, 330039373022726997, 571264302149327910, 219591562616992998, 407619565441801898, 151835231682797397, 566724849297668643, 571154469443007093, 227143861461416474, 415458473569889282, 527044257594250146, 106857222947543974, 346212426139721965, 197311223402831746, 529909318782600257, 35502198459059883, 520485532054272255, 402583824618296978, 136415002723606950, 118925770221146499, 183778487611340114, 256476739326187154, 248592444542778855, 317660816802406744, 324547652341405511, 292103982801274532, 569055293206978072, 331182913106524398, 413926721549106828, 406040093115701575, 43718761677164005, 129637747026068274, 544779479045891379, 166875330355015660, 26193651401132289, 352411088260385752, 25850192591010376, 472008152703844413, 297707829831692966, 341196969590035030, 377971427470149957, 510885285207508844, 193276049333997722, 575329523161531747, 373942099935654974, 551843812232517737, 94966847377267862, 83210354813273121, 378226227004730657, 322261505106315523, 297227006720040634, 463720039062939364, 367510714252085101, 88296839925613166, 426572588616151002, 69758444506219779, 149084691654525794, 391307001444157388, 567981892705475381, 425657609162379296, 41297695518763032, 93957975936343269, 205585588905426666, 177955168587827776, 79731536843757707, 181109216097857240, 474917996295529371, 484381429795358116, 493774180643443184, 222988563987548527, 213132578778947974, 119056050508184574, 232319155245528944, 530871646935835365, 104701037680690567, 571484428048864986, 1730992313718990, 392359800509627985, 180523168032403659, 161736918677753845, 550119453550263000, 364842161801778834, 517184337578385175, 379254023664605743, 552540428025664556, 288513194422872036, 168939224642320394, 399559127568629459, 161566020197680026, 114724856380958907, 19948435630928626, 473078817169058144, 302230993073258797, 559605480634735199, 344717364998230163, 427597155231897012, 126031441411296200, 181379889996913823, 219807385508268476, 19703327242245679, 539493784334724861, 555971281185750789, 147888867710390202, 571955485529041423, 334994706930636693, 73997199783742341, 160820669974940472, 266517658615143599, 331171762319250887, 294590729340228854, 36144117312231740, 31027462670221098, 475371688494719880, 135561753340776531, 423424809082370971, 350881865115568331, 148460956121817560, 304320959085283379, 483979563792033399, 189606449925027523, 542703343218898644, 21231604361649939, 126793588122798523, 255993249795046940, 25734222634623828, 111134567854459477, 141494977869068633, 475039589956777863, 550008844388777734, 219852951234184864, 188561162205663830, 13783865035690631, 14618119150858126, 565282114902876621, 514251490606919060, 216100636335880360, 393082303210225254, 267939581203198332, 77189745237824983, 42791179039368499, 3418584569932510, 169097121666213405, 513124220201262416, 430679593552627295, 423769329801309384, 108288466131214288, 260119361328891541, 294843234368118211, 347542539107972780, 104019847517396285, 404045520204175395, 484995695374574126, 259926588400743394, 60441900619125279, 501785989550591000, 196717414042250004, 283815300911332482, 306878575339671368, 201655570468075275, 21396503689493069, 551592680977066007, 48668533071578272, 34120024171107429, 17276314832219699, 11988355912840846, 348032877954281307, 233774210217173740, 274715600678249388, 407541059579021034, 326759238244731645, 260623610528652121, 156860663706260594, 452852046439264424, 116882794278540727, 429699372520750224, 464536705646748347, 315779670376437621, 302671044846383348, 199265959353230943, 470411062945950797, 22720414864624877, 537303905943378753, 259729396669010127, 448372106760398434, 545856703638493908, 297094985726245160, 510904393622146939, 553145298418297775, 35135868625156453, 490205475864349002, 524062149889824872, 320420910265923914, 327405535484890100, 318048349307047936, 410136284159911460, 296932531679305793, 361488657718526982, 126959259010752741, 53000267853100727, 74461958970920907, 243863182774128675, 122651803020546048, 187266749183026665, 174923025608680122, 318688649308795777, 309806501105889478, 81120994685221135, 83792974580420991, 526212368243039732, 434894680461252442, 431606768347172729, 224359771825741857, 246326778987784288, 83830939687362839, 265740120931394107, 326764911782522600, 486426542385087791, 251252724294525956, 87483704852449070, 46011843047667307, 174626587648137554, 424593668369166641, 41637957064450046, 193246137518342653, 432317515170361644, 245394074460521474, 418138840203732141, 455148389610593677, 492768772251109507, 497280239114315619, 34869598267190021, 296528750997490074, 175053309374893977, 415489357231674552, 181256877434378360, 425311891003143535, 112982403137046010, 375654969155071147, 363025383733187902, 135689801617196180, 68288703430133187, 379146883450004429, 142524821685472881, 112454925863771235, 320014801392235936, 384022922988066790, 251268075163460042, 420909870442277698, 537883121188626484, 21251996073869450, 524967339846403450, 154160978899257400, 499354661990354626, 154057090474654749, 102426081601932301, 178611395127321957, 333508042858991170, 301113001243279803, 170063007128992320, 352001455766320924, 427015845720512154, 422242883802457810, 574071350103865137, 272534824502343329, 200600582804524520, 518689680910833597, 56359342117135943, 322028190286255294, 410056867805089172, 248106680039449966, 559915503968675171, 325851616287589140, 530964321418311690, 72331831075558471, 200865554085219723, 244592115211132375, 183144772604455438, 498607624543832294, 576047094637903750, 76989223152036907, 405631706687511644, 441416474377456099, 153715792917927452, 465981950773737892, 417563329400329859, 297634223667077905, 248430573333647398, 269508814689795398, 434085648420826250, 352629382482611845, 135243176962337111, 11112634420223179, 227133431824127922, 551540163357690675, 322773751785254480, 91859181211416070, 408520996944382256, 461737515054703471, 216649273011463814, 489756154748978966, 304686401959958957, 187093208165297732, 571064112869702272, 483030872037334823, 231208485611976792, 47353167468848188, 220859583967685215, 368791081133506503, 448311434611922228, 11553114033975114, 285880008370673919, 464533331939697806, 250937078568932514, 22493928003895211, 19886615847961270, 524275225434617801, 436418416215785332, 449039215994924755, 195953129418859475, 57551104007934524, 281725799643162096, 48735499166402590, 461699867859813907, 67148210475218788, 543905922728157026, 182226495938922595, 550796496214243613, 191471383351463406, 451757520819077733, 287973802393304697, 551239005008419983, 2088186958798437, 208912411390605397, 198028987282627803, 188736697036049709, 414811519513909375, 477017385587557210, 310757820335969146, 495677794841369251, 84966518519838157, 417413281419232843, 524191040376032585, 172165758595012516, 330270444072059584, 487290023472023529, 287067496070434968, 120245446498493384, 517029628092507616, 146812275273192818, 134523269250962957, 134677175537836959, 176136326962319788, 424799833197667132, 103818595323478580, 223851388626867373, 121439995771647755, 242807308105295658, 150405395853889224, 498412122969935086, 218278857810216868, 208104474970536122, 260221378297549002, 316654686934686699, 30929480163385957, 208198729328663099, 335053023971247599, 562148606183273036, 410536004642549589, 212714257373256468, 103538202285776947, 143832116309273417, 30456322549076849, 86714866437621545, 309564082328786292, 377785962901287154, 272386054544072171, 190311330266192750, 351573784737171748, 352959370189797177, 3827364096388907, 200619906395194508, 542995428548734667, 18702807860278304, 171833939003818968, 227296369242809839, 135726318195433881, 209069986924360244, 393872424531497807, 339663565357057843, 297913425595462606, 437981007656088948, 538602343970248756, 212235339944700832, 211912601341285304, 442783807090235330, 254508593209532514, 224990827065343439, 482109591999300260, 555039280584388850, 126458971256647369, 168556735687900444, 279575156479008612, 565396698992489037, 11549010806200261, 394373488025751232, 419322928436105602, 365294698803403081, 544507796167299908, 230576658402485295, 555433168120863625, 430841505029632093, 194878346529601409, 459971850624033240, 285724118500519407, 193182186076824526, 541111882843089541, 403623419211700395, 317292145774192827, 565745482569156010, 567183177595683829, 412324127964923027, 424070678779344286, 383893710539160088, 79909480744106553, 135317551424476694, 569471794627931742, 341951140321658033, 82328797821410773, 411565860857526708, 321355848454700982, 75126226501014249, 503199356762562838, 302690739615128091, 501265052014414658, 454007627578292409, 317976993312768297, 59895650370837554, 381408048391356716, 81640799388082245, 465634528132834186, 326958541719178539, 410161099408037658, 490579859412689260, 425838442418793789, 1508695588127817, 359963433317418045, 157378769386843229, 480523164440799516, 180144835228005127, 160825291421506582, 359604206030521250, 562833513585114035, 445058912984313512, 288103179412561502, 423443836992136052, 193385142337300526, 534649015391602536, 72577693672868286, 142685760351568760, 97821588438303471, 550478311787984617, 70818771851821037, 258233136873228764, 554088899431500047, 539186318918648282, 325425805459836993, 495914204486223505, 162172224173758922, 236866818298761456, 391080277784028464, 61712296624710490, 161793043170955012, 267423931457620087, 540671913197314373, 98341162388471968, 228286403833826200, 518375967652135127, 56085383489534938, 490055315590720729, 516073932216751232, 369040856736265168, 134780449470695769, 382918318936764072, 143140170583580740, 445408790369445811, 116598228935045038, 175900743630821911, 357223750468405311, 433323211587079812, 496033720069994061, 116960908284347135, 559411137225705475, 107317757053487615, 161704620752076908, 348335260566288056, 173832709061112133, 279480304155135690, 294668652196144909, 251994706183508869, 43004770424611718, 219390200322664008, 326837094723508074, 11038984010640734, 270257516382849480, 124610653289748517, 71200529678388458, 218694178225172333}, + {466271146838164828, 345997737129306449, 396131031422226107, 116937133495041013, 470307369269241327, 372054853593177419, 461194759000203265, 95494996142674216, 296023655354651067, 388561538148330633, 136509946607324730, 97739337225681828, 250474766728238664, 199817794407702265, 179849674100089761, 147712868893473570, 384743230576170026, 323122056426363984, 279964353457368318, 138269675968568711, 127269820131034178, 386046661002048324, 156513367294373255, 378164427720748777, 66095750145279521, 223647012617699896, 296076782617087632, 292460357233706710, 174258923985980557, 46418703090745051, 201100662765574923, 34357221312246651, 105729294181785494, 531737109043801360, 23284441999400353, 560892495742057628, 214174623837839052, 270620859218969900, 114530421649658713, 148277655531181731, 107523630557556833, 381411727632323894, 517738773903320710, 64582714847065129, 56380818575545847, 394793300888262419, 491726049753852459, 431953147634931175, 12729890545215490, 407219403967799925, 494550336713636809, 510531964780906558, 145277482662646831, 120251342113548904, 366558554003566925, 569206546183799622, 17120674021865232, 545549761193429004, 474177731516146612, 504908903018918434, 180222850445718752, 165529884151818797, 433051388176544889, 317589215194447986, 367750654542128615, 350516710654757521, 536510283843822169, 122982904789732385, 555951782547180810, 154900121799960199, 554070850240132404, 192943220014834097, 182002032841832181, 474783212054666171, 560276189954185439, 65665372613331910, 44559631918261371, 62123835124561949, 397079860200017142, 375686386344671012, 325032138763584465, 521867309277341483, 208780799634964117, 103171876387775244, 238130877980292195, 57229872046420951, 430987964548734062, 217085238418230917, 504333912300381504, 425326127782881717, 219172947177223313, 327820696845371053, 414658397273406224, 148040631456141259, 486574959906123934, 121927334317712333, 157668935816710273, 404059031364737330, 165270792150604282, 498885177679994077, 144308111226178369, 176553054880913321, 14101972432915027, 432048471992214931, 126670844387119394, 369159614029378795, 205835200620335595, 11170576026552067, 545124795329650607, 111575454289328226, 440485700344570770, 378801759313392230, 15375506415674646, 558584858623022991, 485130247429239680, 101188836654026154, 264262908316435494, 544349473021042648, 397966082653351654, 210988680650958497, 70988190965937178, 145231291726678069, 238249293696427075, 62034706383252518, 54359013526972008, 424332775154368330, 408418378889307845, 452074936151327047, 85143952432131397, 97719075454291809, 109756567464440943, 215207311530598533, 360816487017851165, 176987217770935548, 88870881399916479, 396419418010155962, 56692460489005625, 201000384706966543, 160927502776586738, 458270030909164757, 395687385485434060, 204607869744071934, 480591906920653728, 229841137060657299, 22956853527789765, 252633384775033685, 14937813478318, 186252030574290570, 350977525255924426, 333284065572366438, 147879717739049820, 472875196275123170, 187179421358092876, 353007469735872106, 526894680292775206, 396174143623321801, 461400545081644867, 496611428475520665, 159274749531192068, 421297899723816458, 96251478272942596, 91188796138456557, 324761852083930624, 542042142024938958, 14179361708260415, 280563944918866135, 255054216368021586, 265422910470798600, 100350834747080409, 476968409202196098, 440153656756277578, 117652243087566517, 553270163748812057, 400885033423307111, 379938607704180061, 457358341089032818, 337837439998305490, 50741340844579070, 459800497249241704, 516274529016745669, 433412884898516172, 190369684621859261, 86239887933174233, 330949199735020874, 558170523373344908, 349209065426802518, 126386900794317269, 139762440266565498, 555796712934466764, 212516932974533684, 516072908479735953, 523150007430540858, 392872325201783914, 283772059382488947, 421374429984116561, 437313502940197471, 322354260197714379, 348085815297191726, 224263599432613588, 31348908904294929, 28616413379325209, 400081352308273621, 418408237629079966, 569077243235319562, 411412223506778698, 385173626138540426, 206520802580080304, 250114503258247730, 529190928290451569, 369219452017396617, 198707331022894256, 206910771415201462, 328349597469889601, 338643866244221429, 450666422080420972, 473567975236898027, 469575485918696903, 183053463197491334, 539640810084103270, 104081722471888903, 241885715480038404, 461880307967768440, 364035592642160360, 147584304614914707, 227297810490094860, 485343280770459207, 153134372305381865, 197435690034151445, 557369686477903272, 397029989611140044, 422284336765314899, 149019753920050359, 260940908146300638, 155092035839799334, 552933182353675536, 183350458647647372, 92806092482483431, 535606885305465070, 286505492809367415, 570069566423372568, 390218330990052622, 467129265621217161, 96956837922110035, 392691768404553185, 349155711592619894, 35214581029746228, 324692261733801539, 270562204886079604, 479519574820212928, 247141196922117346, 6501617166335209, 67031103314214317, 573347971184853932, 5107358710419612, 284010223254113821, 442748896127333283, 281952435677906572, 469641501151084272, 115784128671418848, 469548629381070445, 574555565277555716, 423260478587457471, 384871183849668027, 187098140840923540, 288989864589933865, 342999273978988809, 325733446046738638, 174129640994603724, 261892251668720415, 523036120235525932, 146110573010641454, 497012569068900968, 344234410572230000, 73351393642599373, 64494858336553019, 166940977537337324, 284811071734085598, 364307780745943132, 108942309296533881, 487925645090242720, 144304832233090110, 317152048823243323, 196840401584140857, 79253535328194197, 111754856371159418, 121351044799192409, 196453861485940759, 121813174194232409, 342453081976621890, 11434051624784284, 167697860686816093, 233528705256860827, 465068771923204650, 508688747066213295, 246541519401282567, 266272367112714005, 141293236272439653, 409300570584623214, 569686175558317371, 111662920525006666, 223978446146668561, 218209100648039207, 187382725057537322, 47610767262038889, 96602599284086181, 540632473712363131, 420569058611113125, 43192704522208469, 194125334293975903, 77905386944703817, 97895461773513108, 481799180084097557, 353221013904420600, 14714254363761205, 5872589680407296, 300960681599396269, 170216946604815755, 341186713112889462, 71216939394905485, 491972105932592514, 229419515485398596, 126976249808813518, 179412006695471785, 57403131563047446, 148832052726389176, 124204975353010264, 24130594458303779, 301044196622036976, 108480807311394813, 387398695760878003, 470793459909824624, 274565242175326363, 215549376988427975, 493529759866923382, 414158644512585082, 448232921329203322, 279397864287379368, 385921328000591571, 510803162528851695, 555250923277537883, 556365641961705086, 561981551241207103, 200151213531697127, 326020176181735345, 348927170412172200, 426080585300993963, 489229518822211887, 463182136949111471, 257180473660938448, 417636541678466864, 567212374615025817, 118656760864016921, 182350302216369058, 510953747581147011, 476243800549349531, 472784868841691998, 1859629731208576, 545876001998533822, 126839511235733174, 491710720960582551, 905807527389075, 455345462594802075, 541991300664323245, 170944695324732089, 319137172939860059, 441207306778395303, 235893604708258320, 187756510098277534, 548789333110747016, 473083391264904964, 281610682150903753, 362202931681116777, 552363674076296763, 362516495075315452, 477495854878598355, 83227382076754502, 288715706663209883, 17149401505382573, 142188092975845092, 145511149175846974, 487263249631970725, 379579040691835762, 444361856595697538, 251901411776729981, 519421968809331630, 564594051088515530, 214831332322826267, 477489365776262086, 503404569497105678, 525950699404797475, 211663800152941048, 544504415437890273, 82703882773163155, 215883002493891024, 228206415465367662, 262405671296729818, 552919762067589595, 275282707229127204, 506862872415810722, 223051532741182696, 248520929795284496, 251374539617081468, 459496143812729680, 544259681167706164, 513455149821051369, 153338889223626777, 552553512392463917, 345532237443658967, 276613035962259959, 76052831423776229, 27638414740821390, 468766331039522867, 462504914336801108, 504260205236931059, 153260787175953363, 249603626061351444, 462048919949765548, 325825983710082099, 349570698183439144, 467814558281048838, 319075842483329949, 494782675075346860, 136779850697638520, 550189000585042743, 158778420396589586, 553341782111330506, 108400733792223445, 399256538215209069, 373094641019970380, 243138034856802011, 284711146084351060, 278491248589657095, 405803616347773860, 144010079623340352, 242564151102210173, 304325658359166453, 24224471624104594, 312013094909905962, 102950534848587037, 156646216976992137, 554868615338424708, 356065313504408037, 566554900875042237, 95142308262512631, 330327806567307709, 369314998024605662, 153925071799269127, 56849208511968834, 97675248685366110, 492807069950337980, 505011383316691507, 107137368831333805, 95244666943819810, 558236562180487130, 381134552288649201, 279126085896895435, 226859758644230092, 332926241878417490, 59053186182861837, 153807718980788405, 306658731457151854, 257745138960216484, 472599985235421104, 544827907149369897, 251310520271446155, 358012352843338841, 438215357442019565, 483543526837670693, 158580553055555394, 352654285881331198, 388025798341012870, 338586088212445186, 155117276797284440, 378829719982032, 216312860078349289, 183297139494101146, 356588527437434108, 490284293282429686, 213259456861909560, 359979054012642350, 59403241158934888, 88584374442351305, 149035080700868987, 561415063327994800, 197705271185242657, 153600123134508289, 341557397762112196, 563343428623464997, 421138288411921131, 37404886685863830, 399174946308648257, 226458419633193851, 63022668308744462, 365156258184484613, 494367543361132635, 556015298352559479, 509534126231315064, 341150199135062270, 291235481860477466, 331441313502873095, 108946546082309778, 302268753853175947, 293244050322880997, 174023385589118716, 358845414981291318, 503278587016997718, 65545998668302565, 130388228257893042, 216748567070515186, 456177830619431315, 95337524348576070, 371268046380703332}, + }}, }, } @@ -104,8 +104,8 @@ func TestNTT(t *testing.T) { y := ringQ.NewPoly() z := ringQ.NewPoly() - copy(x.Buff, tv.Buff) - copy(y.Buff, tv.BuffNTT) + x.Copy(tv.poly) + y.Copy(tv.polyNTT) ringQ.NTT(x, z) diff --git a/ring/poly.go b/ring/poly.go index 5497020b..977bf9d3 100644 --- a/ring/poly.go +++ b/ring/poly.go @@ -2,30 +2,25 @@ package ring import ( "bufio" - "fmt" "io" "github.com/tuneinsight/lattigo/v4/utils" "github.com/tuneinsight/lattigo/v4/utils/buffer" + "github.com/tuneinsight/lattigo/v4/utils/structs" ) // Poly is the structure that contains the coefficients of a polynomial. type Poly struct { - Coeffs [][]uint64 // Dimension-2 slice of coefficients (re-slice of Buff) - Buff []uint64 // Dimension-1 slice of coefficient + Coeffs structs.Matrix[uint64] } // NewPoly creates a new polynomial with N coefficients set to zero and Level+1 moduli. func NewPoly(N, Level int) (pol Poly) { - pol = Poly{} - - pol.Buff = make([]uint64, N*(Level+1)) - pol.Coeffs = make([][]uint64, Level+1) - for i := 0; i < Level+1; i++ { - pol.Coeffs[i] = pol.Buff[i*N : (i+1)*N] + Coeffs := make([][]uint64, Level+1) + for i := range Coeffs { + Coeffs[i] = make([]uint64, N) } - - return + return Poly{Coeffs: Coeffs} } // Resize resizes the level of the target polynomial to the provided level. @@ -34,13 +29,12 @@ func NewPoly(N, Level int) (pol Poly) { func (pol *Poly) Resize(level int) { N := pol.N() if pol.Level() > level { - pol.Buff = pol.Buff[:N*(level+1)] pol.Coeffs = pol.Coeffs[:level+1] } else if level > pol.Level() { - pol.Buff = append(pol.Buff, make([]uint64, N*(level-pol.Level()))...) - pol.Coeffs = append(pol.Coeffs, make([][]uint64, level-pol.Level())...) - for i := 0; i < level+1; i++ { - pol.Coeffs[i] = pol.Buff[i*N : (i+1)*N] + prevLevel := pol.Level() + pol.Coeffs = append(pol.Coeffs, make([][]uint64, level-prevLevel)...) + for i := prevLevel + 1; i < level+1; i++ { + pol.Coeffs[i] = make([]uint64, N) } } } @@ -60,42 +54,34 @@ func (pol Poly) Level() int { // Zero sets all coefficients of the target polynomial to 0. func (pol Poly) Zero() { - ZeroVec(pol.Buff) + for i := range pol.Coeffs { + ZeroVec(pol.Coeffs[i]) + } } // CopyNew creates an exact copy of the target polynomial. func (pol Poly) CopyNew() *Poly { - cpy := NewPoly(pol.N(), pol.Level()) - copy(cpy.Buff, pol.Buff) - return &cpy -} - -// Copy copies the coefficients of p0 on p1 within the given Ring. It requires p1 to be at least as big p0. -// Expects the degree of both polynomials to be identical. -func Copy(p0, p1 Poly) { - copy(p1.Buff, p0.Buff) -} - -// CopyLvl copies the coefficients of p0 on p1 within the given Ring. -// Copies for up to level+1 moduli. -// Expects the degree of both polynomials to be identical. -func CopyLvl(level int, p0, p1 Poly) { - copy(p1.Buff[:p1.N()*(level+1)], p0.Buff) -} - -// CopyValues copies the coefficients of p1 on the target polynomial. -// Onyl copies minLevel(pol, p1) levels. -// Expects the degree of both polynomials to be identical. -func (pol *Poly) CopyValues(p1 Poly) { - if !utils.Alias1D(pol.Buff, p1.Buff) { - copy(pol.Buff, p1.Buff) + return &Poly{ + Coeffs: pol.Coeffs.CopyNew(), } } // Copy copies the coefficients of p1 on the target polynomial. -// Onyl copies minLevel(pol, p1) levels. +// This method does nothing if the underlying arrays are the same. +// Expects the degree of both polynomials to be identical. func (pol *Poly) Copy(p1 Poly) { - pol.CopyValues(p1) + pol.CopyLvl(utils.Min(pol.Level(), p1.Level()), p1) +} + +// CopyLvl copies the coefficients of p1 on the target polynomial. +// This method does nothing if the underlying arrays are the same. +// Expects the degree of both polynomials to be identical. +func (pol *Poly) CopyLvl(level int, p1 Poly) { + for i := 0; i < level+1; i++ { + if !utils.Alias1D(pol.Coeffs[i], p1.Coeffs[i]) { + copy(pol.Coeffs[i], p1.Coeffs[i]) + } + } } // Equal returns true if the receiver Poly is equal to the provided other Poly. @@ -103,30 +89,12 @@ func (pol *Poly) Copy(p1 Poly) { // (i.e., it does not consider congruence as equality within the ring like // `Ring.Equal` does). func (pol Poly) Equal(other *Poly) bool { - - if other == nil { - return false - } - - if utils.Alias1D(pol.Buff, other.Buff) { - return true - } - - if len(pol.Buff) == len(other.Buff) { - return utils.EqualSlice(pol.Buff, other.Buff) - } - - return false -} - -// polyBinarySize returns the size in bytes of the Poly object. -func polyBinarySize(N, Level int) (size int) { - return 16 + N*(Level+1)<<3 + return pol.Coeffs.Equal(other.Coeffs) } // BinarySize returns the serialized size of the object in bytes. func (pol Poly) BinarySize() (size int) { - return polyBinarySize(pol.N(), pol.Level()) + return pol.Coeffs.BinarySize() } // WriteTo writes the object on an io.Writer. It implements the io.WriterTo @@ -141,28 +109,12 @@ func (pol Poly) BinarySize() (size int) { // - When writing to a pre-allocated var b []byte, it is preferable to pass // buffer.NewBuffer(b) as w (see lattigo/utils/buffer/buffer.go). func (pol Poly) WriteTo(w io.Writer) (n int64, err error) { - switch w := w.(type) { case buffer.Writer: - - var inc int64 - - if n, err = buffer.WriteAsUint64(w, pol.N()); err != nil { - return n, err + if n, err = pol.Coeffs.WriteTo(w); err != nil { + return } - - if inc, err = buffer.WriteAsUint64(w, pol.Level()); err != nil { - return n + inc, err - } - - n += inc - - if inc, err = buffer.WriteUint64Slice(w, pol.Buff); err != nil { - return n + inc, err - } - - return n + inc, w.Flush() - + return n, w.Flush() default: return pol.WriteTo(bufio.NewWriter(w)) } @@ -180,55 +132,12 @@ func (pol Poly) WriteTo(w io.Writer) (n int64, err error) { // - When reading from a var b []byte, it is preferable to pass a buffer.NewBuffer(b) // as w (see lattigo/utils/buffer/buffer.go). func (pol *Poly) ReadFrom(r io.Reader) (n int64, err error) { - switch r := r.(type) { case buffer.Reader: - - var inc int64 - - var N int - if n, err = buffer.ReadAsUint64[int](r, &N); err != nil { - return n, fmt.Errorf("cannot ReadFrom: N: %w", err) + if n, err = pol.Coeffs.ReadFrom(r); err != nil { + return } - - n += inc - - if N <= 0 { - return n, fmt.Errorf("error ReadFrom: N cannot be 0 or negative") - } - - var Level int - if inc, err = buffer.ReadAsUint64[int](r, &Level); err != nil { - return n + inc, fmt.Errorf("cannot ReadFrom: Level: %w", err) - } - - n += inc - - if Level < 0 { - return n, fmt.Errorf("invalid encoding: Level cannot be negative") - } - - if pol.Buff == nil || len(pol.Buff) != N*(Level+1) { - pol.Buff = make([]uint64, N*int(Level+1)) - } - - if inc, err = buffer.ReadUint64Slice(r, pol.Buff); err != nil { - return n + inc, fmt.Errorf("cannot ReadFrom: pol.Buff: %w", err) - } - - n += inc - - // Reslice - if len(pol.Coeffs) != Level+1 { - pol.Coeffs = make([][]uint64, Level+1) - } - - for i := 0; i < Level+1; i++ { - pol.Coeffs[i] = pol.Buff[i*N : (i+1)*N] - } - return n, nil - default: return pol.ReadFrom(bufio.NewReader(r)) } diff --git a/ring/ring.go b/ring/ring.go index db523bed..35626e39 100644 --- a/ring/ring.go +++ b/ring/ring.go @@ -507,7 +507,7 @@ func (r Ring) Equal(p1, p2 Poly) bool { r.Reduce(p1, p1) r.Reduce(p2, p2) - return utils.EqualSlice(p1.Buff, p2.Buff) + return p1.Equal(&p2) } // ringParametersLiteral is a struct to store the minimum information diff --git a/ring/ring_benchmark_test.go b/ring/ring_benchmark_test.go index 0bfd6878..270d931c 100644 --- a/ring/ring_benchmark_test.go +++ b/ring/ring_benchmark_test.go @@ -39,7 +39,7 @@ func BenchmarkRing(b *testing.B) { func benchGenRing(tc *testParams, b *testing.B) { - b.Run(testString("GenRing/", tc.ringQ), func(b *testing.B) { + b.Run(testString("GenRing", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { if _, err := NewRing(tc.ringQ.N(), tc.ringQ.ModuliChain()); err != nil { b.Error(err) @@ -54,7 +54,7 @@ func benchMarshalling(tc *testParams, b *testing.B) { p := tc.uniformSamplerQ.ReadNew() - b.Run(testString("Marshalling/MarshalPoly/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Marshalling/MarshalPoly", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { if _, err = p.MarshalBinary(); err != nil { b.Error(err) @@ -67,7 +67,7 @@ func benchMarshalling(tc *testParams, b *testing.B) { b.Error(err) } - b.Run(testString("Marshalling/UnmarshalPoly/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Marshalling/UnmarshalPoly", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { if err = p.UnmarshalBinary(data); err != nil { b.Error(err) @@ -80,7 +80,7 @@ func benchSampling(tc *testParams, b *testing.B) { pol := tc.ringQ.NewPoly() - b.Run(testString("Sampling/Gaussian/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Sampling/Gaussian", tc.ringQ), func(b *testing.B) { sampler, err := NewSampler(tc.prng, tc.ringQ, &DiscreteGaussian{Sigma: DefaultSigma, Bound: DefaultBound}, false) require.NoError(b, err) @@ -90,7 +90,7 @@ func benchSampling(tc *testParams, b *testing.B) { } }) - b.Run(testString("Sampling/Ternary/0.3/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Sampling/Ternary/0.3", tc.ringQ), func(b *testing.B) { sampler, err := NewSampler(tc.prng, tc.ringQ, Ternary{P: 1.0 / 3}, true) require.NoError(b, err) @@ -100,7 +100,7 @@ func benchSampling(tc *testParams, b *testing.B) { } }) - b.Run(testString("Sampling/Ternary/0.5/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Sampling/Ternary/0.5", tc.ringQ), func(b *testing.B) { sampler, err := NewSampler(tc.prng, tc.ringQ, Ternary{P: 0.5}, true) require.NoError(b, err) @@ -110,7 +110,7 @@ func benchSampling(tc *testParams, b *testing.B) { } }) - b.Run(testString("Sampling/Ternary/sparse128/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Sampling/Ternary/sparse128", tc.ringQ), func(b *testing.B) { sampler, err := NewSampler(tc.prng, tc.ringQ, Ternary{H: 128}, true) require.NoError(b, err) @@ -120,7 +120,7 @@ func benchSampling(tc *testParams, b *testing.B) { } }) - b.Run(testString("Sampling/Uniform/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Sampling/Uniform", tc.ringQ), func(b *testing.B) { sampler, err := NewSampler(tc.prng, tc.ringQ, &Uniform{}, true) require.NoError(b, err) @@ -135,13 +135,13 @@ func benchMontgomery(tc *testParams, b *testing.B) { p := tc.uniformSamplerQ.ReadNew() - b.Run(testString("Montgomery/MForm/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Montgomery/MForm", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.MForm(p, p) } }) - b.Run(testString("Montgomery/InvMForm/", tc.ringQ), func(b *testing.B) { + b.Run(testString("Montgomery/InvMForm", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.IMForm(p, p) } @@ -152,13 +152,13 @@ func benchNTT(tc *testParams, b *testing.B) { p := tc.uniformSamplerQ.ReadNew() - b.Run(testString("NTT/Forward/Standard/", tc.ringQ), func(b *testing.B) { + b.Run(testString("NTT/Forward/Standard", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.NTT(p, p) } }) - b.Run(testString("NTT/Backward/Standard/", tc.ringQ), func(b *testing.B) { + b.Run(testString("NTT/Backward/Standard", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.INTT(p, p) } @@ -166,13 +166,13 @@ func benchNTT(tc *testParams, b *testing.B) { ringQConjugateInvariant, _ := NewRingConjugateInvariant(tc.ringQ.N(), tc.ringQ.ModuliChain()) - b.Run(testString("NTT/Forward/ConjugateInvariant4NthRoot/", tc.ringQ), func(b *testing.B) { + b.Run(testString("NTT/Forward/ConjugateInvariant4NthRoot", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { ringQConjugateInvariant.NTT(p, p) } }) - b.Run(testString("NTT/Backward/ConjugateInvariant4NthRoot/", tc.ringQ), func(b *testing.B) { + b.Run(testString("NTT/Backward/ConjugateInvariant4NthRoot", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { ringQConjugateInvariant.INTT(p, p) } @@ -184,25 +184,25 @@ func benchMulCoeffs(tc *testParams, b *testing.B) { p0 := tc.uniformSamplerQ.ReadNew() p1 := tc.uniformSamplerQ.ReadNew() - b.Run(testString("MulCoeffs/Montgomery/", tc.ringQ), func(b *testing.B) { + b.Run(testString("MulCoeffs/Montgomery", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.MulCoeffsMontgomery(p0, p1, p0) } }) - b.Run(testString("MulCoeffs/MontgomeryLazy/", tc.ringQ), func(b *testing.B) { + b.Run(testString("MulCoeffs/MontgomeryLazy", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.MulCoeffsMontgomeryLazy(p0, p1, p0) } }) - b.Run(testString("MulCoeffs/Barrett/", tc.ringQ), func(b *testing.B) { + b.Run(testString("MulCoeffs/Barrett", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.MulCoeffsBarrett(p0, p1, p0) } }) - b.Run(testString("MulCoeffs/BarrettLazy/", tc.ringQ), func(b *testing.B) { + b.Run(testString("MulCoeffs/BarrettLazy", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.MulCoeffsBarrettLazy(p0, p1, p0) } @@ -214,7 +214,7 @@ func benchAddCoeffs(tc *testParams, b *testing.B) { p0 := tc.uniformSamplerQ.ReadNew() p1 := tc.uniformSamplerQ.ReadNew() - b.Run(testString("AddCoeffs/Add/", tc.ringQ), func(b *testing.B) { + b.Run(testString("AddCoeffs/Add", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.Add(p0, p1, p0) } @@ -232,13 +232,13 @@ func benchSubCoeffs(tc *testParams, b *testing.B) { p0 := tc.uniformSamplerQ.ReadNew() p1 := tc.uniformSamplerQ.ReadNew() - b.Run(testString("SubCoeffs/Sub/", tc.ringQ), func(b *testing.B) { + b.Run(testString("SubCoeffs/Sub", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.Sub(p0, p1, p0) } }) - b.Run(testString("SubCoeffs/SubLazy/", tc.ringQ), func(b *testing.B) { + b.Run(testString("SubCoeffs/SubLazy", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.SubLazy(p0, p1, p0) } @@ -266,13 +266,13 @@ func benchMulScalar(tc *testParams, b *testing.B) { scalarBigint := bignum.NewInt(rand1) scalarBigint.Mul(scalarBigint, bignum.NewInt(rand2)) - b.Run(testString("MulScalar/uint64/", tc.ringQ), func(b *testing.B) { + b.Run(testString("MulScalar/uint64", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.MulScalar(p, rand1, p) } }) - b.Run(testString("MulScalar/big.Int/", tc.ringQ), func(b *testing.B) { + b.Run(testString("MulScalar/big.Int", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.MulScalarBigint(p, scalarBigint, p) } @@ -315,25 +315,25 @@ func benchDivByLastModulus(tc *testParams, b *testing.B) { buff := tc.ringQ.NewPoly() - b.Run(testString("DivByLastModulus/Floor/", tc.ringQ), func(b *testing.B) { + b.Run(testString("DivByLastModulus/Floor", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.DivFloorByLastModulus(p0, p1) } }) - b.Run(testString("DivByLastModulus/FloorNTT/", tc.ringQ), func(b *testing.B) { + b.Run(testString("DivByLastModulus/FloorNTT", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.DivFloorByLastModulusNTT(p0, buff, p1) } }) - b.Run(testString("DivByLastModulus/Round/", tc.ringQ), func(b *testing.B) { + b.Run(testString("DivByLastModulus/Round", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.DivRoundByLastModulus(p0, p1) } }) - b.Run(testString("DivByLastModulus/RoundNTT/", tc.ringQ), func(b *testing.B) { + b.Run(testString("DivByLastModulus/RoundNTT", tc.ringQ), func(b *testing.B) { for i := 0; i < b.N; i++ { tc.ringQ.DivRoundByLastModulusNTT(p0, buff, p1) } diff --git a/ring/scaling.go b/ring/scaling.go index 35e9221b..a4a6641d 100644 --- a/ring/scaling.go +++ b/ring/scaling.go @@ -1,9 +1,5 @@ package ring -import ( - "github.com/tuneinsight/lattigo/v4/utils" -) - // DivFloorByLastModulusNTT divides (floored) the polynomial by its last modulus. // The input must be in the NTT domain. // Output poly level must be equal or one less than input level. @@ -37,8 +33,8 @@ func (r Ring) DivFloorByLastModulusManyNTT(nbRescales int, p0, buff, p1 Poly) { if nbRescales == 0 { - if !utils.Alias1D(p0.Buff, p1.Buff) { - copy(p1.Buff, p0.Buff) + if !p0.Equal(&p1) { + p1.Copy(p0) } } else { @@ -62,8 +58,8 @@ func (r Ring) DivFloorByLastModulusMany(nbRescales int, p0, buff, p1 Poly) { if nbRescales == 0 { - if !utils.Alias1D(p0.Buff, p1.Buff) { - copy(p1.Buff, p0.Buff) + if !p0.Equal(&p1) { + p1.Copy(p0) } } else { @@ -135,8 +131,8 @@ func (r Ring) DivRoundByLastModulusManyNTT(nbRescales int, p0, buff, p1 Poly) { if nbRescales == 0 { - if !utils.Alias1D(p0.Buff, p1.Buff) { - copy(p1.Buff, p0.Buff) + if !p0.Equal(&p1) { + p1.Copy(p0) } } else { @@ -165,8 +161,8 @@ func (r Ring) DivRoundByLastModulusMany(nbRescales int, p0, buff, p1 Poly) { if nbRescales == 0 { - if !utils.Alias1D(p0.Buff, p1.Buff) { - copy(p1.Buff, p0.Buff) + if !p0.Equal(&p1) { + p1.Copy(p0) } } else { diff --git a/rlwe/decryptor.go b/rlwe/decryptor.go index 2e13960c..433ba152 100644 --- a/rlwe/decryptor.go +++ b/rlwe/decryptor.go @@ -54,7 +54,7 @@ func (d Decryptor) Decrypt(ct *Ciphertext, pt *Plaintext) { *pt.MetaData = *ct.MetaData if ct.IsNTT { - ring.CopyLvl(level, ct.Value[ct.Degree()], pt.Value) + pt.Value.CopyLvl(level, ct.Value[ct.Degree()]) } else { ringQ.NTTLazy(ct.Value[ct.Degree()], pt.Value) } diff --git a/rlwe/element.go b/rlwe/element.go index 2cf54518..e5d0f2bb 100644 --- a/rlwe/element.go +++ b/rlwe/element.go @@ -84,7 +84,6 @@ func NewElementAtLevelFromPoly(level int, poly []ring.Poly) (*Element[ring.Poly] } Value[i].Coeffs = poly[i].Coeffs[:level+1] - Value[i].Buff = poly[i].Buff[:poly[i].N()*(level+1)] } return &Element[ring.Poly]{Value: Value}, nil diff --git a/rlwe/evaluator_evaluationkey.go b/rlwe/evaluator_evaluationkey.go index ec4a7559..8db1415b 100644 --- a/rlwe/evaluator_evaluationkey.go +++ b/rlwe/evaluator_evaluationkey.go @@ -106,7 +106,7 @@ func (eval Evaluator) applyEvaluationKey(level int, ctIn *Ciphertext, evk *Evalu ctTmp.MetaData = ctIn.MetaData eval.GadgetProduct(level, ctIn.Value[1], &evk.GadgetCiphertext, ctTmp) eval.params.RingQ().AtLevel(level).Add(ctIn.Value[0], ctTmp.Value[0], opOut.Value[0]) - ring.CopyLvl(level, ctTmp.Value[1], opOut.Value[1]) + opOut.Value[1].CopyLvl(level, ctTmp.Value[1]) } // Relinearize applies the relinearization procedure on ct0 and returns the result in opOut. diff --git a/rlwe/evaluator_gadget_product.go b/rlwe/evaluator_gadget_product.go index 01b6f6f8..bc413e91 100644 --- a/rlwe/evaluator_gadget_product.go +++ b/rlwe/evaluator_gadget_product.go @@ -66,8 +66,8 @@ func (eval Evaluator) ModDown(levelQ, levelP int, ctQP *Element[ringqp.Poly], ct if ctQP.IsNTT { if ct.IsNTT { // NTT -> NTT - ring.CopyLvl(levelQ, ct.Value[0], ctQP.Value[0].Q) - ring.CopyLvl(levelQ, ct.Value[1], ctQP.Value[1].Q) + ctQP.Value[0].Q.CopyLvl(levelQ, ct.Value[0]) + ctQP.Value[1].Q.CopyLvl(levelQ, ct.Value[1]) } else { // NTT -> INTT ringQP.RingQ.INTT(ctQP.Value[0].Q, ct.Value[0]) @@ -81,8 +81,8 @@ func (eval Evaluator) ModDown(levelQ, levelP int, ctQP *Element[ringqp.Poly], ct } else { // INTT -> INTT - ring.CopyLvl(levelQ, ct.Value[0], ctQP.Value[0].Q) - ring.CopyLvl(levelQ, ct.Value[1], ctQP.Value[1].Q) + ctQP.Value[0].Q.CopyLvl(levelQ, ct.Value[0]) + ctQP.Value[1].Q.CopyLvl(levelQ, ct.Value[1]) } } } diff --git a/rlwe/gadgetciphertext.go b/rlwe/gadgetciphertext.go index d1dd0945..91c7b290 100644 --- a/rlwe/gadgetciphertext.go +++ b/rlwe/gadgetciphertext.go @@ -178,9 +178,7 @@ func AddPolyTimesGadgetVectorToGadgetCiphertext(pt ring.Poly, cts []GadgetCipher ringQ.MulScalarBigint(pt, ringQP.RingP.AtLevel(levelP).Modulus(), buff) // P * pt } else { levelP = 0 - if !utils.Alias1D(pt.Buff, buff.Buff) { - ring.CopyLvl(levelQ, pt, buff) // 1 * pt - } + buff.CopyLvl(levelQ, pt) // 1 * pt } BaseRNSDecompositionVectorSize := len(cts[0].Value) diff --git a/rlwe/inner_sum.go b/rlwe/inner_sum.go index b0dc48f0..9e315cb1 100644 --- a/rlwe/inner_sum.go +++ b/rlwe/inner_sum.go @@ -35,14 +35,14 @@ func (eval Evaluator) InnerSum(ctIn *Ciphertext, batchSize, n int, opOut *Cipher ringQ.NTT(ctIn.Value[0], ctInNTT.Value[0]) ringQ.NTT(ctIn.Value[1], ctInNTT.Value[1]) } else { - ring.CopyLvl(levelQ, ctIn.Value[0], ctInNTT.Value[0]) - ring.CopyLvl(levelQ, ctIn.Value[1], ctInNTT.Value[1]) + ctInNTT.Value[0].CopyLvl(levelQ, ctIn.Value[0]) + ctInNTT.Value[1].CopyLvl(levelQ, ctIn.Value[1]) } if n == 1 { if ctIn != opOut { - ring.CopyLvl(levelQ, ctIn.Value[0], opOut.Value[0]) - ring.CopyLvl(levelQ, ctIn.Value[1], opOut.Value[1]) + opOut.Value[0].CopyLvl(levelQ, ctIn.Value[0]) + opOut.Value[1].CopyLvl(levelQ, ctIn.Value[1]) } } else { @@ -114,8 +114,8 @@ func (eval Evaluator) InnerSum(ctIn *Ciphertext, batchSize, n int, opOut *Cipher ringQ.Add(opOut.Value[1], ctInNTT.Value[1], opOut.Value[1]) } else { - ring.CopyLvl(levelQ, ctInNTT.Value[0], opOut.Value[0]) - ring.CopyLvl(levelQ, ctInNTT.Value[1], opOut.Value[1]) + opOut.Value[0].CopyLvl(levelQ, ctInNTT.Value[0]) + opOut.Value[1].CopyLvl(levelQ, ctInNTT.Value[1]) } } } diff --git a/rlwe/keygenerator.go b/rlwe/keygenerator.go index ebcaa7cd..4d62773f 100644 --- a/rlwe/keygenerator.go +++ b/rlwe/keygenerator.go @@ -100,7 +100,7 @@ func (kgen KeyGenerator) GenRelinearizationKeyNew(sk *SecretKey, evkParams ...Ev // GenRelinearizationKey generates an EvaluationKey that will be used to relinearize Ciphertexts during multiplication. func (kgen KeyGenerator) GenRelinearizationKey(sk *SecretKey, rlk *RelinearizationKey) { - kgen.buffQP.Q.CopyValues(sk.Value.Q) + kgen.buffQP.Q.CopyLvl(rlk.LevelQ(), sk.Value.Q) kgen.params.RingQ().AtLevel(rlk.LevelQ()).MulCoeffsMontgomery(kgen.buffQP.Q, sk.Value.Q, kgen.buffQP.Q) kgen.genEvaluationKey(kgen.buffQP.Q, sk.Value, &rlk.EvaluationKey) } diff --git a/rlwe/ringqp/operations.go b/rlwe/ringqp/operations.go index 5d8c0a0f..283f63a8 100644 --- a/rlwe/ringqp/operations.go +++ b/rlwe/ringqp/operations.go @@ -2,7 +2,6 @@ package ringqp import ( "github.com/tuneinsight/lattigo/v4/ring" - "github.com/tuneinsight/lattigo/v4/utils" ) // Add adds p1 to p2 coefficient-wise and writes the result on p3. @@ -328,7 +327,7 @@ func (r Ring) ExtendBasisSmallNormAndCenter(polyInQ ring.Poly, levelP int, polyO Q = r.RingQ.SubRings[0].Modulus QHalf = Q >> 1 - if !utils.Alias1D(polyInQ.Buff, polyOutQ.Buff) { + if !polyInQ.Equal(&polyOutQ) { polyOutQ.Copy(polyInQ) } diff --git a/rlwe/ringqp/poly.go b/rlwe/ringqp/poly.go index 0977d529..da27621a 100644 --- a/rlwe/ringqp/poly.go +++ b/rlwe/ringqp/poly.go @@ -4,7 +4,6 @@ import ( "bufio" "io" - //"github.com/google/go-cmp/cmp" "github.com/tuneinsight/lattigo/v4/ring" "github.com/tuneinsight/lattigo/v4/utils" "github.com/tuneinsight/lattigo/v4/utils/buffer" @@ -56,25 +55,19 @@ func (p Poly) Equal(other *Poly) (v bool) { // Copy copies the coefficients of other on the target polynomial. // This method simply calls the Copy method for each of its sub-polynomials. func (p *Poly) Copy(other Poly) { - if p.Q.Level() != -1 && !utils.Alias1D(p.Q.Buff, other.Q.Buff) { - copy(p.Q.Buff, other.Q.Buff) - } - - if p.P.Level() != -1 && !utils.Alias1D(p.P.Buff, other.P.Buff) { - copy(p.P.Buff, other.P.Buff) - } + p.CopyLvl(utils.Min(p.LevelQ(), other.LevelQ()), utils.Min(p.LevelP(), other.LevelP()), other) } -// CopyLvl copies the values of p1 on p2. +// CopyLvl copies the values of other on the target polynomial. // The operation is performed at levelQ for the ringQ and levelP for the ringP. -func CopyLvl(levelQ, levelP int, p1, p2 Poly) { +func (p *Poly) CopyLvl(levelQ, levelP int, other Poly) { - if p1.Q.Level() != -1 && p2.Q.Level() != -1 && !utils.Alias1D(p1.Q.Buff, p2.Q.Buff) { - ring.CopyLvl(levelQ, p1.Q, p2.Q) + if p.Q.Level() != -1 && other.Q.Level() != -1 { + p.Q.CopyLvl(levelQ, other.Q) } - if p1.P.Level() != -1 && p2.Q.Level() != -1 && !utils.Alias1D(p1.P.Buff, p2.P.Buff) { - ring.CopyLvl(levelP, p1.P, p2.P) + if p.P.Level() != -1 && other.P.Level() != -1 { + p.P.CopyLvl(levelP, other.P) } } @@ -95,14 +88,7 @@ func (p *Poly) Resize(levelQ, levelP int) { // BinarySize returns the serialized size of the object in bytes. // It assumes that each coefficient takes 8 bytes. func (p Poly) BinarySize() (dataLen int) { - dataLen = 1 - if p.Q.Level() != -1 { - dataLen += p.Q.BinarySize() - } - if p.P.Level() != -1 { - dataLen += p.P.BinarySize() - } - return dataLen + return p.Q.BinarySize() + p.P.BinarySize() } // WriteTo writes the object on an io.Writer. It implements the io.WriterTo @@ -121,21 +107,7 @@ func (p Poly) WriteTo(w io.Writer) (n int64, err error) { switch w := w.(type) { case buffer.Writer: - var hasQP byte - if p.Q.Level() != -1 { - hasQP = hasQP | 2 - } - - if p.P.Level() != -1 { - hasQP = hasQP | 1 - } - var inc int64 - if inc, err = buffer.WriteUint8(w, hasQP); err != nil { - return n + inc, err - } - - n += inc if inc, err = p.Q.WriteTo(w); err != nil { return n + inc, err @@ -143,12 +115,12 @@ func (p Poly) WriteTo(w io.Writer) (n int64, err error) { n += inc - if p.P.Level() != -1 { - if inc, err = p.P.WriteTo(w); err != nil { - return n + inc, err - } - n += inc + if inc, err = p.P.WriteTo(w); err != nil { + return n + inc, err } + + n += inc + return n, w.Flush() default: @@ -171,32 +143,19 @@ func (p *Poly) ReadFrom(r io.Reader) (n int64, err error) { switch r := r.(type) { case buffer.Reader: - var hasQP byte var inc int64 - if inc, err = buffer.ReadUint8(r, &hasQP); err != nil { + + if inc, err = p.Q.ReadFrom(r); err != nil { return n + inc, err } n += inc - if hasQP&2 == 2 { - - if inc, err = p.Q.ReadFrom(r); err != nil { - return n + inc, err - } - - n += inc + if inc, err = p.P.ReadFrom(r); err != nil { + return n + inc, err } - if hasQP&1 == 1 { - - var inc int64 - if inc, err = p.P.ReadFrom(r); err != nil { - return n + inc, err - } - - n += inc - } + n += inc return diff --git a/utils/buffer/utils.go b/utils/buffer/utils.go index 386a242c..9d9e59dd 100644 --- a/utils/buffer/utils.go +++ b/utils/buffer/utils.go @@ -7,9 +7,11 @@ import ( "io" "reflect" "testing" + "unsafe" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" + "github.com/tuneinsight/lattigo/v4/utils" ) // binarySerializer is a testing interface for byte encoding and decoding. @@ -74,3 +76,118 @@ func RequireSerializerCorrect(t *testing.T, input binarySerializer) { // Deep equal output = input require.True(t, cmp.Equal(input, output)) } + +// EqualAsUint64 casts &T to an *uint64 and performs a comparison. +// User must ensure that T can be stored in an uint64. +func EqualAsUint64[T any](a, b T) bool { + /* #nosec G103 -- behavior and consequences well understood */ + return *(*uint64)(unsafe.Pointer(&a)) == *(*uint64)(unsafe.Pointer(&b)) +} + +// EqualAsUint64Slice casts &[]T into *[]uint64 and performs a comparison. +// User must ensure that T can be stored in an uint64. +func EqualAsUint64Slice[T any](a, b []T) bool { + + /* #nosec G103 -- behavior and consequences well understood */ + aU64 := *(*[]uint64)(unsafe.Pointer(&a)) + + /* #nosec G103 -- behavior and consequences well understood */ + bU64 := *(*[]uint64)(unsafe.Pointer(&b)) + + if len(aU64) != len(bU64) { + return false + } + + if utils.Alias1D(aU64, bU64) { + return true + } + + for i := range aU64 { + if aU64[i] != bU64[i] { + return false + } + } + + return true +} + +// EqualAsUint32Slice casts &[]T into *[]uint32 and performs a comparison. +// User must ensure that T can be stored in an uint32. +func EqualAsUint32Slice[T any](a, b []T) bool { + + /* #nosec G103 -- behavior and consequences well understood */ + aU32 := *(*[]uint32)(unsafe.Pointer(&a)) + + /* #nosec G103 -- behavior and consequences well understood */ + bU32 := *(*[]uint32)(unsafe.Pointer(&b)) + + if len(aU32) != len(bU32) { + return false + } + + if utils.Alias1D(aU32, bU32) { + return true + } + + for i := range aU32 { + if aU32[i] != bU32[i] { + return false + } + } + + return true +} + +// EqualAsUint16Slice casts &[]T into *[]uint16 and performs a comparison. +// User must ensure that T can be stored in an uint16. +func EqualAsUint16Slice[T any](a, b []T) bool { + + /* #nosec G103 -- behavior and consequences well understood */ + aU16 := *(*[]uint16)(unsafe.Pointer(&a)) + + /* #nosec G103 -- behavior and consequences well understood */ + bU16 := *(*[]uint16)(unsafe.Pointer(&b)) + + if len(aU16) != len(bU16) { + return false + } + + if utils.Alias1D(aU16, bU16) { + return true + } + + for i := range aU16 { + if aU16[i] != bU16[i] { + return false + } + } + + return true +} + +// EqualAsUint8Slice casts &[]T into *[]uint8 and performs a comparison. +// User must ensure that T can be stored in an uint8. +func EqualAsUint8Slice[T any](a, b []T) bool { + + /* #nosec G103 -- behavior and consequences well understood */ + aU8 := *(*[]uint8)(unsafe.Pointer(&a)) + + /* #nosec G103 -- behavior and consequences well understood */ + bU8 := *(*[]uint8)(unsafe.Pointer(&b)) + + if len(aU8) != len(bU8) { + return false + } + + if utils.Alias1D(aU8, bU8) { + return true + } + + for i := range aU8 { + if aU8[i] != bU8[i] { + return false + } + } + + return true +} diff --git a/utils/structs/matrix.go b/utils/structs/matrix.go index 22fe3a9a..50811fcc 100644 --- a/utils/structs/matrix.go +++ b/utils/structs/matrix.go @@ -5,14 +5,15 @@ import ( "fmt" "io" + "github.com/tuneinsight/lattigo/v4/utils" "github.com/tuneinsight/lattigo/v4/utils/buffer" ) // Vector is a struct wrapping a doube slice of components of type T. // T can be: -// - uint, uint64, uint32, uint16, uint8/byte, int, int64, int32, int16, int8, float64, float32. -// - Or any object that implements CopyNewer, CopyNewer, BinarySizer, io.WriterTo or io.ReaderFrom -// depending on the method called. +// - uint, uint64, uint32, uint16, uint8/byte, int, int64, int32, int16, int8, float64, float32. +// - Or any object that implements CopyNewer, CopyNewer, BinarySizer, io.WriterTo or io.ReaderFrom +// depending on the method called. type Matrix[T any] [][]T // CopyNew returns a deep copy of the object. @@ -170,10 +171,15 @@ func (m *Matrix[T]) UnmarshalBinary(p []byte) (err error) { // Equal performs a deep equal. // If T is a struct, this method requires that T implements Equatable. func (m Matrix[T]) Equal(other Matrix[T]) bool { - + var t T switch any(t).(type) { case uint, uint64, uint32, uint16, uint8, int, int64, int32, int16, int8, float64, float32: + + if utils.Alias2D[T]([][]T(m), [][]T(other)) { + return true + } + default: if _, isEquatable := any(t).(Equatable[T]); !isEquatable { panic(fmt.Errorf("matrix component of type %T does not comply to %T", t, new(Equatable[T]))) diff --git a/utils/structs/vector.go b/utils/structs/vector.go index 101527e1..2672b2d7 100644 --- a/utils/structs/vector.go +++ b/utils/structs/vector.go @@ -5,15 +5,14 @@ import ( "fmt" "io" - "github.com/google/go-cmp/cmp" "github.com/tuneinsight/lattigo/v4/utils/buffer" ) // Vector is a struct wrapping a slice of components of type T. // T can be: -// - uint, uint64, uint32, uint16, uint8/byte, int, int64, int32, int16, int8, float64, float32. -// - Or any object that implements CopyNewer, CopyNewer, io.WriterTo or io.ReaderFrom depending on -// the method called. +// - uint, uint64, uint32, uint16, uint8/byte, int, int64, int32, int16, int8, float64, float32. +// - Or any object that implements CopyNewer, CopyNewer, io.WriterTo or io.ReaderFrom depending on +// the method called. type Vector[T any] []T // CopyNew returns a deep copy of the object. @@ -258,8 +257,14 @@ func (v Vector[T]) Equal(other Vector[T]) (isEqual bool) { var t T switch any(t).(type) { - case uint, uint64, uint32, uint16, uint8, int, int64, int32, int16, int8, float64, float32: - return cmp.Equal([]T(v), []T(other)) + case uint, uint64, int, int64, float64: + return buffer.EqualAsUint64Slice([]T(v), []T(other)) + case uint32, int32, float32: + return buffer.EqualAsUint32Slice([]T(v), []T(other)) + case uint16, int16: + return buffer.EqualAsUint16Slice([]T(v), []T(other)) + case uint8, int8: + return buffer.EqualAsUint8Slice([]T(v), []T(other)) default: if _, isEquatable := any(t).(Equatable[T]); !isEquatable {