diff --git a/bls377/e12.go b/bls377/e12.go index 8b86054b7..b353b76ca 100644 --- a/bls377/e12.go +++ b/bls377/e12.go @@ -16,10 +16,6 @@ package bls377 -import ( - "github.com/consensys/gurvy/bls377/fp" -) - // E12 is a degree-two finite field extension of fp6: // C0 + C1w where w^3-v is irrep in fp6 @@ -135,20 +131,20 @@ func (z *E12) Mul(x, y *E12) *E12 { ySum.Add(&y.C0, &y.C1) // step 3 - { // begin: inline z.C0.MulByNonResidue(&t1) + { // begin inline: set z.C0 to (&t1) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&t1).B0) result.B2.Set(&(&t1).B1) - { // begin: inline result.B0.MulByNonResidue(&(&t1).B2) + { // begin inline: set result.B0 to (&(&t1).B2) * (0,1) buf := (&(&t1).B2).A0 - { // begin: inline MulByNonResidue(&(result.B0).A0, &(&(&t1).B2).A1) + { // begin inline: set &(result.B0).A0 to (&(&(&t1).B2).A1) * (5) buf := *(&(&(&t1).B2).A1) (&(result.B0).A0).Double(&buf).Double(&(result.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(result.B0).A0, &(&(&t1).B2).A1) + } // end inline: set &(result.B0).A0 to (&(&(&t1).B2).A1) * (5) (result.B0).A1 = buf - } // end: inline result.B0.MulByNonResidue(&(&t1).B2) + } // end inline: set result.B0 to (&(&t1).B2) * (0,1) z.C0.Set(&result) - } // end: inline z.C0.MulByNonResidue(&t1) + } // end inline: set z.C0 to (&t1) * ((0,0),(1,0),(0,0)) z.C0.Add(&z.C0, &t0) // step 4 @@ -168,20 +164,20 @@ func (z *E12) Square(x *E12) *E12 { b0.Square(&x.C0) b1.Square(&x.C1) - { // begin: inline b1.MulByNonResidue(&b1) + { // begin inline: set b1 to (&b1) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&b1).B0) result.B2.Set(&(&b1).B1) - { // begin: inline result.B0.MulByNonResidue(&(&b1).B2) + { // begin inline: set result.B0 to (&(&b1).B2) * (0,1) buf := (&(&b1).B2).A0 - { // begin: inline MulByNonResidue(&(result.B0).A0, &(&(&b1).B2).A1) + { // begin inline: set &(result.B0).A0 to (&(&(&b1).B2).A1) * (5) buf := *(&(&(&b1).B2).A1) (&(result.B0).A0).Double(&buf).Double(&(result.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(result.B0).A0, &(&(&b1).B2).A1) + } // end inline: set &(result.B0).A0 to (&(&(&b1).B2).A1) * (5) (result.B0).A1 = buf - } // end: inline result.B0.MulByNonResidue(&(&b1).B2) + } // end inline: set result.B0 to (&(&b1).B2) * (0,1) b1.Set(&result) - } // end: inline b1.MulByNonResidue(&b1) + } // end inline: set b1 to (&b1) * ((0,0),(1,0),(0,0)) b1.Add(&b0, &b1) z.C1.Mul(&x.C0, &x.C1).Double(&z.C1) @@ -200,20 +196,20 @@ func (z *E12) Inverse(x *E12) *E12 { t[1].Square(&x.C1) // step 2 { // step 3 var buf E6 - { // begin: inline buf.MulByNonResidue(&t[1]) + { // begin inline: set buf to (&t[1]) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&t[1]).B0) result.B2.Set(&(&t[1]).B1) - { // begin: inline result.B0.MulByNonResidue(&(&t[1]).B2) + { // begin inline: set result.B0 to (&(&t[1]).B2) * (0,1) buf := (&(&t[1]).B2).A0 - { // begin: inline MulByNonResidue(&(result.B0).A0, &(&(&t[1]).B2).A1) + { // begin inline: set &(result.B0).A0 to (&(&(&t[1]).B2).A1) * (5) buf := *(&(&(&t[1]).B2).A1) (&(result.B0).A0).Double(&buf).Double(&(result.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(result.B0).A0, &(&(&t[1]).B2).A1) + } // end inline: set &(result.B0).A0 to (&(&(&t[1]).B2).A1) * (5) (result.B0).A1 = buf - } // end: inline result.B0.MulByNonResidue(&(&t[1]).B2) + } // end inline: set result.B0 to (&(&t[1]).B2) * (0,1) buf.Set(&result) - } // end: inline buf.MulByNonResidue(&t[1]) + } // end inline: set buf to (&t[1]) * ((0,0),(1,0),(0,0)) t[0].Sub(&t[0], &buf) } t[1].Inverse(&t[0]) // step 4 @@ -235,194 +231,3 @@ func (z *E12) Conjugate(x *E12) *E12 { z.C1.Neg(&z.C1) return z } - -// MulByVW set z to x*(y*v*w) and return z -// here y*v*w means the E12 element with C1.B1=y and all other components 0 -func (z *E12) MulByVW(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - buf := (y).A0 - { // begin: inline MulByNonResidue(&(yNR).A0, &(y).A1) - buf := *(&(y).A1) - (&(yNR).A0).Double(&buf).Double(&(yNR).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(yNR).A0, &(y).A1) - (yNR).A1 = buf - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C1.B1, &yNR) - result.C0.B1.Mul(&x.C1.B2, &yNR) - result.C0.B2.Mul(&x.C1.B0, y) - result.C1.B0.Mul(&x.C0.B2, &yNR) - result.C1.B1.Mul(&x.C0.B0, y) - result.C1.B2.Mul(&x.C0.B1, y) - z.Set(&result) - return z -} - -// MulByV set z to x*(y*v) and return z -// here y*v means the E12 element with C0.B1=y and all other components 0 -func (z *E12) MulByV(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - buf := (y).A0 - { // begin: inline MulByNonResidue(&(yNR).A0, &(y).A1) - buf := *(&(y).A1) - (&(yNR).A0).Double(&buf).Double(&(yNR).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(yNR).A0, &(y).A1) - (yNR).A1 = buf - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C0.B2, &yNR) - result.C0.B1.Mul(&x.C0.B0, y) - result.C0.B2.Mul(&x.C0.B1, y) - result.C1.B0.Mul(&x.C1.B2, &yNR) - result.C1.B1.Mul(&x.C1.B0, y) - result.C1.B2.Mul(&x.C1.B1, y) - z.Set(&result) - return z -} - -// MulByV2W set z to x*(y*v^2*w) and return z -// here y*v^2*w means the E12 element with C1.B2=y and all other components 0 -func (z *E12) MulByV2W(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - buf := (y).A0 - { // begin: inline MulByNonResidue(&(yNR).A0, &(y).A1) - buf := *(&(y).A1) - (&(yNR).A0).Double(&buf).Double(&(yNR).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(yNR).A0, &(y).A1) - (yNR).A1 = buf - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C1.B0, &yNR) - result.C0.B1.Mul(&x.C1.B1, &yNR) - result.C0.B2.Mul(&x.C1.B2, &yNR) - result.C1.B0.Mul(&x.C0.B1, &yNR) - result.C1.B1.Mul(&x.C0.B2, &yNR) - result.C1.B2.Mul(&x.C0.B0, y) - z.Set(&result) - return z -} - -// MulByV2NRInv set z to x*(y*v^2*(0,1)^{-1}) and return z -// here y*v^2 means the E12 element with C0.B2=y and all other components 0 -func (z *E12) MulByV2NRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - buf := (y).A1 - { // begin: inline MulByNonResidueInv(&(yNRInv).A1, &(y).A0) - nrinv := fp.Element{ - 330620507644336508, - 9878087358076053079, - 11461392860540703536, - 6973035786057818995, - 8846909097162646007, - 104838758629667239, - } - (&(yNRInv).A1).Mul(&(y).A0, &nrinv) - } // end: inline MulByNonResidueInv(&(yNRInv).A1, &(y).A0) - (yNRInv).A0 = buf - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C0.B1, y) - result.C0.B1.Mul(&x.C0.B2, y) - result.C0.B2.Mul(&x.C0.B0, &yNRInv) - - result.C1.B0.Mul(&x.C1.B1, y) - result.C1.B1.Mul(&x.C1.B2, y) - result.C1.B2.Mul(&x.C1.B0, &yNRInv) - - z.Set(&result) - return z -} - -// MulByVWNRInv set z to x*(y*v*w*(0,1)^{-1}) and return z -// here y*v*w means the E12 element with C1.B1=y and all other components 0 -func (z *E12) MulByVWNRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - buf := (y).A1 - { // begin: inline MulByNonResidueInv(&(yNRInv).A1, &(y).A0) - nrinv := fp.Element{ - 330620507644336508, - 9878087358076053079, - 11461392860540703536, - 6973035786057818995, - 8846909097162646007, - 104838758629667239, - } - (&(yNRInv).A1).Mul(&(y).A0, &nrinv) - } // end: inline MulByNonResidueInv(&(yNRInv).A1, &(y).A0) - (yNRInv).A0 = buf - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C1.B1, y) - result.C0.B1.Mul(&x.C1.B2, y) - result.C0.B2.Mul(&x.C1.B0, &yNRInv) - - result.C1.B0.Mul(&x.C0.B2, y) - result.C1.B1.Mul(&x.C0.B0, &yNRInv) - result.C1.B2.Mul(&x.C0.B1, &yNRInv) - - z.Set(&result) - return z -} - -// MulByWNRInv set z to x*(y*w*(0,1)^{-1}) and return z -// here y*w means the E12 element with C1.B0=y and all other components 0 -func (z *E12) MulByWNRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - buf := (y).A1 - { // begin: inline MulByNonResidueInv(&(yNRInv).A1, &(y).A0) - nrinv := fp.Element{ - 330620507644336508, - 9878087358076053079, - 11461392860540703536, - 6973035786057818995, - 8846909097162646007, - 104838758629667239, - } - (&(yNRInv).A1).Mul(&(y).A0, &nrinv) - } // end: inline MulByNonResidueInv(&(yNRInv).A1, &(y).A0) - (yNRInv).A0 = buf - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C1.B2, y) - result.C0.B1.Mul(&x.C1.B0, &yNRInv) - result.C0.B2.Mul(&x.C1.B1, &yNRInv) - - result.C1.B0.Mul(&x.C0.B0, &yNRInv) - result.C1.B1.Mul(&x.C0.B1, &yNRInv) - result.C1.B2.Mul(&x.C0.B2, &yNRInv) - - z.Set(&result) - return z -} - -// MulByNonResidue multiplies a E6 by ((0,0),(1,0),(0,0)) -func (z *E6) MulByNonResidue(x *E6) *E6 { - var result E6 - result.B1.Set(&(x).B0) - result.B2.Set(&(x).B1) - { // begin: inline result.B0.MulByNonResidue(&(x).B2) - buf := (&(x).B2).A0 - { // begin: inline MulByNonResidue(&(result.B0).A0, &(&(x).B2).A1) - buf := *(&(&(x).B2).A1) - (&(result.B0).A0).Double(&buf).Double(&(result.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(result.B0).A0, &(&(x).B2).A1) - (result.B0).A1 = buf - } // end: inline result.B0.MulByNonResidue(&(x).B2) - z.Set(&result) - return z -} diff --git a/bls377/e12_test.go b/bls377/e12_test.go index 793202e08..fd8da8d2a 100644 --- a/bls377/e12_test.go +++ b/bls377/e12_test.go @@ -8,7 +8,7 @@ import ( type E12TestPoint struct { in [2]E12 - out [17]E12 + out [11]E12 } var E12TestPoints []E12TestPoint @@ -77,60 +77,36 @@ func TestE12Mul(t *testing.T) { E12check(t, (*E12).Mul, 2) } -func TestE12MulByV(t *testing.T) { - E12check(t, (*E12).MulByVBinary, 3) -} - -func TestE12MulByVW(t *testing.T) { - E12check(t, (*E12).MulByVWBinary, 4) -} - -func TestE12MulByV2W(t *testing.T) { - E12check(t, (*E12).MulByV2WBinary, 5) -} - -func TestE12MulByV2NRInv(t *testing.T) { - E12check(t, (*E12).MulByV2NRInvBinary, 6) -} - -func TestE12MulByVWNRInv(t *testing.T) { - E12check(t, (*E12).MulByVWNRInvBinary, 7) -} - -func TestE12MulByWNRInv(t *testing.T) { - E12check(t, (*E12).MulByWNRInvBinary, 8) -} - func TestE12Square(t *testing.T) { - E12check(t, (*E12).SquareBinary, 9) + E12check(t, (*E12).SquareBinary, 3) } func TestE12Inverse(t *testing.T) { - E12check(t, (*E12).InverseBinary, 10) + E12check(t, (*E12).InverseBinary, 4) } func TestE12Conjugate(t *testing.T) { - E12check(t, (*E12).ConjugateBinary, 11) + E12check(t, (*E12).ConjugateBinary, 5) } func TestE12Frobenius(t *testing.T) { - E12check(t, (*E12).FrobeniusBinary, 12) + E12check(t, (*E12).FrobeniusBinary, 6) } func TestE12FrobeniusSquare(t *testing.T) { - E12check(t, (*E12).FrobeniusSquareBinary, 13) + E12check(t, (*E12).FrobeniusSquareBinary, 7) } func TestE12FrobeniusCube(t *testing.T) { - E12check(t, (*E12).FrobeniusCubeBinary, 14) + E12check(t, (*E12).FrobeniusCubeBinary, 8) } func TestE12Expt(t *testing.T) { - E12check(t, (*E12).ExptBinary, 15) + E12check(t, (*E12).ExptBinary, 9) } func TestE12FinalExponentiation(t *testing.T) { - E12check(t, (*E12).FinalExponentiationBinary, 16) + E12check(t, (*E12).FinalExponentiationBinary, 10) } //--------------------// @@ -157,42 +133,6 @@ func BenchmarkE12Mul(b *testing.B) { } } -func BenchmarkE12MulByV(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByVW(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVWBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByV2W(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByV2WBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByV2NRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByV2NRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByVWNRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVWNRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByWNRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByWNRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - func BenchmarkE12Square(b *testing.B) { for i := 0; i < b.N; i++ { E12BenchOut.SquareBinary(&E12BenchIn1, &E12BenchIn2) @@ -292,45 +232,3 @@ func (z *E12) ExptBinary(x, y *E12) *E12 { return z } - -// MulByVBinary a binary wrapper for MulByV -func (z *E12) MulByVBinary(x, y *E12) *E12 { - yCopy := y.C0.B1 - z.MulByV(x, &yCopy) - return z -} - -// MulByVWBinary a binary wrapper for MulByVW -func (z *E12) MulByVWBinary(x, y *E12) *E12 { - yCopy := y.C1.B1 - z.MulByVW(x, &yCopy) - return z -} - -// MulByV2WBinary a binary wrapper for MulByV2W -func (z *E12) MulByV2WBinary(x, y *E12) *E12 { - yCopy := y.C1.B2 - z.MulByV2W(x, &yCopy) - return z -} - -// MulByV2NRInvBinary a binary wrapper for MulByV2NRInv -func (z *E12) MulByV2NRInvBinary(x, y *E12) *E12 { - yCopy := y.C0.B2 - z.MulByV2NRInv(x, &yCopy) - return z -} - -// MulByVWNRInvBinary a binary wrapper for MulByVWNRInv -func (z *E12) MulByVWNRInvBinary(x, y *E12) *E12 { - yCopy := y.C1.B1 - z.MulByVWNRInv(x, &yCopy) - return z -} - -// MulByWNRInvBinary a binary wrapper for MulByWNRInv -func (z *E12) MulByWNRInvBinary(x, y *E12) *E12 { - yCopy := y.C1.B0 - z.MulByWNRInv(x, &yCopy) - return z -} diff --git a/bls377/e12testpoints_test.go b/bls377/e12testpoints_test.go index 7ac88389b..1bd05a766 100644 --- a/bls377/e12testpoints_test.go +++ b/bls377/e12testpoints_test.go @@ -18,172 +18,118 @@ func init() { E12TestPoints[0].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[0].out[9].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[0].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[15].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[16].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].in[0].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[0].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[1].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[9].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[10].SetString("0", "0", "0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[11].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[12].SetString("0", "0", "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[13].SetString("0", "0", "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[14].SetString("0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[15].SetString("0", "0", "85826770384498279333594143312121361780122930237299080593732639699090058806487494408017449052910956686849489676400", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[3].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[4].SetString("0", "0", "0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[5].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[6].SetString("0", "0", "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[7].SetString("0", "0", "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[8].SetString("0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[9].SetString("0", "0", "85826770384498279333594143312121361780122930237299080593732639699090058806487494408017449052910956686849489676400", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].in[0].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[0].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[1].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[9].SetString("0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[10].SetString("0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[11].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[12].SetString("0", "0", "0", "0", "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[13].SetString("0", "0", "0", "0", "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[14].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[15].SetString("0", "0", "0", "0", "33096321634486825016800384912644334428799442496163195904880778081164963317531839288400192719007369651588186631882", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[3].SetString("0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[4].SetString("0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[5].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[6].SetString("0", "0", "0", "0", "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[7].SetString("0", "0", "0", "0", "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047231", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[8].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[9].SetString("0", "0", "0", "0", "33096321634486825016800384912644334428799442496163195904880778081164963317531839288400192719007369651588186631882", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[3].in[0].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[3].out[0].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].out[1].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[9].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271") - E12TestPoints[3].out[11].SetString("0", "0", "0", "0", "0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0", "0", "0", "0", "0") - E12TestPoints[3].out[12].SetString("0", "0", "0", "0", "0", "0", "92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353", "0", "0", "0", "0", "0") - E12TestPoints[3].out[13].SetString("0", "0", "0", "0", "0", "0", "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946", "0", "0", "0", "0", "0") - E12TestPoints[3].out[14].SetString("0", "0", "0", "0", "0", "0", "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499", "0", "0", "0", "0", "0") - E12TestPoints[3].out[15].SetString("0", "0", "0", "0", "0", "0", "175675437591379430441374949575352522030907415996300783409227081411669559795924327950121622662760046728935761998864", "0", "0", "0", "0", "0") - E12TestPoints[3].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[3].out[3].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[3].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271") + E12TestPoints[3].out[5].SetString("0", "0", "0", "0", "0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0", "0", "0", "0", "0") + E12TestPoints[3].out[6].SetString("0", "0", "0", "0", "0", "0", "92949345220277864758624960506473182677953048909283248980960104381795901929519566951595905490535835115111760994353", "0", "0", "0", "0", "0") + E12TestPoints[3].out[7].SetString("0", "0", "0", "0", "0", "0", "80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946", "0", "0", "0", "0", "0") + E12TestPoints[3].out[8].SetString("0", "0", "0", "0", "0", "0", "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499", "0", "0", "0", "0", "0") + E12TestPoints[3].out[9].SetString("0", "0", "0", "0", "0", "0", "175675437591379430441374949575352522030907415996300783409227081411669559795924327950121622662760046728935761998864", "0", "0", "0", "0", "0") + E12TestPoints[3].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[4].in[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[4].out[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].out[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[9].SetString("0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271", "0", "0") - E12TestPoints[4].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0", "0", "0") - E12TestPoints[4].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499", "0", "0", "0") - E12TestPoints[4].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0", "0", "0") - E12TestPoints[4].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678", "0", "0", "0") - E12TestPoints[4].out[15].SetString("0", "0", "0", "0", "0", "0", "0", "0", "255373455359566129419803036020222586280158932252885898023643168329183911473973279915579996482738265311713324062077", "0", "0", "0") - E12TestPoints[4].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[4].out[3].SetString("0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[4].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271", "0", "0") + E12TestPoints[4].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0", "0", "0") + E12TestPoints[4].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499", "0", "0", "0") + E12TestPoints[4].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0", "0", "0") + E12TestPoints[4].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "42198664672744474621281227892288285906241943207628877683080515507620245292955241189266486323192680957485559243678", "0", "0", "0") + E12TestPoints[4].out[9].SetString("0", "0", "0", "0", "0", "0", "0", "0", "255373455359566129419803036020222586280158932252885898023643168329183911473973279915579996482738265311713324062077", "0", "0", "0") + E12TestPoints[4].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[5].in[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[5].out[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].out[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[9].SetString("0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271", "0", "0", "0", "0") - E12TestPoints[5].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0") - E12TestPoints[5].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146", "0") - E12TestPoints[5].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232", "0") - E12TestPoints[5].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499", "0") - E12TestPoints[5].out[15].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "77009225163774313665994591608509276738131780581789411263293065047047354674988700073217157111377492952134108920541", "0") - E12TestPoints[5].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[5].out[3].SetString("0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0") + E12TestPoints[5].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "103465770405187637604261093477957413414557405101965864215953705066688187339336329109987555255829344049776128583271", "0", "0", "0", "0") + E12TestPoints[5].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458176", "0") + E12TestPoints[5].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "123516416119946754630746545296132064952198520638002533875843642777304321125866014634106496325844844051843001220146", "0") + E12TestPoints[5].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "258664426012969093929703085429980814127835149614277183275038967946009968870203535512256352201271898244626862047232", "0") + E12TestPoints[5].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499", "0") + E12TestPoints[5].out[9].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "77009225163774313665994591608509276738131780581789411263293065047047354674988700073217157111377492952134108920541", "0") + E12TestPoints[5].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[6].in[0].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "19375457018642844301720185311533848811236389564892653381994577433448441544971062787207105694393175081766384230069", "103771508188070009627499940464911310732394576306035423422297756896655508034653708912944278823540696278949871355887", "250165039921671105386185524955996623500990391272947239778635104298220330173670202154310129477613250625677474501325", "1603994068982978513824427306179569411324111885745241417076330262145198119786398635256432376922652384312965190574", "78928072115282771090692033563557763137202832505013876316815849201533287367104934382087204469053100909180676965898", "258214674837126740892061187620429216247498204557471919074813399218714979694473981536167332821797980756055399858189", "229789566606445764868605117970988775064247067150636537603508873503537245730434782467161671557174631503332791573382", "144415167871022086485901521749824249250833128730160416247848332762731457771998135106625002843240488967898685674401", "18872619621747221810879014336829128554514465494422620274224837531294334197812273920165238809690713355107802954963", "149622723941569753334859560910752326380625917859677755463192188301997911450970692608425783550901970295677647890820", "15389471032318411034004677539630528100696758364201995928344315387817899494081856365360518132918391301234388699198") E12TestPoints[6].in[1].SetString("24714582652642763630854396786219197867114100418570062837645863466708760679847438857489413764974322435576898366883", "43057512337602972264994144333739862668968156833350565199858941378006902312448315626224397015505451266912808424445", "22937429414966854388907956960452114845654554159797130528839904576184596522139537218281729454351309624749341417159", "154779710743074601230835161510919184472916933600144598024836523033981078603609557461057374016181379526844433411338", "74570814209135670130664531724299075479007884253547655777143224102928760553397754551960093524540836841435539160184", "200353701801897393415474560474171618169704876251434593858814628067971264769742084240626895459059010351550983331724", "218535725791666403948609708461678402391065746223757697173515749782633153815681141602323414044047963363467153661065", "232286797896950404486856341762741862818620445009502966700685718458944682738916033200107099824611489434824774509044", "14368060357469034156675853896285378227920497328664507055707537943376556125921199379352228453841540110020969290520", "54718822437885112750036833992071853717521874310868236978787815165404295845071141360893412471622486888001037423159", "208362466459162768690249736407713037568252820478729798065522651323769115546144590082812853501631663075697567919703", "171468371711697947999622231884187384729690095803722810920740903787072473574840840555677148816898767051747815624272") E12TestPoints[6].out[0].SetString("83898525032300299923621491086637908487153750874133294486782126008217121999241173656395369424872267610610039881994", "62432969356245816566714329645273711480204546398243218581853518811455343857419378413431502709898626348679192654514", "126708937603036864016407897425363425578049130465832553951137661472840104556793246131226008277892005903699212773046", "146280324651776612606367952772022274437513812118177177263587364665480940428938936840398615354221270028081586454486", "76174808278118648644488959030478644890331996139292897194219554365073958673184153187216525901463489225748504350758", "20617347904211070495513860342835847770514196001533809635746214602784083788506195847745211788538751136291338839445", "218085974615824050830018162387214085102170438026314955708444886334627665161814300363521858726272583995082232061077", "203411938490427075344808726038837104346473999405224843764310329295761460121009992892299883242212760813717244624249", "158783228228491120642577375646109627478753626058824923303555870706108013897919334485977231297082029077919654964921", "73591442059632334560915848328900982272036339805290857253012652696698630042883415281058651281313200243108840378122", "99320764387763428014456563623571830412485225583492892988830576959046558648774459916269748912960273246934894352346", "186857842744016359033626909423817912830386854167924806849085219174890373068922696921037666949817158352982204323470") E12TestPoints[6].out[1].SetString("34469359727014772661912697514199512752925550036993168811490399074799600639546295941416541894923622739456243148228", "234982370694008966047378774672687519678661745486456748722019898722162007580863569935951596818461083939293897263801", "80834078773103155238591983504459195886740022146238292893457852320470911512514171694662549369189386654200529938728", "95385329178596504155350363445077439028073457672802641753798581264239251570060644693252755461431871098833041089987", "185697605872816402393812629276774027468709740387112246179817368825936905914729466858265226991955175667317747488567", "137238796326354471685870206784279678503891469008493942997885483800282490945703672916429197149567450682070015092351", "39678949045460336943451479158750813856432458333714221901297649436081825878792839933843918777750017392588246197124", "256167194722464454392401509903140445782020134896048231442707417711313031339859572042023459872136502192948338522515", "130047107513553052329225667853538871022912631401495909192140794819354901646076935727272774389398948857877716383881", "222818223196831203071494914039650808373386103938469043835321285032610506701081955334240714477641586591547086989981", "199924683495376078655262558197932822348766610135862617937553799644949264253166925300581818188843667344420401429294", "102585525333589557045035179350336676907400175315393845547487674267465894267581838584652257455592984373926894533103") E12TestPoints[6].out[2].SetString("150341768339539410750661905708859675720123162880175549943840140682850835539167411574962057901114294618313813675385", "215198892500407925468789539438486928894049389012710064410890833944335571152415438215228318313541796871966471555847", "11969230357122864345494324760670474259785786354242625738763523215032064152110572058206474143110281675268083681118", "185960392697654879428169893537563596408724844186590278816342045333660524611353369838998730659436983719394135840228", "108916022601309955628116346017061261583983364503802787807142198052318855598877284015522191734197792984273010721330", "34694803377852272165026077343560190023853485322074765841195894170985205230070622680255716871883136024911327510616", "258024306965136549867979326385436413636324422197758211779855296060058216274435334442264598926652685813440761864310", "171787738547553289535938351171674537684993759764538259785591505703559513863389084207750576615901569626269363993970", "190286245776172364493355116230854434902213549284789513513299953022698962615122633825759063367166671865094331865481", "196836564549025753546460949125751516436679879850971242487236041478285844900581052057117868716956001475231475446740", "219261618168157468314556152391022013454994476080172219723874815412460076000226843364946666436441407027977433177948", "75700862010943141806706886013618784586031001371691082401292227774264695675456710089357457827040814080856182028946") - E12TestPoints[6].out[3].SetString("183645607779503113379101579831612481202867837863449779342342878546386357283317696500640349946277204832591931529940", "43470131423219075503368390090788998034903461291284544837787381713691609860149067340547365237256224661056228536819", "137978608706315426588706254305738520146304279185289010980576568546634235345171922710968670926190152369323685062936", "31972321956631898734588773070829425705581933065608046034429000504822140122500620979010239769146027915412113656893", "133935401948813277071727758352573398418007941276801222900223709466179172121028378055965342098149075220964547004859", "101365663661771362191710632440751000534973166258561638163115918665770860149131988951541014901633949870399291681683", "218296379202777762193030453699361374208216541957815076394992440856827460490947918383786032620132362860224173214887", "182030183180105959026967548524033243977632559337843647377037113163959972613338830094865775612840486166298735383286", "220381338731857499158450444237242429521040356879090772492746297828928110240111000955838417496915788570842184877274", "239075172500070852915064753562090814143085440453926823714923586387466906447588143482056883624822533089605478223269", "254507051333626136451016595322699554735023313779437518326630419283588944988056754465032148169163200383345213010254", "246107602602273346279477671727821229213183146375678664297512839145076957216686973651219081213379806781998327450466") - E12TestPoints[6].out[4].SetString("2757428956482725412728993379131962442678482860953371694383693223168077855614783423491046884207412514189406309975", "124042121582168494396320698388727750951549968248930143359062257660442302376024732661737886558945618528076770243646", "3752105814272016225597312946223635691745961350875998264957159368479232877049832647368435851725429001675184114320", "32223945110526088302706222673475510080289362743955569717121122119157386756527666865689461520800802324183670803882", "233191800395368994830562687789452575672826909105169594453861802677757622773011856083604501225068501839604905541631", "35269105200618965956796770674690209671136563471500550312537366183976584082632334583837757312424628952098066672614", "204802095067542062307289430611733559964186173856603677400283963610972370657280735434111589587761851663363875032800", "175045244552878788781828407326687641103739250621466119634947191514689415895964290584369849278320106898487115501494", "90130985399848448027509688435630559794421791576337128886267713619688089286304557019473083070407188209528411461514", "9100860058137438757288287098883869208679536545156909227424957261302454190939822820927484909391032606206520484831", "238861694860458891529862414633728459972237517026679976206123306944898025477762816444507639283092033968651373216108", "51290824718424139807629244214522153801409058283969675680101042105266993849548795966098378254670907259921731602666") - E12TestPoints[6].out[5].SetString("182549654893615937629047430831363975452526695739498315139978135750820465205744147492666285934507337363351604239695", "98189832097748672941483255661194048200052272869386977228753952215276357557906090888334885714719612121117636422104", "62801236813887346640976647034499875470892670649510239690913062439926859689934937746681373300617914384416773062775", "155586153074997517870975634246136774046440865252972971163025556105740419590684538102785079366948744759036306143162", "70848671149799362248871906559281125182701837610637621923109829747480596628991573880830205474061734009251896948631", "213037047311677214293350533091140607639932446859251124465854861524540105519285005829009125995724609447600851645860", "57166849733644644713640266704312912492105680886873160057376969701687328614900095344074078507846006382729845670741", "31182977447278189101501473570269458425326197200162004326665865382304469935628995680533527269479806754431781657064", "72074597957425516073027112537263316409284206982661368246388344091457296327829434127756329379068567554530328774574", "65575274879800287598229434366998228126704603027456265606305032803461805312379049850287192057705016593510474130732", "51509496241864100028882932757676110278459552463044891392563973563057205134107864223979714907502380077119476343213", "237165788054242126955304770069893813657301843651076784040771443686197765819227322070838149189790992189377646120579") - E12TestPoints[6].out[6].SetString("85558734733796584335446287522614250049687072412476311652206129427651366220284747228143560654915760082919276206185", "168131894029753386128815577125428199715492127996595223707904199444539269864737009384549705268922310561548012897484", "36088433559321518296931422854112729254910517049705749771800440739492221071621764162746591481450217384962034569357", "183350262612457493769570384460676424333658349642710850685987101709248097055970654619739634211149704247387487762405", "79601191092532091784402567723862164620972913238152949269455307145968489682057171524374427321111078315986132688246", "215499625860652668903026737876001434937584731575103282364203603144471992140480420363302488358725590942135491203628", "43670139508936160663012029933498981442185589735514520302390336921518090172049042440794537833303257972474681735318", "102114183561404712807687711903599883863318532214547620233455526165479180018876462181394174555312762123986032843201", "68702629255658429674704516658691815864854717522077975416122213560711092744511464219920335530378023125374719168472", "84676523383285621704200079311496308558015799665802190455542207478791924554356525114408894059173140102194952337597", "11406669838202468887850198448339180512803716246946369198586139703758865942576196880406390944439881679235462562428", "247331241360781745797043133192620229569838234127155946871402859654914175525487140038815923544870537748753545297099") - E12TestPoints[6].out[7].SetString("124042121582168494396320698388727750951549968248930143359062257660442302376024732661737886558945618528076770243646", "551485791296545082545798675826392488535696572190674338876738644633615571122956684698209376841482502837881261995", "32223945110526088302706222673475510080289362743955569717121122119157386756527666865689461520800802324183670803882", "750421162854403245119462589244727138349192270175199652991431873695846575409966529473687170345085800335036822864", "35269105200618965956796770674690209671136563471500550312537366183976584082632334583837757312424628952098066672614", "150104130484261436570373631035847928549122786922999783106726065602239711893938700326708455500843044417697109691597", "175045244552878788781828407326687641103739250621466119634947191514689415895964290584369849278320106898487115501494", "40960419013508412461457886122346711992837234771320735480056792722194474131456147086822317917552370332672775006560", "9100860058137438757288287098883869208679536545156909227424957261302454190939822820927484909391032606206520484831", "173224852687751146011893577904062232080720465968216222101184100323969898866265405068875949497825453716569875167209", "51290824718424139807629244214522153801409058283969675680101042105266993849548795966098378254670907259921731602666", "99505224174685597108103029665724398701726205956318927349201513922323698765220727843895305484533078818618338934857") - E12TestPoints[6].out[8].SetString("119771574764644759819584398442465944396580575477586107388566552950676621666638978170110442455064425897650074614973", "140736138249469894308366197808912644617701169123779679375746903681208689789963750149534483140346571879511869916560", "119547528060091194269959931264960077741524536953351347922904554030036187403812043508457514337905778469955963343566", "127594346243403776128085168523833379571988810680869108732796046761443056453687003291119867292195168695323361127391", "163415564418845932926979158711363436505902796944944246993727878240120598778432153667615660391953133904959110811780", "57513538903356271430020313349389024531678309874898986067111312752541850772534819092911281529109899700630313845629", "177679503289830061353852364664552517240137648928747099336449029278490376547627941005339948726773331130082153140009", "128136252068771007306509287475508625552914774495639314369782259979847450938110396772455435501245962974395876752428", "96151811712322458755884300970942577829495157107273519976986216256699909817063636356639490852763506608176369048488", "123597366157423450629285767281686203696572817305714082914795403961721877422709987351647594327966829738934201083466", "38707506224748672762791580883587557562462651551163000029977714309347746750250647869814760103035518170116183285436", "22409024922660745374756267089868487610715811363997131607925536867472147306774844036526005979508171123539884254324") - E12TestPoints[6].out[9].SetString("124688422512795936456708399705275209853789175200861408277903413846071674795895264413049738053841007850625383702647", "239250479947312154785351644973796602076703044673993844401091668696831004140352074657976973096385850110050824777319", "62521737401229278098497080446998853806751248198702740367301972544792470808146326924023805723757604617996669551598", "153985447048077493548668838817600467034570946409387870969344533537810058952866714147209449604994290781657942749580", "42820958806379661570848377612061602040087872603170328810728536047188435404076249224172072760715174700731543352274", "36197274374003999202607270804045272440771433193695183530438794582504388990414824550047812838859575535079850283534", "182324423848175793717062357440304592501362625781250537185788200188566795896146554185790257127996759433414816770547", "61066221324330412988150635976148096164383323527565931212872916388622708425981116266981677534725439544612294292205", "193798006893698060200817520807878287731485660210656270801821143742107051616114691614710086364930465548371541589996", "245011752487891073364680516477735558401260109560332069831969474253034979248393896398352140779318988447564217170213", "19708135802172865831342656301560112527100892889562936491427868456017597088441579445862347011839159337787105054474", "62050959311744813557589836252123360364128411774655235236018651678280800989097061220415482344763887023091730293446") - E12TestPoints[6].out[10].SetString("75227345136185367752864027592594931579969210641440067220120091254780033481135648173450360943439540689379458618696", "82378852490683324412381925418587302173456187788917531981097359472206492009293971232309259127983433792115349382116", "69280145376908157278094869555250082169689369609252106160378153488036709636279756483429772593224360885970990685705", "106127332579964371312871400889890854385614084568250132046203150307168014300024973974723966255523403606036369889671", "24601768921162180097584068042981971479268037248841675554049198126018601890021328825367782119199065583725195049728", "11035754604556842910717414257332715248161037396529107058676604572911859498939829043168665916141282318974169447450", "168232929140932193180864891018240652761687316638776750079802373913564312326178914556782582542138861314317483456884", "240378082002344320717778346662499875038922086248795171599598233973303660373415038169453529953967063140217211874801", "83718387963722440052198050138858438438626290996115104685372653052635914571367774233612889980889149329037902400708", "179922008026434513424730397605516499012263660830041667692766913437568296297369344940384045684060186660979381175544", "86212193053238006694151824529826999924692894679308306555833813323537847011114600839293547773041710593900997531139", "155824603647459994042402083709900978918251380110622643974117439901904121970864511052330169690852532901297637208986") - E12TestPoints[6].out[11].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "19375457018642844301720185311533848811236389564892653381994577433448441544971062787207105694393175081766384230069", "103771508188070009627499940464911310732394576306035423422297756896655508034653708912944278823540696278949871355887", "250165039921671105386185524955996623500990391272947239778635104298220330173670202154310129477613250625677474501325", "1603994068982978513824427306179569411324111885745241417076330262145198119786398635256432376922652384312965190574", "78928072115282771090692033563557763137202832505013876316815849201533287367104934382087204469053100909180676965898", "449751175842353118591546074464317288895308197442741465070863448005488653866841238801555317775379368384921599988", "28874859406523329142047615723904758472146445604278122936375389163183222617906040307807216582398728621107529884795", "114249258141947007524751211945069284285560384024754244292035929903989010576342687668343885296332871156541635783776", "239791806391221872199773719358064404981879047260492040265659425135426134150528548854803649329882646769332518503214", "109041702071399340675793172784141207155767594895236905076692074364722556897370130166543104588671389828762673567357", "243274954980650682976648056155263005435696754390712664611539947278902568854258966409608370006654968823205932758979") - E12TestPoints[6].out[12].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "239288968994326249708932548383359684725157123190022007157889685233272026803369759987761782445180185042673937228108", "106757314754294643142446121004775304176318293916316402642094157339192976717876133726204774288950019159487032917844", "220182790029135881551287969844320686716229355341872410316694244521407385678706051890601331858565041829001526757393", "251338436075205183238647376190648586180381185401813597427279051726841743319148157758583717346365400514927388544653", "228195715308204041980125659376616567028025333858977587223848084731213671208822874009381910735883161779689554281506", "216188940499926479252058131101970770024423258985077655765899728033071879710154858595867704393009285914820588291171", "210973204530131649610740983246324341691438249321193232381496308523201548120782801481857012818328883737917151983166", "44484882098409443598108768796828444013647234365477541588583696526436019981343142636081205623966794954612938884251", "206237025222213209341188436291076512375764588638401648378558634451602815677459745062491198092783423487162297015715", "202108272998140650712586313210445535452842787240636268709478173683399870996662104640846600557166811742339174714761", "204312454076627858969467381567003536424855063991868777647697002758382790322551019293360761708402876957722538513585") - E12TestPoints[6].out[13].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "19375457018642844301720185311533848811236389564892653381994577433448441544971062787207105694393175081766384230069", "2985806566224633514946180539863993443923717610280979219796400442537468683222424813260495465409322880537161561957", "46981022075131201083831972589469756855567278895009670984439176513813220844305391505026314942968427794201641657636", "5721995868780932258180930198065377944688215467355821695528880677733526909406266381128738416285307225199967722950", "149267643192921270889433625813058803890822501353963710907032235529680383841717939627294706266830060870508877315608", "85336695179750167742186079536020753588124042616618041742734199314338398108087262773461342028444594698661727695656", "80561431934580118152023707227688359396970445350517352130807516278783631874985904221698199891753213356067905617086", "114249258141947007524751211945069284285560384024754244292035929903989010576342687668343885296332871156541635783776", "239791806391221872199773719358064404981879047260492040265659425135426134150528548854803649329882646769332518503214", "181079595740359320551644068677273383911203486428453365858503281905191852474597275529501328267518111944897157582112", "120072138556213582369184835793751637970722081468593273304559267728140945517049009361579808779032040558082504517556") - E12TestPoints[6].out[14].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "239288968994326249708932548383359684725157123190022007157889685233272026803369759987761782445180185042673937228108", "154892917824899084383152793229982222803998936448879237117586505770064960313687113862024609316032663845490450102290", "250165039921671105386185524955996623500990391272947239778635104298220330173670202154310129477613250625677474501325", "1603994068982978513824427306179569411324111885745241417076330262145198119786398635256432376922652384312965190574", "179736353897686322919960700131335770399190680249900784223068413465187180981235888392881683670520259215259644492279", "141911995957506039700215639494217518892769781451483006870507554199280150790163669841694211232971258038215172973438", "76522440126650653000416363830521560355621874600534317260440430480784167488301832305228674491149610076983186588436", "214179543914559650412543964898065089522746278389437118951300566140284448366997680138887682515606565169827382573926", "52427400790755884669464297403817021160628924116513012161325628215117652670881077712477690046789936637278024442462", "238046944047644634587780291134954198310939085143631114549597022973113145984526642364513215607690078813971073392053", "61673004312618642160705603777671439111871036604892258066775118744340952142312940186966919119213293395837961267032") - E12TestPoints[6].out[15].SetString("90327798324835028117977656131006943414462339309117286606307088196329111047203832838598530383642653875649497766397", "225313479407404839464284283743838686937856224779598818657578421328969217628492304803965540068419972940860934784394", "97027948980150264315893791207930658471848945503806485319504420829739629005139964757597988081221561118469666141726", "82650253512100551587828643714125124800302763673502237954589645918303075899832917017927597930595206534755951406553", "2271502996833724954983011895405519451642083374462173671504288039365925197046116002629340362652129174635184149804", "175518680877823830373388322274092094751114522616100557037420768478366754338841438356387976731839910296358307910161", "175191735733900136841306402568785014544827024306606961820288166075115326894327868093171011067693875804685582256932", "156346492396714830410675271266989387998956968203417075800093296148184406313109326580446257298336443129238551545363", "182592530197235587461535561904686723779562928397937828351428381726242757688484796455186632136038769260486519101380", "98226164481584647393137681721139274526546241587415571392551305230013443668402604273262418316093945628689740735524", "81750151959045783189707094388477247204415326344795159348916645353908974968872834180322415641682488135437168557844", "69007680801020040044228130298023123341395629362167362382856137215687894930858501803407962527257817280036436884415") - E12TestPoints[6].out[16].SetString("10819526752076968042884504255886380643984419015528695690052071521621245986316533463331518924262731624324722327146", "181866505350649341241718897361090354793656826178898895772478333483195153326218771801099789256033519692419953803682", "64293819904885125041016175394474891707017018803364832097270719737006096029834838626095792678822601961956614854977", "105634064661097249920253287592394193905902038763664257424594695566004606696531742556459332779014648038494350751879", "62906702048314223645829181757894812013413201252797957637665336892134110967551759256496528543391444019254365158204", "68703763363832940708111722893305109505904189996082711399264836004922073729084053658210302373024552414472825766295", "231215222102570725303758653737553205960956923035382475486320616384893246174470846426049063516864176272324286274973", "172278396878944050819521497709066195252724939718961549550951258773555892608205478345434560755799117629163256400167", "28358216183400432709724049012356502737105958935791160692782592225888686643181698642675145705920653980198763666448", "211867060814230996206359214459618260668792557558028380548344555352525197972150717705782813583077892268417971800651", "181995746745027704291239187443805727954018034968708728503106296981643877660302183740898591424294875150611888732928", "239052321376148601199361261054588200910375055023293646636214980744513829280783364645944506323272255309158246713023") + E12TestPoints[6].out[3].SetString("124688422512795936456708399705275209853789175200861408277903413846071674795895264413049738053841007850625383702647", "239250479947312154785351644973796602076703044673993844401091668696831004140352074657976973096385850110050824777319", "62521737401229278098497080446998853806751248198702740367301972544792470808146326924023805723757604617996669551598", "153985447048077493548668838817600467034570946409387870969344533537810058952866714147209449604994290781657942749580", "42820958806379661570848377612061602040087872603170328810728536047188435404076249224172072760715174700731543352274", "36197274374003999202607270804045272440771433193695183530438794582504388990414824550047812838859575535079850283534", "182324423848175793717062357440304592501362625781250537185788200188566795896146554185790257127996759433414816770547", "61066221324330412988150635976148096164383323527565931212872916388622708425981116266981677534725439544612294292205", "193798006893698060200817520807878287731485660210656270801821143742107051616114691614710086364930465548371541589996", "245011752487891073364680516477735558401260109560332069831969474253034979248393896398352140779318988447564217170213", "19708135802172865831342656301560112527100892889562936491427868456017597088441579445862347011839159337787105054474", "62050959311744813557589836252123360364128411774655235236018651678280800989097061220415482344763887023091730293446") + E12TestPoints[6].out[4].SetString("75227345136185367752864027592594931579969210641440067220120091254780033481135648173450360943439540689379458618696", "82378852490683324412381925418587302173456187788917531981097359472206492009293971232309259127983433792115349382116", "69280145376908157278094869555250082169689369609252106160378153488036709636279756483429772593224360885970990685705", "106127332579964371312871400889890854385614084568250132046203150307168014300024973974723966255523403606036369889671", "24601768921162180097584068042981971479268037248841675554049198126018601890021328825367782119199065583725195049728", "11035754604556842910717414257332715248161037396529107058676604572911859498939829043168665916141282318974169447450", "168232929140932193180864891018240652761687316638776750079802373913564312326178914556782582542138861314317483456884", "240378082002344320717778346662499875038922086248795171599598233973303660373415038169453529953967063140217211874801", "83718387963722440052198050138858438438626290996115104685372653052635914571367774233612889980889149329037902400708", "179922008026434513424730397605516499012263660830041667692766913437568296297369344940384045684060186660979381175544", "86212193053238006694151824529826999924692894679308306555833813323537847011114600839293547773041710593900997531139", "155824603647459994042402083709900978918251380110622643974117439901904121970864511052330169690852532901297637208986") + E12TestPoints[6].out[5].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "19375457018642844301720185311533848811236389564892653381994577433448441544971062787207105694393175081766384230069", "103771508188070009627499940464911310732394576306035423422297756896655508034653708912944278823540696278949871355887", "250165039921671105386185524955996623500990391272947239778635104298220330173670202154310129477613250625677474501325", "1603994068982978513824427306179569411324111885745241417076330262145198119786398635256432376922652384312965190574", "78928072115282771090692033563557763137202832505013876316815849201533287367104934382087204469053100909180676965898", "449751175842353118591546074464317288895308197442741465070863448005488653866841238801555317775379368384921599988", "28874859406523329142047615723904758472146445604278122936375389163183222617906040307807216582398728621107529884795", "114249258141947007524751211945069284285560384024754244292035929903989010576342687668343885296332871156541635783776", "239791806391221872199773719358064404981879047260492040265659425135426134150528548854803649329882646769332518503214", "109041702071399340675793172784141207155767594895236905076692074364722556897370130166543104588671389828762673567357", "243274954980650682976648056155263005435696754390712664611539947278902568854258966409608370006654968823205932758979") + E12TestPoints[6].out[6].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "239288968994326249708932548383359684725157123190022007157889685233272026803369759987761782445180185042673937228108", "106757314754294643142446121004775304176318293916316402642094157339192976717876133726204774288950019159487032917844", "220182790029135881551287969844320686716229355341872410316694244521407385678706051890601331858565041829001526757393", "251338436075205183238647376190648586180381185401813597427279051726841743319148157758583717346365400514927388544653", "228195715308204041980125659376616567028025333858977587223848084731213671208822874009381910735883161779689554281506", "216188940499926479252058131101970770024423258985077655765899728033071879710154858595867704393009285914820588291171", "210973204530131649610740983246324341691438249321193232381496308523201548120782801481857012818328883737917151983166", "44484882098409443598108768796828444013647234365477541588583696526436019981343142636081205623966794954612938884251", "206237025222213209341188436291076512375764588638401648378558634451602815677459745062491198092783423487162297015715", "202108272998140650712586313210445535452842787240636268709478173683399870996662104640846600557166811742339174714761", "204312454076627858969467381567003536424855063991868777647697002758382790322551019293360761708402876957722538513585") + E12TestPoints[6].out[7].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "19375457018642844301720185311533848811236389564892653381994577433448441544971062787207105694393175081766384230069", "2985806566224633514946180539863993443923717610280979219796400442537468683222424813260495465409322880537161561957", "46981022075131201083831972589469756855567278895009670984439176513813220844305391505026314942968427794201641657636", "5721995868780932258180930198065377944688215467355821695528880677733526909406266381128738416285307225199967722950", "149267643192921270889433625813058803890822501353963710907032235529680383841717939627294706266830060870508877315608", "85336695179750167742186079536020753588124042616618041742734199314338398108087262773461342028444594698661727695656", "80561431934580118152023707227688359396970445350517352130807516278783631874985904221698199891753213356067905617086", "114249258141947007524751211945069284285560384024754244292035929903989010576342687668343885296332871156541635783776", "239791806391221872199773719358064404981879047260492040265659425135426134150528548854803649329882646769332518503214", "181079595740359320551644068677273383911203486428453365858503281905191852474597275529501328267518111944897157582112", "120072138556213582369184835793751637970722081468593273304559267728140945517049009361579808779032040558082504517556") + E12TestPoints[6].out[8].SetString("59183942379657536292767094300418710620039650455563231649136262541508361319393734798905955659897945175033141515111", "239288968994326249708932548383359684725157123190022007157889685233272026803369759987761782445180185042673937228108", "154892917824899084383152793229982222803998936448879237117586505770064960313687113862024609316032663845490450102290", "250165039921671105386185524955996623500990391272947239778635104298220330173670202154310129477613250625677474501325", "1603994068982978513824427306179569411324111885745241417076330262145198119786398635256432376922652384312965190574", "179736353897686322919960700131335770399190680249900784223068413465187180981235888392881683670520259215259644492279", "141911995957506039700215639494217518892769781451483006870507554199280150790163669841694211232971258038215172973438", "76522440126650653000416363830521560355621874600534317260440430480784167488301832305228674491149610076983186588436", "214179543914559650412543964898065089522746278389437118951300566140284448366997680138887682515606565169827382573926", "52427400790755884669464297403817021160628924116513012161325628215117652670881077712477690046789936637278024442462", "238046944047644634587780291134954198310939085143631114549597022973113145984526642364513215607690078813971073392053", "61673004312618642160705603777671439111871036604892258066775118744340952142312940186966919119213293395837961267032") + E12TestPoints[6].out[9].SetString("90327798324835028117977656131006943414462339309117286606307088196329111047203832838598530383642653875649497766397", "225313479407404839464284283743838686937856224779598818657578421328969217628492304803965540068419972940860934784394", "97027948980150264315893791207930658471848945503806485319504420829739629005139964757597988081221561118469666141726", "82650253512100551587828643714125124800302763673502237954589645918303075899832917017927597930595206534755951406553", "2271502996833724954983011895405519451642083374462173671504288039365925197046116002629340362652129174635184149804", "175518680877823830373388322274092094751114522616100557037420768478366754338841438356387976731839910296358307910161", "175191735733900136841306402568785014544827024306606961820288166075115326894327868093171011067693875804685582256932", "156346492396714830410675271266989387998956968203417075800093296148184406313109326580446257298336443129238551545363", "182592530197235587461535561904686723779562928397937828351428381726242757688484796455186632136038769260486519101380", "98226164481584647393137681721139274526546241587415571392551305230013443668402604273262418316093945628689740735524", "81750151959045783189707094388477247204415326344795159348916645353908974968872834180322415641682488135437168557844", "69007680801020040044228130298023123341395629362167362382856137215687894930858501803407962527257817280036436884415") + E12TestPoints[6].out[10].SetString("10819526752076968042884504255886380643984419015528695690052071521621245986316533463331518924262731624324722327146", "181866505350649341241718897361090354793656826178898895772478333483195153326218771801099789256033519692419953803682", "64293819904885125041016175394474891707017018803364832097270719737006096029834838626095792678822601961956614854977", "105634064661097249920253287592394193905902038763664257424594695566004606696531742556459332779014648038494350751879", "62906702048314223645829181757894812013413201252797957637665336892134110967551759256496528543391444019254365158204", "68703763363832940708111722893305109505904189996082711399264836004922073729084053658210302373024552414472825766295", "231215222102570725303758653737553205960956923035382475486320616384893246174470846426049063516864176272324286274973", "172278396878944050819521497709066195252724939718961549550951258773555892608205478345434560755799117629163256400167", "28358216183400432709724049012356502737105958935791160692782592225888686643181698642675145705920653980198763666448", "211867060814230996206359214459618260668792557558028380548344555352525197972150717705782813583077892268417971800651", "181995746745027704291239187443805727954018034968708728503106296981643877660302183740898591424294875150611888732928", "239052321376148601199361261054588200910375055023293646636214980744513829280783364645944506323272255309158246713023") E12TestPoints[7].in[0].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "215615170178511149669777256309951490112103822803021732346473985447939400607855609232780099011985566714403987153093", "91333495637130952832223037037490830736541650367226645209343317196198819620611505716123188508746333957983566676750", "205060968981828461414327058011445389735001290276451045557653973736628384876939033603824448972760942028837636209496", "114555377043120725312627537181092755800735946792360801633767877635083634513151626643429918664562963693410247982387", "53425135589223804869956026470632049156365851518446510000542960301120563010424534463779112554087535795746101891125", "235851375542680103037837503888925587654520305916362229662228962042447612372273232789788014621971475074575555467218", "81753971125494995518169924621546156557609227242820789484276664716493384035087641072704201311697215618514826064629", "168991003550622650794228173839340985961582097120168139429195840749326310737731209789667893656476053244959533449469", "235184990161260024178878224547086240791004116339824962314665375199666145298685360619235186053917575077569339363218", "49048053806763545998416762617385865166379566019309946838968320828062626780217261957861980539272868937982675090910", "147097452756430602175830287359996153936176256819612875989221615580152092013411442848766169175569511602233138398033") E12TestPoints[7].in[1].SetString("6883636033069229248657233739405481684993846505713305144851233092920835836572301910854234121327884024142091825351", "39616150442368321874380835776551107849834608292327600145832702136281295632424076276709993058748286195502486294887", "174126177386789317702574302984652006773140333020662589557481022892876671675407342123466013055867208720185336877107", "34617985126419834606610331471338852794730901878749587121548019034704336400474265015724363182454442592616287911936", "219194439762270808492563425630213895821359622765337718108508569236160421187555442581178590644541719569997339577312", "96287716290337105466754352615099147939206458753145419562938856204729372611806512541780095873143464818122802806493", "248505271903618365155707261153737240821053596668196765209733988993804890857975491645741127065931081565158200633341", "254351406005908125134361051750276582381523438464964069559671807260487641414062992132813360540866040888887532567269", "139141031905760766528544194058142619908786457719889858049855846739100141205464950845935151910346851529690557344495", "128096873857340693550570040063430016903838318222477121644221484522805104196817583570889201530771695443169286367181", "240282449405685752665254130131969852044980775996524862453148568858587706316452776530665811176760427235989406420552", "120517240785352472361424137918682432233898326631908160872129075383167658630458794910537716483563176844392866120769") E12TestPoints[7].out[0].SetString("131166750219458353386415805940989210060731594774714084983088762281207378817420715995100664270062240326747767204068", "255231320620879471544158092086502597961938431095349332492306687584220696240279685509490092070733852909906473447980", "6795247010951176524144606327249303973288470632974574226940077422355022947678025064620313425040182553728582095680", "239678954108248296020937389482784242529732192155200632679201992771332721277413298619548812155215384621453924121432", "75085390792422439794538229116413118085702056802783859202392184204523587352366246449639621169531323138967266101522", "149712851879560910336710379085731197095572310271591929563481816505849935622231047005559208427231000613868904697618", "225692221433329374182892031347769294939180389829644334332078688369532034881907901660560253548329196515293434642382", "77440951118434026641878242676929205402739152952870198504064209310260557100809810430548673712989896382962037173721", "49467609443414323312119634202590072333975042085143336939167424821705983594855337860634157427249544650209769335787", "104617438005631623718795530915622724158448921807387423419002597055750781147162121415155499445115910396298304272222", "30666077199480204653018159054462183674966829260920148752232627019929864748329215713558903576459936049531760053285", "8950267528813980526601691583785052633681070696606376321466428296599282295529414984334997519559328322185683060625") E12TestPoints[7].out[1].SetString("117399478153319894889101338462178246690743901763287474693386296095365707144276112173392196027406472278463583553366", "175999019736142827795396420533400382262269214510694132200641283311658104975431532956070105953237280518901500858206", "175871744263310729140301467747732357499794830101478716191746556970042616293544986367626063592452485362238551257820", "170442983855408626807716726540106536940270388397701458436105954701924048476464768588100085790306499436221348297560", "154025363293819010830716845245772393515769836781937744065143571065643681673937006837220216159594604247853229863252", "215801845311855793413854407550426434753552905520215750977488366763111658746958844696967904820517431102063620542809", "246010529652030831892782976430081880369860222003080124992379235715363189862638563919015775695613753633857676292054", "86066991132555964394461606566163107712479301532771380464489120122726210969365471714859728910404534854067614955537", "29849971644861884265683979781198366052795639400278281379339994010226169532266258943732741746129201715268976104974", "107088116303919330628308184483656223887165798117347840670443890676861041101867777048345984523145879634400052996037", "67430030414046887343815366180309546657792302777699744925704014636195388812105308202165057502085801826433590128535", "26580211971078129814406149441313721702277930187704715117092540196984433382952647938228452692006334757840272277264") E12TestPoints[7].out[2].SetString("100840396996717217354217628333009084929507912881304741934071355114727004733536707134603453776975087604927550228124", "223629133593627992326795748874544948696601880442542611820822401235477877018693676525205340374169614003261575511524", "248664676363338469253035562883236574488447311414349994617480308316256337727950179780345020756250082024851536618863", "9867314769831489801106956087627470911068911375553444543144941444622398528075341642734325551451555213031814902216", "64869449148450750346799207124514363739054493346537572946938027780067236757668495094985330210028605480122523182729", "124092935742977229951988569127074615115156138638088953706529584969224052295947303698979661975869997155404583006615", "109254093130579551369445570792490809060669653918400191453177633547689053755537917048468420171337482402273581319304", "155025123142357021475478870219936490565200915725412922074776574615872464655031101144284218336615137116807610476326", "107172465705544783210929249807827036879370047531507192444236814834698090148977209341167043302353578293922830283611", "154881199377863037450703693691948778777427309083675338122993107413506096711589538197156031693119958110032678331226", "88613676683553183245142318907524039270555192455884030986601793890096798109996289073963761605578380843403095236062", "115291287204408149718969594115957886898442918198123740345758214583623249373901469494401978457653208776223416257542") - E12TestPoints[7].out[3].SetString("184753459467912926718422136114721470239095717756297232954773482605147909614286521979037900425960222433357643908353", "22931847877453073698352460028613205983215605040700241949804496358557580901627462555867372982361290901174801932640", "30422736284678341554873317862680118759058589739673833893087877358032869012767285440690300109410713062241912472183", "223227772709200622021974724517057697471275428350828338986148338089637585494420095979384710998170151223467252466062", "171155905851964092179727989909624054088080158160011186879530114722950582420178285014761135999716591506141601936871", "221197364884185634637085432876560491597953830223466516919812229966275359281248063777387194712320759556344068677475", "68326039127231622645227765015956604176318343634042080917202983358729665340847746005501996341165463453898842404689", "99596347601926179029560604711177324538108180789371166808057268704300233737441373799026267285981066085486495674185", "213833413864708558928390145749656363552974614267071304424745817268848907714793490729371648383359227336565497684830", "221901993451601994060135576449431340274087877785312348106581245529710553240468028592502361823078123206728502292882", "195948159809605832097225744918902932205879974513143227962560142689739548510327666647821757140042145691679307144341", "216337229401332533972974879765913268752756876640768118245515718680918788920527527341483143516855941372925120493627") - E12TestPoints[7].out[4].SetString("126207657519763882516534054070540873741302972620386882766859235215157157834498062863551601824735811938911584618438", "28240178689778292914275109656719899400197484038560400925358482228038702961084341312861251177679203758825356574034", "38835416687048861170125496978170382748778678859672583109322291321132395189187000136872161552281036242425279966389", "103702131689335024397450227200788616287474146132494465216481857626764044405140077533411790949431850510306509081591", "114677790911714577361984502765078025649684308757455168362704658359367114557446603496634081509826415508219354379319", "171852493664944440006449679696572551593078789906881101588270623277962465471231192093480046696434017712136304329982", "257573029949009753295178578665633694107182754085496731759030515718836180054633324601316832782948427404310026967143", "106680745373804831505270065374699529942931469887714757791496973692742362022302224979709418905188761086608886948140", "66289587574237216345851111709817719800005743201575374553986260169482797618844238670699812328130538765387164146557", "225569277974078682484738825571521059393907101517125138817144673843596564748181785022028985910861132195860586539589", "113694465723052914511195187889709921569977731001384142268821777081473326628140673828130923959799158310185945814504", "243395134548132873157782058424155508242875354424044850508987444296904486405348133361405037403309551927185307819308") - E12TestPoints[7].out[5].SetString("201776136973003527621428582024401508447177821786335991357355270709267858752543381466576329065735058898808496432192", "143408078989797963336262837507673738384568687584950728229028565742475869665935899904404753763148913375908616829010", "179498114775620329369486323654554122486684750310455006979304006049074518205084744415978958728689472793814187221400", "172739527683934253063551242576854013411477830090565716098064562913941124395166582458651513254489080809840989139389", "157910569567241507642255832249101465660485205720299680938441395477063746102988412861450220913087533498796122894994", "55302243353145965305713424997833859232840095839660915759585353324995459624952705303647907639767294067535991906231", "252383719641713096682308381797768188732226867960453965147377066544602393770421528413514232848439509119781412079304", "250310814045223402172110831751767678829267070638136678449499072967816153064681332214411339835509180703416155001429", "1276249325064642088962201238037821683256042849386381473776197870643852432657964125802452386714556448441391916175", "234848496370779032705705660465438041553991313663395949137222462720431288503849578789393915909547950256387181144385", "50787460443059528100337114383076637710847505305146802610009658842631470826149740931241241052874316425549717138945", "228161320287308786389717325849932442012981925134000437350419120400283773093367821255443763605625501988368137693369") - E12TestPoints[7].out[6].SetString("108147141428016440738917504106629609770765250386157526559150493765867354757594492447788885246878514604439203859043", "150860590351120947154951264446310919976396272026177598093769564894067539201533338840007193321682894880006657735130", "166852888013615921021792693600346291683252698462967368174030631711951602598715395203070267999159217816202563932115", "81509963560655594293001555368082495162824000375226910907740100867535596327561449212102905681412077261354553070540", "73290176438982375978627228857933939509909799811254080564499067011029048616973212874115582808643653438547184820358", "24954723286065129163694777580805646430395594092897478043939558090670418879061826327604438269439925013374594024229", "34680342335247702641474477387928476106239703723322223692592053174577594712571587502659055062960595427667942536951", "53048934847087126890020015313181519451433717279796806147187308486889394737466765554479116397494231185936196063068", "52563298705212652268552765812794462841097023384306365311763802987371772870002098487431279695497115499422419943817", "133036447344050433591932934940662656181415341158569988644776162703605625683755513650463222587567774337386901130456", "134455928732669785008529530857568057385356436339652908684625247313208922885253161548403451647118062194044277811810", "187528020884454062111686200308081757482478427717882686517269387161269219196808050899277768499654724874227381609089") - E12TestPoints[7].out[7].SetString("28240178689778292914275109656719899400197484038560400925358482228038702961084341312861251177679203758825356574034", "76974416706546595305437357553086881455539297075060308661348699576375525236567777127704097992861834412670381215323", "103702131689335024397450227200788616287474146132494465216481857626764044405140077533411790949431850510306509081591", "162965738945191228640416739612570196671591843424883312945795015864258760046841893692355765194200223323149248868184", "171852493664944440006449679696572551593078789906881101588270623277962465471231192093480046696434017712136304329982", "178134213790124371878788540769951725251772969404439829996471489271905703920493814364308149185709299176308063750770", "106680745373804831505270065374699529942931469887714757791496973692742362022302224979709418905188761086608886948140", "103247491192395769461166262472105445528715253368082278459782955677111329680594829475257144184504357505750069685064", "225569277974078682484738825571521059393907101517125138817144673843596564748181785022028985910861132195860586539589", "220189458325222718477692409297878370789115958844246803342704662167272934202441505954115072977284795852629689995853", "243395134548132873157782058424155508242875354424044850508987444296904486405348133361405037403309551927185307819308", "177937548752392039308630677794878104435831653853225624777694913016326946334632628430607517675703847736701382037807") - E12TestPoints[7].out[8].SetString("137498714761974581556118621103262699760125439988380823692354084217098559988388991561931998846871536125248637835498", "104871092428101995822719186902905398735909516539882591452568833356041955830875322131659982367226186250547216886751", "148437716079101153029508376270453445240344659487591190542568640600479225703071518295329890603841677684155397805538", "82328210577935769992696235088242650819169919522197676215862517518924748429368629255385495350722886316177281994009", "41608931142051065045061056578660744965650976721275586684289290139016057862844311701321070989100784690006411520263", "81419642958215385300496468708191100743309896685075889968531534465408941987131342424402298229598476705857257428944", "68238029906832793815849339545745927997258238030597254968181752085443751113293401282518257124352057153128216287846", "161336430194539572035540778490076875544850767181682880220312018960120671906885309273666276197634022093434336498939", "214326929853807567732627240287515403893218015780303839815408575165867802393669540050123202363714769404197569033057", "161517089087590454877990948077828977009478084878101427188384139076473956854402181893488577447318972380909758622698", "180944207576070858316858401633509713299516002887236931422880718205889607910389599791500633138661063624656001011297", "81267685689445995050407854924669966988698116195706336003500609327182619432832596722441589951115996181087429435483") - E12TestPoints[7].out[9].SetString("119591468319021410322998475464746808100875858461732740370502118766295573362274433190950262557301346847834844198894", "8064571573872802108721387643579573907760340628553722280421792569203106745308169458113339630650128232524458715092", "111086485635634517868981286306667035052447491791525037865951754834151888213518958788134800618626893226980042685751", "141548288860568169699639022165222113808310043186595954798641134839656831249148789038393316436266700238324379921202", "85474246776190738497058464746911515793341577627738565802307720952115626290339176387253008330207322581112127194267", "15648512417997722325719812799046289749822423942590873654909044843519875851032709265778938755164588858896749341190", "118308545477001331517455199617637741723527252271881877281846827971892589308715701408322682988577132914243287979183", "118105970147615065796565667140965746725297277152010911988394534906523458644728690864536143490415244055002720023431", "249718844097383431862979263232239516969868436213649840842083048980382698216803228787207852896867089905585667167079", "141041243497990819833904782253185405826925807476529679905960825428509112635021191673139514341577771847738303596056", "119487104482272481435175951096612073975707243332220986833045399993714326634201650482707152966601931289009387426053", "173792456704432310826542620422836315719607610225325503611930434986752798469654448826456507486518486489188115817578") - E12TestPoints[7].out[10].SetString("162416243321560611409913132661452868695468170420103333595525873025303088503597915463718279577863383476171851768901", "187179655311320043380328022298751672573988444755510512323813482572842188485131972963960155311070267915844160285419", "116806844537797742065105631809832178430275090247377890982728715486848448021909670720677565170818428331678328584982", "18439806575040536467989796551050102335265931910112087610775804255135352314086042282412007021357638187923842367520", "21564264628444630825160508943678367828098362139807599746323118210837862000701624207746703796439490904396130141922", "13008567891762720204990957233073267684449053477556183796438638809673702798160750007604271314533031524626650674380", "39270716060303727477418421378069336180741921535246609683364980833821504948776087409969418693224348620522988303558", "31777383755865478900186068622218947499016666760290272767284381043968704713183392666881281759923754327504486144416", "221089246514347868094842346424719319140308457786095974066441647440408949559997046176962189279071841710713779093448", "6124306520012155566915313662514993769599375936530092975260757773642907347238884914062858472182943865489410371068", "60945483677864397071322125089874839583409636040596963536684107077875860022307017940807826596797858545668752139798", "37439568511070760613227004501537573473328316609838795843408883279676127410730673882747674236380471478800224722347") - E12TestPoints[7].out[11].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "215615170178511149669777256309951490112103822803021732346473985447939400607855609232780099011985566714403987153093", "91333495637130952832223037037490830736541650367226645209343317196198819620611505716123188508746333957983566676750", "205060968981828461414327058011445389735001290276451045557653973736628384876939033603824448972760942028837636209496", "114555377043120725312627537181092755800735946792360801633767877635083634513151626643429918664562963693410247982387", "53425135589223804869956026470632049156365851518446510000542960301120563010424534463779112554087535795746101891125", "22813050470288990972815229805967945881873206838552430877655300624272855976067589985180873517601885049864765990959", "176910454887474098492482809073347376978784285512093871055607597950227084313253181702264686827876144505925495393548", "89673422462346443216424559855552547574811415634746521110688421917394157610609612985300994483097306879480788008708", "23479435851709069831774509147807292745389396415089698225218887467054323049655462155733702085655785046870982094959", "209616372206205548012235971077507668370013946735604713700915941838657841568123560817106907600300491186457646367267", "111566973256538491834822446334897379600217255935301784550662647086568376334929379926202718964003848522207183060144") - E12TestPoints[7].out[12].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "43049255834457944340875477384942043424289689951892928193410277218781067740485213542188789127587793410036334305084", "74783400657001383559999031626871934438323867227566453598905914889612599199855589176532075974989398979969989579812", "14748053041717860930839267836712421522074951843119316870832934159593414140632263042154722838805592067106171597499", "251145679107148511082249867810009978928705677385352527616892392287003780016959627890330944030293702606539291107402", "185845190878429110466163557433913847459718202740006658321253524599731245904256991812678694860760545886762706049585", "218681576273327338561580904981292486989318006556741239251258086895618806917993587526643635200823794421310664908843", "185797303664705022119292485435926936895328900773831393670807959161222219012463208756977634072465837695613877856937", "154160079689863075695378374976683008562312941124133966479126025067402480393273192099685524782153926017960293591311", "26752728390845125102276613765958402793115723029214652452554516941621815347923255586302231449894352247465973882256", "196747970470694734391580794231301640168028884219370491975494669988211634656649616257022360161301782727487000921693", "150005266858935387965039149211868673217333801412430697119707214361717131278756987036489171335685046757098701827390") - E12TestPoints[7].out[13].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "215615170178511149669777256309951490112103822803021732346473985447939400607855609232780099011985566714403987153093", "242114331032839524738428728284274637238175729615254468929446860360134247927584906235377775605816425146426744361239", "38855403989422771665486407846735722279317270635344298111397354770498669330769526128989716328006826028496513651182", "151627795875668951626428062398684332343345401332115991829108255411353522166570391016176913584290053948931103826565", "132420055289205305596207530963281798303352351221560148320710564298610682893832457348899582306673010091016604158460", "112583536815373977423922141238865917983557277475254440579763669654192191202181061508936434410438025815638033221619", "174838915870263967745722428185255582917033501852731447222266821560240608908591305626490498697937045807078764175572", "89673422462346443216424559855552547574811415634746521110688421917394157610609612985300994483097306879480788008708", "23479435851709069831774509147807292745389396415089698225218887467054323049655462155733702085655785046870982094959", "130178254860154399214981937068469351847253716589466187972542195931818427688862928504169086320899941236145618519079", "241722216016958035039924764320532852376487871818575815043112716746443751688030097593805086408855521696008527298674") - E12TestPoints[7].out[14].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "43049255834457944340875477384942043424289689951892928193410277218781067740485213542188789127587793410036334305084", "167330930375838141178429696657402702799851862387688015330540945470521648727729317058845699630827026166456754781427", "205060968981828461414327058011445389735001290276451045557653973736628384876939033603824448972760942028837636209496", "114555377043120725312627537181092755800735946792360801633767877635083634513151626643429918664562963693410247982387", "205239290423745289140696707224261484380027661236468150539341302365599905337916288311189775585485824328694219567052", "173695428350886044557359954814598403662643438122099991584426880338268212399487793146502368764834855331992995720828", "167956078177024122674117184019269762627718013396200668046616522124717344368561377396321756053086037760933207992282", "104504346323106018315274358718210524974080571630780694060758237599317987955067630675283363357419434106480027866866", "231911697622123968908376119928935130743277789725700008087329745725098653000417567188666656689679007876974347575921", "167898078890374103245919971653390886826006189147707966652934520827920010437266078576770527733442972407254892729483", "194491899997075308613106677248939960746027877730029109813534013743943903012883263626063635004367577929536642333826") - E12TestPoints[7].out[15].SetString("77185844824404117857695693406835252496460559030231022788254207924187508311267394730140567574003402769793999125647", "107750407325246733304064444703252587444478497274227827003635454575895908831741090269623386272412655902465961478976", "82610773095770821822465605863494449008883622453645125888833483898597284986576882035492096272763955145496254355411", "53468208396775367387309723903223612230385357149895828615411967895730977518697023495159410148018213850600627722794", "76275181254060595470638067486870296306022429360614194674207508551867226247974027218858999262487894085012236228400", "11638054800912500488470913129687768494099423195071565386964544276061415041178843153624381879105214951567050840243", "93300351952223465041412365568713186960304303666950633602644326548170208201218400461537058815361247462153057758404", "77232595359060914047053530815345323057886254499173653406393556547104866124912222815795591521713944209002542361535", "117244548222129554334897731912745707697718351923667994548659896204084624185230250165341228320185287336251808061162", "119813275460679822252618314035060126780377914246292334168681566979424184174915955476385507348618028074220061578823", "57386095948566842840732317901082098224991787101100291535920049440691551013298750082391385829973424210773421025413", "89553987476223020569167481479188704993867901445162184627650685231543154298762769866975739079414571661308582001457") - E12TestPoints[7].out[16].SetString("4016675250098449402298453044204116567289349393859598882992052208971998895203673149581493465747766533454231044865", "169051215862478929279651572740137778839710382279345171456492043482134072645416543743258964525671939527598675686046", "43836877501794885431542735381963847832046858313947275554171326332507737583113332012037281298191381221988141907587", "117242116644371712508354336611773239331707266317687938308409480829642609676526549232861309081487086185019735554560", "104478481597248347671649121987902571786402992318340185212815643444663218289327015122955381385174190403366182572072", "136917842993611561033202192577049587616060455488963464627519130163316346199510216534116282917388677971785104649980", "242530288924685306063545798833916999728224795250336783709943116047136808049716915924064428487956079899755422596496", "128211252068412585899234811098856199826239677591455899268842137891310455583221943881265316019654745327978399469829", "147807481761553592366840976409906158303823240659266344438313408919647155456412113706326618871493914893569038431303", "8833221561130765089529226149866008943238339522854237070119732936332606355813570449358143453102424352102367250175", "171197715657190157590159958300765172305718453777281894132913642189163303149891362059054820552394355203409559383177", "88415927351467504770879242970952303044968364478583118413996608783954911484596796072209032362931931472077788974791") + E12TestPoints[7].out[3].SetString("119591468319021410322998475464746808100875858461732740370502118766295573362274433190950262557301346847834844198894", "8064571573872802108721387643579573907760340628553722280421792569203106745308169458113339630650128232524458715092", "111086485635634517868981286306667035052447491791525037865951754834151888213518958788134800618626893226980042685751", "141548288860568169699639022165222113808310043186595954798641134839656831249148789038393316436266700238324379921202", "85474246776190738497058464746911515793341577627738565802307720952115626290339176387253008330207322581112127194267", "15648512417997722325719812799046289749822423942590873654909044843519875851032709265778938755164588858896749341190", "118308545477001331517455199617637741723527252271881877281846827971892589308715701408322682988577132914243287979183", "118105970147615065796565667140965746725297277152010911988394534906523458644728690864536143490415244055002720023431", "249718844097383431862979263232239516969868436213649840842083048980382698216803228787207852896867089905585667167079", "141041243497990819833904782253185405826925807476529679905960825428509112635021191673139514341577771847738303596056", "119487104482272481435175951096612073975707243332220986833045399993714326634201650482707152966601931289009387426053", "173792456704432310826542620422836315719607610225325503611930434986752798469654448826456507486518486489188115817578") + E12TestPoints[7].out[4].SetString("162416243321560611409913132661452868695468170420103333595525873025303088503597915463718279577863383476171851768901", "187179655311320043380328022298751672573988444755510512323813482572842188485131972963960155311070267915844160285419", "116806844537797742065105631809832178430275090247377890982728715486848448021909670720677565170818428331678328584982", "18439806575040536467989796551050102335265931910112087610775804255135352314086042282412007021357638187923842367520", "21564264628444630825160508943678367828098362139807599746323118210837862000701624207746703796439490904396130141922", "13008567891762720204990957233073267684449053477556183796438638809673702798160750007604271314533031524626650674380", "39270716060303727477418421378069336180741921535246609683364980833821504948776087409969418693224348620522988303558", "31777383755865478900186068622218947499016666760290272767284381043968704713183392666881281759923754327504486144416", "221089246514347868094842346424719319140308457786095974066441647440408949559997046176962189279071841710713779093448", "6124306520012155566915313662514993769599375936530092975260757773642907347238884914062858472182943865489410371068", "60945483677864397071322125089874839583409636040596963536684107077875860022307017940807826596797858545668752139798", "37439568511070760613227004501537573473328316609838795843408883279676127410730673882747674236380471478800224722347") + E12TestPoints[7].out[5].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "215615170178511149669777256309951490112103822803021732346473985447939400607855609232780099011985566714403987153093", "91333495637130952832223037037490830736541650367226645209343317196198819620611505716123188508746333957983566676750", "205060968981828461414327058011445389735001290276451045557653973736628384876939033603824448972760942028837636209496", "114555377043120725312627537181092755800735946792360801633767877635083634513151626643429918664562963693410247982387", "53425135589223804869956026470632049156365851518446510000542960301120563010424534463779112554087535795746101891125", "22813050470288990972815229805967945881873206838552430877655300624272855976067589985180873517601885049864765990959", "176910454887474098492482809073347376978784285512093871055607597950227084313253181702264686827876144505925495393548", "89673422462346443216424559855552547574811415634746521110688421917394157610609612985300994483097306879480788008708", "23479435851709069831774509147807292745389396415089698225218887467054323049655462155733702085655785046870982094959", "209616372206205548012235971077507668370013946735604713700915941838657841568123560817106907600300491186457646367267", "111566973256538491834822446334897379600217255935301784550662647086568376334929379926202718964003848522207183060144") + E12TestPoints[7].out[6].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "43049255834457944340875477384942043424289689951892928193410277218781067740485213542188789127587793410036334305084", "74783400657001383559999031626871934438323867227566453598905914889612599199855589176532075974989398979969989579812", "14748053041717860930839267836712421522074951843119316870832934159593414140632263042154722838805592067106171597499", "251145679107148511082249867810009978928705677385352527616892392287003780016959627890330944030293702606539291107402", "185845190878429110466163557433913847459718202740006658321253524599731245904256991812678694860760545886762706049585", "218681576273327338561580904981292486989318006556741239251258086895618806917993587526643635200823794421310664908843", "185797303664705022119292485435926936895328900773831393670807959161222219012463208756977634072465837695613877856937", "154160079689863075695378374976683008562312941124133966479126025067402480393273192099685524782153926017960293591311", "26752728390845125102276613765958402793115723029214652452554516941621815347923255586302231449894352247465973882256", "196747970470694734391580794231301640168028884219370491975494669988211634656649616257022360161301782727487000921693", "150005266858935387965039149211868673217333801412430697119707214361717131278756987036489171335685046757098701827390") + E12TestPoints[7].out[7].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "215615170178511149669777256309951490112103822803021732346473985447939400607855609232780099011985566714403987153093", "242114331032839524738428728284274637238175729615254468929446860360134247927584906235377775605816425146426744361239", "38855403989422771665486407846735722279317270635344298111397354770498669330769526128989716328006826028496513651182", "151627795875668951626428062398684332343345401332115991829108255411353522166570391016176913584290053948931103826565", "132420055289205305596207530963281798303352351221560148320710564298610682893832457348899582306673010091016604158460", "112583536815373977423922141238865917983557277475254440579763669654192191202181061508936434410438025815638033221619", "174838915870263967745722428185255582917033501852731447222266821560240608908591305626490498697937045807078764175572", "89673422462346443216424559855552547574811415634746521110688421917394157610609612985300994483097306879480788008708", "23479435851709069831774509147807292745389396415089698225218887467054323049655462155733702085655785046870982094959", "130178254860154399214981937068469351847253716589466187972542195931818427688862928504169086320899941236145618519079", "241722216016958035039924764320532852376487871818575815043112716746443751688030097593805086408855521696008527298674") + E12TestPoints[7].out[8].SetString("124283114186389124137758572201583728375737748269000779838237529188286542980848414084246430148734356302605675378717", "43049255834457944340875477384942043424289689951892928193410277218781067740485213542188789127587793410036334305084", "167330930375838141178429696657402702799851862387688015330540945470521648727729317058845699630827026166456754781427", "205060968981828461414327058011445389735001290276451045557653973736628384876939033603824448972760942028837636209496", "114555377043120725312627537181092755800735946792360801633767877635083634513151626643429918664562963693410247982387", "205239290423745289140696707224261484380027661236468150539341302365599905337916288311189775585485824328694219567052", "173695428350886044557359954814598403662643438122099991584426880338268212399487793146502368764834855331992995720828", "167956078177024122674117184019269762627718013396200668046616522124717344368561377396321756053086037760933207992282", "104504346323106018315274358718210524974080571630780694060758237599317987955067630675283363357419434106480027866866", "231911697622123968908376119928935130743277789725700008087329745725098653000417567188666656689679007876974347575921", "167898078890374103245919971653390886826006189147707966652934520827920010437266078576770527733442972407254892729483", "194491899997075308613106677248939960746027877730029109813534013743943903012883263626063635004367577929536642333826") + E12TestPoints[7].out[9].SetString("77185844824404117857695693406835252496460559030231022788254207924187508311267394730140567574003402769793999125647", "107750407325246733304064444703252587444478497274227827003635454575895908831741090269623386272412655902465961478976", "82610773095770821822465605863494449008883622453645125888833483898597284986576882035492096272763955145496254355411", "53468208396775367387309723903223612230385357149895828615411967895730977518697023495159410148018213850600627722794", "76275181254060595470638067486870296306022429360614194674207508551867226247974027218858999262487894085012236228400", "11638054800912500488470913129687768494099423195071565386964544276061415041178843153624381879105214951567050840243", "93300351952223465041412365568713186960304303666950633602644326548170208201218400461537058815361247462153057758404", "77232595359060914047053530815345323057886254499173653406393556547104866124912222815795591521713944209002542361535", "117244548222129554334897731912745707697718351923667994548659896204084624185230250165341228320185287336251808061162", "119813275460679822252618314035060126780377914246292334168681566979424184174915955476385507348618028074220061578823", "57386095948566842840732317901082098224991787101100291535920049440691551013298750082391385829973424210773421025413", "89553987476223020569167481479188704993867901445162184627650685231543154298762769866975739079414571661308582001457") + E12TestPoints[7].out[10].SetString("4016675250098449402298453044204116567289349393859598882992052208971998895203673149581493465747766533454231044865", "169051215862478929279651572740137778839710382279345171456492043482134072645416543743258964525671939527598675686046", "43836877501794885431542735381963847832046858313947275554171326332507737583113332012037281298191381221988141907587", "117242116644371712508354336611773239331707266317687938308409480829642609676526549232861309081487086185019735554560", "104478481597248347671649121987902571786402992318340185212815643444663218289327015122955381385174190403366182572072", "136917842993611561033202192577049587616060455488963464627519130163316346199510216534116282917388677971785104649980", "242530288924685306063545798833916999728224795250336783709943116047136808049716915924064428487956079899755422596496", "128211252068412585899234811098856199826239677591455899268842137891310455583221943881265316019654745327978399469829", "147807481761553592366840976409906158303823240659266344438313408919647155456412113706326618871493914893569038431303", "8833221561130765089529226149866008943238339522854237070119732936332606355813570449358143453102424352102367250175", "171197715657190157590159958300765172305718453777281894132913642189163303149891362059054820552394355203409559383177", "88415927351467504770879242970952303044968364478583118413996608783954911484596796072209032362931931472077788974791") E12TestPoints[8].in[0].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "255620416113434055453576946784466311854889092620609584281611369888188808194841414051302287931388347771953519546461", "178706773475359235176923405751079964183386316028964821957530590492682263309780459365485977390560164312162751061360", "205666368584361305382329371824691464171045709594840934321683333418552011014623503190112494145889853791749683877522", "237671405707868902684992726497380686213304295827910841250157940937066208380651562923368539120542301606997226264577", "14219177149219371288178644831879401727342947357727640598210845236564165434500254298652307467253141106095268985941", "257444318338990278888758398287444276379039873016053321723544717453234411512913209009473977302006776597885783340797", "122221628904970088865501508305821324429433498463196160952835901332217996147549632762108875513865887424063162714106", "50029674290341673347324104957517109442016532747024014487404819541222150771434057788741540482448163575656508249908", "95624696750454654470021552218510815503733313966632997735253754449024932187124732261496210589607614109843203813190", "36634196930912111267485886936731026448037880585528025872171848519411546982964068363854460617899998074974970023996", "229327473572335852058190646554637352511945419058189653069911694502216079767137027983344480047066847060453234389698") E12TestPoints[8].in[1].SetString("207097427862262045506542782432415378801280824143490607858371902435453457174689868215749293280184081518343739324755", "77102785505565975572603352574164066168394971450728314020034923890902468088373394195072402392139632297127869976704", "97860306268329774155148437658210765747681879467946093410397511584444456390079392483736525613586793754917960329433", "9973280872158834118709296857614543519991002262199801088509720888072904728884536923204100035610510688979304225259", "189094048727525573038242358590329812867783197565773758657748558533316824394452923305517114048361880018764208239163", "210242423488114844932946188774203147827868784766626013360478617159177954147546471781833818051446884345213445308278", "60893867017412548170832282947766064233732703779985305951995041532966975376625872702325164043562830269843361531647", "242124489717781746521656534821161302225106978246760836557098560322917808125406743080293209513261578286606663907937", "106799336345245705192155219788465386994490979342033660325447259128205063790172277675274257553027820895071757320082", "179865773943781718488460459434508293547138205307476939173695670661077470632813339223337916287167586451981562530095", "145741818253163039130928431899250756553640469626890028914350528418679371595301310971558283003632575700291184242782", "162487213807031674625054548489145810398515010573444202177709445665128039594060549241583374030819760997129941000695") E12TestPoints[8].out[0].SetString("1845245848594856664515622426343853254812085031827922912199880081857447465646712194772199520200772905817217421933", "74058775606030937015527565663736844486890551316423237761762031112370807934873985471405802183954619944641068064988", "17902653730719915321419109714397196394674682741996254828043839410406251351519029074253614864573597942640389932616", "215639649456520139501038668682306007691036711857040735410193054306624915743508040113316594181500364480728988102781", "168101028422425381712582351392816965544693980638769939368022236803662564426763663453916765029330821501321113045563", "224461600637334216221124833606082549555211732124353653958689462395742119582046726080486125518700025451308714294219", "59673759343433733048937947540316807076379064041123967135655496319480918541198258936830253205996246743288823414267", "105681692609782741376505309432089093118146963955042336970050198988415335924615553067433196887554105586229505163866", "156829010635587378539479324745982496436507512089057674812852078669427214561606335464015798035475984470728265569990", "16826044681267278947829277958125575514478006519195276369065162443381934471597248709865238737201840437384444885108", "182376015184075150398414318835981783001678350212418054786522376938090918578265379335412743621532573775266154266778", "133150261366398432672592461348889629374066916876719194707736877500623651012856754449958965938313247933142853932216") E12TestPoints[8].out[1].SetString("104979242150008953672735524951300162725037462254676028275224600544391469812948621313211389238979330118010381688777", "178517630607868079880973594210302245686494121169881270261576445997286340106468019856229885539248715474825649569757", "80846467207029461021774968092869198435704436561018728547133078908237806919701066881749451776973370557244790731927", "195693087712202471263620074967076920651054707332641133233173612530479106285738966266908394110279343102770379652263", "48577356980343329646750367907050873345521098262137082592409382403749383986198639617851425072180421588233018025414", "62641179674073620365885189752569787435867675346016287777616490744106679635294605291787377555379616885322145135840", "196550451321577730717926115339678212145307169236068015771549675920267436136287336307148813258443946328042421809150", "138761565200157436354497707179553555740720032971349984935621603676020656370483712456784554140177669261896820264346", "201894763958065062165821618863945255983919066159905014701841823079737555329602602888436171068993702805025072388003", "174423348819642029992213826478896055492988621414070719101442346454667929902652215813127182442013387782301962741272", "149556804690718166147210188732373803430790923713552657497705582767452643736003580167265065753840782499124107239391", "66840259765304177433136098065491542113430408484745450892202248837088040173076478741761106016247086063323293389003") E12TestPoints[8].out[2].SetString("142836602491064121860040360582091080798523471439639163576849191001132664779035295417126767131054234732195163010728", "129834323111658738645831821321232723826753236414212643041040265261480142916858722593603943705684536967505767940203", "2015951500902093277402552549724785274956975948684961509076900693496483424365885814178069555998835983087887277975", "80216930818737513815150630818079452837303564757805446917870897424879231555028112835375588688447557319218520193676", "223015111763416891642983603847953077110930463987103896129048222355993100461755908677132724621916670463715505287184", "98411074468823692815091683149040745304714464967415550453688744932208855717996435031161477184522049675219130609900", "63950111961829214516252703894596959627277897047060563161230909455730468085997623269409221662896796271290316116153", "204774882016487262807956058329088992787934693701660393574254027856276388194782466838371339098046877658170243939721", "83452036841355498067164008977666348505497718631026858413331248421886917827408186497508602820672469436993751677999", "200973678981927634556776100965908790747766205975257216346698814871684247103347817898595593897257101361879539781083", "238585048915786088079457776665680696698655779968158532789960507559010539474443576934373743736913390108153750868755", "71504488585000451706985697718708388823802012724941692023104767783302661329132146787741991094512873098031054493724") - E12TestPoints[8].out[3].SetString("191820041705226282108836122084570162861301803731742488255840077771022567184337860825369641794414170699798475689367", "170789609002342041808234351737681386900544546668241429182703477258065867863332413232346538612885504475681131977562", "137553283762811550459552347026015628314983014988049269746574804086258253436017747768769765327049451227998276312996", "209967109658167051836964271437232385411184524267294562267055919231075275085126356195275000943199336882869893983899", "12294411304434251508027119137253322065616410466544820970274311560351742875956189898074240238401466737722217730109", "28797127247170294085987970019763676100926594990029229745991867557414691423332807464189983195616630709245307966754", "61812253413131173588886173878223697256567251102063917267148116716901557242509926098945426584039937561536042570711", "219330479282869827608655410917100858465164655871072468732793001185742538141152134162264273538403747046224194848046", "9081913120852644935641604414722603151245127129180748237560827467253146690257526064462919598457062751750493757785", "217311537959175829553374683931358884575594565501958496441448215834853241658365563139006007842482342440843297832111", "116291308644803720279951405043739416425883928554860791062144950360997866104671850714822599902166850006374155943030", "245882491778163287753283975368035221863503480733497697104479936265002191980341859108303129524816715364494293896157") - E12TestPoints[8].out[4].SetString("202244590732800585488833245256012131424575011510579441533102321252381555027491038528611270748096038146615904421222", "5310336915258977491762590522284544593645457038150137113249872988074753340229638675031535279189419931061646774355", "214967255163748891773724779261130022582818408524967318254287765725875932514704707012602228640904391978203057679534", "192493054266265020195161450724618877252287731551083643938458843100682338772095618255877049951112672208364604895178", "111694677783349035977389686920952411294719086864025202621135552926102090268245621162507371678717172774162281750799", "160604783182724122258158511467038281242508953501588164569397606564374194547791357852534426544766697026041637805469", "33370986462838032131729494676279347871883312513511197943918022852375457117489543413862115780124408241347878074720", "96905957636087183062782503005096233083292590244276378127922022203634429996269778185949712790845000746691002228581", "242567411135865662232744384551837201539160785353405221577884334173976563457073531399971165513059847205432275056112", "245974285208696571403780767073270239132320240529342690058116301751436718474580564454584566497931148846531401640541", "10204837088117254986168995710980669838445905887882226469559830145433677993505297129120520374286900733254507587052", "166358124316337658699464145627645581164094758682803593486108675909753511559951908917678778630047123704679198812538") - E12TestPoints[8].out[5].SetString("13157877022749436058888437504843710035208713489690241335983672447620007276554209914825819725209400639448478359579", "163761583183193467966306951888949259030439163466588615957115360332329623819978415343457740030512502254462539444319", "250488712242863777964960459703577451137959088809922197519068767700074413974822415599718065106077110754319525163489", "122826855007288276099490260623623871686498519745718582908512267244158352433454126539463386065311358773708563440361", "227572732896426971804406144269929693496681616527548937922740459189895764382612827084951429283338041567412116363942", "183199135034454162555085217613771098341638984557087740189166577477631131639480942735622975303258917369888020501086", "89199266992881628548098380461671325623033119793169233782970397201941725876011033051426371103250564820406874148399", "76963706630053854462152860892091669411298932910291586096112442119145722481287417144370467936575710048639586152939", "144291698013177789719915359060033947523696705548407293306017374082709781223142948515302692553753036339085513620975", "197517983919250157398001090813763280255849847127232812352310321902325102179516769017326977767969167724855723641077", "247297283977101543946784215702701940659779277259972208582162841512793774692685433755169662503322468625617436343557", "45734964528012830812960269996738841112327157252193526477430030995664963873839796497986200026740250305133462119264") - E12TestPoints[8].out[6].SetString("255469625212514757222953598721151031625611047126659363475256755295599720215548834629178158161074219301175458875275", "246312023331654137750608549846410989532582122568584781105559840800543999393839077564403797582746452944999699099978", "94331857257847563914491597865552123957905067539044053279572768333648257829838837998364716491889853459986075908575", "215370580557973763798193518755424039199332542714065206421624503237449124884670253308698706144402806807589477395363", "27516644066214495554484398415073699233636032361464138783533891722203926636998028969953196273164596879060993404581", "155271721353199021758049886337330763904501606655971920666276662353700031126287753513319507186970217058672716638271", "102049971521800456406993227807867560930251253715631112027091253952762380636580342171148231060806136139239298417153", "101529853775095857165240513006027502127899022543776780535728128698243529283162122714140985212991228803089317841838", "113992983772183525573031526238873361401436309966333045411557731543656948526327019464665012562971224004495163240593", "67442486627438888004648795690363421316801587426786510150441143145910519272254883653256561324334191059556959793152", "9414736742238124265205686636464284611405595721735293763291770682310947403522520895420360995695626176692024651746", "191415942067193113719183441096743860188429057223364340098573059088639027043524815209091322552878183844164356608193") - E12TestPoints[8].out[7].SetString("5310336915258977491762590522284544593645457038150137113249872988074753340229638675031535279189419931061646774355", "247380458956935392306288836007117253114029812506047616738527874383852685684170865925697364661277895728875438050786", "192493054266265020195161450724618877252287731551083643938458843100682338772095618255877049951112672208364604895178", "198192106640531234761136596069162124638399789357942259974788110745207467511945435067501778611924894470304804410813", "160604783182724122258158511467038281242508953501588164569397606564374194547791357852534426544766697026041637805469", "177537591164451263601869577601126602380779925025753836848157668185252699062653617897482807219487450629496649225066", "96905957636087183062782503005096233083292590244276378127922022203634429996269778185949712790845000746691002228581", "6674197292567606426345898935255869574376662502702239588783604570475091423497908682772423156024881648269575614944", "245974285208696571403780767073270239132320240529342690058116301751436718474580564454584566497931148846531401640541", "255445023037548407655071063866282267136946967274612772747484276968171687370087364499969343614270657540638712177764", "166358124316337658699464145627645581164094758682803593486108675909753511559951908917678778630047123704679198812538", "208972508227998726205755986098110960796803991381508173725819376162463110277373717645799214586516068246203158683952") - E12TestPoints[8].out[8].SetString("208724574958469165246640258680262516782977149828501249194093037147821996382133835436771735002684179032312648059080", "216614645879254210949415742666369758803279423785924368387411404104632029257166669424564840243488108614037991572595", "41405631589083040401963824258635734972918682389847374051111835506597087859613796385600401747656597420040162293331", "49256189457714354240798660857633219792577819855646580345703413982994171020722669268140492546824198176927961445266", "253136792575819466011022035571543338838854364059670618891911460795801196521260370573220968497043297112056659179439", "112216461756170033010348747138226146021418077633748615839600025317294152299185347025311788344051073630888629110031", "140102753935854093683383648959280587654468352553867827094050701182527879760298527003615943320585131715662686239857", "115178375296293723397982130446097977333407722403201718841373129563571133032170933159430966173158867854557337467145", "137946625466675468958596823019737783929673422166851292100824931149881276090761484438029333447031447150140546210954", "137605432033896302044858400618063629565869537389959038858505082538379046570697431938273512564006861743143833063843", "141619402016247392119399423814235379192318174291169905307373451943431310313250396902985523189908169432458255855743", "200225794131357166000053902661808417478377311407611674009655799405582055048503961770097642487763152034064455298233") - E12TestPoints[8].out[9].SetString("46613539405002676128658801628192705940989180195955826057636528586112357749568229679692776819251002032205666357940", "42718069686378461075594140843537651822139390786353968004986631967208303554605043140852942249617402657744591417475", "119974254407433121215578001355732012206587382415747581352648049634996957525746023090183048653899267053322274406181", "81291501829346911474238123224466064358846841145041974614522022095352771462723867140467845948534429407359186169523", "4096335967862433257466137557520382891839544473840490122965764968943948096635872454306806149993062805592124704787", "69382051319564906985052564436072343345468707725147746236032815052204758958578000892240399568307299147731531781055", "11636196225048538024168472661501776937027064976340665078669497707234724009901476837643271945567972465543348872865", "188797699086891275256065380790653007793314877787215968775968150197063730004894538256751083392901766710215150180491", "130660813936041854503460067898787479165963858349111893672923809095495181409158195818759523700761288135257940936807", "57961547675913170622492784072481386512901946410046048603769316811334699418726276816965033294421845579117073382979", "215770515926161557718393834760274474464087186210865659534005806138307435561011193640143999799063402972989126259098", "234762439916123575853041524184554434989933682219298474199109732495497221062027478005111298940136035030649792668811") - E12TestPoints[8].out[10].SetString("229158025585174620312151266786248844371574245490368448207184998093138982353977297177349537597064197852775340457938", "206886723424221745989110343141220543288323692070116415831863604684126816435278720353120572071672812761614070827345", "145916102169716666065539987361786629217430015858939267011483521560154689634761667193144584358958280489597241200062", "240811534231391921758264710717258840799857480011926674211657046689020239773401550897403571282647217540168262361584", "248678782749779437944624292757225878767673738227972695081056063550782591394162547858324893732000533682400113354731", "234339977427668448550718033181253665335758354949261203255880900646096233524706974206806176203736113665061254256288", "27038237365941922701202935092295508313244052906382366436685711850491369707748975125177233232104523610618524398030", "64001110661578897894856274380311728450405488651857262462316618372586807591080258305939711789109594563735384922628", "205898181607118195707367690863792877751999310112546444534689346292803864535992999008877123668518219621047964725033", "7674000335223986358343660380760394260454466646586535812100056423472403912925732661670362361213608700062289289690", "116630244311347800083040626464371655012127266214560633814705662687742905768722630150252178530013438130860432874338", "240670659361796732058487071966675839343277687630960482298584561675797747274383434671198650093716471359391588907759") - E12TestPoints[8].out[11].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "255620416113434055453576946784466311854889092620609584281611369888188808194841414051302287931388347771953519546461", "178706773475359235176923405751079964183386316028964821957530590492682263309780459365485977390560164312162751061360", "205666368584361305382329371824691464171045709594840934321683333418552011014623503190112494145889853791749683877522", "237671405707868902684992726497380686213304295827910841250157940937066208380651562923368539120542301606997226264577", "14219177149219371288178644831879401727342947357727640598210845236564165434500254298652307467253141106095268985941", "1220107673978815121894335407449257157353639738861338816339545213486056835427613765494910837566583526554538117380", "136442797107999005145151225389072209106960014291718499587048361334502472200791190012860012625707472700377158744071", "208634751722627420663328628737376424094376980007890646052479443125498317576906764986227347657125196548783813208269", "163039729262514439540631181476382718032660198788281662804630508217695536161216090513472677549965746014597117644987", "222030229082056982743166846758162507088355632169386634667712414147308921365376754411114427521673362049465351434181", "29336952440633241952462087140256181024448093696725007469972568164504388581203794791624408092506513063987087068479") - E12TestPoints[8].out[12].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "3044009899535038557075786910427221681504420134305076258272892778531660153499408723666600208185012352486801911716", "186570615353179279430512844081537288362334908454596326610557744380601144267338207261762814913113308939790036802796", "102482532122020012645532727486742023392155364231858465206793234082278166162619303408421149472098194661987911145362", "80533582656794266016909634517969379672001617111922366814696830014318978700936453157542705735826327688028854104550", "5644114269204823621151251640886088701289526091023898497628158497052029326974910726305442267471222526111278239255", "118520874163474700317995612565010854687327537469468128279977022474014482050907489944965179894032724445634243308896", "149286080949931766467082957591580333455945456111104066488579389075036925998824233661592878148817406179449786302658", "81811808064397736477482069348136691312397277186381020850647481032475018223396786671197522420579010634145176164206", "59010415680539183173214614372394780682437740646510403598131366110366732883470195739946680287236119899483384899142", "25582475366446206585169539691246615589685739724536157694983600856502895580697110531130539596336234556143891394808", "72783763415735864235398906861232432640149328400665841517600642375334427371871379080408833841037595265815648332922") - E12TestPoints[8].out[13].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "255620416113434055453576946784466311854889092620609584281611369888188808194841414051302287931388347771953519546461", "7863841877820044253589438330457324178948592425631504653027153887918880957557747896276837522553144627627285741436", "209179951319556869993443368078353579509585951683129921551291957832610759519438838951404132661158671795143047893470", "199123863661275019319403106374437001187481112569996113014913754382055749615093629469026531422778090953854562547227", "250089363132954546343625340503900220510340091488210918439301575927208332240815479202622022939791441544456330711491", "73553023168638905670995604325987508185630187801467648481838918696808698202564199474142581814769138385481131795838", "77542561094851029528802571350699359602679015951815178447201716279494001160566082066699025483352527623826140060935", "208634751722627420663328628737376424094376980007890646052479443125498317576906764986227347657125196548783813208269", "163039729262514439540631181476382718032660198788281662804630508217695536161216090513472677549965746014597117644987", "89644324488726579208176902019297213087727334423251345583210217291577844377193354491339300679960581518943066763245", "4822063265666615965801792562594868292072634548832484012069418708974124434412278093640523154195961381131925744921") - E12TestPoints[8].out[14].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "3044009899535038557075786910427221681504420134305076258272892778531660153499408723666600208185012352486801911716", "79957652537609858833729327943813569353007196725949838582353672174038205038560363409482910749013195812277570396817", "205666368584361305382329371824691464171045709594840934321683333418552011014623503190112494145889853791749683877522", "237671405707868902684992726497380686213304295827910841250157940937066208380651562923368539120542301606997226264577", "244445248863749722722474088863014131809050565397187019941673417430156302913840568476316580672320219018345052472236", "177494254460933092632378357967415593942121382157615850393951237809463602220091360020049562655949615620946697511715", "108100904867913100897169621657540275335038428917361145653323008705093762137907991598298327155628127401497789053488", "176852617948571357533170664346756842223996235568533639689236781634245450124944036103771365718994349490295145293971", "199654010332429910837438119322498752853955772108404256941752896556353735464870627035022207852337240224956936559035", "185827075965108189481471732504325153800014328238607255410692722984199544107056044726428105491417050718185198782946", "107837327685399522501861241143173764672258410585911188482927858199474664439150324026809094348113558095548013858030") - E12TestPoints[8].out[15].SetString("131866027180704677022202884751556351007751088952213212003144604602595470533442816920678354298532011806525536774167", "194314205518456273776469614816591235307433817440637211442445861293000896842053626511337764169904439343893006591480", "234618416312613337850146059842619997586784587047081330057479334813557398418473860539422379946879516031267185080315", "194806143408046001789786388747921391906349204106586897515391522077323939203645279736276703667712089260580771527882", "134580210079542338308106798532666113279234816934573383577329431363032980219405647918555669544286031129975877743399", "135957548388771498511620953273042617406858321735530726344932408099165488584289967033858335421972359541682497767915", "162548641397864425007033850268175253283405380719117941089156537165135195086592774875578765923450602854858888293220", "221260309427853755502785129634482363739669961931806720344882703048230256180517088067328543678458564140886930272257", "180375548003313005104127243621926103826839403060610734021366321416278249305089517311915284649241831261070555492054", "97893426211581835629765150788277937240784207502249159063194927476737623450922027096549899554593139091226057965113", "151371923521478529010666608179192421722935157619415800529207300015895572527862014655812593382787606328053728017710", "109964484061854190657355119973679754635552284559995796399727184030860275176119164220986855589320219816237824633937") - E12TestPoints[8].out[16].SetString("11103685223415230263813529880980668474210237045643330203234419361865597262229012704558649769850611646973517000849", "204052271128901306565942609265066282845574872360203125629669202674577276002129145307148049195575162451263087237898", "134566449483280049070433074652849620016416649699045056090657395712632425818166930702404897348298393653380887777779", "136902779746695424464361259404374216448544079401142857556724232597034660318571328145049042277170355272677133073425", "38663128583832772793320761198755427185679610154715472016172012552376090666326564013890784719724692139784123665026", "90632081224135307717410770021618712245823720534589845933924683093696228320280890696527397103506349301307100522627", "112298095562001636546872845236797540180647157593405383561462483180963270005300780931268394142113810528376663933755", "233629851172623961591595196195223765102571999461530021238701456698851073035262443506623438684580442315002565883822", "218167866256822571789381763267086180146561973153980800273938231423188653182403395903909409492955864510455186439828", "29704286745681638028456530897652187334771161907168770783534202998719560703044006064856077038783375999867497618317", "250901422958837689202284065474690511664746066654567516942146078079627317553432916187047689913592812058428334278961", "68900424283768860327316618959678968915760351105548008358338586046313352525010102746730256608706764969063343967115") + E12TestPoints[8].out[3].SetString("46613539405002676128658801628192705940989180195955826057636528586112357749568229679692776819251002032205666357940", "42718069686378461075594140843537651822139390786353968004986631967208303554605043140852942249617402657744591417475", "119974254407433121215578001355732012206587382415747581352648049634996957525746023090183048653899267053322274406181", "81291501829346911474238123224466064358846841145041974614522022095352771462723867140467845948534429407359186169523", "4096335967862433257466137557520382891839544473840490122965764968943948096635872454306806149993062805592124704787", "69382051319564906985052564436072343345468707725147746236032815052204758958578000892240399568307299147731531781055", "11636196225048538024168472661501776937027064976340665078669497707234724009901476837643271945567972465543348872865", "188797699086891275256065380790653007793314877787215968775968150197063730004894538256751083392901766710215150180491", "130660813936041854503460067898787479165963858349111893672923809095495181409158195818759523700761288135257940936807", "57961547675913170622492784072481386512901946410046048603769316811334699418726276816965033294421845579117073382979", "215770515926161557718393834760274474464087186210865659534005806138307435561011193640143999799063402972989126259098", "234762439916123575853041524184554434989933682219298474199109732495497221062027478005111298940136035030649792668811") + E12TestPoints[8].out[4].SetString("229158025585174620312151266786248844371574245490368448207184998093138982353977297177349537597064197852775340457938", "206886723424221745989110343141220543288323692070116415831863604684126816435278720353120572071672812761614070827345", "145916102169716666065539987361786629217430015858939267011483521560154689634761667193144584358958280489597241200062", "240811534231391921758264710717258840799857480011926674211657046689020239773401550897403571282647217540168262361584", "248678782749779437944624292757225878767673738227972695081056063550782591394162547858324893732000533682400113354731", "234339977427668448550718033181253665335758354949261203255880900646096233524706974206806176203736113665061254256288", "27038237365941922701202935092295508313244052906382366436685711850491369707748975125177233232104523610618524398030", "64001110661578897894856274380311728450405488651857262462316618372586807591080258305939711789109594563735384922628", "205898181607118195707367690863792877751999310112546444534689346292803864535992999008877123668518219621047964725033", "7674000335223986358343660380760394260454466646586535812100056423472403912925732661670362361213608700062289289690", "116630244311347800083040626464371655012127266214560633814705662687742905768722630150252178530013438130860432874338", "240670659361796732058487071966675839343277687630960482298584561675797747274383434671198650093716471359391588907759") + E12TestPoints[8].out[5].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "255620416113434055453576946784466311854889092620609584281611369888188808194841414051302287931388347771953519546461", "178706773475359235176923405751079964183386316028964821957530590492682263309780459365485977390560164312162751061360", "205666368584361305382329371824691464171045709594840934321683333418552011014623503190112494145889853791749683877522", "237671405707868902684992726497380686213304295827910841250157940937066208380651562923368539120542301606997226264577", "14219177149219371288178644831879401727342947357727640598210845236564165434500254298652307467253141106095268985941", "1220107673978815121894335407449257157353639738861338816339545213486056835427613765494910837566583526554538117380", "136442797107999005145151225389072209106960014291718499587048361334502472200791190012860012625707472700377158744071", "208634751722627420663328628737376424094376980007890646052479443125498317576906764986227347657125196548783813208269", "163039729262514439540631181476382718032660198788281662804630508217695536161216090513472677549965746014597117644987", "222030229082056982743166846758162507088355632169386634667712414147308921365376754411114427521673362049465351434181", "29336952440633241952462087140256181024448093696725007469972568164504388581203794791624408092506513063987087068479") + E12TestPoints[8].out[6].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "3044009899535038557075786910427221681504420134305076258272892778531660153499408723666600208185012352486801911716", "186570615353179279430512844081537288362334908454596326610557744380601144267338207261762814913113308939790036802796", "102482532122020012645532727486742023392155364231858465206793234082278166162619303408421149472098194661987911145362", "80533582656794266016909634517969379672001617111922366814696830014318978700936453157542705735826327688028854104550", "5644114269204823621151251640886088701289526091023898497628158497052029326974910726305442267471222526111278239255", "118520874163474700317995612565010854687327537469468128279977022474014482050907489944965179894032724445634243308896", "149286080949931766467082957591580333455945456111104066488579389075036925998824233661592878148817406179449786302658", "81811808064397736477482069348136691312397277186381020850647481032475018223396786671197522420579010634145176164206", "59010415680539183173214614372394780682437740646510403598131366110366732883470195739946680287236119899483384899142", "25582475366446206585169539691246615589685739724536157694983600856502895580697110531130539596336234556143891394808", "72783763415735864235398906861232432640149328400665841517600642375334427371871379080408833841037595265815648332922") + E12TestPoints[8].out[7].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "255620416113434055453576946784466311854889092620609584281611369888188808194841414051302287931388347771953519546461", "7863841877820044253589438330457324178948592425631504653027153887918880957557747896276837522553144627627285741436", "209179951319556869993443368078353579509585951683129921551291957832610759519438838951404132661158671795143047893470", "199123863661275019319403106374437001187481112569996113014913754382055749615093629469026531422778090953854562547227", "250089363132954546343625340503900220510340091488210918439301575927208332240815479202622022939791441544456330711491", "73553023168638905670995604325987508185630187801467648481838918696808698202564199474142581814769138385481131795838", "77542561094851029528802571350699359602679015951815178447201716279494001160566082066699025483352527623826140060935", "208634751722627420663328628737376424094376980007890646052479443125498317576906764986227347657125196548783813208269", "163039729262514439540631181476382718032660198788281662804630508217695536161216090513472677549965746014597117644987", "89644324488726579208176902019297213087727334423251345583210217291577844377193354491339300679960581518943066763245", "4822063265666615965801792562594868292072634548832484012069418708974124434412278093640523154195961381131925744921") + E12TestPoints[8].out[8].SetString("53412243999301905168625573688822007989924773643251975593712240313124458639297666753991794379590051511913799555355", "3044009899535038557075786910427221681504420134305076258272892778531660153499408723666600208185012352486801911716", "79957652537609858833729327943813569353007196725949838582353672174038205038560363409482910749013195812277570396817", "205666368584361305382329371824691464171045709594840934321683333418552011014623503190112494145889853791749683877522", "237671405707868902684992726497380686213304295827910841250157940937066208380651562923368539120542301606997226264577", "244445248863749722722474088863014131809050565397187019941673417430156302913840568476316580672320219018345052472236", "177494254460933092632378357967415593942121382157615850393951237809463602220091360020049562655949615620946697511715", "108100904867913100897169621657540275335038428917361145653323008705093762137907991598298327155628127401497789053488", "176852617948571357533170664346756842223996235568533639689236781634245450124944036103771365718994349490295145293971", "199654010332429910837438119322498752853955772108404256941752896556353735464870627035022207852337240224956936559035", "185827075965108189481471732504325153800014328238607255410692722984199544107056044726428105491417050718185198782946", "107837327685399522501861241143173764672258410585911188482927858199474664439150324026809094348113558095548013858030") + E12TestPoints[8].out[9].SetString("131866027180704677022202884751556351007751088952213212003144604602595470533442816920678354298532011806525536774167", "194314205518456273776469614816591235307433817440637211442445861293000896842053626511337764169904439343893006591480", "234618416312613337850146059842619997586784587047081330057479334813557398418473860539422379946879516031267185080315", "194806143408046001789786388747921391906349204106586897515391522077323939203645279736276703667712089260580771527882", "134580210079542338308106798532666113279234816934573383577329431363032980219405647918555669544286031129975877743399", "135957548388771498511620953273042617406858321735530726344932408099165488584289967033858335421972359541682497767915", "162548641397864425007033850268175253283405380719117941089156537165135195086592774875578765923450602854858888293220", "221260309427853755502785129634482363739669961931806720344882703048230256180517088067328543678458564140886930272257", "180375548003313005104127243621926103826839403060610734021366321416278249305089517311915284649241831261070555492054", "97893426211581835629765150788277937240784207502249159063194927476737623450922027096549899554593139091226057965113", "151371923521478529010666608179192421722935157619415800529207300015895572527862014655812593382787606328053728017710", "109964484061854190657355119973679754635552284559995796399727184030860275176119164220986855589320219816237824633937") + E12TestPoints[8].out[10].SetString("11103685223415230263813529880980668474210237045643330203234419361865597262229012704558649769850611646973517000849", "204052271128901306565942609265066282845574872360203125629669202674577276002129145307148049195575162451263087237898", "134566449483280049070433074652849620016416649699045056090657395712632425818166930702404897348298393653380887777779", "136902779746695424464361259404374216448544079401142857556724232597034660318571328145049042277170355272677133073425", "38663128583832772793320761198755427185679610154715472016172012552376090666326564013890784719724692139784123665026", "90632081224135307717410770021618712245823720534589845933924683093696228320280890696527397103506349301307100522627", "112298095562001636546872845236797540180647157593405383561462483180963270005300780931268394142113810528376663933755", "233629851172623961591595196195223765102571999461530021238701456698851073035262443506623438684580442315002565883822", "218167866256822571789381763267086180146561973153980800273938231423188653182403395903909409492955864510455186439828", "29704286745681638028456530897652187334771161907168770783534202998719560703044006064856077038783375999867497618317", "250901422958837689202284065474690511664746066654567516942146078079627317553432916187047689913592812058428334278961", "68900424283768860327316618959678968915760351105548008358338586046313352525010102746730256608706764969063343967115") // benchmark inputs should be randomly generated, // so use the final test point diff --git a/bls377/e2.go b/bls377/e2.go index 335a4ed46..c5044ceb6 100644 --- a/bls377/e2.go +++ b/bls377/e2.go @@ -159,7 +159,10 @@ func (z *E2) Mul(x, y *E2) *E2 { aplusbcplusd.MulAssign(&cplusd) // [3]: (a+b)*(c+d) z.A1.Add(&ac, &bd) // ad+bc, [2] + [1] z.A1.Sub(&aplusbcplusd, &z.A1) // z.A1: [3] - [2] - [1] - MulByNonResidue(&z.A0, &bd) + { // begin inline: set &z.A0 to (&bd) * (5) + buf := *(&bd) + (&z.A0).Double(&buf).Double(&z.A0).AddAssign(&buf) + } // end inline: set &z.A0 to (&bd) * (5) z.A0.AddAssign(&ac) // z.A0: [1] + (5)*[2] return z } @@ -182,7 +185,10 @@ func (z *E2) MulAssign(x *E2) *E2 { aplusbcplusd.MulAssign(&cplusd) // [3]: (a+b)*(c+d) z.A1.Add(&ac, &bd) // ad+bc, [2] + [1] z.A1.Sub(&aplusbcplusd, &z.A1) // z.A1: [3] - [2] - [1] - MulByNonResidue(&z.A0, &bd) + { // begin inline: set &z.A0 to (&bd) * (5) + buf := *(&bd) + (&z.A0).Double(&buf).Double(&z.A0).AddAssign(&buf) + } // end inline: set &z.A0 to (&bd) * (5) z.A0.AddAssign(&ac) // z.A0: [1] + (5)*[2] return z } @@ -197,7 +203,10 @@ func (z *E2) Square(x *E2) *E2 { // Then z.A1: 2[1] var ab, aplusb, ababetab fp.Element - MulByNonResidue(&ababetab, &x.A1) + { // begin inline: set &ababetab to (&x.A1) * (5) + buf := *(&x.A1) + (&ababetab).Double(&buf).Double(&ababetab).AddAssign(&buf) + } // end inline: set &ababetab to (&x.A1) * (5) ababetab.AddAssign(&x.A0) // a+(5)*b aplusb.Add(&x.A0, &x.A1) // a+b @@ -210,15 +219,6 @@ func (z *E2) Square(x *E2) *E2 { return z } -// MulByNonSquare multiplies an element by (0,1) -// TODO deprecate in favor of inlined MulByNonResidue in fp6 package -func (z *E2) MulByNonSquare(x *E2) *E2 { - a := x.A0 - MulByNonResidue(&z.A0, &x.A1) - z.A1 = a - return z -} - // Inverse sets z to the E2-inverse of x, returns z func (z *E2) Inverse(x *E2) *E2 { // Algorithm 8 from https://eprint.iacr.org/2010/354.pdf @@ -229,7 +229,10 @@ func (z *E2) Inverse(x *E2) *E2 { t0.Square(&a0) // step 1 t1.Square(&a1) // step 2 - MulByNonResidue(&t1beta, &t1) + { // begin inline: set &t1beta to (&t1) * (5) + buf := *(&t1) + (&t1beta).Double(&buf).Double(&t1beta).AddAssign(&buf) + } // end inline: set &t1beta to (&t1) * (5) t0.SubAssign(&t1beta) // step 3 t1.Inverse(&t0) // step 4 z.A0.Mul(&a0, &t1) // step 5 @@ -253,26 +256,3 @@ func (z *E2) Conjugate(x *E2) *E2 { z.A1.Neg(&x.A1) return z } - -// MulByNonResidue multiplies a fp.Element by 5 -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidue(out, in *fp.Element) *fp.Element { - buf := *(in) - (out).Double(&buf).Double(out).AddAssign(&buf) - return out -} - -// MulByNonResidueInv multiplies a fp.Element by 5^{-1} -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidueInv(out, in *fp.Element) *fp.Element { - nrinv := fp.Element{ - 330620507644336508, - 9878087358076053079, - 11461392860540703536, - 6973035786057818995, - 8846909097162646007, - 104838758629667239, - } - (out).Mul(in, &nrinv) - return out -} diff --git a/bls377/e6.go b/bls377/e6.go index be08a2530..a62b5a253 100644 --- a/bls377/e6.go +++ b/bls377/e6.go @@ -16,8 +16,6 @@ package bls377 -import "github.com/consensys/gurvy/bls377/fp" - // E6 is a degree-three finite field extension of fp2: // B0 + B1v + B2v^2 where v^3-0,1 is irrep in fp2 @@ -113,14 +111,14 @@ func (z *E6) MulByGen(x *E6) *E6 { result.B1 = x.B0 result.B2 = x.B1 - { // begin: inline result.B0.MulByNonResidue(&x.B2) + { // begin inline: set result.B0 to (&x.B2) * (0,1) buf := (&x.B2).A0 - { // begin: inline MulByNonResidue(&(result.B0).A0, &(&x.B2).A1) + { // begin inline: set &(result.B0).A0 to (&(&x.B2).A1) * (5) buf := *(&(&x.B2).A1) (&(result.B0).A0).Double(&buf).Double(&(result.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(result.B0).A0, &(&x.B2).A1) + } // end inline: set &(result.B0).A0 to (&(&x.B2).A1) * (5) (result.B0).A1 = buf - } // end: inline result.B0.MulByNonResidue(&x.B2) + } // end inline: set result.B0 to (&x.B2) * (0,1) z.Set(&result) return z @@ -154,14 +152,14 @@ func (z *E6) Mul(x, y *E6) *E6 { rb0.Mul(&b3, &b4). SubAssign(&b1). SubAssign(&b2) - { // begin: inline rb0.MulByNonResidue(&rb0) + { // begin inline: set rb0 to (&rb0) * (0,1) buf := (&rb0).A0 - { // begin: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) + { // begin inline: set &(rb0).A0 to (&(&rb0).A1) * (5) buf := *(&(&rb0).A1) (&(rb0).A0).Double(&buf).Double(&(rb0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) + } // end inline: set &(rb0).A0 to (&(&rb0).A1) * (5) (rb0).A1 = buf - } // end: inline rb0.MulByNonResidue(&rb0) + } // end inline: set rb0 to (&rb0) * (0,1) rb0.AddAssign(&b0) // step 5 @@ -170,14 +168,14 @@ func (z *E6) Mul(x, y *E6) *E6 { z.B1.Mul(&b3, &b4). SubAssign(&b0). SubAssign(&b1) - { // begin: inline b3.MulByNonResidue(&b2) + { // begin inline: set b3 to (&b2) * (0,1) buf := (&b2).A0 - { // begin: inline MulByNonResidue(&(b3).A0, &(&b2).A1) + { // begin inline: set &(b3).A0 to (&(&b2).A1) * (5) buf := *(&(&b2).A1) (&(b3).A0).Double(&buf).Double(&(b3).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(b3).A0, &(&b2).A1) + } // end inline: set &(b3).A0 to (&(&b2).A1) * (5) (b3).A1 = buf - } // end: inline b3.MulByNonResidue(&b2) + } // end inline: set b3 to (&b2) * (0,1) z.B1.AddAssign(&b3) // step 6 @@ -206,14 +204,14 @@ func (z *E6) MulAssign(x *E6) *E6 { rb0.Mul(&b3, &b4). SubAssign(&b1). SubAssign(&b2) - { // begin: inline rb0.MulByNonResidue(&rb0) + { // begin inline: set rb0 to (&rb0) * (0,1) buf := (&rb0).A0 - { // begin: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) + { // begin inline: set &(rb0).A0 to (&(&rb0).A1) * (5) buf := *(&(&rb0).A1) (&(rb0).A0).Double(&buf).Double(&(rb0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) + } // end inline: set &(rb0).A0 to (&(&rb0).A1) * (5) (rb0).A1 = buf - } // end: inline rb0.MulByNonResidue(&rb0) + } // end inline: set rb0 to (&rb0) * (0,1) rb0.AddAssign(&b0) // step 5 @@ -222,14 +220,14 @@ func (z *E6) MulAssign(x *E6) *E6 { z.B1.Mul(&b3, &b4). SubAssign(&b0). SubAssign(&b1) - { // begin: inline b3.MulByNonResidue(&b2) + { // begin inline: set b3 to (&b2) * (0,1) buf := (&b2).A0 - { // begin: inline MulByNonResidue(&(b3).A0, &(&b2).A1) + { // begin inline: set &(b3).A0 to (&(&b2).A1) * (5) buf := *(&(&b2).A1) (&(b3).A0).Double(&buf).Double(&(b3).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(b3).A0, &(&b2).A1) + } // end inline: set &(b3).A0 to (&(&b2).A1) * (5) (b3).A1 = buf - } // end: inline b3.MulByNonResidue(&b2) + } // end inline: set b3 to (&b2) * (0,1) z.B1.AddAssign(&b3) // step 6 @@ -253,38 +251,6 @@ func (z *E6) MulByE2(x *E6, y *E2) *E6 { return z } -// MulByNotv2 multiplies x by y with &y.b2=0 -func (z *E6) MulByNotv2(x, y *E6) *E6 { - // Algorithm 15 from https://eprint.iacr.org/2010/354.pdf - var rb0, b0, b1, b2, b3 E2 - b0.Mul(&x.B0, &y.B0) // step 1 - b1.Mul(&x.B1, &y.B1) // step 2 - // step 3 - b2.Add(&x.B1, &x.B2) - rb0.Mul(&b2, &y.B1). - SubAssign(&b1) - { // begin: inline rb0.MulByNonResidue(&rb0) - buf := (&rb0).A0 - { // begin: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) - buf := *(&(&rb0).A1) - (&(rb0).A0).Double(&buf).Double(&(rb0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) - (rb0).A1 = buf - } // end: inline rb0.MulByNonResidue(&rb0) - rb0.AddAssign(&b0) - // step 4 - b2.Add(&x.B0, &x.B1) - b3.Add(&y.B0, &y.B1) - z.B1.Mul(&b2, &b3). - SubAssign(&b0). - SubAssign(&b1) - // step 5 - z.B2.Mul(&x.B2, &y.B0). - AddAssign(&b1) - z.B0 = rb0 - return z -} - // Square sets z to the E6-product of x,x, returns z func (z *E6) Square(x *E6) *E6 { @@ -294,28 +260,28 @@ func (z *E6) Square(x *E6) *E6 { b4.Square(&x.B2) // step 2 // step 3 - { // begin: inline b0.MulByNonResidue(&b4) + { // begin inline: set b0 to (&b4) * (0,1) buf := (&b4).A0 - { // begin: inline MulByNonResidue(&(b0).A0, &(&b4).A1) + { // begin inline: set &(b0).A0 to (&(&b4).A1) * (5) buf := *(&(&b4).A1) (&(b0).A0).Double(&buf).Double(&(b0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(b0).A0, &(&b4).A1) + } // end inline: set &(b0).A0 to (&(&b4).A1) * (5) (b0).A1 = buf - } // end: inline b0.MulByNonResidue(&b4) + } // end inline: set b0 to (&b4) * (0,1) b0.AddAssign(&b3) b1.Sub(&b3, &b4) // step 4 b2.Square(&x.B0) // step 5 b3.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&b3) // steps 6 and 8 b4.Mul(&x.B1, &x.B2).Double(&b4) // step 7 // step 9 - { // begin: inline z.B0.MulByNonResidue(&b4) + { // begin inline: set z.B0 to (&b4) * (0,1) buf := (&b4).A0 - { // begin: inline MulByNonResidue(&(z.B0).A0, &(&b4).A1) + { // begin inline: set &(z.B0).A0 to (&(&b4).A1) * (5) buf := *(&(&b4).A1) (&(z.B0).A0).Double(&buf).Double(&(z.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(z.B0).A0, &(&b4).A1) + } // end inline: set &(z.B0).A0 to (&(&b4).A1) * (5) (z.B0).A1 = buf - } // end: inline z.B0.MulByNonResidue(&b4) + } // end inline: set z.B0 to (&b4) * (0,1) z.B0.AddAssign(&b2) // step 10 @@ -335,28 +301,28 @@ func (z *E6) SquareAssign() *E6 { b4.Square(&z.B2) // step 2 // step 3 - { // begin: inline b0.MulByNonResidue(&b4) + { // begin inline: set b0 to (&b4) * (0,1) buf := (&b4).A0 - { // begin: inline MulByNonResidue(&(b0).A0, &(&b4).A1) + { // begin inline: set &(b0).A0 to (&(&b4).A1) * (5) buf := *(&(&b4).A1) (&(b0).A0).Double(&buf).Double(&(b0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(b0).A0, &(&b4).A1) + } // end inline: set &(b0).A0 to (&(&b4).A1) * (5) (b0).A1 = buf - } // end: inline b0.MulByNonResidue(&b4) + } // end inline: set b0 to (&b4) * (0,1) b0.AddAssign(&b3) b1.Sub(&b3, &b4) // step 4 b2.Square(&z.B0) // step 5 b3.Sub(&z.B0, &z.B1).AddAssign(&z.B2).Square(&b3) // steps 6 and 8 b4.Mul(&z.B1, &z.B2).Double(&b4) // step 7 // step 9 - { // begin: inline z.B0.MulByNonResidue(&b4) + { // begin inline: set z.B0 to (&b4) * (0,1) buf := (&b4).A0 - { // begin: inline MulByNonResidue(&(z.B0).A0, &(&b4).A1) + { // begin inline: set &(z.B0).A0 to (&(&b4).A1) * (5) buf := *(&(&b4).A1) (&(z.B0).A0).Double(&buf).Double(&(z.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(z.B0).A0, &(&b4).A1) + } // end inline: set &(z.B0).A0 to (&(&b4).A1) * (5) (z.B0).A1 = buf - } // end: inline z.B0.MulByNonResidue(&b4) + } // end inline: set z.B0 to (&b4) * (0,1) z.B0.AddAssign(&b2) // step 10 @@ -381,23 +347,23 @@ func (z *E6) SquarE2(x *E6) *E6 { v12.Add(&x.B1, &x.B2) v12.Square(&v12) z.B0.Sub(&v12, &v1).SubAssign(&v2) - { // begin: inline z.B0.MulByNonResidue(&z.B0) + { // begin inline: set z.B0 to (&z.B0) * (0,1) buf := (&z.B0).A0 - { // begin: inline MulByNonResidue(&(z.B0).A0, &(&z.B0).A1) + { // begin inline: set &(z.B0).A0 to (&(&z.B0).A1) * (5) buf := *(&(&z.B0).A1) (&(z.B0).A0).Double(&buf).Double(&(z.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(z.B0).A0, &(&z.B0).A1) + } // end inline: set &(z.B0).A0 to (&(&z.B0).A1) * (5) (z.B0).A1 = buf - } // end: inline z.B0.MulByNonResidue(&z.B0) + } // end inline: set z.B0 to (&z.B0) * (0,1) z.B0.AddAssign(&v0) - { // begin: inline z.B1.MulByNonResidue(&v2) + { // begin inline: set z.B1 to (&v2) * (0,1) buf := (&v2).A0 - { // begin: inline MulByNonResidue(&(z.B1).A0, &(&v2).A1) + { // begin inline: set &(z.B1).A0 to (&(&v2).A1) * (5) buf := *(&(&v2).A1) (&(z.B1).A0).Double(&buf).Double(&(z.B1).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(z.B1).A0, &(&v2).A1) + } // end inline: set &(z.B1).A0 to (&(&v2).A1) * (5) (z.B1).A1 = buf - } // end: inline z.B1.MulByNonResidue(&v2) + } // end inline: set z.B1 to (&v2) * (0,1) z.B1.AddAssign(&v01).SubAssign(&v0).SubAssign(&v1) z.B2.Add(&v02, &v1).SubAssign(&v0).SubAssign(&v2) return z @@ -412,23 +378,23 @@ func (z *E6) Square3(x *E6) *E6 { s2.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&s2) s3.Mul(&x.B1, &x.B2).Double(&s3) s4.Square(&x.B2) - { // begin: inline z.B0.MulByNonResidue(&s3) + { // begin inline: set z.B0 to (&s3) * (0,1) buf := (&s3).A0 - { // begin: inline MulByNonResidue(&(z.B0).A0, &(&s3).A1) + { // begin inline: set &(z.B0).A0 to (&(&s3).A1) * (5) buf := *(&(&s3).A1) (&(z.B0).A0).Double(&buf).Double(&(z.B0).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(z.B0).A0, &(&s3).A1) + } // end inline: set &(z.B0).A0 to (&(&s3).A1) * (5) (z.B0).A1 = buf - } // end: inline z.B0.MulByNonResidue(&s3) + } // end inline: set z.B0 to (&s3) * (0,1) z.B0.AddAssign(&s0) - { // begin: inline z.B1.MulByNonResidue(&s4) + { // begin inline: set z.B1 to (&s4) * (0,1) buf := (&s4).A0 - { // begin: inline MulByNonResidue(&(z.B1).A0, &(&s4).A1) + { // begin inline: set &(z.B1).A0 to (&(&s4).A1) * (5) buf := *(&(&s4).A1) (&(z.B1).A0).Double(&buf).Double(&(z.B1).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(z.B1).A0, &(&s4).A1) + } // end inline: set &(z.B1).A0 to (&(&s4).A1) * (5) (z.B1).A1 = buf - } // end: inline z.B1.MulByNonResidue(&s4) + } // end inline: set z.B1 to (&s4) * (0,1) z.B1.AddAssign(&s1) z.B2.Add(&s1, &s2).AddAssign(&s3).SubAssign(&s0).SubAssign(&s4) return z @@ -449,38 +415,38 @@ func (z *E6) Inverse(x *E6) *E6 { t[4].Mul(&x.B0, &x.B2) // step 5 t[5].Mul(&x.B1, &x.B2) // step 6 // step 7 - { // begin: inline c[0].MulByNonResidue(&t[5]) + { // begin inline: set c[0] to (&t[5]) * (0,1) buf := (&t[5]).A0 - { // begin: inline MulByNonResidue(&(c[0]).A0, &(&t[5]).A1) + { // begin inline: set &(c[0]).A0 to (&(&t[5]).A1) * (5) buf := *(&(&t[5]).A1) (&(c[0]).A0).Double(&buf).Double(&(c[0]).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(c[0]).A0, &(&t[5]).A1) + } // end inline: set &(c[0]).A0 to (&(&t[5]).A1) * (5) (c[0]).A1 = buf - } // end: inline c[0].MulByNonResidue(&t[5]) + } // end inline: set c[0] to (&t[5]) * (0,1) c[0].Neg(&c[0]).AddAssign(&t[0]) // step 8 - { // begin: inline c[1].MulByNonResidue(&t[2]) + { // begin inline: set c[1] to (&t[2]) * (0,1) buf := (&t[2]).A0 - { // begin: inline MulByNonResidue(&(c[1]).A0, &(&t[2]).A1) + { // begin inline: set &(c[1]).A0 to (&(&t[2]).A1) * (5) buf := *(&(&t[2]).A1) (&(c[1]).A0).Double(&buf).Double(&(c[1]).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(c[1]).A0, &(&t[2]).A1) + } // end inline: set &(c[1]).A0 to (&(&t[2]).A1) * (5) (c[1]).A1 = buf - } // end: inline c[1].MulByNonResidue(&t[2]) + } // end inline: set c[1] to (&t[2]) * (0,1) c[1].SubAssign(&t[3]) c[2].Sub(&t[1], &t[4]) // step 9 is wrong in 2010/354! // steps 10, 11, 12 t[6].Mul(&x.B2, &c[1]) buf.Mul(&x.B1, &c[2]) t[6].AddAssign(&buf) - { // begin: inline t[6].MulByNonResidue(&t[6]) + { // begin inline: set t[6] to (&t[6]) * (0,1) buf := (&t[6]).A0 - { // begin: inline MulByNonResidue(&(t[6]).A0, &(&t[6]).A1) + { // begin inline: set &(t[6]).A0 to (&(&t[6]).A1) * (5) buf := *(&(&t[6]).A1) (&(t[6]).A0).Double(&buf).Double(&(t[6]).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(t[6]).A0, &(&t[6]).A1) + } // end inline: set &(t[6]).A0 to (&(&t[6]).A1) * (5) (t[6]).A1 = buf - } // end: inline t[6].MulByNonResidue(&t[6]) + } // end inline: set t[6] to (&t[6]) * (0,1) buf.Mul(&x.B0, &c[0]) t[6].AddAssign(&buf) @@ -490,32 +456,3 @@ func (z *E6) Inverse(x *E6) *E6 { z.B2.Mul(&c[2], &t[6]) // step 16 return z } - -// MulByNonResidue multiplies a E2 by (0,1) -func (z *E2) MulByNonResidue(x *E2) *E2 { - buf := (x).A0 - { // begin: inline MulByNonResidue(&(z).A0, &(x).A1) - buf := *(&(x).A1) - (&(z).A0).Double(&buf).Double(&(z).A0).AddAssign(&buf) - } // end: inline MulByNonResidue(&(z).A0, &(x).A1) - (z).A1 = buf - return z -} - -// MulByNonResidueInv multiplies a E2 by (0,1)^{-1} -func (z *E2) MulByNonResidueInv(x *E2) *E2 { - buf := (x).A1 - { // begin: inline MulByNonResidueInv(&(z).A1, &(x).A0) - nrinv := fp.Element{ - 330620507644336508, - 9878087358076053079, - 11461392860540703536, - 6973035786057818995, - 8846909097162646007, - 104838758629667239, - } - (&(z).A1).Mul(&(x).A0, &nrinv) - } // end: inline MulByNonResidueInv(&(z).A1, &(x).A0) - (z).A0 = buf - return z -} diff --git a/bls377/pairing.go b/bls377/pairing.go index 56c86ad55..5afe6fcbb 100644 --- a/bls377/pairing.go +++ b/bls377/pairing.go @@ -213,7 +213,7 @@ type lineEvalRes struct { func (l *lineEvalRes) mulAssign(z *PairingResult) *PairingResult { - var a, b, c E12 + var a, b, c PairingResult a.MulByVW(z, &l.r1) b.MulByV(z, &l.r0) c.MulByV2W(z, &l.r2) @@ -222,6 +222,78 @@ func (l *lineEvalRes) mulAssign(z *PairingResult) *PairingResult { return z } +// MulByVW set z to x*(y*v*w) and return z +// here y*v*w means the PairingResult element with C1.B1=y and all other components 0 +func (z *PairingResult) MulByVW(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNR G2CoordType + + { // begin inline: set yNR to (y) * (0,1) + buf := (y).A0 + { // begin inline: set &(yNR).A0 to (&(y).A1) * (5) + buf := *(&(y).A1) + (&(yNR).A0).Double(&buf).Double(&(yNR).A0).AddAssign(&buf) + } // end inline: set &(yNR).A0 to (&(y).A1) * (5) + (yNR).A1 = buf + } // end inline: set yNR to (y) * (0,1) + result.C0.B0.Mul(&x.C1.B1, &yNR) + result.C0.B1.Mul(&x.C1.B2, &yNR) + result.C0.B2.Mul(&x.C1.B0, y) + result.C1.B0.Mul(&x.C0.B2, &yNR) + result.C1.B1.Mul(&x.C0.B0, y) + result.C1.B2.Mul(&x.C0.B1, y) + z.Set(&result) + return z +} + +// MulByV set z to x*(y*v) and return z +// here y*v means the PairingResult element with C0.B1=y and all other components 0 +func (z *PairingResult) MulByV(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNR G2CoordType + + { // begin inline: set yNR to (y) * (0,1) + buf := (y).A0 + { // begin inline: set &(yNR).A0 to (&(y).A1) * (5) + buf := *(&(y).A1) + (&(yNR).A0).Double(&buf).Double(&(yNR).A0).AddAssign(&buf) + } // end inline: set &(yNR).A0 to (&(y).A1) * (5) + (yNR).A1 = buf + } // end inline: set yNR to (y) * (0,1) + result.C0.B0.Mul(&x.C0.B2, &yNR) + result.C0.B1.Mul(&x.C0.B0, y) + result.C0.B2.Mul(&x.C0.B1, y) + result.C1.B0.Mul(&x.C1.B2, &yNR) + result.C1.B1.Mul(&x.C1.B0, y) + result.C1.B2.Mul(&x.C1.B1, y) + z.Set(&result) + return z +} + +// MulByV2W set z to x*(y*v^2*w) and return z +// here y*v^2*w means the PairingResult element with C1.B2=y and all other components 0 +func (z *PairingResult) MulByV2W(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNR G2CoordType + + { // begin inline: set yNR to (y) * (0,1) + buf := (y).A0 + { // begin inline: set &(yNR).A0 to (&(y).A1) * (5) + buf := *(&(y).A1) + (&(yNR).A0).Double(&buf).Double(&(yNR).A0).AddAssign(&buf) + } // end inline: set &(yNR).A0 to (&(y).A1) * (5) + (yNR).A1 = buf + } // end inline: set yNR to (y) * (0,1) + result.C0.B0.Mul(&x.C1.B0, &yNR) + result.C0.B1.Mul(&x.C1.B1, &yNR) + result.C0.B2.Mul(&x.C1.B2, &yNR) + result.C1.B0.Mul(&x.C0.B1, &yNR) + result.C1.B1.Mul(&x.C0.B2, &yNR) + result.C1.B2.Mul(&x.C0.B0, y) + z.Set(&result) + return z +} + const tAbsVal uint64 = 9586122913090633729 // Expt set z to x^t in PairingResult and return z diff --git a/bls381/e12.go b/bls381/e12.go index 6730a926d..4431a7b6d 100644 --- a/bls381/e12.go +++ b/bls381/e12.go @@ -16,10 +16,6 @@ package bls381 -import ( - "github.com/consensys/gurvy/bls381/fp" -) - // E12 is a degree-two finite field extension of fp6: // C0 + C1w where w^3-v is irrep in fp6 @@ -135,21 +131,21 @@ func (z *E12) Mul(x, y *E12) *E12 { ySum.Add(&y.C0, &y.C1) // step 3 - { // begin: inline z.C0.MulByNonResidue(&t1) + { // begin inline: set z.C0 to (&t1) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&t1).B0) result.B2.Set(&(&t1).B1) - { // begin: inline result.B0.MulByNonResidue(&(&t1).B2) + { // begin inline: set result.B0 to (&(&t1).B2) * (1,1) var buf E2 buf.Set(&(&t1).B2) result.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + { // begin inline: set &(result.B0).A0 to (&buf.A1) * (-1) (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + } // end inline: set &(result.B0).A0 to (&buf.A1) * (-1) result.B0.A0.AddAssign(&buf.A0) - } // end: inline result.B0.MulByNonResidue(&(&t1).B2) + } // end inline: set result.B0 to (&(&t1).B2) * (1,1) z.C0.Set(&result) - } // end: inline z.C0.MulByNonResidue(&t1) + } // end inline: set z.C0 to (&t1) * ((0,0),(1,0),(0,0)) z.C0.Add(&z.C0, &t0) // step 4 @@ -169,21 +165,21 @@ func (z *E12) Square(x *E12) *E12 { b0.Square(&x.C0) b1.Square(&x.C1) - { // begin: inline b1.MulByNonResidue(&b1) + { // begin inline: set b1 to (&b1) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&b1).B0) result.B2.Set(&(&b1).B1) - { // begin: inline result.B0.MulByNonResidue(&(&b1).B2) + { // begin inline: set result.B0 to (&(&b1).B2) * (1,1) var buf E2 buf.Set(&(&b1).B2) result.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + { // begin inline: set &(result.B0).A0 to (&buf.A1) * (-1) (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + } // end inline: set &(result.B0).A0 to (&buf.A1) * (-1) result.B0.A0.AddAssign(&buf.A0) - } // end: inline result.B0.MulByNonResidue(&(&b1).B2) + } // end inline: set result.B0 to (&(&b1).B2) * (1,1) b1.Set(&result) - } // end: inline b1.MulByNonResidue(&b1) + } // end inline: set b1 to (&b1) * ((0,0),(1,0),(0,0)) b1.Add(&b0, &b1) z.C1.Mul(&x.C0, &x.C1).Double(&z.C1) @@ -202,21 +198,21 @@ func (z *E12) Inverse(x *E12) *E12 { t[1].Square(&x.C1) // step 2 { // step 3 var buf E6 - { // begin: inline buf.MulByNonResidue(&t[1]) + { // begin inline: set buf to (&t[1]) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&t[1]).B0) result.B2.Set(&(&t[1]).B1) - { // begin: inline result.B0.MulByNonResidue(&(&t[1]).B2) + { // begin inline: set result.B0 to (&(&t[1]).B2) * (1,1) var buf E2 buf.Set(&(&t[1]).B2) result.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + { // begin inline: set &(result.B0).A0 to (&buf.A1) * (-1) (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + } // end inline: set &(result.B0).A0 to (&buf.A1) * (-1) result.B0.A0.AddAssign(&buf.A0) - } // end: inline result.B0.MulByNonResidue(&(&t[1]).B2) + } // end inline: set result.B0 to (&(&t[1]).B2) * (1,1) buf.Set(&result) - } // end: inline buf.MulByNonResidue(&t[1]) + } // end inline: set buf to (&t[1]) * ((0,0),(1,0),(0,0)) t[0].Sub(&t[0], &buf) } t[1].Inverse(&t[0]) // step 4 @@ -238,204 +234,3 @@ func (z *E12) Conjugate(x *E12) *E12 { z.C1.Neg(&z.C1) return z } - -// MulByVW set z to x*(y*v*w) and return z -// here y*v*w means the E12 element with C1.B1=y and all other components 0 -func (z *E12) MulByVW(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - var buf E2 - buf.Set(y) - yNR.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(yNR).A0, &buf.A1) - (&(yNR).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(yNR).A0, &buf.A1) - yNR.A0.AddAssign(&buf.A0) - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C1.B1, &yNR) - result.C0.B1.Mul(&x.C1.B2, &yNR) - result.C0.B2.Mul(&x.C1.B0, y) - result.C1.B0.Mul(&x.C0.B2, &yNR) - result.C1.B1.Mul(&x.C0.B0, y) - result.C1.B2.Mul(&x.C0.B1, y) - z.Set(&result) - return z -} - -// MulByV set z to x*(y*v) and return z -// here y*v means the E12 element with C0.B1=y and all other components 0 -func (z *E12) MulByV(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - var buf E2 - buf.Set(y) - yNR.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(yNR).A0, &buf.A1) - (&(yNR).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(yNR).A0, &buf.A1) - yNR.A0.AddAssign(&buf.A0) - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C0.B2, &yNR) - result.C0.B1.Mul(&x.C0.B0, y) - result.C0.B2.Mul(&x.C0.B1, y) - result.C1.B0.Mul(&x.C1.B2, &yNR) - result.C1.B1.Mul(&x.C1.B0, y) - result.C1.B2.Mul(&x.C1.B1, y) - z.Set(&result) - return z -} - -// MulByV2W set z to x*(y*v^2*w) and return z -// here y*v^2*w means the E12 element with C1.B2=y and all other components 0 -func (z *E12) MulByV2W(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - var buf E2 - buf.Set(y) - yNR.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(yNR).A0, &buf.A1) - (&(yNR).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(yNR).A0, &buf.A1) - yNR.A0.AddAssign(&buf.A0) - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C1.B0, &yNR) - result.C0.B1.Mul(&x.C1.B1, &yNR) - result.C0.B2.Mul(&x.C1.B2, &yNR) - result.C1.B0.Mul(&x.C0.B1, &yNR) - result.C1.B1.Mul(&x.C0.B2, &yNR) - result.C1.B2.Mul(&x.C0.B0, y) - z.Set(&result) - return z -} - -// MulByV2NRInv set z to x*(y*v^2*(1,1)^{-1}) and return z -// here y*v^2 means the E12 element with C0.B2=y and all other components 0 -func (z *E12) MulByV2NRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - // (yNRInv).A0 = ((y).A0 + (y).A1)/2 - // (yNRInv).A1 = ((y).A1 - (y).A0)/2 - buf := *(y) - (yNRInv).A0.Add(&buf.A0, &buf.A1) - (yNRInv).A1.Sub(&buf.A1, &buf.A0) - twoInv := fp.Element{ - 1730508156817200468, - 9606178027640717313, - 7150789853162776431, - 7936136305760253186, - 15245073033536294050, - 1728177566264616342, - } - (yNRInv).A0.MulAssign(&twoInv) - (yNRInv).A1.MulAssign(&twoInv) - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C0.B1, y) - result.C0.B1.Mul(&x.C0.B2, y) - result.C0.B2.Mul(&x.C0.B0, &yNRInv) - - result.C1.B0.Mul(&x.C1.B1, y) - result.C1.B1.Mul(&x.C1.B2, y) - result.C1.B2.Mul(&x.C1.B0, &yNRInv) - - z.Set(&result) - return z -} - -// MulByVWNRInv set z to x*(y*v*w*(1,1)^{-1}) and return z -// here y*v*w means the E12 element with C1.B1=y and all other components 0 -func (z *E12) MulByVWNRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - // (yNRInv).A0 = ((y).A0 + (y).A1)/2 - // (yNRInv).A1 = ((y).A1 - (y).A0)/2 - buf := *(y) - (yNRInv).A0.Add(&buf.A0, &buf.A1) - (yNRInv).A1.Sub(&buf.A1, &buf.A0) - twoInv := fp.Element{ - 1730508156817200468, - 9606178027640717313, - 7150789853162776431, - 7936136305760253186, - 15245073033536294050, - 1728177566264616342, - } - (yNRInv).A0.MulAssign(&twoInv) - (yNRInv).A1.MulAssign(&twoInv) - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C1.B1, y) - result.C0.B1.Mul(&x.C1.B2, y) - result.C0.B2.Mul(&x.C1.B0, &yNRInv) - - result.C1.B0.Mul(&x.C0.B2, y) - result.C1.B1.Mul(&x.C0.B0, &yNRInv) - result.C1.B2.Mul(&x.C0.B1, &yNRInv) - - z.Set(&result) - return z -} - -// MulByWNRInv set z to x*(y*w*(1,1)^{-1}) and return z -// here y*w means the E12 element with C1.B0=y and all other components 0 -func (z *E12) MulByWNRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - // (yNRInv).A0 = ((y).A0 + (y).A1)/2 - // (yNRInv).A1 = ((y).A1 - (y).A0)/2 - buf := *(y) - (yNRInv).A0.Add(&buf.A0, &buf.A1) - (yNRInv).A1.Sub(&buf.A1, &buf.A0) - twoInv := fp.Element{ - 1730508156817200468, - 9606178027640717313, - 7150789853162776431, - 7936136305760253186, - 15245073033536294050, - 1728177566264616342, - } - (yNRInv).A0.MulAssign(&twoInv) - (yNRInv).A1.MulAssign(&twoInv) - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C1.B2, y) - result.C0.B1.Mul(&x.C1.B0, &yNRInv) - result.C0.B2.Mul(&x.C1.B1, &yNRInv) - - result.C1.B0.Mul(&x.C0.B0, &yNRInv) - result.C1.B1.Mul(&x.C0.B1, &yNRInv) - result.C1.B2.Mul(&x.C0.B2, &yNRInv) - - z.Set(&result) - return z -} - -// MulByNonResidue multiplies a E6 by ((0,0),(1,0),(0,0)) -func (z *E6) MulByNonResidue(x *E6) *E6 { - var result E6 - result.B1.Set(&(x).B0) - result.B2.Set(&(x).B1) - { // begin: inline result.B0.MulByNonResidue(&(x).B2) - var buf E2 - buf.Set(&(x).B2) - result.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) - (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) - result.B0.A0.AddAssign(&buf.A0) - } // end: inline result.B0.MulByNonResidue(&(x).B2) - z.Set(&result) - return z -} diff --git a/bls381/e12_test.go b/bls381/e12_test.go index 1d79ee800..1174243a8 100644 --- a/bls381/e12_test.go +++ b/bls381/e12_test.go @@ -8,7 +8,7 @@ import ( type E12TestPoint struct { in [2]E12 - out [17]E12 + out [11]E12 } var E12TestPoints []E12TestPoint @@ -77,60 +77,36 @@ func TestE12Mul(t *testing.T) { E12check(t, (*E12).Mul, 2) } -func TestE12MulByV(t *testing.T) { - E12check(t, (*E12).MulByVBinary, 3) -} - -func TestE12MulByVW(t *testing.T) { - E12check(t, (*E12).MulByVWBinary, 4) -} - -func TestE12MulByV2W(t *testing.T) { - E12check(t, (*E12).MulByV2WBinary, 5) -} - -func TestE12MulByV2NRInv(t *testing.T) { - E12check(t, (*E12).MulByV2NRInvBinary, 6) -} - -func TestE12MulByVWNRInv(t *testing.T) { - E12check(t, (*E12).MulByVWNRInvBinary, 7) -} - -func TestE12MulByWNRInv(t *testing.T) { - E12check(t, (*E12).MulByWNRInvBinary, 8) -} - func TestE12Square(t *testing.T) { - E12check(t, (*E12).SquareBinary, 9) + E12check(t, (*E12).SquareBinary, 3) } func TestE12Inverse(t *testing.T) { - E12check(t, (*E12).InverseBinary, 10) + E12check(t, (*E12).InverseBinary, 4) } func TestE12Conjugate(t *testing.T) { - E12check(t, (*E12).ConjugateBinary, 11) + E12check(t, (*E12).ConjugateBinary, 5) } func TestE12Frobenius(t *testing.T) { - E12check(t, (*E12).FrobeniusBinary, 12) + E12check(t, (*E12).FrobeniusBinary, 6) } func TestE12FrobeniusSquare(t *testing.T) { - E12check(t, (*E12).FrobeniusSquareBinary, 13) + E12check(t, (*E12).FrobeniusSquareBinary, 7) } func TestE12FrobeniusCube(t *testing.T) { - E12check(t, (*E12).FrobeniusCubeBinary, 14) + E12check(t, (*E12).FrobeniusCubeBinary, 8) } func TestE12Expt(t *testing.T) { - E12check(t, (*E12).ExptBinary, 15) + E12check(t, (*E12).ExptBinary, 9) } func TestE12FinalExponentiation(t *testing.T) { - E12check(t, (*E12).FinalExponentiationBinary, 16) + E12check(t, (*E12).FinalExponentiationBinary, 10) } //--------------------// @@ -157,42 +133,6 @@ func BenchmarkE12Mul(b *testing.B) { } } -func BenchmarkE12MulByV(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByVW(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVWBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByV2W(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByV2WBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByV2NRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByV2NRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByVWNRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVWNRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByWNRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByWNRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - func BenchmarkE12Square(b *testing.B) { for i := 0; i < b.N; i++ { E12BenchOut.SquareBinary(&E12BenchIn1, &E12BenchIn2) @@ -293,45 +233,3 @@ func (z *E12) ExptBinary(x, y *E12) *E12 { return z } - -// MulByVBinary a binary wrapper for MulByV -func (z *E12) MulByVBinary(x, y *E12) *E12 { - yCopy := y.C0.B1 - z.MulByV(x, &yCopy) - return z -} - -// MulByVWBinary a binary wrapper for MulByVW -func (z *E12) MulByVWBinary(x, y *E12) *E12 { - yCopy := y.C1.B1 - z.MulByVW(x, &yCopy) - return z -} - -// MulByV2WBinary a binary wrapper for MulByV2W -func (z *E12) MulByV2WBinary(x, y *E12) *E12 { - yCopy := y.C1.B2 - z.MulByV2W(x, &yCopy) - return z -} - -// MulByV2NRInvBinary a binary wrapper for MulByV2NRInv -func (z *E12) MulByV2NRInvBinary(x, y *E12) *E12 { - yCopy := y.C0.B2 - z.MulByV2NRInv(x, &yCopy) - return z -} - -// MulByVWNRInvBinary a binary wrapper for MulByVWNRInv -func (z *E12) MulByVWNRInvBinary(x, y *E12) *E12 { - yCopy := y.C1.B1 - z.MulByVWNRInv(x, &yCopy) - return z -} - -// MulByWNRInvBinary a binary wrapper for MulByWNRInv -func (z *E12) MulByWNRInvBinary(x, y *E12) *E12 { - yCopy := y.C1.B0 - z.MulByWNRInv(x, &yCopy) - return z -} diff --git a/bls381/e12testpoints_test.go b/bls381/e12testpoints_test.go index 81aad5641..6ad2b3ddb 100644 --- a/bls381/e12testpoints_test.go +++ b/bls381/e12testpoints_test.go @@ -18,172 +18,118 @@ func init() { E12TestPoints[0].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[0].out[9].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[0].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[15].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[16].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].in[0].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[0].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[1].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[9].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[10].SetString("0", "0", "0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[11].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[12].SetString("0", "0", "0", "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[13].SetString("0", "0", "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[14].SetString("0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[15].SetString("0", "0", "0", "0", "0", "1531167010076010104265380948281075035781828491938381734313146386857216833430924011676324336711424558603557834443335", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[3].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[4].SetString("0", "0", "0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[5].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[6].SetString("0", "0", "0", "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[7].SetString("0", "0", "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[8].SetString("0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[9].SetString("0", "0", "0", "0", "0", "1531167010076010104265380948281075035781828491938381734313146386857216833430924011676324336711424558603557834443335", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].in[0].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[0].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[1].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[9].SetString("0", "0", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[10].SetString("0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[11].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[12].SetString("0", "0", "0", "0", "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[13].SetString("0", "0", "0", "0", "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[14].SetString("0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[15].SetString("0", "0", "618051147002072081975380982845929153882217543045579389650228529845406089882786003458784753351050726454796838474161", "618051147002072081975380982845929153882217543045579389650228529845406089882786003458784753351050726454796838474161", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[3].SetString("0", "0", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[4].SetString("0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[5].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[6].SetString("0", "0", "0", "0", "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[7].SetString("0", "0", "0", "0", "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[8].SetString("0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[9].SetString("0", "0", "618051147002072081975380982845929153882217543045579389650228529845406089882786003458784753351050726454796838474161", "618051147002072081975380982845929153882217543045579389650228529845406089882786003458784753351050726454796838474161", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[3].in[0].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[3].out[0].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].out[1].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[9].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893") - E12TestPoints[3].out[11].SetString("0", "0", "0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0", "0", "0", "0", "0") - E12TestPoints[3].out[12].SetString("0", "0", "0", "0", "0", "0", "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760", "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027", "0", "0", "0", "0") - E12TestPoints[3].out[13].SetString("0", "0", "0", "0", "0", "0", "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351", "0", "0", "0", "0", "0") - E12TestPoints[3].out[14].SetString("0", "0", "0", "0", "0", "0", "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530", "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257", "0", "0", "0", "0") - E12TestPoints[3].out[15].SetString("0", "0", "2959966731190856622412436119196184812157267906799877360220017165970419425845869334278964550326055610105643837543370", "2959966731190856622412436119196184812157267906799877360220017165970419425845869334278964550326055610105643837543370", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[3].out[3].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[3].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893") + E12TestPoints[3].out[5].SetString("0", "0", "0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0", "0", "0", "0", "0") + E12TestPoints[3].out[6].SetString("0", "0", "0", "0", "0", "0", "3850754370037169011952147076051364057158807420970682438676050522613628423219637725072182697113062777891589506424760", "151655185184498381465642749684540099398075398968325446656007613510403227271200139370504932015952886146304766135027", "0", "0", "0", "0") + E12TestPoints[3].out[7].SetString("0", "0", "0", "0", "0", "0", "793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620351", "0", "0", "0", "0", "0") + E12TestPoints[3].out[8].SetString("0", "0", "0", "0", "0", "0", "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530", "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257", "0", "0", "0", "0") + E12TestPoints[3].out[9].SetString("0", "0", "2959966731190856622412436119196184812157267906799877360220017165970419425845869334278964550326055610105643837543370", "2959966731190856622412436119196184812157267906799877360220017165970419425845869334278964550326055610105643837543370", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[3].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[4].in[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[4].out[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].out[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[9].SetString("1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893", "0", "0") - E12TestPoints[4].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0", "0", "0") - E12TestPoints[4].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257", "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257", "0", "0") - E12TestPoints[4].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0", "0", "0") - E12TestPoints[4].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530", "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530", "0", "0") - E12TestPoints[4].out[15].SetString("1179571815585788646479215548487624391649390749168842928270673081195050193434236352954668666256448418017854847226412", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[4].out[3].SetString("1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[4].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893", "0", "0") + E12TestPoints[4].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0", "0", "0") + E12TestPoints[4].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257", "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257", "0", "0") + E12TestPoints[4].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0", "0", "0") + E12TestPoints[4].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530", "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530", "0", "0") + E12TestPoints[4].out[9].SetString("1179571815585788646479215548487624391649390749168842928270673081195050193434236352954668666256448418017854847226412", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[4].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[5].in[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[5].out[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].out[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[9].SetString("0", "0", "0", "0", "1", "1", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[10].SetString("0", "0", "0", "0", "0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893", "0", "0", "0", "0") - E12TestPoints[5].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0") - E12TestPoints[5].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230", "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557") - E12TestPoints[5].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437", "0") - E12TestPoints[5].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257", "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530") - E12TestPoints[5].out[15].SetString("0", "0", "0", "0", "0", "860874299824359755284038922585449358596602598560122936245029876424895542656824724041995715010416570765928267724018", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[5].out[3].SetString("0", "0", "0", "0", "1", "1", "0", "0", "0", "0", "0", "0") + E12TestPoints[5].out[4].SetString("0", "0", "0", "0", "0", "0", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279894", "2001204777610833696708894912867952078278441409969503942666029068062015825245418932221343814564507832018947136279893", "0", "0", "0", "0") + E12TestPoints[5].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786", "0") + E12TestPoints[5].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "877076961050607968509681729531255177986764537961432449499635504522207616027455086505066378536590128544573588734230", "3125332594171059424908108096204648978570118281977575435832422631601824034463382777937621250592425535493320683825557") + E12TestPoints[5].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437", "0") + E12TestPoints[5].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257", "2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530") + E12TestPoints[5].out[9].SetString("0", "0", "0", "0", "0", "860874299824359755284038922585449358596602598560122936245029876424895542656824724041995715010416570765928267724018", "0", "0", "0", "0", "0", "0") + E12TestPoints[5].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[6].in[0].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "1857599092883977158241331766682740723538653864586512247565949969300055384008221058364575100813721649626609996709967", "1744825127527173129327940751516240214200841185705560550710869189531115342873984598363882431611302615929339711393119", "2749737605182831434740283564292844341521105724417036850002228157299212674615525900988788378885346089458179412562425", "27199942597878419545100370654855539674189137855391351558466369768935626228818541433771196022169814192262969218553", "3346808423546822545131410295992702178326451119965155114178264070967208351941063078889742275732289985988345520868830", "594120237045481252983953743895928268307447621981339389081716935318292638594315592421519155627337984494448080911466", "3794214516140678111913892689158530139861152241115309423312456504171906942611837083654013083691439056953088809376201", "3000242755577847188902458653898286545466571488285476543804980199187400093552279351808612803691596913990725927643379", "2416577462554131980270793923846326252482302337498868482068307617873644037247486619655750668416813129543078521939118", "264664271340292955008963312398448303445158289886465416943719590763752937290408411695538674587337450987521094253077", "284409326284753535253686608669565058743358376666192584022120188351670935331950878660586298917023978610307947154902") E12TestPoints[6].in[1].SetString("899596226081130507684720635237624217694282709412365238710535947780691859262478543825004599596198866874737751528480", "3492366087849697160385465343346072926968559944949661380185485616015543632391861570895545244218715788701536229443080", "1055754128034598642287216495245497688691822416953490422835213237318317614028276187275894603306769889802233674034982", "3048983367673342658736086799758952128690312077313748106878947660475747504192951612933075755904761895785600358698270", "1407225340166158567746929597008059241723090555655192535429709735130135094742998032662901774344725487639187091457289", "2146355118585628535559889822598007470810412833299991304732320214945537013300488878733760762511513688329549024423562", "1515585298374077889302768082621857014710033314049709932949265531166956402068620577359857106816653267907083384016204", "2438219484171522777079338289393100136454360280402431323598581806594190480015058385424508239035495565128238004694752", "2007436599767364560829100373509167964945591017128339855757923864726936413789065683089331673564852666293804436253584", "1179805572477639950070848014096704965883976564209095091141544970410492497315957245071587339488713682527427180309861", "3313674720499546443112927094151429886144294860118693783550129478772052185519801900509748820530761478285280080507537", "2663629295017415271848072810516319477416552759073153717205059417999615240980119976491322606126514211035275299870901") E12TestPoints[6].out[0].SetString("3629408904550513060817087981570563946698187266868105336295765017343248002722050668488040578678760168370048818304015", "1347555625512006925209007284292909493950330989597165742419377449191567365909244764817432715903421774290251953593260", "2800579255561771771615157246761737902892663602659050973546082426849432956902260785639777034918072505731573385428101", "1796311417634506700058580538315892313654534981791777071549117681650928528317639649479176505661092321205885498700908", "1434425282764036987292029967662914781397279693510583886988176104899070720971816574096672970366895301831450060675842", "1490753986910783687273510292854805492579981133326138533578526149788713714750714093180815409114788010280000272732605", "2109705535419559142286721826517785283017480936031049322030982466485249040662936169781376262443991252401531464927670", "2230024445090533495575441152815726119758629701578732861578980174642065772136057604635833693597918958043432541511166", "1005269800123544356313769201671550353855279685474808514230845927790304856850507170455256848127433916246636091337176", "3596383035031771930341641937943031218366278901707963573209852588284136534563443864727338007905526812070505702248979", "3578338991839839398121890406549878189589453150005159200493849069535805122810210312205287495118098929272801174760614", "2948038621302168807101759419185884536159911135739346301227179606351286176312070855151908905043538189645583247025803") E12TestPoints[6].out[1].SetString("1830216452388252045447646711095315511309621848043374858874693121781864284197093580838031379486362434620573315247055", "2367642560255947391273656249072571953126976739575858752712522489408543402107197351911717485724021524962968039826674", "689070999492574487040724256270742525509018768752070127875655952212797728845708411087987828304532726127106037358137", "3703163792731156169421986590269796369387676467042296628455338632947496820913412152498400252109599857710473326423942", "2622384157653387245215960599382700454507981402139206701460814770762832181976658373213557050806459990590970150321051", "1200453304961194009571520473394694707516038286665163809445943856021671338640574200155981513220776297658796496445268", "3080944493893070757098975487009975410154297127870637341464509540275367887016532879504349677939700380625258969455049", "1355995031969155334834554399765430003406791960712878099713874697577716462596778698229504844655943491824850804681449", "992806155810482628073358280389118580520980471157136688047056334460463679763213668719281130126744247696921491389795", "1236771890076492030199945909749621286598325773289773390926762647463151539931529374584163328928099447015651341629257", "953399106062413905313826043982922573857746249706779518725648248115732402261444375628477483185591636740135286305327", "1623189586489005656823403623889149737883688437532046752149118906476087344842668766611951321919525431612926919843788") E12TestPoints[6].out[2].SetString("1740251881508655400841464430841276061493786996754248049061553164371780552663427619942767283235607908975670303485906", "3397424897351765336521848756493430764265944605561445500766990697881225338538967825428379332807984255617504981577827", "2127210983579297229951457914340286982335153028829987333823881109260438578725458324277018433305093426470149525402907", "2408890108808408709567880186528789354537588746198853917439884605123535515688116234974051603651155779522199835046248", "868381729218240144194378314528911764350637965731921904412971737762911220022480454590157418149866726749619922892921", "3152724896378649912551411749889243422678348780636486612011189128238202773480945344424402658364247666679029247950710", "3416581668996441662424641608861617674145742759760133315958307275211234333346860228234160807923000283914655421318271", "3688769505801745652625264744468686689544340196245211937910987130372494308987371812063957693756689629379839863649103", "2314579877717906279922087473668915260822457028949982641440425173457820094074816085214799945472527229900702877802063", "1375632917130091272146316222103094446169938199062441728231122712992757109253018083999028306169515277536060779760289", "1023943145840006057089787641483582638583487538605219220576661768251398136935487619710229519050465688218265952923382", "519671386414217660164453949785977215914514167290719438594041602104161048910762627492410010159676458217407112730759") - E12TestPoints[6].out[3].SetString("560557609804927668159965642128578681202513548051268099854023884131831109316261020849296032360608148659322779701764", "469109284494151271287804475782146516320867707576163541592966216088334387209971842595259355036990551101998574488051", "3775692784616620687427946798575764835911653708504080968393633032075897210891714284779729500811093987357739808867059", "3769305877067704311215066011598168522780043929289091390865892697822050499335394417705191879740755373534860551192388", "110835961982465208843920546626294799684133777127680493020312449625961752957744244393114590675263993729035508801262", "678976429946246281569203296869886563244619678498601381652206580295796722418884566904060391188267988088763397906850", "974029799598303968259595277705109361938400853728189234766853204819350128117524837041883100430096518728365845608556", "2455606993592086123021666308979554969937068354067733405820008011249762027056606951497804733185460431814701965097747", "1104761643369289716134506413526330556568346232774592078567434284784348821342734028387702093496842214990996331584045", "424222846570177311759791261009210019999167161277868930646121904683067947712192013699813471842269070576949525728539", "1732530772772677977838085560955905995603954919531758308136214168659072541338402173672940699352373821635559044538808", "2691548827381258744566803302964662991895073371118140286801567872040704495904835803413163469222410111012716021504867") - E12TestPoints[6].out[4].SetString("1964427232795233122808565852055023622566155915835420506285384355895442260051341950517380261310449272661174528063982", "2143339964881321799624890940220707437274904841355177939264589889196302167648646007125873386273721188053067122161376", "3647638174316733234044136356701852717428392222326919346917152556258880301826573725325484567086520472755915194520367", "673430415499308193318739681854666989523719513472735125953147724761119324371343955089557187575832890092041854218006", "1304384979973153871843247838387826049247803533975289196597499358778066212183669905000398049390023294904127202800586", "1822088671626218507759242948730073188023151004419295759263712228632828913467285027745814681640938279405334281705462", "3129674109200508171679982694236806656469906002798939518220727401890586676692155528619168758924229608844585213014747", "2617412822988778945249429624606277590164727102913553853020219685796627774108532216456281057650453856713292108697012", "3939432854332195162701350927357948205556491390020785804571808424932321040807766832266296741740749395100543926040682", "861234256992562128350311073733665810472112641754946249304713818576444001191061740839087030263220583991250073297001", "3777306151808401105866924865026492776373318065834505655128128091905091494073190254638947724823206560595708961007617", "636430661079249827026433168184758607188782131654515427465855422964916671934523255739342262251790176120076114156374") - E12TestPoints[6].out[5].SetString("3076745993110123140787813079439547760364024951843033568134091065221619079087888409716626346450414208362725141576728", "2111645877206197105853673073352135755731274782436477367791274442511550421884270609044270669458251869300127481543108", "2712722582358625047484263238911211601093885766445728223254307098026938899405376766079564138740800239488633284558406", "3576177194330166919818609279614255238272975278010456160176888080769561729340022038227281173987527447864583700355685", "1647663308664441604176009290907789987788199677160021319358664676462451784664467866189338395284499984996593076069460", "3874396165199907246395885359409860454382596468720632301691565480032218063540707600930403660199916482273139870271662", "3827384626860227566232193544031029688766636825930292947599936968101538325226449836347076138527094226407101318045031", "1329680628605718974397153369934459245042217180392365547740481424403090880305076960791661757890924345617999898103844", "3831513602573838321385948147371724240823060996468301737639399747194039425927208148273573852853535997000004081527464", "2978425109444618273741465040677720560338427871005269571800358778268418441162688762506381055344763314467848325541089", "3366466299779149405089773835965993352198504842600829764108790066616783857337577327103960971403687184339521090131928", "878086202361091623063365272262042505654923531840788984869643161026395877836643401240258739986675890675319567601113") - E12TestPoints[6].out[6].SetString("3537997479535567588166032640010988384462804530421469703994594406995329194964832263430850333270589960782435958773283", "1050818741625240470204614369970276289337382031169892598012954280265213878513558189586138351910316951318760837198104", "990950884931780567021824886815373539269081971024666937044019894554534421995360179768363729705303364211116425588966", "1204662059736112785987577488302867509076244971750207987199539069995398763839038510722960062322265931792050738683892", "3242361778378881610620423925384820919924199636121732326568036878560257514555695224444791933356235090361237452881156", "2371311643305039304768075057838605297546706179560927515362140679460054973524726959092246363472469445589328267339640", "172085753053127904426129877751338431774522172219096869852377900934604312132083005788401500076866844396269598139951", "220849856805200386105810680803864018622117168890647805248601446885852166809279856025838814341991570359240920008454", "2148716525536627651831938666260747261293496735104233706756240680019468871912888156183776663715719292419621879173422", "3172125300125305924856575041257793693702293953175341383587192210770382528030588069525595402951956763531107009081553", "3356040297865348736245592653974867107791529049147639883432713117643354263499819677166343453920330889958051946300211", "3238404807218872589795350907653699653161675192434268986230447921650458186929856757370642368702004921100801384572399") - E12TestPoints[6].out[7].SetString("2053883598838277461216728396137865529920530378595299222774987122545872213849993978821626823792085230357120825112679", "89456366043044338408162544082841907354374462759878716489602766650429953798652028304246562481635957695946297048697", "159329517297187016972543106410307775197614457930323293769121072447983987853539907986177062766668849405031388089293", "514100898202121176346196575444359214326105055542411832184026652313135336517804047103380124809164040687010466128713", "1563236825799686189801245393558949618635477269197292477930605793705447562825477466373106365515480787154730742253024", "258851845826532317957997555171123569387673735222003281333106434927381350641807561372708316125457492250603539452438", "872338688483809861755811246553590045038875142886742742954444475781591400154924940316381093722833900759991524575986", "1745074134504969083493618378052687545125851960026811110065775210015036373953607276139899963927619955953300584121026", "399128778051544948816936087677854929735860605918362084272232053692366695753995354331348071437477157526949863388948", "462105478941017179533374986055810880736252035836584165032481764884077305437066386507738958825743426464300209908053", "205663628832991769737784103737673613502608688775006598630962689372988257758437822967801178972990536338945401302102", "430767032246258057288649064447084993686173442879508828834892733591928414176085432771541083278799639781130712854272") - E12TestPoints[6].out[8].SetString("1407400728907580506454742969311322985089761477245225209334121410829169732711705718870376800776775572359837989884560", "597007247525805200637224991397983741261010262753957801937281989343688147374339761555778165291771894147730502236242", "2453971258036728751900036343805851550682470802924036036428782750070675952932738440727049773300247704603752735063238", "422377273365808590720472691675879493983623283887206571899371308941206329394161620361781425533641038360918539094693", "3212723522408638438050497102072490725096195004461402092661655168206622901492911651611938639769758576059130713662790", "1522828150408612253803028492700112276161186369908727719220953090453554331700809150054219952090315495205178833201029", "2022245621997858948839736904049764364575827161228868481048003814511593042823474194832263986317191469669413430586514", "1656788786511723695595518420146890080644397793319093136086710175221118736111490519802633190944088841363033447190566", "2257008438143810179823321383919896250524472710148213366148357792709237605512955779579004806102514368543597969424842", "2541733277482895076858373278222272550799539357628913761054225783038827891415278330316857361475410075342351444296517", "2227519466465969179088229102851574061743013971085533192307553470044850692965634513541682415906075948918157076494512", "190002686929305966561916952449382433751338765878879249493241590622568098902037890621826299346142429169532389123785") - E12TestPoints[6].out[9].SetString("222584017519360607948694471172798812003985781631564009291504198576225358833775407202293335980833702951348038477718", "3833694356413897792564743677391590837419633180598484979017198589312755350463824223264859846767218648427855568089736", "3539679045660053724950074204653612414067014764806152768044238155801433118682624215975792674223676569807221798529918", "3013460057321335078901103353994165397188049649906643074237150169310536900373123157948807260326903883234910035952451", "2478565042528389484627722209305871706284609661783648965571804367070102505365668766030040329265690799364210754249414", "2051303567093085581231780696936446945594017285818646686405235158918902369802050117675593601814958981799066467836178", "703338503092949592346954734550924686182418364568894268457476100624414991434331376259216960269917694980212429832823", "3780170386926651220790105100383776884670458942844476119288876165276331668253273420284175998723866730349182300084556", "1162807377003764164585650779990293978379215310913229448577789324368800296162229716024040318943253062757450128276854", "888871295896473575600494828920480334444752335882840491406823938693571733127394113133381241646326572956244825639988", "1103724814564501120926246619379631476290168816686777100957010816708956638500750525956660622204241748602893782184797", "2219790565003353808760639069212272945406817886367911889093726798471620032024615152609237849538420033953140285330399") - E12TestPoints[6].out[10].SetString("3119475316626812276591457638465696555595293541965366706820509221437401642654145283231899391080419749243792639505673", "2656447858179334256440155069399979150203071203041401314420597283898767689903876285974962170797032191174670580439073", "3304421225312618656394243738625980458354644463757274452113825333952388603568956034585360785641070761344485495531830", "3345924898975979912562115028497878020556592405333246264509631667902945862472036079542598087338317044197169463380623", "2945782675050986572320491872235812043013031481628047034906648711982412413961866162072668275218879252673133712355873", "725259486476940106805298798796656522946202424606898759822166226946733978080969684932611182527407680820325440721337", "2693648959345591857011990723524969625768513346708316538073936789513616082935783792147655860525553966529320575675394", "2769811490439448145461108607849585893001547392369975609392437130270078141664043993377249005944828578916447641675595", "683043532069426918173817160538569441643337436116297932820520852721505635168714750752498427614498180102560584244820", "2906281977219699771695077071182668138577252627774789084398886978707312298528883937867154421126201233361419542348092", "2626928535574556350878879354116450864183963797619103399975165428551722388666131830823372655257552358169934738150645", "508540472187302204474532406807735500294362527298506587686305827492006028200458869259885232834229758413626732067560") - E12TestPoints[6].out[11].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "1857599092883977158241331766682740723538653864586512247565949969300055384008221058364575100813721649626609996709967", "1744825127527173129327940751516240214200841185705560550710869189531115342873984598363882431611302615929339711393119", "2749737605182831434740283564292844341521105724417036850002228157299212674615525900988788378885346089458179412562425", "27199942597878419545100370654855539674189137855391351558466369768935626228818541433771196022169814192262969218553", "3346808423546822545131410295992702178326451119965155114178264070967208351941063078889742275732289985988345520868830", "3408289318176186140433836081839975888249435197957668496250341200805739011896522272021168473501677679543446191648321", "208195039080989281503897136577374016695730578823698462019601631952124707879000780788674545437576607084805463183586", "1002166799643820204515331171837617611090311331653531341527077936936631556938558512634074825437418750047168344916408", "1585832092667535413146995901889577904074580482440139403263750518250387613243351244786936960712202534494815750620669", "3737745283881374438408826513337455853111724530052542468388338545360278713200429452747148954541678213050373178306710", "3718000228936913858164103217066339097813524443272815301309937947772360715158886985782101330211991685427586325404885") - E12TestPoints[6].out[12].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "2144810462337690235176458059053163433018228955352495637766108166823976266482616806078112528315294014411284275849820", "3773508247341565496004985009744713294430585718255444905375541953706585945707225168774760797901305016485572953768316", "825462185044195356998688951740034796738430793314144500758560775186676105624014504651791577430095028832225042025633", "3251595919449881718565078354480921428116233565694076234632226656374415922003995438993784445208695305032368911027301", "179589731415971158193016429237804078453179887316360772702893348972366680939856692651002702343589069815912302463034", "1057634876383562105009320021055243416582228694973693998833518297746602628628613243786256818183664508171949446314759", "863465333278164736236174949054206303335094573691456591064077418002899481370852782672342921395742956154479837769727", "3273013949523336826750183612975765012756478076712030818532492625949971823302256561440404996993420087580900686932617", "2043895948645120300386401865859719966055244449390477072360902721439643752878537382627187853303150069618406211684583", "312312513723963166067219933063877836013119793335106788773500287418346362928622952534620465233873119208055129458495", "804894837494653830448066294838375894621633966666269418552957757042367306762827795020653586182612498979717139617343") - E12TestPoints[6].out[13].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "1857599092883977158241331766682740723538653864586512247565949969300055384008221058364575100813721649626609996709967", "1432122242650298907091160122479629145617610840919302833862628171406240201992838761427013620087618019276329519141035", "1481573257918937856090311077434250677162074197205534015286346161242264680658924659121826081471380222132036178788833", "3224395976852003299019977983826065888442044427838684883073760286605480295775176897560013249186525490840105941808748", "476011400258873690093363100505397899777251812657491998450900716184456617609918092901942651053136608233636449227923", "3221239736167530275049480804090973825928047594484043660625342647835945334757114766240361545760141111987859027742497", "3146920796749004526121052989304738891314885636495663360075060553542026655239109655391717270035776398781544305965429", "1002166799643820204515331171837617611090311331653531341527077936936631556938558512634074825437418750047168344916408", "1585832092667535413146995901889577904074580482440139403263750518250387613243351244786936960712202534494815750620669", "31756382972739993311324075529376262570273354657575834278746514725569893630197420409200474830715296413016799481228", "1465676976701805310822993413466565648264774869292062110553431756786520265963167638496125745557489696135023330382484") - E12TestPoints[6].out[14].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "2144810462337690235176458059053163433018228955352495637766108166823976266482616806078112528315294014411284275849820", "2749737605182831434740283564292844341521105724417036850002228157299212674615525900988788378885346089458179412562425", "1744825127527173129327940751516240214200841185705560550710869189531115342873984598363882431611302615929339711393119", "3975209612623788973872689455081048616882693682083616533773591766355096024262019323008916433106845849845631303341234", "3346808423546822545131410295992702178326451119965155114178264070967208351941063078889742275732289985988345520868830", "2899595808261344853679209618521211181450605014321724567138303459787985701743862973355840997050343806928563635461510", "1995772310385360474721329874567336296308275338167198265771550441735367186892061812800037851707182057423778971364103", "729395605698330566667606212760139143800404743226977066799565510174059827188581303002282632135595576456993585627170", "1958513606576547093031387959876184190501638370548530812971155414684387897612300481815499775825865594419488060875204", "1854914474528566095644673411827279190307727730382175071417860188732065096902949012418118152253164204516432992829016", "1889711661116705274048088026225662880086927926225906245706566198670628369368444688125218967601485777273748743675513") - E12TestPoints[6].out[15].SetString("185852993515291649874658444805706390271696971070614189501127793909642116485736099029844311544356664841823527823135", "2602822006351015239025626866172854229822357655838606656518058761119387997846412234139951510425122680245866035416978", "2344074511384256516134713030844472640180984765925956461368693760623880931618386296914588951454614011630704922521728", "1860561114301562377667699691084563249643414690684015757246166018235201009541047859912284699719104295804926213159767", "840490482765601032693725956508855289976841448865574082541133503550760983021198657549426901433366832802385421963561", "2439877503896138019516026450766139885201948122586292565508775574406959369655103179581884927807666456432746368595299", "2659891517253248043634963066007988555957301605487405270199051918444157500326223987676218514828719262596841095304684", "2234533414895814175359094702308751010759273348926370625401569888125289310487934403538004242974454951385018524027172", "422012816665646239902356790556319984115511312479385697492851812225056412490326230037419660691693529606916046804368", "2730898906429918665050366820019054815508723052679190540657235392867995551647658622458106856086250064900756746877847", "2041292529361599395252652039433828399032959161802951273021217464599155049117389202596137120046871143312521345501562", "2252266954223199330848207674986972408530464846957914736707288505482334859075513304308372566955983470426640630754933") - E12TestPoints[6].out[16].SetString("3024116809502647958287311579146744961221179625765791338366044225039779998801091446150900971331865232774307953911370", "2714369552395713974745042879788146902181624097808108730852540179727474871503590539629672933086623212319080128742284", "431483986666099640574480186729318557915184024404929375359647119451473534227226393372460416231484250993090407060627", "1852346878073991462816480508601978452404626072860427424900790225453967217499477181004084906658668786782838048496132", "1964129223769855635578650484089691564383192145796800021821435747014413382211849286057432923936826343769077215320927", "3500458372027502869562603751133726016102455100608744997889953513450959613185974387544619253418216822972503070344589", "3679252997920465385119527487767575489873344883196235533566296259580585283956934949136817238881466795012044841959558", "1488189650820702523686773870972831822559453515098378782260368169752792160530636921650999393166960866842933782731873", "189157697483217729736372973599489317814180769257967470899731382500965812136786588146917210914747652206739813604890", "3503669132507398151055875466164081795663427236791291962912675549690607502462273494054767770282109751346200302755886", "764122483189462747080940164410412310482402268578271113435272154878092226895799694828235515246077552543714374923015", "1310703585181548900468829491761588403042151940482430673724273613222052648492294000144273138857561069278020118991503") + E12TestPoints[6].out[3].SetString("222584017519360607948694471172798812003985781631564009291504198576225358833775407202293335980833702951348038477718", "3833694356413897792564743677391590837419633180598484979017198589312755350463824223264859846767218648427855568089736", "3539679045660053724950074204653612414067014764806152768044238155801433118682624215975792674223676569807221798529918", "3013460057321335078901103353994165397188049649906643074237150169310536900373123157948807260326903883234910035952451", "2478565042528389484627722209305871706284609661783648965571804367070102505365668766030040329265690799364210754249414", "2051303567093085581231780696936446945594017285818646686405235158918902369802050117675593601814958981799066467836178", "703338503092949592346954734550924686182418364568894268457476100624414991434331376259216960269917694980212429832823", "3780170386926651220790105100383776884670458942844476119288876165276331668253273420284175998723866730349182300084556", "1162807377003764164585650779990293978379215310913229448577789324368800296162229716024040318943253062757450128276854", "888871295896473575600494828920480334444752335882840491406823938693571733127394113133381241646326572956244825639988", "1103724814564501120926246619379631476290168816686777100957010816708956638500750525956660622204241748602893782184797", "2219790565003353808760639069212272945406817886367911889093726798471620032024615152609237849538420033953140285330399") + E12TestPoints[6].out[4].SetString("3119475316626812276591457638465696555595293541965366706820509221437401642654145283231899391080419749243792639505673", "2656447858179334256440155069399979150203071203041401314420597283898767689903876285974962170797032191174670580439073", "3304421225312618656394243738625980458354644463757274452113825333952388603568956034585360785641070761344485495531830", "3345924898975979912562115028497878020556592405333246264509631667902945862472036079542598087338317044197169463380623", "2945782675050986572320491872235812043013031481628047034906648711982412413961866162072668275218879252673133712355873", "725259486476940106805298798796656522946202424606898759822166226946733978080969684932611182527407680820325440721337", "2693648959345591857011990723524969625768513346708316538073936789513616082935783792147655860525553966529320575675394", "2769811490439448145461108607849585893001547392369975609392437130270078141664043993377249005944828578916447641675595", "683043532069426918173817160538569441643337436116297932820520852721505635168714750752498427614498180102560584244820", "2906281977219699771695077071182668138577252627774789084398886978707312298528883937867154421126201233361419542348092", "2626928535574556350878879354116450864183963797619103399975165428551722388666131830823372655257552358169934738150645", "508540472187302204474532406807735500294362527298506587686305827492006028200458869259885232834229758413626732067560") + E12TestPoints[6].out[5].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "1857599092883977158241331766682740723538653864586512247565949969300055384008221058364575100813721649626609996709967", "1744825127527173129327940751516240214200841185705560550710869189531115342873984598363882431611302615929339711393119", "2749737605182831434740283564292844341521105724417036850002228157299212674615525900988788378885346089458179412562425", "27199942597878419545100370654855539674189137855391351558466369768935626228818541433771196022169814192262969218553", "3346808423546822545131410295992702178326451119965155114178264070967208351941063078889742275732289985988345520868830", "3408289318176186140433836081839975888249435197957668496250341200805739011896522272021168473501677679543446191648321", "208195039080989281503897136577374016695730578823698462019601631952124707879000780788674545437576607084805463183586", "1002166799643820204515331171837617611090311331653531341527077936936631556938558512634074825437418750047168344916408", "1585832092667535413146995901889577904074580482440139403263750518250387613243351244786936960712202534494815750620669", "3737745283881374438408826513337455853111724530052542468388338545360278713200429452747148954541678213050373178306710", "3718000228936913858164103217066339097813524443272815301309937947772360715158886985782101330211991685427586325404885") + E12TestPoints[6].out[6].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "2144810462337690235176458059053163433018228955352495637766108166823976266482616806078112528315294014411284275849820", "3773508247341565496004985009744713294430585718255444905375541953706585945707225168774760797901305016485572953768316", "825462185044195356998688951740034796738430793314144500758560775186676105624014504651791577430095028832225042025633", "3251595919449881718565078354480921428116233565694076234632226656374415922003995438993784445208695305032368911027301", "179589731415971158193016429237804078453179887316360772702893348972366680939856692651002702343589069815912302463034", "1057634876383562105009320021055243416582228694973693998833518297746602628628613243786256818183664508171949446314759", "863465333278164736236174949054206303335094573691456591064077418002899481370852782672342921395742956154479837769727", "3273013949523336826750183612975765012756478076712030818532492625949971823302256561440404996993420087580900686932617", "2043895948645120300386401865859719966055244449390477072360902721439643752878537382627187853303150069618406211684583", "312312513723963166067219933063877836013119793335106788773500287418346362928622952534620465233873119208055129458495", "804894837494653830448066294838375894621633966666269418552957757042367306762827795020653586182612498979717139617343") + E12TestPoints[6].out[7].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "1857599092883977158241331766682740723538653864586512247565949969300055384008221058364575100813721649626609996709967", "1432122242650298907091160122479629145617610840919302833862628171406240201992838761427013620087618019276329519141035", "1481573257918937856090311077434250677162074197205534015286346161242264680658924659121826081471380222132036178788833", "3224395976852003299019977983826065888442044427838684883073760286605480295775176897560013249186525490840105941808748", "476011400258873690093363100505397899777251812657491998450900716184456617609918092901942651053136608233636449227923", "3221239736167530275049480804090973825928047594484043660625342647835945334757114766240361545760141111987859027742497", "3146920796749004526121052989304738891314885636495663360075060553542026655239109655391717270035776398781544305965429", "1002166799643820204515331171837617611090311331653531341527077936936631556938558512634074825437418750047168344916408", "1585832092667535413146995901889577904074580482440139403263750518250387613243351244786936960712202534494815750620669", "31756382972739993311324075529376262570273354657575834278746514725569893630197420409200474830715296413016799481228", "1465676976701805310822993413466565648264774869292062110553431756786520265963167638496125745557489696135023330382484") + E12TestPoints[6].out[8].SetString("2729812678469382553132367346332939729003904557455740097585229069562556143459572124663035979082561301495311066775535", "2144810462337690235176458059053163433018228955352495637766108166823976266482616806078112528315294014411284275849820", "2749737605182831434740283564292844341521105724417036850002228157299212674615525900988788378885346089458179412562425", "1744825127527173129327940751516240214200841185705560550710869189531115342873984598363882431611302615929339711393119", "3975209612623788973872689455081048616882693682083616533773591766355096024262019323008916433106845849845631303341234", "3346808423546822545131410295992702178326451119965155114178264070967208351941063078889742275732289985988345520868830", "2899595808261344853679209618521211181450605014321724567138303459787985701743862973355840997050343806928563635461510", "1995772310385360474721329874567336296308275338167198265771550441735367186892061812800037851707182057423778971364103", "729395605698330566667606212760139143800404743226977066799565510174059827188581303002282632135595576456993585627170", "1958513606576547093031387959876184190501638370548530812971155414684387897612300481815499775825865594419488060875204", "1854914474528566095644673411827279190307727730382175071417860188732065096902949012418118152253164204516432992829016", "1889711661116705274048088026225662880086927926225906245706566198670628369368444688125218967601485777273748743675513") + E12TestPoints[6].out[9].SetString("185852993515291649874658444805706390271696971070614189501127793909642116485736099029844311544356664841823527823135", "2602822006351015239025626866172854229822357655838606656518058761119387997846412234139951510425122680245866035416978", "2344074511384256516134713030844472640180984765925956461368693760623880931618386296914588951454614011630704922521728", "1860561114301562377667699691084563249643414690684015757246166018235201009541047859912284699719104295804926213159767", "840490482765601032693725956508855289976841448865574082541133503550760983021198657549426901433366832802385421963561", "2439877503896138019516026450766139885201948122586292565508775574406959369655103179581884927807666456432746368595299", "2659891517253248043634963066007988555957301605487405270199051918444157500326223987676218514828719262596841095304684", "2234533414895814175359094702308751010759273348926370625401569888125289310487934403538004242974454951385018524027172", "422012816665646239902356790556319984115511312479385697492851812225056412490326230037419660691693529606916046804368", "2730898906429918665050366820019054815508723052679190540657235392867995551647658622458106856086250064900756746877847", "2041292529361599395252652039433828399032959161802951273021217464599155049117389202596137120046871143312521345501562", "2252266954223199330848207674986972408530464846957914736707288505482334859075513304308372566955983470426640630754933") + E12TestPoints[6].out[10].SetString("3024116809502647958287311579146744961221179625765791338366044225039779998801091446150900971331865232774307953911370", "2714369552395713974745042879788146902181624097808108730852540179727474871503590539629672933086623212319080128742284", "431483986666099640574480186729318557915184024404929375359647119451473534227226393372460416231484250993090407060627", "1852346878073991462816480508601978452404626072860427424900790225453967217499477181004084906658668786782838048496132", "1964129223769855635578650484089691564383192145796800021821435747014413382211849286057432923936826343769077215320927", "3500458372027502869562603751133726016102455100608744997889953513450959613185974387544619253418216822972503070344589", "3679252997920465385119527487767575489873344883196235533566296259580585283956934949136817238881466795012044841959558", "1488189650820702523686773870972831822559453515098378782260368169752792160530636921650999393166960866842933782731873", "189157697483217729736372973599489317814180769257967470899731382500965812136786588146917210914747652206739813604890", "3503669132507398151055875466164081795663427236791291962912675549690607502462273494054767770282109751346200302755886", "764122483189462747080940164410412310482402268578271113435272154878092226895799694828235515246077552543714374923015", "1310703585181548900468829491761588403042151940482430673724273613222052648492294000144273138857561069278020118991503") E12TestPoints[7].in[0].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "527308942306717486757915312029417273574429181327162556081593223052291953408016323452563259175229324996214905871008", "1830058412945392218502804289234688920115807490101366281198866396547937042860284410713893747632909565627015984300170", "941235368115924759574834144640944446593867708823113907983266655356668012197408508496877674294093002443230425941517", "3445738167756824837990288450276658651227287301195914962102625721229084551904882407682556089063696731326995816210487", "3052916461528414259166838237883204157869922299076595821144758206215927825791801876217535256703777467973285212800305", "2569194893836609450435187615528719017869193637763262098959865690838636264514116805937188155189116916389525698222518", "2723282020755540074451900853023741174890327273611801867608779801861053152205609724888818591604240524898799561552005", "843114003792400036684877496253043250015911886893048125403656336434871857204591892944725859221012679595762949017006", "221659391537771798292605271294205937913196116696041543470681514152045938486051177845390416817827691129619850951777", "1469493368749947603488187690530323006310066733873870347063593062832575168399428319011073467885099300689282646270192", "2829220044216647235783289436888577307788465867980273283457977927379772374263811965417895357206630035651319470193995") E12TestPoints[7].in[1].SetString("958525583110161172304321462598166457269573644893702476276086443238289694474410085051228534484237399030351911418320", "2907489192712376528815173297472096426884926790843708331386092201035540035797039557923645154464733926479987172864116", "939818213949356240906658957881763711148105774190246204961251080615972683395360521387764540561656120037054906258039", "3224095443580100076661324049367352587527812495918893453116506467953517367948987897426040061208380842587934213326933", "1496144507712566536283198081294211053681421573598943078923587494743277105811075408256086886157769063015711544775483", "2222742851970941337229444588110634725726296311286025293823280558570341459659865992666828462100013666213422377183797", "519751545419001164848499200479742414008920210732528708884428458549514722617302524942853898991415051537157205115651", "2843129154667958968602668793801116722430551262952961347989348766196519618645415532748113410807561505931100021369537", "3414835313354667683609705146494042653819357705083862139188342101494885616580540215837374602776420249720343951930924", "2185307687702869700250418525726318496073903389200126689412601826685724612705328827458393410353084777157970558840895", "89569223135624488847338416682241965355465792699716118984861432809246864712988564742925580811672154846082862018635", "3658473463574973927093936514108715468080050753736299813251736102565430910021341248662946067943966683779480207291357") E12TestPoints[7].out[0].SetString("725386709351196174724486330955560178189555336146410786810416391183002409861268374220315463675018749053771522799394", "3434798135019094015573088609501513700459355972170870887467685424087831989205055881376208413639963251476202078735124", "2769876626894748459409463247116452631263913264291612486160117477163909726255644932101658288194565685664070890558209", "162921256474357442818368368272392877564797384802999475767714987186153729655558541480230106373458180993270366708663", "939473120247723980855696705834965548351826054855850155694155079848330007225119951495955346092450130304813088426183", "1273249758277688202978493000257934727039335790423613229635980628662237634960830004441676089674775470148813317424315", "3088946439255610615283686816008461431878113848495790807844294149388150987131419330880042054180531967926682903338169", "1564001620201831649636779821088953740763995716625755330266070431933541120360187393194244373282786366792005310361755", "255539761925400326876792817011181747278386772037902379259940301805725823294294244339412832868417265278212628388143", "2406967079240641498543023797020524433987099505896168232883283340837770551191380005303783827170912468287590409792672", "1559062591885572092335526107212564971665532526573586466048454495641822033112416883753999048696771455535365508288827", "2485283952569953769459436125261388619311633801777565211377655893821171633794315349638153796021581055392905404925565") E12TestPoints[7].out[1].SetString("2810745098352541223533633231495131420207290866298013719590301640830454671403286068560546023835559615030961972522541", "1622229304816008351360531840293225003246385210422462110027559158140783568101814629971605733839511062554122005566679", "890240198996035977596145331352925208967701715911120076237615315931964359464923889326129207071253445589961078042131", "1719549479757492076331299921009496015622938032843228340198818323527182294739258475513525242214727823893190485174371", "1949593660044258301707090368982447597545865727596971883179038226485807446093806999426469202905927668311284271435004", "830173609557472921937393649772569432143625987790570527321477647645586366131935883550706794603763801759862835616508", "2049443348417608285586688415048976603860273427030733390075437232289121541896814280994334256197701864852368493106867", "3882562421309248499267021884958528609016658830597848404951489171788565184051032056583392809925694683005593812742255", "1430688245659399746492962175494904752753437001748193871547372371064017891114889541550038885573608093913313269645869", "2038761259056569491459976571303791598396175547434922739390137823590352976271560214829684635593758578009543564670669", "1379924145614323114640849273848081040954600941174154228078731630023328303686439754268147887073427145843199784251557", "3173156135863340702107142748515765996265297934182981355538299960938373114733308581197636918391679015909733535462425") E12TestPoints[7].out[2].SetString("2017609922295809946158947532885766999245300512806467952987114542012379150142726347001127467224767772350901939494479", "2230967023775315877249119080081214069762875280224644001452784805950225627035749577447823861790849367319521956229757", "3189721626628912696090050085103550945042168953662540960877818105737226586830409793533016486793924838028556322011721", "394142446081674220198531081692033440598155505520046881300284119144303904274003836885209270319636820827288089824812", "2124889332439040455785589671815633840335913557823879862125915806664852246385663016057982312471439928922605341522601", "3386394475668171983126888526372906657567246865497332127873119637222498148567847927336336514166452736724270273606166", "2089793932052407969949799875542292912349689549794117579607792018925399950587528111624984907577411260060947086063311", "453889543826420205153509237166290939081230422321991628472215440861205988133120173101554785994891644916740084872983", "1737002618198048513299194467706384763995493905372372489229018860835834105917348948412112482620531083236939423349575", "431402888301052903746002458552540283388047255168879953192784306795357685688723974276052467670902945209702581621169", "1880218751388690773994680296534653750365226678876067956234109798451057006368207892215530098811015253589206853114290", "771068353802413433563095078848697902998060144901736475894791393958093380735543252505046708431062966956868417592911") - E12TestPoints[7].out[3].SetString("557979009708633005000987742891859399779135110974196090053768026313357367214533186686499945903631488709282624887193", "3259622569611147157309319935356610761773155876484147493531705216710691352316593577346795227033421901248872049025975", "574940587934446950683132431558995643985193863957620201527518393468997166658423443869048285093916362257938183178888", "2366223998460450470385165012939174173778821013491585412227560390757913252733952003066716208829894921820446901001417", "1386151551613375898774415487327577077197358329894311931084050563109623487673804174211094404444871948780910049985854", "620280418735072275667518609393228058037355049993314426473393204388993768924788933510009849803615265850093492327548", "182769911633080027562323193068283866769903191658180048167070978875205894660917544978482239293821918318486990045729", "51612922747958144885685997431539293142991451392196884302690195094958249582457786723044403053715058716987957481348", "2715565543548500576108322996491929502119890118651753354324786982637833013445557105683184931209149367796017130793556", "3840675258876109670393860241120824524475601182940071067235716239491949435166653594065815121958515226619830138600300", "2806876166984623428337274954028626273872287655688043824876854385725503690785210920809824711801664483866528006558604", "102131043486280206148433788382131440603336331072459788977645752413671107926920521412669481854942709592324526417023") - E12TestPoints[7].out[4].SetString("1509559556558998745891294370900528207693830357444998960254384292101063586702757518088088929417827526613939231663340", "2515843335951219368617042728716552098136686964732358099848538510123826805924554197250703587266489726548785191882966", "2471593116038133326664729193153687321987135768430026185958733020075894358018508416584157190547283880563896965312087", "2052278471000273412043968175739794788848300577534365108404153076563803493545409939978122284353584565012142545379959", "3196678850141025721898941022079195800143621301742757508195820510288577812092675134038887959524372866704369250573758", "1928555089066497349044129668852655537589252872913634244377900613938034580701526095217348955215639443288299925693879", "664056568196156206926031421860552802601345787340272828300478566471796047577515259913207593056377353057977354169444", "2246656260380526569301165789155482325609887905290673258441593760048238870830343626411839874586551024617723731324404", "1745009029863988418182289803448888783579437300376149563014033155733093569971131863011705593991932179788604513118699", "2763326219368127187592661731047975909594918408924229680768848433815522979581110902962426841958433335255718518770102", "615068642690884572267753273739676236470346357185872799812380889943831270707250007028887691262072193682697961425632", "2202938480839709033300547229893966044793018489855382789711086918785464502643730688010607489754732653308835707621618") - E12TestPoints[7].out[5].SetString("850399619318150609409178414297211532937615996594743634871477761316984133146318382399566554575365452940076153105205", "1263474294308605809066081254152327942689262995912739267247281880076273013943500210218494626230290732504146897333262", "314832049104649828591022978091959057159706639443871079970293285868151218993111970969247908822796177661436952915843", "1790377838143489095857855502982821428006774614725422619042071470552135011978557880635445723409028178611206767088295", "2938344850801030353720755843128672664710152780029273488895400670746116615560448193212856564755394134970261913858374", "2977985167594421116383537545313017008668432726161767194899962042454818839779496359495165695977141993504097268534451", "3359983307675518369455385049542374724948221506733412265075046817608518715115368001524418934930338430157558080700761", "254867992501059101024246193336557883383997141971492057628082778199404962414120946688262287034623951252583255752632", "546490570005702395126124446166628676012085296953127725255925183141235566032455294697329954957406677761413360583042", "360309607501915257129032534795935764250152211412798849162140938889817836869343388891262173090501400476949337091023", "3574282501583058035075753605530415026833084897957660569370510612521034281695891862026862442525530252814118670006801", "2815346305183664593181980937823575206549104731460765303762401142008739966529765581858369935109278909388407330619374") - E12TestPoints[7].out[6].SetString("3014351610038009907831086057960198444793733946297897655903162014737045958513564259891572379446407110527523945019436", "644395621666298155996706769242590462046059730808990032569538815010124227614266741658786849937942294097266232269814", "1452322391468188404942635889928714385610303242486639895334577631683616910770105798563984589083351031490157509319088", "2507866774926157369080284276345535901056405370060542669828981223951622200120706552476913433611884888437336622808841", "2856219063571424228073049414949440387550513766981388277094837362514581698317743602303193417303859674933651027373496", "2459048276364015844038350118028580322774350855124060553113827132111749917246222397697735693915758546896932373569598", "1042122988765173346095702921309849664088559490001476940342989913785564795842582998073605799695641540623537086483396", "2787434428214179251111515239408396860200243126100331258128217225648711151477165587925362331696234031926876228092733", "3044841952972376464171131502836503484903981071219615584460730926175262060926679287589949165770604391800163371082137", "3800250396276499689711438810908184454770355176803528113877017952462838810034907872459823483387290614183505016000965", "1111826791058238883995996315748243113979933448465416451487759131077036711636560965539348892384200968606676263884360", "3055812085403686504127780327670546075749936067270714804081563033634252671225102765655414169987429898444986128493636") - E12TestPoints[7].out[7].SetString("2012701446255109057254168549808540152915258661088678530051461401112445196313655857669396258342158626581362211773153", "503141889696110311362874178908011945221428303643679569797077109011381609610898339581307328924331099967422980109813", "2261935793519203369354348684446741055417718172982195647181443048319848925781959178281139737450434222788019755346023", "3792752232702737436107409317028957889987465224491177346554768164367986218254288626139670176032166006262017062593723", "561412191992927838762640432597973590587995677358691933620831494051290371151681682406774642805498322977387451853925", "1367142897073569510281489236254681947001257195554942310757069119886744209549844412810574312410141120310912473839954", "1455356414288341388113598605508017564105616846315473043371036163260017459203929443162523733821464188837850542746924", "791299846092185181187567183647464761504271058975200215070557596788221411626414183249316140765086835779873188577480", "252962847005224106178580854380480268308736444680685679225411726712292449530702450765722403410674925503214379664507", "2510363372362903081414080876667495641286181964243544001543436707103230530050408452196704438547758409752504139105595", "1409003561765296802784150251816821140631682423520627794761733904364647886675490347519747590508402423495766834523625", "793934919074412230516396978077144904161336066334754994949353014420816615968240340490859899246330229813068873097993") - E12TestPoints[7].out[8].SetString("2496111560652285468747100018840019725932886813267150827062112294630770955884391053193890592044738350974986455420507", "2593440614671744725729464141337613104073389545093454745127645070611120526263140180999385656273594129637879386745867", "2566830417954822027892923848491838804409168216375474446917774140459459872361619800963663067554821790214892454608450", "2609880261312998728648240794659332762154747250118641282285641392458934798951028822563692864761790980746047580110952", "637334090582173530836786399668340056147473053853841547272871019553629570908799314947677204554755199398041803850443", "1734565322176093240681426733947456667695814143382123198965948400167441331193860042713567855784448785818499124509331", "1857855606141070152727371523030144369366469777645124522888489866639144007769938379932778174410599742292930650643751", "3117834641753832359429023161149810994327298538070609893017226270171921302013726862954071648220767595592122527975270", "2777099608641017268099887573159603451841289984858517059837342683813046923836356290284250754870510015720998095340152", "1460237539097199647212390592772576927153749592274451469423298328293983384636622715598809918001625199071880824404729", "2254738294545457569044025068919668962273030685270748506656462311343079207212114665765394634200054382120213858987355", "3009522725659407656912402699568247311195096451733902117493806812012172238658921439798440135701289801601227719374058") - E12TestPoints[7].out[9].SetString("819821842431189835335659388264650948320231889587073648198124680006577060344176178346544806519078462418009775687940", "2071138730480047685539366778551307196183784212506383171206362267374495074097258838576222013095616006160186500342992", "837027986325953906374109705298870450508501335358825629321130547093463382335854424466758286760311850678734042579237", "637282286738458395287671541249274944042575163851180719094674893850512726205378662667545286433358489528008543670131", "2487198262273734069249624610729180817400443477483417340052498209100469811034082737638103383168341627143226521451484", "3419475347427562543044983249566572071396429617008453821174149058851832574767510509388248564232639284527949893709029", "704098367990269081481229578577064827556777843802461332140658108858447294228381573536840179416898938864243436177848", "2558995364357951477511397840283935159491896736479984234687057163600368311366470679390263057995511415826148196756449", "2739528003929663686219655338141243786615156343367317541162389846010309090746381630285319028388055025761118285277380", "2876511619459598293057707629634070275192906633343267966602427279950063170357159051077396202864459889078615685696651", "1022288660857854209570575505669142046067722445982292448249259230397577085805687302260739494485398121320242129575682", "2886668684436052881862688537640345214351713508893145293450005652563933286611958485669153033998796451452588030922252") - E12TestPoints[7].out[10].SetString("1300137347237986686928455406091737260638643798074570953985571687024756015233948160352778813170403172905186200005759", "3347207642422127857443210087969928832189276540145484748469129775614189493549007690839567310922817229811026219446112", "715585302214124422434511963802811604994274394149284343218771545872246478623020786976589476732581638467475659461076", "3347458435082761735653838319534904192203516114309199595632266965401602654718304734689982155312073622646073631281651", "3766717022726572674497666298115867892884413332618849753261395059232127049430629631676216623027503481303566876126794", "3845069278049057189760503535053018532766437698082783030320356006627823997658542891391373254126425212380642398163661", "3512468905345890188343155406217762935567750260132059226062134512750847381148678851591722309687505032447929281944564", "1121762469118772366404542406257037193358424284268321208701134906867124637616992263319682426245632378500947106783828", "1800023434922845410684043052636009424247202338998375409907865927021249594515307471391978152562150511010441010317645", "2316251034217069089696524885129165435402616699120357449090133871824835329908565723343774222238908768321875013312819", "2055490751393770039510987277759061798849323257109661546998543034456226230578677597371064546685687028362702609039373", "1196272338179694768600999144304379632914959515649912505115115629486205252321578777191602183854394057825436050662588") - E12TestPoints[7].out[11].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "527308942306717486757915312029417273574429181327162556081593223052291953408016323452563259175229324996214905871008", "1830058412945392218502804289234688920115807490101366281198866396547937042860284410713893747632909565627015984300170", "941235368115924759574834144640944446593867708823113907983266655356668012197408508496877674294093002443230425941517", "3445738167756824837990288450276658651227287301195914962102625721229084551904882407682556089063696731326995816210487", "3052916461528414259166838237883204157869922299076595821144758206215927825791801876217535256703777467973285212800305", "1433214661385057942982602210207185138687689182175745786372192445285395385976721058505499473939898747648368574337269", "1279127534466127318965888972712162981666555546327206017723278334262978498285228139553869037524775139139094711007782", "3159295551429267356732912329482860906540970933045959759928401799689159793286245971497961769908002984442131323542781", "3780750163683895595125184554441698218643686703242966341861376621971985712004786686597297212311187972908274421608010", "2532916186471719789929602135205581150246816086065137538268465073291456482091409545431614161243916363348611626289595", "1173189511005020157634500388847326848768416951958734601874080208744259276227025899024792271922385628386574802365792") - E12TestPoints[7].out[12].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "3475100612914949906659874513706486882982453638611845329250464913071739697082821540990124369953786339041679366688779", "1152800935291363517607485731757702820673571485674042845736146352613933722513364907622882088699592107840421802932285", "2057581607676369689759481844310685313647148118127015001173909598106932268282651270446831387657890753718192027885823", "208650246869418603332804752171031437109172151982620534530846592245700234231616202025139417851400850807520076106667", "1606296512320416928810629122340125705884954664289341463166750548391660025689563825975236497691186191384586472797621", "2573693279894896414927880694766233472330582742554931234238328695311078178210453814264194995188304958695377963200717", "2458359522403425906338667678119737758227018591859545945309903006711284611299407321343836425132420650321087457788511", "286237708488545335797788859166976580118643645961241690257460231669283488760885676665787078061752487396953440851272", "1341932648495170020776475744577296423802367612752768077390170969908789676133174413724659602407662858868948105336329", "3071172871764612189803866297757042066546096695852380275477166344686338270842475583807425836519739491260431215324246", "3581035962302804372086471757815952343081015169326443641568594078245075746231218144489919530239717197050490138638258") - E12TestPoints[7].out[13].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "527308942306717486757915312029417273574429181327162556081593223052291953408016323452563259175229324996214905871008", "114769534599905485155503692190529922793927211710626602959282141469162339347902183281962493838215344692686260373794", "1908373251814379116235469949337256889289443625441851131612645128153429915780064448322927866135330553754242043685985", "765321634334261158760306127630276942438767670725713457760279007140647332817571658785270957916719783518418532455967", "3345606136594503598858112291248478449358888676512078486352607517640475449500310026692603503863067668717916859521648", "2582483716390227785515751564976059294094983151527593036423880801202248348999108847702752791475322439565347571112013", "1798985288058217798575922966180923826942820433368221642024783758200282447679110746900575510954015301201521478122258", "3159295551429267356732912329482860906540970933045959759928401799689159793286245971497961769908002984442131323542781", "3780750163683895595125184554441698218643686703242966341861376621971985712004786686597297212311187972908274421608010", "2308141403110203498506345065627674964319403487868260048196649143449550861360276360026585205985925718650155872543628", "1997934887442050381604238231803504113225935362560718930666932867979110933194958860454125485937857221182392169334877") - E12TestPoints[7].out[14].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "3475100612914949906659874513706486882982453638611845329250464913071739697082821540990124369953786339041679366688779", "941235368115924759574834144640944446593867708823113907983266655356668012197408508496877674294093002443230425941517", "1830058412945392218502804289234688920115807490101366281198866396547937042860284410713893747632909565627015984300170", "556671387464842555427501375459245505329595518743092923229432414894947098585955456760131540065318932710898456349300", "3052916461528414259166838237883204157869922299076595821144758206215927825791801876217535256703777467973285212800305", "3935241680402011261344248648788842433376788366507037214527715800143227867968484512417044126889369569451887563465683", "2925025480848564094149786465861588720410412852847582750894684865834528944520816498502222656581288010752998628001816", "3716171846733122057620000966568927576438239173977766195074597904454748161729952187776900551067263176640940831708515", "2660476906726497372641314081158607732754515207186239807941887166215241974357663450718028026721352805168946167223458", "2615651680984643299335583218154086280167919248959456634588857969263077036602360139303778385228463125137659837609713", "294736329783924644688312428242763446322034960100331920393643310773240410703604971381848463566967594113865883119072") - E12TestPoints[7].out[15].SetString("447187671312478853941925577816767686741050422713847069413761790802966250907501193676090212973272652251156329002769", "3069503048309046706727415640809553758804814328321170386609992717364029082791323678276920706450169671918594449770104", "3075617578396455397157196681731644371821364820124870028262506539182466842075271081689582481110135473923992653494380", "2270851550104799865967348161536337031178982791588770329974091977398180467638822725214471048506792646666749690174431", "3181311240980247987080509069464531566065459741384843331897503345938596226241406198819644113967863976942949723103663", "3731487368435590543576677357782668052330059822883825971769345077489799443317797063318647395968009392517603693129505", "2762049279309977521213764547630139990427851627665978223307460990166867473799182151154233352717164995234244273726924", "2613258290054370886252596720665779420996518556020185564288321476154982552897365577270005320673263786273221275959349", "1366282176609091764174658841188918321796299039596169236200409097681850580015983869222066902359700193780096817679015", "3869424208118913952005053314765796197430073011013103054263014538405142407553540136181315843557611077811319255962852", "2057949296311573944799611077248865274815400495169628950324371472527520756704792276615468119295848144610977370845946", "807295275518899020261825999801500347578189412552017134274092141727964980253182041675133160137497984403983922456323") - E12TestPoints[7].out[16].SetString("3426576037100839319296007190063805501894243013390800957926725743452883358098038873411986157992303144273847813715533", "2313793479178871374000118598207896054487829104427607610015656111058214335695845272057736301341724097159506074612739", "3223434601723283379658671155841091983223989185329245577654206626099420117659534575025650958549043244178746055044402", "1276746930111096375643324254805496429948689393206503346799265913812480666280865745128684293043400735745308576805925", "699859566625757258812314305143435948562962080944568507292873971526286588629725869175071549684681851996668762887077", "1584441252047453775565555066133452498548601114048288950402511585573697405474816565898777119875213226107795934132135", "3188069339284199665798538444083543526939253130267652204639463426286711965033804810385142403354271707420878059548206", "368999084306462835665518585932582071467546492282860518088795342037448537732964928113375560268840705094670663989269", "2542084190144347738907796137051924859371249548398988527585706631669046506148153387732768732994351293030073316335072", "466361130676240076559627461712064705228964498978971478419527889472422877828030858586697133251215056624096132351268", "347401534481639076181456467449450298027318223155999808862315420922124340887361847615416481658503793586186091219060", "374249360601311594024044590367703298569458535117293724819597618855255081481506889054342988153121898163131231320859") + E12TestPoints[7].out[3].SetString("819821842431189835335659388264650948320231889587073648198124680006577060344176178346544806519078462418009775687940", "2071138730480047685539366778551307196183784212506383171206362267374495074097258838576222013095616006160186500342992", "837027986325953906374109705298870450508501335358825629321130547093463382335854424466758286760311850678734042579237", "637282286738458395287671541249274944042575163851180719094674893850512726205378662667545286433358489528008543670131", "2487198262273734069249624610729180817400443477483417340052498209100469811034082737638103383168341627143226521451484", "3419475347427562543044983249566572071396429617008453821174149058851832574767510509388248564232639284527949893709029", "704098367990269081481229578577064827556777843802461332140658108858447294228381573536840179416898938864243436177848", "2558995364357951477511397840283935159491896736479984234687057163600368311366470679390263057995511415826148196756449", "2739528003929663686219655338141243786615156343367317541162389846010309090746381630285319028388055025761118285277380", "2876511619459598293057707629634070275192906633343267966602427279950063170357159051077396202864459889078615685696651", "1022288660857854209570575505669142046067722445982292448249259230397577085805687302260739494485398121320242129575682", "2886668684436052881862688537640345214351713508893145293450005652563933286611958485669153033998796451452588030922252") + E12TestPoints[7].out[4].SetString("1300137347237986686928455406091737260638643798074570953985571687024756015233948160352778813170403172905186200005759", "3347207642422127857443210087969928832189276540145484748469129775614189493549007690839567310922817229811026219446112", "715585302214124422434511963802811604994274394149284343218771545872246478623020786976589476732581638467475659461076", "3347458435082761735653838319534904192203516114309199595632266965401602654718304734689982155312073622646073631281651", "3766717022726572674497666298115867892884413332618849753261395059232127049430629631676216623027503481303566876126794", "3845069278049057189760503535053018532766437698082783030320356006627823997658542891391373254126425212380642398163661", "3512468905345890188343155406217762935567750260132059226062134512750847381148678851591722309687505032447929281944564", "1121762469118772366404542406257037193358424284268321208701134906867124637616992263319682426245632378500947106783828", "1800023434922845410684043052636009424247202338998375409907865927021249594515307471391978152562150511010441010317645", "2316251034217069089696524885129165435402616699120357449090133871824835329908565723343774222238908768321875013312819", "2055490751393770039510987277759061798849323257109661546998543034456226230578677597371064546685687028362702609039373", "1196272338179694768600999144304379632914959515649912505115115629486205252321578777191602183854394057825436050662588") + E12TestPoints[7].out[5].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "527308942306717486757915312029417273574429181327162556081593223052291953408016323452563259175229324996214905871008", "1830058412945392218502804289234688920115807490101366281198866396547937042860284410713893747632909565627015984300170", "941235368115924759574834144640944446593867708823113907983266655356668012197408508496877674294093002443230425941517", "3445738167756824837990288450276658651227287301195914962102625721229084551904882407682556089063696731326995816210487", "3052916461528414259166838237883204157869922299076595821144758206215927825791801876217535256703777467973285212800305", "1433214661385057942982602210207185138687689182175745786372192445285395385976721058505499473939898747648368574337269", "1279127534466127318965888972712162981666555546327206017723278334262978498285228139553869037524775139139094711007782", "3159295551429267356732912329482860906540970933045959759928401799689159793286245971497961769908002984442131323542781", "3780750163683895595125184554441698218643686703242966341861376621971985712004786686597297212311187972908274421608010", "2532916186471719789929602135205581150246816086065137538268465073291456482091409545431614161243916363348611626289595", "1173189511005020157634500388847326848768416951958734601874080208744259276227025899024792271922385628386574802365792") + E12TestPoints[7].out[6].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "3475100612914949906659874513706486882982453638611845329250464913071739697082821540990124369953786339041679366688779", "1152800935291363517607485731757702820673571485674042845736146352613933722513364907622882088699592107840421802932285", "2057581607676369689759481844310685313647148118127015001173909598106932268282651270446831387657890753718192027885823", "208650246869418603332804752171031437109172151982620534530846592245700234231616202025139417851400850807520076106667", "1606296512320416928810629122340125705884954664289341463166750548391660025689563825975236497691186191384586472797621", "2573693279894896414927880694766233472330582742554931234238328695311078178210453814264194995188304958695377963200717", "2458359522403425906338667678119737758227018591859545945309903006711284611299407321343836425132420650321087457788511", "286237708488545335797788859166976580118643645961241690257460231669283488760885676665787078061752487396953440851272", "1341932648495170020776475744577296423802367612752768077390170969908789676133174413724659602407662858868948105336329", "3071172871764612189803866297757042066546096695852380275477166344686338270842475583807425836519739491260431215324246", "3581035962302804372086471757815952343081015169326443641568594078245075746231218144489919530239717197050490138638258") + E12TestPoints[7].out[7].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "527308942306717486757915312029417273574429181327162556081593223052291953408016323452563259175229324996214905871008", "114769534599905485155503692190529922793927211710626602959282141469162339347902183281962493838215344692686260373794", "1908373251814379116235469949337256889289443625441851131612645128153429915780064448322927866135330553754242043685985", "765321634334261158760306127630276942438767670725713457760279007140647332817571658785270957916719783518418532455967", "3345606136594503598858112291248478449358888676512078486352607517640475449500310026692603503863067668717916859521648", "2582483716390227785515751564976059294094983151527593036423880801202248348999108847702752791475322439565347571112013", "1798985288058217798575922966180923826942820433368221642024783758200282447679110746900575510954015301201521478122258", "3159295551429267356732912329482860906540970933045959759928401799689159793286245971497961769908002984442131323542781", "3780750163683895595125184554441698218643686703242966341861376621971985712004786686597297212311187972908274421608010", "2308141403110203498506345065627674964319403487868260048196649143449550861360276360026585205985925718650155872543628", "1997934887442050381604238231803504113225935362560718930666932867979110933194958860454125485937857221182392169334877") + E12TestPoints[7].out[8].SetString("3769270681462702395837954694093297877476864511191716195866388084068744365877696153611774558319797014061313883940861", "3475100612914949906659874513706486882982453638611845329250464913071739697082821540990124369953786339041679366688779", "941235368115924759574834144640944446593867708823113907983266655356668012197408508496877674294093002443230425941517", "1830058412945392218502804289234688920115807490101366281198866396547937042860284410713893747632909565627015984300170", "556671387464842555427501375459245505329595518743092923229432414894947098585955456760131540065318932710898456349300", "3052916461528414259166838237883204157869922299076595821144758206215927825791801876217535256703777467973285212800305", "3935241680402011261344248648788842433376788366507037214527715800143227867968484512417044126889369569451887563465683", "2925025480848564094149786465861588720410412852847582750894684865834528944520816498502222656581288010752998628001816", "3716171846733122057620000966568927576438239173977766195074597904454748161729952187776900551067263176640940831708515", "2660476906726497372641314081158607732754515207186239807941887166215241974357663450718028026721352805168946167223458", "2615651680984643299335583218154086280167919248959456634588857969263077036602360139303778385228463125137659837609713", "294736329783924644688312428242763446322034960100331920393643310773240410703604971381848463566967594113865883119072") + E12TestPoints[7].out[9].SetString("447187671312478853941925577816767686741050422713847069413761790802966250907501193676090212973272652251156329002769", "3069503048309046706727415640809553758804814328321170386609992717364029082791323678276920706450169671918594449770104", "3075617578396455397157196681731644371821364820124870028262506539182466842075271081689582481110135473923992653494380", "2270851550104799865967348161536337031178982791588770329974091977398180467638822725214471048506792646666749690174431", "3181311240980247987080509069464531566065459741384843331897503345938596226241406198819644113967863976942949723103663", "3731487368435590543576677357782668052330059822883825971769345077489799443317797063318647395968009392517603693129505", "2762049279309977521213764547630139990427851627665978223307460990166867473799182151154233352717164995234244273726924", "2613258290054370886252596720665779420996518556020185564288321476154982552897365577270005320673263786273221275959349", "1366282176609091764174658841188918321796299039596169236200409097681850580015983869222066902359700193780096817679015", "3869424208118913952005053314765796197430073011013103054263014538405142407553540136181315843557611077811319255962852", "2057949296311573944799611077248865274815400495169628950324371472527520756704792276615468119295848144610977370845946", "807295275518899020261825999801500347578189412552017134274092141727964980253182041675133160137497984403983922456323") + E12TestPoints[7].out[10].SetString("3426576037100839319296007190063805501894243013390800957926725743452883358098038873411986157992303144273847813715533", "2313793479178871374000118598207896054487829104427607610015656111058214335695845272057736301341724097159506074612739", "3223434601723283379658671155841091983223989185329245577654206626099420117659534575025650958549043244178746055044402", "1276746930111096375643324254805496429948689393206503346799265913812480666280865745128684293043400735745308576805925", "699859566625757258812314305143435948562962080944568507292873971526286588629725869175071549684681851996668762887077", "1584441252047453775565555066133452498548601114048288950402511585573697405474816565898777119875213226107795934132135", "3188069339284199665798538444083543526939253130267652204639463426286711965033804810385142403354271707420878059548206", "368999084306462835665518585932582071467546492282860518088795342037448537732964928113375560268840705094670663989269", "2542084190144347738907796137051924859371249548398988527585706631669046506148153387732768732994351293030073316335072", "466361130676240076559627461712064705228964498978971478419527889472422877828030858586697133251215056624096132351268", "347401534481639076181456467449450298027318223155999808862315420922124340887361847615416481658503793586186091219060", "374249360601311594024044590367703298569458535117293724819597618855255081481506889054342988153121898163131231320859") E12TestPoints[8].in[0].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "739720370888128899389935988267945500556872046608720366574823531255138012045624448171330568782247571484325216814848", "3045994411941858844134551299808225050985416478928065786450719210557961778565994733952807190391128346929612685704080", "2043695846950757749030770196243625649023953373050961770309432994533208966551436688421364780112364739013805300309764", "3209959377057937068260946222481871266209012684123170890162832339595781994429157212860813130991147250766470273787074", "734928445668943616472876868241776430885042033317181722601687270509797800945907264516941891473688076111147480384056", "1808574193214925037624552645163021269110902107057164349379421565693018617972043731456321562717035355758615271603176", "189725184010114347420362844307429452063457228460099358404695014887267431204225262804515326254687872664229357550831", "2792283110496749106334938774097377585339389947572585251856186303400540649824560092949330034849067626190377307611461", "2007501425535489565488302014040761203203787435892367048427712429674331883917766371993632621052079442928799331734147", "1517850604783937256700629626030366540935850553931613585472719263784703735430307776632510828506388038422079369905417", "2886052906809725638248756417790086144355952523194632521941514925507107387819046592552606294690338643840323276679215") E12TestPoints[8].in[1].SetString("2471938525527678873078338086057100514018139817869854248260865507322716036237652030960639738993561270892037441567573", "1719612062288606269361171323716069977991438236566871325713996517427894522444425336905365098534370088814406274499378", "2789728503508156146607332340928480978286655411944119904109127089951740574488680735703669045797809722389774891592561", "112780573284578415213811327706469913952670321093234316730362301193174415479350928640707925786648985869236146364321", "1401350580890065120626460410617157116929743651496654804966413740745459455449834225906865968188397368337621915530116", "607621161694189303746084983657481775002978542296636611337357070608575775841329627856392064352627169947225016586015", "3341909921323125737928775190081402925832422436429304446449427269483298201387011081526850473143847397289908729061002", "838866576413573152003389408973581666867020484420439167314718348579883331775478475080458057377020454840238358882792", "1476311062553529425997959636471955613321464144756422271062463590522487747266561816901315774725435020557201185775292", "2315612807004501059193983181481931018037426319009778543124228879448588576812119271577979054222494262711768323045741", "820110742436987987291467196453396204346341514910279711988122000753893264842151419669368487481543368155127370750236", "976916854517407792786695470213868117002776086157077152480600871520586416200040888035861886436938319280586399018541") E12TestPoints[8].out[0].SetString("3060209988459339147665224202304137541043781038360454776639678856787100890835229062148859675649723510424514897149352", "2459332433176735168751107311984015478548310283175591692288820048683032534490049785076695667316617660298731491314226", "1833313360228347597324093815000801872715189070933177805227788164385670702563837605213788607059922405281493304736854", "2156476420235336164244581523950095562976623694144196087039795295726383382030787617062072705899013724883041446674085", "608900402726334795469616807363124226581873515680817809797187944217209799388153574324991470050528955066197916757403", "1342549607363132920218961851899258205888020575613818333939044341118373576787236892373333955826315246058372496970071", "1148074559316383382135538009508520038386441723547460910496790699052285168868216948540484406731867089010629728104391", "1028591760423687499423752253281011118930477712880538525719413363467150762979703737884973383631708327504467716433623", "266184617828611138915108584833429042103971272389999637586591757798996746600284045407958180445486982709684220826966", "320704677318323231264495369786788064684330934963137706219883172998888810239047779128924046145558041602673382220101", "2337961347220925243992096822483762745282192068841893297460841264538597000272459196301879315987931406577206740655653", "3862969761327133431035451888003954261358728609351709674422115797027693804019087480588468181127276963120909675697756") E12TestPoints[8].out[1].SetString("2118742492625648794926337855925840669564384222559754165450005978265700468850762864670267826791616632678334286573993", "3022517863821190023446554490287779679122316629980856926192885149951275140092036975708653099376893146707813214875257", "256265908433702697527218958879744072698761066983945882341592120606221204077313998249138144593318624539837794111519", "1930915273666179333816958868537155735071283051957727453579070693340034551072085759780656854325715753144569153945443", "1808608796167871947634485811864714149279269032626516085196418598850322538979322986953947162802749882428848358256958", "127307283974754312726791884584294655882063491020545111264330199901222025104577636660549827121060906163922463798041", "2469073827113466693113567280817522499835362490566867788262052432333752067075870514372158718702203622506600815101961", "3353268162818208588834763261069751941753319563978668076422034802431415749919584652166744898006683081861885271227826", "1315972047943219680336979137625421972017925802816162980793722712878052902557998276048014260123632605633176121836169", "3694298173752655899712108658294734341723243936821596390635541686349774957596484964858341195958600844254925281248193", "697739862346949269409162429576970336589509039021333873484597263030810470588156356963142341024844670266951999155181", "1909136052292317845462060947576218027353176437037555369460914053986520971619005704516744408253400324559736877660674") E12TestPoints[8].out[2].SetString("1990244616802079762330557112019797634148124183011671798235001289258469719353983605863856921727212878658997010008705", "1835447698521511639369140636835109053658681107261027804770108695390220105728325537244970498737732988346249995782323", "1009271256444214395115999387599349574926294594278884593030367975620914634770947132359804709525225601485472356781946", "3535970912770020699768434711595463280362560710501793471424479302326216895198402604489658835057124613701536468343367", "2248405014282624151871532961805100677184844780380690737985016237172117697003687960442669051673633729795061909401315", "1787179396181505365773384599923989791902766217267803105816402430758047028706331717462075175314122352904319890160288", "3433205422392412447783253197173640135800350550042843292853347204218292725380328147012234542258963302157573420436666", "3016099734441084485086721774501363484500273394962333149277411453731195783919084574815814080394514953485026436135141", "2182914028226984439363318296377954778471264881486368477210278923915148836858935338876327968635818565640341348977555", "3432042136257070414725249506222596399678380316328969246380196579777779338197171998448567443561211929141329322240764", "2249906190741268743416725360313110068422251752994989597687190040890380542456477661297136715719442259807909644657398", "2596895021559821861430467486519602090646246559829503409332437577525712255265066806280518639968948339837348772913912") - E12TestPoints[8].out[3].SetString("2661560136887287277655647508591766656329427277407285269966883430414995109992024574548801618892582526342680659730213", "1041291586186176371598993984443759950399543926288773950553354469415931912145462068568972514180370838700270102787690", "1394400039280910618136181869498471577853040344371697161587090987905019305181431281584149731156918609586365144224516", "1208603306332875806097593048230263788116967604431845438557391343881938447353324101612594187236473378875593310588339", "3791996623462652810390994929782843766003152833799969243693738892289314959765607908276902612960664786604538072666286", "2986800301787298384181931646642880662804111240586544278246223440779968255608133658820545601352765371600078991881406", "3027306711861901844713557574306465976085197929194126990389074675856780848909378371133746140927036641570934279898889", "1252208471968727606926200142203700519310135559762782265985952714985179379240400301435793294512632500549124011314597", "1508931732659335009251701453514959701923077264049053218737081874326800571970755260040919460375646053734659677116310", "3602329528533068594023011075383896245752085640631647857906900529352980256235707195590419131758320531147791544453923", "1198968452214896567039669945876306068775232880305305304002845178362365829536359034241946882637920488701440730660870", "2947396910547782550313776448015308556736842445729188179000862709395705850867281244857924170506863632603031449870735") - E12TestPoints[8].out[4].SetString("2011762644314690497310441053353619983952663750910332491039516059707047130949971337275298501632760153270664622420225", "3144086845295737430511592777377553791071734488042330121701053940153128915134118324096057751061095987258313213039516", "2309411120206718924464609328482504227896495090290849306100790451229330096922390876490960501849164329215396339696727", "623436743061049700933521328105312603677795723856450951450799339506727367484723099979382864865936401074648106746176", "3181624852027960666683487283263108254565821913762351514121049684116599835926507973694639029623357411014872437794205", "2556602232244847638963832691363974386097505905575848619254749714900107732433548057135350371359682560471756615376920", "1344309807648713982906484872301028175896183987852221164788124082688532118719387305301446180062295059668487460893406", "1237290058504223943797540719913492072694173861610604884984218422679172865198018187313552721578537413844107231793109", "2532098762899461102693387455384440785446532722007512481183453322837774930840944758956134886281851881048795892775788", "3677173795452533435986914763466489372598122667871358408124055956659302102910895024559990375599068566262062147382197", "761748556372594604730476179078609023168122014764011660052396245588527741097909216305619608399799177795221182270101", "1809030045718451651432876443081864756428717143214460553809549194358940420285559985897613882721559993355723232300599") - E12TestPoints[8].out[5].SetString("227520708552116954505938686868870570966338248708483697370075972714386884889497127573291713310919553755075630391442", "480739975953544985069955195627059574379039424179475119594801405829255148643726871355296427964874090013239590535505", "1293951907673436428993732900786375379079994500876482862181133371112321030147738277698263287092846282425090394400788", "458252598557296669977456330827311987453900825732288384145938804347542354622715793365222195163464851051235425197175", "2498747275829362383474008608864969652566658878404362617412741955111878798363820867547650120453878041787465563256276", "2039486809852438594138287160077582933836421537097335786969966439316178706902088892550407949078804507876950737009964", "1961326107865621872723940196497998454681285817572298220370572715689148862005729339116425065262121841109165997817010", "2714379944172727110805680753009937669205263366325437333362352815575938077942320490065685330082840330934087152104666", "518765522369797558813033212346811841253129495151023096440308484862364113263641976139139129006891897459077187392500", "1580441385922088236174150099023413669584685419403167604854505626108847428588018855788269424187474960561270806015602", "2644516063705938831193869275227432355958574957479650907691058102662936935566541500629549455275135516997920269708957", "201083453919883492283223149410603434300359641761879623492594309215287038270216360073899090869512004568656669742747") - E12TestPoints[8].out[6].SetString("1237080009214616776475900092157793528827757852754487563662091959076411831619352215110911392741580426777150866754848", "2053686819295575427346884543580345143722273680797072212547528207527585590770293088937942876078354714515719067401564", "643395015851306115312442377726782566348193775646039306072329649735192672336021525417137086648278940347984897447856", "2616607915128108999813902760819959403469419292205494660259476424369491945299872957368388813051355832367922177935688", "3616116775332017044794865225822726180316860442628659960385954499622722027793803149698798197467813764691724865329645", "3202790063431712570868680519923376895866718182189924764835273734552705769080018436134203507980703308194516330196338", "2981253370357161785933662725812716919547683087928988847888064444611597575432471280288304783388218092347394244348947", "614403232179458877612713234779564360071984552392828935695449364275772571445654474143633060673240034986141111131496", "2096114638219329485391252318786218398742163038217723753191534691195340426563217416158815514812104026297997945927497", "2686023372869720049715486226349794940727939732839787021704836333806621646673876712346487537075857827547257051122295", "2453124295618331203114678921284010710800730570030461153181336034487342480056228919724109509075847813281467271790900", "1055626187389809705514483330004028969664101148199752115869448543449638792225482159141513030346689451345623388450200") - E12TestPoints[8].out[7].SetString("576719967194380267202122002497634809233757709506827363704255931868072197796625898464334311782420238245541781449977", "2567366878101357163309470774879918981837976778535502757996798008285056717337492425631723439278675749012771431589539", "3467628709244718009407960241161860494065586817043154071441823963430044557448975920456515497922058197163969359501345", "1158217589037999084943350912679356266169091726752304765341033512200714460526585043965554996072893867948573019804618", "867908764525570456114765074445589242053222499699596124021870631446337958934609083193650885927012153724367390305669", "1688693467719277182849067616918385144044283405876252495232879083453769773498938973941699485432670406747389225071251", "3292004710687302660060907708975212202573620334700916967552200320745868317204121678528843265384924068775244482623151", "1947694903038588677154422836674184026677436346848695802764076238057336198484734373227397085322629009106757021729745", "1103431501565163572631256196557513000743886284969931501987725571686522691630500959536718816375952391636481883799099", "2573742293887369863355658566908976371854236382901426906136330384972779411280394065023271559223116174625580263583098", "1285389301045523128081676311080236889798419578989236106930972719973734080691734601101616745560679585575472207285350", "523640744672928523351200132001627866630297564225224446878576474385206339593825384795997137160880407780251025015249") - E12TestPoints[8].out[8].SetString("3780967050762824354692650864069890710517337732608846026377544538581248136847407247979766059714981448785903658989820", "3610134310243265395923587664536785756682969718662603347688155979006293026248207221295119741829156919206019934615568", "2849874232736404719773988775320305830107215298388679819863977485309274552463026810352693022038772660094497024606063", "2633099120431349591813288692480789231958140280022781183125986329737011843740528678433216175099738712726250271531738", "1399456971613491706326991810216578832859831291770368705203261291709166449461860136141827799821256540398507422323194", "2050856350245823523202805996078685237825027373668603368420532228623154236427103008198707248182432649966934261417274", "1268189373733187962623551225752268544536248529750077784715558397820090208623501038111651914847240098893529306792183", "2436036969475226838609338924331518801622501002799829912625696121262188175049118065603567553150331955553625442687702", "2552317084671124801594705477247574834887355682129786208304735179602255843354493497751636936886798438803277621376372", "532598317751111333245945688222520017866431313438384745377354055709250117207626349070304776308792787813826615061199", "534738466639064140221448671052736751402972481930893940698134685823108990354101571236090091204329781136400952609724", "576877657291526565641239225597456519253926352771660579391719831043230930987916067365796280140370138848022659481447") - E12TestPoints[8].out[9].SetString("761684956550320687258428090434086442017350798665909480546809039993760453841363878355614699319517533733385420095983", "3206821974829232193357127387096744241435207843906208157800307931999684672620902969715939746929330156549173356186138", "3825072835745570347143618238433896135218188167408553364445437901427337248552051948727905072777674721776343256981144", "1341025937425944041990091570196912141880380278941426002377635374670386915420606017322292698114886596520013060471607", "2878060845207468025666888525096082255504662425579133728613403353334119666648712148447083944801279558188077485367390", "2493726872696313724317143367215932616793086136732916258436960022053301663972858204237232761878833194064451660201149", "1149563734352767105468082765941261731925129720021954033688383256441489665052833992049856268034612725199251393101206", "2122641498526386405447857357403536414650928357544692642964307399262385249688213424615027518433167193442115644201429", "2221543619388728840763986795659024633208518494660321396084908340563129805641686578763415922242239235208089563775130", "2233002587571570157887117101130134880558337964699631492781175140198404376986568255290554225003097974438932193886222", "900586193737015554415142319965704653123281107350109363209684488076238119994075525049584475129334301266414870817513", "3210034662884231717511984425923507219316128977422855018625067664131770091540506885952130317195409185881875410068524") - E12TestPoints[8].out[10].SetString("131889601048058872609082575043595334373205188394850970171125326611289374605394530178936715337660084822680230967297", "1548597723464833681700503727455999933570994700497074014852308732009291385052337531980166064648653950237311702928201", "548734540211363673280001404606154847045332383987041783218531659617471852976845703505606435069697480912823530925734", "3878747801619607552716801391949974754209272423368213407587986801542764857387929771463184970417605316065401229459603", "3415245305398169504893508364151226973362808852615578862740663598276850459249217159119370004487621759794820970246312", "521711343696460873073339157724707739853820167893543539571960283536242939358162106258354386114871533898559310032606", "3694183974201214836929314245655121840540030293034453270460829602176335396049950139295413951816238816668021164840722", "3502100150850936071190678929248897866436317103087620414774871074665469395174225413661859505887807498035632003364545", "3900496446874116524117124797439276218426887323625433229483742099513591689014388046482273702449100156597064896884189", "115826207325966365058650896198804579718986987745864248037999454943285502979559636246637079453919259610937508247590", "370382909012252009126576037524309283110128747909366422227766008710794127538404124720578059834125951050393460675551", "1217061599361399191288839740226132052953000385366944544474813644462363918109332479781961326110237979478581237858028") - E12TestPoints[8].out[11].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "739720370888128899389935988267945500556872046608720366574823531255138012045624448171330568782247571484325216814848", "3045994411941858844134551299808225050985416478928065786450719210557961778565994733952807190391128346929612685704080", "2043695846950757749030770196243625649023953373050961770309432994533208966551436688421364780112364739013805300309764", "3209959377057937068260946222481871266209012684123170890162832339595781994429157212860813130991147250766470273787074", "734928445668943616472876868241776430885042033317181722601687270509797800945907264516941891473688076111147480384056", "2193835362006742355793237180572882887445980712881843535952636570431013032518794132986366066411980308279279000956611", "3812684371211553045997426981428474704493425591478908526927363121236764219286612601638172302874327791373664915008956", "1210126444724918287082851051638526571217492872366422633475871832723491000666277771493357594279948037847516964948326", "1994908129686177827929487811695142953353095384046640836904345706449699766573071492449055008076936221109094940825640", "2484558950437730136717160199705537615621032266007394299859338872339327915060530087810176800622627625615814902654370", "1116356648411941755169033407945818012200930296744375363390543210616924262671791271890081334438677020197570995880572") - E12TestPoints[8].out[12].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "3262689184333538494027853837467958656000010773330287518757234604868893638445213416271357060346768092553569055744939", "1056051940317546779511931099639214446752733164778062768063772677954727253657617264339040358517063423978300911242963", "3030398317094021316355486490600474359576023927010785129734511402373694547375957618190816057528570714989410811494267", "1867078933980559464599811251949506213253117936587679508047241047019744991103964429805627498912044282925599007286342", "236447136324589846688575800367954110232704664319248411047443873781982785200385252566136460635804633292162300925297", "3544011588410509508160367058864288220920509755270627812936145953360939012884249538136070496016928899985280445774573", "124318036999530337501596234412409562659520862985316109193028479607019553498000883938245369688715578693980263746979", "3438243864052822658473198755321413349971994375572142556430847416861740500061873788504179632746128322190476253618008", "2814424810681849364703763898573444001408543071886413437905836136126012657422676404580157355994253321456697229899280", "1887043143938749864722210855572482378949679642698255225898716133636811982353622642554575355144100059592887692928345", "519235238324767718547026438902698043043617864316510864040927305417051408559521425260996594779053605808794818939980") - E12TestPoints[8].out[13].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "739720370888128899389935988267945500556872046608720366574823531255138012045624448171330568782247571484325216814848", "1928426381407454626345541861063108902552325233939164854478885659316406975039723376741752010338332266156765047921227", "902661767953362864875088529853064060780196282109983346958852463636095430281783911682282490499587501045788061007060", "2659529112144289789756654855203539103600988072403516503216466843547994647165645081387501997049912696197023006059055", "3031033973228133930256337157126173615439136122302577751682926991832251064344545347359609277019522954634584491250434", "2517919098016470468951019539177851722775597649778193266194321593066565507928672208392083517601154429396387107535358", "1521549687867310532451973688584952086187646563905925884360149060599886941262795244323700007186605840877524770908705", "1210126444724918287082851051638526571217492872366422633475871832723491000666277771493357594279948037847516964948326", "1994908129686177827929487811695142953353095384046640836904345706449699766573071492449055008076936221109094940825640", "3559753848161179292150997191056110160893255499041505648948725945254419772052741649528085057899241181436419462496398", "3669954308650006427709156359187778671159600611090697195712665328759838821362902370416363305910167497531033112837454") - E12TestPoints[8].out[14].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "3262689184333538494027853837467958656000010773330287518757234604868893638445213416271357060346768092553569055744939", "2043695846950757749030770196243625649023953373050961770309432994533208966551436688421364780112364739013805300309764", "3045994411941858844134551299808225050985416478928065786450719210557961778565994733952807190391128346929612685704080", "792450178163730325156843603254032890347870135815836995169225796528249656061680651581874498137868413271423998772713", "734928445668943616472876868241776430885042033317181722601687270509797800945907264516941891473688076111147480384056", "3222385247486482203757185702829081072042845914438103919189571366791627033435593890959793005356914714238950884884975", "2821543967866460774320395683299619996374123327535756855446478080701862986668393862681298602570980968299016970944884", "564165691168844734944591070414490806584888444366865328901210719262291150428964075938507996382887341847418018941779", "1187984744539818028714025927162460155148339748052594447426221999998018993068161459862530273134762342581197042660507", "1260258626232414566859766755977177962636191527199985170408360653813159511772331853281817268084666193699075010871513", "1459889301558553975963454542644550405531035769077330244260422265438445820358426034098604437110341635626681768691785") - E12TestPoints[8].out[15].SetString("2814109130285621506284600691543276602039947772040665135291219377943522741065969314485120235653550394700235231439009", "1662307097773886171011531474209295921921010220289870716786912230858190656672231158120791417424648315536456101764387", "1854033990482390897252903128103068048086956912077634172777180568127214433920786199136075139777336223099431185041486", "3426211824360317990114401858009958125791257915635270511284227449035532426634607886594200404238558963054282303017520", "207772410531730703551783331377900621761510239275594126571332937996944424889067379520252107997628104330392439041993", "629695512333361907011377894717435694398059660869533975976641763984350934433221602778210850822480713888267117515206", "3559351227052497999894105128680920088416402798636649449795621519511328959883453880439235553840392889109043132342802", "1442358864634400877370897652231645014345263023171611750370786126222601644668356106626830813260630386722600605411501", "2634354207484303198331063532539350285136456283471564722085723442770408627479899041763358779063612640397450723815219", "273589920814261179509173985364977704582604376307015197138211537315493174446920809702857347506194460794627618929364", "1203137969932357766052654217188341130152386875762565949524378814625082821491205405324663544162435414352678844969824", "3390512161036723503905503625318402161608251273540798217899408087887021246093368302679106744633063912581116806273304") - E12TestPoints[8].out[16].SetString("829100078143258261556080870183507323151403432495177907368944129982968729041211595810581137846036200090478185290980", "3549993138768905411172506761783965570304001532041742940522803226815609836697267473942101007426463308421663106302027", "970203121182612163906413012529266700959784834034649270739057510440836223837915172343057128282305041564110588556400", "3642292778155218095393369686866966741776760014101737614382312091457905183735466768571140968454175115003428825032778", "1555138346289316837832710098441995427070382855704169868367934570772096892175680068946386311238219627930298550148536", "93179841730920883865561993714394300599752670839472998093328175206904114576710254124775579846990296735077875345145", "2204311767400232064481560386469881161057317087109002198977748616568235153011881416324785518305440689806393332212623", "137552185157267773970266157042348580801993161448149074699999819921436597874537870607415244197292924045253451782141", "1507771491063764017086684996116951003851893406970856655456763868674780966724587339374785331114987769684376447822361", "2113948456172443773911506886432434646620325507485729827508492848121996632432093944363954528084748970466803907635546", "2678456296223887028729903819773724296888432823715872661955391465654808010771837599455184411068655063115257402791169", "3752621049789536068483260480891969945630759066565322003674638454587875733520695091354521353125390829414128506830904") + E12TestPoints[8].out[3].SetString("761684956550320687258428090434086442017350798665909480546809039993760453841363878355614699319517533733385420095983", "3206821974829232193357127387096744241435207843906208157800307931999684672620902969715939746929330156549173356186138", "3825072835745570347143618238433896135218188167408553364445437901427337248552051948727905072777674721776343256981144", "1341025937425944041990091570196912141880380278941426002377635374670386915420606017322292698114886596520013060471607", "2878060845207468025666888525096082255504662425579133728613403353334119666648712148447083944801279558188077485367390", "2493726872696313724317143367215932616793086136732916258436960022053301663972858204237232761878833194064451660201149", "1149563734352767105468082765941261731925129720021954033688383256441489665052833992049856268034612725199251393101206", "2122641498526386405447857357403536414650928357544692642964307399262385249688213424615027518433167193442115644201429", "2221543619388728840763986795659024633208518494660321396084908340563129805641686578763415922242239235208089563775130", "2233002587571570157887117101130134880558337964699631492781175140198404376986568255290554225003097974438932193886222", "900586193737015554415142319965704653123281107350109363209684488076238119994075525049584475129334301266414870817513", "3210034662884231717511984425923507219316128977422855018625067664131770091540506885952130317195409185881875410068524") + E12TestPoints[8].out[4].SetString("131889601048058872609082575043595334373205188394850970171125326611289374605394530178936715337660084822680230967297", "1548597723464833681700503727455999933570994700497074014852308732009291385052337531980166064648653950237311702928201", "548734540211363673280001404606154847045332383987041783218531659617471852976845703505606435069697480912823530925734", "3878747801619607552716801391949974754209272423368213407587986801542764857387929771463184970417605316065401229459603", "3415245305398169504893508364151226973362808852615578862740663598276850459249217159119370004487621759794820970246312", "521711343696460873073339157724707739853820167893543539571960283536242939358162106258354386114871533898559310032606", "3694183974201214836929314245655121840540030293034453270460829602176335396049950139295413951816238816668021164840722", "3502100150850936071190678929248897866436317103087620414774871074665469395174225413661859505887807498035632003364545", "3900496446874116524117124797439276218426887323625433229483742099513591689014388046482273702449100156597064896884189", "115826207325966365058650896198804579718986987745864248037999454943285502979559636246637079453919259610937508247590", "370382909012252009126576037524309283110128747909366422227766008710794127538404124720578059834125951050393460675551", "1217061599361399191288839740226132052953000385366944544474813644462363918109332479781961326110237979478581237858028") + E12TestPoints[8].out[5].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "739720370888128899389935988267945500556872046608720366574823531255138012045624448171330568782247571484325216814848", "3045994411941858844134551299808225050985416478928065786450719210557961778565994733952807190391128346929612685704080", "2043695846950757749030770196243625649023953373050961770309432994533208966551436688421364780112364739013805300309764", "3209959377057937068260946222481871266209012684123170890162832339595781994429157212860813130991147250766470273787074", "734928445668943616472876868241776430885042033317181722601687270509797800945907264516941891473688076111147480384056", "2193835362006742355793237180572882887445980712881843535952636570431013032518794132986366066411980308279279000956611", "3812684371211553045997426981428474704493425591478908526927363121236764219286612601638172302874327791373664915008956", "1210126444724918287082851051638526571217492872366422633475871832723491000666277771493357594279948037847516964948326", "1994908129686177827929487811695142953353095384046640836904345706449699766573071492449055008076936221109094940825640", "2484558950437730136717160199705537615621032266007394299859338872339327915060530087810176800622627625615814902654370", "1116356648411941755169033407945818012200930296744375363390543210616924262671791271890081334438677020197570995880572") + E12TestPoints[8].out[6].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "3262689184333538494027853837467958656000010773330287518757234604868893638445213416271357060346768092553569055744939", "1056051940317546779511931099639214446752733164778062768063772677954727253657617264339040358517063423978300911242963", "3030398317094021316355486490600474359576023927010785129734511402373694547375957618190816057528570714989410811494267", "1867078933980559464599811251949506213253117936587679508047241047019744991103964429805627498912044282925599007286342", "236447136324589846688575800367954110232704664319248411047443873781982785200385252566136460635804633292162300925297", "3544011588410509508160367058864288220920509755270627812936145953360939012884249538136070496016928899985280445774573", "124318036999530337501596234412409562659520862985316109193028479607019553498000883938245369688715578693980263746979", "3438243864052822658473198755321413349971994375572142556430847416861740500061873788504179632746128322190476253618008", "2814424810681849364703763898573444001408543071886413437905836136126012657422676404580157355994253321456697229899280", "1887043143938749864722210855572482378949679642698255225898716133636811982353622642554575355144100059592887692928345", "519235238324767718547026438902698043043617864316510864040927305417051408559521425260996594779053605808794818939980") + E12TestPoints[8].out[7].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "739720370888128899389935988267945500556872046608720366574823531255138012045624448171330568782247571484325216814848", "1928426381407454626345541861063108902552325233939164854478885659316406975039723376741752010338332266156765047921227", "902661767953362864875088529853064060780196282109983346958852463636095430281783911682282490499587501045788061007060", "2659529112144289789756654855203539103600988072403516503216466843547994647165645081387501997049912696197023006059055", "3031033973228133930256337157126173615439136122302577751682926991832251064344545347359609277019522954634584491250434", "2517919098016470468951019539177851722775597649778193266194321593066565507928672208392083517601154429396387107535358", "1521549687867310532451973688584952086187646563905925884360149060599886941262795244323700007186605840877524770908705", "1210126444724918287082851051638526571217492872366422633475871832723491000666277771493357594279948037847516964948326", "1994908129686177827929487811695142953353095384046640836904345706449699766573071492449055008076936221109094940825640", "3559753848161179292150997191056110160893255499041505648948725945254419772052741649528085057899241181436419462496398", "3669954308650006427709156359187778671159600611090697195712665328759838821362902370416363305910167497531033112837454") + E12TestPoints[8].out[8].SetString("588271462931660274586886116247037027025641220490600528378813349464384854597577031188219936656162239532477455581779", "3262689184333538494027853837467958656000010773330287518757234604868893638445213416271357060346768092553569055744939", "2043695846950757749030770196243625649023953373050961770309432994533208966551436688421364780112364739013805300309764", "3045994411941858844134551299808225050985416478928065786450719210557961778565994733952807190391128346929612685704080", "792450178163730325156843603254032890347870135815836995169225796528249656061680651581874498137868413271423998772713", "734928445668943616472876868241776430885042033317181722601687270509797800945907264516941891473688076111147480384056", "3222385247486482203757185702829081072042845914438103919189571366791627033435593890959793005356914714238950884884975", "2821543967866460774320395683299619996374123327535756855446478080701862986668393862681298602570980968299016970944884", "564165691168844734944591070414490806584888444366865328901210719262291150428964075938507996382887341847418018941779", "1187984744539818028714025927162460155148339748052594447426221999998018993068161459862530273134762342581197042660507", "1260258626232414566859766755977177962636191527199985170408360653813159511772331853281817268084666193699075010871513", "1459889301558553975963454542644550405531035769077330244260422265438445820358426034098604437110341635626681768691785") + E12TestPoints[8].out[9].SetString("2814109130285621506284600691543276602039947772040665135291219377943522741065969314485120235653550394700235231439009", "1662307097773886171011531474209295921921010220289870716786912230858190656672231158120791417424648315536456101764387", "1854033990482390897252903128103068048086956912077634172777180568127214433920786199136075139777336223099431185041486", "3426211824360317990114401858009958125791257915635270511284227449035532426634607886594200404238558963054282303017520", "207772410531730703551783331377900621761510239275594126571332937996944424889067379520252107997628104330392439041993", "629695512333361907011377894717435694398059660869533975976641763984350934433221602778210850822480713888267117515206", "3559351227052497999894105128680920088416402798636649449795621519511328959883453880439235553840392889109043132342802", "1442358864634400877370897652231645014345263023171611750370786126222601644668356106626830813260630386722600605411501", "2634354207484303198331063532539350285136456283471564722085723442770408627479899041763358779063612640397450723815219", "273589920814261179509173985364977704582604376307015197138211537315493174446920809702857347506194460794627618929364", "1203137969932357766052654217188341130152386875762565949524378814625082821491205405324663544162435414352678844969824", "3390512161036723503905503625318402161608251273540798217899408087887021246093368302679106744633063912581116806273304") + E12TestPoints[8].out[10].SetString("829100078143258261556080870183507323151403432495177907368944129982968729041211595810581137846036200090478185290980", "3549993138768905411172506761783965570304001532041742940522803226815609836697267473942101007426463308421663106302027", "970203121182612163906413012529266700959784834034649270739057510440836223837915172343057128282305041564110588556400", "3642292778155218095393369686866966741776760014101737614382312091457905183735466768571140968454175115003428825032778", "1555138346289316837832710098441995427070382855704169868367934570772096892175680068946386311238219627930298550148536", "93179841730920883865561993714394300599752670839472998093328175206904114576710254124775579846990296735077875345145", "2204311767400232064481560386469881161057317087109002198977748616568235153011881416324785518305440689806393332212623", "137552185157267773970266157042348580801993161448149074699999819921436597874537870607415244197292924045253451782141", "1507771491063764017086684996116951003851893406970856655456763868674780966724587339374785331114987769684376447822361", "2113948456172443773911506886432434646620325507485729827508492848121996632432093944363954528084748970466803907635546", "2678456296223887028729903819773724296888432823715872661955391465654808010771837599455184411068655063115257402791169", "3752621049789536068483260480891969945630759066565322003674638454587875733520695091354521353125390829414128506830904") // benchmark inputs should be randomly generated, // so use the final test point diff --git a/bls381/e2.go b/bls381/e2.go index 3d83aa259..1a5bacd72 100644 --- a/bls381/e2.go +++ b/bls381/e2.go @@ -207,15 +207,6 @@ func (z *E2) Square(x *E2) *E2 { return z } -// MulByNonSquare multiplies an element by (0,1) -// TODO deprecate in favor of inlined MulByNonResidue in fp6 package -func (z *E2) MulByNonSquare(x *E2) *E2 { - a := x.A0 - MulByNonResidue(&z.A0, &x.A1) - z.A1 = a - return z -} - // Inverse sets z to the E2-inverse of x, returns z func (z *E2) Inverse(x *E2) *E2 { // Algorithm 8 from https://eprint.iacr.org/2010/354.pdf @@ -249,18 +240,3 @@ func (z *E2) Conjugate(x *E2) *E2 { z.A1.Neg(&x.A1) return z } - -// MulByNonResidue multiplies a fp.Element by -1 -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidue(out, in *fp.Element) *fp.Element { - (out).Neg(in) - return out -} - -// MulByNonResidueInv multiplies a fp.Element by -1^{-1} -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidueInv(out, in *fp.Element) *fp.Element { - // TODO this should be a no-op when out==in - (out).Set(in) - return out -} diff --git a/bls381/e6.go b/bls381/e6.go index 9f3edf360..24cc026fc 100644 --- a/bls381/e6.go +++ b/bls381/e6.go @@ -16,8 +16,6 @@ package bls381 -import "github.com/consensys/gurvy/bls381/fp" - // E6 is a degree-three finite field extension of fp2: // B0 + B1v + B2v^2 where v^3-1,1 is irrep in fp2 @@ -113,15 +111,15 @@ func (z *E6) MulByGen(x *E6) *E6 { result.B1 = x.B0 result.B2 = x.B1 - { // begin: inline result.B0.MulByNonResidue(&x.B2) + { // begin inline: set result.B0 to (&x.B2) * (1,1) var buf E2 buf.Set(&x.B2) result.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + { // begin inline: set &(result.B0).A0 to (&buf.A1) * (-1) (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + } // end inline: set &(result.B0).A0 to (&buf.A1) * (-1) result.B0.A0.AddAssign(&buf.A0) - } // end: inline result.B0.MulByNonResidue(&x.B2) + } // end inline: set result.B0 to (&x.B2) * (1,1) z.Set(&result) return z @@ -155,15 +153,15 @@ func (z *E6) Mul(x, y *E6) *E6 { rb0.Mul(&b3, &b4). SubAssign(&b1). SubAssign(&b2) - { // begin: inline rb0.MulByNonResidue(&rb0) + { // begin inline: set rb0 to (&rb0) * (1,1) var buf E2 buf.Set(&rb0) rb0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(rb0).A0, &buf.A1) + { // begin inline: set &(rb0).A0 to (&buf.A1) * (-1) (&(rb0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(rb0).A0, &buf.A1) + } // end inline: set &(rb0).A0 to (&buf.A1) * (-1) rb0.A0.AddAssign(&buf.A0) - } // end: inline rb0.MulByNonResidue(&rb0) + } // end inline: set rb0 to (&rb0) * (1,1) rb0.AddAssign(&b0) // step 5 @@ -172,15 +170,15 @@ func (z *E6) Mul(x, y *E6) *E6 { z.B1.Mul(&b3, &b4). SubAssign(&b0). SubAssign(&b1) - { // begin: inline b3.MulByNonResidue(&b2) + { // begin inline: set b3 to (&b2) * (1,1) var buf E2 buf.Set(&b2) b3.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(b3).A0, &buf.A1) + { // begin inline: set &(b3).A0 to (&buf.A1) * (-1) (&(b3).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(b3).A0, &buf.A1) + } // end inline: set &(b3).A0 to (&buf.A1) * (-1) b3.A0.AddAssign(&buf.A0) - } // end: inline b3.MulByNonResidue(&b2) + } // end inline: set b3 to (&b2) * (1,1) z.B1.AddAssign(&b3) // step 6 @@ -209,15 +207,15 @@ func (z *E6) MulAssign(x *E6) *E6 { rb0.Mul(&b3, &b4). SubAssign(&b1). SubAssign(&b2) - { // begin: inline rb0.MulByNonResidue(&rb0) + { // begin inline: set rb0 to (&rb0) * (1,1) var buf E2 buf.Set(&rb0) rb0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(rb0).A0, &buf.A1) + { // begin inline: set &(rb0).A0 to (&buf.A1) * (-1) (&(rb0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(rb0).A0, &buf.A1) + } // end inline: set &(rb0).A0 to (&buf.A1) * (-1) rb0.A0.AddAssign(&buf.A0) - } // end: inline rb0.MulByNonResidue(&rb0) + } // end inline: set rb0 to (&rb0) * (1,1) rb0.AddAssign(&b0) // step 5 @@ -226,15 +224,15 @@ func (z *E6) MulAssign(x *E6) *E6 { z.B1.Mul(&b3, &b4). SubAssign(&b0). SubAssign(&b1) - { // begin: inline b3.MulByNonResidue(&b2) + { // begin inline: set b3 to (&b2) * (1,1) var buf E2 buf.Set(&b2) b3.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(b3).A0, &buf.A1) + { // begin inline: set &(b3).A0 to (&buf.A1) * (-1) (&(b3).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(b3).A0, &buf.A1) + } // end inline: set &(b3).A0 to (&buf.A1) * (-1) b3.A0.AddAssign(&buf.A0) - } // end: inline b3.MulByNonResidue(&b2) + } // end inline: set b3 to (&b2) * (1,1) z.B1.AddAssign(&b3) // step 6 @@ -258,39 +256,6 @@ func (z *E6) MulByE2(x *E6, y *E2) *E6 { return z } -// MulByNotv2 multiplies x by y with &y.b2=0 -func (z *E6) MulByNotv2(x, y *E6) *E6 { - // Algorithm 15 from https://eprint.iacr.org/2010/354.pdf - var rb0, b0, b1, b2, b3 E2 - b0.Mul(&x.B0, &y.B0) // step 1 - b1.Mul(&x.B1, &y.B1) // step 2 - // step 3 - b2.Add(&x.B1, &x.B2) - rb0.Mul(&b2, &y.B1). - SubAssign(&b1) - { // begin: inline rb0.MulByNonResidue(&rb0) - var buf E2 - buf.Set(&rb0) - rb0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(rb0).A0, &buf.A1) - (&(rb0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(rb0).A0, &buf.A1) - rb0.A0.AddAssign(&buf.A0) - } // end: inline rb0.MulByNonResidue(&rb0) - rb0.AddAssign(&b0) - // step 4 - b2.Add(&x.B0, &x.B1) - b3.Add(&y.B0, &y.B1) - z.B1.Mul(&b2, &b3). - SubAssign(&b0). - SubAssign(&b1) - // step 5 - z.B2.Mul(&x.B2, &y.B0). - AddAssign(&b1) - z.B0 = rb0 - return z -} - // Square sets z to the E6-product of x,x, returns z func (z *E6) Square(x *E6) *E6 { @@ -300,30 +265,30 @@ func (z *E6) Square(x *E6) *E6 { b4.Square(&x.B2) // step 2 // step 3 - { // begin: inline b0.MulByNonResidue(&b4) + { // begin inline: set b0 to (&b4) * (1,1) var buf E2 buf.Set(&b4) b0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(b0).A0, &buf.A1) + { // begin inline: set &(b0).A0 to (&buf.A1) * (-1) (&(b0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(b0).A0, &buf.A1) + } // end inline: set &(b0).A0 to (&buf.A1) * (-1) b0.A0.AddAssign(&buf.A0) - } // end: inline b0.MulByNonResidue(&b4) + } // end inline: set b0 to (&b4) * (1,1) b0.AddAssign(&b3) b1.Sub(&b3, &b4) // step 4 b2.Square(&x.B0) // step 5 b3.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&b3) // steps 6 and 8 b4.Mul(&x.B1, &x.B2).Double(&b4) // step 7 // step 9 - { // begin: inline z.B0.MulByNonResidue(&b4) + { // begin inline: set z.B0 to (&b4) * (1,1) var buf E2 buf.Set(&b4) z.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + { // begin inline: set &(z.B0).A0 to (&buf.A1) * (-1) (&(z.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + } // end inline: set &(z.B0).A0 to (&buf.A1) * (-1) z.B0.A0.AddAssign(&buf.A0) - } // end: inline z.B0.MulByNonResidue(&b4) + } // end inline: set z.B0 to (&b4) * (1,1) z.B0.AddAssign(&b2) // step 10 @@ -343,30 +308,30 @@ func (z *E6) SquareAssign() *E6 { b4.Square(&z.B2) // step 2 // step 3 - { // begin: inline b0.MulByNonResidue(&b4) + { // begin inline: set b0 to (&b4) * (1,1) var buf E2 buf.Set(&b4) b0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(b0).A0, &buf.A1) + { // begin inline: set &(b0).A0 to (&buf.A1) * (-1) (&(b0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(b0).A0, &buf.A1) + } // end inline: set &(b0).A0 to (&buf.A1) * (-1) b0.A0.AddAssign(&buf.A0) - } // end: inline b0.MulByNonResidue(&b4) + } // end inline: set b0 to (&b4) * (1,1) b0.AddAssign(&b3) b1.Sub(&b3, &b4) // step 4 b2.Square(&z.B0) // step 5 b3.Sub(&z.B0, &z.B1).AddAssign(&z.B2).Square(&b3) // steps 6 and 8 b4.Mul(&z.B1, &z.B2).Double(&b4) // step 7 // step 9 - { // begin: inline z.B0.MulByNonResidue(&b4) + { // begin inline: set z.B0 to (&b4) * (1,1) var buf E2 buf.Set(&b4) z.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + { // begin inline: set &(z.B0).A0 to (&buf.A1) * (-1) (&(z.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + } // end inline: set &(z.B0).A0 to (&buf.A1) * (-1) z.B0.A0.AddAssign(&buf.A0) - } // end: inline z.B0.MulByNonResidue(&b4) + } // end inline: set z.B0 to (&b4) * (1,1) z.B0.AddAssign(&b2) // step 10 @@ -391,25 +356,25 @@ func (z *E6) SquarE2(x *E6) *E6 { v12.Add(&x.B1, &x.B2) v12.Square(&v12) z.B0.Sub(&v12, &v1).SubAssign(&v2) - { // begin: inline z.B0.MulByNonResidue(&z.B0) + { // begin inline: set z.B0 to (&z.B0) * (1,1) var buf E2 buf.Set(&z.B0) z.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + { // begin inline: set &(z.B0).A0 to (&buf.A1) * (-1) (&(z.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + } // end inline: set &(z.B0).A0 to (&buf.A1) * (-1) z.B0.A0.AddAssign(&buf.A0) - } // end: inline z.B0.MulByNonResidue(&z.B0) + } // end inline: set z.B0 to (&z.B0) * (1,1) z.B0.AddAssign(&v0) - { // begin: inline z.B1.MulByNonResidue(&v2) + { // begin inline: set z.B1 to (&v2) * (1,1) var buf E2 buf.Set(&v2) z.B1.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(z.B1).A0, &buf.A1) + { // begin inline: set &(z.B1).A0 to (&buf.A1) * (-1) (&(z.B1).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B1).A0, &buf.A1) + } // end inline: set &(z.B1).A0 to (&buf.A1) * (-1) z.B1.A0.AddAssign(&buf.A0) - } // end: inline z.B1.MulByNonResidue(&v2) + } // end inline: set z.B1 to (&v2) * (1,1) z.B1.AddAssign(&v01).SubAssign(&v0).SubAssign(&v1) z.B2.Add(&v02, &v1).SubAssign(&v0).SubAssign(&v2) return z @@ -424,25 +389,25 @@ func (z *E6) Square3(x *E6) *E6 { s2.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&s2) s3.Mul(&x.B1, &x.B2).Double(&s3) s4.Square(&x.B2) - { // begin: inline z.B0.MulByNonResidue(&s3) + { // begin inline: set z.B0 to (&s3) * (1,1) var buf E2 buf.Set(&s3) z.B0.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + { // begin inline: set &(z.B0).A0 to (&buf.A1) * (-1) (&(z.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + } // end inline: set &(z.B0).A0 to (&buf.A1) * (-1) z.B0.A0.AddAssign(&buf.A0) - } // end: inline z.B0.MulByNonResidue(&s3) + } // end inline: set z.B0 to (&s3) * (1,1) z.B0.AddAssign(&s0) - { // begin: inline z.B1.MulByNonResidue(&s4) + { // begin inline: set z.B1 to (&s4) * (1,1) var buf E2 buf.Set(&s4) z.B1.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(z.B1).A0, &buf.A1) + { // begin inline: set &(z.B1).A0 to (&buf.A1) * (-1) (&(z.B1).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B1).A0, &buf.A1) + } // end inline: set &(z.B1).A0 to (&buf.A1) * (-1) z.B1.A0.AddAssign(&buf.A0) - } // end: inline z.B1.MulByNonResidue(&s4) + } // end inline: set z.B1 to (&s4) * (1,1) z.B1.AddAssign(&s1) z.B2.Add(&s1, &s2).AddAssign(&s3).SubAssign(&s0).SubAssign(&s4) return z @@ -463,41 +428,41 @@ func (z *E6) Inverse(x *E6) *E6 { t[4].Mul(&x.B0, &x.B2) // step 5 t[5].Mul(&x.B1, &x.B2) // step 6 // step 7 - { // begin: inline c[0].MulByNonResidue(&t[5]) + { // begin inline: set c[0] to (&t[5]) * (1,1) var buf E2 buf.Set(&t[5]) c[0].A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(c[0]).A0, &buf.A1) + { // begin inline: set &(c[0]).A0 to (&buf.A1) * (-1) (&(c[0]).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(c[0]).A0, &buf.A1) + } // end inline: set &(c[0]).A0 to (&buf.A1) * (-1) c[0].A0.AddAssign(&buf.A0) - } // end: inline c[0].MulByNonResidue(&t[5]) + } // end inline: set c[0] to (&t[5]) * (1,1) c[0].Neg(&c[0]).AddAssign(&t[0]) // step 8 - { // begin: inline c[1].MulByNonResidue(&t[2]) + { // begin inline: set c[1] to (&t[2]) * (1,1) var buf E2 buf.Set(&t[2]) c[1].A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(c[1]).A0, &buf.A1) + { // begin inline: set &(c[1]).A0 to (&buf.A1) * (-1) (&(c[1]).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(c[1]).A0, &buf.A1) + } // end inline: set &(c[1]).A0 to (&buf.A1) * (-1) c[1].A0.AddAssign(&buf.A0) - } // end: inline c[1].MulByNonResidue(&t[2]) + } // end inline: set c[1] to (&t[2]) * (1,1) c[1].SubAssign(&t[3]) c[2].Sub(&t[1], &t[4]) // step 9 is wrong in 2010/354! // steps 10, 11, 12 t[6].Mul(&x.B2, &c[1]) buf.Mul(&x.B1, &c[2]) t[6].AddAssign(&buf) - { // begin: inline t[6].MulByNonResidue(&t[6]) + { // begin inline: set t[6] to (&t[6]) * (1,1) var buf E2 buf.Set(&t[6]) t[6].A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(t[6]).A0, &buf.A1) + { // begin inline: set &(t[6]).A0 to (&buf.A1) * (-1) (&(t[6]).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(t[6]).A0, &buf.A1) + } // end inline: set &(t[6]).A0 to (&buf.A1) * (-1) t[6].A0.AddAssign(&buf.A0) - } // end: inline t[6].MulByNonResidue(&t[6]) + } // end inline: set t[6] to (&t[6]) * (1,1) buf.Mul(&x.B0, &c[0]) t[6].AddAssign(&buf) @@ -507,35 +472,3 @@ func (z *E6) Inverse(x *E6) *E6 { z.B2.Mul(&c[2], &t[6]) // step 16 return z } - -// MulByNonResidue multiplies a E2 by (1,1) -func (z *E2) MulByNonResidue(x *E2) *E2 { - var buf E2 - buf.Set(x) - z.A1.Add(&buf.A0, &buf.A1) - { // begin: inline MulByNonResidue(&(z).A0, &buf.A1) - (&(z).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z).A0, &buf.A1) - z.A0.AddAssign(&buf.A0) - return z -} - -// MulByNonResidueInv multiplies a E2 by (1,1)^{-1} -func (z *E2) MulByNonResidueInv(x *E2) *E2 { - // (z).A0 = ((x).A0 + (x).A1)/2 - // (z).A1 = ((x).A1 - (x).A0)/2 - buf := *(x) - (z).A0.Add(&buf.A0, &buf.A1) - (z).A1.Sub(&buf.A1, &buf.A0) - twoInv := fp.Element{ - 1730508156817200468, - 9606178027640717313, - 7150789853162776431, - 7936136305760253186, - 15245073033536294050, - 1728177566264616342, - } - (z).A0.MulAssign(&twoInv) - (z).A1.MulAssign(&twoInv) - return z -} diff --git a/bls381/pairing.go b/bls381/pairing.go index dc419bd96..ffa41e183 100644 --- a/bls381/pairing.go +++ b/bls381/pairing.go @@ -16,7 +16,10 @@ package bls381 -import "math/bits" +import ( + "github.com/consensys/gurvy/bls381/fp" + "math/bits" +) // FinalExponentiation computes the final expo x**(p**6-1)(p**2+1)(p**4 - p**2 +1)/r func (curve *Curve) FinalExponentiation(z *PairingResult, _z ...*PairingResult) PairingResult { @@ -214,7 +217,7 @@ type lineEvalRes struct { func (l *lineEvalRes) mulAssign(z *PairingResult) *PairingResult { - var a, b, c E12 + var a, b, c PairingResult a.MulByVWNRInv(z, &l.r1) b.MulByV2NRInv(z, &l.r0) c.MulByWNRInv(z, &l.r2) @@ -223,6 +226,85 @@ func (l *lineEvalRes) mulAssign(z *PairingResult) *PairingResult { return z } +// MulByV2NRInv set z to x*(y*v^2*(1,1)^{-1}) and return z +// here y*v^2 means the PairingResult element with C0.B2=y and all other components 0 +func (z *PairingResult) MulByV2NRInv(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNRInv G2CoordType + yNRInv.mulByNonResidueInv(y) + + result.C0.B0.Mul(&x.C0.B1, y) + result.C0.B1.Mul(&x.C0.B2, y) + result.C0.B2.Mul(&x.C0.B0, &yNRInv) + + result.C1.B0.Mul(&x.C1.B1, y) + result.C1.B1.Mul(&x.C1.B2, y) + result.C1.B2.Mul(&x.C1.B0, &yNRInv) + + z.Set(&result) + return z +} + +// MulByVWNRInv set z to x*(y*v*w*(1,1)^{-1}) and return z +// here y*v*w means the PairingResult element with C1.B1=y and all other components 0 +func (z *PairingResult) MulByVWNRInv(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNRInv G2CoordType + yNRInv.mulByNonResidueInv(y) + + result.C0.B0.Mul(&x.C1.B1, y) + result.C0.B1.Mul(&x.C1.B2, y) + result.C0.B2.Mul(&x.C1.B0, &yNRInv) + + result.C1.B0.Mul(&x.C0.B2, y) + result.C1.B1.Mul(&x.C0.B0, &yNRInv) + result.C1.B2.Mul(&x.C0.B1, &yNRInv) + + z.Set(&result) + return z +} + +// MulByWNRInv set z to x*(y*w*(1,1)^{-1}) and return z +// here y*w means the PairingResult element with C1.B0=y and all other components 0 +func (z *PairingResult) MulByWNRInv(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNRInv G2CoordType + yNRInv.mulByNonResidueInv(y) + + result.C0.B0.Mul(&x.C1.B2, y) + result.C0.B1.Mul(&x.C1.B0, &yNRInv) + result.C0.B2.Mul(&x.C1.B1, &yNRInv) + + result.C1.B0.Mul(&x.C0.B0, &yNRInv) + result.C1.B1.Mul(&x.C0.B1, &yNRInv) + result.C1.B2.Mul(&x.C0.B2, &yNRInv) + + z.Set(&result) + return z +} + +// mulByNonResidueInv set z to x * (1,1)^{-1} and return z +func (z *G2CoordType) mulByNonResidueInv(x *G2CoordType) *G2CoordType { + { // begin inline: set z to x * (1,1)^{-1} + // z.A0 = (x.A0 + x.A1)/2 + // z.A1 = (x.A1 - x.A0)/2 + buf := *x + z.A0.Add(&buf.A0, &buf.A1) + z.A1.Sub(&buf.A1, &buf.A0) + twoInv := fp.Element{ + 1730508156817200468, + 9606178027640717313, + 7150789853162776431, + 7936136305760253186, + 15245073033536294050, + 1728177566264616342, + } + z.A0.MulAssign(&twoInv) + z.A1.MulAssign(&twoInv) + } // end inline: set z to x * (1,1)^{-1} + return z +} + const tAbsVal uint64 = 15132376222941642752 // negative // Expt set z to x^t in PairingResult and return z diff --git a/bn256/e12.go b/bn256/e12.go index 96e34707a..ba738521b 100644 --- a/bn256/e12.go +++ b/bn256/e12.go @@ -16,10 +16,6 @@ package bn256 -import ( - "github.com/consensys/gurvy/bn256/fp" -) - // E12 is a degree-two finite field extension of fp6: // C0 + C1w where w^3-v is irrep in fp6 @@ -135,11 +131,11 @@ func (z *E12) Mul(x, y *E12) *E12 { ySum.Add(&y.C0, &y.C1) // step 3 - { // begin: inline z.C0.MulByNonResidue(&t1) + { // begin inline: set z.C0 to (&t1) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&t1).B0) result.B2.Set(&(&t1).B1) - { // begin: inline result.B0.MulByNonResidue(&(&t1).B2) + { // begin inline: set result.B0 to (&(&t1).B2) * (9,1) var buf, buf9 E2 buf.Set(&(&t1).B2) buf9.Double(&buf). @@ -147,13 +143,13 @@ func (z *E12) Mul(x, y *E12) *E12 { Double(&buf9). Add(&buf9, &buf) result.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + { // begin inline: set &(result.B0).A0 to (&buf.A1) * (-1) (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + } // end inline: set &(result.B0).A0 to (&buf.A1) * (-1) result.B0.A0.AddAssign(&buf9.A0) - } // end: inline result.B0.MulByNonResidue(&(&t1).B2) + } // end inline: set result.B0 to (&(&t1).B2) * (9,1) z.C0.Set(&result) - } // end: inline z.C0.MulByNonResidue(&t1) + } // end inline: set z.C0 to (&t1) * ((0,0),(1,0),(0,0)) z.C0.Add(&z.C0, &t0) // step 4 @@ -173,11 +169,11 @@ func (z *E12) Square(x *E12) *E12 { b0.Square(&x.C0) b1.Square(&x.C1) - { // begin: inline b1.MulByNonResidue(&b1) + { // begin inline: set b1 to (&b1) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&b1).B0) result.B2.Set(&(&b1).B1) - { // begin: inline result.B0.MulByNonResidue(&(&b1).B2) + { // begin inline: set result.B0 to (&(&b1).B2) * (9,1) var buf, buf9 E2 buf.Set(&(&b1).B2) buf9.Double(&buf). @@ -185,13 +181,13 @@ func (z *E12) Square(x *E12) *E12 { Double(&buf9). Add(&buf9, &buf) result.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + { // begin inline: set &(result.B0).A0 to (&buf.A1) * (-1) (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + } // end inline: set &(result.B0).A0 to (&buf.A1) * (-1) result.B0.A0.AddAssign(&buf9.A0) - } // end: inline result.B0.MulByNonResidue(&(&b1).B2) + } // end inline: set result.B0 to (&(&b1).B2) * (9,1) b1.Set(&result) - } // end: inline b1.MulByNonResidue(&b1) + } // end inline: set b1 to (&b1) * ((0,0),(1,0),(0,0)) b1.Add(&b0, &b1) z.C1.Mul(&x.C0, &x.C1).Double(&z.C1) @@ -210,11 +206,11 @@ func (z *E12) Inverse(x *E12) *E12 { t[1].Square(&x.C1) // step 2 { // step 3 var buf E6 - { // begin: inline buf.MulByNonResidue(&t[1]) + { // begin inline: set buf to (&t[1]) * ((0,0),(1,0),(0,0)) var result E6 result.B1.Set(&(&t[1]).B0) result.B2.Set(&(&t[1]).B1) - { // begin: inline result.B0.MulByNonResidue(&(&t[1]).B2) + { // begin inline: set result.B0 to (&(&t[1]).B2) * (9,1) var buf, buf9 E2 buf.Set(&(&t[1]).B2) buf9.Double(&buf). @@ -222,13 +218,13 @@ func (z *E12) Inverse(x *E12) *E12 { Double(&buf9). Add(&buf9, &buf) result.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + { // begin inline: set &(result.B0).A0 to (&buf.A1) * (-1) (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + } // end inline: set &(result.B0).A0 to (&buf.A1) * (-1) result.B0.A0.AddAssign(&buf9.A0) - } // end: inline result.B0.MulByNonResidue(&(&t[1]).B2) + } // end inline: set result.B0 to (&(&t[1]).B2) * (9,1) buf.Set(&result) - } // end: inline buf.MulByNonResidue(&t[1]) + } // end inline: set buf to (&t[1]) * ((0,0),(1,0),(0,0)) t[0].Sub(&t[0], &buf) } t[1].Inverse(&t[0]) // step 4 @@ -250,238 +246,3 @@ func (z *E12) Conjugate(x *E12) *E12 { z.C1.Neg(&z.C1) return z } - -// MulByVW set z to x*(y*v*w) and return z -// here y*v*w means the E12 element with C1.B1=y and all other components 0 -func (z *E12) MulByVW(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - var buf, buf9 E2 - buf.Set(y) - buf9.Double(&buf). - Double(&buf9). - Double(&buf9). - Add(&buf9, &buf) - yNR.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(yNR).A0, &buf.A1) - (&(yNR).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(yNR).A0, &buf.A1) - yNR.A0.AddAssign(&buf9.A0) - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C1.B1, &yNR) - result.C0.B1.Mul(&x.C1.B2, &yNR) - result.C0.B2.Mul(&x.C1.B0, y) - result.C1.B0.Mul(&x.C0.B2, &yNR) - result.C1.B1.Mul(&x.C0.B0, y) - result.C1.B2.Mul(&x.C0.B1, y) - z.Set(&result) - return z -} - -// MulByV set z to x*(y*v) and return z -// here y*v means the E12 element with C0.B1=y and all other components 0 -func (z *E12) MulByV(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - var buf, buf9 E2 - buf.Set(y) - buf9.Double(&buf). - Double(&buf9). - Double(&buf9). - Add(&buf9, &buf) - yNR.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(yNR).A0, &buf.A1) - (&(yNR).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(yNR).A0, &buf.A1) - yNR.A0.AddAssign(&buf9.A0) - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C0.B2, &yNR) - result.C0.B1.Mul(&x.C0.B0, y) - result.C0.B2.Mul(&x.C0.B1, y) - result.C1.B0.Mul(&x.C1.B2, &yNR) - result.C1.B1.Mul(&x.C1.B0, y) - result.C1.B2.Mul(&x.C1.B1, y) - z.Set(&result) - return z -} - -// MulByV2W set z to x*(y*v^2*w) and return z -// here y*v^2*w means the E12 element with C1.B2=y and all other components 0 -func (z *E12) MulByV2W(x *E12, y *E2) *E12 { - var result E12 - var yNR E2 - - { // begin: inline yNR.MulByNonResidue(y) - var buf, buf9 E2 - buf.Set(y) - buf9.Double(&buf). - Double(&buf9). - Double(&buf9). - Add(&buf9, &buf) - yNR.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(yNR).A0, &buf.A1) - (&(yNR).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(yNR).A0, &buf.A1) - yNR.A0.AddAssign(&buf9.A0) - } // end: inline yNR.MulByNonResidue(y) - result.C0.B0.Mul(&x.C1.B0, &yNR) - result.C0.B1.Mul(&x.C1.B1, &yNR) - result.C0.B2.Mul(&x.C1.B2, &yNR) - result.C1.B0.Mul(&x.C0.B1, &yNR) - result.C1.B1.Mul(&x.C0.B2, &yNR) - result.C1.B2.Mul(&x.C0.B0, y) - z.Set(&result) - return z -} - -// MulByV2NRInv set z to x*(y*v^2*(9,1)^{-1}) and return z -// here y*v^2 means the E12 element with C0.B2=y and all other components 0 -func (z *E12) MulByV2NRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - // (yNRInv).A0 = (9*(y).A0 + (y).A1)/82 - // (yNRInv).A1 = (9*(y).A1 - (y).A0)/82 - copy := *(y) - - var copy9 E2 - copy9.Double(©). - Double(©9). - Double(©9). - AddAssign(©) - - (yNRInv).A0.Add(©9.A0, ©.A1) - (yNRInv).A1.Sub(©9.A1, ©.A0) - - buf82inv := fp.Element{ - 15263610803691847034, - 14617516054323294413, - 1961223913490700324, - 3456812345740674661, - } - (yNRInv).A0.MulAssign(&buf82inv) - (yNRInv).A1.MulAssign(&buf82inv) - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C0.B1, y) - result.C0.B1.Mul(&x.C0.B2, y) - result.C0.B2.Mul(&x.C0.B0, &yNRInv) - - result.C1.B0.Mul(&x.C1.B1, y) - result.C1.B1.Mul(&x.C1.B2, y) - result.C1.B2.Mul(&x.C1.B0, &yNRInv) - - z.Set(&result) - return z -} - -// MulByVWNRInv set z to x*(y*v*w*(9,1)^{-1}) and return z -// here y*v*w means the E12 element with C1.B1=y and all other components 0 -func (z *E12) MulByVWNRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - // (yNRInv).A0 = (9*(y).A0 + (y).A1)/82 - // (yNRInv).A1 = (9*(y).A1 - (y).A0)/82 - copy := *(y) - - var copy9 E2 - copy9.Double(©). - Double(©9). - Double(©9). - AddAssign(©) - - (yNRInv).A0.Add(©9.A0, ©.A1) - (yNRInv).A1.Sub(©9.A1, ©.A0) - - buf82inv := fp.Element{ - 15263610803691847034, - 14617516054323294413, - 1961223913490700324, - 3456812345740674661, - } - (yNRInv).A0.MulAssign(&buf82inv) - (yNRInv).A1.MulAssign(&buf82inv) - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C1.B1, y) - result.C0.B1.Mul(&x.C1.B2, y) - result.C0.B2.Mul(&x.C1.B0, &yNRInv) - - result.C1.B0.Mul(&x.C0.B2, y) - result.C1.B1.Mul(&x.C0.B0, &yNRInv) - result.C1.B2.Mul(&x.C0.B1, &yNRInv) - - z.Set(&result) - return z -} - -// MulByWNRInv set z to x*(y*w*(9,1)^{-1}) and return z -// here y*w means the E12 element with C1.B0=y and all other components 0 -func (z *E12) MulByWNRInv(x *E12, y *E2) *E12 { - var result E12 - var yNRInv E2 - - { // begin: inline yNRInv.MulByNonResidueInv(y) - // (yNRInv).A0 = (9*(y).A0 + (y).A1)/82 - // (yNRInv).A1 = (9*(y).A1 - (y).A0)/82 - copy := *(y) - - var copy9 E2 - copy9.Double(©). - Double(©9). - Double(©9). - AddAssign(©) - - (yNRInv).A0.Add(©9.A0, ©.A1) - (yNRInv).A1.Sub(©9.A1, ©.A0) - - buf82inv := fp.Element{ - 15263610803691847034, - 14617516054323294413, - 1961223913490700324, - 3456812345740674661, - } - (yNRInv).A0.MulAssign(&buf82inv) - (yNRInv).A1.MulAssign(&buf82inv) - } // end: inline yNRInv.MulByNonResidueInv(y) - - result.C0.B0.Mul(&x.C1.B2, y) - result.C0.B1.Mul(&x.C1.B0, &yNRInv) - result.C0.B2.Mul(&x.C1.B1, &yNRInv) - - result.C1.B0.Mul(&x.C0.B0, &yNRInv) - result.C1.B1.Mul(&x.C0.B1, &yNRInv) - result.C1.B2.Mul(&x.C0.B2, &yNRInv) - - z.Set(&result) - return z -} - -// MulByNonResidue multiplies a E6 by ((0,0),(1,0),(0,0)) -func (z *E6) MulByNonResidue(x *E6) *E6 { - var result E6 - result.B1.Set(&(x).B0) - result.B2.Set(&(x).B1) - { // begin: inline result.B0.MulByNonResidue(&(x).B2) - var buf, buf9 E2 - buf.Set(&(x).B2) - buf9.Double(&buf). - Double(&buf9). - Double(&buf9). - Add(&buf9, &buf) - result.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) - (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) - result.B0.A0.AddAssign(&buf9.A0) - } // end: inline result.B0.MulByNonResidue(&(x).B2) - z.Set(&result) - return z -} diff --git a/bn256/e12_test.go b/bn256/e12_test.go index 612b54ce1..5d98dd91c 100644 --- a/bn256/e12_test.go +++ b/bn256/e12_test.go @@ -8,7 +8,7 @@ import ( type E12TestPoint struct { in [2]E12 - out [17]E12 + out [11]E12 } var E12TestPoints []E12TestPoint @@ -77,60 +77,36 @@ func TestE12Mul(t *testing.T) { E12check(t, (*E12).Mul, 2) } -func TestE12MulByV(t *testing.T) { - E12check(t, (*E12).MulByVBinary, 3) -} - -func TestE12MulByVW(t *testing.T) { - E12check(t, (*E12).MulByVWBinary, 4) -} - -func TestE12MulByV2W(t *testing.T) { - E12check(t, (*E12).MulByV2WBinary, 5) -} - -func TestE12MulByV2NRInv(t *testing.T) { - E12check(t, (*E12).MulByV2NRInvBinary, 6) -} - -func TestE12MulByVWNRInv(t *testing.T) { - E12check(t, (*E12).MulByVWNRInvBinary, 7) -} - -func TestE12MulByWNRInv(t *testing.T) { - E12check(t, (*E12).MulByWNRInvBinary, 8) -} - func TestE12Square(t *testing.T) { - E12check(t, (*E12).SquareBinary, 9) + E12check(t, (*E12).SquareBinary, 3) } func TestE12Inverse(t *testing.T) { - E12check(t, (*E12).InverseBinary, 10) + E12check(t, (*E12).InverseBinary, 4) } func TestE12Conjugate(t *testing.T) { - E12check(t, (*E12).ConjugateBinary, 11) + E12check(t, (*E12).ConjugateBinary, 5) } func TestE12Frobenius(t *testing.T) { - E12check(t, (*E12).FrobeniusBinary, 12) + E12check(t, (*E12).FrobeniusBinary, 6) } func TestE12FrobeniusSquare(t *testing.T) { - E12check(t, (*E12).FrobeniusSquareBinary, 13) + E12check(t, (*E12).FrobeniusSquareBinary, 7) } func TestE12FrobeniusCube(t *testing.T) { - E12check(t, (*E12).FrobeniusCubeBinary, 14) + E12check(t, (*E12).FrobeniusCubeBinary, 8) } func TestE12Expt(t *testing.T) { - E12check(t, (*E12).ExptBinary, 15) + E12check(t, (*E12).ExptBinary, 9) } func TestE12FinalExponentiation(t *testing.T) { - E12check(t, (*E12).FinalExponentiationBinary, 16) + E12check(t, (*E12).FinalExponentiationBinary, 10) } //--------------------// @@ -157,42 +133,6 @@ func BenchmarkE12Mul(b *testing.B) { } } -func BenchmarkE12MulByV(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByVW(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVWBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByV2W(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByV2WBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByV2NRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByV2NRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByVWNRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByVWNRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - -func BenchmarkE12MulByWNRInv(b *testing.B) { - for i := 0; i < b.N; i++ { - E12BenchOut.MulByWNRInvBinary(&E12BenchIn1, &E12BenchIn2) - } -} - func BenchmarkE12Square(b *testing.B) { for i := 0; i < b.N; i++ { E12BenchOut.SquareBinary(&E12BenchIn1, &E12BenchIn2) @@ -292,45 +232,3 @@ func (z *E12) ExptBinary(x, y *E12) *E12 { return z } - -// MulByVBinary a binary wrapper for MulByV -func (z *E12) MulByVBinary(x, y *E12) *E12 { - yCopy := y.C0.B1 - z.MulByV(x, &yCopy) - return z -} - -// MulByVWBinary a binary wrapper for MulByVW -func (z *E12) MulByVWBinary(x, y *E12) *E12 { - yCopy := y.C1.B1 - z.MulByVW(x, &yCopy) - return z -} - -// MulByV2WBinary a binary wrapper for MulByV2W -func (z *E12) MulByV2WBinary(x, y *E12) *E12 { - yCopy := y.C1.B2 - z.MulByV2W(x, &yCopy) - return z -} - -// MulByV2NRInvBinary a binary wrapper for MulByV2NRInv -func (z *E12) MulByV2NRInvBinary(x, y *E12) *E12 { - yCopy := y.C0.B2 - z.MulByV2NRInv(x, &yCopy) - return z -} - -// MulByVWNRInvBinary a binary wrapper for MulByVWNRInv -func (z *E12) MulByVWNRInvBinary(x, y *E12) *E12 { - yCopy := y.C1.B1 - z.MulByVWNRInv(x, &yCopy) - return z -} - -// MulByWNRInvBinary a binary wrapper for MulByWNRInv -func (z *E12) MulByWNRInvBinary(x, y *E12) *E12 { - yCopy := y.C1.B0 - z.MulByWNRInv(x, &yCopy) - return z -} diff --git a/bn256/e12testpoints_test.go b/bn256/e12testpoints_test.go index cccc47857..c263bf8f2 100644 --- a/bn256/e12testpoints_test.go +++ b/bn256/e12testpoints_test.go @@ -18,172 +18,118 @@ func init() { E12TestPoints[0].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[0].out[9].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[0].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[15].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[0].out[16].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].in[0].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[0].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[1].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[1].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[9].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[10].SetString("0", "0", "0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[11].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[12].SetString("0", "0", "21575463638280843010398324269430826099269044274347216827212613867836435027261", "10307601595873709700152284273816112264069230130616436755625194854815875713954", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[13].SetString("0", "0", "21888242871839275220042445260109153167277707414472061641714758635765020556616", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[14].SetString("0", "0", "3772000881919853776433695186713858239009073593817195771773381919316419345261", "2236595495967245188281701248203181795121068902605861227855261137820944008926", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[15].SetString("13914957386299512726234389482947894200630722727726147380644585528023451969395", "18944321610015330588354659227171275362523880687727723819377026532423606736725", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[1].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[3].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[4].SetString("0", "0", "0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[5].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[6].SetString("0", "0", "21575463638280843010398324269430826099269044274347216827212613867836435027261", "10307601595873709700152284273816112264069230130616436755625194854815875713954", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[7].SetString("0", "0", "21888242871839275220042445260109153167277707414472061641714758635765020556616", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[8].SetString("0", "0", "3772000881919853776433695186713858239009073593817195771773381919316419345261", "2236595495967245188281701248203181795121068902605861227855261137820944008926", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[9].SetString("13914957386299512726234389482947894200630722727726147380644585528023451969395", "18944321610015330588354659227171275362523880687727723819377026532423606736725", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[1].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].in[0].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[0].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[1].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[2].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[9].SetString("0", "0", "9", "1", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[10].SetString("0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[11].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[12].SetString("0", "0", "0", "0", "2581911344467009335267311115468803099551665605076196740867805258568234346338", "19937756971775647987995932169929341994314640652964949448313374472400716661030", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[13].SetString("0", "0", "0", "0", "2203960485148121921418603742825762020974279258880205651966", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[14].SetString("0", "0", "0", "0", "5324479202449903542726783395506214481928257762400643279780343368557297135718", "16208900380737693084919495127334387981393726419856888799917914180988844123039", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[15].SetString("1822008324987741107378546940044322452566154097673849219687946013262753631290", "4054971750375589228177002057339482442314128775657335629084489698950834576744", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[2].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[3].SetString("0", "0", "9", "1", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[4].SetString("0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[5].SetString("0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[6].SetString("0", "0", "0", "0", "2581911344467009335267311115468803099551665605076196740867805258568234346338", "19937756971775647987995932169929341994314640652964949448313374472400716661030", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[7].SetString("0", "0", "0", "0", "2203960485148121921418603742825762020974279258880205651966", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[8].SetString("0", "0", "0", "0", "5324479202449903542726783395506214481928257762400643279780343368557297135718", "16208900380737693084919495127334387981393726419856888799917914180988844123039", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[9].SetString("1822008324987741107378546940044322452566154097673849219687946013262753631290", "4054971750375589228177002057339482442314128775657335629084489698950834576744", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[2].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[3].in[0].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[3].out[0].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].out[1].SetString("0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0") E12TestPoints[3].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[9].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[3].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952") - E12TestPoints[3].out[11].SetString("0", "0", "0", "0", "0", "0", "21888242871839275222246405745257275088696311157297823662689037894645226208582", "0", "0", "0", "0", "0") - E12TestPoints[3].out[12].SetString("0", "0", "0", "0", "0", "0", "8376118865763821496583973867626364092589906065868298776909617916018768340080", "16469823323077808223889137241176536799009286646108169935659301613961712198316", "0", "0", "0", "0") - E12TestPoints[3].out[13].SetString("0", "0", "0", "0", "0", "0", "21888242871839275220042445260109153167277707414472061641714758635765020556617", "0", "0", "0", "0", "0") - E12TestPoints[3].out[14].SetString("0", "0", "0", "0", "0", "0", "11697423496358154304825782922584725312912383441159505038794027105778954184319", "303847389135065887422783454877609941456349188919719272345083954437860409601", "0", "0", "0", "0") - E12TestPoints[3].out[15].SetString("0", "0", "0", "0", "0", "0", "0", "0", "9435347093672308614640923273577415046217537609793085851611007744839255039075", "8934703048857334637450358394037288077892100161613194099107489272933646085482", "0", "0") - E12TestPoints[3].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[3].out[3].SetString("0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[3].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952") + E12TestPoints[3].out[5].SetString("0", "0", "0", "0", "0", "0", "21888242871839275222246405745257275088696311157297823662689037894645226208582", "0", "0", "0", "0", "0") + E12TestPoints[3].out[6].SetString("0", "0", "0", "0", "0", "0", "8376118865763821496583973867626364092589906065868298776909617916018768340080", "16469823323077808223889137241176536799009286646108169935659301613961712198316", "0", "0", "0", "0") + E12TestPoints[3].out[7].SetString("0", "0", "0", "0", "0", "0", "21888242871839275220042445260109153167277707414472061641714758635765020556617", "0", "0", "0", "0", "0") + E12TestPoints[3].out[8].SetString("0", "0", "0", "0", "0", "0", "11697423496358154304825782922584725312912383441159505038794027105778954184319", "303847389135065887422783454877609941456349188919719272345083954437860409601", "0", "0", "0", "0") + E12TestPoints[3].out[9].SetString("0", "0", "0", "0", "0", "0", "0", "0", "9435347093672308614640923273577415046217537609793085851611007744839255039075", "8934703048857334637450358394037288077892100161613194099107489272933646085482", "0", "0") + E12TestPoints[3].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[4].in[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[4].out[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].out[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0") E12TestPoints[4].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[9].SetString("9", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[4].out[10].SetString("0", "0", "0", "0", "0", "0", "0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952", "0", "0") - E12TestPoints[4].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "21888242871839275222246405745257275088696311157297823662689037894645226208582", "0", "0", "0") - E12TestPoints[4].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "2821565182194536844548159561693502659359617185244120367078079554186484126554", "3505843767911556378687030309984248845540243509899259641013678093033130930403", "0", "0") - E12TestPoints[4].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "21888242871839275222246405745257275088696311157297823662689037894645226208582", "0", "0", "0") - E12TestPoints[4].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "19066677689644738377698246183563772429336693972053703295610958340458742082029", "18382399103927718843559375435273026243156067647398564021675359801612095278180", "0", "0") - E12TestPoints[4].out[15].SetString("0", "0", "0", "0", "0", "0", "0", "0", "21054022642655178596350740835242480351813005389503203614839390088231356222827", "19836239850953848072723805759553033567646682370929358372921578371175502638339", "0", "0") - E12TestPoints[4].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[4].out[3].SetString("9", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[4].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952", "0", "0") + E12TestPoints[4].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "21888242871839275222246405745257275088696311157297823662689037894645226208582", "0", "0", "0") + E12TestPoints[4].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "2821565182194536844548159561693502659359617185244120367078079554186484126554", "3505843767911556378687030309984248845540243509899259641013678093033130930403", "0", "0") + E12TestPoints[4].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "21888242871839275222246405745257275088696311157297823662689037894645226208582", "0", "0", "0") + E12TestPoints[4].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "19066677689644738377698246183563772429336693972053703295610958340458742082029", "18382399103927718843559375435273026243156067647398564021675359801612095278180", "0", "0") + E12TestPoints[4].out[9].SetString("0", "0", "0", "0", "0", "0", "0", "0", "21054022642655178596350740835242480351813005389503203614839390088231356222827", "19836239850953848072723805759553033567646682370929358372921578371175502638339", "0", "0") + E12TestPoints[4].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[5].in[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].in[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[5].out[0].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].out[1].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0") E12TestPoints[5].out[2].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[3].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[4].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[9].SetString("0", "0", "0", "0", "9", "1", "0", "0", "0", "0", "0", "0") - E12TestPoints[5].out[10].SetString("0", "0", "0", "0", "0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952", "0", "0", "0", "0") - E12TestPoints[5].out[11].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "21888242871839275222246405745257275088696311157297823662689037894645226208582", "0") - E12TestPoints[5].out[12].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "685108087231508774477564247770172212460312782337200605669322048753928464687", "8447204650696766136447902020341177575205426561248465145919723016860428151883") - E12TestPoints[5].out[13].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2203960485148121921418603742825762020974279258880205651967", "0") - E12TestPoints[5].out[14].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "8941241848238582420466759817324047081148088512956452953208002715982955420483", "10338197737521362862238855242243140895517409139741313354160881284257516364953") - E12TestPoints[5].out[15].SetString("0", "0", "0", "0", "0", "0", "0", "0", "2342303558874489518938122874278078156794040441070912176308462194879416618819", "21135433368953517908793734228876472639038613864114877831533346924055879659685", "0", "0") - E12TestPoints[5].out[16].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") + E12TestPoints[5].out[3].SetString("0", "0", "0", "0", "9", "1", "0", "0", "0", "0", "0", "0") + E12TestPoints[5].out[4].SetString("0", "0", "0", "0", "0", "0", "21087453498479301738505683583845423561061080261299122796980902361914303298513", "14681138511599513868579906292550611339979233093309515871315818100066920017952", "0", "0", "0", "0") + E12TestPoints[5].out[5].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "21888242871839275222246405745257275088696311157297823662689037894645226208582", "0") + E12TestPoints[5].out[6].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "685108087231508774477564247770172212460312782337200605669322048753928464687", "8447204650696766136447902020341177575205426561248465145919723016860428151883") + E12TestPoints[5].out[7].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2203960485148121921418603742825762020974279258880205651967", "0") + E12TestPoints[5].out[8].SetString("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "8941241848238582420466759817324047081148088512956452953208002715982955420483", "10338197737521362862238855242243140895517409139741313354160881284257516364953") + E12TestPoints[5].out[9].SetString("0", "0", "0", "0", "0", "0", "0", "0", "2342303558874489518938122874278078156794040441070912176308462194879416618819", "21135433368953517908793734228876472639038613864114877831533346924055879659685", "0", "0") + E12TestPoints[5].out[10].SetString("1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") E12TestPoints[6].in[0].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "12400382958542462801906222473087420600562229272091905816240459399418489160741", "3048312015182622469820234020826433655201231721262150236582154527929496885078", "197691022533435794397451101688434676793779771300738149949822448669324408006", "1900146309614524471139311718449969882731765059571586099214572711814355643141", "5081570600428920354625966618550116398799578790168592831158645865463305368048", "20017111245135799979493897718573986497364743310082345089275884491050740119338", "6285902611929649233433031439418497627265357380930648950363264083344808929412", "20711483515463386896067100184136615338601688398670429228357730423973161001301", "16631288831860366476938006577805782700424499455480914472610881608959319798628", "14644413786492685652143596545249304614979120447303791848631407380480487949491", "20633270843668106630652844415386898662163642451132808874536488118506118661082") E12TestPoints[6].in[1].SetString("11258170439381296896600149117004942205173591156808483285394024435809531206126", "15128092021453569602693249976127296473917676333041717036334829122299575339417", "5623795403609419654661871877716681228795678562772938613799349980689450967968", "20766904341417552333457509394082532574420296198040777731597451607291423311264", "2769004611660675025436578797897909619186066184529507073515883742049433671868", "12854368803725315170506118474398714007939494237739178134341022787709169377893", "3999313965358799405007897774875655516308476381253780886625615161286103441336", "12955970058709988229424758581575129737946360453077501002782425736756762927351", "20609476131707362501705640243529509728464793448076938632128557602183370589241", "8627836792964858463706730222113976341245281280490048166862060226776850060825", "13288034704028483903665509394494164293374372221859581669875883060033396510759", "1855528749356153484018032463745062565698912588450886914578566215095542137623") E12TestPoints[6].out[0].SetString("19611493350195037444458228121623327477296286078134462248944014055603303518839", "5640232108156757182353066703957441985783594447835799189886250627072838291575", "8672107418792042124482105898543114883996910284035088850381504508618947853046", "20964595363950988127854960495770967251214075969341515881547274055960747719270", "4669150921275199496575890516347879501917831244101093172730456453863789315009", "17935939404154235525132085092948830406739073027907770965499668653172474745941", "2128182338655324162255389748192366924976908534038302313212461757691617352091", "19241872670639637462857790020993627365211717834008149953145689820101571856763", "19432716775331474175526334682408849978370170689449544197797250131511305381959", "3370882752985949718398331054662483952973469578673138976783903941090943650870", "6044205618681894333562700194486193819657181511865549855818252545868658251667", "600556721184984892424471133874686139166243882285872126426016438956434590122") E12TestPoints[6].out[1].SetString("18983395343271718873504335632870718155645414921815319340845003078629467315170", "19160533808928168421459378242217399215340864096348012442594668171764140029907", "19312759483412478037404767888367027515101864315787035285471842441885272125693", "1319029552955158683186347452863177191069794730557784081041408736023127305325", "21019384569793124667949138665809335352242010032339902688387726864410148179856", "14115444668542880406366253889408677479556395709727238359506660972399362198738", "16017797279777000574485999943698330981056266928828564202650269329764636678002", "15218175425058936226254678603100642978015308085150971610269876241233272210644", "102007383756024394361459940607105610136894950593490596229172821789790412060", "8003452038895508013231276355691806359179218174990866305748821382182469737803", "1356379082464201748478087150755140321604748225444210178755524320447091438732", "18777742094311953146634811951641836096464729862681921959957921903410576523459") E12TestPoints[6].out[2].SetString("19009239809921856121573871957354917309532491499398488078511094096893939046142", "17994616135147904533062655948473423751772640009880697165986622632069985093419", "2247797772265793406441040077193338604990484945085249538122118612365331017989", "11770236057053438309000032784024223479421925144933078740961961252626286864614", "19068981721980515341019206848260756588314401869817532302274093016353996721666", "11957789362867932993274533639412993612975877279349243507320925284219985375511", "14653569059310953211529264614873400444338820160566570856145773770550687290866", "19628538713556247799969635098437595757999631789740791721222874875507428363106", "1731982513720925953338536527661964040312055190748454372107775482370556183762", "9707004414771055950315590242892270889677341371849216762172146061827179089800", "8774373104303495346117499925555905791943936450280171548203359727159756525315", "15403228558658133556869589054405414133310001960290125095139490536665489422458") - E12TestPoints[6].out[3].SetString("10467198362192212088014904005747835889597359216456970638361201468636373920735", "14869001738585252686045058708802852685181622036843036402269914857312169757321", "7058440165673656835334912142154543427780587516941781534416237298562146069649", "14499834608659975167973502383206645212181835257603683554246561635055530649422", "6661757407115155965976798745768969527569249395293051810531893641536844065736", "4781682757554929267424345337547308247788269302493522749717950179409479942971", "12161298345801759264940639069734031426847438254579368230838991499175829133663", "21100742284480307957958817539177398147911706687830499371539712689342210852960", "2022235675417981482161803129667417912687991199366855157442031438040269792419", "1299171587872708602860912249492532745952516617575236078917921733269230652257", "4867181409895273034796442601614104657488317788869160581764807924887536917844", "17147448758672328975858713007598918051992603602794964616878297761829125835373") - E12TestPoints[6].out[4].SetString("5101941480166368065716732712345286874616829683823725132341740858959763098888", "7505047800514043062048013804512108093994642598437799761752111910987412299273", "15669045632224739583093788963895923914002577466764073664194140096389180696211", "13761142566188403186410368006193298630308059937560601766049963491654172722215", "11565412263455800834871683391827274435227753485325137144515266159676622450925", "12392679226114039633809283175916461921561038090990391665433558958028372294933", "19076901204669281509885220346962812929634142766146909371973736042851563180816", "9993270866781065431794056957905595377078499139583378162869217383485477690448", "19607514593163373377526634107486517972448270219662311707516479812961757172743", "306849075595251854599189568884797198570424247570803073495587438250116562806", "5222233921619074008247630970715072755747103290714374580396970317081688395934", "10575823214985178862650316173122041996336612569072749602861611690197424817665") - E12TestPoints[6].out[5].SetString("17667534139408144204228275574337866477381819613548570462143125425784430120387", "21505536528491043078421382047232844489372448034128328231243853322854741294013", "17640121688530205780631995300142400833908855819806790303554046136910944960688", "18242442901158696982070579651396028676712483793939378940916625544658932992692", "8432190617404010644111970880493188027946023676783662375909146598434835234576", "3539844337313101345068927431545389638254401318780516369154251209544062628770", "13197408361502767619002300499499236669589369522286301025068934528240707408396", "1408065073918373147685894463898856709852674675699482755687829640642434452137", "4858814900743335399179175749767410611311039247534001414450977957450424355362", "14590120343501619853115835588286855132579941616182737928141713017627930121965", "538891345130399202538725441209554461987284367248649554034188589928901009399", "6258590115441547561877904011289796179569198988949654372240376912935699500437") - E12TestPoints[6].out[6].SetString("18855586974808005337260765411659390386445033549015888445245705299799839834847", "14928208123338016203407592394053878983766133075892823027858944645334094972481", "11046368834986036142960346679516972429647359098779569046069563313230721271753", "12276610202997251671212904409073687541852648270120258286230683302800937959288", "19351434969769989450022218141744153540129562534572176971628721649209527897070", "4162937389905739073868933601721971806231103163308934616239623666795869351315", "20310788022864828448244976719236907322293626684812142112866002335982014103601", "7872050437157498171453239922667256176522736907782129380145480122907490652947", "1790546586744090355160361255916055247853357480065145555503976884186139736945", "19863394534231026156291674102639618490861874524626181611797162898947342942907", "7121096266056281496703004292947109938980358013137184827842006078762638140964", "3960969301007810784162341357732655496428643976140408896503799794508919898930") - E12TestPoints[6].out[7].SetString("11595615595944166338604893216721560592708473990269049952720467479537555545624", "11705627395974028092741683257119658104974191599406429791386314878297331977396", "4023030441840551966002752617601400177632948126790486024942799116052665959229", "20538228344340228110930984594516677684693955674350300560291051948084812936850", "21173309294064909921876688522578052297587046891450677768354387299986155046200", "3888428408414186684047267349316995533485179279348373469161916383036963296211", "614096639972792044966861044012527575751316062086812445542666029283880354467", "8338211426925122117062934794407210340824012949932226300599296115348586217970", "15769205693632544494962263287126640103342886893252690429735180955875761801893", "12874122290333150965901706750366867514156156033122783846654959316693968001379", "17518722310188185169980518986106902772999123720673963555802972340324169164900", "21116809639038941188098605432703401669067143251564355445695553377964476836668") - E12TestPoints[6].out[8].SetString("19721411576200137146667915507101104741968727940999865576791830252141855468771", "12015445917927209314974218420316810930763745769021369028482385802698082193038", "17998443787179118258312832223856615506772745943772128692188745228734717695727", "21194411599010077619925416073268826105256765844883528103025981528881355700674", "1255381624560870690146855684827213788369518614903912717406129586230162030866", "21663501977526874370958465707263669837857406004676827798253782537481258947310", "15295599040853214476207648144496909516492232159977725012029004399926348548352", "11612078676346325244408364186423647661867474254175113532717520301394647670273", "13895315706027934186456557774594371348964130392075336408530092763395938602221", "1286044341124231407768358028639358720052632395273448809682360254608814675754", "1680865850473460416849301210970898100563985928982786058820717251565187745279", "8243156931569371177437475799265436675724915292911052377685256020656849540568") - E12TestPoints[6].out[9].SetString("21690646695096275421968612515828300465795908561441639174091477377002007551952", "10553821244552751990291979826650893783334934479329310864304979619375692370055", "12218818817256621092758953792909893106468195784798843438310884248938584249352", "6110507626359061087179384079078726271079603659221747432648489963265647163217", "1295910507639031907155388829605522126392284364118770589105868301335003306145", "20954470316588505929153360840175781185868384281204137104625675663633928777245", "3400058163940606499426934297305223761685428535250146437113988172497347640205", "16548904248683839223792432671466390407981041070329963209258130761786985338812", "10341025649363719927334606736017806305464199827810560167297656879327045821029", "773305233617916099716635033007314289116385614495862209458083798960947323190", "17827886258163889856691595295139145128853126033602477097582571529329532083009", "19256220314498181898228469682160491217216934789850287853244557206813557601490") - E12TestPoints[6].out[10].SetString("13346674155009246955232630132845391715137510962810296562789187730171237517003", "18385782540010905033702269032529097927674878538001825837549544371399869659285", "10121514826380034969390657732010518504439468347585984776186291293177541970619", "19798361155388287984945992186696110411035975873746655518775555996355673105546", "3570820915592064643170413599490617905050680012187999362866720239209070103844", "6892158951610408995268334345959533736649861802893755271054198082462076387106", "19193290088517172100953841593646152102947761582363273332857801761896346911888", "19595197586446250958532073624264221239635496367028424893640413226801080385413", "12170224295396625645071918255534237779180283558467727958532046653453378219493", "3392979417328634143971159506874681622112495673218642738096010075448064544036", "4679488393842977414031751758695577922268905872806158152951094691807475784210", "1586063063469559315255656430030891419221519844201098378197176537704684470264") - E12TestPoints[6].out[11].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "12400382958542462801906222473087420600562229272091905816240459399418489160741", "3048312015182622469820234020826433655201231721262150236582154527929496885078", "197691022533435794397451101688434676793779771300738149949822448669324408006", "1900146309614524471139311718449969882731765059571586099214572711814355643141", "5081570600428920354625966618550116398799578790168592831158645865463305368048", "1871131626703475242752508026683288591331567847215478573413153403594486089245", "15602340259909625988813374305838777461430953776367174712325773811300417279171", "1176759356375888326179305561120659750094622758627394434331307470672065207282", "5256954039978908745308399167451492388271811701816909190078156285685906409955", "7243829085346589570102809200007970473717190709994031814057630514164738259092", "1254972028171168591593561329870376426532668706165014788152549776139107547501") - E12TestPoints[6].out[12].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "9487859913296812420340183272169854488134081885205917846448578495226737047842", "12845010277059282424657175609306271745198283100648983752250727667927560043342", "7843752209416774481722543634295968080961839316618580411330620761842318788926", "3592463005892233647884604797344218540562988738867568125343129042009214753303", "6132106753256340215294805953884590523055326967710420210761468858810150172036", "9140414048579008241193221422757691766719527833107311550384125480457164476791", "18975667982105931641221371491523819384029323326284485603758461053912580435398", "7616238705259258348618557895287307802678370065872319201670072944910957616487", "1395287992777046974992936068225297813442917979048709382862767781983019385588", "9563172077824393068269080949770390055350919781369457102523159585504469302320", "2254287053516224030912596630412830975018555921584740572166136618860726137086") - E12TestPoints[6].out[13].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "12400382958542462801906222473087420600562229272091905816240459399418489160741", "8718879642404550655539678867953468107269500321363286805063150942354804647222", "2298031358326721200513606106565351357574393401747820375264481621667119991029", "16055765031441492683277429146715021549556320007329882686033518906634155929937", "6265318739709135684751428671890479312281667881381430284480060272453485465845", "6241719137298318166373553137003824300235363621572017774611670161666401595851", "7430861669554935784469471451241427253319114377691553823430123230936523432926", "1176759356375888326179305561120659750094622758627394434331307470672065207282", "5256954039978908745308399167451492388271811701816909190078156285685906409955", "9125973225865430048867148131987527489820632166716186422397886733076585492941", "15907798177011376307887468960433159995370326538636866577776962890618615038412") - E12TestPoints[6].out[14].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "9487859913296812420340183272169854488134081885205917846448578495226737047842", "19192889140245001398444745331536306936430813085151492065435772967251866398947", "156485557148840011297437670411278331396065250595965547392891015360662953537", "873380452123383528911676417222692361190058130054195663664672414718942721823", "7480481989213009126393372015696460488943745941496770110452376608329158711998", "19574720379899900013935471670000347289951958457646557973096786966894035211449", "15350568192013780229112326758257034440003490921833237264909075162761418045776", "14272004166580016873627847849969967286017941091425504461018964949734268592096", "20492954879062228247253469677031977275253393178249114279826270112662206822995", "18294290836109145691240745895107629947859408323788072084949462041937375445427", "15912369769337792883561205997808765282070649495938401931876310656558925983101") - E12TestPoints[6].out[15].SetString("20002241751976515125475398358669768745784946504747531199131520018724534974773", "17343324654146265113241473144460437251207186921223079091057248183641213407629", "13959083550916114620054054843218387920708168054065093693886036040316990518722", "162548701643753644061033393375261913986489039215150303013382611646529691533", "13004098068684533596997661953845143671605534277981808719166084905694443085034", "17801082839087996759993296151727395310479736092954529566812703943079126985585", "2681429082735164545212378770392012293478640901425991236475503164913327939118", "8085610285001762456815447074990368514859416786916237384994121527995640907640", "11885757522981524417227829680276855100574445368058557650777910509931520972682", "21846199511925109883204357774853170919467468676111239169049070908462132120919", "7959059876652943892391208253540842751093806658018348381758845687707345349456", "1647716729323999886617936144848779316945092463027674079441418566735261349494") - E12TestPoints[6].out[16].SetString("6309094504171399600397696502673397875568541964636345598659521087805156992088", "10068932086043801996403692371973581536338493927174028652752712729027588227746", "19152125681117800711561368238611233232598157790046416819626319757365359294297", "13852811701744563850171169197652803922931864214099630745633259998558295776451", "2750058083678677979706919950387045295244958299975420061745937844059303745867", "12020252917492408982971312962625567037071548612343391035180544981584566282826", "3658033406618259710156840416176810903325885519507435314536141047215831216266", "1263358453771552984283922914001035402997844283744024997308944322820306464741", "5636632881145593460082241125303834168459562920104844052496523345249136311616", "16761635387581432138987686123464347520518869276638188614566661048343711853699", "13307293977129109058710811042413392099899326634477376506901171608514733721834", "13441655700825124691777614645000768334010271838828976291937413034686546428250") + E12TestPoints[6].out[3].SetString("21690646695096275421968612515828300465795908561441639174091477377002007551952", "10553821244552751990291979826650893783334934479329310864304979619375692370055", "12218818817256621092758953792909893106468195784798843438310884248938584249352", "6110507626359061087179384079078726271079603659221747432648489963265647163217", "1295910507639031907155388829605522126392284364118770589105868301335003306145", "20954470316588505929153360840175781185868384281204137104625675663633928777245", "3400058163940606499426934297305223761685428535250146437113988172497347640205", "16548904248683839223792432671466390407981041070329963209258130761786985338812", "10341025649363719927334606736017806305464199827810560167297656879327045821029", "773305233617916099716635033007314289116385614495862209458083798960947323190", "17827886258163889856691595295139145128853126033602477097582571529329532083009", "19256220314498181898228469682160491217216934789850287853244557206813557601490") + E12TestPoints[6].out[4].SetString("13346674155009246955232630132845391715137510962810296562789187730171237517003", "18385782540010905033702269032529097927674878538001825837549544371399869659285", "10121514826380034969390657732010518504439468347585984776186291293177541970619", "19798361155388287984945992186696110411035975873746655518775555996355673105546", "3570820915592064643170413599490617905050680012187999362866720239209070103844", "6892158951610408995268334345959533736649861802893755271054198082462076387106", "19193290088517172100953841593646152102947761582363273332857801761896346911888", "19595197586446250958532073624264221239635496367028424893640413226801080385413", "12170224295396625645071918255534237779180283558467727958532046653453378219493", "3392979417328634143971159506874681622112495673218642738096010075448064544036", "4679488393842977414031751758695577922268905872806158152951094691807475784210", "1586063063469559315255656430030891419221519844201098378197176537704684470264") + E12TestPoints[6].out[5].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "12400382958542462801906222473087420600562229272091905816240459399418489160741", "3048312015182622469820234020826433655201231721262150236582154527929496885078", "197691022533435794397451101688434676793779771300738149949822448669324408006", "1900146309614524471139311718449969882731765059571586099214572711814355643141", "5081570600428920354625966618550116398799578790168592831158645865463305368048", "1871131626703475242752508026683288591331567847215478573413153403594486089245", "15602340259909625988813374305838777461430953776367174712325773811300417279171", "1176759356375888326179305561120659750094622758627394434331307470672065207282", "5256954039978908745308399167451492388271811701816909190078156285685906409955", "7243829085346589570102809200007970473717190709994031814057630514164738259092", "1254972028171168591593561329870376426532668706165014788152549776139107547501") + E12TestPoints[6].out[6].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "9487859913296812420340183272169854488134081885205917846448578495226737047842", "12845010277059282424657175609306271745198283100648983752250727667927560043342", "7843752209416774481722543634295968080961839316618580411330620761842318788926", "3592463005892233647884604797344218540562988738867568125343129042009214753303", "6132106753256340215294805953884590523055326967710420210761468858810150172036", "9140414048579008241193221422757691766719527833107311550384125480457164476791", "18975667982105931641221371491523819384029323326284485603758461053912580435398", "7616238705259258348618557895287307802678370065872319201670072944910957616487", "1395287992777046974992936068225297813442917979048709382862767781983019385588", "9563172077824393068269080949770390055350919781369457102523159585504469302320", "2254287053516224030912596630412830975018555921584740572166136618860726137086") + E12TestPoints[6].out[7].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "12400382958542462801906222473087420600562229272091905816240459399418489160741", "8718879642404550655539678867953468107269500321363286805063150942354804647222", "2298031358326721200513606106565351357574393401747820375264481621667119991029", "16055765031441492683277429146715021549556320007329882686033518906634155929937", "6265318739709135684751428671890479312281667881381430284480060272453485465845", "6241719137298318166373553137003824300235363621572017774611670161666401595851", "7430861669554935784469471451241427253319114377691553823430123230936523432926", "1176759356375888326179305561120659750094622758627394434331307470672065207282", "5256954039978908745308399167451492388271811701816909190078156285685906409955", "9125973225865430048867148131987527489820632166716186422397886733076585492941", "15907798177011376307887468960433159995370326538636866577776962890618615038412") + E12TestPoints[6].out[8].SetString("8353322910813740547858079004618385272122694921325978963549989619793772312713", "9487859913296812420340183272169854488134081885205917846448578495226737047842", "19192889140245001398444745331536306936430813085151492065435772967251866398947", "156485557148840011297437670411278331396065250595965547392891015360662953537", "873380452123383528911676417222692361190058130054195663664672414718942721823", "7480481989213009126393372015696460488943745941496770110452376608329158711998", "19574720379899900013935471670000347289951958457646557973096786966894035211449", "15350568192013780229112326758257034440003490921833237264909075162761418045776", "14272004166580016873627847849969967286017941091425504461018964949734268592096", "20492954879062228247253469677031977275253393178249114279826270112662206822995", "18294290836109145691240745895107629947859408323788072084949462041937375445427", "15912369769337792883561205997808765282070649495938401931876310656558925983101") + E12TestPoints[6].out[9].SetString("20002241751976515125475398358669768745784946504747531199131520018724534974773", "17343324654146265113241473144460437251207186921223079091057248183641213407629", "13959083550916114620054054843218387920708168054065093693886036040316990518722", "162548701643753644061033393375261913986489039215150303013382611646529691533", "13004098068684533596997661953845143671605534277981808719166084905694443085034", "17801082839087996759993296151727395310479736092954529566812703943079126985585", "2681429082735164545212378770392012293478640901425991236475503164913327939118", "8085610285001762456815447074990368514859416786916237384994121527995640907640", "11885757522981524417227829680276855100574445368058557650777910509931520972682", "21846199511925109883204357774853170919467468676111239169049070908462132120919", "7959059876652943892391208253540842751093806658018348381758845687707345349456", "1647716729323999886617936144848779316945092463027674079441418566735261349494") + E12TestPoints[6].out[10].SetString("6309094504171399600397696502673397875568541964636345598659521087805156992088", "10068932086043801996403692371973581536338493927174028652752712729027588227746", "19152125681117800711561368238611233232598157790046416819626319757365359294297", "13852811701744563850171169197652803922931864214099630745633259998558295776451", "2750058083678677979706919950387045295244958299975420061745937844059303745867", "12020252917492408982971312962625567037071548612343391035180544981584566282826", "3658033406618259710156840416176810903325885519507435314536141047215831216266", "1263358453771552984283922914001035402997844283744024997308944322820306464741", "5636632881145593460082241125303834168459562920104844052496523345249136311616", "16761635387581432138987686123464347520518869276638188614566661048343711853699", "13307293977129109058710811042413392099899326634477376506901171608514733721834", "13441655700825124691777614645000768334010271838828976291937413034686546428250") E12TestPoints[7].in[0].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "5123656372827556640017850347369319207992981297045307970575708461804676921410", "8261070158509506242113480038494098982488908270652696658013459163997039526163", "5060171208598752476266793118582849783749129506737816995697945008734633172119", "20668782073444667007103511274225209720741399054872217549638905889555203250088", "9165754144182203753883928072550478721228232530586928543296902413452520614185", "11363045351571867844795151267732196176390681333554949992702950093981297475193", "15049087694703425016148435981794683180622710926350268320133939451770541656721", "21131232630884425461040893389917523259763932487012685342623622127848402492589", "12952002314176128330987718985200185676285498598011530307993426857047897543602", "20332341352801617466437837831898561601617202213314925128621415352817720570812", "16125511403610899059422092216929522793524552238845665586528746324987124189370") E12TestPoints[7].in[1].SetString("10117005677769701946307764203241751846774258909054429914512470074660283536367", "841497513947517848948605280804987798343685962084115550465252851486375468108", "11683448735148452927203648993715279938839973027202590640787869355498986705851", "14131763155701789327725342345438929417426885731062462157921077490487464610481", "5055989597198170097507643439436354701461610596502005063522464440088825047438", "19327891777236627792115627543544610467735535530256970097402655972814799632840", "15160369756489607871298344068704555229261445960321987455332914575913347895235", "6587988269642728783091617694919391830472213880293317497364429513074222551841", "2090479660334970729142341135749930933509436356848629341107278119991733055879", "9203463678997301721640555789282144326675626111607285820146835038704342712021", "4491195013979499090383537315009616221744775811802298736775210861288467667989", "9417677363210554089468604661845556778177167301691167855926901670825161650434") E12TestPoints[7].out[0].SetString("17343154296540889856665387893674808826246652167180281704872720577130421977998", "5965153886775074488966455628174307006336667259129423521040961313291052389518", "19944518893657959169317129032209378921328881297855287298801328519496026232014", "19191934364300541803992135464021779201176015237800279153619022499222097782600", "3836528798803561882364748968404289333506698494076398950472332434998802088943", "6605403049579556323753149870837814100267456903546074978010520491622094038442", "4635172236222200493847089591179476316955816136579113785346826775249419161845", "21637075964346153799240053676714075011094924806643585817498368964844764208562", "1333469419380120967936828780410179104577057686563491021041862353194909339885", "267223121334154830381869029225054914264813552320992465451224001107014047040", "2935293494941841334574969401650902734665666867819400202707588319460962030218", "3654945894982177926644291133517804483005408383239009779766610101167059631221") E12TestPoints[7].out[1].SetString("18997385812840761186296265232448580221394445506369245538536818322455081113847", "4282158858880038791069245066564331409649295334961192420110455610318301453302", "18465864295200328537156236790036094132345246400747929679914627703143279028895", "12816650924736238370787856518401195455018554932973178500465905412892394770221", "15612792476246496909595867834788855019279788458370212486116441449466378202650", "11726105238784851184014706274263143342189008157627782108583284335282947189928", "18090918466921535195743212944284916035825546530530786200059073412713175788541", "8461099425060696233056818286875291350150497046056950822769509938696319104880", "19040752970549454731898552254167592326254496130164056001516344007856669436710", "3748538635178826609347163195918041349609872486404244487846591818343554831581", "15841146338822118376054300516888945379872426401512626391846204491529252902823", "6707834040400344969953487555083966015347384937154497730601844654161962538936") E12TestPoints[7].out[2].SetString("1113873138338153617343913647779517913875384260559330798534564707868420555436", "10890485513251162373054379859004902840810372675843036307139937230280333204746", "14370430836350220457130579019880626678677424527337211763396126714550308057510", "10057999514900232924997045319181274004817315725145683901657875463063495872328", "396876616066968880292141656277714762289662197773658433240043543556302648273", "7918478070436073946924408939284664415947214204587281660805607594652121122967", "13921468092722376527740345266441564616031407543131251564444399664360079395096", "19600805201617839802769345793904530142817309699049976010462988367365689308455", "9397780645059752113516055949505252613860091414605815322162678320088480611946", "669126262800315948898680971478141672564796293365721572988197671865329391310", "14865708294883166813832366477572476828846356713320893373870943809875432346698", "3821482876046027922205846229516868188263984235381934519405683032660847787037") - E12TestPoints[7].out[3].SetString("17634005121037035755050666265740722973625862606383964586450385068192670080762", "15599282613302730866941039540409284767447184299909128480269045930605339741863", "3243868320717241752775082160676637370721008405637096287250286287916390299697", "16585565939536059499123166520641084944945051220384352352700058265465267082682", "12476208882072934752572919144257468367176360696294030584603911381605639941351", "11573251748265737799078096405220783113552393277747938538651176000654117850859", "10650493303431099946954139869272574967649048362214908289726154669346741975045", "5798247543729992731249016126584093262632842126391820923378878076320602367565", "4726407426898554603978827822869504627273759421163529241641393191132996437096", "16778567518937463389404749943408016007465735922409458449194793306611839799936", "19306892254346257762300150197483160400370198977479419176274483572370683581467", "6334876597437833977169662599967751299860489902868176157075731027559098158585") - E12TestPoints[7].out[4].SetString("5095255476420674043242239953808644156381953014019938022477101056698411200815", "6431916900680160243152117553657535932126874885054737710253022175831226904017", "5915184166648698745921776318450047760124066615880120011415673651370703948057", "7370823736702018038869128191490397214549286160904652724909831177901406245197", "15489400779024526000294742084069692136638741658033663591942035650928385371810", "14380836063798867042327928059430235082174624146670046075623363400998663089265", "6276780139919675609921098399486495182857794852508315228164445178936801105261", "11501385894272845585933870929208673497618401229720047652569790829414669020462", "1099406441143934571594842642305300742573796620641039366688914001197096055493", "17784689648231746702855136253868329440546664471040442128374591853925216788032", "17692457596900127855927418119458406149029096877398198020981904602994279491868", "8558732931441583729229067091916963794654419812055322189514537381955151177174") - E12TestPoints[7].out[5].SetString("3860313839351580930741826203848649016120254957505797563375437119107930366979", "6832515038254903986663754514882091483276044386738162819693815741056156834740", "341641144545101551314403362568614623514992955593280097860055314501198948184", "1942985949330840927399512625586453514693758689910816086809545302304177923493", "6429808677161600701398863886180088072354065791807724433108107583132989428382", "8477517400419377134486346845673930819760479435228979286107134487910474155648", "7307056526451810826172205952313445686594857664976852537331204533332587293032", "6232205816360211371044828680953720983430568192831094113795771563301455172627", "6183753202055755146612993161354400571604287354100297775494334842609650125696", "15645375294620903277776044787954230218442695153420007122163842946127028445178", "1683077597316987842987428479713008649519193199306684644209902486423819271902", "10371827748593836604826763153154001475320877791533369636562834341586857830265") - E12TestPoints[7].out[6].SetString("3463193587386654061461720738834411467450467438132362965399612937087016596261", "1995497341291741499966082627383972951658842932346830487090739001785368168632", "8874097747913593975231594857980211476554557589064738348301224035722110113095", "18941102164018923271005156162037655900428651099079614322775633045219432314141", "8228331543250758315278016030599062524314252194590344696005760348478244079393", "7037950905449120867422448820620952819659016702139315147085658736796411561109", "4915608932759317972502533397066273387276145409192381605461685705168655562000", "8104109243765456098174198557709884763950931881044701744821390491272177749501", "12204259894672779106348493441430517352268340835341252880638012143836619360449", "2885154636097917972865455050292546216359866083395916946630353737114266919922", "5969316117965027825904470719419077832844463173927719976885093557820726773316", "18063436199650357832303231073043392452923057605558498216900580823395207074454") - E12TestPoints[7].out[7].SetString("18788899164311426118842534973358902919157483057408368158236603762463320852378", "10787136899507234470615734589620556495161216401570609762829067542954893010506", "10348588105155539204305313681546374759130891309348138837615320222530071771789", "21557380164233328426086829579695499805965021696359658539055094667464263372295", "5879379099422057675349715768230690129784975200346833821261429910719908836150", "15536768243934717855606294084749243942729723987790017136721795650905567944957", "8570139639474254969760603940695708630677214371511363060049169468104359012399", "5189747999830793451185119831003057227148201019200481324210966350066751380581", "16620270278057596907368774030430607518709583105511915120153733285829974146476", "17153568830338786261245689160026516393634584385179254738560458203401314011293", "17528157778905130455156919065755665540003687058925766790418486301199107154900", "8731505182210394907006419000798933178826219709146761116650244739926327650734") - E12TestPoints[7].out[8].SetString("14682557852241365148112005871741199489523361983319782857711479228658643495971", "8072061218194324853915193356653498225805936003070767851202032960138776982651", "19432538373015335675850605679315112270921033364544481054811258660783686982937", "18882743292154278118301853678235809803796635186666343794553676186661225573966", "9584144743494911924731368358987081114548635297497166146476448733296393444879", "4036203360188026438869920789499813463557443079608782592312707839588585164528", "9492421802127266136070311228666858335600074849100549667629728972345129927018", "4560731715529127888690027692394587272693796109863917950982982251892083073151", "17520679943563173409776866060416545547966807999804467630385017616599243352765", "18459186040990420295498583619005401629210133343779810481245656592307956742818", "14342017351709140610475821670000099391690209904127788881032486580834906611923", "7484850777113042053186260494498058722660069513970509104964272913224541803407") - E12TestPoints[7].out[9].SetString("4604190401023183904332177559092908915516525120453193345233840723138651959455", "15372460411789548472153290576403084008230093178242000332805216502880364228487", "1274114415836431045961151519046654762227443766493593886680735563884762517403", "16711723482908811472959663628030392846556330680957171363634950774336004517516", "12043819028457857150292038880308387097881503179529642805480878658039531245468", "13108870879275398201872660553162967528970257459234841841696202808880800371664", "3102481634234262961747771980322567044093191052456577042940721450739175567926", "208271002088496775595247128515401075059364760008636496726621562520064847682", "13542142004554222117975772810559354626962185512052165820407343940320068503711", "18075561162393177401516863610194617099968014645964521660104044658120619820898", "16565611913200948748853175896413580055827952365856739235976092460561970480473", "5414125893284219974703287813547809473622793715138106645740261456413587808156") - E12TestPoints[7].out[10].SetString("14686110889374132978573503326571077653173367597497698694190629726942598908986", "15835607216757345887905958176614239490677356827055887756560650395954345966358", "3437507687284658957514111154114871629192118703201902193809893425635613420101", "15136135924573357592552132700756946378829415708201094457510364034298668129989", "8448531495307931322867332229908473628531255743282135927821254707139158257645", "4928828776300732657482662989037404065584079108678744308553520328665458378753", "19908060729052957527956132894590435673450182556441116760604695445600428519835", "18712053029915244053533288898492655712711011584717567082482635224684540195150", "7318203578712609303022981985719700885434592029188222529041040728511961978179", "4402780882788278770888387027019074477485560111767884449076030178516464113896", "4057601399240887832164500924265977270980384032800764027102460802407830595932", "17999928236546910002685736914266833382099523189821547770793068495850372381376") - E12TestPoints[7].out[11].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "5123656372827556640017850347369319207992981297045307970575708461804676921410", "8261070158509506242113480038494098982488908270652696658013459163997039526163", "5060171208598752476266793118582849783749129506737816995697945008734633172119", "20668782073444667007103511274225209720741399054872217549638905889555203250088", "9165754144182203753883928072550478721228232530586928543296902413452520614185", "10525197520267407377451254477525078912305629823742873669986087800663928733390", "6839155177135850206097969763462591908073600230947555342555098442874684551862", "757010240954849761205512355339751828932378670285138320065415766796823715994", "8936240557663146891258686760057089412410812559286293354695611037597328664981", "1555901519037657755808567913358713487079108943982898534067622541827505637771", "5762731468228376162824313528327752295171758918452158076160291569658102019213") - E12TestPoints[7].out[12].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "16764586499011718582228555397887955880703329860252515692113329432840549287173", "789606614128984736739451609500825417223807938827706654379920298648996935848", "3065852506200839934715611382010219839633268074124299437630251144771517036280", "1185394913589895165104229098130752453445849604002166034194832124559265456977", "9762275573864385244014163432837250915490015499509411447184400053167056217459", "14904042368484032829934444230767832183176363236810146236172920227276797794391", "1332096839498666708703471939706497032741120378987350660207800530605344881040", "13933974189108252226455700939572631430367597869263762304174196709551645889250", "13594891619073744338882947446406678880393516628730845629045002595022483635604", "415991417037262337959388475367332551408835980151377014151385473039519267609", "13451483482153623609000499506420349580741683475575296994168326568342944746450") - E12TestPoints[7].out[13].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "5123656372827556640017850347369319207992981297045307970575708461804676921410", "19096743761344135233554319337751621554213757237121646597474821728217107924976", "4607126038542898516768712111342706640569695452973641730043391188805409035708", "9806828718677902489583896433807344577041142541384319402719105418876357511755", "1590123046373212930402966480079356071204394767986467122504524348213734558084", "18797100406675211183223354136499634189279661572730681255117181529440509182593", "19936408255131037874287521201667247846269705234032935825926050767301412741232", "757010240954849761205512355339751828932378670285138320065415766796823715994", "8936240557663146891258686760057089412410812559286293354695611037597328664981", "8355254484286435871875816389551842666648896760819246226574809478474440602149", "19628409400108603266991345795673503739465069529095624307685938638791321037610") - E12TestPoints[7].out[14].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "16764586499011718582228555397887955880703329860252515692113329432840549287173", "1372495573686708329744162215669543392452149613581889924882532516288124224042", "10244244306513913582808147597287734430982708260493606104593186059738914506527", "8577074929221422946631606564610305128376470273610666019572336486963914428668", "5827319117397689434525541293806195623306546111749757008689340206127123589489", "4609648503859757217381513801786040435139212638462047270549029107684555953190", "5749082840350461224229142670859795376429252971177486915881628069345289862085", "7954268682731022995790704805684643658328713288034061358514841185093580319333", "8293351252765530883363458298850596208302794528566978033644035299622742572979", "20712314201889987053226348014913065024531778780512020170550807832843808803864", "21351040183225557859507969075284153220034262125156972167791587878170981489320") - E12TestPoints[7].out[15].SetString("8863307460284783895976505473591373079526164344468635187054838231002809811573", "9558744784492311629968027171559215201048480204912451201483163874892080984226", "14542140194826419255082664201955027952522135600308572264471684705239633090933", "19827532175176206386567050202911639449911863724309726047575290926814478119558", "4131002285819261408045826081927297332005057884833235323540559197643871708331", "7901251301550183934823295569396809255977192717596750400379348484667155227882", "16656268414095274454817150976260562533264140625913472773686370907608069977123", "3558635624252955469508434946450188015538756982406882377257880550792417307166", "8583903590236593922299108544334151904003295201707541424591765285000773283975", "10607344520897400159116866696460104347634504429016528356563618601825428734291", "21482956383955857566680534310055595965370586064731820582131167307983959789920", "5584836199404806224533509823750380902658574433204775521271739874371268531963") - E12TestPoints[7].out[16].SetString("17971527602127950213886778446079589353171480167103436709666266714607228526277", "19260998898902775558117061535522896026083391959330741751140480166370800823938", "5775300519073833958166733203520678069785870701888704688700748431355454430460", "1028782046567034284233345292083382360009816010717599100251860188022710028630", "9880793858761936860896705810843413359811913760321061716528367063088494062021", "8464215643082946204083291267809863514491589821043501758846326567273135683269", "20676263165548407852417587208735090657231247924702188298829285092954226808916", "2415543628123321395516371566414290679934532292884772369228701700473549805383", "20881549240090519243359512063459503024017296582023971523525035056492821642442", "15355490541435988046627014991596010767994017928531297029417298310646209857335", "6725786203270635749965145016623877437084601340402990775172892486213974858838", "17111600180875965926291820227529528808501800187455556118031918850396992329356") + E12TestPoints[7].out[3].SetString("4604190401023183904332177559092908915516525120453193345233840723138651959455", "15372460411789548472153290576403084008230093178242000332805216502880364228487", "1274114415836431045961151519046654762227443766493593886680735563884762517403", "16711723482908811472959663628030392846556330680957171363634950774336004517516", "12043819028457857150292038880308387097881503179529642805480878658039531245468", "13108870879275398201872660553162967528970257459234841841696202808880800371664", "3102481634234262961747771980322567044093191052456577042940721450739175567926", "208271002088496775595247128515401075059364760008636496726621562520064847682", "13542142004554222117975772810559354626962185512052165820407343940320068503711", "18075561162393177401516863610194617099968014645964521660104044658120619820898", "16565611913200948748853175896413580055827952365856739235976092460561970480473", "5414125893284219974703287813547809473622793715138106645740261456413587808156") + E12TestPoints[7].out[4].SetString("14686110889374132978573503326571077653173367597497698694190629726942598908986", "15835607216757345887905958176614239490677356827055887756560650395954345966358", "3437507687284658957514111154114871629192118703201902193809893425635613420101", "15136135924573357592552132700756946378829415708201094457510364034298668129989", "8448531495307931322867332229908473628531255743282135927821254707139158257645", "4928828776300732657482662989037404065584079108678744308553520328665458378753", "19908060729052957527956132894590435673450182556441116760604695445600428519835", "18712053029915244053533288898492655712711011584717567082482635224684540195150", "7318203578712609303022981985719700885434592029188222529041040728511961978179", "4402780882788278770888387027019074477485560111767884449076030178516464113896", "4057601399240887832164500924265977270980384032800764027102460802407830595932", "17999928236546910002685736914266833382099523189821547770793068495850372381376") + E12TestPoints[7].out[5].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "5123656372827556640017850347369319207992981297045307970575708461804676921410", "8261070158509506242113480038494098982488908270652696658013459163997039526163", "5060171208598752476266793118582849783749129506737816995697945008734633172119", "20668782073444667007103511274225209720741399054872217549638905889555203250088", "9165754144182203753883928072550478721228232530586928543296902413452520614185", "10525197520267407377451254477525078912305629823742873669986087800663928733390", "6839155177135850206097969763462591908073600230947555342555098442874684551862", "757010240954849761205512355339751828932378670285138320065415766796823715994", "8936240557663146891258686760057089412410812559286293354695611037597328664981", "1555901519037657755808567913358713487079108943982898534067622541827505637771", "5762731468228376162824313528327752295171758918452158076160291569658102019213") + E12TestPoints[7].out[6].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "16764586499011718582228555397887955880703329860252515692113329432840549287173", "789606614128984736739451609500825417223807938827706654379920298648996935848", "3065852506200839934715611382010219839633268074124299437630251144771517036280", "1185394913589895165104229098130752453445849604002166034194832124559265456977", "9762275573864385244014163432837250915490015499509411447184400053167056217459", "14904042368484032829934444230767832183176363236810146236172920227276797794391", "1332096839498666708703471939706497032741120378987350660207800530605344881040", "13933974189108252226455700939572631430367597869263762304174196709551645889250", "13594891619073744338882947446406678880393516628730845629045002595022483635604", "415991417037262337959388475367332551408835980151377014151385473039519267609", "13451483482153623609000499506420349580741683475575296994168326568342944746450") + E12TestPoints[7].out[7].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "5123656372827556640017850347369319207992981297045307970575708461804676921410", "19096743761344135233554319337751621554213757237121646597474821728217107924976", "4607126038542898516768712111342706640569695452973641730043391188805409035708", "9806828718677902489583896433807344577041142541384319402719105418876357511755", "1590123046373212930402966480079356071204394767986467122504524348213734558084", "18797100406675211183223354136499634189279661572730681255117181529440509182593", "19936408255131037874287521201667247846269705234032935825926050767301412741232", "757010240954849761205512355339751828932378670285138320065415766796823715994", "8936240557663146891258686760057089412410812559286293354695611037597328664981", "8355254484286435871875816389551842666648896760819246226574809478474440602149", "19628409400108603266991345795673503739465069529095624307685938638791321037610") + E12TestPoints[7].out[8].SetString("7226148618771187910357623690433056979472393258125851790360250502470138441631", "16764586499011718582228555397887955880703329860252515692113329432840549287173", "1372495573686708329744162215669543392452149613581889924882532516288124224042", "10244244306513913582808147597287734430982708260493606104593186059738914506527", "8577074929221422946631606564610305128376470273610666019572336486963914428668", "5827319117397689434525541293806195623306546111749757008689340206127123589489", "4609648503859757217381513801786040435139212638462047270549029107684555953190", "5749082840350461224229142670859795376429252971177486915881628069345289862085", "7954268682731022995790704805684643658328713288034061358514841185093580319333", "8293351252765530883363458298850596208302794528566978033644035299622742572979", "20712314201889987053226348014913065024531778780512020170550807832843808803864", "21351040183225557859507969075284153220034262125156972167791587878170981489320") + E12TestPoints[7].out[9].SetString("8863307460284783895976505473591373079526164344468635187054838231002809811573", "9558744784492311629968027171559215201048480204912451201483163874892080984226", "14542140194826419255082664201955027952522135600308572264471684705239633090933", "19827532175176206386567050202911639449911863724309726047575290926814478119558", "4131002285819261408045826081927297332005057884833235323540559197643871708331", "7901251301550183934823295569396809255977192717596750400379348484667155227882", "16656268414095274454817150976260562533264140625913472773686370907608069977123", "3558635624252955469508434946450188015538756982406882377257880550792417307166", "8583903590236593922299108544334151904003295201707541424591765285000773283975", "10607344520897400159116866696460104347634504429016528356563618601825428734291", "21482956383955857566680534310055595965370586064731820582131167307983959789920", "5584836199404806224533509823750380902658574433204775521271739874371268531963") + E12TestPoints[7].out[10].SetString("17971527602127950213886778446079589353171480167103436709666266714607228526277", "19260998898902775558117061535522896026083391959330741751140480166370800823938", "5775300519073833958166733203520678069785870701888704688700748431355454430460", "1028782046567034284233345292083382360009816010717599100251860188022710028630", "9880793858761936860896705810843413359811913760321061716528367063088494062021", "8464215643082946204083291267809863514491589821043501758846326567273135683269", "20676263165548407852417587208735090657231247924702188298829285092954226808916", "2415543628123321395516371566414290679934532292884772369228701700473549805383", "20881549240090519243359512063459503024017296582023971523525035056492821642442", "15355490541435988046627014991596010767994017928531297029417298310646209857335", "6725786203270635749965145016623877437084601340402990775172892486213974858838", "17111600180875965926291820227529528808501800187455556118031918850396992329356") E12TestPoints[8].in[0].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "139673979561694557024716317915896939428578014035841859479144931520445903684", "17796472642737802596929261301682665967094686651373828507670097042127780962135", "13469842459547031564369375991287245647193656749482550867828904941184619705534", "5516586890125700817223718805821826061920205171036639693476005448200263087624", "6937761570669783621051646668645340299189607865406518438948294029180289511630", "20143944156573192540059145686932931077966424062956027918090294520530754977589", "9643800013535920573202381709041191873653807172060647533990336144216925796099", "21798936208539181881112654302500251204168263905688140314472527485900044329784", "16956617274900375180203368611096837654724124196618967601947611832133015032922", "16833808213091005101423478701494553057929319952446805884645059259346061268384", "17737700705606628905343327734888551053308287661757941399761794606786465276046") E12TestPoints[8].in[1].SetString("12946233236692732948398631871757219659012250475495016552511433374744803181490", "15480026516043308535605463128560910693483382604891663710343847945407923686927", "15853237158131566477111093045200646128988703807364793171048107884494557771392", "12111145814658591903208202349860187771867929789511102784503159587487822805589", "16893382726041778972491165686691896123917886751850847811652490629644316534103", "2314343939147343636648560675979716609115708933437389943194552627493752764830", "12559042810458007340792434747243921355086768707761280876426584334619007777376", "20091223095249419853321587903517803751075870885500822831541088660751949721628", "9423804808361337114063687220444983068546319727134355670261600997153476421779", "11636884898378126415922660051855011235802775468801253260568648842642367027382", "5410924714014565508150270345697154400084040492442937449578476891690510082195", "14601112584861169767608742297138407653805166606012786204677580973474780353838") E12TestPoints[8].out[0].SetString("12467454598054776944700669536399504006965575861773234856077166176792133219323", "15619700495605003092630179446476807632911960618927505569822992876928369590611", "11761466929030093851793948601626037007387079301440798016029167031977112524944", "3692745402366348245331172595890158330365275381695829989643026634027216302540", "521726744328204567468478747256447097141780765589663842439458183199353413144", "9252105509817127257700207344625056908305316798843908382142846656674042276460", "10814744095191924658605174688919577344356881613419485131827840960504536546382", "7846780236946065204277563867301720536033366900263646702842386910323649309144", "9334498145061243772929935777687959184018272475524672322045090588408294542980", "6705259301439226373879622917694573801830588508122397199827222780130155851721", "356490055266295387327343301934432369317049287591919671534498256391345141996", "10450570418628523450705664286769683618417143110472903941750337685616019421301") E12TestPoints[8].out[1].SetString("8463230996508586270149811538142339777637386068081025413743337321947753064926", "6547890335357661243665658934612261334641506566442001811824334880757748425340", "1943235484606236119818168256482019838105982844009035336621989157633223190743", "1358696644888439661161173641427057875325726959971448083325745353696796899945", "10511447035923197066978958864387205026698629576483615544512552713201172762104", "4623417631522439984403085992665623690073898931969128495753741401686536746800", "7584901346115185199266710939689009722879655355194747041663710185911747200213", "11440819790125775942127199550780663211274247443857648365138285378110202283054", "12375131400177844767048967082055268135621944178553784644210926488746567908005", "5319732376522248764280708559241826418921348727817714341378962989490648005540", "11422883499076439593273208355797398657845279460003868435066582367655551186189", "3136588120745459137734585437750143399503121055745155195084213633311684922208") E12TestPoints[8].out[2].SetString("20035011587678457653063284819137564878736427796715246169733177866074598820265", "10584192053038658357001834356850373522644643601152649006998469990651087915786", "6766874563744661122223970924829056211777059479442584318309318551723670529023", "20723587419082713642735032094181359134942028656943724481076949192702518609381", "2692493401615839963145557380925554749004802242390317875832986642328755801584", "4653381204716591005547719322985155733376940582817051853918762333729315859717", "20558589167121919747061012220592334929189947284014873265303337785865927702543", "9978653290481061773664849565244817926182367061678533131694178149562854126159", "8071413578445652825177686132824115469593442714999152949405752954055736612603", "16993273249195765805133155464463939773804375007369161834559741249160370164636", "12991450288683841618406105120712576808609264910065886318041944094814646543991", "8834748002261277358940426370624893854196157552373043627786583514097569489971") - E12TestPoints[8].out[3].SetString("11443860017801324063176920508597702516674436168848447000376591588044977598922", "9377585826478948587415604835864562259234163701171898205376585498928441118772", "12951079550381693516497399115316763345825250820665202780785250015076685043125", "7577769935598518709206264900126165382637670256341780273811236691142974974348", "3018941405462073656663988430480260931958788974237611427157657226668539986117", "14669154335368948167758548493162039195322957380108041889739562930308306949103", "9003529897386004813216201461730317447648761904356214560937999932962028419718", "1470013334107684545923129925051838961096854302754595282039493621092626676260", "19062806571000088949191902768140941269056553255816524985301434177431817175247", "2771717052545464272815942576713412417470029195750754755206407221010200962646", "11963117569388743166292174735601038509732107980498911019833321047882808788377", "17468025693846681770286896064587352562188639640315728693997035884259119892718") - E12TestPoints[8].out[4].SetString("3410877120717044305756653622966732699950024644283813689324414674655625782423", "8989895789119479494267259470608957130326447579871775640628839352761804154454", "15717701831141263869658434272431968962412448339251448556303197079689690568620", "18123001197584452850843049592282973443639249220879732151620803583815193277262", "15421145763025042076926130217477909648461990273843555767143027534938822945028", "1363136246051527721885600634132716506847559633904457750556944685864976939248", "16364784016570908427526214268345748669327512500985967866820747296356088941453", "8870011501094907628487757036812095228548984126721883182826030805637709369884", "590729795897828922468937162517184458202671601366860780126044512686115939010", "1965502958756510106741503143875738446708758301312861313784796268782076917438", "9205952012026232807017923240023185931667671528548016645923508045419896773190", "18484295786788145924432058093740683087001876080521533085477783233490012608478") - E12TestPoints[8].out[5].SetString("8179990350862503798802534084361073418226281077033383763178924347215717640597", "9938401166126759515654996375421180811703718607648040207171217413241321915920", "19803050565467183590446730105666416630285508635309166801677204616182510149122", "3526163328864539166940549869838378360812246700339333268747183846982827607504", "7348829398403393568555878535257225776217927615792618507150936498646338659704", "6598804118083872332022119023442531617754707248139240216331897013904139929006", "13703661643968768201571034307538828267964081500398299589743635921827456371492", "14830427268699111353228617867477669671633489021717974798274093756412909710137", "21014218974611232183899736547225335617303076736040109083059623808187837843216", "8519233288558210714193461368037116912224026704310201958336722317689818541785", "5179139361988812329724644589682333866049542075905875302845621958476342926733", "521697047250089837714182195705522017904166347487241563452716847756296174985") - E12TestPoints[8].out[6].SetString("5191374228212470774292701927056841189207282083373024333537404234422649009896", "6779712380038791723308012477127454799430582474706645554819326463534878653194", "13321952524830162996633018250358584775577069082818834453447106071816247973246", "10155105501367589821029053823292057753886858351769417355319095805525483762183", "3847821724173944519112397888525468391233960833595957785787151417686685535425", "8939678832465701280283049823967322386519845481899681630933672330898790718589", "2629440494292073134482113536409112140407610002908541917671881497583409763361", "7628724870088807073167340842424957100948658698932531751460990469175869599560", "6832550007665726724449365435242803856449077457548041975344614590044478572580", "1898411944387391755906725146822783023856579289168508332125104485828339465355", "4421499018531172414340453739212655545944080727343965903445590548513315559868", "13567149631541627972237280106323897362238394668602306065354750609192398668923") - E12TestPoints[8].out[7].SetString("3420225139826889093790092747257799724457757220837831208952780344704389323057", "5482906265885682316107775357096189731473479185958843528561570533038651916507", "19563492039259121857878435819892083536089119764095111352388122906678138270260", "7136026419315906295522647889795857241515451436519787976366643817896970403639", "8649362960745098319422284414245403117672067831563900913228770460501100791069", "18646635140002292353381618020216168233193997895635905126537830820280631757427", "17653163379131101482789775907586622725433889694099599879059341368986717757919", "11184229164573353584103334428390205327399627802123489068579097656653013628320", "15570733630347743089015286229651857972133156705327907082571748716736344395931", "8216415646196207545190204432805886758817871802797360986885466570069626372871", "16717755493435392732657132932669162336785328865374725065057970165020636630061", "9924390197856650453417838682455624567222421316037566963463996071894475645861") - E12TestPoints[8].out[8].SetString("19368196142288311778182756612857921505111917268031349170773827665957949430295", "10370849956200103992707155471905782696734188091848378571211439917654533123586", "3193152965959106309374217060698498579468304876085215678511315806887939256207", "6475415872672998537835611486932892045327059526372828345919605627704629301548", "7042876806683865041651512067282147804046473011432404487711914894481309174674", "19957179848661963710984753131759121804539318948388321979459486832313228219150", "5740714970086525075025015491201856296649367474373773769408981434340564560358", "3787061162656723615535458228837880317878865639333040400949923794241516670897", "17118439507191273089614915920141592618716092018754213464255554534056765381595", "18639337453055781881108496837829535456121729877922493759848266256606948928621", "8970130492111436452895013006101152708049788662588941733663442745781050089241", "8201038812784903936607427614851722196272243815970661223137527514618223636749") - E12TestPoints[8].out[9].SetString("17043450889252145429961546015624441585637149795582370673808803917066251040645", "10309307438356975932460598445188347570569243967197135800058838165120774601032", "20619841717886092833435657878971041107544334375221609060439676400022549611929", "5279647813471532587964671379166648546241940314785515371579386478843453763909", "3159389880289118645199186970475493841456160389605504246272661836292984455197", "7997798457439289229290888670140795910742845350395321309972723250339083108074", "2285567867515308335800624592882675637935987427517205425744521130127087425995", "6594746707824657086264071347075802485056904531736136241612148199110080036577", "14111655696207279591303977803512176870768046851252468687888408222506286721318", "19252886448114036784169785103811478636943061285604534572166882558099446699922", "8433989513230862574301527182429283991824278450036651079439776808036103708069", "11702018818494977321444808834398494835085411036009982005002191512114457281068") - E12TestPoints[8].out[10].SetString("4872941184922230369006115552733547373978950380049817229737244345645821661687", "7581857698714893307189162734235899446154890764120794161865365676867315042263", "16182279461524107863622770950033227156797563289266179862438217616908613233108", "15251595632611226355074280073216245517495704596206695950947114607051770523208", "8749960188374554096555612219266376389030002757036153034018891626529178789779", "21294731869337308882488267973395611445621806931992944806526266033509370316185", "2543600238275704484648307209801483193678481159948272155677969969743466925205", "11191299769783153677429557390218212749710340354014486331618296586280289117523", "18264906038357497936047790718051797486377406115850623058755221156413791795740", "295066152151603081066029311358726673287720158543039561011715327782617885274", "6233032285640957782821625610390313121714852111648635942267544761165685365699", "10386817297324207493208747798679341776952446394488199578738166069131448053637") - E12TestPoints[8].out[11].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "139673979561694557024716317915896939428578014035841859479144931520445903684", "17796472642737802596929261301682665967094686651373828507670097042127780962135", "13469842459547031564369375991287245647193656749482550867828904941184619705534", "5516586890125700817223718805821826061920205171036639693476005448200263087624", "6937761570669783621051646668645340299189607865406518438948294029180289511630", "1744298715266082682187260058324344010729887094341795744598743374114471230994", "12244442858303354649044024036216083215042503985237176128698701750428300412484", "89306663300093341133751442757023884528047251609683348216510408745181878799", "4931625596938900042043037134160437433972186960678856060741426062512211175661", "5054434658748270120822927043762722030766991204851017778043978635299164940199", "4150542166232646316903078010368724035388023495539882262927243287858760932537") - E12TestPoints[8].out[12].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "21748568892277580665221689427341378149267733143261981803209892963124780304899", "5296769470702785508306860301746897174238626852520625561565219907892826217555", "11599980891015161330530645996962162487234325128482629626910882811293043014619", "7896419023551005198653431590508154791380621987043177492233208807173182967831", "20883118836604530805704753584088464488954775713012519443683754934896928739474", "15619543815690890782225863652012173264670797411098470542078317645276427520631", "17731549894067569502749988117964508277787101176005506352784912837730975519832", "13486772222902472462076531453655191357074331423011078356107912880831346908058", "9462300037238578945962456385810974341028226008754956635874368541485070195411", "13989749403307971331026584644925675982730655856866369588586546696472005435194", "16309832397349767880702046337569489949838739268349654686343398979990599546784") - E12TestPoints[8].out[13].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "139673979561694557024716317915896939428578014035841859479144931520445903684", "12464972264245367574226469191242056879274063184171669449501548586293428363129", "6516967790157139476989668330989127368016457103817869792772621617254910838638", "19379651003863023045498915384401054676295053371772730828951702646577677570663", "5367829617627277181676464568549352826037658108381180777229608417193573597311", "17960101758394378343471438525148312389906268311128602547164862714522690016352", "13398271482520775917086589223635798498592889135468858730073747098629114638411", "89306663300093341133751442757023884528047251609683348216510408745181878799", "4931625596938900042043037134160437433972186960678856060741426062512211175661", "21805270639911482599700150512545756844661995309089896579374948046118358898938", "2098448720430616375336133000907263473520775290870211330414400149554130214485") - E12TestPoints[8].out[14].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "21748568892277580665221689427341378149267733143261981803209892963124780304899", "16224789921004027593446855436766870739217780205852919157565859161259415699579", "14569541926343099082535824739913352201553959607047474331135256811292749948580", "2435593014243858576240646930133341306491057042148556814757149577080697742830", "776518715497678364406051653481624126296000596214742388214740629663441573018", "5971559820800603918643321817577010885355959093253685571940021236377629363867", "7524049391899091418924114233178661077078733801691314266995932969229818015922", "8401470648936802760169874291602083731621979734286745306581125013813879300525", "12425942834600696276283949359446300747668085148542867026814669353160156013172", "6714816125984671211220332483117575858190815463597170462887431365285797737844", "8558523637453067863850387166711695806660365138060651176752412967271362180911") - E12TestPoints[8].out[15].SetString("20487266959338645046763972128775980570883937129776839054515867555560993446578", "8492628272545867157829400479409034108689008105348736752888615100151879870693", "8017584605614765523735107569163309188353209044816594921830425400952463283585", "13103916021554963117470293127491706147886804768178202235688367672335797246960", "10514323453811743429982542017207117667264734623193746632935726006304377641992", "2436735533925827361409266132200100570796344178778122559159746717033380554634", "15773751616198121648875947620698222512509414629654129714355797965377795749560", "2279073898012292030236221104000236495340005687536974368323325186141715907232", "1474608711389637141937481759044389190048560041810246035494683315475806011711", "11233900307349575727508927144597697758225086769891474325430688243869651455965", "6680775300152001073371484237861950102311828032423538505908853014381104837211", "2362079995219423391918542741264670807362321892916727462581112664457110310593") - E12TestPoints[8].out[16].SetString("11527041328880245659776088259756526413568846731523504198894369839190139069113", "9785819462948836853994268089966796590960223490128093100966847286986789574973", "21166143018372024213685408617258330169943355372420309137545238944253708218373", "15685534550544607599437687668517174356731998374089849948816864736454309723283", "1633855097793134534565506381814975724209037108629098080467002683680591983127", "19180382517521122032086485970414765387488487539975927065418646046570954612911", "20279330572781813117297164222753628161951238331346054394598249350437674224227", "10629330997877918839178865067762462234317656864314210378265445758376559867047", "18443603668379463727409716607381722300128842248386119401914059546088821530654", "10345998230310874056052860829131036389095731842176668116944977644446926831486", "6693520291159801294715572053757339995278423081444419417881496015585178577108", "3600530953379437541306870529083961401589886137670145667040066139928626723587") + E12TestPoints[8].out[3].SetString("17043450889252145429961546015624441585637149795582370673808803917066251040645", "10309307438356975932460598445188347570569243967197135800058838165120774601032", "20619841717886092833435657878971041107544334375221609060439676400022549611929", "5279647813471532587964671379166648546241940314785515371579386478843453763909", "3159389880289118645199186970475493841456160389605504246272661836292984455197", "7997798457439289229290888670140795910742845350395321309972723250339083108074", "2285567867515308335800624592882675637935987427517205425744521130127087425995", "6594746707824657086264071347075802485056904531736136241612148199110080036577", "14111655696207279591303977803512176870768046851252468687888408222506286721318", "19252886448114036784169785103811478636943061285604534572166882558099446699922", "8433989513230862574301527182429283991824278450036651079439776808036103708069", "11702018818494977321444808834398494835085411036009982005002191512114457281068") + E12TestPoints[8].out[4].SetString("4872941184922230369006115552733547373978950380049817229737244345645821661687", "7581857698714893307189162734235899446154890764120794161865365676867315042263", "16182279461524107863622770950033227156797563289266179862438217616908613233108", "15251595632611226355074280073216245517495704596206695950947114607051770523208", "8749960188374554096555612219266376389030002757036153034018891626529178789779", "21294731869337308882488267973395611445621806931992944806526266033509370316185", "2543600238275704484648307209801483193678481159948272155677969969743466925205", "11191299769783153677429557390218212749710340354014486331618296586280289117523", "18264906038357497936047790718051797486377406115850623058755221156413791795740", "295066152151603081066029311358726673287720158543039561011715327782617885274", "6233032285640957782821625610390313121714852111648635942267544761165685365699", "10386817297324207493208747798679341776952446394488199578738166069131448053637") + E12TestPoints[8].out[5].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "139673979561694557024716317915896939428578014035841859479144931520445903684", "17796472642737802596929261301682665967094686651373828507670097042127780962135", "13469842459547031564369375991287245647193656749482550867828904941184619705534", "5516586890125700817223718805821826061920205171036639693476005448200263087624", "6937761570669783621051646668645340299189607865406518438948294029180289511630", "1744298715266082682187260058324344010729887094341795744598743374114471230994", "12244442858303354649044024036216083215042503985237176128698701750428300412484", "89306663300093341133751442757023884528047251609683348216510408745181878799", "4931625596938900042043037134160437433972186960678856060741426062512211175661", "5054434658748270120822927043762722030766991204851017778043978635299164940199", "4150542166232646316903078010368724035388023495539882262927243287858760932537") + E12TestPoints[8].out[6].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "21748568892277580665221689427341378149267733143261981803209892963124780304899", "5296769470702785508306860301746897174238626852520625561565219907892826217555", "11599980891015161330530645996962162487234325128482629626910882811293043014619", "7896419023551005198653431590508154791380621987043177492233208807173182967831", "20883118836604530805704753584088464488954775713012519443683754934896928739474", "15619543815690890782225863652012173264670797411098470542078317645276427520631", "17731549894067569502749988117964508277787101176005506352784912837730975519832", "13486772222902472462076531453655191357074331423011078356107912880831346908058", "9462300037238578945962456385810974341028226008754956635874368541485070195411", "13989749403307971331026584644925675982730655856866369588586546696472005435194", "16309832397349767880702046337569489949838739268349654686343398979990599546784") + E12TestPoints[8].out[7].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "139673979561694557024716317915896939428578014035841859479144931520445903684", "12464972264245367574226469191242056879274063184171669449501548586293428363129", "6516967790157139476989668330989127368016457103817869792772621617254910838638", "19379651003863023045498915384401054676295053371772730828951702646577677570663", "5367829617627277181676464568549352826037658108381180777229608417193573597311", "17960101758394378343471438525148312389906268311128602547164862714522690016352", "13398271482520775917086589223635798498592889135468858730073747098629114638411", "89306663300093341133751442757023884528047251609683348216510408745181878799", "4931625596938900042043037134160437433972186960678856060741426062512211175661", "21805270639911482599700150512545756844661995309089896579374948046118358898938", "2098448720430616375336133000907263473520775290870211330414400149554130214485") + E12TestPoints[8].out[8].SetString("21409464233201319218548443409899559436649636543576041966254770696692556246416", "21748568892277580665221689427341378149267733143261981803209892963124780304899", "16224789921004027593446855436766870739217780205852919157565859161259415699579", "14569541926343099082535824739913352201553959607047474331135256811292749948580", "2435593014243858576240646930133341306491057042148556814757149577080697742830", "776518715497678364406051653481624126296000596214742388214740629663441573018", "5971559820800603918643321817577010885355959093253685571940021236377629363867", "7524049391899091418924114233178661077078733801691314266995932969229818015922", "8401470648936802760169874291602083731621979734286745306581125013813879300525", "12425942834600696276283949359446300747668085148542867026814669353160156013172", "6714816125984671211220332483117575858190815463597170462887431365285797737844", "8558523637453067863850387166711695806660365138060651176752412967271362180911") + E12TestPoints[8].out[9].SetString("20487266959338645046763972128775980570883937129776839054515867555560993446578", "8492628272545867157829400479409034108689008105348736752888615100151879870693", "8017584605614765523735107569163309188353209044816594921830425400952463283585", "13103916021554963117470293127491706147886804768178202235688367672335797246960", "10514323453811743429982542017207117667264734623193746632935726006304377641992", "2436735533925827361409266132200100570796344178778122559159746717033380554634", "15773751616198121648875947620698222512509414629654129714355797965377795749560", "2279073898012292030236221104000236495340005687536974368323325186141715907232", "1474608711389637141937481759044389190048560041810246035494683315475806011711", "11233900307349575727508927144597697758225086769891474325430688243869651455965", "6680775300152001073371484237861950102311828032423538505908853014381104837211", "2362079995219423391918542741264670807362321892916727462581112664457110310593") + E12TestPoints[8].out[10].SetString("11527041328880245659776088259756526413568846731523504198894369839190139069113", "9785819462948836853994268089966796590960223490128093100966847286986789574973", "21166143018372024213685408617258330169943355372420309137545238944253708218373", "15685534550544607599437687668517174356731998374089849948816864736454309723283", "1633855097793134534565506381814975724209037108629098080467002683680591983127", "19180382517521122032086485970414765387488487539975927065418646046570954612911", "20279330572781813117297164222753628161951238331346054394598249350437674224227", "10629330997877918839178865067762462234317656864314210378265445758376559867047", "18443603668379463727409716607381722300128842248386119401914059546088821530654", "10345998230310874056052860829131036389095731842176668116944977644446926831486", "6693520291159801294715572053757339995278423081444419417881496015585178577108", "3600530953379437541306870529083961401589886137670145667040066139928626723587") // benchmark inputs should be randomly generated, // so use the final test point diff --git a/bn256/e2.go b/bn256/e2.go index 948f6d09c..e8d519186 100644 --- a/bn256/e2.go +++ b/bn256/e2.go @@ -207,15 +207,6 @@ func (z *E2) Square(x *E2) *E2 { return z } -// MulByNonSquare multiplies an element by (0,1) -// TODO deprecate in favor of inlined MulByNonResidue in fp6 package -func (z *E2) MulByNonSquare(x *E2) *E2 { - a := x.A0 - MulByNonResidue(&z.A0, &x.A1) - z.A1 = a - return z -} - // Inverse sets z to the E2-inverse of x, returns z func (z *E2) Inverse(x *E2) *E2 { // Algorithm 8 from https://eprint.iacr.org/2010/354.pdf @@ -249,18 +240,3 @@ func (z *E2) Conjugate(x *E2) *E2 { z.A1.Neg(&x.A1) return z } - -// MulByNonResidue multiplies a fp.Element by -1 -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidue(out, in *fp.Element) *fp.Element { - (out).Neg(in) - return out -} - -// MulByNonResidueInv multiplies a fp.Element by -1^{-1} -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidueInv(out, in *fp.Element) *fp.Element { - // TODO this should be a no-op when out==in - (out).Set(in) - return out -} diff --git a/bn256/e6.go b/bn256/e6.go index b3d7a36d6..b323fd211 100644 --- a/bn256/e6.go +++ b/bn256/e6.go @@ -16,8 +16,6 @@ package bn256 -import "github.com/consensys/gurvy/bn256/fp" - // E6 is a degree-three finite field extension of fp2: // B0 + B1v + B2v^2 where v^3-9,1 is irrep in fp2 @@ -113,7 +111,7 @@ func (z *E6) MulByGen(x *E6) *E6 { result.B1 = x.B0 result.B2 = x.B1 - { // begin: inline result.B0.MulByNonResidue(&x.B2) + { // begin inline: set result.B0 to (&x.B2) * (9,1) var buf, buf9 E2 buf.Set(&x.B2) buf9.Double(&buf). @@ -121,11 +119,11 @@ func (z *E6) MulByGen(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) result.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + { // begin inline: set &(result.B0).A0 to (&buf.A1) * (-1) (&(result.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(result.B0).A0, &buf.A1) + } // end inline: set &(result.B0).A0 to (&buf.A1) * (-1) result.B0.A0.AddAssign(&buf9.A0) - } // end: inline result.B0.MulByNonResidue(&x.B2) + } // end inline: set result.B0 to (&x.B2) * (9,1) z.Set(&result) return z @@ -159,7 +157,7 @@ func (z *E6) Mul(x, y *E6) *E6 { rb0.Mul(&b3, &b4). SubAssign(&b1). SubAssign(&b2) - { // begin: inline rb0.MulByNonResidue(&rb0) + { // begin inline: set rb0 to (&rb0) * (9,1) var buf, buf9 E2 buf.Set(&rb0) buf9.Double(&buf). @@ -167,11 +165,11 @@ func (z *E6) Mul(x, y *E6) *E6 { Double(&buf9). Add(&buf9, &buf) rb0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(rb0).A0, &buf.A1) + { // begin inline: set &(rb0).A0 to (&buf.A1) * (-1) (&(rb0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(rb0).A0, &buf.A1) + } // end inline: set &(rb0).A0 to (&buf.A1) * (-1) rb0.A0.AddAssign(&buf9.A0) - } // end: inline rb0.MulByNonResidue(&rb0) + } // end inline: set rb0 to (&rb0) * (9,1) rb0.AddAssign(&b0) // step 5 @@ -180,7 +178,7 @@ func (z *E6) Mul(x, y *E6) *E6 { z.B1.Mul(&b3, &b4). SubAssign(&b0). SubAssign(&b1) - { // begin: inline b3.MulByNonResidue(&b2) + { // begin inline: set b3 to (&b2) * (9,1) var buf, buf9 E2 buf.Set(&b2) buf9.Double(&buf). @@ -188,11 +186,11 @@ func (z *E6) Mul(x, y *E6) *E6 { Double(&buf9). Add(&buf9, &buf) b3.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(b3).A0, &buf.A1) + { // begin inline: set &(b3).A0 to (&buf.A1) * (-1) (&(b3).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(b3).A0, &buf.A1) + } // end inline: set &(b3).A0 to (&buf.A1) * (-1) b3.A0.AddAssign(&buf9.A0) - } // end: inline b3.MulByNonResidue(&b2) + } // end inline: set b3 to (&b2) * (9,1) z.B1.AddAssign(&b3) // step 6 @@ -221,7 +219,7 @@ func (z *E6) MulAssign(x *E6) *E6 { rb0.Mul(&b3, &b4). SubAssign(&b1). SubAssign(&b2) - { // begin: inline rb0.MulByNonResidue(&rb0) + { // begin inline: set rb0 to (&rb0) * (9,1) var buf, buf9 E2 buf.Set(&rb0) buf9.Double(&buf). @@ -229,11 +227,11 @@ func (z *E6) MulAssign(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) rb0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(rb0).A0, &buf.A1) + { // begin inline: set &(rb0).A0 to (&buf.A1) * (-1) (&(rb0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(rb0).A0, &buf.A1) + } // end inline: set &(rb0).A0 to (&buf.A1) * (-1) rb0.A0.AddAssign(&buf9.A0) - } // end: inline rb0.MulByNonResidue(&rb0) + } // end inline: set rb0 to (&rb0) * (9,1) rb0.AddAssign(&b0) // step 5 @@ -242,7 +240,7 @@ func (z *E6) MulAssign(x *E6) *E6 { z.B1.Mul(&b3, &b4). SubAssign(&b0). SubAssign(&b1) - { // begin: inline b3.MulByNonResidue(&b2) + { // begin inline: set b3 to (&b2) * (9,1) var buf, buf9 E2 buf.Set(&b2) buf9.Double(&buf). @@ -250,11 +248,11 @@ func (z *E6) MulAssign(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) b3.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(b3).A0, &buf.A1) + { // begin inline: set &(b3).A0 to (&buf.A1) * (-1) (&(b3).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(b3).A0, &buf.A1) + } // end inline: set &(b3).A0 to (&buf.A1) * (-1) b3.A0.AddAssign(&buf9.A0) - } // end: inline b3.MulByNonResidue(&b2) + } // end inline: set b3 to (&b2) * (9,1) z.B1.AddAssign(&b3) // step 6 @@ -278,43 +276,6 @@ func (z *E6) MulByE2(x *E6, y *E2) *E6 { return z } -// MulByNotv2 multiplies x by y with &y.b2=0 -func (z *E6) MulByNotv2(x, y *E6) *E6 { - // Algorithm 15 from https://eprint.iacr.org/2010/354.pdf - var rb0, b0, b1, b2, b3 E2 - b0.Mul(&x.B0, &y.B0) // step 1 - b1.Mul(&x.B1, &y.B1) // step 2 - // step 3 - b2.Add(&x.B1, &x.B2) - rb0.Mul(&b2, &y.B1). - SubAssign(&b1) - { // begin: inline rb0.MulByNonResidue(&rb0) - var buf, buf9 E2 - buf.Set(&rb0) - buf9.Double(&buf). - Double(&buf9). - Double(&buf9). - Add(&buf9, &buf) - rb0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(rb0).A0, &buf.A1) - (&(rb0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(rb0).A0, &buf.A1) - rb0.A0.AddAssign(&buf9.A0) - } // end: inline rb0.MulByNonResidue(&rb0) - rb0.AddAssign(&b0) - // step 4 - b2.Add(&x.B0, &x.B1) - b3.Add(&y.B0, &y.B1) - z.B1.Mul(&b2, &b3). - SubAssign(&b0). - SubAssign(&b1) - // step 5 - z.B2.Mul(&x.B2, &y.B0). - AddAssign(&b1) - z.B0 = rb0 - return z -} - // Square sets z to the E6-product of x,x, returns z func (z *E6) Square(x *E6) *E6 { @@ -324,7 +285,7 @@ func (z *E6) Square(x *E6) *E6 { b4.Square(&x.B2) // step 2 // step 3 - { // begin: inline b0.MulByNonResidue(&b4) + { // begin inline: set b0 to (&b4) * (9,1) var buf, buf9 E2 buf.Set(&b4) buf9.Double(&buf). @@ -332,18 +293,18 @@ func (z *E6) Square(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) b0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(b0).A0, &buf.A1) + { // begin inline: set &(b0).A0 to (&buf.A1) * (-1) (&(b0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(b0).A0, &buf.A1) + } // end inline: set &(b0).A0 to (&buf.A1) * (-1) b0.A0.AddAssign(&buf9.A0) - } // end: inline b0.MulByNonResidue(&b4) + } // end inline: set b0 to (&b4) * (9,1) b0.AddAssign(&b3) b1.Sub(&b3, &b4) // step 4 b2.Square(&x.B0) // step 5 b3.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&b3) // steps 6 and 8 b4.Mul(&x.B1, &x.B2).Double(&b4) // step 7 // step 9 - { // begin: inline z.B0.MulByNonResidue(&b4) + { // begin inline: set z.B0 to (&b4) * (9,1) var buf, buf9 E2 buf.Set(&b4) buf9.Double(&buf). @@ -351,11 +312,11 @@ func (z *E6) Square(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) z.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + { // begin inline: set &(z.B0).A0 to (&buf.A1) * (-1) (&(z.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + } // end inline: set &(z.B0).A0 to (&buf.A1) * (-1) z.B0.A0.AddAssign(&buf9.A0) - } // end: inline z.B0.MulByNonResidue(&b4) + } // end inline: set z.B0 to (&b4) * (9,1) z.B0.AddAssign(&b2) // step 10 @@ -375,7 +336,7 @@ func (z *E6) SquareAssign() *E6 { b4.Square(&z.B2) // step 2 // step 3 - { // begin: inline b0.MulByNonResidue(&b4) + { // begin inline: set b0 to (&b4) * (9,1) var buf, buf9 E2 buf.Set(&b4) buf9.Double(&buf). @@ -383,18 +344,18 @@ func (z *E6) SquareAssign() *E6 { Double(&buf9). Add(&buf9, &buf) b0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(b0).A0, &buf.A1) + { // begin inline: set &(b0).A0 to (&buf.A1) * (-1) (&(b0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(b0).A0, &buf.A1) + } // end inline: set &(b0).A0 to (&buf.A1) * (-1) b0.A0.AddAssign(&buf9.A0) - } // end: inline b0.MulByNonResidue(&b4) + } // end inline: set b0 to (&b4) * (9,1) b0.AddAssign(&b3) b1.Sub(&b3, &b4) // step 4 b2.Square(&z.B0) // step 5 b3.Sub(&z.B0, &z.B1).AddAssign(&z.B2).Square(&b3) // steps 6 and 8 b4.Mul(&z.B1, &z.B2).Double(&b4) // step 7 // step 9 - { // begin: inline z.B0.MulByNonResidue(&b4) + { // begin inline: set z.B0 to (&b4) * (9,1) var buf, buf9 E2 buf.Set(&b4) buf9.Double(&buf). @@ -402,11 +363,11 @@ func (z *E6) SquareAssign() *E6 { Double(&buf9). Add(&buf9, &buf) z.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + { // begin inline: set &(z.B0).A0 to (&buf.A1) * (-1) (&(z.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + } // end inline: set &(z.B0).A0 to (&buf.A1) * (-1) z.B0.A0.AddAssign(&buf9.A0) - } // end: inline z.B0.MulByNonResidue(&b4) + } // end inline: set z.B0 to (&b4) * (9,1) z.B0.AddAssign(&b2) // step 10 @@ -431,7 +392,7 @@ func (z *E6) SquarE2(x *E6) *E6 { v12.Add(&x.B1, &x.B2) v12.Square(&v12) z.B0.Sub(&v12, &v1).SubAssign(&v2) - { // begin: inline z.B0.MulByNonResidue(&z.B0) + { // begin inline: set z.B0 to (&z.B0) * (9,1) var buf, buf9 E2 buf.Set(&z.B0) buf9.Double(&buf). @@ -439,13 +400,13 @@ func (z *E6) SquarE2(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) z.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + { // begin inline: set &(z.B0).A0 to (&buf.A1) * (-1) (&(z.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + } // end inline: set &(z.B0).A0 to (&buf.A1) * (-1) z.B0.A0.AddAssign(&buf9.A0) - } // end: inline z.B0.MulByNonResidue(&z.B0) + } // end inline: set z.B0 to (&z.B0) * (9,1) z.B0.AddAssign(&v0) - { // begin: inline z.B1.MulByNonResidue(&v2) + { // begin inline: set z.B1 to (&v2) * (9,1) var buf, buf9 E2 buf.Set(&v2) buf9.Double(&buf). @@ -453,11 +414,11 @@ func (z *E6) SquarE2(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) z.B1.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(z.B1).A0, &buf.A1) + { // begin inline: set &(z.B1).A0 to (&buf.A1) * (-1) (&(z.B1).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B1).A0, &buf.A1) + } // end inline: set &(z.B1).A0 to (&buf.A1) * (-1) z.B1.A0.AddAssign(&buf9.A0) - } // end: inline z.B1.MulByNonResidue(&v2) + } // end inline: set z.B1 to (&v2) * (9,1) z.B1.AddAssign(&v01).SubAssign(&v0).SubAssign(&v1) z.B2.Add(&v02, &v1).SubAssign(&v0).SubAssign(&v2) return z @@ -472,7 +433,7 @@ func (z *E6) Square3(x *E6) *E6 { s2.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&s2) s3.Mul(&x.B1, &x.B2).Double(&s3) s4.Square(&x.B2) - { // begin: inline z.B0.MulByNonResidue(&s3) + { // begin inline: set z.B0 to (&s3) * (9,1) var buf, buf9 E2 buf.Set(&s3) buf9.Double(&buf). @@ -480,13 +441,13 @@ func (z *E6) Square3(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) z.B0.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + { // begin inline: set &(z.B0).A0 to (&buf.A1) * (-1) (&(z.B0).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B0).A0, &buf.A1) + } // end inline: set &(z.B0).A0 to (&buf.A1) * (-1) z.B0.A0.AddAssign(&buf9.A0) - } // end: inline z.B0.MulByNonResidue(&s3) + } // end inline: set z.B0 to (&s3) * (9,1) z.B0.AddAssign(&s0) - { // begin: inline z.B1.MulByNonResidue(&s4) + { // begin inline: set z.B1 to (&s4) * (9,1) var buf, buf9 E2 buf.Set(&s4) buf9.Double(&buf). @@ -494,11 +455,11 @@ func (z *E6) Square3(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) z.B1.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(z.B1).A0, &buf.A1) + { // begin inline: set &(z.B1).A0 to (&buf.A1) * (-1) (&(z.B1).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z.B1).A0, &buf.A1) + } // end inline: set &(z.B1).A0 to (&buf.A1) * (-1) z.B1.A0.AddAssign(&buf9.A0) - } // end: inline z.B1.MulByNonResidue(&s4) + } // end inline: set z.B1 to (&s4) * (9,1) z.B1.AddAssign(&s1) z.B2.Add(&s1, &s2).AddAssign(&s3).SubAssign(&s0).SubAssign(&s4) return z @@ -519,7 +480,7 @@ func (z *E6) Inverse(x *E6) *E6 { t[4].Mul(&x.B0, &x.B2) // step 5 t[5].Mul(&x.B1, &x.B2) // step 6 // step 7 - { // begin: inline c[0].MulByNonResidue(&t[5]) + { // begin inline: set c[0] to (&t[5]) * (9,1) var buf, buf9 E2 buf.Set(&t[5]) buf9.Double(&buf). @@ -527,14 +488,14 @@ func (z *E6) Inverse(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) c[0].A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(c[0]).A0, &buf.A1) + { // begin inline: set &(c[0]).A0 to (&buf.A1) * (-1) (&(c[0]).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(c[0]).A0, &buf.A1) + } // end inline: set &(c[0]).A0 to (&buf.A1) * (-1) c[0].A0.AddAssign(&buf9.A0) - } // end: inline c[0].MulByNonResidue(&t[5]) + } // end inline: set c[0] to (&t[5]) * (9,1) c[0].Neg(&c[0]).AddAssign(&t[0]) // step 8 - { // begin: inline c[1].MulByNonResidue(&t[2]) + { // begin inline: set c[1] to (&t[2]) * (9,1) var buf, buf9 E2 buf.Set(&t[2]) buf9.Double(&buf). @@ -542,18 +503,18 @@ func (z *E6) Inverse(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) c[1].A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(c[1]).A0, &buf.A1) + { // begin inline: set &(c[1]).A0 to (&buf.A1) * (-1) (&(c[1]).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(c[1]).A0, &buf.A1) + } // end inline: set &(c[1]).A0 to (&buf.A1) * (-1) c[1].A0.AddAssign(&buf9.A0) - } // end: inline c[1].MulByNonResidue(&t[2]) + } // end inline: set c[1] to (&t[2]) * (9,1) c[1].SubAssign(&t[3]) c[2].Sub(&t[1], &t[4]) // step 9 is wrong in 2010/354! // steps 10, 11, 12 t[6].Mul(&x.B2, &c[1]) buf.Mul(&x.B1, &c[2]) t[6].AddAssign(&buf) - { // begin: inline t[6].MulByNonResidue(&t[6]) + { // begin inline: set t[6] to (&t[6]) * (9,1) var buf, buf9 E2 buf.Set(&t[6]) buf9.Double(&buf). @@ -561,11 +522,11 @@ func (z *E6) Inverse(x *E6) *E6 { Double(&buf9). Add(&buf9, &buf) t[6].A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(t[6]).A0, &buf.A1) + { // begin inline: set &(t[6]).A0 to (&buf.A1) * (-1) (&(t[6]).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(t[6]).A0, &buf.A1) + } // end inline: set &(t[6]).A0 to (&buf.A1) * (-1) t[6].A0.AddAssign(&buf9.A0) - } // end: inline t[6].MulByNonResidue(&t[6]) + } // end inline: set t[6] to (&t[6]) * (9,1) buf.Mul(&x.B0, &c[0]) t[6].AddAssign(&buf) @@ -575,45 +536,3 @@ func (z *E6) Inverse(x *E6) *E6 { z.B2.Mul(&c[2], &t[6]) // step 16 return z } - -// MulByNonResidue multiplies a E2 by (9,1) -func (z *E2) MulByNonResidue(x *E2) *E2 { - var buf, buf9 E2 - buf.Set(x) - buf9.Double(&buf). - Double(&buf9). - Double(&buf9). - Add(&buf9, &buf) - z.A1.Add(&buf.A0, &buf9.A1) - { // begin: inline MulByNonResidue(&(z).A0, &buf.A1) - (&(z).A0).Neg(&buf.A1) - } // end: inline MulByNonResidue(&(z).A0, &buf.A1) - z.A0.AddAssign(&buf9.A0) - return z -} - -// MulByNonResidueInv multiplies a E2 by (9,1)^{-1} -func (z *E2) MulByNonResidueInv(x *E2) *E2 { - // (z).A0 = (9*(x).A0 + (x).A1)/82 - // (z).A1 = (9*(x).A1 - (x).A0)/82 - copy := *(x) - - var copy9 E2 - copy9.Double(©). - Double(©9). - Double(©9). - AddAssign(©) - - (z).A0.Add(©9.A0, ©.A1) - (z).A1.Sub(©9.A1, ©.A0) - - buf82inv := fp.Element{ - 15263610803691847034, - 14617516054323294413, - 1961223913490700324, - 3456812345740674661, - } - (z).A0.MulAssign(&buf82inv) - (z).A1.MulAssign(&buf82inv) - return z -} diff --git a/bn256/pairing.go b/bn256/pairing.go index 97b1763e7..703cb3686 100644 --- a/bn256/pairing.go +++ b/bn256/pairing.go @@ -247,7 +247,7 @@ type lineEvalRes struct { func (l *lineEvalRes) mulAssign(z *PairingResult) *PairingResult { - var a, b, c E12 + var a, b, c PairingResult a.MulByVW(z, &l.r1) b.MulByV(z, &l.r0) c.MulByV2W(z, &l.r2) @@ -256,6 +256,93 @@ func (l *lineEvalRes) mulAssign(z *PairingResult) *PairingResult { return z } +// MulByVW set z to x*(y*v*w) and return z +// here y*v*w means the PairingResult element with C1.B1=y and all other components 0 +func (z *PairingResult) MulByVW(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNR G2CoordType + + { // begin inline: set yNR to (y) * (9,1) + var buf, buf9 G2CoordType + buf.Set(y) + buf9.Double(&buf). + Double(&buf9). + Double(&buf9). + Add(&buf9, &buf) + yNR.A1.Add(&buf.A0, &buf9.A1) + { // begin inline: set &(yNR).A0 to (&buf.A1) * (-1) + (&(yNR).A0).Neg(&buf.A1) + } // end inline: set &(yNR).A0 to (&buf.A1) * (-1) + yNR.A0.AddAssign(&buf9.A0) + } // end inline: set yNR to (y) * (9,1) + result.C0.B0.Mul(&x.C1.B1, &yNR) + result.C0.B1.Mul(&x.C1.B2, &yNR) + result.C0.B2.Mul(&x.C1.B0, y) + result.C1.B0.Mul(&x.C0.B2, &yNR) + result.C1.B1.Mul(&x.C0.B0, y) + result.C1.B2.Mul(&x.C0.B1, y) + z.Set(&result) + return z +} + +// MulByV set z to x*(y*v) and return z +// here y*v means the PairingResult element with C0.B1=y and all other components 0 +func (z *PairingResult) MulByV(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNR G2CoordType + + { // begin inline: set yNR to (y) * (9,1) + var buf, buf9 G2CoordType + buf.Set(y) + buf9.Double(&buf). + Double(&buf9). + Double(&buf9). + Add(&buf9, &buf) + yNR.A1.Add(&buf.A0, &buf9.A1) + { // begin inline: set &(yNR).A0 to (&buf.A1) * (-1) + (&(yNR).A0).Neg(&buf.A1) + } // end inline: set &(yNR).A0 to (&buf.A1) * (-1) + yNR.A0.AddAssign(&buf9.A0) + } // end inline: set yNR to (y) * (9,1) + result.C0.B0.Mul(&x.C0.B2, &yNR) + result.C0.B1.Mul(&x.C0.B0, y) + result.C0.B2.Mul(&x.C0.B1, y) + result.C1.B0.Mul(&x.C1.B2, &yNR) + result.C1.B1.Mul(&x.C1.B0, y) + result.C1.B2.Mul(&x.C1.B1, y) + z.Set(&result) + return z +} + +// MulByV2W set z to x*(y*v^2*w) and return z +// here y*v^2*w means the PairingResult element with C1.B2=y and all other components 0 +func (z *PairingResult) MulByV2W(x *PairingResult, y *G2CoordType) *PairingResult { + var result PairingResult + var yNR G2CoordType + + { // begin inline: set yNR to (y) * (9,1) + var buf, buf9 G2CoordType + buf.Set(y) + buf9.Double(&buf). + Double(&buf9). + Double(&buf9). + Add(&buf9, &buf) + yNR.A1.Add(&buf.A0, &buf9.A1) + { // begin inline: set &(yNR).A0 to (&buf.A1) * (-1) + (&(yNR).A0).Neg(&buf.A1) + } // end inline: set &(yNR).A0 to (&buf.A1) * (-1) + yNR.A0.AddAssign(&buf9.A0) + } // end inline: set yNR to (y) * (9,1) + result.C0.B0.Mul(&x.C1.B0, &yNR) + result.C0.B1.Mul(&x.C1.B1, &yNR) + result.C0.B2.Mul(&x.C1.B2, &yNR) + result.C1.B0.Mul(&x.C0.B1, &yNR) + result.C1.B1.Mul(&x.C0.B2, &yNR) + result.C1.B2.Mul(&x.C0.B0, y) + z.Set(&result) + return z +} + const tAbsVal uint64 = 4965661367192848881 // Expt set z to x^t in PairingResult and return z diff --git a/bw761/e2.go b/bw761/e2.go index 137590357..b1a64b17f 100644 --- a/bw761/e2.go +++ b/bw761/e2.go @@ -159,7 +159,10 @@ func (z *E2) Mul(x, y *E2) *E2 { aplusbcplusd.MulAssign(&cplusd) // [3]: (a+b)*(c+d) z.A1.Add(&ac, &bd) // ad+bc, [2] + [1] z.A1.Sub(&aplusbcplusd, &z.A1) // z.A1: [3] - [2] - [1] - MulByNonResidue(&z.A0, &bd) + { // begin inline: set &z.A0 to (&bd) * (-4) + buf := *(&bd) + (&z.A0).Double(&buf).Double(&z.A0).Neg(&z.A0) + } // end inline: set &z.A0 to (&bd) * (-4) z.A0.AddAssign(&ac) // z.A0: [1] + (-4)*[2] return z } @@ -182,7 +185,10 @@ func (z *E2) MulAssign(x *E2) *E2 { aplusbcplusd.MulAssign(&cplusd) // [3]: (a+b)*(c+d) z.A1.Add(&ac, &bd) // ad+bc, [2] + [1] z.A1.Sub(&aplusbcplusd, &z.A1) // z.A1: [3] - [2] - [1] - MulByNonResidue(&z.A0, &bd) + { // begin inline: set &z.A0 to (&bd) * (-4) + buf := *(&bd) + (&z.A0).Double(&buf).Double(&z.A0).Neg(&z.A0) + } // end inline: set &z.A0 to (&bd) * (-4) z.A0.AddAssign(&ac) // z.A0: [1] + (-4)*[2] return z } @@ -197,25 +203,23 @@ func (z *E2) Square(x *E2) *E2 { // Then z.A1: 2[1] var ab, aplusb, ababetab fp.Element - MulByNonResidue(&ababetab, &x.A1) + { // begin inline: set &ababetab to (&x.A1) * (-4) + buf := *(&x.A1) + (&ababetab).Double(&buf).Double(&ababetab).Neg(&ababetab) + } // end inline: set &ababetab to (&x.A1) * (-4) + + ababetab.AddAssign(&x.A0) // a+(-4)*b + aplusb.Add(&x.A0, &x.A1) // a+b + ababetab.MulAssign(&aplusb) // [2]: (a+b)*(a+(-4)*b) + ab.Mul(&x.A0, &x.A1) // [1]: ab + z.A1.Double(&ab) // z.A1: 2*[1] + { // begin inline: set &z.A0 to (&ab) * (-4) + buf := *(&ab) + (&z.A0).Double(&buf).Double(&z.A0).Neg(&z.A0) + } // end inline: set &z.A0 to (&ab) * (-4) + z.A0.AddAssign(&ab) // (-4+1)*ab + z.A0.Sub(&ababetab, &z.A0) // z.A0: [2] - (-4+1)[1] - ababetab.AddAssign(&x.A0) // a+(-4)*b - aplusb.Add(&x.A0, &x.A1) // a+b - ababetab.MulAssign(&aplusb) // [2]: (a+b)*(a+(-4)*b) - ab.Mul(&x.A0, &x.A1) // [1]: ab - z.A1.Double(&ab) // z.A1: 2*[1] - MulByNonResidue(&z.A0, &ab).AddAssign(&ab) // (-4+1)*ab - z.A0.Sub(&ababetab, &z.A0) // z.A0: [2] - (-4+1)[1] - - return z -} - -// MulByNonSquare multiplies an element by (0,1) -// TODO deprecate in favor of inlined MulByNonResidue in fp6 package -func (z *E2) MulByNonSquare(x *E2) *E2 { - a := x.A0 - MulByNonResidue(&z.A0, &x.A1) - z.A1 = a return z } @@ -229,7 +233,10 @@ func (z *E2) Inverse(x *E2) *E2 { t0.Square(&a0) // step 1 t1.Square(&a1) // step 2 - MulByNonResidue(&t1beta, &t1) + { // begin inline: set &t1beta to (&t1) * (-4) + buf := *(&t1) + (&t1beta).Double(&buf).Double(&t1beta).Neg(&t1beta) + } // end inline: set &t1beta to (&t1) * (-4) t0.SubAssign(&t1beta) // step 3 t1.Inverse(&t0) // step 4 z.A0.Mul(&a0, &t1) // step 5 @@ -253,18 +260,3 @@ func (z *E2) Conjugate(x *E2) *E2 { z.A1.Neg(&x.A1) return z } - -// MulByNonResidue multiplies a fp.Element by -4 -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidue(out, in *fp.Element) *fp.Element { - buf := *(in) - (out).Double(&buf).Double(out).Neg(out) - return out -} - -// MulByNonResidueInv multiplies a fp.Element by -4^{-1} -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidueInv(out, in *fp.Element) *fp.Element { - // TODO not implemented - return out -} diff --git a/bw761/e6.go b/bw761/e6.go index c7ef69872..cefd593d4 100644 --- a/bw761/e6.go +++ b/bw761/e6.go @@ -111,14 +111,14 @@ func (z *E6) MulByGen(x *E6) *E6 { result.B1 = x.B0 result.B2 = x.B1 - { // begin: inline result.B0.MulByNonResidue(&x.B2) + { // begin inline: set result.B0 to (&x.B2) * (0,1) buf := (&x.B2).A0 - { // begin: inline MulByNonResidue(&(result.B0).A0, &(&x.B2).A1) + { // begin inline: set &(result.B0).A0 to (&(&x.B2).A1) * (-4) buf := *(&(&x.B2).A1) (&(result.B0).A0).Double(&buf).Double(&(result.B0).A0).Neg(&(result.B0).A0) - } // end: inline MulByNonResidue(&(result.B0).A0, &(&x.B2).A1) + } // end inline: set &(result.B0).A0 to (&(&x.B2).A1) * (-4) (result.B0).A1 = buf - } // end: inline result.B0.MulByNonResidue(&x.B2) + } // end inline: set result.B0 to (&x.B2) * (0,1) z.Set(&result) return z @@ -152,14 +152,14 @@ func (z *E6) Mul(x, y *E6) *E6 { rb0.Mul(&b3, &b4). SubAssign(&b1). SubAssign(&b2) - { // begin: inline rb0.MulByNonResidue(&rb0) + { // begin inline: set rb0 to (&rb0) * (0,1) buf := (&rb0).A0 - { // begin: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) + { // begin inline: set &(rb0).A0 to (&(&rb0).A1) * (-4) buf := *(&(&rb0).A1) (&(rb0).A0).Double(&buf).Double(&(rb0).A0).Neg(&(rb0).A0) - } // end: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) + } // end inline: set &(rb0).A0 to (&(&rb0).A1) * (-4) (rb0).A1 = buf - } // end: inline rb0.MulByNonResidue(&rb0) + } // end inline: set rb0 to (&rb0) * (0,1) rb0.AddAssign(&b0) // step 5 @@ -168,14 +168,14 @@ func (z *E6) Mul(x, y *E6) *E6 { z.B1.Mul(&b3, &b4). SubAssign(&b0). SubAssign(&b1) - { // begin: inline b3.MulByNonResidue(&b2) + { // begin inline: set b3 to (&b2) * (0,1) buf := (&b2).A0 - { // begin: inline MulByNonResidue(&(b3).A0, &(&b2).A1) + { // begin inline: set &(b3).A0 to (&(&b2).A1) * (-4) buf := *(&(&b2).A1) (&(b3).A0).Double(&buf).Double(&(b3).A0).Neg(&(b3).A0) - } // end: inline MulByNonResidue(&(b3).A0, &(&b2).A1) + } // end inline: set &(b3).A0 to (&(&b2).A1) * (-4) (b3).A1 = buf - } // end: inline b3.MulByNonResidue(&b2) + } // end inline: set b3 to (&b2) * (0,1) z.B1.AddAssign(&b3) // step 6 @@ -204,14 +204,14 @@ func (z *E6) MulAssign(x *E6) *E6 { rb0.Mul(&b3, &b4). SubAssign(&b1). SubAssign(&b2) - { // begin: inline rb0.MulByNonResidue(&rb0) + { // begin inline: set rb0 to (&rb0) * (0,1) buf := (&rb0).A0 - { // begin: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) + { // begin inline: set &(rb0).A0 to (&(&rb0).A1) * (-4) buf := *(&(&rb0).A1) (&(rb0).A0).Double(&buf).Double(&(rb0).A0).Neg(&(rb0).A0) - } // end: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) + } // end inline: set &(rb0).A0 to (&(&rb0).A1) * (-4) (rb0).A1 = buf - } // end: inline rb0.MulByNonResidue(&rb0) + } // end inline: set rb0 to (&rb0) * (0,1) rb0.AddAssign(&b0) // step 5 @@ -220,14 +220,14 @@ func (z *E6) MulAssign(x *E6) *E6 { z.B1.Mul(&b3, &b4). SubAssign(&b0). SubAssign(&b1) - { // begin: inline b3.MulByNonResidue(&b2) + { // begin inline: set b3 to (&b2) * (0,1) buf := (&b2).A0 - { // begin: inline MulByNonResidue(&(b3).A0, &(&b2).A1) + { // begin inline: set &(b3).A0 to (&(&b2).A1) * (-4) buf := *(&(&b2).A1) (&(b3).A0).Double(&buf).Double(&(b3).A0).Neg(&(b3).A0) - } // end: inline MulByNonResidue(&(b3).A0, &(&b2).A1) + } // end inline: set &(b3).A0 to (&(&b2).A1) * (-4) (b3).A1 = buf - } // end: inline b3.MulByNonResidue(&b2) + } // end inline: set b3 to (&b2) * (0,1) z.B1.AddAssign(&b3) // step 6 @@ -251,38 +251,6 @@ func (z *E6) MulByE2(x *E6, y *E2) *E6 { return z } -// MulByNotv2 multiplies x by y with &y.b2=0 -func (z *E6) MulByNotv2(x, y *E6) *E6 { - // Algorithm 15 from https://eprint.iacr.org/2010/354.pdf - var rb0, b0, b1, b2, b3 E2 - b0.Mul(&x.B0, &y.B0) // step 1 - b1.Mul(&x.B1, &y.B1) // step 2 - // step 3 - b2.Add(&x.B1, &x.B2) - rb0.Mul(&b2, &y.B1). - SubAssign(&b1) - { // begin: inline rb0.MulByNonResidue(&rb0) - buf := (&rb0).A0 - { // begin: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) - buf := *(&(&rb0).A1) - (&(rb0).A0).Double(&buf).Double(&(rb0).A0).Neg(&(rb0).A0) - } // end: inline MulByNonResidue(&(rb0).A0, &(&rb0).A1) - (rb0).A1 = buf - } // end: inline rb0.MulByNonResidue(&rb0) - rb0.AddAssign(&b0) - // step 4 - b2.Add(&x.B0, &x.B1) - b3.Add(&y.B0, &y.B1) - z.B1.Mul(&b2, &b3). - SubAssign(&b0). - SubAssign(&b1) - // step 5 - z.B2.Mul(&x.B2, &y.B0). - AddAssign(&b1) - z.B0 = rb0 - return z -} - // Square sets z to the E6-product of x,x, returns z func (z *E6) Square(x *E6) *E6 { @@ -292,28 +260,28 @@ func (z *E6) Square(x *E6) *E6 { b4.Square(&x.B2) // step 2 // step 3 - { // begin: inline b0.MulByNonResidue(&b4) + { // begin inline: set b0 to (&b4) * (0,1) buf := (&b4).A0 - { // begin: inline MulByNonResidue(&(b0).A0, &(&b4).A1) + { // begin inline: set &(b0).A0 to (&(&b4).A1) * (-4) buf := *(&(&b4).A1) (&(b0).A0).Double(&buf).Double(&(b0).A0).Neg(&(b0).A0) - } // end: inline MulByNonResidue(&(b0).A0, &(&b4).A1) + } // end inline: set &(b0).A0 to (&(&b4).A1) * (-4) (b0).A1 = buf - } // end: inline b0.MulByNonResidue(&b4) + } // end inline: set b0 to (&b4) * (0,1) b0.AddAssign(&b3) b1.Sub(&b3, &b4) // step 4 b2.Square(&x.B0) // step 5 b3.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&b3) // steps 6 and 8 b4.Mul(&x.B1, &x.B2).Double(&b4) // step 7 // step 9 - { // begin: inline z.B0.MulByNonResidue(&b4) + { // begin inline: set z.B0 to (&b4) * (0,1) buf := (&b4).A0 - { // begin: inline MulByNonResidue(&(z.B0).A0, &(&b4).A1) + { // begin inline: set &(z.B0).A0 to (&(&b4).A1) * (-4) buf := *(&(&b4).A1) (&(z.B0).A0).Double(&buf).Double(&(z.B0).A0).Neg(&(z.B0).A0) - } // end: inline MulByNonResidue(&(z.B0).A0, &(&b4).A1) + } // end inline: set &(z.B0).A0 to (&(&b4).A1) * (-4) (z.B0).A1 = buf - } // end: inline z.B0.MulByNonResidue(&b4) + } // end inline: set z.B0 to (&b4) * (0,1) z.B0.AddAssign(&b2) // step 10 @@ -333,28 +301,28 @@ func (z *E6) SquareAssign() *E6 { b4.Square(&z.B2) // step 2 // step 3 - { // begin: inline b0.MulByNonResidue(&b4) + { // begin inline: set b0 to (&b4) * (0,1) buf := (&b4).A0 - { // begin: inline MulByNonResidue(&(b0).A0, &(&b4).A1) + { // begin inline: set &(b0).A0 to (&(&b4).A1) * (-4) buf := *(&(&b4).A1) (&(b0).A0).Double(&buf).Double(&(b0).A0).Neg(&(b0).A0) - } // end: inline MulByNonResidue(&(b0).A0, &(&b4).A1) + } // end inline: set &(b0).A0 to (&(&b4).A1) * (-4) (b0).A1 = buf - } // end: inline b0.MulByNonResidue(&b4) + } // end inline: set b0 to (&b4) * (0,1) b0.AddAssign(&b3) b1.Sub(&b3, &b4) // step 4 b2.Square(&z.B0) // step 5 b3.Sub(&z.B0, &z.B1).AddAssign(&z.B2).Square(&b3) // steps 6 and 8 b4.Mul(&z.B1, &z.B2).Double(&b4) // step 7 // step 9 - { // begin: inline z.B0.MulByNonResidue(&b4) + { // begin inline: set z.B0 to (&b4) * (0,1) buf := (&b4).A0 - { // begin: inline MulByNonResidue(&(z.B0).A0, &(&b4).A1) + { // begin inline: set &(z.B0).A0 to (&(&b4).A1) * (-4) buf := *(&(&b4).A1) (&(z.B0).A0).Double(&buf).Double(&(z.B0).A0).Neg(&(z.B0).A0) - } // end: inline MulByNonResidue(&(z.B0).A0, &(&b4).A1) + } // end inline: set &(z.B0).A0 to (&(&b4).A1) * (-4) (z.B0).A1 = buf - } // end: inline z.B0.MulByNonResidue(&b4) + } // end inline: set z.B0 to (&b4) * (0,1) z.B0.AddAssign(&b2) // step 10 @@ -379,23 +347,23 @@ func (z *E6) SquarE2(x *E6) *E6 { v12.Add(&x.B1, &x.B2) v12.Square(&v12) z.B0.Sub(&v12, &v1).SubAssign(&v2) - { // begin: inline z.B0.MulByNonResidue(&z.B0) + { // begin inline: set z.B0 to (&z.B0) * (0,1) buf := (&z.B0).A0 - { // begin: inline MulByNonResidue(&(z.B0).A0, &(&z.B0).A1) + { // begin inline: set &(z.B0).A0 to (&(&z.B0).A1) * (-4) buf := *(&(&z.B0).A1) (&(z.B0).A0).Double(&buf).Double(&(z.B0).A0).Neg(&(z.B0).A0) - } // end: inline MulByNonResidue(&(z.B0).A0, &(&z.B0).A1) + } // end inline: set &(z.B0).A0 to (&(&z.B0).A1) * (-4) (z.B0).A1 = buf - } // end: inline z.B0.MulByNonResidue(&z.B0) + } // end inline: set z.B0 to (&z.B0) * (0,1) z.B0.AddAssign(&v0) - { // begin: inline z.B1.MulByNonResidue(&v2) + { // begin inline: set z.B1 to (&v2) * (0,1) buf := (&v2).A0 - { // begin: inline MulByNonResidue(&(z.B1).A0, &(&v2).A1) + { // begin inline: set &(z.B1).A0 to (&(&v2).A1) * (-4) buf := *(&(&v2).A1) (&(z.B1).A0).Double(&buf).Double(&(z.B1).A0).Neg(&(z.B1).A0) - } // end: inline MulByNonResidue(&(z.B1).A0, &(&v2).A1) + } // end inline: set &(z.B1).A0 to (&(&v2).A1) * (-4) (z.B1).A1 = buf - } // end: inline z.B1.MulByNonResidue(&v2) + } // end inline: set z.B1 to (&v2) * (0,1) z.B1.AddAssign(&v01).SubAssign(&v0).SubAssign(&v1) z.B2.Add(&v02, &v1).SubAssign(&v0).SubAssign(&v2) return z @@ -410,23 +378,23 @@ func (z *E6) Square3(x *E6) *E6 { s2.Sub(&x.B0, &x.B1).AddAssign(&x.B2).Square(&s2) s3.Mul(&x.B1, &x.B2).Double(&s3) s4.Square(&x.B2) - { // begin: inline z.B0.MulByNonResidue(&s3) + { // begin inline: set z.B0 to (&s3) * (0,1) buf := (&s3).A0 - { // begin: inline MulByNonResidue(&(z.B0).A0, &(&s3).A1) + { // begin inline: set &(z.B0).A0 to (&(&s3).A1) * (-4) buf := *(&(&s3).A1) (&(z.B0).A0).Double(&buf).Double(&(z.B0).A0).Neg(&(z.B0).A0) - } // end: inline MulByNonResidue(&(z.B0).A0, &(&s3).A1) + } // end inline: set &(z.B0).A0 to (&(&s3).A1) * (-4) (z.B0).A1 = buf - } // end: inline z.B0.MulByNonResidue(&s3) + } // end inline: set z.B0 to (&s3) * (0,1) z.B0.AddAssign(&s0) - { // begin: inline z.B1.MulByNonResidue(&s4) + { // begin inline: set z.B1 to (&s4) * (0,1) buf := (&s4).A0 - { // begin: inline MulByNonResidue(&(z.B1).A0, &(&s4).A1) + { // begin inline: set &(z.B1).A0 to (&(&s4).A1) * (-4) buf := *(&(&s4).A1) (&(z.B1).A0).Double(&buf).Double(&(z.B1).A0).Neg(&(z.B1).A0) - } // end: inline MulByNonResidue(&(z.B1).A0, &(&s4).A1) + } // end inline: set &(z.B1).A0 to (&(&s4).A1) * (-4) (z.B1).A1 = buf - } // end: inline z.B1.MulByNonResidue(&s4) + } // end inline: set z.B1 to (&s4) * (0,1) z.B1.AddAssign(&s1) z.B2.Add(&s1, &s2).AddAssign(&s3).SubAssign(&s0).SubAssign(&s4) return z @@ -447,38 +415,38 @@ func (z *E6) Inverse(x *E6) *E6 { t[4].Mul(&x.B0, &x.B2) // step 5 t[5].Mul(&x.B1, &x.B2) // step 6 // step 7 - { // begin: inline c[0].MulByNonResidue(&t[5]) + { // begin inline: set c[0] to (&t[5]) * (0,1) buf := (&t[5]).A0 - { // begin: inline MulByNonResidue(&(c[0]).A0, &(&t[5]).A1) + { // begin inline: set &(c[0]).A0 to (&(&t[5]).A1) * (-4) buf := *(&(&t[5]).A1) (&(c[0]).A0).Double(&buf).Double(&(c[0]).A0).Neg(&(c[0]).A0) - } // end: inline MulByNonResidue(&(c[0]).A0, &(&t[5]).A1) + } // end inline: set &(c[0]).A0 to (&(&t[5]).A1) * (-4) (c[0]).A1 = buf - } // end: inline c[0].MulByNonResidue(&t[5]) + } // end inline: set c[0] to (&t[5]) * (0,1) c[0].Neg(&c[0]).AddAssign(&t[0]) // step 8 - { // begin: inline c[1].MulByNonResidue(&t[2]) + { // begin inline: set c[1] to (&t[2]) * (0,1) buf := (&t[2]).A0 - { // begin: inline MulByNonResidue(&(c[1]).A0, &(&t[2]).A1) + { // begin inline: set &(c[1]).A0 to (&(&t[2]).A1) * (-4) buf := *(&(&t[2]).A1) (&(c[1]).A0).Double(&buf).Double(&(c[1]).A0).Neg(&(c[1]).A0) - } // end: inline MulByNonResidue(&(c[1]).A0, &(&t[2]).A1) + } // end inline: set &(c[1]).A0 to (&(&t[2]).A1) * (-4) (c[1]).A1 = buf - } // end: inline c[1].MulByNonResidue(&t[2]) + } // end inline: set c[1] to (&t[2]) * (0,1) c[1].SubAssign(&t[3]) c[2].Sub(&t[1], &t[4]) // step 9 is wrong in 2010/354! // steps 10, 11, 12 t[6].Mul(&x.B2, &c[1]) buf.Mul(&x.B1, &c[2]) t[6].AddAssign(&buf) - { // begin: inline t[6].MulByNonResidue(&t[6]) + { // begin inline: set t[6] to (&t[6]) * (0,1) buf := (&t[6]).A0 - { // begin: inline MulByNonResidue(&(t[6]).A0, &(&t[6]).A1) + { // begin inline: set &(t[6]).A0 to (&(&t[6]).A1) * (-4) buf := *(&(&t[6]).A1) (&(t[6]).A0).Double(&buf).Double(&(t[6]).A0).Neg(&(t[6]).A0) - } // end: inline MulByNonResidue(&(t[6]).A0, &(&t[6]).A1) + } // end inline: set &(t[6]).A0 to (&(&t[6]).A1) * (-4) (t[6]).A1 = buf - } // end: inline t[6].MulByNonResidue(&t[6]) + } // end inline: set t[6] to (&t[6]) * (0,1) buf.Mul(&x.B0, &c[0]) t[6].AddAssign(&buf) @@ -488,24 +456,3 @@ func (z *E6) Inverse(x *E6) *E6 { z.B2.Mul(&c[2], &t[6]) // step 16 return z } - -// MulByNonResidue multiplies a E2 by (0,1) -func (z *E2) MulByNonResidue(x *E2) *E2 { - buf := (x).A0 - { // begin: inline MulByNonResidue(&(z).A0, &(x).A1) - buf := *(&(x).A1) - (&(z).A0).Double(&buf).Double(&(z).A0).Neg(&(z).A0) - } // end: inline MulByNonResidue(&(z).A0, &(x).A1) - (z).A1 = buf - return z -} - -// MulByNonResidueInv multiplies a E2 by (0,1)^{-1} -func (z *E2) MulByNonResidueInv(x *E2) *E2 { - buf := (x).A1 - { // begin: inline MulByNonResidueInv(&(z).A1, &(x).A0) - // TODO not implemented - } // end: inline MulByNonResidueInv(&(z).A1, &(x).A0) - (z).A0 = buf - return z -} diff --git a/bw761/pairing.go b/bw761/pairing.go index 62ecdc73f..3ffcff4a9 100644 --- a/bw761/pairing.go +++ b/bw761/pairing.go @@ -350,14 +350,64 @@ type lineEvalRes struct { r2 G2CoordType // c1.b2 } +// mulAssign finish the work of lineEval by applying the twist isomorphism to l, obtaining a PairingResult p +// then set z to z*p and return z func (l *lineEvalRes) mulAssign(z *PairingResult) *PairingResult { var a, b, c PairingResult - a.MulByVMinusThree(z, &l.r1) - b.MulByVminusTwo(z, &l.r0) - c.MulByVminusFive(z, &l.r2) - z.Add(&a, &b).Add(z, &c) + fourinv := G2CoordType{ // (-4)^(-1) + 8571757465769615091, + 6221412002326125864, + 16781361031322833010, + 18148962537424854844, + 6497335359600054623, + 17630955688667215145, + 15638647242705587201, + 830917065158682257, + 6848922060227959954, + 4142027113657578586, + 12050453106507568375, + 55644342162350184, + } + + // in what follows arithmetic is in Fp6(v) where v^3=u, v^6=-4 + + // set a to z * (l.r1 * v^-3) where v^(-3) = u^(-1) = (-4)^(-1)*u + { + var tmp E2 // tmp = l.r1 * (-4)^(-1)*u + tmp.A0.SetZero() + tmp.A1.Mul(&l.r1, &fourinv) + a.MulByE2(z, &tmp) + } + + // set b to z * (l.r0 * v^-2) where v^(-2) = (-4)^(-1)*u*v + { + var tmp E2 // tmp = l.r0 * (-4)^(-1)*u + tmp.A0.SetZero() + tmp.A1.Mul(&l.r0, &fourinv) + + var a E2 + a.MulByElement(&z.B2, &l.r0) + b.B2.Mul(&z.B1, &tmp) + b.B1.Mul(&z.B0, &tmp) + b.B0.Set(&a) + } + + // set c to z * (l.r2 * v^-5) (Fp6(v) where v^3=u, v^6=-4, so v^(-5) = (-4)^(-1)*v) + { + var tmp E2 // tmp = l.r2 * (-4)^(-1)*u + tmp.A0.SetZero() + tmp.A1.Mul(&l.r2, &fourinv) + + var a E2 + a.Mul(&z.B2, &tmp) + c.B2.MulByElement(&z.B1, &tmp.A1) + c.B1.MulByElement(&z.B0, &tmp.A1) + c.B0.Set(&a) + } + + z.Add(&a, &b).Add(z, &c) return z } @@ -410,59 +460,3 @@ func (z *PairingResult) Expt(x *PairingResult) *PairingResult { z.Set(&result) return z } - -// MulByVMinusThree set z to x*(y*v**-3) and return z (Fp6(v) where v**3=u, v**6=-4, so v**-3 = u**-1 = (-4)**-1*u) -func (z *PairingResult) MulByVMinusThree(x *PairingResult, y *G2CoordType) *PairingResult { - - var fourinv G2CoordType // (-4)**-1 - fourinv.SetString("5168587788236799404547592261706743156859751684402112582135342620157217566682618802065762387467058765730648425815339960088371319340415685819512133774343976199213703824533881637779407723567697596963924775322476834632073684839301224") - - // tmp = y*(-4)**-1 * u - var tmp E2 - tmp.A0.SetZero() - tmp.A1.Mul(y, &fourinv) - - z.MulByE2(x, &tmp) - - return z -} - -// MulByVminusTwo set z to x*(y*v**-2) and return z (Fp6(v) where v**3=u, v**6=-4, so v**-2 = (-4)**-1*u*v) -func (z *PairingResult) MulByVminusTwo(x *PairingResult, y *G2CoordType) *PairingResult { - - var fourinv G2CoordType // (-4)**-1 - fourinv.SetString("5168587788236799404547592261706743156859751684402112582135342620157217566682618802065762387467058765730648425815339960088371319340415685819512133774343976199213703824533881637779407723567697596963924775322476834632073684839301224") - - // tmp = y*(-4)**-1 * u - var tmp E2 - tmp.A0.SetZero() - tmp.A1.Mul(y, &fourinv) - - var a E2 - a.MulByElement(&x.B2, y) - z.B2.Mul(&x.B1, &tmp) - z.B1.Mul(&x.B0, &tmp) - z.B0.Set(&a) - - return z -} - -// MulByVminusFive set z to x*(y*v**-5) and return z (Fp6(v) where v**3=u, v**6=-4, so v**-5 = (-4)**-1*v) -func (z *PairingResult) MulByVminusFive(x *PairingResult, y *G2CoordType) *PairingResult { - - var fourinv G2CoordType // (-4)**-1 - fourinv.SetString("5168587788236799404547592261706743156859751684402112582135342620157217566682618802065762387467058765730648425815339960088371319340415685819512133774343976199213703824533881637779407723567697596963924775322476834632073684839301224") - - // tmp = y*(-4)**-1 * u - var tmp E2 - tmp.A0.SetZero() - tmp.A1.Mul(y, &fourinv) - - var a E2 - a.Mul(&x.B2, &tmp) - z.B2.MulByElement(&x.B1, &tmp.A1) - z.B1.MulByElement(&x.B0, &tmp.A1) - z.B0.Set(&a) - - return z -} diff --git a/internal/generators/main.go b/internal/generators/main.go index ce65d0420..7811535b0 100644 --- a/internal/generators/main.go +++ b/internal/generators/main.go @@ -8,7 +8,6 @@ import ( "github.com/consensys/bavard" "github.com/consensys/gurvy/internal/generators/curve" "github.com/consensys/gurvy/internal/generators/pairing" - "github.com/consensys/gurvy/internal/generators/tower" ) // TODO move all this curve data to config file(s)? @@ -122,21 +121,6 @@ func main() { } } - // generate tower generator (uses curve.C, primefield) - { - src := []string{ - tower.TwoInvTemplate, - } - if err := bavard.Generate("tower/generated-code.go", src, d, - bavard.Package("tower"), - bavard.Apache2("ConsenSys AG", 2020), - bavard.GeneratedBy("gurvy/internal/generators"), - ); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(-1) - } - } - // generate tower (uses curve.C) { cmd := exec.Command("go", "run", "./tower/main/main.go") diff --git a/internal/generators/tower/generator.go b/internal/generators/tower/generator.go index f7a6ca86d..c561d04c2 100644 --- a/internal/generators/tower/generator.go +++ b/internal/generators/tower/generator.go @@ -22,9 +22,6 @@ type Data struct { Fp2Name string Fp6Name string Fp12Name string - - // these members are computed as needed - TwoInv []uint64 // fp.Element, used only when Fp2NonResidue==-1 and Fp6NonResidue==(1,1). TODO there must be a better way to do this. } // Generate generates pairing @@ -32,12 +29,6 @@ func Generate(d Data, outputDir string) error { rootPath := filepath.Join(outputDir, d.Fpackage) - // inverse of 2 in fp is used by some curves - // TODO this sucks, generalize it - if d.Fp2NonResidue == "-1" && d.Fp6NonResidue == "1,1" { - d.InitTwoInv() - } - // fp2 if d.EmbeddingDegree >= 2 { src := []string{ @@ -91,17 +82,3 @@ func Generate(d Data, outputDir string) error { return nil } - -// InitTwoInv set z.TwoInv to the inverse of 2 as an fp.Element -func (z *Data) InitTwoInv() *Data { - var twoInv fpElement - twoInv.SetUint64(2).Inverse(&twoInv) - z.TwoInv = twoInv[:] - return z -} - -const TwoInvTemplate = ` -import "github.com/consensys/gurvy/{{$.Fpackage}}/fp" - -type fpElement = fp.Element -` diff --git a/internal/generators/tower/templates/fp12/inline.go b/internal/generators/tower/templates/fp12/inline.go index 1fd8e7936..934332e84 100644 --- a/internal/generators/tower/templates/fp12/inline.go +++ b/internal/generators/tower/templates/fp12/inline.go @@ -4,16 +4,12 @@ package fp12 const Inline = ` {{- define "fp6InlineMulByNonResidue" }} - { // begin: inline {{$.out}}.MulByNonResidue({{$.in}}) - {{- template "fp6MulByNonResidueBody" dict "all" $.all "out" $.out "in" $.in }} - } // end: inline {{$.out}}.MulByNonResidue({{$.in}}) -{{- end }} - -{{- define "fp6MulByNonResidueBody" }} - var result {{$.all.Fp6Name}} - result.B1.Set(&({{$.in}}).B0) - result.B2.Set(&({{$.in}}).B1) - {{- template "fp2InlineMulByNonResidue" dict "all" $.all "out" "result.B0" "in" (print "&(" $.in ").B2") }} - {{$.out}}.Set(&result) + { // begin inline: set {{.out}} to ({{.in}}) * ((0,0),(1,0),(0,0)) + var result {{.all.Fp6Name}} + result.B1.Set(&({{.in}}).B0) + result.B2.Set(&({{.in}}).B1) + {{- template "fp2InlineMulByNonResidue" dict "all" .all "out" "result.B0" "in" (print "&(" .in ").B2") }} + {{.out}}.Set(&result) + } // end inline: set {{.out}} to ({{.in}}) * ((0,0),(1,0),(0,0)) {{- end }} ` diff --git a/internal/generators/tower/templates/fp12/mul.go b/internal/generators/tower/templates/fp12/mul.go index 323c239c8..e4fbd40f3 100644 --- a/internal/generators/tower/templates/fp12/mul.go +++ b/internal/generators/tower/templates/fp12/mul.go @@ -76,118 +76,4 @@ func (z *{{.Fp12Name}}) Conjugate(x *{{.Fp12Name}}) *{{.Fp12Name}} { z.C1.Neg(&z.C1) return z } - -// MulByVW set z to x*(y*v*w) and return z -// here y*v*w means the {{.Fp12Name}} element with C1.B1=y and all other components 0 -func (z *{{.Fp12Name}}) MulByVW(x *{{.Fp12Name}}, y *{{.Fp2Name}}) *{{.Fp12Name}} { - var result {{.Fp12Name}} - var yNR {{.Fp2Name}} - {{ template "fp2InlineMulByNonResidue" dict "all" . "out" "yNR" "in" "y" }} - result.C0.B0.Mul(&x.C1.B1, &yNR) - result.C0.B1.Mul(&x.C1.B2, &yNR) - result.C0.B2.Mul(&x.C1.B0, y) - result.C1.B0.Mul(&x.C0.B2, &yNR) - result.C1.B1.Mul(&x.C0.B0, y) - result.C1.B2.Mul(&x.C0.B1, y) - z.Set(&result) - return z -} - -// MulByV set z to x*(y*v) and return z -// here y*v means the {{.Fp12Name}} element with C0.B1=y and all other components 0 -func (z *{{.Fp12Name}}) MulByV(x *{{.Fp12Name}}, y *{{.Fp2Name}}) *{{.Fp12Name}} { - var result {{.Fp12Name}} - var yNR {{.Fp2Name}} - {{ template "fp2InlineMulByNonResidue" dict "all" . "out" "yNR" "in" "y" }} - result.C0.B0.Mul(&x.C0.B2, &yNR) - result.C0.B1.Mul(&x.C0.B0, y) - result.C0.B2.Mul(&x.C0.B1, y) - result.C1.B0.Mul(&x.C1.B2, &yNR) - result.C1.B1.Mul(&x.C1.B0, y) - result.C1.B2.Mul(&x.C1.B1, y) - z.Set(&result) - return z -} - -// MulByV2W set z to x*(y*v^2*w) and return z -// here y*v^2*w means the {{.Fp12Name}} element with C1.B2=y and all other components 0 -func (z *{{.Fp12Name}}) MulByV2W(x *{{.Fp12Name}}, y *{{.Fp2Name}}) *{{.Fp12Name}} { - var result {{.Fp12Name}} - var yNR {{.Fp2Name}} - {{ template "fp2InlineMulByNonResidue" dict "all" . "out" "yNR" "in" "y" }} - result.C0.B0.Mul(&x.C1.B0, &yNR) - result.C0.B1.Mul(&x.C1.B1, &yNR) - result.C0.B2.Mul(&x.C1.B2, &yNR) - result.C1.B0.Mul(&x.C0.B1, &yNR) - result.C1.B1.Mul(&x.C0.B2, &yNR) - result.C1.B2.Mul(&x.C0.B0, y) - z.Set(&result) - return z -} - -// MulByV2NRInv set z to x*(y*v^2*({{.Fp6NonResidue}})^{-1}) and return z -// here y*v^2 means the {{.Fp12Name}} element with C0.B2=y and all other components 0 -func (z *{{.Fp12Name}}) MulByV2NRInv(x *{{.Fp12Name}}, y *{{.Fp2Name}}) *{{.Fp12Name}} { - var result {{.Fp12Name}} - var yNRInv {{.Fp2Name}} - - {{ template "fp2InlineMulByNonResidueInv" dict "all" . "out" "yNRInv" "in" "y" }} - - result.C0.B0.Mul(&x.C0.B1, y) - result.C0.B1.Mul(&x.C0.B2, y) - result.C0.B2.Mul(&x.C0.B0, &yNRInv) - - result.C1.B0.Mul(&x.C1.B1, y) - result.C1.B1.Mul(&x.C1.B2, y) - result.C1.B2.Mul(&x.C1.B0, &yNRInv) - - z.Set(&result) - return z -} - -// MulByVWNRInv set z to x*(y*v*w*({{.Fp6NonResidue}})^{-1}) and return z -// here y*v*w means the {{.Fp12Name}} element with C1.B1=y and all other components 0 -func (z *{{.Fp12Name}}) MulByVWNRInv(x *{{.Fp12Name}}, y *{{.Fp2Name}}) *{{.Fp12Name}} { - var result {{.Fp12Name}} - var yNRInv {{.Fp2Name}} - - {{ template "fp2InlineMulByNonResidueInv" dict "all" . "out" "yNRInv" "in" "y" }} - - result.C0.B0.Mul(&x.C1.B1, y) - result.C0.B1.Mul(&x.C1.B2, y) - result.C0.B2.Mul(&x.C1.B0, &yNRInv) - - result.C1.B0.Mul(&x.C0.B2, y) - result.C1.B1.Mul(&x.C0.B0, &yNRInv) - result.C1.B2.Mul(&x.C0.B1, &yNRInv) - - z.Set(&result) - return z -} - -// MulByWNRInv set z to x*(y*w*({{.Fp6NonResidue}})^{-1}) and return z -// here y*w means the {{.Fp12Name}} element with C1.B0=y and all other components 0 -func (z *{{.Fp12Name}}) MulByWNRInv(x *{{.Fp12Name}}, y *{{.Fp2Name}}) *{{.Fp12Name}} { - var result {{.Fp12Name}} - var yNRInv {{.Fp2Name}} - - {{ template "fp2InlineMulByNonResidueInv" dict "all" . "out" "yNRInv" "in" "y" }} - - result.C0.B0.Mul(&x.C1.B2, y) - result.C0.B1.Mul(&x.C1.B0, &yNRInv) - result.C0.B2.Mul(&x.C1.B1, &yNRInv) - - result.C1.B0.Mul(&x.C0.B0, &yNRInv) - result.C1.B1.Mul(&x.C0.B1, &yNRInv) - result.C1.B2.Mul(&x.C0.B2, &yNRInv) - - z.Set(&result) - return z -} - -// MulByNonResidue multiplies a {{.Fp6Name}} by ((0,0),(1,0),(0,0)) -func (z *{{.Fp6Name}}) MulByNonResidue(x *{{.Fp6Name}}) *{{.Fp6Name}} { - {{- template "fp6MulByNonResidueBody" dict "all" . "out" "z" "in" "x" }} - return z -} ` diff --git a/internal/generators/tower/templates/fp2/inline.go b/internal/generators/tower/templates/fp2/inline.go index 30d33cbab..b3fc96bd4 100644 --- a/internal/generators/tower/templates/fp2/inline.go +++ b/internal/generators/tower/templates/fp2/inline.go @@ -4,58 +4,21 @@ package fp2 const Inline = ` {{- define "fpInlineMulByNonResidue" }} - { // begin: inline MulByNonResidue({{$.out}}, {{$.in}}) - {{- template "fpMulByNonResidueBody" dict "all" $.all "out" $.out "in" $.in }} - } // end: inline MulByNonResidue({{$.out}}, {{$.in}}) -{{- end }} - -{{- define "fpMulByNonResidueBody" }} - {{- if eq $.all.Fp2NonResidue "5" }} - buf := *({{$.in}}) - ({{$.out}}).Double(&buf).Double({{$.out}}).AddAssign(&buf) - {{- else if eq $.all.Fp2NonResidue "-1" }} - ({{$.out}}).Neg({{$.in}}) - {{- else if eq $.all.Fp2NonResidue "3" }} - buf := *({{$.in}}) - ({{$.out}}).Double(&buf).AddAssign(&buf) - {{- else if eq $.all.Fp2NonResidue "-4" }} - buf := *({{$.in}}) - ({{$.out}}).Double(&buf).Double({{$.out}}).Neg({{$.out}}) - {{- else }} - // TODO not implemented - {{- end }} -{{- end }} - -{{- define "fpInlineMulByNonResidueInv" }} - { // begin: inline MulByNonResidueInv({{$.out}}, {{$.in}}) - {{- template "fpMulByNonResidueInvBody" dict "all" $.all "out" $.out "in" $.in }} - } // end: inline MulByNonResidueInv({{$.out}}, {{$.in}}) -{{- end }} - -{{- define "fpMulByNonResidueInvBody" }} - {{- if eq $.all.Fp2NonResidue "5" }} - nrinv := fp.Element{ - 330620507644336508, - 9878087358076053079, - 11461392860540703536, - 6973035786057818995, - 8846909097162646007, - 104838758629667239, - } - ({{$.out}}).Mul({{$.in}}, &nrinv) - {{- else if eq $.all.Fp2NonResidue "-1" }} - // TODO this should be a no-op when {{$.out}}=={{$.in}} - ({{$.out}}).Set({{$.in}}) - {{- else if eq $.all.Fp2NonResidue "3" }} - nrinv := fp.Element{ - 12669921578670009932, - 16188407930212075331, - 13036317521149659693, - 1499583668832556317, - } - ({{$.out}}).Mul(({{$.in}}), &nrinv) - {{- else }} - // TODO not implemented - {{- end }} + { // begin inline: set {{.out}} to ({{.in}}) * ({{.all.Fp2NonResidue}}) + {{- if eq .all.Fp2NonResidue "5" }} + buf := *({{.in}}) + ({{.out}}).Double(&buf).Double({{$.out}}).AddAssign(&buf) + {{- else if eq .all.Fp2NonResidue "-1" }} + ({{.out}}).Neg({{.in}}) + {{- else if eq .all.Fp2NonResidue "3" }} + buf := *({{.in}}) + ({{.out}}).Double(&buf).AddAssign(&buf) + {{- else if eq .all.Fp2NonResidue "-4" }} + buf := *({{.in}}) + ({{.out}}).Double(&buf).Double({{.out}}).Neg({{.out}}) + {{- else }} + panic("not implemented") + {{- end }} + } // end inline: set {{.out}} to ({{.in}}) * ({{.all.Fp2NonResidue}}) {{- end }} ` diff --git a/internal/generators/tower/templates/fp2/mul.go b/internal/generators/tower/templates/fp2/mul.go index a1020c332..895d49f3b 100644 --- a/internal/generators/tower/templates/fp2/mul.go +++ b/internal/generators/tower/templates/fp2/mul.go @@ -34,7 +34,7 @@ func (z *{{.Fp2Name}}) MulAssign(x *{{.Fp2Name}}) *{{.Fp2Name}} { {{- if eq $.all.Fp2NonResidue "-1" }} z.A0.Sub(&ac, &bd) // z.A0: [1] - [2] {{- else }} - MulByNonResidue(&z.A0, &bd) + {{- template "fpInlineMulByNonResidue" dict "all" .all "out" "&z.A0" "in" "&bd" }} z.A0.AddAssign(&ac) // z.A0: [1] + ({{.all.Fp2NonResidue}})*[2] {{- end -}} @@ -63,7 +63,7 @@ func (z *{{.Fp2Name}}) Square(x *{{.Fp2Name}}) *{{.Fp2Name}} { {{- else }} var ab, aplusb, ababetab fp.Element - MulByNonResidue(&ababetab, &x.A1) + {{ template "fpInlineMulByNonResidue" dict "all" . "out" "&ababetab" "in" "&x.A1" }} ababetab.AddAssign(&x.A0) // a+({{.Fp2NonResidue}})*b aplusb.Add(&x.A0, &x.A1) // a+b @@ -74,7 +74,8 @@ func (z *{{.Fp2Name}}) Square(x *{{.Fp2Name}}) *{{.Fp2Name}} { {{- if eq .Fp2NonResidue "5"}} z.A0.Add(&ab, &z.A1).Double(&z.A0) // (5+1)*ab, optimize for quadratic nonresidue 5 {{- else}} - MulByNonResidue(&z.A0, &ab).AddAssign(&ab) // ({{.Fp2NonResidue}}+1)*ab + {{- template "fpInlineMulByNonResidue" dict "all" . "out" "&z.A0" "in" "&ab" }} + z.A0.AddAssign(&ab) // ({{.Fp2NonResidue}}+1)*ab {{- end }} z.A0.Sub(&ababetab, &z.A0) // z.A0: [2] - ({{.Fp2NonResidue}}+1)[1] {{- end }} @@ -82,15 +83,6 @@ func (z *{{.Fp2Name}}) Square(x *{{.Fp2Name}}) *{{.Fp2Name}} { return z } -// MulByNonSquare multiplies an element by (0,1) -// TODO deprecate in favor of inlined MulByNonResidue in fp6 package -func (z *{{.Fp2Name}}) MulByNonSquare(x *{{.Fp2Name}}) *{{.Fp2Name}} { - a := x.A0 - MulByNonResidue(&z.A0, &x.A1) - z.A1 = a - return z -} - // Inverse sets z to the {{.Fp2Name}}-inverse of x, returns z func (z *{{.Fp2Name}}) Inverse(x *{{.Fp2Name}}) *{{.Fp2Name}} { // Algorithm 8 from https://eprint.iacr.org/2010/354.pdf @@ -109,7 +101,7 @@ func (z *{{.Fp2Name}}) Inverse(x *{{.Fp2Name}}) *{{.Fp2Name}} { {{- if eq .Fp2NonResidue "-1" }} t0.Add(&t0, &t1) // step 3 {{- else }} - MulByNonResidue(&t1beta, &t1) + {{- template "fpInlineMulByNonResidue" dict "all" . "out" "&t1beta" "in" "&t1" }} t0.SubAssign(&t1beta) // step 3 {{- end }} t1.Inverse(&t0) // step 4 @@ -134,18 +126,4 @@ func (z *{{.Fp2Name}}) Conjugate(x *{{.Fp2Name}}) *{{.Fp2Name}} { z.A1.Neg(&x.A1) return z } - -// MulByNonResidue multiplies a fp.Element by {{.Fp2NonResidue}} -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidue(out, in *fp.Element) *fp.Element { - {{- template "fpMulByNonResidueBody" dict "all" . "out" "out" "in" "in" }} - return out -} - -// MulByNonResidueInv multiplies a fp.Element by {{.Fp2NonResidue}}^{-1} -// It would be nice to make this a method of fp.Element but fp.Element is outside this package -func MulByNonResidueInv(out, in *fp.Element) *fp.Element { - {{- template "fpMulByNonResidueInvBody" dict "all" . "out" "out" "in" "in" }} - return out -} ` diff --git a/internal/generators/tower/templates/fp6/inline.go b/internal/generators/tower/templates/fp6/inline.go index fe85b61e6..e079cc8da 100644 --- a/internal/generators/tower/templates/fp6/inline.go +++ b/internal/generators/tower/templates/fp6/inline.go @@ -4,106 +4,30 @@ package fp6 const Inline = ` {{- define "fp2InlineMulByNonResidue" }} - { // begin: inline {{$.out}}.MulByNonResidue({{$.in}}) - {{- template "fp2MulByNonResidueBody" dict "all" $.all "out" $.out "in" $.in }} - } // end: inline {{$.out}}.MulByNonResidue({{$.in}}) -{{- end }} - -{{- define "fp2MulByNonResidueBody" }} - {{- if eq $.all.Fp6NonResidue "0,1" }} - buf := ({{$.in}}).A0 - {{- template "fpInlineMulByNonResidue" dict "all" $.all "out" (print "&(" $.out ").A0") "in" (print "&(" $.in ").A1") }} - ({{$.out}}).A1 = buf - {{- else if eq $.all.Fp6NonResidue "1,1"}} - var buf {{$.all.Fp2Name}} - buf.Set({{$.in}}) - {{$.out}}.A1.Add(&buf.A0, &buf.A1) - {{- template "fpInlineMulByNonResidue" dict "all" $.all "out" (print "&(" $.out ").A0") "in" "&buf.A1" }} - {{$.out}}.A0.AddAssign(&buf.A0) - {{- else if eq $.all.Fp6NonResidue "9,1"}} - var buf, buf9 {{$.all.Fp2Name}} - buf.Set({{$.in}}) - buf9.Double(&buf). - Double(&buf9). - Double(&buf9). - Add(&buf9, &buf) - {{$.out}}.A1.Add(&buf.A0, &buf9.A1) - {{- template "fpInlineMulByNonResidue" dict "all" $.all "out" (print "&(" $.out ").A0") "in" "&buf.A1" }} - {{$.out}}.A0.AddAssign(&buf9.A0) - {{- else}} - // TODO not implemented - {{- end }} -{{- end }} - -{{- define "fp2InlineMulByNonResidueInv" }} - { // begin: inline {{$.out}}.MulByNonResidueInv({{$.in}}) - {{- template "fp2MulByNonResidueInvBody" dict "all" $.all "out" $.out "in" $.in }} - } // end: inline {{$.out}}.MulByNonResidueInv({{$.in}}) -{{- end }} - -{{- define "fp2MulByNonResidueInvBody" }} - {{- if eq $.all.Fp6NonResidue "0,1" }} - buf := ({{$.in}}).A1 - {{- template "fpInlineMulByNonResidueInv" dict "all" $.all "out" (print "&(" $.out ").A1") "in" (print "&(" $.in ").A0") }} - ({{$.out}}).A0 = buf - {{- else if (and (eq $.all.Fp6NonResidue "1,1") (eq $.all.Fp2NonResidue "-1")) }} - // ({{$.out}}).A0 = (({{$.in}}).A0 + ({{$.in}}).A1)/2 - // ({{$.out}}).A1 = (({{$.in}}).A1 - ({{$.in}}).A0)/2 - buf := *({{$.in}}) - ({{$.out}}).A0.Add(&buf.A0, &buf.A1) - ({{$.out}}).A1.Sub(&buf.A1, &buf.A0) - twoInv := fp.Element{ - {{- range $i := .all.TwoInv}} - {{$i}},{{end}} - } - ({{$.out}}).A0.MulAssign(&twoInv) - ({{$.out}}).A1.MulAssign(&twoInv) - {{- else if (and (eq $.all.Fp6NonResidue "9,1") (eq $.all.Fp2NonResidue "-1")) }} - // ({{$.out}}).A0 = (9*({{$.in}}).A0 + ({{$.in}}).A1)/82 - // ({{$.out}}).A1 = (9*({{$.in}}).A1 - ({{$.in}}).A0)/82 - copy := *({{$.in}}) - - var copy9 E2 - copy9.Double(©). - Double(©9). - Double(©9). - AddAssign(©) - - ({{$.out}}).A0.Add(©9.A0, ©.A1) - ({{$.out}}).A1.Sub(©9.A1, ©.A0) - - buf82inv := fp.Element{ - 15263610803691847034, - 14617516054323294413, - 1961223913490700324, - 3456812345740674661, - } - ({{$.out}}).A0.MulAssign(&buf82inv) - ({{$.out}}).A1.MulAssign(&buf82inv) - {{- else if (and (eq $.all.Fp6NonResidue "9,1") (eq $.all.Fp2NonResidue "3")) }} - // ({{$.out}}).A0 = (9*({{$.in}}).A0 - 3*({{$.in}}).A1)/78 - // ({{$.out}}).A1 = (9*({{$.in}}).A1 - ({{$.in}}).A0)/78 - copy := *({{$.in}}) - - var copy9 E2 - copy9.Double(©). - Double(©9). - Double(©9). - AddAssign(©) - - var copy3A1 fp.Element - copy3A1.Double(©.A1). - AddAssign(©.A1) - - ({{$.out}}).A0.Sub(©9.A0, ©3A1) - ({{$.out}}).A1.Sub(©9.A1, ©.A0) - - var buf78inv fp.Element - buf78inv.SetUint64(78).Inverse(&buf78inv) // TODO hardcode - ({{$.out}}).A0.MulAssign(&buf78inv) - ({{$.out}}).A1.MulAssign(&buf78inv) - {{- else}} - // TODO not implemented - {{- end }} + { // begin inline: set {{.out}} to ({{.in}}) * ({{.all.Fp6NonResidue}}) + {{- if eq .all.Fp6NonResidue "0,1" }} + buf := ({{.in}}).A0 + {{- template "fpInlineMulByNonResidue" dict "all" .all "out" (print "&(" .out ").A0") "in" (print "&(" .in ").A1") }} + ({{.out}}).A1 = buf + {{- else if eq .all.Fp6NonResidue "1,1"}} + var buf {{.all.Fp2Name}} + buf.Set({{.in}}) + {{.out}}.A1.Add(&buf.A0, &buf.A1) + {{- template "fpInlineMulByNonResidue" dict "all" .all "out" (print "&(" .out ").A0") "in" "&buf.A1" }} + {{.out}}.A0.AddAssign(&buf.A0) + {{- else if eq .all.Fp6NonResidue "9,1"}} + var buf, buf9 {{.all.Fp2Name}} + buf.Set({{.in}}) + buf9.Double(&buf). + Double(&buf9). + Double(&buf9). + Add(&buf9, &buf) + {{.out}}.A1.Add(&buf.A0, &buf9.A1) + {{- template "fpInlineMulByNonResidue" dict "all" .all "out" (print "&(" .out ").A0") "in" "&buf.A1" }} + {{.out}}.A0.AddAssign(&buf9.A0) + {{- else}} + panic("not implemented") + {{- end }} + } // end inline: set {{.out}} to ({{.in}}) * ({{.all.Fp6NonResidue}}) {{- end }} ` diff --git a/internal/generators/tower/templates/fp6/mul.go b/internal/generators/tower/templates/fp6/mul.go index 937f2b3f7..dfa4d438f 100644 --- a/internal/generators/tower/templates/fp6/mul.go +++ b/internal/generators/tower/templates/fp6/mul.go @@ -58,6 +58,7 @@ func (z *{{.Fp6Name}}) MulBy{{capitalize .Fp2Name}}(x *{{.Fp6Name}}, y *{{.Fp2Na return z } +{{- /* MulByNotv2 is no longer used // MulByNotv2 multiplies x by y with &y.b2=0 func (z *{{.Fp6Name}}) MulByNotv2(x, y *{{.Fp6Name}}) *{{.Fp6Name}} { // Algorithm 15 from https://eprint.iacr.org/2010/354.pdf @@ -82,6 +83,7 @@ func (z *{{.Fp6Name}}) MulByNotv2(x, y *{{.Fp6Name}}) *{{.Fp6Name}} { z.B0 = rb0 return z } +*/}} // Square sets z to the {{.Fp6Name}}-product of x,x, returns z func (z *{{.Fp6Name}}) Square(x *{{.Fp6Name}}) *{{.Fp6Name}} { @@ -191,14 +193,4 @@ func (z *{{.Fp6Name}}) Inverse(x *{{.Fp6Name}}) *{{.Fp6Name}} { z.B2.Mul(&c[2], &t[6]) // step 16 return z } -// MulByNonResidue multiplies a {{.Fp2Name}} by ({{.Fp6NonResidue}}) -func (z *{{.Fp2Name}}) MulByNonResidue(x *{{.Fp2Name}}) *{{.Fp2Name}} { - {{- template "fp2MulByNonResidueBody" dict "all" . "out" "z" "in" "x" }} - return z -} -// MulByNonResidueInv multiplies a {{.Fp2Name}} by ({{.Fp6NonResidue}})^{-1} -func (z *{{.Fp2Name}}) MulByNonResidueInv(x *{{.Fp2Name}}) *{{.Fp2Name}} { - {{- template "fp2MulByNonResidueInvBody" dict "all" . "out" "z" "in" "x" }} - return z -} `