github.com/shrimpyuk/bor@v0.2.15-0.20220224151350-fb4ec6020bae/crypto/bls12381/fp6.go (about) 1 // Copyright 2020 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package bls12381 18 19 import ( 20 "errors" 21 "math/big" 22 ) 23 24 type fp6Temp struct { 25 t [6]*fe2 26 } 27 28 type fp6 struct { 29 fp2 *fp2 30 fp6Temp 31 } 32 33 func newFp6Temp() fp6Temp { 34 t := [6]*fe2{} 35 for i := 0; i < len(t); i++ { 36 t[i] = &fe2{} 37 } 38 return fp6Temp{t} 39 } 40 41 func newFp6(f *fp2) *fp6 { 42 t := newFp6Temp() 43 if f == nil { 44 return &fp6{newFp2(), t} 45 } 46 return &fp6{f, t} 47 } 48 49 func (e *fp6) fromBytes(b []byte) (*fe6, error) { 50 if len(b) < 288 { 51 return nil, errors.New("input string should be larger than 288 bytes") 52 } 53 fp2 := e.fp2 54 u2, err := fp2.fromBytes(b[:96]) 55 if err != nil { 56 return nil, err 57 } 58 u1, err := fp2.fromBytes(b[96:192]) 59 if err != nil { 60 return nil, err 61 } 62 u0, err := fp2.fromBytes(b[192:]) 63 if err != nil { 64 return nil, err 65 } 66 return &fe6{*u0, *u1, *u2}, nil 67 } 68 69 func (e *fp6) toBytes(a *fe6) []byte { 70 fp2 := e.fp2 71 out := make([]byte, 288) 72 copy(out[:96], fp2.toBytes(&a[2])) 73 copy(out[96:192], fp2.toBytes(&a[1])) 74 copy(out[192:], fp2.toBytes(&a[0])) 75 return out 76 } 77 78 func (e *fp6) new() *fe6 { 79 return new(fe6) 80 } 81 82 func (e *fp6) zero() *fe6 { 83 return new(fe6) 84 } 85 86 func (e *fp6) one() *fe6 { 87 return new(fe6).one() 88 } 89 90 func (e *fp6) add(c, a, b *fe6) { 91 fp2 := e.fp2 92 fp2.add(&c[0], &a[0], &b[0]) 93 fp2.add(&c[1], &a[1], &b[1]) 94 fp2.add(&c[2], &a[2], &b[2]) 95 } 96 97 func (e *fp6) addAssign(a, b *fe6) { 98 fp2 := e.fp2 99 fp2.addAssign(&a[0], &b[0]) 100 fp2.addAssign(&a[1], &b[1]) 101 fp2.addAssign(&a[2], &b[2]) 102 } 103 104 func (e *fp6) double(c, a *fe6) { 105 fp2 := e.fp2 106 fp2.double(&c[0], &a[0]) 107 fp2.double(&c[1], &a[1]) 108 fp2.double(&c[2], &a[2]) 109 } 110 111 func (e *fp6) doubleAssign(a *fe6) { 112 fp2 := e.fp2 113 fp2.doubleAssign(&a[0]) 114 fp2.doubleAssign(&a[1]) 115 fp2.doubleAssign(&a[2]) 116 } 117 118 func (e *fp6) sub(c, a, b *fe6) { 119 fp2 := e.fp2 120 fp2.sub(&c[0], &a[0], &b[0]) 121 fp2.sub(&c[1], &a[1], &b[1]) 122 fp2.sub(&c[2], &a[2], &b[2]) 123 } 124 125 func (e *fp6) subAssign(a, b *fe6) { 126 fp2 := e.fp2 127 fp2.subAssign(&a[0], &b[0]) 128 fp2.subAssign(&a[1], &b[1]) 129 fp2.subAssign(&a[2], &b[2]) 130 } 131 132 func (e *fp6) neg(c, a *fe6) { 133 fp2 := e.fp2 134 fp2.neg(&c[0], &a[0]) 135 fp2.neg(&c[1], &a[1]) 136 fp2.neg(&c[2], &a[2]) 137 } 138 139 func (e *fp6) mul(c, a, b *fe6) { 140 fp2, t := e.fp2, e.t 141 fp2.mul(t[0], &a[0], &b[0]) 142 fp2.mul(t[1], &a[1], &b[1]) 143 fp2.mul(t[2], &a[2], &b[2]) 144 fp2.add(t[3], &a[1], &a[2]) 145 fp2.add(t[4], &b[1], &b[2]) 146 fp2.mulAssign(t[3], t[4]) 147 fp2.add(t[4], t[1], t[2]) 148 fp2.subAssign(t[3], t[4]) 149 fp2.mulByNonResidue(t[3], t[3]) 150 fp2.add(t[5], t[0], t[3]) 151 fp2.add(t[3], &a[0], &a[1]) 152 fp2.add(t[4], &b[0], &b[1]) 153 fp2.mulAssign(t[3], t[4]) 154 fp2.add(t[4], t[0], t[1]) 155 fp2.subAssign(t[3], t[4]) 156 fp2.mulByNonResidue(t[4], t[2]) 157 fp2.add(&c[1], t[3], t[4]) 158 fp2.add(t[3], &a[0], &a[2]) 159 fp2.add(t[4], &b[0], &b[2]) 160 fp2.mulAssign(t[3], t[4]) 161 fp2.add(t[4], t[0], t[2]) 162 fp2.subAssign(t[3], t[4]) 163 fp2.add(&c[2], t[1], t[3]) 164 c[0].set(t[5]) 165 } 166 167 func (e *fp6) mulAssign(a, b *fe6) { 168 fp2, t := e.fp2, e.t 169 fp2.mul(t[0], &a[0], &b[0]) 170 fp2.mul(t[1], &a[1], &b[1]) 171 fp2.mul(t[2], &a[2], &b[2]) 172 fp2.add(t[3], &a[1], &a[2]) 173 fp2.add(t[4], &b[1], &b[2]) 174 fp2.mulAssign(t[3], t[4]) 175 fp2.add(t[4], t[1], t[2]) 176 fp2.subAssign(t[3], t[4]) 177 fp2.mulByNonResidue(t[3], t[3]) 178 fp2.add(t[5], t[0], t[3]) 179 fp2.add(t[3], &a[0], &a[1]) 180 fp2.add(t[4], &b[0], &b[1]) 181 fp2.mulAssign(t[3], t[4]) 182 fp2.add(t[4], t[0], t[1]) 183 fp2.subAssign(t[3], t[4]) 184 fp2.mulByNonResidue(t[4], t[2]) 185 fp2.add(&a[1], t[3], t[4]) 186 fp2.add(t[3], &a[0], &a[2]) 187 fp2.add(t[4], &b[0], &b[2]) 188 fp2.mulAssign(t[3], t[4]) 189 fp2.add(t[4], t[0], t[2]) 190 fp2.subAssign(t[3], t[4]) 191 fp2.add(&a[2], t[1], t[3]) 192 a[0].set(t[5]) 193 } 194 195 func (e *fp6) square(c, a *fe6) { 196 fp2, t := e.fp2, e.t 197 fp2.square(t[0], &a[0]) 198 fp2.mul(t[1], &a[0], &a[1]) 199 fp2.doubleAssign(t[1]) 200 fp2.sub(t[2], &a[0], &a[1]) 201 fp2.addAssign(t[2], &a[2]) 202 fp2.squareAssign(t[2]) 203 fp2.mul(t[3], &a[1], &a[2]) 204 fp2.doubleAssign(t[3]) 205 fp2.square(t[4], &a[2]) 206 fp2.mulByNonResidue(t[5], t[3]) 207 fp2.add(&c[0], t[0], t[5]) 208 fp2.mulByNonResidue(t[5], t[4]) 209 fp2.add(&c[1], t[1], t[5]) 210 fp2.addAssign(t[1], t[2]) 211 fp2.addAssign(t[1], t[3]) 212 fp2.addAssign(t[0], t[4]) 213 fp2.sub(&c[2], t[1], t[0]) 214 } 215 216 func (e *fp6) mulBy01Assign(a *fe6, b0, b1 *fe2) { 217 fp2, t := e.fp2, e.t 218 fp2.mul(t[0], &a[0], b0) 219 fp2.mul(t[1], &a[1], b1) 220 fp2.add(t[5], &a[1], &a[2]) 221 fp2.mul(t[2], b1, t[5]) 222 fp2.subAssign(t[2], t[1]) 223 fp2.mulByNonResidue(t[2], t[2]) 224 fp2.add(t[5], &a[0], &a[2]) 225 fp2.mul(t[3], b0, t[5]) 226 fp2.subAssign(t[3], t[0]) 227 fp2.add(&a[2], t[3], t[1]) 228 fp2.add(t[4], b0, b1) 229 fp2.add(t[5], &a[0], &a[1]) 230 fp2.mulAssign(t[4], t[5]) 231 fp2.subAssign(t[4], t[0]) 232 fp2.sub(&a[1], t[4], t[1]) 233 fp2.add(&a[0], t[2], t[0]) 234 } 235 236 func (e *fp6) mulBy01(c, a *fe6, b0, b1 *fe2) { 237 fp2, t := e.fp2, e.t 238 fp2.mul(t[0], &a[0], b0) 239 fp2.mul(t[1], &a[1], b1) 240 fp2.add(t[2], &a[1], &a[2]) 241 fp2.mulAssign(t[2], b1) 242 fp2.subAssign(t[2], t[1]) 243 fp2.mulByNonResidue(t[2], t[2]) 244 fp2.add(t[3], &a[0], &a[2]) 245 fp2.mulAssign(t[3], b0) 246 fp2.subAssign(t[3], t[0]) 247 fp2.add(&c[2], t[3], t[1]) 248 fp2.add(t[4], b0, b1) 249 fp2.add(t[3], &a[0], &a[1]) 250 fp2.mulAssign(t[4], t[3]) 251 fp2.subAssign(t[4], t[0]) 252 fp2.sub(&c[1], t[4], t[1]) 253 fp2.add(&c[0], t[2], t[0]) 254 } 255 256 func (e *fp6) mulBy1(c, a *fe6, b1 *fe2) { 257 fp2, t := e.fp2, e.t 258 fp2.mul(t[0], &a[2], b1) 259 fp2.mul(&c[2], &a[1], b1) 260 fp2.mul(&c[1], &a[0], b1) 261 fp2.mulByNonResidue(&c[0], t[0]) 262 } 263 264 func (e *fp6) mulByNonResidue(c, a *fe6) { 265 fp2, t := e.fp2, e.t 266 t[0].set(&a[0]) 267 fp2.mulByNonResidue(&c[0], &a[2]) 268 c[2].set(&a[1]) 269 c[1].set(t[0]) 270 } 271 272 func (e *fp6) mulByBaseField(c, a *fe6, b *fe2) { 273 fp2 := e.fp2 274 fp2.mul(&c[0], &a[0], b) 275 fp2.mul(&c[1], &a[1], b) 276 fp2.mul(&c[2], &a[2], b) 277 } 278 279 func (e *fp6) exp(c, a *fe6, s *big.Int) { 280 z := e.one() 281 for i := s.BitLen() - 1; i >= 0; i-- { 282 e.square(z, z) 283 if s.Bit(i) == 1 { 284 e.mul(z, z, a) 285 } 286 } 287 c.set(z) 288 } 289 290 func (e *fp6) inverse(c, a *fe6) { 291 fp2, t := e.fp2, e.t 292 fp2.square(t[0], &a[0]) 293 fp2.mul(t[1], &a[1], &a[2]) 294 fp2.mulByNonResidue(t[1], t[1]) 295 fp2.subAssign(t[0], t[1]) 296 fp2.square(t[1], &a[1]) 297 fp2.mul(t[2], &a[0], &a[2]) 298 fp2.subAssign(t[1], t[2]) 299 fp2.square(t[2], &a[2]) 300 fp2.mulByNonResidue(t[2], t[2]) 301 fp2.mul(t[3], &a[0], &a[1]) 302 fp2.subAssign(t[2], t[3]) 303 fp2.mul(t[3], &a[2], t[2]) 304 fp2.mul(t[4], &a[1], t[1]) 305 fp2.addAssign(t[3], t[4]) 306 fp2.mulByNonResidue(t[3], t[3]) 307 fp2.mul(t[4], &a[0], t[0]) 308 fp2.addAssign(t[3], t[4]) 309 fp2.inverse(t[3], t[3]) 310 fp2.mul(&c[0], t[0], t[3]) 311 fp2.mul(&c[1], t[2], t[3]) 312 fp2.mul(&c[2], t[1], t[3]) 313 } 314 315 func (e *fp6) frobeniusMap(c, a *fe6, power uint) { 316 fp2 := e.fp2 317 fp2.frobeniusMap(&c[0], &a[0], power) 318 fp2.frobeniusMap(&c[1], &a[1], power) 319 fp2.frobeniusMap(&c[2], &a[2], power) 320 switch power % 6 { 321 case 0: 322 return 323 case 3: 324 neg(&c[0][0], &a[1][1]) 325 c[1][1].set(&a[1][0]) 326 fp2.neg(&a[2], &a[2]) 327 default: 328 fp2.mul(&c[1], &c[1], &frobeniusCoeffs61[power%6]) 329 fp2.mul(&c[2], &c[2], &frobeniusCoeffs62[power%6]) 330 } 331 } 332 333 func (e *fp6) frobeniusMapAssign(a *fe6, power uint) { 334 fp2 := e.fp2 335 fp2.frobeniusMapAssign(&a[0], power) 336 fp2.frobeniusMapAssign(&a[1], power) 337 fp2.frobeniusMapAssign(&a[2], power) 338 t := e.t 339 switch power % 6 { 340 case 0: 341 return 342 case 3: 343 neg(&t[0][0], &a[1][1]) 344 a[1][1].set(&a[1][0]) 345 a[1][0].set(&t[0][0]) 346 fp2.neg(&a[2], &a[2]) 347 default: 348 fp2.mulAssign(&a[1], &frobeniusCoeffs61[power%6]) 349 fp2.mulAssign(&a[2], &frobeniusCoeffs62[power%6]) 350 } 351 }