github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/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] = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 42 // q[base16] = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab 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 = 381 // 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 = 13402431016077863595 58 q1 uint64 = 2210141511517208575 59 q2 uint64 = 7435674573564081700 60 q3 uint64 = 7239337960414712511 61 q4 uint64 = 5412103778470702295 62 q5 uint64 = 1873798617647539866 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] = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 79 // q[base16] = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab 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 = 9940570264628428797 87 88 func init() { 89 _modulus.SetString("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 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] = 8505329371266088957 212 z[1] = 17002214543764226050 213 z[2] = 6865905132761471162 214 z[3] = 8632934651105793861 215 z[4] = 6631298214892334189 216 z[5] = 1582556514881692819 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] ^ 1582556514881692819) | (z[4] ^ 6631298214892334189) | (z[3] ^ 8632934651105793861) | (z[2] ^ 6865905132761471162) | (z[1] ^ 17002214543764226050) | (z[0] ^ 8505329371266088957)) == 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], 15924587544893707606, 0) 319 _, b = bits.Sub64(_z[1], 1105070755758604287, b) 320 _, b = bits.Sub64(_z[2], 12941209323636816658, b) 321 _, b = bits.Sub64(_z[3], 12843041017062132063, b) 322 _, b = bits.Sub64(_z[4], 2706051889235351147, b) 323 _, b = bits.Sub64(_z[5], 936899308823769933, 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 = 381 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 17644856173732828998, 965 754043588434789617, 966 10224657059481499349, 967 7488229067341005760, 968 11130996698012816685, 969 1267921511277847466, 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 ≡ 3 (mod 4) 1344 // using z ≡ ± x^((p+1)/4) (mod q) 1345 var y, square Element 1346 y.expBySqrtExp(*x) 1347 // as we didn't compute the legendre symbol, ensure we found y such that y * y = x 1348 square.Square(&y) 1349 if square.Equal(x) { 1350 return z.Set(&y) 1351 } 1352 return nil 1353 } 1354 1355 const ( 1356 k = 32 // word size / 2 1357 signBitSelector = uint64(1) << 63 1358 approxLowBitsN = k - 1 1359 approxHighBitsN = k + 1 1360 ) 1361 1362 const ( 1363 inversionCorrectionFactorWord0 = 8737414717120368535 1364 inversionCorrectionFactorWord1 = 10094300570241649429 1365 inversionCorrectionFactorWord2 = 6339946188669102923 1366 inversionCorrectionFactorWord3 = 10492640117780001228 1367 inversionCorrectionFactorWord4 = 12201317704601795701 1368 inversionCorrectionFactorWord5 = 1158882751927031822 1369 invIterationsN = 26 1370 ) 1371 1372 // Inverse z = x⁻¹ (mod q) 1373 // 1374 // if x == 0, sets and returns z = x 1375 func (z *Element) Inverse(x *Element) *Element { 1376 // Implements "Optimized Binary GCD for Modular Inversion" 1377 // https://github.com/pornin/bingcd/blob/main/doc/bingcd.pdf 1378 1379 a := *x 1380 b := Element{ 1381 q0, 1382 q1, 1383 q2, 1384 q3, 1385 q4, 1386 q5, 1387 } // b := q 1388 1389 u := Element{1} 1390 1391 // Update factors: we get [u; v] ← [f₀ g₀; f₁ g₁] [u; v] 1392 // cᵢ = fᵢ + 2³¹ - 1 + 2³² * (gᵢ + 2³¹ - 1) 1393 var c0, c1 int64 1394 1395 // Saved update factors to reduce the number of field multiplications 1396 var pf0, pf1, pg0, pg1 int64 1397 1398 var i uint 1399 1400 var v, s Element 1401 1402 // Since u,v are updated every other iteration, we must make sure we terminate after evenly many iterations 1403 // This also lets us get away with half as many updates to u,v 1404 // To make this constant-time-ish, replace the condition with i < invIterationsN 1405 for i = 0; i&1 == 1 || !a.IsZero(); i++ { 1406 n := max(a.BitLen(), b.BitLen()) 1407 aApprox, bApprox := approximate(&a, n), approximate(&b, n) 1408 1409 // f₀, g₀, f₁, g₁ = 1, 0, 0, 1 1410 c0, c1 = updateFactorIdentityMatrixRow0, updateFactorIdentityMatrixRow1 1411 1412 for j := 0; j < approxLowBitsN; j++ { 1413 1414 // -2ʲ < f₀, f₁ ≤ 2ʲ 1415 // |f₀| + |f₁| < 2ʲ⁺¹ 1416 1417 if aApprox&1 == 0 { 1418 aApprox /= 2 1419 } else { 1420 s, borrow := bits.Sub64(aApprox, bApprox, 0) 1421 if borrow == 1 { 1422 s = bApprox - aApprox 1423 bApprox = aApprox 1424 c0, c1 = c1, c0 1425 // invariants unchanged 1426 } 1427 1428 aApprox = s / 2 1429 c0 = c0 - c1 1430 1431 // Now |f₀| < 2ʲ⁺¹ ≤ 2ʲ⁺¹ (only the weaker inequality is needed, strictly speaking) 1432 // Started with f₀ > -2ʲ and f₁ ≤ 2ʲ, so f₀ - f₁ > -2ʲ⁺¹ 1433 // Invariants unchanged for f₁ 1434 } 1435 1436 c1 *= 2 1437 // -2ʲ⁺¹ < f₁ ≤ 2ʲ⁺¹ 1438 // So now |f₀| + |f₁| < 2ʲ⁺² 1439 } 1440 1441 s = a 1442 1443 var g0 int64 1444 // from this point on c0 aliases for f0 1445 c0, g0 = updateFactorsDecompose(c0) 1446 aHi := a.linearCombNonModular(&s, c0, &b, g0) 1447 if aHi&signBitSelector != 0 { 1448 // if aHi < 0 1449 c0, g0 = -c0, -g0 1450 aHi = negL(&a, aHi) 1451 } 1452 // right-shift a by k-1 bits 1453 a[0] = (a[0] >> approxLowBitsN) | ((a[1]) << approxHighBitsN) 1454 a[1] = (a[1] >> approxLowBitsN) | ((a[2]) << approxHighBitsN) 1455 a[2] = (a[2] >> approxLowBitsN) | ((a[3]) << approxHighBitsN) 1456 a[3] = (a[3] >> approxLowBitsN) | ((a[4]) << approxHighBitsN) 1457 a[4] = (a[4] >> approxLowBitsN) | ((a[5]) << approxHighBitsN) 1458 a[5] = (a[5] >> approxLowBitsN) | (aHi << approxHighBitsN) 1459 1460 var f1 int64 1461 // from this point on c1 aliases for g0 1462 f1, c1 = updateFactorsDecompose(c1) 1463 bHi := b.linearCombNonModular(&s, f1, &b, c1) 1464 if bHi&signBitSelector != 0 { 1465 // if bHi < 0 1466 f1, c1 = -f1, -c1 1467 bHi = negL(&b, bHi) 1468 } 1469 // right-shift b by k-1 bits 1470 b[0] = (b[0] >> approxLowBitsN) | ((b[1]) << approxHighBitsN) 1471 b[1] = (b[1] >> approxLowBitsN) | ((b[2]) << approxHighBitsN) 1472 b[2] = (b[2] >> approxLowBitsN) | ((b[3]) << approxHighBitsN) 1473 b[3] = (b[3] >> approxLowBitsN) | ((b[4]) << approxHighBitsN) 1474 b[4] = (b[4] >> approxLowBitsN) | ((b[5]) << approxHighBitsN) 1475 b[5] = (b[5] >> approxLowBitsN) | (bHi << approxHighBitsN) 1476 1477 if i&1 == 1 { 1478 // Combine current update factors with previously stored ones 1479 // [F₀, G₀; F₁, G₁] ← [f₀, g₀; f₁, g₁] [pf₀, pg₀; pf₁, pg₁], with capital letters denoting new combined values 1480 // We get |F₀| = | f₀pf₀ + g₀pf₁ | ≤ |f₀pf₀| + |g₀pf₁| = |f₀| |pf₀| + |g₀| |pf₁| ≤ 2ᵏ⁻¹|pf₀| + 2ᵏ⁻¹|pf₁| 1481 // = 2ᵏ⁻¹ (|pf₀| + |pf₁|) < 2ᵏ⁻¹ 2ᵏ = 2²ᵏ⁻¹ 1482 // So |F₀| < 2²ᵏ⁻¹ meaning it fits in a 2k-bit signed register 1483 1484 // c₀ aliases f₀, c₁ aliases g₁ 1485 c0, g0, f1, c1 = c0*pf0+g0*pf1, 1486 c0*pg0+g0*pg1, 1487 f1*pf0+c1*pf1, 1488 f1*pg0+c1*pg1 1489 1490 s = u 1491 1492 // 0 ≤ u, v < 2²⁵⁵ 1493 // |F₀|, |G₀| < 2⁶³ 1494 u.linearComb(&u, c0, &v, g0) 1495 // |F₁|, |G₁| < 2⁶³ 1496 v.linearComb(&s, f1, &v, c1) 1497 1498 } else { 1499 // Save update factors 1500 pf0, pg0, pf1, pg1 = c0, g0, f1, c1 1501 } 1502 } 1503 1504 // For every iteration that we miss, v is not being multiplied by 2ᵏ⁻² 1505 const pSq uint64 = 1 << (2 * (k - 1)) 1506 a = Element{pSq} 1507 // If the function is constant-time ish, this loop will not run (no need to take it out explicitly) 1508 for ; i < invIterationsN; i += 2 { 1509 // could optimize further with mul by word routine or by pre-computing a table since with k=26, 1510 // we would multiply by pSq up to 13times; 1511 // on x86, the assembly routine outperforms generic code for mul by word 1512 // on arm64, we may loose up to ~5% for 6 limbs 1513 v.Mul(&v, &a) 1514 } 1515 1516 u.Set(x) // for correctness check 1517 1518 z.Mul(&v, &Element{ 1519 inversionCorrectionFactorWord0, 1520 inversionCorrectionFactorWord1, 1521 inversionCorrectionFactorWord2, 1522 inversionCorrectionFactorWord3, 1523 inversionCorrectionFactorWord4, 1524 inversionCorrectionFactorWord5, 1525 }) 1526 1527 // correctness check 1528 v.Mul(&u, z) 1529 if !v.IsOne() && !u.IsZero() { 1530 return z.inverseExp(u) 1531 } 1532 1533 return z 1534 } 1535 1536 // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q) 1537 func (z *Element) inverseExp(x Element) *Element { 1538 // e == q-2 1539 e := Modulus() 1540 e.Sub(e, big.NewInt(2)) 1541 1542 z.Set(&x) 1543 1544 for i := e.BitLen() - 2; i >= 0; i-- { 1545 z.Square(z) 1546 if e.Bit(i) == 1 { 1547 z.Mul(z, &x) 1548 } 1549 } 1550 1551 return z 1552 } 1553 1554 // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits 1555 // if x fits in a word as is, no approximation necessary 1556 func approximate(x *Element, nBits int) uint64 { 1557 1558 if nBits <= 64 { 1559 return x[0] 1560 } 1561 1562 const mask = (uint64(1) << (k - 1)) - 1 // k-1 ones 1563 lo := mask & x[0] 1564 1565 hiWordIndex := (nBits - 1) / 64 1566 1567 hiWordBitsAvailable := nBits - hiWordIndex*64 1568 hiWordBitsUsed := min(hiWordBitsAvailable, approxHighBitsN) 1569 1570 mask_ := uint64(^((1 << (hiWordBitsAvailable - hiWordBitsUsed)) - 1)) 1571 hi := (x[hiWordIndex] & mask_) << (64 - hiWordBitsAvailable) 1572 1573 mask_ = ^(1<<(approxLowBitsN+hiWordBitsUsed) - 1) 1574 mid := (mask_ & x[hiWordIndex-1]) >> hiWordBitsUsed 1575 1576 return lo | mid | hi 1577 } 1578 1579 // linearComb z = xC * x + yC * y; 1580 // 0 ≤ x, y < 2³⁸¹ 1581 // |xC|, |yC| < 2⁶³ 1582 func (z *Element) linearComb(x *Element, xC int64, y *Element, yC int64) { 1583 // | (hi, z) | < 2 * 2⁶³ * 2³⁸¹ = 2⁴⁴⁵ 1584 // therefore | hi | < 2⁶¹ ≤ 2⁶³ 1585 hi := z.linearCombNonModular(x, xC, y, yC) 1586 z.montReduceSigned(z, hi) 1587 } 1588 1589 // montReduceSigned z = (xHi * r + x) * r⁻¹ using the SOS algorithm 1590 // Requires |xHi| < 2⁶³. Most significant bit of xHi is the sign bit. 1591 func (z *Element) montReduceSigned(x *Element, xHi uint64) { 1592 const signBitRemover = ^signBitSelector 1593 mustNeg := xHi&signBitSelector != 0 1594 // the SOS implementation requires that most significant bit is 0 1595 // Let X be xHi*r + x 1596 // If X is negative we would have initially stored it as 2⁶⁴ r + X (à la 2's complement) 1597 xHi &= signBitRemover 1598 // with this a negative X is now represented as 2⁶³ r + X 1599 1600 var t [2*Limbs - 1]uint64 1601 var C uint64 1602 1603 m := x[0] * qInvNeg 1604 1605 C = madd0(m, q0, x[0]) 1606 C, t[1] = madd2(m, q1, x[1], C) 1607 C, t[2] = madd2(m, q2, x[2], C) 1608 C, t[3] = madd2(m, q3, x[3], C) 1609 C, t[4] = madd2(m, q4, x[4], C) 1610 C, t[5] = madd2(m, q5, x[5], C) 1611 1612 // m * qElement[5] ≤ (2⁶⁴ - 1) * (2⁶³ - 1) = 2¹²⁷ - 2⁶⁴ - 2⁶³ + 1 1613 // x[5] + C ≤ 2*(2⁶⁴ - 1) = 2⁶⁵ - 2 1614 // On LHS, (C, t[5]) ≤ 2¹²⁷ - 2⁶⁴ - 2⁶³ + 1 + 2⁶⁵ - 2 = 2¹²⁷ + 2⁶³ - 1 1615 // So on LHS, C ≤ 2⁶³ 1616 t[6] = xHi + C 1617 // xHi + C < 2⁶³ + 2⁶³ = 2⁶⁴ 1618 1619 // <standard SOS> 1620 { 1621 const i = 1 1622 m = t[i] * qInvNeg 1623 1624 C = madd0(m, q0, t[i+0]) 1625 C, t[i+1] = madd2(m, q1, t[i+1], C) 1626 C, t[i+2] = madd2(m, q2, t[i+2], C) 1627 C, t[i+3] = madd2(m, q3, t[i+3], C) 1628 C, t[i+4] = madd2(m, q4, t[i+4], C) 1629 C, t[i+5] = madd2(m, q5, t[i+5], C) 1630 1631 t[i+Limbs] += C 1632 } 1633 { 1634 const i = 2 1635 m = t[i] * qInvNeg 1636 1637 C = madd0(m, q0, t[i+0]) 1638 C, t[i+1] = madd2(m, q1, t[i+1], C) 1639 C, t[i+2] = madd2(m, q2, t[i+2], C) 1640 C, t[i+3] = madd2(m, q3, t[i+3], C) 1641 C, t[i+4] = madd2(m, q4, t[i+4], C) 1642 C, t[i+5] = madd2(m, q5, t[i+5], C) 1643 1644 t[i+Limbs] += C 1645 } 1646 { 1647 const i = 3 1648 m = t[i] * qInvNeg 1649 1650 C = madd0(m, q0, t[i+0]) 1651 C, t[i+1] = madd2(m, q1, t[i+1], C) 1652 C, t[i+2] = madd2(m, q2, t[i+2], C) 1653 C, t[i+3] = madd2(m, q3, t[i+3], C) 1654 C, t[i+4] = madd2(m, q4, t[i+4], C) 1655 C, t[i+5] = madd2(m, q5, t[i+5], C) 1656 1657 t[i+Limbs] += C 1658 } 1659 { 1660 const i = 4 1661 m = t[i] * qInvNeg 1662 1663 C = madd0(m, q0, t[i+0]) 1664 C, t[i+1] = madd2(m, q1, t[i+1], C) 1665 C, t[i+2] = madd2(m, q2, t[i+2], C) 1666 C, t[i+3] = madd2(m, q3, t[i+3], C) 1667 C, t[i+4] = madd2(m, q4, t[i+4], C) 1668 C, t[i+5] = madd2(m, q5, t[i+5], C) 1669 1670 t[i+Limbs] += C 1671 } 1672 { 1673 const i = 5 1674 m := t[i] * qInvNeg 1675 1676 C = madd0(m, q0, t[i+0]) 1677 C, z[0] = madd2(m, q1, t[i+1], C) 1678 C, z[1] = madd2(m, q2, t[i+2], C) 1679 C, z[2] = madd2(m, q3, t[i+3], C) 1680 C, z[3] = madd2(m, q4, t[i+4], C) 1681 z[5], z[4] = madd2(m, q5, t[i+5], C) 1682 } 1683 1684 // if z ⩾ q → z -= q 1685 if !z.smallerThanModulus() { 1686 var b uint64 1687 z[0], b = bits.Sub64(z[0], q0, 0) 1688 z[1], b = bits.Sub64(z[1], q1, b) 1689 z[2], b = bits.Sub64(z[2], q2, b) 1690 z[3], b = bits.Sub64(z[3], q3, b) 1691 z[4], b = bits.Sub64(z[4], q4, b) 1692 z[5], _ = bits.Sub64(z[5], q5, b) 1693 } 1694 // </standard SOS> 1695 1696 if mustNeg { 1697 // We have computed ( 2⁶³ r + X ) r⁻¹ = 2⁶³ + X r⁻¹ instead 1698 var b uint64 1699 z[0], b = bits.Sub64(z[0], signBitSelector, 0) 1700 z[1], b = bits.Sub64(z[1], 0, b) 1701 z[2], b = bits.Sub64(z[2], 0, b) 1702 z[3], b = bits.Sub64(z[3], 0, b) 1703 z[4], b = bits.Sub64(z[4], 0, b) 1704 z[5], b = bits.Sub64(z[5], 0, b) 1705 1706 // Occurs iff x == 0 && xHi < 0, i.e. X = rX' for -2⁶³ ≤ X' < 0 1707 1708 if b != 0 { 1709 // z[5] = -1 1710 // negative: add q 1711 const neg1 = 0xFFFFFFFFFFFFFFFF 1712 1713 var carry uint64 1714 1715 z[0], carry = bits.Add64(z[0], q0, 0) 1716 z[1], carry = bits.Add64(z[1], q1, carry) 1717 z[2], carry = bits.Add64(z[2], q2, carry) 1718 z[3], carry = bits.Add64(z[3], q3, carry) 1719 z[4], carry = bits.Add64(z[4], q4, carry) 1720 z[5], _ = bits.Add64(neg1, q5, carry) 1721 } 1722 } 1723 } 1724 1725 const ( 1726 updateFactorsConversionBias int64 = 0x7fffffff7fffffff // (2³¹ - 1)(2³² + 1) 1727 updateFactorIdentityMatrixRow0 = 1 1728 updateFactorIdentityMatrixRow1 = 1 << 32 1729 ) 1730 1731 func updateFactorsDecompose(c int64) (int64, int64) { 1732 c += updateFactorsConversionBias 1733 const low32BitsFilter int64 = 0xFFFFFFFF 1734 f := c&low32BitsFilter - 0x7FFFFFFF 1735 g := c>>32&low32BitsFilter - 0x7FFFFFFF 1736 return f, g 1737 } 1738 1739 // negL negates in place [x | xHi] and return the new most significant word xHi 1740 func negL(x *Element, xHi uint64) uint64 { 1741 var b uint64 1742 1743 x[0], b = bits.Sub64(0, x[0], 0) 1744 x[1], b = bits.Sub64(0, x[1], b) 1745 x[2], b = bits.Sub64(0, x[2], b) 1746 x[3], b = bits.Sub64(0, x[3], b) 1747 x[4], b = bits.Sub64(0, x[4], b) 1748 x[5], b = bits.Sub64(0, x[5], b) 1749 xHi, _ = bits.Sub64(0, xHi, b) 1750 1751 return xHi 1752 } 1753 1754 // mulWNonModular multiplies by one word in non-montgomery, without reducing 1755 func (z *Element) mulWNonModular(x *Element, y int64) uint64 { 1756 1757 // w := abs(y) 1758 m := y >> 63 1759 w := uint64((y ^ m) - m) 1760 1761 var c uint64 1762 c, z[0] = bits.Mul64(x[0], w) 1763 c, z[1] = madd1(x[1], w, c) 1764 c, z[2] = madd1(x[2], w, c) 1765 c, z[3] = madd1(x[3], w, c) 1766 c, z[4] = madd1(x[4], w, c) 1767 c, z[5] = madd1(x[5], w, c) 1768 1769 if y < 0 { 1770 c = negL(z, c) 1771 } 1772 1773 return c 1774 } 1775 1776 // linearCombNonModular computes a linear combination without modular reduction 1777 func (z *Element) linearCombNonModular(x *Element, xC int64, y *Element, yC int64) uint64 { 1778 var yTimes Element 1779 1780 yHi := yTimes.mulWNonModular(y, yC) 1781 xHi := z.mulWNonModular(x, xC) 1782 1783 var carry uint64 1784 z[0], carry = bits.Add64(z[0], yTimes[0], 0) 1785 z[1], carry = bits.Add64(z[1], yTimes[1], carry) 1786 z[2], carry = bits.Add64(z[2], yTimes[2], carry) 1787 z[3], carry = bits.Add64(z[3], yTimes[3], carry) 1788 z[4], carry = bits.Add64(z[4], yTimes[4], carry) 1789 z[5], carry = bits.Add64(z[5], yTimes[5], carry) 1790 1791 yHi, _ = bits.Add64(xHi, yHi, carry) 1792 1793 return yHi 1794 }