github.com/emmansun/gmsm@v0.29.1/sm9/bn256/gfp12_b6.go (about)

     1  package bn256
     2  
     3  import "math/big"
     4  
     5  // gfP12b6 implements the field of size p¹² as a quadratic extension of gfP6
     6  // where t²=s.
     7  type gfP12b6 struct {
     8  	x, y gfP6 // value is xt + y
     9  }
    10  
    11  func gfP12b6Decode(in *gfP12b6) *gfP12b6 {
    12  	out := &gfP12b6{}
    13  	out.x = *gfP6Decode(&in.x)
    14  	out.y = *gfP6Decode(&in.y)
    15  	return out
    16  }
    17  
    18  var gfP12b6Gen *gfP12b6 = &gfP12b6{
    19  	x: gfP6{
    20  		x: gfP2{
    21  			x: *fromBigInt(bigFromHex("256943fbdb2bf87ab91ae7fbeaff14e146cf7e2279b9d155d13461e09b22f523")),
    22  			y: *fromBigInt(bigFromHex("0167b0280051495c6af1ec23ba2cd2ff1cdcdeca461a5ab0b5449e9091308310")),
    23  		},
    24  		y: gfP2{
    25  			x: *fromBigInt(bigFromHex("8ffe1c0e9de45fd0fed790ac26be91f6b3f0a49c084fe29a3fb6ed288ad7994d")),
    26  			y: *fromBigInt(bigFromHex("1664a1366beb3196f0443e15f5f9042a947354a5678430d45ba031cff06db927")),
    27  		},
    28  		z: gfP2{
    29  			x: *fromBigInt(bigFromHex("7fc6eb2aa771d99c9234fddd31752edfd60723e05a4ebfdeb5c33fbd47e0cf06")),
    30  			y: *fromBigInt(bigFromHex("6fa6b6fa6dd6b6d3b19a959a110e748154eef796dc0fc2dd766ea414de786968")),
    31  		},
    32  	},
    33  	y: gfP6{
    34  		x: gfP2{
    35  			x: *fromBigInt(bigFromHex("082cde173022da8cd09b28a2d80a8cee53894436a52007f978dc37f36116d39b")),
    36  			y: *fromBigInt(bigFromHex("3fa7ed741eaed99a58f53e3df82df7ccd3407bcc7b1d44a9441920ced5fb824f")),
    37  		},
    38  		y: gfP2{
    39  			x: *fromBigInt(bigFromHex("5e7addaddf7fbfe16291b4e89af50b8217ddc47ba3cba833c6e77c3fb027685e")),
    40  			y: *fromBigInt(bigFromHex("79d0c8337072c93fef482bb055f44d6247ccac8e8e12525854b3566236337ebe")),
    41  		},
    42  		z: gfP2{
    43  			x: *fromBigInt(bigFromHex("7f7c6d52b475e6aaa827fdc5b4175ac6929320f782d998f86b6b57cda42a0426")),
    44  			y: *fromBigInt(bigFromHex("36a699de7c136f78eee2dbac4ca9727bff0cee02ee920f5822e65ea170aa9669")),
    45  		},
    46  	},
    47  }
    48  
    49  func (e *gfP12b6) String() string {
    50  	return "(" + e.x.String() + "," + e.y.String() + ")"
    51  }
    52  
    53  func (e *gfP12b6) ToGfP12() *gfP12 {
    54  	ret := &gfP12{}
    55  
    56  	ret.z.y.Set(&e.y.z)
    57  	ret.x.y.Set(&e.y.y)
    58  	ret.y.x.Set(&e.y.x)
    59  	ret.y.y.Set(&e.x.z)
    60  	ret.z.x.Set(&e.x.y)
    61  	ret.x.x.Set(&e.x.x)
    62  
    63  	return ret
    64  }
    65  
    66  func (e *gfP12b6) SetGfP12(a *gfP12) *gfP12b6 {
    67  	e.y.z.Set(&a.z.y) //a
    68  	e.y.y.Set(&a.x.y) //b
    69  	e.y.x.Set(&a.y.x)
    70  	e.x.z.Set(&a.y.y)
    71  	e.x.y.Set(&a.z.x) //c
    72  	e.x.x.Set(&a.x.x)
    73  
    74  	return e
    75  }
    76  
    77  func (e *gfP12b6) Set(a *gfP12b6) *gfP12b6 {
    78  	e.x.Set(&a.x)
    79  	e.y.Set(&a.y)
    80  	return e
    81  }
    82  
    83  func (e *gfP12b6) SetZero() *gfP12b6 {
    84  	e.x.SetZero()
    85  	e.y.SetZero()
    86  	return e
    87  }
    88  
    89  func (e *gfP12b6) SetOne() *gfP12b6 {
    90  	e.x.SetZero()
    91  	e.y.SetOne()
    92  	return e
    93  }
    94  
    95  func (e *gfP12b6) IsZero() bool {
    96  	return e.x.IsZero() && e.y.IsZero()
    97  }
    98  
    99  func (e *gfP12b6) IsOne() bool {
   100  	return e.x.IsZero() && e.y.IsOne()
   101  }
   102  
   103  func (e *gfP12b6) Neg(a *gfP12b6) *gfP12b6 {
   104  	e.x.Neg(&a.x)
   105  	e.y.Neg(&a.y)
   106  	return e
   107  }
   108  
   109  func (e *gfP12b6) Conjugate(a *gfP12b6) *gfP12b6 {
   110  	e.x.Neg(&a.x)
   111  	e.y.Set(&a.y)
   112  	return e
   113  }
   114  
   115  func (e *gfP12b6) Add(a, b *gfP12b6) *gfP12b6 {
   116  	e.x.Add(&a.x, &b.x)
   117  	e.y.Add(&a.y, &b.y)
   118  	return e
   119  }
   120  
   121  func (e *gfP12b6) Sub(a, b *gfP12b6) *gfP12b6 {
   122  	e.x.Sub(&a.x, &b.x)
   123  	e.y.Sub(&a.y, &b.y)
   124  	return e
   125  }
   126  
   127  func (e *gfP12b6) Mul(a, b *gfP12b6) *gfP12b6 {
   128  	tmp := &gfP12b6{}
   129  	tmp.MulNC(a, b)
   130  	e.x.Set(&tmp.x)
   131  	e.y.Set(&tmp.y)
   132  	return e
   133  }
   134  
   135  // Mul without value copy, will use e directly, so e can't be same as a and b.
   136  func (e *gfP12b6) MulNC(a, b *gfP12b6) *gfP12b6 {
   137  	// "Multiplication and Squaring on Pairing-Friendly Fields"
   138  	// Section 4, Karatsuba method.
   139  	// http://eprint.iacr.org/2006/471.pdf
   140  	//(a0+a1*t)(b0+b1*t)=c0+c1*t, where
   141  	//c0 = a0*b0 +a1*b1*s
   142  	//c1 = (a0 + a1)(b0 + b1) - a0*b0 - a1*b1 = a0*b1 + a1*b0
   143  	tx := &e.x
   144  	ty := &e.y
   145  	v0, v1 := &gfP6{}, &gfP6{}
   146  	v0.MulNC(&a.y, &b.y)
   147  	v1.MulNC(&a.x, &b.x)
   148  
   149  	tx.Add(&a.x, &a.y)
   150  	ty.Add(&b.x, &b.y)
   151  	tx.Mul(tx, ty)
   152  	tx.Sub(tx, v0)
   153  	tx.Sub(tx, v1)
   154  
   155  	ty.MulS(v1)
   156  	ty.Add(ty, v0)
   157  
   158  	return e
   159  }
   160  
   161  func (e *gfP12b6) MulScalar(a *gfP12b6, b *gfP6) *gfP12b6 {
   162  	e.x.Mul(&a.x, b)
   163  	e.y.Mul(&a.y, b)
   164  	return e
   165  }
   166  
   167  func (e *gfP12b6) MulGfP(a *gfP12b6, b *gfP) *gfP12b6 {
   168  	e.x.MulGfP(&a.x, b)
   169  	e.y.MulGfP(&a.y, b)
   170  	return e
   171  }
   172  
   173  func (e *gfP12b6) MulGfP2(a *gfP12b6, b *gfP2) *gfP12b6 {
   174  	e.x.MulScalar(&a.x, b)
   175  	e.y.MulScalar(&a.y, b)
   176  	return e
   177  }
   178  
   179  func (e *gfP12b6) Square(a *gfP12b6) *gfP12b6 {
   180  	tmp := &gfP12b6{}
   181  	tmp.SquareNC(a)
   182  	e.x.Set(&tmp.x)
   183  	e.y.Set(&tmp.y)
   184  	return e
   185  }
   186  
   187  // Square without value copy, will use e directly, so e can't be same as a.
   188  func (e *gfP12b6) SquareNC(a *gfP12b6) *gfP12b6 {
   189  	// Complex squaring algorithm
   190  	// (xt+y)² = (x^2*s + y^2) + 2*x*y*t
   191  	tx := &e.x
   192  	ty := &e.y
   193  
   194  	tx.SquareNC(&a.x).MulS(tx)
   195  	ty.SquareNC(&a.y)
   196  	ty.Add(tx, ty)
   197  
   198  	tx.Mul(&a.x, &a.y)
   199  	tx.Add(tx, tx)
   200  
   201  	return e
   202  }
   203  
   204  // Cyclo6Square is used in final exponentiation after easy part(a ^ ((p^2 + 1)(p^6-1))).
   205  // Note that after the easy part of the final exponentiation, 
   206  // the resulting element lies in cyclotomic subgroup. 
   207  // "New software speed records for cryptographic pairings"
   208  // Section 3.3, Final exponentiation
   209  // https://cryptojedi.org/papers/dclxvi-20100714.pdf
   210  // The fomula reference:
   211  // Granger/Scott (PKC2010). 
   212  // Section 3.2
   213  // https://eprint.iacr.org/2009/565.pdf
   214  func (e *gfP12b6) Cyclo6Square(a *gfP12b6) *gfP12b6 {
   215  	tmp := &gfP12b6{}
   216  	tmp.Cyclo6SquareNC(a)
   217  	e.x.Set(&tmp.x)
   218  	e.y.Set(&tmp.y)
   219  	return e
   220  }
   221  
   222  // Special Square without value copy, will use e directly, so e can't be same as a.
   223  func (e *gfP12b6) Cyclo6SquareNC(a *gfP12b6) *gfP12b6 {
   224  	f02 := &e.y.x
   225  	f01 := &e.y.y
   226  	f00 := &e.y.z
   227  	f12 := &e.x.x
   228  	f11 := &e.x.y
   229  	f10 := &e.x.z
   230  
   231  	t00, t01, t02, t10, t11, t12 := &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}
   232  
   233  	gfP4Square(t11, t00, &a.x.y, &a.y.z)
   234  	gfP4Square(t12, t01, &a.y.x, &a.x.z)
   235  	gfP4Square(t02, t10, &a.x.x, &a.y.y)
   236  
   237  	f00.MulU1(t02)
   238  	t02.Set(t10)
   239  	t10.Set(f00)
   240  
   241  	f00.Add(t00, t00)
   242  	t00.Add(f00, t00)
   243  	f00.Add(t01, t01)
   244  	t01.Add(f00, t01)
   245  	f00.Add(t02, t02)
   246  	t02.Add(f00, t02)
   247  	f00.Add(t10, t10)
   248  	t10.Add(f00, t10)
   249  	f00.Add(t11, t11)
   250  	t11.Add(f00, t11)
   251  	f00.Add(t12, t12)
   252  	t12.Add(f00, t12)
   253  
   254  	f00.Add(&a.y.z, &a.y.z)
   255  	f00.Neg(f00)
   256  	f01.Add(&a.y.y, &a.y.y)
   257  	f01.Neg(f01)
   258  	f02.Add(&a.y.x, &a.y.x)
   259  	f02.Neg(f02)
   260  	f10.Add(&a.x.z, &a.x.z)
   261  	f11.Add(&a.x.y, &a.x.y)
   262  	f12.Add(&a.x.x, &a.x.x)
   263  
   264  	f00.Add(f00, t00)
   265  	f01.Add(f01, t01)
   266  	f02.Add(f02, t02)
   267  	f10.Add(f10, t10)
   268  	f11.Add(f11, t11)
   269  	f12.Add(f12, t12)
   270  
   271  	return e
   272  }
   273  
   274  func (e *gfP12b6) Cyclo6Squares(a *gfP12b6, n int) *gfP12b6 {
   275  	// Square first round
   276  	in := &gfP12b6{}
   277  	f02 := &in.y.x
   278  	f01 := &in.y.y
   279  	f00 := &in.y.z
   280  	f12 := &in.x.x
   281  	f11 := &in.x.y
   282  	f10 := &in.x.z
   283  
   284  	t00, t01, t02, t10, t11, t12 := &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}, &gfP2{}
   285  	gfP4Square(t11, t00, &a.x.y, &a.y.z)
   286  	gfP4Square(t12, t01, &a.y.x, &a.x.z)
   287  	gfP4Square(t02, t10, &a.x.x, &a.y.y)
   288  
   289  	f00.MulU1(t02)
   290  	t02.Set(t10)
   291  	t10.Set(f00)
   292  
   293  	f00.Add(t00, t00)
   294  	t00.Add(f00, t00)
   295  	f00.Add(t01, t01)
   296  	t01.Add(f00, t01)
   297  	f00.Add(t02, t02)
   298  	t02.Add(f00, t02)
   299  	f00.Add(t10, t10)
   300  	t10.Add(f00, t10)
   301  	f00.Add(t11, t11)
   302  	t11.Add(f00, t11)
   303  	f00.Add(t12, t12)
   304  	t12.Add(f00, t12)
   305  
   306  	f00.Add(&a.y.z, &a.y.z)
   307  	f00.Neg(f00)
   308  	f01.Add(&a.y.y, &a.y.y)
   309  	f01.Neg(f01)
   310  	f02.Add(&a.y.x, &a.y.x)
   311  	f02.Neg(f02)
   312  	f10.Add(&a.x.z, &a.x.z)
   313  	f11.Add(&a.x.y, &a.x.y)
   314  	f12.Add(&a.x.x, &a.x.x)
   315  
   316  	f00.Add(f00, t00)
   317  	f01.Add(f01, t01)
   318  	f02.Add(f02, t02)
   319  	f10.Add(f10, t10)
   320  	f11.Add(f11, t11)
   321  	f12.Add(f12, t12)
   322  
   323  	tmp := &gfP12b6{}
   324  	var tmp2 *gfP12b6
   325  
   326  	for i := 1; i < n; i++ {
   327  		f02 = &tmp.y.x
   328  		f01 = &tmp.y.y
   329  		f00 = &tmp.y.z
   330  		f12 = &tmp.x.x
   331  		f11 = &tmp.x.y
   332  		f10 = &tmp.x.z
   333  
   334  		gfP4Square(t11, t00, &in.x.y, &in.y.z)
   335  		gfP4Square(t12, t01, &in.y.x, &in.x.z)
   336  		gfP4Square(t02, t10, &in.x.x, &in.y.y)
   337  	
   338  		f00.MulU1(t02)
   339  		t02.Set(t10)
   340  		t10.Set(f00)
   341  	
   342  		f00.Add(t00, t00)
   343  		t00.Add(f00, t00)
   344  		f00.Add(t01, t01)
   345  		t01.Add(f00, t01)
   346  		f00.Add(t02, t02)
   347  		t02.Add(f00, t02)
   348  		f00.Add(t10, t10)
   349  		t10.Add(f00, t10)
   350  		f00.Add(t11, t11)
   351  		t11.Add(f00, t11)
   352  		f00.Add(t12, t12)
   353  		t12.Add(f00, t12)
   354  	
   355  		f00.Add(&in.y.z, &in.y.z)
   356  		f00.Neg(f00)
   357  		f01.Add(&in.y.y, &in.y.y)
   358  		f01.Neg(f01)
   359  		f02.Add(&in.y.x, &in.y.x)
   360  		f02.Neg(f02)
   361  		f10.Add(&in.x.z, &in.x.z)
   362  		f11.Add(&in.x.y, &in.x.y)
   363  		f12.Add(&in.x.x, &in.x.x)
   364  	
   365  		f00.Add(f00, t00)
   366  		f01.Add(f01, t01)
   367  		f02.Add(f02, t02)
   368  		f10.Add(f10, t10)
   369  		f11.Add(f11, t11)
   370  		f12.Add(f12, t12)
   371  
   372  		// Switch references
   373  		tmp2 = in
   374  		in = tmp
   375  		tmp = tmp2
   376  	}
   377  	e.x.Set(&in.x)
   378  	e.y.Set(&in.y)
   379  	return e
   380  }
   381  
   382  func gfP4Square(retX, retY, x, y *gfP2) {
   383  	retX.SquareU(x)
   384  	retY.Square(y)
   385  	retY.Add(retX, retY)
   386  
   387  	retX.Mul(x, y)
   388  	retX.Add(retX, retX)
   389  }
   390  
   391  func (c *gfP12b6) Exp(a *gfP12b6, power *big.Int) *gfP12b6 {
   392  	sum := (&gfP12b6{}).SetOne()
   393  	t := &gfP12b6{}
   394  
   395  	for i := power.BitLen() - 1; i >= 0; i-- {
   396  		t.Square(sum)
   397  		if power.Bit(i) != 0 {
   398  			sum.Mul(t, a)
   399  		} else {
   400  			sum.Set(t)
   401  		}
   402  	}
   403  
   404  	c.Set(sum)
   405  	return c
   406  }
   407  
   408  func (e *gfP12b6) Invert(a *gfP12b6) *gfP12b6 {
   409  	// See "Implementing cryptographic pairings", M. Scott, section 3.2.
   410  	// ftp://136.206.11.249/pub/crypto/pairings.pdf
   411  
   412  	t0, t1 := &gfP6{}, &gfP6{}
   413  
   414  	t0.MulNC(&a.y, &a.y)
   415  	t1.MulNC(&a.x, &a.x).MulS(t1)
   416  	t0.Sub(t0, t1)
   417  	t0.Invert(t0)
   418  
   419  	e.x.Neg(&a.x)
   420  	e.y.Set(&a.y)
   421  	e.MulScalar(e, t0)
   422  
   423  	return e
   424  }
   425  
   426  // Frobenius computes (xt+y)^p
   427  // = x^p t^p + y^p
   428  // = x^p t^(p-1) t + y^p
   429  // = x^p s^((p-1)/2) t + y^p
   430  // sToPMinus1Over2
   431  func (e *gfP12b6) Frobenius(a *gfP12b6) *gfP12b6 {
   432  	e.x.Frobenius(&a.x)
   433  	e.y.Frobenius(&a.y)
   434  	e.x.MulGfP(&e.x, sToPMinus1Over2)
   435  	return e
   436  }
   437  
   438  // FrobeniusP2 computes (xt+y)^p² = x^p² t ·s^((p²-1)/2) + y^p²
   439  func (e *gfP12b6) FrobeniusP2(a *gfP12b6) *gfP12b6 {
   440  	e.x.FrobeniusP2(&a.x)
   441  	e.y.FrobeniusP2(&a.y)
   442  	e.x.MulGfP(&e.x, sToPSquaredMinus1Over2)
   443  	return e
   444  }
   445  
   446  func (e *gfP12b6) FrobeniusP4(a *gfP12b6) *gfP12b6 {
   447  	e.x.FrobeniusP4(&a.x)
   448  	e.y.FrobeniusP4(&a.y)
   449  	e.x.MulGfP(&e.x, sToPSquaredMinus1)
   450  	return e
   451  }
   452  
   453  func (e *gfP12b6) FrobeniusP6(a *gfP12b6) *gfP12b6 {
   454  	e.x.Neg(&a.x)
   455  	e.y.Set(&a.y)
   456  	return e
   457  }
   458  
   459  // Select sets q to p1 if cond == 1, and to p2 if cond == 0.
   460  func (q *gfP12b6) Select(p1, p2 *gfP12b6, cond int) *gfP12b6 {
   461  	q.x.Select(&p1.x, &p2.x, cond)
   462  	q.y.Select(&p1.y, &p2.y, cond)
   463  	return q
   464  }