github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-378/fp/element.go (about) 1 // Copyright 2020 ConsenSys Software Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Code generated by consensys/gnark-crypto DO NOT EDIT 16 17 package fp 18 19 import ( 20 "crypto/rand" 21 "encoding/binary" 22 "errors" 23 "io" 24 "math/big" 25 "math/bits" 26 "reflect" 27 "strconv" 28 "strings" 29 30 "github.com/bits-and-blooms/bitset" 31 "github.com/consensys/gnark-crypto/field/hash" 32 "github.com/consensys/gnark-crypto/field/pool" 33 ) 34 35 // Element represents a field element stored on 6 words (uint64) 36 // 37 // Element are assumed to be in Montgomery form in all methods. 38 // 39 // Modulus q = 40 // 41 // q[base10] = 605248206075306171733248481581800960739847691770924913753520744034740935903401304776283802348837311170974282940417 42 // q[base16] = 0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce97f76a822c00009948a20000000001 43 // 44 // # Warning 45 // 46 // This code has not been audited and is provided as-is. In particular, there is no security guarantees such as constant time implementation or side-channel attack resistance. 47 type Element [6]uint64 48 49 const ( 50 Limbs = 6 // number of 64 bits words needed to represent a Element 51 Bits = 378 // number of bits needed to represent a Element 52 Bytes = 48 // number of bytes needed to represent a Element 53 ) 54 55 // Field modulus q 56 const ( 57 q0 uint64 = 11045256207009841153 58 q1 uint64 = 14886639130118979584 59 q2 uint64 = 10956628289047010687 60 q3 uint64 = 9513184293603517222 61 q4 uint64 = 6038022134869067682 62 q5 uint64 = 283357621510263184 63 ) 64 65 var qElement = Element{ 66 q0, 67 q1, 68 q2, 69 q3, 70 q4, 71 q5, 72 } 73 74 var _modulus big.Int // q stored as big.Int 75 76 // Modulus returns q as a big.Int 77 // 78 // q[base10] = 605248206075306171733248481581800960739847691770924913753520744034740935903401304776283802348837311170974282940417 79 // q[base16] = 0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce97f76a822c00009948a20000000001 80 func Modulus() *big.Int { 81 return new(big.Int).Set(&_modulus) 82 } 83 84 // q + r'.r = 1, i.e., qInvNeg = - q⁻¹ mod r 85 // used for Montgomery reduction 86 const qInvNeg uint64 = 11045256207009841151 87 88 func init() { 89 _modulus.SetString("3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce97f76a822c00009948a20000000001", 16) 90 } 91 92 // NewElement returns a new Element from a uint64 value 93 // 94 // it is equivalent to 95 // 96 // var v Element 97 // v.SetUint64(...) 98 func NewElement(v uint64) Element { 99 z := Element{v} 100 z.Mul(&z, &rSquare) 101 return z 102 } 103 104 // SetUint64 sets z to v and returns z 105 func (z *Element) SetUint64(v uint64) *Element { 106 // sets z LSB to v (non-Montgomery form) and convert z to Montgomery form 107 *z = Element{v} 108 return z.Mul(z, &rSquare) // z.toMont() 109 } 110 111 // SetInt64 sets z to v and returns z 112 func (z *Element) SetInt64(v int64) *Element { 113 114 // absolute value of v 115 m := v >> 63 116 z.SetUint64(uint64((v ^ m) - m)) 117 118 if m != 0 { 119 // v is negative 120 z.Neg(z) 121 } 122 123 return z 124 } 125 126 // Set z = x and returns z 127 func (z *Element) Set(x *Element) *Element { 128 z[0] = x[0] 129 z[1] = x[1] 130 z[2] = x[2] 131 z[3] = x[3] 132 z[4] = x[4] 133 z[5] = x[5] 134 return z 135 } 136 137 // SetInterface converts provided interface into Element 138 // returns an error if provided type is not supported 139 // supported types: 140 // 141 // Element 142 // *Element 143 // uint64 144 // int 145 // string (see SetString for valid formats) 146 // *big.Int 147 // big.Int 148 // []byte 149 func (z *Element) SetInterface(i1 interface{}) (*Element, error) { 150 if i1 == nil { 151 return nil, errors.New("can't set fp.Element with <nil>") 152 } 153 154 switch c1 := i1.(type) { 155 case Element: 156 return z.Set(&c1), nil 157 case *Element: 158 if c1 == nil { 159 return nil, errors.New("can't set fp.Element with <nil>") 160 } 161 return z.Set(c1), nil 162 case uint8: 163 return z.SetUint64(uint64(c1)), nil 164 case uint16: 165 return z.SetUint64(uint64(c1)), nil 166 case uint32: 167 return z.SetUint64(uint64(c1)), nil 168 case uint: 169 return z.SetUint64(uint64(c1)), nil 170 case uint64: 171 return z.SetUint64(c1), nil 172 case int8: 173 return z.SetInt64(int64(c1)), nil 174 case int16: 175 return z.SetInt64(int64(c1)), nil 176 case int32: 177 return z.SetInt64(int64(c1)), nil 178 case int64: 179 return z.SetInt64(c1), nil 180 case int: 181 return z.SetInt64(int64(c1)), nil 182 case string: 183 return z.SetString(c1) 184 case *big.Int: 185 if c1 == nil { 186 return nil, errors.New("can't set fp.Element with <nil>") 187 } 188 return z.SetBigInt(c1), nil 189 case big.Int: 190 return z.SetBigInt(&c1), nil 191 case []byte: 192 return z.SetBytes(c1), nil 193 default: 194 return nil, errors.New("can't set fp.Element from type " + reflect.TypeOf(i1).String()) 195 } 196 } 197 198 // SetZero z = 0 199 func (z *Element) SetZero() *Element { 200 z[0] = 0 201 z[1] = 0 202 z[2] = 0 203 z[3] = 0 204 z[4] = 0 205 z[5] = 0 206 return z 207 } 208 209 // SetOne z = 1 (in Montgomery form) 210 func (z *Element) SetOne() *Element { 211 z[0] = 1481365419032838079 212 z[1] = 10045892448872562649 213 z[2] = 7242180086616818316 214 z[3] = 8832319421896135475 215 z[4] = 13356930855120736188 216 z[5] = 28498675542444634 217 return z 218 } 219 220 // Div z = x*y⁻¹ (mod q) 221 func (z *Element) Div(x, y *Element) *Element { 222 var yInv Element 223 yInv.Inverse(y) 224 z.Mul(x, &yInv) 225 return z 226 } 227 228 // Equal returns z == x; constant-time 229 func (z *Element) Equal(x *Element) bool { 230 return z.NotEqual(x) == 0 231 } 232 233 // NotEqual returns 0 if and only if z == x; constant-time 234 func (z *Element) NotEqual(x *Element) uint64 { 235 return (z[5] ^ x[5]) | (z[4] ^ x[4]) | (z[3] ^ x[3]) | (z[2] ^ x[2]) | (z[1] ^ x[1]) | (z[0] ^ x[0]) 236 } 237 238 // IsZero returns z == 0 239 func (z *Element) IsZero() bool { 240 return (z[5] | z[4] | z[3] | z[2] | z[1] | z[0]) == 0 241 } 242 243 // IsOne returns z == 1 244 func (z *Element) IsOne() bool { 245 return ((z[5] ^ 28498675542444634) | (z[4] ^ 13356930855120736188) | (z[3] ^ 8832319421896135475) | (z[2] ^ 7242180086616818316) | (z[1] ^ 10045892448872562649) | (z[0] ^ 1481365419032838079)) == 0 246 } 247 248 // IsUint64 reports whether z can be represented as an uint64. 249 func (z *Element) IsUint64() bool { 250 zz := *z 251 zz.fromMont() 252 return zz.FitsOnOneWord() 253 } 254 255 // Uint64 returns the uint64 representation of x. If x cannot be represented in a uint64, the result is undefined. 256 func (z *Element) Uint64() uint64 { 257 return z.Bits()[0] 258 } 259 260 // FitsOnOneWord reports whether z words (except the least significant word) are 0 261 // 262 // It is the responsibility of the caller to convert from Montgomery to Regular form if needed. 263 func (z *Element) FitsOnOneWord() bool { 264 return (z[5] | z[4] | z[3] | z[2] | z[1]) == 0 265 } 266 267 // Cmp compares (lexicographic order) z and x and returns: 268 // 269 // -1 if z < x 270 // 0 if z == x 271 // +1 if z > x 272 func (z *Element) Cmp(x *Element) int { 273 _z := z.Bits() 274 _x := x.Bits() 275 if _z[5] > _x[5] { 276 return 1 277 } else if _z[5] < _x[5] { 278 return -1 279 } 280 if _z[4] > _x[4] { 281 return 1 282 } else if _z[4] < _x[4] { 283 return -1 284 } 285 if _z[3] > _x[3] { 286 return 1 287 } else if _z[3] < _x[3] { 288 return -1 289 } 290 if _z[2] > _x[2] { 291 return 1 292 } else if _z[2] < _x[2] { 293 return -1 294 } 295 if _z[1] > _x[1] { 296 return 1 297 } else if _z[1] < _x[1] { 298 return -1 299 } 300 if _z[0] > _x[0] { 301 return 1 302 } else if _z[0] < _x[0] { 303 return -1 304 } 305 return 0 306 } 307 308 // LexicographicallyLargest returns true if this element is strictly lexicographically 309 // larger than its negation, false otherwise 310 func (z *Element) LexicographicallyLargest() bool { 311 // adapted from github.com/zkcrypto/bls12_381 312 // we check if the element is larger than (q-1) / 2 313 // if z - (((q -1) / 2) + 1) have no underflow, then z > (q-1) / 2 314 315 _z := z.Bits() 316 317 var b uint64 318 _, b = bits.Sub64(_z[0], 5522628103504920577, 0) 319 _, b = bits.Sub64(_z[1], 16666691601914265600, b) 320 _, b = bits.Sub64(_z[2], 5478314144523505343, b) 321 _, b = bits.Sub64(_z[3], 4756592146801758611, b) 322 _, b = bits.Sub64(_z[4], 3019011067434533841, b) 323 _, b = bits.Sub64(_z[5], 141678810755131592, b) 324 325 return b == 0 326 } 327 328 // SetRandom sets z to a uniform random value in [0, q). 329 // 330 // This might error only if reading from crypto/rand.Reader errors, 331 // in which case, value of z is undefined. 332 func (z *Element) SetRandom() (*Element, error) { 333 // this code is generated for all modulus 334 // and derived from go/src/crypto/rand/util.go 335 336 // l is number of limbs * 8; the number of bytes needed to reconstruct 6 uint64 337 const l = 48 338 339 // bitLen is the maximum bit length needed to encode a value < q. 340 const bitLen = 378 341 342 // k is the maximum byte length needed to encode a value < q. 343 const k = (bitLen + 7) / 8 344 345 // b is the number of bits in the most significant byte of q-1. 346 b := uint(bitLen % 8) 347 if b == 0 { 348 b = 8 349 } 350 351 var bytes [l]byte 352 353 for { 354 // note that bytes[k:l] is always 0 355 if _, err := io.ReadFull(rand.Reader, bytes[:k]); err != nil { 356 return nil, err 357 } 358 359 // Clear unused bits in in the most significant byte to increase probability 360 // that the candidate is < q. 361 bytes[k-1] &= uint8(int(1<<b) - 1) 362 z[0] = binary.LittleEndian.Uint64(bytes[0:8]) 363 z[1] = binary.LittleEndian.Uint64(bytes[8:16]) 364 z[2] = binary.LittleEndian.Uint64(bytes[16:24]) 365 z[3] = binary.LittleEndian.Uint64(bytes[24:32]) 366 z[4] = binary.LittleEndian.Uint64(bytes[32:40]) 367 z[5] = binary.LittleEndian.Uint64(bytes[40:48]) 368 369 if !z.smallerThanModulus() { 370 continue // ignore the candidate and re-sample 371 } 372 373 return z, nil 374 } 375 } 376 377 // smallerThanModulus returns true if z < q 378 // This is not constant time 379 func (z *Element) smallerThanModulus() bool { 380 return (z[5] < q5 || (z[5] == q5 && (z[4] < q4 || (z[4] == q4 && (z[3] < q3 || (z[3] == q3 && (z[2] < q2 || (z[2] == q2 && (z[1] < q1 || (z[1] == q1 && (z[0] < q0))))))))))) 381 } 382 383 // One returns 1 384 func One() Element { 385 var one Element 386 one.SetOne() 387 return one 388 } 389 390 // Halve sets z to z / 2 (mod q) 391 func (z *Element) Halve() { 392 var carry uint64 393 394 if z[0]&1 == 1 { 395 // z = z + q 396 z[0], carry = bits.Add64(z[0], q0, 0) 397 z[1], carry = bits.Add64(z[1], q1, carry) 398 z[2], carry = bits.Add64(z[2], q2, carry) 399 z[3], carry = bits.Add64(z[3], q3, carry) 400 z[4], carry = bits.Add64(z[4], q4, carry) 401 z[5], _ = bits.Add64(z[5], q5, carry) 402 403 } 404 // z = z >> 1 405 z[0] = z[0]>>1 | z[1]<<63 406 z[1] = z[1]>>1 | z[2]<<63 407 z[2] = z[2]>>1 | z[3]<<63 408 z[3] = z[3]>>1 | z[4]<<63 409 z[4] = z[4]>>1 | z[5]<<63 410 z[5] >>= 1 411 412 } 413 414 // fromMont converts z in place (i.e. mutates) from Montgomery to regular representation 415 // sets and returns z = z * 1 416 func (z *Element) fromMont() *Element { 417 fromMont(z) 418 return z 419 } 420 421 // Add z = x + y (mod q) 422 func (z *Element) Add(x, y *Element) *Element { 423 424 var carry uint64 425 z[0], carry = bits.Add64(x[0], y[0], 0) 426 z[1], carry = bits.Add64(x[1], y[1], carry) 427 z[2], carry = bits.Add64(x[2], y[2], carry) 428 z[3], carry = bits.Add64(x[3], y[3], carry) 429 z[4], carry = bits.Add64(x[4], y[4], carry) 430 z[5], _ = bits.Add64(x[5], y[5], carry) 431 432 // if z ⩾ q → z -= q 433 if !z.smallerThanModulus() { 434 var b uint64 435 z[0], b = bits.Sub64(z[0], q0, 0) 436 z[1], b = bits.Sub64(z[1], q1, b) 437 z[2], b = bits.Sub64(z[2], q2, b) 438 z[3], b = bits.Sub64(z[3], q3, b) 439 z[4], b = bits.Sub64(z[4], q4, b) 440 z[5], _ = bits.Sub64(z[5], q5, b) 441 } 442 return z 443 } 444 445 // Double z = x + x (mod q), aka Lsh 1 446 func (z *Element) Double(x *Element) *Element { 447 448 var carry uint64 449 z[0], carry = bits.Add64(x[0], x[0], 0) 450 z[1], carry = bits.Add64(x[1], x[1], carry) 451 z[2], carry = bits.Add64(x[2], x[2], carry) 452 z[3], carry = bits.Add64(x[3], x[3], carry) 453 z[4], carry = bits.Add64(x[4], x[4], carry) 454 z[5], _ = bits.Add64(x[5], x[5], carry) 455 456 // if z ⩾ q → z -= q 457 if !z.smallerThanModulus() { 458 var b uint64 459 z[0], b = bits.Sub64(z[0], q0, 0) 460 z[1], b = bits.Sub64(z[1], q1, b) 461 z[2], b = bits.Sub64(z[2], q2, b) 462 z[3], b = bits.Sub64(z[3], q3, b) 463 z[4], b = bits.Sub64(z[4], q4, b) 464 z[5], _ = bits.Sub64(z[5], q5, b) 465 } 466 return z 467 } 468 469 // Sub z = x - y (mod q) 470 func (z *Element) Sub(x, y *Element) *Element { 471 var b uint64 472 z[0], b = bits.Sub64(x[0], y[0], 0) 473 z[1], b = bits.Sub64(x[1], y[1], b) 474 z[2], b = bits.Sub64(x[2], y[2], b) 475 z[3], b = bits.Sub64(x[3], y[3], b) 476 z[4], b = bits.Sub64(x[4], y[4], b) 477 z[5], b = bits.Sub64(x[5], y[5], b) 478 if b != 0 { 479 var c uint64 480 z[0], c = bits.Add64(z[0], q0, 0) 481 z[1], c = bits.Add64(z[1], q1, c) 482 z[2], c = bits.Add64(z[2], q2, c) 483 z[3], c = bits.Add64(z[3], q3, c) 484 z[4], c = bits.Add64(z[4], q4, c) 485 z[5], _ = bits.Add64(z[5], q5, c) 486 } 487 return z 488 } 489 490 // Neg z = q - x 491 func (z *Element) Neg(x *Element) *Element { 492 if x.IsZero() { 493 z.SetZero() 494 return z 495 } 496 var borrow uint64 497 z[0], borrow = bits.Sub64(q0, x[0], 0) 498 z[1], borrow = bits.Sub64(q1, x[1], borrow) 499 z[2], borrow = bits.Sub64(q2, x[2], borrow) 500 z[3], borrow = bits.Sub64(q3, x[3], borrow) 501 z[4], borrow = bits.Sub64(q4, x[4], borrow) 502 z[5], _ = bits.Sub64(q5, x[5], borrow) 503 return z 504 } 505 506 // Select is a constant-time conditional move. 507 // If c=0, z = x0. Else z = x1 508 func (z *Element) Select(c int, x0 *Element, x1 *Element) *Element { 509 cC := uint64((int64(c) | -int64(c)) >> 63) // "canonicized" into: 0 if c=0, -1 otherwise 510 z[0] = x0[0] ^ cC&(x0[0]^x1[0]) 511 z[1] = x0[1] ^ cC&(x0[1]^x1[1]) 512 z[2] = x0[2] ^ cC&(x0[2]^x1[2]) 513 z[3] = x0[3] ^ cC&(x0[3]^x1[3]) 514 z[4] = x0[4] ^ cC&(x0[4]^x1[4]) 515 z[5] = x0[5] ^ cC&(x0[5]^x1[5]) 516 return z 517 } 518 519 // _mulGeneric is unoptimized textbook CIOS 520 // it is a fallback solution on x86 when ADX instruction set is not available 521 // and is used for testing purposes. 522 func _mulGeneric(z, x, y *Element) { 523 524 // Implements CIOS multiplication -- section 2.3.2 of Tolga Acar's thesis 525 // https://www.microsoft.com/en-us/research/wp-content/uploads/1998/06/97Acar.pdf 526 // 527 // The algorithm: 528 // 529 // for i=0 to N-1 530 // C := 0 531 // for j=0 to N-1 532 // (C,t[j]) := t[j] + x[j]*y[i] + C 533 // (t[N+1],t[N]) := t[N] + C 534 // 535 // C := 0 536 // m := t[0]*q'[0] mod D 537 // (C,_) := t[0] + m*q[0] 538 // for j=1 to N-1 539 // (C,t[j-1]) := t[j] + m*q[j] + C 540 // 541 // (C,t[N-1]) := t[N] + C 542 // t[N] := t[N+1] + C 543 // 544 // → N is the number of machine words needed to store the modulus q 545 // → D is the word size. For example, on a 64-bit architecture D is 2 64 546 // → x[i], y[i], q[i] is the ith word of the numbers x,y,q 547 // → q'[0] is the lowest word of the number -q⁻¹ mod r. This quantity is pre-computed, as it does not depend on the inputs. 548 // → t is a temporary array of size N+2 549 // → C, S are machine words. A pair (C,S) refers to (hi-bits, lo-bits) of a two-word number 550 551 var t [7]uint64 552 var D uint64 553 var m, C uint64 554 // ----------------------------------- 555 // First loop 556 557 C, t[0] = bits.Mul64(y[0], x[0]) 558 C, t[1] = madd1(y[0], x[1], C) 559 C, t[2] = madd1(y[0], x[2], C) 560 C, t[3] = madd1(y[0], x[3], C) 561 C, t[4] = madd1(y[0], x[4], C) 562 C, t[5] = madd1(y[0], x[5], C) 563 564 t[6], D = bits.Add64(t[6], C, 0) 565 566 // m = t[0]n'[0] mod W 567 m = t[0] * qInvNeg 568 569 // ----------------------------------- 570 // Second loop 571 C = madd0(m, q0, t[0]) 572 C, t[0] = madd2(m, q1, t[1], C) 573 C, t[1] = madd2(m, q2, t[2], C) 574 C, t[2] = madd2(m, q3, t[3], C) 575 C, t[3] = madd2(m, q4, t[4], C) 576 C, t[4] = madd2(m, q5, t[5], C) 577 578 t[5], C = bits.Add64(t[6], C, 0) 579 t[6], _ = bits.Add64(0, D, C) 580 // ----------------------------------- 581 // First loop 582 583 C, t[0] = madd1(y[1], x[0], t[0]) 584 C, t[1] = madd2(y[1], x[1], t[1], C) 585 C, t[2] = madd2(y[1], x[2], t[2], C) 586 C, t[3] = madd2(y[1], x[3], t[3], C) 587 C, t[4] = madd2(y[1], x[4], t[4], C) 588 C, t[5] = madd2(y[1], x[5], t[5], C) 589 590 t[6], D = bits.Add64(t[6], C, 0) 591 592 // m = t[0]n'[0] mod W 593 m = t[0] * qInvNeg 594 595 // ----------------------------------- 596 // Second loop 597 C = madd0(m, q0, t[0]) 598 C, t[0] = madd2(m, q1, t[1], C) 599 C, t[1] = madd2(m, q2, t[2], C) 600 C, t[2] = madd2(m, q3, t[3], C) 601 C, t[3] = madd2(m, q4, t[4], C) 602 C, t[4] = madd2(m, q5, t[5], C) 603 604 t[5], C = bits.Add64(t[6], C, 0) 605 t[6], _ = bits.Add64(0, D, C) 606 // ----------------------------------- 607 // First loop 608 609 C, t[0] = madd1(y[2], x[0], t[0]) 610 C, t[1] = madd2(y[2], x[1], t[1], C) 611 C, t[2] = madd2(y[2], x[2], t[2], C) 612 C, t[3] = madd2(y[2], x[3], t[3], C) 613 C, t[4] = madd2(y[2], x[4], t[4], C) 614 C, t[5] = madd2(y[2], x[5], t[5], C) 615 616 t[6], D = bits.Add64(t[6], C, 0) 617 618 // m = t[0]n'[0] mod W 619 m = t[0] * qInvNeg 620 621 // ----------------------------------- 622 // Second loop 623 C = madd0(m, q0, t[0]) 624 C, t[0] = madd2(m, q1, t[1], C) 625 C, t[1] = madd2(m, q2, t[2], C) 626 C, t[2] = madd2(m, q3, t[3], C) 627 C, t[3] = madd2(m, q4, t[4], C) 628 C, t[4] = madd2(m, q5, t[5], C) 629 630 t[5], C = bits.Add64(t[6], C, 0) 631 t[6], _ = bits.Add64(0, D, C) 632 // ----------------------------------- 633 // First loop 634 635 C, t[0] = madd1(y[3], x[0], t[0]) 636 C, t[1] = madd2(y[3], x[1], t[1], C) 637 C, t[2] = madd2(y[3], x[2], t[2], C) 638 C, t[3] = madd2(y[3], x[3], t[3], C) 639 C, t[4] = madd2(y[3], x[4], t[4], C) 640 C, t[5] = madd2(y[3], x[5], t[5], C) 641 642 t[6], D = bits.Add64(t[6], C, 0) 643 644 // m = t[0]n'[0] mod W 645 m = t[0] * qInvNeg 646 647 // ----------------------------------- 648 // Second loop 649 C = madd0(m, q0, t[0]) 650 C, t[0] = madd2(m, q1, t[1], C) 651 C, t[1] = madd2(m, q2, t[2], C) 652 C, t[2] = madd2(m, q3, t[3], C) 653 C, t[3] = madd2(m, q4, t[4], C) 654 C, t[4] = madd2(m, q5, t[5], C) 655 656 t[5], C = bits.Add64(t[6], C, 0) 657 t[6], _ = bits.Add64(0, D, C) 658 // ----------------------------------- 659 // First loop 660 661 C, t[0] = madd1(y[4], x[0], t[0]) 662 C, t[1] = madd2(y[4], x[1], t[1], C) 663 C, t[2] = madd2(y[4], x[2], t[2], C) 664 C, t[3] = madd2(y[4], x[3], t[3], C) 665 C, t[4] = madd2(y[4], x[4], t[4], C) 666 C, t[5] = madd2(y[4], x[5], t[5], C) 667 668 t[6], D = bits.Add64(t[6], C, 0) 669 670 // m = t[0]n'[0] mod W 671 m = t[0] * qInvNeg 672 673 // ----------------------------------- 674 // Second loop 675 C = madd0(m, q0, t[0]) 676 C, t[0] = madd2(m, q1, t[1], C) 677 C, t[1] = madd2(m, q2, t[2], C) 678 C, t[2] = madd2(m, q3, t[3], C) 679 C, t[3] = madd2(m, q4, t[4], C) 680 C, t[4] = madd2(m, q5, t[5], C) 681 682 t[5], C = bits.Add64(t[6], C, 0) 683 t[6], _ = bits.Add64(0, D, C) 684 // ----------------------------------- 685 // First loop 686 687 C, t[0] = madd1(y[5], x[0], t[0]) 688 C, t[1] = madd2(y[5], x[1], t[1], C) 689 C, t[2] = madd2(y[5], x[2], t[2], C) 690 C, t[3] = madd2(y[5], x[3], t[3], C) 691 C, t[4] = madd2(y[5], x[4], t[4], C) 692 C, t[5] = madd2(y[5], x[5], t[5], C) 693 694 t[6], D = bits.Add64(t[6], C, 0) 695 696 // m = t[0]n'[0] mod W 697 m = t[0] * qInvNeg 698 699 // ----------------------------------- 700 // Second loop 701 C = madd0(m, q0, t[0]) 702 C, t[0] = madd2(m, q1, t[1], C) 703 C, t[1] = madd2(m, q2, t[2], C) 704 C, t[2] = madd2(m, q3, t[3], C) 705 C, t[3] = madd2(m, q4, t[4], C) 706 C, t[4] = madd2(m, q5, t[5], C) 707 708 t[5], C = bits.Add64(t[6], C, 0) 709 t[6], _ = bits.Add64(0, D, C) 710 711 if t[6] != 0 { 712 // we need to reduce, we have a result on 7 words 713 var b uint64 714 z[0], b = bits.Sub64(t[0], q0, 0) 715 z[1], b = bits.Sub64(t[1], q1, b) 716 z[2], b = bits.Sub64(t[2], q2, b) 717 z[3], b = bits.Sub64(t[3], q3, b) 718 z[4], b = bits.Sub64(t[4], q4, b) 719 z[5], _ = bits.Sub64(t[5], q5, b) 720 return 721 } 722 723 // copy t into z 724 z[0] = t[0] 725 z[1] = t[1] 726 z[2] = t[2] 727 z[3] = t[3] 728 z[4] = t[4] 729 z[5] = t[5] 730 731 // if z ⩾ q → z -= q 732 if !z.smallerThanModulus() { 733 var b uint64 734 z[0], b = bits.Sub64(z[0], q0, 0) 735 z[1], b = bits.Sub64(z[1], q1, b) 736 z[2], b = bits.Sub64(z[2], q2, b) 737 z[3], b = bits.Sub64(z[3], q3, b) 738 z[4], b = bits.Sub64(z[4], q4, b) 739 z[5], _ = bits.Sub64(z[5], q5, b) 740 } 741 } 742 743 func _fromMontGeneric(z *Element) { 744 // the following lines implement z = z * 1 745 // with a modified CIOS montgomery multiplication 746 // see Mul for algorithm documentation 747 { 748 // m = z[0]n'[0] mod W 749 m := z[0] * qInvNeg 750 C := madd0(m, q0, z[0]) 751 C, z[0] = madd2(m, q1, z[1], C) 752 C, z[1] = madd2(m, q2, z[2], C) 753 C, z[2] = madd2(m, q3, z[3], C) 754 C, z[3] = madd2(m, q4, z[4], C) 755 C, z[4] = madd2(m, q5, z[5], C) 756 z[5] = C 757 } 758 { 759 // m = z[0]n'[0] mod W 760 m := z[0] * qInvNeg 761 C := madd0(m, q0, z[0]) 762 C, z[0] = madd2(m, q1, z[1], C) 763 C, z[1] = madd2(m, q2, z[2], C) 764 C, z[2] = madd2(m, q3, z[3], C) 765 C, z[3] = madd2(m, q4, z[4], C) 766 C, z[4] = madd2(m, q5, z[5], C) 767 z[5] = C 768 } 769 { 770 // m = z[0]n'[0] mod W 771 m := z[0] * qInvNeg 772 C := madd0(m, q0, z[0]) 773 C, z[0] = madd2(m, q1, z[1], C) 774 C, z[1] = madd2(m, q2, z[2], C) 775 C, z[2] = madd2(m, q3, z[3], C) 776 C, z[3] = madd2(m, q4, z[4], C) 777 C, z[4] = madd2(m, q5, z[5], C) 778 z[5] = C 779 } 780 { 781 // m = z[0]n'[0] mod W 782 m := z[0] * qInvNeg 783 C := madd0(m, q0, z[0]) 784 C, z[0] = madd2(m, q1, z[1], C) 785 C, z[1] = madd2(m, q2, z[2], C) 786 C, z[2] = madd2(m, q3, z[3], C) 787 C, z[3] = madd2(m, q4, z[4], C) 788 C, z[4] = madd2(m, q5, z[5], C) 789 z[5] = C 790 } 791 { 792 // m = z[0]n'[0] mod W 793 m := z[0] * qInvNeg 794 C := madd0(m, q0, z[0]) 795 C, z[0] = madd2(m, q1, z[1], C) 796 C, z[1] = madd2(m, q2, z[2], C) 797 C, z[2] = madd2(m, q3, z[3], C) 798 C, z[3] = madd2(m, q4, z[4], C) 799 C, z[4] = madd2(m, q5, z[5], C) 800 z[5] = C 801 } 802 { 803 // m = z[0]n'[0] mod W 804 m := z[0] * qInvNeg 805 C := madd0(m, q0, z[0]) 806 C, z[0] = madd2(m, q1, z[1], C) 807 C, z[1] = madd2(m, q2, z[2], C) 808 C, z[2] = madd2(m, q3, z[3], C) 809 C, z[3] = madd2(m, q4, z[4], C) 810 C, z[4] = madd2(m, q5, z[5], C) 811 z[5] = C 812 } 813 814 // if z ⩾ q → z -= q 815 if !z.smallerThanModulus() { 816 var b uint64 817 z[0], b = bits.Sub64(z[0], q0, 0) 818 z[1], b = bits.Sub64(z[1], q1, b) 819 z[2], b = bits.Sub64(z[2], q2, b) 820 z[3], b = bits.Sub64(z[3], q3, b) 821 z[4], b = bits.Sub64(z[4], q4, b) 822 z[5], _ = bits.Sub64(z[5], q5, b) 823 } 824 } 825 826 func _reduceGeneric(z *Element) { 827 828 // if z ⩾ q → z -= q 829 if !z.smallerThanModulus() { 830 var b uint64 831 z[0], b = bits.Sub64(z[0], q0, 0) 832 z[1], b = bits.Sub64(z[1], q1, b) 833 z[2], b = bits.Sub64(z[2], q2, b) 834 z[3], b = bits.Sub64(z[3], q3, b) 835 z[4], b = bits.Sub64(z[4], q4, b) 836 z[5], _ = bits.Sub64(z[5], q5, b) 837 } 838 } 839 840 // BatchInvert returns a new slice with every element inverted. 841 // Uses Montgomery batch inversion trick 842 func BatchInvert(a []Element) []Element { 843 res := make([]Element, len(a)) 844 if len(a) == 0 { 845 return res 846 } 847 848 zeroes := bitset.New(uint(len(a))) 849 accumulator := One() 850 851 for i := 0; i < len(a); i++ { 852 if a[i].IsZero() { 853 zeroes.Set(uint(i)) 854 continue 855 } 856 res[i] = accumulator 857 accumulator.Mul(&accumulator, &a[i]) 858 } 859 860 accumulator.Inverse(&accumulator) 861 862 for i := len(a) - 1; i >= 0; i-- { 863 if zeroes.Test(uint(i)) { 864 continue 865 } 866 res[i].Mul(&res[i], &accumulator) 867 accumulator.Mul(&accumulator, &a[i]) 868 } 869 870 return res 871 } 872 873 func _butterflyGeneric(a, b *Element) { 874 t := *a 875 a.Add(a, b) 876 b.Sub(&t, b) 877 } 878 879 // BitLen returns the minimum number of bits needed to represent z 880 // returns 0 if z == 0 881 func (z *Element) BitLen() int { 882 if z[5] != 0 { 883 return 320 + bits.Len64(z[5]) 884 } 885 if z[4] != 0 { 886 return 256 + bits.Len64(z[4]) 887 } 888 if z[3] != 0 { 889 return 192 + bits.Len64(z[3]) 890 } 891 if z[2] != 0 { 892 return 128 + bits.Len64(z[2]) 893 } 894 if z[1] != 0 { 895 return 64 + bits.Len64(z[1]) 896 } 897 return bits.Len64(z[0]) 898 } 899 900 // Hash msg to count prime field elements. 901 // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 902 func Hash(msg, dst []byte, count int) ([]Element, error) { 903 // 128 bits of security 904 // L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128 905 const Bytes = 1 + (Bits-1)/8 906 const L = 16 + Bytes 907 908 lenInBytes := count * L 909 pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes) 910 if err != nil { 911 return nil, err 912 } 913 914 // get temporary big int from the pool 915 vv := pool.BigInt.Get() 916 917 res := make([]Element, count) 918 for i := 0; i < count; i++ { 919 vv.SetBytes(pseudoRandomBytes[i*L : (i+1)*L]) 920 res[i].SetBigInt(vv) 921 } 922 923 // release object into pool 924 pool.BigInt.Put(vv) 925 926 return res, nil 927 } 928 929 // Exp z = xᵏ (mod q) 930 func (z *Element) Exp(x Element, k *big.Int) *Element { 931 if k.IsUint64() && k.Uint64() == 0 { 932 return z.SetOne() 933 } 934 935 e := k 936 if k.Sign() == -1 { 937 // negative k, we invert 938 // if k < 0: xᵏ (mod q) == (x⁻¹)ᵏ (mod q) 939 x.Inverse(&x) 940 941 // we negate k in a temp big.Int since 942 // Int.Bit(_) of k and -k is different 943 e = pool.BigInt.Get() 944 defer pool.BigInt.Put(e) 945 e.Neg(k) 946 } 947 948 z.Set(&x) 949 950 for i := e.BitLen() - 2; i >= 0; i-- { 951 z.Square(z) 952 if e.Bit(i) == 1 { 953 z.Mul(z, &x) 954 } 955 } 956 957 return z 958 } 959 960 // rSquare where r is the Montgommery constant 961 // see section 2.3.2 of Tolga Acar's thesis 962 // https://www.microsoft.com/en-us/research/wp-content/uploads/1998/06/97Acar.pdf 963 var rSquare = Element{ 964 13541478318970833666, 965 5510290684934426267, 966 8467587974331926354, 967 13931463632695577534, 968 3531303697457869800, 969 51529254522778566, 970 } 971 972 // toMont converts z to Montgomery form 973 // sets and returns z = z * r² 974 func (z *Element) toMont() *Element { 975 return z.Mul(z, &rSquare) 976 } 977 978 // String returns the decimal representation of z as generated by 979 // z.Text(10). 980 func (z *Element) String() string { 981 return z.Text(10) 982 } 983 984 // toBigInt returns z as a big.Int in Montgomery form 985 func (z *Element) toBigInt(res *big.Int) *big.Int { 986 var b [Bytes]byte 987 binary.BigEndian.PutUint64(b[40:48], z[0]) 988 binary.BigEndian.PutUint64(b[32:40], z[1]) 989 binary.BigEndian.PutUint64(b[24:32], z[2]) 990 binary.BigEndian.PutUint64(b[16:24], z[3]) 991 binary.BigEndian.PutUint64(b[8:16], z[4]) 992 binary.BigEndian.PutUint64(b[0:8], z[5]) 993 994 return res.SetBytes(b[:]) 995 } 996 997 // Text returns the string representation of z in the given base. 998 // Base must be between 2 and 36, inclusive. The result uses the 999 // lower-case letters 'a' to 'z' for digit values 10 to 35. 1000 // No prefix (such as "0x") is added to the string. If z is a nil 1001 // pointer it returns "<nil>". 1002 // If base == 10 and -z fits in a uint16 prefix "-" is added to the string. 1003 func (z *Element) Text(base int) string { 1004 if base < 2 || base > 36 { 1005 panic("invalid base") 1006 } 1007 if z == nil { 1008 return "<nil>" 1009 } 1010 1011 const maxUint16 = 65535 1012 if base == 10 { 1013 var zzNeg Element 1014 zzNeg.Neg(z) 1015 zzNeg.fromMont() 1016 if zzNeg.FitsOnOneWord() && zzNeg[0] <= maxUint16 && zzNeg[0] != 0 { 1017 return "-" + strconv.FormatUint(zzNeg[0], base) 1018 } 1019 } 1020 zz := *z 1021 zz.fromMont() 1022 if zz.FitsOnOneWord() { 1023 return strconv.FormatUint(zz[0], base) 1024 } 1025 vv := pool.BigInt.Get() 1026 r := zz.toBigInt(vv).Text(base) 1027 pool.BigInt.Put(vv) 1028 return r 1029 } 1030 1031 // BigInt sets and return z as a *big.Int 1032 func (z *Element) BigInt(res *big.Int) *big.Int { 1033 _z := *z 1034 _z.fromMont() 1035 return _z.toBigInt(res) 1036 } 1037 1038 // ToBigIntRegular returns z as a big.Int in regular form 1039 // 1040 // Deprecated: use BigInt(*big.Int) instead 1041 func (z Element) ToBigIntRegular(res *big.Int) *big.Int { 1042 z.fromMont() 1043 return z.toBigInt(res) 1044 } 1045 1046 // Bits provides access to z by returning its value as a little-endian [6]uint64 array. 1047 // Bits is intended to support implementation of missing low-level Element 1048 // functionality outside this package; it should be avoided otherwise. 1049 func (z *Element) Bits() [6]uint64 { 1050 _z := *z 1051 fromMont(&_z) 1052 return _z 1053 } 1054 1055 // Bytes returns the value of z as a big-endian byte array 1056 func (z *Element) Bytes() (res [Bytes]byte) { 1057 BigEndian.PutElement(&res, *z) 1058 return 1059 } 1060 1061 // Marshal returns the value of z as a big-endian byte slice 1062 func (z *Element) Marshal() []byte { 1063 b := z.Bytes() 1064 return b[:] 1065 } 1066 1067 // Unmarshal is an alias for SetBytes, it sets z to the value of e. 1068 func (z *Element) Unmarshal(e []byte) { 1069 z.SetBytes(e) 1070 } 1071 1072 // SetBytes interprets e as the bytes of a big-endian unsigned integer, 1073 // sets z to that value, and returns z. 1074 func (z *Element) SetBytes(e []byte) *Element { 1075 if len(e) == Bytes { 1076 // fast path 1077 v, err := BigEndian.Element((*[Bytes]byte)(e)) 1078 if err == nil { 1079 *z = v 1080 return z 1081 } 1082 } 1083 1084 // slow path. 1085 // get a big int from our pool 1086 vv := pool.BigInt.Get() 1087 vv.SetBytes(e) 1088 1089 // set big int 1090 z.SetBigInt(vv) 1091 1092 // put temporary object back in pool 1093 pool.BigInt.Put(vv) 1094 1095 return z 1096 } 1097 1098 // SetBytesCanonical interprets e as the bytes of a big-endian 48-byte integer. 1099 // If e is not a 48-byte slice or encodes a value higher than q, 1100 // SetBytesCanonical returns an error. 1101 func (z *Element) SetBytesCanonical(e []byte) error { 1102 if len(e) != Bytes { 1103 return errors.New("invalid fp.Element encoding") 1104 } 1105 v, err := BigEndian.Element((*[Bytes]byte)(e)) 1106 if err != nil { 1107 return err 1108 } 1109 *z = v 1110 return nil 1111 } 1112 1113 // SetBigInt sets z to v and returns z 1114 func (z *Element) SetBigInt(v *big.Int) *Element { 1115 z.SetZero() 1116 1117 var zero big.Int 1118 1119 // fast path 1120 c := v.Cmp(&_modulus) 1121 if c == 0 { 1122 // v == 0 1123 return z 1124 } else if c != 1 && v.Cmp(&zero) != -1 { 1125 // 0 < v < q 1126 return z.setBigInt(v) 1127 } 1128 1129 // get temporary big int from the pool 1130 vv := pool.BigInt.Get() 1131 1132 // copy input + modular reduction 1133 vv.Mod(v, &_modulus) 1134 1135 // set big int byte value 1136 z.setBigInt(vv) 1137 1138 // release object into pool 1139 pool.BigInt.Put(vv) 1140 return z 1141 } 1142 1143 // setBigInt assumes 0 ⩽ v < q 1144 func (z *Element) setBigInt(v *big.Int) *Element { 1145 vBits := v.Bits() 1146 1147 if bits.UintSize == 64 { 1148 for i := 0; i < len(vBits); i++ { 1149 z[i] = uint64(vBits[i]) 1150 } 1151 } else { 1152 for i := 0; i < len(vBits); i++ { 1153 if i%2 == 0 { 1154 z[i/2] = uint64(vBits[i]) 1155 } else { 1156 z[i/2] |= uint64(vBits[i]) << 32 1157 } 1158 } 1159 } 1160 1161 return z.toMont() 1162 } 1163 1164 // SetString creates a big.Int with number and calls SetBigInt on z 1165 // 1166 // The number prefix determines the actual base: A prefix of 1167 // ”0b” or ”0B” selects base 2, ”0”, ”0o” or ”0O” selects base 8, 1168 // and ”0x” or ”0X” selects base 16. Otherwise, the selected base is 10 1169 // and no prefix is accepted. 1170 // 1171 // For base 16, lower and upper case letters are considered the same: 1172 // The letters 'a' to 'f' and 'A' to 'F' represent digit values 10 to 15. 1173 // 1174 // An underscore character ”_” may appear between a base 1175 // prefix and an adjacent digit, and between successive digits; such 1176 // underscores do not change the value of the number. 1177 // Incorrect placement of underscores is reported as a panic if there 1178 // are no other errors. 1179 // 1180 // If the number is invalid this method leaves z unchanged and returns nil, error. 1181 func (z *Element) SetString(number string) (*Element, error) { 1182 // get temporary big int from the pool 1183 vv := pool.BigInt.Get() 1184 1185 if _, ok := vv.SetString(number, 0); !ok { 1186 return nil, errors.New("Element.SetString failed -> can't parse number into a big.Int " + number) 1187 } 1188 1189 z.SetBigInt(vv) 1190 1191 // release object into pool 1192 pool.BigInt.Put(vv) 1193 1194 return z, nil 1195 } 1196 1197 // MarshalJSON returns json encoding of z (z.Text(10)) 1198 // If z == nil, returns null 1199 func (z *Element) MarshalJSON() ([]byte, error) { 1200 if z == nil { 1201 return []byte("null"), nil 1202 } 1203 const maxSafeBound = 15 // we encode it as number if it's small 1204 s := z.Text(10) 1205 if len(s) <= maxSafeBound { 1206 return []byte(s), nil 1207 } 1208 var sbb strings.Builder 1209 sbb.WriteByte('"') 1210 sbb.WriteString(s) 1211 sbb.WriteByte('"') 1212 return []byte(sbb.String()), nil 1213 } 1214 1215 // UnmarshalJSON accepts numbers and strings as input 1216 // See Element.SetString for valid prefixes (0x, 0b, ...) 1217 func (z *Element) UnmarshalJSON(data []byte) error { 1218 s := string(data) 1219 if len(s) > Bits*3 { 1220 return errors.New("value too large (max = Element.Bits * 3)") 1221 } 1222 1223 // we accept numbers and strings, remove leading and trailing quotes if any 1224 if len(s) > 0 && s[0] == '"' { 1225 s = s[1:] 1226 } 1227 if len(s) > 0 && s[len(s)-1] == '"' { 1228 s = s[:len(s)-1] 1229 } 1230 1231 // get temporary big int from the pool 1232 vv := pool.BigInt.Get() 1233 1234 if _, ok := vv.SetString(s, 0); !ok { 1235 return errors.New("can't parse into a big.Int: " + s) 1236 } 1237 1238 z.SetBigInt(vv) 1239 1240 // release object into pool 1241 pool.BigInt.Put(vv) 1242 return nil 1243 } 1244 1245 // A ByteOrder specifies how to convert byte slices into a Element 1246 type ByteOrder interface { 1247 Element(*[Bytes]byte) (Element, error) 1248 PutElement(*[Bytes]byte, Element) 1249 String() string 1250 } 1251 1252 // BigEndian is the big-endian implementation of ByteOrder and AppendByteOrder. 1253 var BigEndian bigEndian 1254 1255 type bigEndian struct{} 1256 1257 // Element interpret b is a big-endian 48-byte slice. 1258 // If b encodes a value higher than q, Element returns error. 1259 func (bigEndian) Element(b *[Bytes]byte) (Element, error) { 1260 var z Element 1261 z[0] = binary.BigEndian.Uint64((*b)[40:48]) 1262 z[1] = binary.BigEndian.Uint64((*b)[32:40]) 1263 z[2] = binary.BigEndian.Uint64((*b)[24:32]) 1264 z[3] = binary.BigEndian.Uint64((*b)[16:24]) 1265 z[4] = binary.BigEndian.Uint64((*b)[8:16]) 1266 z[5] = binary.BigEndian.Uint64((*b)[0:8]) 1267 1268 if !z.smallerThanModulus() { 1269 return Element{}, errors.New("invalid fp.Element encoding") 1270 } 1271 1272 z.toMont() 1273 return z, nil 1274 } 1275 1276 func (bigEndian) PutElement(b *[Bytes]byte, e Element) { 1277 e.fromMont() 1278 binary.BigEndian.PutUint64((*b)[40:48], e[0]) 1279 binary.BigEndian.PutUint64((*b)[32:40], e[1]) 1280 binary.BigEndian.PutUint64((*b)[24:32], e[2]) 1281 binary.BigEndian.PutUint64((*b)[16:24], e[3]) 1282 binary.BigEndian.PutUint64((*b)[8:16], e[4]) 1283 binary.BigEndian.PutUint64((*b)[0:8], e[5]) 1284 } 1285 1286 func (bigEndian) String() string { return "BigEndian" } 1287 1288 // LittleEndian is the little-endian implementation of ByteOrder and AppendByteOrder. 1289 var LittleEndian littleEndian 1290 1291 type littleEndian struct{} 1292 1293 func (littleEndian) Element(b *[Bytes]byte) (Element, error) { 1294 var z Element 1295 z[0] = binary.LittleEndian.Uint64((*b)[0:8]) 1296 z[1] = binary.LittleEndian.Uint64((*b)[8:16]) 1297 z[2] = binary.LittleEndian.Uint64((*b)[16:24]) 1298 z[3] = binary.LittleEndian.Uint64((*b)[24:32]) 1299 z[4] = binary.LittleEndian.Uint64((*b)[32:40]) 1300 z[5] = binary.LittleEndian.Uint64((*b)[40:48]) 1301 1302 if !z.smallerThanModulus() { 1303 return Element{}, errors.New("invalid fp.Element encoding") 1304 } 1305 1306 z.toMont() 1307 return z, nil 1308 } 1309 1310 func (littleEndian) PutElement(b *[Bytes]byte, e Element) { 1311 e.fromMont() 1312 binary.LittleEndian.PutUint64((*b)[0:8], e[0]) 1313 binary.LittleEndian.PutUint64((*b)[8:16], e[1]) 1314 binary.LittleEndian.PutUint64((*b)[16:24], e[2]) 1315 binary.LittleEndian.PutUint64((*b)[24:32], e[3]) 1316 binary.LittleEndian.PutUint64((*b)[32:40], e[4]) 1317 binary.LittleEndian.PutUint64((*b)[40:48], e[5]) 1318 } 1319 1320 func (littleEndian) String() string { return "LittleEndian" } 1321 1322 // Legendre returns the Legendre symbol of z (either +1, -1, or 0.) 1323 func (z *Element) Legendre() int { 1324 var l Element 1325 // z^((q-1)/2) 1326 l.expByLegendreExp(*z) 1327 1328 if l.IsZero() { 1329 return 0 1330 } 1331 1332 // if l == 1 1333 if l.IsOne() { 1334 return 1 1335 } 1336 return -1 1337 } 1338 1339 // Sqrt z = √x (mod q) 1340 // if the square root doesn't exist (x is not a square mod q) 1341 // Sqrt leaves z unchanged and returns nil 1342 func (z *Element) Sqrt(x *Element) *Element { 1343 // q ≡ 1 (mod 4) 1344 // see modSqrtTonelliShanks in math/big/int.go 1345 // using https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf 1346 1347 var y, b, t, w Element 1348 // w = x^((s-1)/2)) 1349 w.expBySqrtExp(*x) 1350 1351 // y = x^((s+1)/2)) = w * x 1352 y.Mul(x, &w) 1353 1354 // b = xˢ = w * w * x = y * x 1355 b.Mul(&w, &y) 1356 1357 // g = nonResidue ^ s 1358 var g = Element{ 1359 15655215628902554004, 1360 15894127656167592378, 1361 9702012166408397168, 1362 12335982559306940759, 1363 1313802173610541430, 1364 81629743607937133, 1365 } 1366 r := uint64(41) 1367 1368 // compute legendre symbol 1369 // t = x^((q-1)/2) = r-1 squaring of xˢ 1370 t = b 1371 for i := uint64(0); i < r-1; i++ { 1372 t.Square(&t) 1373 } 1374 if t.IsZero() { 1375 return z.SetZero() 1376 } 1377 if !t.IsOne() { 1378 // t != 1, we don't have a square root 1379 return nil 1380 } 1381 for { 1382 var m uint64 1383 t = b 1384 1385 // for t != 1 1386 for !t.IsOne() { 1387 t.Square(&t) 1388 m++ 1389 } 1390 1391 if m == 0 { 1392 return z.Set(&y) 1393 } 1394 // t = g^(2^(r-m-1)) (mod q) 1395 ge := int(r - m - 1) 1396 t = g 1397 for ge > 0 { 1398 t.Square(&t) 1399 ge-- 1400 } 1401 1402 g.Square(&t) 1403 y.Mul(&y, &t) 1404 b.Mul(&b, &g) 1405 r = m 1406 } 1407 } 1408 1409 const ( 1410 k = 32 // word size / 2 1411 signBitSelector = uint64(1) << 63 1412 approxLowBitsN = k - 1 1413 approxHighBitsN = k + 1 1414 ) 1415 1416 const ( 1417 inversionCorrectionFactorWord0 = 851295657643717122 1418 inversionCorrectionFactorWord1 = 10857859049187504913 1419 inversionCorrectionFactorWord2 = 7148604188520083019 1420 inversionCorrectionFactorWord3 = 1138623559447261654 1421 inversionCorrectionFactorWord4 = 1203095380280779597 1422 inversionCorrectionFactorWord5 = 148579538565968037 1423 invIterationsN = 26 1424 ) 1425 1426 // Inverse z = x⁻¹ (mod q) 1427 // 1428 // if x == 0, sets and returns z = x 1429 func (z *Element) Inverse(x *Element) *Element { 1430 // Implements "Optimized Binary GCD for Modular Inversion" 1431 // https://github.com/pornin/bingcd/blob/main/doc/bingcd.pdf 1432 1433 a := *x 1434 b := Element{ 1435 q0, 1436 q1, 1437 q2, 1438 q3, 1439 q4, 1440 q5, 1441 } // b := q 1442 1443 u := Element{1} 1444 1445 // Update factors: we get [u; v] ← [f₀ g₀; f₁ g₁] [u; v] 1446 // cᵢ = fᵢ + 2³¹ - 1 + 2³² * (gᵢ + 2³¹ - 1) 1447 var c0, c1 int64 1448 1449 // Saved update factors to reduce the number of field multiplications 1450 var pf0, pf1, pg0, pg1 int64 1451 1452 var i uint 1453 1454 var v, s Element 1455 1456 // Since u,v are updated every other iteration, we must make sure we terminate after evenly many iterations 1457 // This also lets us get away with half as many updates to u,v 1458 // To make this constant-time-ish, replace the condition with i < invIterationsN 1459 for i = 0; i&1 == 1 || !a.IsZero(); i++ { 1460 n := max(a.BitLen(), b.BitLen()) 1461 aApprox, bApprox := approximate(&a, n), approximate(&b, n) 1462 1463 // f₀, g₀, f₁, g₁ = 1, 0, 0, 1 1464 c0, c1 = updateFactorIdentityMatrixRow0, updateFactorIdentityMatrixRow1 1465 1466 for j := 0; j < approxLowBitsN; j++ { 1467 1468 // -2ʲ < f₀, f₁ ≤ 2ʲ 1469 // |f₀| + |f₁| < 2ʲ⁺¹ 1470 1471 if aApprox&1 == 0 { 1472 aApprox /= 2 1473 } else { 1474 s, borrow := bits.Sub64(aApprox, bApprox, 0) 1475 if borrow == 1 { 1476 s = bApprox - aApprox 1477 bApprox = aApprox 1478 c0, c1 = c1, c0 1479 // invariants unchanged 1480 } 1481 1482 aApprox = s / 2 1483 c0 = c0 - c1 1484 1485 // Now |f₀| < 2ʲ⁺¹ ≤ 2ʲ⁺¹ (only the weaker inequality is needed, strictly speaking) 1486 // Started with f₀ > -2ʲ and f₁ ≤ 2ʲ, so f₀ - f₁ > -2ʲ⁺¹ 1487 // Invariants unchanged for f₁ 1488 } 1489 1490 c1 *= 2 1491 // -2ʲ⁺¹ < f₁ ≤ 2ʲ⁺¹ 1492 // So now |f₀| + |f₁| < 2ʲ⁺² 1493 } 1494 1495 s = a 1496 1497 var g0 int64 1498 // from this point on c0 aliases for f0 1499 c0, g0 = updateFactorsDecompose(c0) 1500 aHi := a.linearCombNonModular(&s, c0, &b, g0) 1501 if aHi&signBitSelector != 0 { 1502 // if aHi < 0 1503 c0, g0 = -c0, -g0 1504 aHi = negL(&a, aHi) 1505 } 1506 // right-shift a by k-1 bits 1507 a[0] = (a[0] >> approxLowBitsN) | ((a[1]) << approxHighBitsN) 1508 a[1] = (a[1] >> approxLowBitsN) | ((a[2]) << approxHighBitsN) 1509 a[2] = (a[2] >> approxLowBitsN) | ((a[3]) << approxHighBitsN) 1510 a[3] = (a[3] >> approxLowBitsN) | ((a[4]) << approxHighBitsN) 1511 a[4] = (a[4] >> approxLowBitsN) | ((a[5]) << approxHighBitsN) 1512 a[5] = (a[5] >> approxLowBitsN) | (aHi << approxHighBitsN) 1513 1514 var f1 int64 1515 // from this point on c1 aliases for g0 1516 f1, c1 = updateFactorsDecompose(c1) 1517 bHi := b.linearCombNonModular(&s, f1, &b, c1) 1518 if bHi&signBitSelector != 0 { 1519 // if bHi < 0 1520 f1, c1 = -f1, -c1 1521 bHi = negL(&b, bHi) 1522 } 1523 // right-shift b by k-1 bits 1524 b[0] = (b[0] >> approxLowBitsN) | ((b[1]) << approxHighBitsN) 1525 b[1] = (b[1] >> approxLowBitsN) | ((b[2]) << approxHighBitsN) 1526 b[2] = (b[2] >> approxLowBitsN) | ((b[3]) << approxHighBitsN) 1527 b[3] = (b[3] >> approxLowBitsN) | ((b[4]) << approxHighBitsN) 1528 b[4] = (b[4] >> approxLowBitsN) | ((b[5]) << approxHighBitsN) 1529 b[5] = (b[5] >> approxLowBitsN) | (bHi << approxHighBitsN) 1530 1531 if i&1 == 1 { 1532 // Combine current update factors with previously stored ones 1533 // [F₀, G₀; F₁, G₁] ← [f₀, g₀; f₁, g₁] [pf₀, pg₀; pf₁, pg₁], with capital letters denoting new combined values 1534 // We get |F₀| = | f₀pf₀ + g₀pf₁ | ≤ |f₀pf₀| + |g₀pf₁| = |f₀| |pf₀| + |g₀| |pf₁| ≤ 2ᵏ⁻¹|pf₀| + 2ᵏ⁻¹|pf₁| 1535 // = 2ᵏ⁻¹ (|pf₀| + |pf₁|) < 2ᵏ⁻¹ 2ᵏ = 2²ᵏ⁻¹ 1536 // So |F₀| < 2²ᵏ⁻¹ meaning it fits in a 2k-bit signed register 1537 1538 // c₀ aliases f₀, c₁ aliases g₁ 1539 c0, g0, f1, c1 = c0*pf0+g0*pf1, 1540 c0*pg0+g0*pg1, 1541 f1*pf0+c1*pf1, 1542 f1*pg0+c1*pg1 1543 1544 s = u 1545 1546 // 0 ≤ u, v < 2²⁵⁵ 1547 // |F₀|, |G₀| < 2⁶³ 1548 u.linearComb(&u, c0, &v, g0) 1549 // |F₁|, |G₁| < 2⁶³ 1550 v.linearComb(&s, f1, &v, c1) 1551 1552 } else { 1553 // Save update factors 1554 pf0, pg0, pf1, pg1 = c0, g0, f1, c1 1555 } 1556 } 1557 1558 // For every iteration that we miss, v is not being multiplied by 2ᵏ⁻² 1559 const pSq uint64 = 1 << (2 * (k - 1)) 1560 a = Element{pSq} 1561 // If the function is constant-time ish, this loop will not run (no need to take it out explicitly) 1562 for ; i < invIterationsN; i += 2 { 1563 // could optimize further with mul by word routine or by pre-computing a table since with k=26, 1564 // we would multiply by pSq up to 13times; 1565 // on x86, the assembly routine outperforms generic code for mul by word 1566 // on arm64, we may loose up to ~5% for 6 limbs 1567 v.Mul(&v, &a) 1568 } 1569 1570 u.Set(x) // for correctness check 1571 1572 z.Mul(&v, &Element{ 1573 inversionCorrectionFactorWord0, 1574 inversionCorrectionFactorWord1, 1575 inversionCorrectionFactorWord2, 1576 inversionCorrectionFactorWord3, 1577 inversionCorrectionFactorWord4, 1578 inversionCorrectionFactorWord5, 1579 }) 1580 1581 // correctness check 1582 v.Mul(&u, z) 1583 if !v.IsOne() && !u.IsZero() { 1584 return z.inverseExp(u) 1585 } 1586 1587 return z 1588 } 1589 1590 // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) 1591 func (z *Element) inverseExp(x Element) *Element { 1592 // e == q-2 1593 e := Modulus() 1594 e.Sub(e, big.NewInt(2)) 1595 1596 z.Set(&x) 1597 1598 for i := e.BitLen() - 2; i >= 0; i-- { 1599 z.Square(z) 1600 if e.Bit(i) == 1 { 1601 z.Mul(z, &x) 1602 } 1603 } 1604 1605 return z 1606 } 1607 1608 // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits 1609 // if x fits in a word as is, no approximation necessary 1610 func approximate(x *Element, nBits int) uint64 { 1611 1612 if nBits <= 64 { 1613 return x[0] 1614 } 1615 1616 const mask = (uint64(1) << (k - 1)) - 1 // k-1 ones 1617 lo := mask & x[0] 1618 1619 hiWordIndex := (nBits - 1) / 64 1620 1621 hiWordBitsAvailable := nBits - hiWordIndex*64 1622 hiWordBitsUsed := min(hiWordBitsAvailable, approxHighBitsN) 1623 1624 mask_ := uint64(^((1 << (hiWordBitsAvailable - hiWordBitsUsed)) - 1)) 1625 hi := (x[hiWordIndex] & mask_) << (64 - hiWordBitsAvailable) 1626 1627 mask_ = ^(1<<(approxLowBitsN+hiWordBitsUsed) - 1) 1628 mid := (mask_ & x[hiWordIndex-1]) >> hiWordBitsUsed 1629 1630 return lo | mid | hi 1631 } 1632 1633 // linearComb z = xC * x + yC * y; 1634 // 0 ≤ x, y < 2³⁷⁸ 1635 // |xC|, |yC| < 2⁶³ 1636 func (z *Element) linearComb(x *Element, xC int64, y *Element, yC int64) { 1637 // | (hi, z) | < 2 * 2⁶³ * 2³⁷⁸ = 2⁴⁴² 1638 // therefore | hi | < 2⁵⁸ ≤ 2⁶³ 1639 hi := z.linearCombNonModular(x, xC, y, yC) 1640 z.montReduceSigned(z, hi) 1641 } 1642 1643 // montReduceSigned z = (xHi * r + x) * r⁻¹ using the SOS algorithm 1644 // Requires |xHi| < 2⁶³. Most significant bit of xHi is the sign bit. 1645 func (z *Element) montReduceSigned(x *Element, xHi uint64) { 1646 const signBitRemover = ^signBitSelector 1647 mustNeg := xHi&signBitSelector != 0 1648 // the SOS implementation requires that most significant bit is 0 1649 // Let X be xHi*r + x 1650 // If X is negative we would have initially stored it as 2⁶⁴ r + X (à la 2's complement) 1651 xHi &= signBitRemover 1652 // with this a negative X is now represented as 2⁶³ r + X 1653 1654 var t [2*Limbs - 1]uint64 1655 var C uint64 1656 1657 m := x[0] * qInvNeg 1658 1659 C = madd0(m, q0, x[0]) 1660 C, t[1] = madd2(m, q1, x[1], C) 1661 C, t[2] = madd2(m, q2, x[2], C) 1662 C, t[3] = madd2(m, q3, x[3], C) 1663 C, t[4] = madd2(m, q4, x[4], C) 1664 C, t[5] = madd2(m, q5, x[5], C) 1665 1666 // m * qElement[5] ≤ (2⁶⁴ - 1) * (2⁶³ - 1) = 2¹²⁷ - 2⁶⁴ - 2⁶³ + 1 1667 // x[5] + C ≤ 2*(2⁶⁴ - 1) = 2⁶⁵ - 2 1668 // On LHS, (C, t[5]) ≤ 2¹²⁷ - 2⁶⁴ - 2⁶³ + 1 + 2⁶⁵ - 2 = 2¹²⁷ + 2⁶³ - 1 1669 // So on LHS, C ≤ 2⁶³ 1670 t[6] = xHi + C 1671 // xHi + C < 2⁶³ + 2⁶³ = 2⁶⁴ 1672 1673 // <standard SOS> 1674 { 1675 const i = 1 1676 m = t[i] * qInvNeg 1677 1678 C = madd0(m, q0, t[i+0]) 1679 C, t[i+1] = madd2(m, q1, t[i+1], C) 1680 C, t[i+2] = madd2(m, q2, t[i+2], C) 1681 C, t[i+3] = madd2(m, q3, t[i+3], C) 1682 C, t[i+4] = madd2(m, q4, t[i+4], C) 1683 C, t[i+5] = madd2(m, q5, t[i+5], C) 1684 1685 t[i+Limbs] += C 1686 } 1687 { 1688 const i = 2 1689 m = t[i] * qInvNeg 1690 1691 C = madd0(m, q0, t[i+0]) 1692 C, t[i+1] = madd2(m, q1, t[i+1], C) 1693 C, t[i+2] = madd2(m, q2, t[i+2], C) 1694 C, t[i+3] = madd2(m, q3, t[i+3], C) 1695 C, t[i+4] = madd2(m, q4, t[i+4], C) 1696 C, t[i+5] = madd2(m, q5, t[i+5], C) 1697 1698 t[i+Limbs] += C 1699 } 1700 { 1701 const i = 3 1702 m = t[i] * qInvNeg 1703 1704 C = madd0(m, q0, t[i+0]) 1705 C, t[i+1] = madd2(m, q1, t[i+1], C) 1706 C, t[i+2] = madd2(m, q2, t[i+2], C) 1707 C, t[i+3] = madd2(m, q3, t[i+3], C) 1708 C, t[i+4] = madd2(m, q4, t[i+4], C) 1709 C, t[i+5] = madd2(m, q5, t[i+5], C) 1710 1711 t[i+Limbs] += C 1712 } 1713 { 1714 const i = 4 1715 m = t[i] * qInvNeg 1716 1717 C = madd0(m, q0, t[i+0]) 1718 C, t[i+1] = madd2(m, q1, t[i+1], C) 1719 C, t[i+2] = madd2(m, q2, t[i+2], C) 1720 C, t[i+3] = madd2(m, q3, t[i+3], C) 1721 C, t[i+4] = madd2(m, q4, t[i+4], C) 1722 C, t[i+5] = madd2(m, q5, t[i+5], C) 1723 1724 t[i+Limbs] += C 1725 } 1726 { 1727 const i = 5 1728 m := t[i] * qInvNeg 1729 1730 C = madd0(m, q0, t[i+0]) 1731 C, z[0] = madd2(m, q1, t[i+1], C) 1732 C, z[1] = madd2(m, q2, t[i+2], C) 1733 C, z[2] = madd2(m, q3, t[i+3], C) 1734 C, z[3] = madd2(m, q4, t[i+4], C) 1735 z[5], z[4] = madd2(m, q5, t[i+5], C) 1736 } 1737 1738 // if z ⩾ q → z -= q 1739 if !z.smallerThanModulus() { 1740 var b uint64 1741 z[0], b = bits.Sub64(z[0], q0, 0) 1742 z[1], b = bits.Sub64(z[1], q1, b) 1743 z[2], b = bits.Sub64(z[2], q2, b) 1744 z[3], b = bits.Sub64(z[3], q3, b) 1745 z[4], b = bits.Sub64(z[4], q4, b) 1746 z[5], _ = bits.Sub64(z[5], q5, b) 1747 } 1748 // </standard SOS> 1749 1750 if mustNeg { 1751 // We have computed ( 2⁶³ r + X ) r⁻¹ = 2⁶³ + X r⁻¹ instead 1752 var b uint64 1753 z[0], b = bits.Sub64(z[0], signBitSelector, 0) 1754 z[1], b = bits.Sub64(z[1], 0, b) 1755 z[2], b = bits.Sub64(z[2], 0, b) 1756 z[3], b = bits.Sub64(z[3], 0, b) 1757 z[4], b = bits.Sub64(z[4], 0, b) 1758 z[5], b = bits.Sub64(z[5], 0, b) 1759 1760 // Occurs iff x == 0 && xHi < 0, i.e. X = rX' for -2⁶³ ≤ X' < 0 1761 1762 if b != 0 { 1763 // z[5] = -1 1764 // negative: add q 1765 const neg1 = 0xFFFFFFFFFFFFFFFF 1766 1767 var carry uint64 1768 1769 z[0], carry = bits.Add64(z[0], q0, 0) 1770 z[1], carry = bits.Add64(z[1], q1, carry) 1771 z[2], carry = bits.Add64(z[2], q2, carry) 1772 z[3], carry = bits.Add64(z[3], q3, carry) 1773 z[4], carry = bits.Add64(z[4], q4, carry) 1774 z[5], _ = bits.Add64(neg1, q5, carry) 1775 } 1776 } 1777 } 1778 1779 const ( 1780 updateFactorsConversionBias int64 = 0x7fffffff7fffffff // (2³¹ - 1)(2³² + 1) 1781 updateFactorIdentityMatrixRow0 = 1 1782 updateFactorIdentityMatrixRow1 = 1 << 32 1783 ) 1784 1785 func updateFactorsDecompose(c int64) (int64, int64) { 1786 c += updateFactorsConversionBias 1787 const low32BitsFilter int64 = 0xFFFFFFFF 1788 f := c&low32BitsFilter - 0x7FFFFFFF 1789 g := c>>32&low32BitsFilter - 0x7FFFFFFF 1790 return f, g 1791 } 1792 1793 // negL negates in place [x | xHi] and return the new most significant word xHi 1794 func negL(x *Element, xHi uint64) uint64 { 1795 var b uint64 1796 1797 x[0], b = bits.Sub64(0, x[0], 0) 1798 x[1], b = bits.Sub64(0, x[1], b) 1799 x[2], b = bits.Sub64(0, x[2], b) 1800 x[3], b = bits.Sub64(0, x[3], b) 1801 x[4], b = bits.Sub64(0, x[4], b) 1802 x[5], b = bits.Sub64(0, x[5], b) 1803 xHi, _ = bits.Sub64(0, xHi, b) 1804 1805 return xHi 1806 } 1807 1808 // mulWNonModular multiplies by one word in non-montgomery, without reducing 1809 func (z *Element) mulWNonModular(x *Element, y int64) uint64 { 1810 1811 // w := abs(y) 1812 m := y >> 63 1813 w := uint64((y ^ m) - m) 1814 1815 var c uint64 1816 c, z[0] = bits.Mul64(x[0], w) 1817 c, z[1] = madd1(x[1], w, c) 1818 c, z[2] = madd1(x[2], w, c) 1819 c, z[3] = madd1(x[3], w, c) 1820 c, z[4] = madd1(x[4], w, c) 1821 c, z[5] = madd1(x[5], w, c) 1822 1823 if y < 0 { 1824 c = negL(z, c) 1825 } 1826 1827 return c 1828 } 1829 1830 // linearCombNonModular computes a linear combination without modular reduction 1831 func (z *Element) linearCombNonModular(x *Element, xC int64, y *Element, yC int64) uint64 { 1832 var yTimes Element 1833 1834 yHi := yTimes.mulWNonModular(y, yC) 1835 xHi := z.mulWNonModular(x, xC) 1836 1837 var carry uint64 1838 z[0], carry = bits.Add64(z[0], yTimes[0], 0) 1839 z[1], carry = bits.Add64(z[1], yTimes[1], carry) 1840 z[2], carry = bits.Add64(z[2], yTimes[2], carry) 1841 z[3], carry = bits.Add64(z[3], yTimes[3], carry) 1842 z[4], carry = bits.Add64(z[4], yTimes[4], carry) 1843 z[5], carry = bits.Add64(z[5], yTimes[5], carry) 1844 1845 yHi, _ = bits.Add64(xHi, yHi, carry) 1846 1847 return yHi 1848 }