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 }