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