github.com/emmansun/gmsm@v0.29.1/sm9/bn256/gt.go (about) 1 package bn256 2 3 import ( 4 "crypto/subtle" 5 "errors" 6 "io" 7 "math/big" 8 ) 9 10 // GT is an abstract cyclic group. The zero value is suitable for use as the 11 // output of an operation, but cannot be used as an input. 12 type GT struct { 13 p *gfP12 14 } 15 16 // RandomGT returns x and e(g₁, g₂)ˣ where x is a random, non-zero number read 17 // from r. 18 func RandomGT(r io.Reader) (*big.Int, *GT, error) { 19 k, err := randomK(r) 20 if err != nil { 21 return nil, nil, err 22 } 23 24 return k, new(GT).ScalarBaseMult(k), nil 25 } 26 27 // Pair calculates an R-Ate pairing. 28 func Pair(g1 *G1, g2 *G2) *GT { 29 return >{pairing(g2.p, g1.p)} 30 } 31 32 // Miller applies Miller's algorithm, which is a bilinear function from the 33 // source groups to F_p^12. Miller(g1, g2).Finalize() is equivalent to Pair(g1, 34 // g2). 35 func Miller(g1 *G1, g2 *G2) *GT { 36 return >{miller(g2.p, g1.p)} 37 } 38 39 func (g *GT) String() string { 40 return "sm9.GT" + g.p.String() 41 } 42 43 // ScalarBaseMult sets e to g*k where g is the generator of the group and then 44 // returns out. 45 func (e *GT) ScalarBaseMult(k *big.Int) *GT { 46 if e.p == nil { 47 e.p = &gfP12{} 48 } 49 e.p.Exp(gfP12Gen, k) 50 return e 51 } 52 53 // ScalarMult sets e to a*k and then returns e. 54 func (e *GT) ScalarMult(a *GT, k *big.Int) *GT { 55 if e.p == nil { 56 e.p = &gfP12{} 57 } 58 e.p.Exp(a.p, k) 59 return e 60 } 61 62 // Add sets e to a+b and then returns e. 63 func (e *GT) Add(a, b *GT) *GT { 64 if e.p == nil { 65 e.p = &gfP12{} 66 } 67 e.p.Mul(a.p, b.p) 68 return e 69 } 70 71 // Set sets e to a and then returns e. 72 func (e *GT) Set(a *GT) *GT { 73 if e.p == nil { 74 e.p = &gfP12{} 75 } 76 e.p.Set(a.p) 77 return e 78 } 79 80 // Set sets e to one and then returns e. 81 func (e *GT) SetOne() *GT { 82 if e.p == nil { 83 e.p = &gfP12{} 84 } 85 e.p.SetOne() 86 return e 87 } 88 89 // Finalize is a linear function from F_p^12 to GT. 90 func (e *GT) Finalize() *GT { 91 ret := finalExponentiation(e.p) 92 e.p.Set(ret) 93 return e 94 } 95 96 // Marshal converts e into a byte slice. 97 func (e *GT) Marshal() []byte { 98 // Each value is a 256-bit number. 99 const numBytes = 256 / 8 100 101 ret := make([]byte, numBytes*12) 102 temp := &gfP{} 103 104 montDecode(temp, &e.p.x.x.x) 105 temp.Marshal(ret) 106 montDecode(temp, &e.p.x.x.y) 107 temp.Marshal(ret[numBytes:]) 108 montDecode(temp, &e.p.x.y.x) 109 temp.Marshal(ret[2*numBytes:]) 110 montDecode(temp, &e.p.x.y.y) 111 temp.Marshal(ret[3*numBytes:]) 112 113 montDecode(temp, &e.p.y.x.x) 114 temp.Marshal(ret[4*numBytes:]) 115 montDecode(temp, &e.p.y.x.y) 116 temp.Marshal(ret[5*numBytes:]) 117 montDecode(temp, &e.p.y.y.x) 118 temp.Marshal(ret[6*numBytes:]) 119 montDecode(temp, &e.p.y.y.y) 120 temp.Marshal(ret[7*numBytes:]) 121 122 montDecode(temp, &e.p.z.x.x) 123 temp.Marshal(ret[8*numBytes:]) 124 montDecode(temp, &e.p.z.x.y) 125 temp.Marshal(ret[9*numBytes:]) 126 montDecode(temp, &e.p.z.y.x) 127 temp.Marshal(ret[10*numBytes:]) 128 montDecode(temp, &e.p.z.y.y) 129 temp.Marshal(ret[11*numBytes:]) 130 131 return ret 132 } 133 134 // Unmarshal sets e to the result of converting the output of Marshal back into 135 // a group element and then returns e. 136 func (e *GT) Unmarshal(m []byte) ([]byte, error) { 137 // Each value is a 256-bit number. 138 const numBytes = 256 / 8 139 140 if len(m) < 12*numBytes { 141 return nil, errors.New("sm9.GT: not enough data") 142 } 143 144 if e.p == nil { 145 e.p = &gfP12{} 146 } 147 148 var err error 149 if err = e.p.x.x.x.Unmarshal(m); err != nil { 150 return nil, err 151 } 152 if err = e.p.x.x.y.Unmarshal(m[numBytes:]); err != nil { 153 return nil, err 154 } 155 if err = e.p.x.y.x.Unmarshal(m[2*numBytes:]); err != nil { 156 return nil, err 157 } 158 if err = e.p.x.y.y.Unmarshal(m[3*numBytes:]); err != nil { 159 return nil, err 160 } 161 if err = e.p.y.x.x.Unmarshal(m[4*numBytes:]); err != nil { 162 return nil, err 163 } 164 if err = e.p.y.x.y.Unmarshal(m[5*numBytes:]); err != nil { 165 return nil, err 166 } 167 if err = e.p.y.y.x.Unmarshal(m[6*numBytes:]); err != nil { 168 return nil, err 169 } 170 if err = e.p.y.y.y.Unmarshal(m[7*numBytes:]); err != nil { 171 return nil, err 172 } 173 if err = e.p.z.x.x.Unmarshal(m[8*numBytes:]); err != nil { 174 return nil, err 175 } 176 if err = e.p.z.x.y.Unmarshal(m[9*numBytes:]); err != nil { 177 return nil, err 178 } 179 if err = e.p.z.y.x.Unmarshal(m[10*numBytes:]); err != nil { 180 return nil, err 181 } 182 if err = e.p.z.y.y.Unmarshal(m[11*numBytes:]); err != nil { 183 return nil, err 184 } 185 186 montEncode(&e.p.x.x.x, &e.p.x.x.x) 187 montEncode(&e.p.x.x.y, &e.p.x.x.y) 188 montEncode(&e.p.x.y.x, &e.p.x.y.x) 189 montEncode(&e.p.x.y.y, &e.p.x.y.y) 190 montEncode(&e.p.y.x.x, &e.p.y.x.x) 191 montEncode(&e.p.y.x.y, &e.p.y.x.y) 192 montEncode(&e.p.y.y.x, &e.p.y.y.x) 193 montEncode(&e.p.y.y.y, &e.p.y.y.y) 194 montEncode(&e.p.z.x.x, &e.p.z.x.x) 195 montEncode(&e.p.z.x.y, &e.p.z.x.y) 196 montEncode(&e.p.z.y.x, &e.p.z.y.x) 197 montEncode(&e.p.z.y.y, &e.p.z.y.y) 198 199 return m[12*numBytes:], nil 200 } 201 202 // A GTFieldTable holds the first 15 Exp of a value at offset -1, so P 203 // is at table[0], P^15 is at table[14], and P^0 is implicitly the identity 204 // point. 205 type GTFieldTable [15]*GT 206 207 // Select selects the n-th multiple of the table base point into p. It works in 208 // constant time by iterating over every entry of the table. n must be in [0, 15]. 209 func (table *GTFieldTable) Select(p *GT, n uint8) { 210 if n >= 16 { 211 panic("sm9: internal error: GTFieldTable called with out-of-bounds value") 212 } 213 p.p.SetOne() 214 for i, f := range table { 215 cond := subtle.ConstantTimeByteEq(uint8(i+1), n) 216 gfP12MovCond(p.p, f.p, p.p, cond) 217 } 218 } 219 220 func GenerateGTFieldTable(basePoint *GT) *[32 * 2]GTFieldTable { 221 table := new([32 * 2]GTFieldTable) 222 base := >{} 223 base.Set(basePoint) 224 for i := 0; i < 32*2; i++ { 225 table[i][0] = >{} 226 table[i][0].Set(base) 227 for j := 1; j < 15; j += 2 { 228 table[i][j] = >{} 229 table[i][j].p = &gfP12{} 230 table[i][j].p.Cyclo6SquareNC(table[i][j/2].p) 231 table[i][j+1] = >{} 232 table[i][j+1].p = &gfP12{} 233 table[i][j+1].Add(table[i][j], base) 234 } 235 base.p.Squares(base.p, 4) 236 } 237 return table 238 } 239 240 // ScalarBaseMultGT compute basepoint^r with precomputed table 241 func ScalarBaseMultGT(tables *[32 * 2]GTFieldTable, scalar []byte) (*GT, error) { 242 if len(scalar) != 32 { 243 return nil, errors.New("invalid scalar length") 244 } 245 // This is also a scalar multiplication with a four-bit window like in 246 // ScalarMult, but in this case the doublings are precomputed. The value 247 // [windowValue]G added at iteration k would normally get doubled 248 // (totIterations-k)×4 times, but with a larger precomputation we can 249 // instead add [2^((totIterations-k)×4)][windowValue]G and avoid the 250 // doublings between iterations. 251 e, t := >{}, >{} 252 tableIndex := len(tables) - 1 253 e.SetOne() 254 t.SetOne() 255 for _, byte := range scalar { 256 windowValue := byte >> 4 257 tables[tableIndex].Select(t, windowValue) 258 e.Add(e, t) 259 tableIndex-- 260 windowValue = byte & 0b1111 261 tables[tableIndex].Select(t, windowValue) 262 e.Add(e, t) 263 tableIndex-- 264 } 265 return e, nil 266 } 267 268 // ScalarMultGT compute a^scalar 269 func ScalarMultGT(a *GT, scalar []byte) (*GT, error) { 270 var table GTFieldTable 271 272 table[0] = >{} 273 table[0].Set(a) 274 for i := 1; i < 15; i += 2 { 275 table[i] = >{} 276 table[i].p = &gfP12{} 277 table[i].p.Cyclo6SquareNC(table[i/2].p) 278 279 table[i+1] = >{} 280 table[i+1].p = &gfP12{} 281 table[i+1].Add(table[i], a) 282 } 283 284 e, t := >{}, >{} 285 e.SetOne() 286 t.SetOne() 287 288 for i, byte := range scalar { 289 // No need to double on the first iteration, as p is the identity at 290 // this point, and [N]∞ = ∞. 291 if i != 0 { 292 e.p.Cyclo6Squares(e.p, 4) 293 } 294 windowValue := byte >> 4 295 table.Select(t, windowValue) 296 e.Add(e, t) 297 e.p.Cyclo6Squares(e.p, 4) 298 windowValue = byte & 0b1111 299 table.Select(t, windowValue) 300 e.Add(e, t) 301 } 302 return e, nil 303 }