github.com/hellobchain/newcryptosm@v0.0.0-20221019060107-edb949a317e9/sm9/gfp12.go (about)

     1  package sm9
     2  
     3  // For details of the algorithms used, see "Multiplication and Squaring on
     4  // Pairing-Friendly Fields, Devegili et al.
     5  // http://eprint.iacr.org/2006/471.pdf.
     6  
     7  import (
     8  	"math/big"
     9  )
    10  
    11  // gfP12 implements the field of size p¹² as a quadratic extension of gfP6
    12  // where ω²=τ.
    13  type gfP12 struct {
    14  	x, y gfP6 // value is xω + y
    15  }
    16  
    17  var gfP12Gen *gfP12 = &gfP12{
    18  	x: gfP6{
    19  		x: gfP2{
    20  			x: gfP{0xeb2aeaa2823d010c, 0xe192c39d7c3e6440, 0x68411e843fea2a9b, 0x5f23b1ce3ac438e7},
    21  			y: gfP{0x065c1ad6d376db4f, 0xe2447d6d5edfdda6, 0x0d4eba5c8c017781, 0x61ebca2110d736bf},
    22  		},
    23  		y: gfP2{
    24  			x: gfP{0xc219536a54552cae, 0xc4e4ad66027f8f55, 0xff31b23d5bc78184, 0x3b0fc03d5711c93d},
    25  			y: gfP{0x290e1c8bdb9441aa, 0x074e1694c800c130, 0xfa196a2583564700, 0x254eb32dea84e64d},
    26  		},
    27  		z: gfP2{
    28  			x: gfP{0x24fb5abe38626c9c, 0xd32d71f71d7bd3de, 0x671d686fd9c9271d, 0xa3eec3cd6a795be8},
    29  			y: gfP{0x7b9c733c1f964b52, 0x9b988c0c238fb05e, 0xe546ccb8d6e1f9b8, 0xb101d668bfbf8ac8},
    30  		},
    31  	},
    32  	y: gfP6{
    33  		x: gfP2{
    34  			x: gfP{0x487ab1a6229d91f3, 0x7e2a3e36c6c822c7, 0x282c24f00c10930f, 0x2efe33f18332bb77},
    35  			y: gfP{0x346965f4dc5b5813, 0xed43ed38c0ce33e6, 0x9ba7630e295a5ce7, 0xa6db7142e0ca24ae},
    36  		},
    37  		y: gfP2{
    38  			x: gfP{0xfea0bce10965b32b, 0x441e074b4573390c, 0xe9d6067a4cf3c571, 0x9ee43c7e3740bcd8},
    39  			y: gfP{0x0e06727b47ee6118, 0xb01ab631f2f10a18, 0xb0ebd9852fc780ef, 0xaa07010f9d42787c},
    40  		},
    41  		z: gfP2{
    42  			x: gfP{0xbe7381e2bce90a00, 0x2a72158dbf514e31, 0x44e199bee3498d4d, 0x6a5fed210720de58},
    43  			y: gfP{0xb55d63ee8d7a8468, 0x9ef5d413e3176666, 0x796c802ec3f1370b, 0xa0f422c35d7b6262},
    44  		},
    45  	},
    46  }
    47  
    48  func (e *gfP12) String() string {
    49  	return "(" + e.x.String() + "," + e.y.String() + ")"
    50  }
    51  
    52  func (e *gfP12) Set(a *gfP12) *gfP12 {
    53  	e.x.Set(&a.x)
    54  	e.y.Set(&a.y)
    55  	return e
    56  }
    57  
    58  func (e *gfP12) SetZero() *gfP12 {
    59  	e.x.SetZero()
    60  	e.y.SetZero()
    61  	return e
    62  }
    63  
    64  func (e *gfP12) SetOne() *gfP12 {
    65  	e.x.SetZero()
    66  	e.y.SetOne()
    67  	return e
    68  }
    69  
    70  func (e *gfP12) IsZero() bool {
    71  	return e.x.IsZero() && e.y.IsZero()
    72  }
    73  
    74  func (e *gfP12) IsOne() bool {
    75  	return e.x.IsZero() && e.y.IsOne()
    76  }
    77  
    78  func (e *gfP12) Conjugate(a *gfP12) *gfP12 {
    79  	e.x.Neg(&a.x)
    80  	e.y.Set(&a.y)
    81  	return e
    82  }
    83  
    84  func (e *gfP12) Neg(a *gfP12) *gfP12 {
    85  	e.x.Neg(&a.x)
    86  	e.y.Neg(&a.y)
    87  	return e
    88  }
    89  
    90  // Frobenius computes (xω+y)^p = x^p ω·ξ^((p-1)/6) + y^p
    91  func (e *gfP12) Frobenius(a *gfP12) *gfP12 {
    92  	e.x.Frobenius(&a.x)
    93  	e.y.Frobenius(&a.y)
    94  	e.x.MulScalar(&e.x, xiToPMinus1Over6)
    95  	return e
    96  }
    97  
    98  // FrobeniusP2 computes (xω+y)^p² = x^p² ω·ξ^((p²-1)/6) + y^p²
    99  func (e *gfP12) FrobeniusP2(a *gfP12) *gfP12 {
   100  	e.x.FrobeniusP2(&a.x)
   101  	e.x.MulGFP(&e.x, xiToPSquaredMinus1Over6)
   102  	e.y.FrobeniusP2(&a.y)
   103  	return e
   104  }
   105  
   106  func (e *gfP12) FrobeniusP4(a *gfP12) *gfP12 {
   107  	e.x.FrobeniusP4(&a.x)
   108  	e.x.MulGFP(&e.x, xiToPSquaredMinus1Over3)
   109  	e.y.FrobeniusP4(&a.y)
   110  	return e
   111  }
   112  
   113  func (e *gfP12) Add(a, b *gfP12) *gfP12 {
   114  	e.x.Add(&a.x, &b.x)
   115  	e.y.Add(&a.y, &b.y)
   116  	return e
   117  }
   118  
   119  func (e *gfP12) Sub(a, b *gfP12) *gfP12 {
   120  	e.x.Sub(&a.x, &b.x)
   121  	e.y.Sub(&a.y, &b.y)
   122  	return e
   123  }
   124  
   125  func (e *gfP12) Mul1(a, b *gfP12) *gfP12 {
   126  	tx := (&gfP6{}).Mul(&a.x, &b.y)
   127  	t := (&gfP6{}).Mul(&b.x, &a.y)
   128  	tx.Add(tx, t)
   129  
   130  	ty := (&gfP6{}).Mul(&a.y, &b.y)
   131  	t.Mul(&a.x, &b.x).MulTau(t)
   132  
   133  	e.x.Set(tx)
   134  	e.y.Add(ty, t)
   135  	return e
   136  }
   137  func (e *gfP12) Mul(a, b *gfP12) *gfP12 { //lazy reduction;1113version;
   138  
   139  	t0, t1, t2, t3 := &gfP6{}, &gfP6{}, &gfP6{}, &gfP6{}
   140  	t0.Add(&a.x, &a.y)
   141  	t1.Add(&b.x, &b.y)
   142  	t2.Mul(&a.x, &b.x)
   143  	t3.Mul(&a.y, &b.y)
   144  
   145  	t0.Mul(t0, t1)
   146  	t0.Sub(t0, t2)
   147  	t0.Sub(t0, t3)
   148  
   149  	t2.MulTau(t2)
   150  	t3.Add(t3, t2)
   151  
   152  	e.x.Set(t0)
   153  	e.y.Set(t3)
   154  	return e
   155  }
   156  
   157  func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 {
   158  	e.x.Mul(&e.x, b)
   159  	e.y.Mul(&e.y, b)
   160  	return e
   161  }
   162  
   163  func (c *gfP12) Exp(a *gfP12, power *big.Int) *gfP12 {
   164  	sum := (&gfP12{}).SetOne()
   165  	t := &gfP12{}
   166  
   167  	for i := power.BitLen() - 1; i >= 0; i-- {
   168  		t.Square(sum)
   169  		if power.Bit(i) != 0 {
   170  			sum.Mul(t, a)
   171  		} else {
   172  			sum.Set(t)
   173  		}
   174  	}
   175  
   176  	c.Set(sum)
   177  	return c
   178  }
   179  
   180  func (e *gfP12) Square(a *gfP12) *gfP12 {
   181  	// Complex squaring algorithm
   182  	v0 := (&gfP6{}).Mul(&a.x, &a.y)
   183  
   184  	t := (&gfP6{}).MulTau(&a.x)
   185  	t.Add(&a.y, t)
   186  	ty := (&gfP6{}).Add(&a.x, &a.y)
   187  	ty.Mul(ty, t).Sub(ty, v0)
   188  	t.MulTau(v0)
   189  	ty.Sub(ty, t)
   190  
   191  	e.x.Add(v0, v0)
   192  	e.y.Set(ty)
   193  	return e
   194  }
   195  
   196  func (e *gfP12) Square1(a *gfP12) *gfP12 { //not faster;1115
   197  	v0 := (&gfP6{}).Square(&a.x)
   198  	v1 := (&gfP6{}).Square(&a.y)
   199  	v2 := (&gfP6{}).Add(&a.x, &a.y)
   200  	v2.Square(v2)
   201  
   202  	e.x.Sub(v2, v0)
   203  	e.x.Sub(v2, v1)
   204  
   205  	v0.MulTau(v0)
   206  	v0.Add(v0, v1)
   207  	e.y.Set(v0)
   208  
   209  	return e
   210  }
   211  
   212  func (e *gfP12) Invert(a *gfP12) *gfP12 {
   213  	// See "Implementing cryptographic pairings", M. Scott, section 3.2.
   214  	// ftp://136.206.11.249/pub/crypto/pairings.pdf
   215  	t1, t2 := &gfP6{}, &gfP6{}
   216  
   217  	t1.Square(&a.x)
   218  	t2.Square(&a.y)
   219  	t1.MulTau(t1).Sub(t2, t1)
   220  	t2.Invert(t1)
   221  
   222  	e.x.Neg(&a.x)
   223  	e.y.Set(&a.y)
   224  	e.MulScalar(e, t2)
   225  	return e
   226  }