arnaucube
arnaucube/circomPublic Self-hosted repository
circom/ports/c/buildasm/fr.asm
ports/c/buildasm/fr.asmRaw
   1
   2
   3        global Fr_copy
   4        global Fr_copyn
   5        global Fr_add
   6        global Fr_sub
   7        global Fr_neg
   8        global Fr_mul
   9        global Fr_square
  10        global Fr_band
  11        global Fr_bor
  12        global Fr_bxor
  13        global Fr_bnot
  14        global Fr_eq
  15        global Fr_neq
  16        global Fr_lt
  17        global Fr_gt
  18        global Fr_leq
  19        global Fr_geq
  20        global Fr_land
  21        global Fr_lor
  22        global Fr_lnot
  23        global Fr_toNormal
  24        global Fr_toLongNormal
  25        global Fr_toMontgomery
  26        global Fr_toInt
  27        global Fr_isTrue
  28        global Fr_q
  29        extern Fr_fail
  30        DEFAULT REL
  31
  32        section .text
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49;;;;;;;;;;;;;;;;;;;;;;
  50; copy
  51;;;;;;;;;;;;;;;;;;;;;;
  52; Copies
  53; Params:
  54;   rsi <= the src
  55;   rdi <= the dest
  56;
  57; Nidified registers:
  58;   rax
  59;;;;;;;;;;;;;;;;;;;;;;;
  60Fr_copy:
  61
  62        mov     rax, [rsi + 0]
  63        mov     [rdi + 0], rax
  64
  65        mov     rax, [rsi + 8]
  66        mov     [rdi + 8], rax
  67
  68        mov     rax, [rsi + 16]
  69        mov     [rdi + 16], rax
  70
  71        mov     rax, [rsi + 24]
  72        mov     [rdi + 24], rax
  73
  74        mov     rax, [rsi + 32]
  75        mov     [rdi + 32], rax
  76
  77        ret
  78
  79;;;;;;;;;;;;;;;;;;;;;;
  80; copy an array of integers
  81;;;;;;;;;;;;;;;;;;;;;;
  82; Copies
  83; Params:
  84;   rsi <= the src
  85;   rdi <= the dest
  86;   rdx <= number of integers to copy
  87;
  88; Nidified registers:
  89;   rax
  90;;;;;;;;;;;;;;;;;;;;;;;
  91Fr_copyn:
  92Fr_copyn_loop:
  93        mov     r8, rsi
  94        mov     r9, rdi
  95        mov     rax, 5
  96        mul     rdx
  97        mov     rcx, rax
  98        cld
  99   rep  movsq
 100        mov     rsi, r8
 101        mov     rdi, r9
 102        ret
 103
 104;;;;;;;;;;;;;;;;;;;;;;
 105; rawCopyS2L
 106;;;;;;;;;;;;;;;;;;;;;;
 107; Convert a 64 bit integer to a long format field element
 108; Params:
 109;   rsi <= the integer
 110;   rdi <= Pointer to the overwritted element
 111;
 112; Nidified registers:
 113;   rax
 114;;;;;;;;;;;;;;;;;;;;;;;
 115
 116rawCopyS2L:
 117        mov     al, 0x80
 118        shl     rax, 56
 119        mov     [rdi], rax    ; set the result to LONG normal
 120
 121        cmp     rsi, 0
 122        js      u64toLong_adjust_neg
 123
 124        mov     [rdi + 8], rsi
 125        xor     rax, rax
 126
 127        mov     [rdi + 16], rax
 128
 129        mov     [rdi + 24], rax
 130
 131        mov     [rdi + 32], rax
 132
 133        ret
 134
 135u64toLong_adjust_neg:
 136        add    rsi, [q]         ; Set the first digit
 137        mov    [rdi + 8], rsi   ;
 138
 139        mov    rsi, -1          ; all ones
 140
 141        mov    rax, rsi                       ; Add to q
 142        adc    rax, [q + 8 ]
 143        mov    [rdi + 16], rax
 144
 145        mov    rax, rsi                       ; Add to q
 146        adc    rax, [q + 16 ]
 147        mov    [rdi + 24], rax
 148
 149        mov    rax, rsi                       ; Add to q
 150        adc    rax, [q + 24 ]
 151        mov    [rdi + 32], rax
 152
 153        ret
 154
 155;;;;;;;;;;;;;;;;;;;;;;
 156; toInt
 157;;;;;;;;;;;;;;;;;;;;;;
 158; Convert a 64 bit integer to a long format field element
 159; Params:
 160;   rsi <= Pointer to the element
 161; Returs:
 162;   rax <= The value
 163;;;;;;;;;;;;;;;;;;;;;;;
 164Fr_toInt:
 165        mov     rax, [rdi]
 166        bt      rax, 63
 167        jc      Fr_long
 168        movsx   rax, eax
 169        ret
 170
 171Fr_long:
 172        bt      rax, 62
 173        jnc     Fr_longNormal
 174Fr_longMontgomery:
 175        call    Fr_toLongNormal
 176
 177Fr_longNormal:
 178        mov     rax, [rdi + 8]
 179        mov     rcx, rax
 180        shr     rcx, 31
 181        jnz     Fr_longNeg
 182
 183        mov     rcx, [rdi + 16]
 184        test    rcx, rcx
 185        jnz     Fr_longNeg
 186
 187        mov     rcx, [rdi + 24]
 188        test    rcx, rcx
 189        jnz     Fr_longNeg
 190
 191        mov     rcx, [rdi + 32]
 192        test    rcx, rcx
 193        jnz     Fr_longNeg
 194
 195        ret
 196
 197Fr_longNeg:
 198        mov     rax, [rdi + 8]
 199        sub     rax, [q]
 200        jnc     Fr_longErr
 201
 202        mov     rcx, [rdi + 16]
 203        sbb     rcx, [q + 8]
 204        jnc     Fr_longErr
 205
 206        mov     rcx, [rdi + 24]
 207        sbb     rcx, [q + 16]
 208        jnc     Fr_longErr
 209
 210        mov     rcx, [rdi + 32]
 211        sbb     rcx, [q + 24]
 212        jnc     Fr_longErr
 213
 214        mov     rcx, rax
 215        sar     rcx, 31
 216        add     rcx, 1
 217        jnz     Fr_longErr
 218        ret
 219
 220Fr_longErr:
 221        push    rdi
 222        mov     rdi, 0
 223        call    Fr_fail
 224        pop     rdi
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234;;;;;;;;;;;;;;;;;;;;;;
 235; rawMontgomeryMul
 236;;;;;;;;;;;;;;;;;;;;;;
 237; Multiply two elements in montgomery form
 238; Params:
 239;   rsi <= Pointer to the long data of element 1
 240;   rdx <= Pointer to the long data of element 2
 241;   rdi <= Pointer to the long data of result
 242; Modified registers:
 243;    r8, r9, 10, r11, rax, rcx
 244;;;;;;;;;;;;;;;;;;;;;;
 245
 246rawMontgomeryMul:
 247        sub     rsp, 32  ; Reserve space for ms
 248        mov     rcx, rdx            ; rdx is needed for multiplications so keep it in cx
 249        mov     r11, 0xc2e1f593efffffff ; np
 250        xor     r8,r8
 251        xor     r9,r9
 252        xor     r10,r10
 253
 254        mov     rax, [rsi + 0]
 255        mul     qword [rcx + 0]
 256        add     r8, rax
 257        adc     r9, rdx
 258        adc     r10, 0x0
 259
 260
 261
 262
 263
 264        mov     rax, r8
 265        mul     r11
 266        mov     [rsp + 0], rax
 267        mul     qword [q]
 268        add     r8, rax
 269        adc     r9, rdx
 270        adc     r10, 0x0
 271
 272
 273
 274        mov     rax, [rsi + 0]
 275        mul     qword [rcx + 8]
 276        add     r9, rax
 277        adc     r10, rdx
 278        adc     r8, 0x0
 279
 280        mov     rax, [rsi + 8]
 281        mul     qword [rcx + 0]
 282        add     r9, rax
 283        adc     r10, rdx
 284        adc     r8, 0x0
 285
 286
 287
 288        mov     rax, [rsp + 0]
 289        mul     qword [q + 8]
 290        add     r9, rax
 291        adc     r10, rdx
 292        adc     r8, 0x0
 293
 294
 295
 296        mov     rax, r9
 297        mul     r11
 298        mov     [rsp + 8], rax
 299        mul     qword [q]
 300        add     r9, rax
 301        adc     r10, rdx
 302        adc     r8, 0x0
 303
 304
 305
 306        mov     rax, [rsi + 0]
 307        mul     qword [rcx + 16]
 308        add     r10, rax
 309        adc     r8, rdx
 310        adc     r9, 0x0
 311
 312        mov     rax, [rsi + 8]
 313        mul     qword [rcx + 8]
 314        add     r10, rax
 315        adc     r8, rdx
 316        adc     r9, 0x0
 317
 318        mov     rax, [rsi + 16]
 319        mul     qword [rcx + 0]
 320        add     r10, rax
 321        adc     r8, rdx
 322        adc     r9, 0x0
 323
 324
 325
 326        mov     rax, [rsp + 8]
 327        mul     qword [q + 8]
 328        add     r10, rax
 329        adc     r8, rdx
 330        adc     r9, 0x0
 331
 332        mov     rax, [rsp + 0]
 333        mul     qword [q + 16]
 334        add     r10, rax
 335        adc     r8, rdx
 336        adc     r9, 0x0
 337
 338
 339
 340        mov     rax, r10
 341        mul     r11
 342        mov     [rsp + 16], rax
 343        mul     qword [q]
 344        add     r10, rax
 345        adc     r8, rdx
 346        adc     r9, 0x0
 347
 348
 349
 350        mov     rax, [rsi + 0]
 351        mul     qword [rcx + 24]
 352        add     r8, rax
 353        adc     r9, rdx
 354        adc     r10, 0x0
 355
 356        mov     rax, [rsi + 8]
 357        mul     qword [rcx + 16]
 358        add     r8, rax
 359        adc     r9, rdx
 360        adc     r10, 0x0
 361
 362        mov     rax, [rsi + 16]
 363        mul     qword [rcx + 8]
 364        add     r8, rax
 365        adc     r9, rdx
 366        adc     r10, 0x0
 367
 368        mov     rax, [rsi + 24]
 369        mul     qword [rcx + 0]
 370        add     r8, rax
 371        adc     r9, rdx
 372        adc     r10, 0x0
 373
 374
 375
 376        mov     rax, [rsp + 16]
 377        mul     qword [q + 8]
 378        add     r8, rax
 379        adc     r9, rdx
 380        adc     r10, 0x0
 381
 382        mov     rax, [rsp + 8]
 383        mul     qword [q + 16]
 384        add     r8, rax
 385        adc     r9, rdx
 386        adc     r10, 0x0
 387
 388        mov     rax, [rsp + 0]
 389        mul     qword [q + 24]
 390        add     r8, rax
 391        adc     r9, rdx
 392        adc     r10, 0x0
 393
 394
 395
 396        mov     rax, r8
 397        mul     r11
 398        mov     [rsp + 24], rax
 399        mul     qword [q]
 400        add     r8, rax
 401        adc     r9, rdx
 402        adc     r10, 0x0
 403
 404
 405
 406        mov     rax, [rsi + 8]
 407        mul     qword [rcx + 24]
 408        add     r9, rax
 409        adc     r10, rdx
 410        adc     r8, 0x0
 411
 412        mov     rax, [rsi + 16]
 413        mul     qword [rcx + 16]
 414        add     r9, rax
 415        adc     r10, rdx
 416        adc     r8, 0x0
 417
 418        mov     rax, [rsi + 24]
 419        mul     qword [rcx + 8]
 420        add     r9, rax
 421        adc     r10, rdx
 422        adc     r8, 0x0
 423
 424
 425
 426        mov     rax, [rsp + 24]
 427        mul     qword [q + 8]
 428        add     r9, rax
 429        adc     r10, rdx
 430        adc     r8, 0x0
 431
 432        mov     rax, [rsp + 16]
 433        mul     qword [q + 16]
 434        add     r9, rax
 435        adc     r10, rdx
 436        adc     r8, 0x0
 437
 438        mov     rax, [rsp + 8]
 439        mul     qword [q + 24]
 440        add     r9, rax
 441        adc     r10, rdx
 442        adc     r8, 0x0
 443
 444
 445
 446        mov     [rdi + 0 ], r9
 447        xor     r9,r9
 448
 449
 450
 451        mov     rax, [rsi + 16]
 452        mul     qword [rcx + 24]
 453        add     r10, rax
 454        adc     r8, rdx
 455        adc     r9, 0x0
 456
 457        mov     rax, [rsi + 24]
 458        mul     qword [rcx + 16]
 459        add     r10, rax
 460        adc     r8, rdx
 461        adc     r9, 0x0
 462
 463
 464
 465        mov     rax, [rsp + 24]
 466        mul     qword [q + 16]
 467        add     r10, rax
 468        adc     r8, rdx
 469        adc     r9, 0x0
 470
 471        mov     rax, [rsp + 16]
 472        mul     qword [q + 24]
 473        add     r10, rax
 474        adc     r8, rdx
 475        adc     r9, 0x0
 476
 477
 478
 479        mov     [rdi + 8 ], r10
 480        xor     r10,r10
 481
 482
 483
 484        mov     rax, [rsi + 24]
 485        mul     qword [rcx + 24]
 486        add     r8, rax
 487        adc     r9, rdx
 488        adc     r10, 0x0
 489
 490
 491
 492        mov     rax, [rsp + 24]
 493        mul     qword [q + 24]
 494        add     r8, rax
 495        adc     r9, rdx
 496        adc     r10, 0x0
 497
 498
 499
 500        mov     [rdi + 16 ], r8
 501        xor     r8,r8
 502
 503
 504
 505
 506
 507
 508
 509        mov     [rdi + 24 ], r9
 510        xor     r9,r9
 511
 512
 513
 514        test    r10, r10
 515        jnz     rawMontgomeryMul_mulM_sq
 516        ; Compare with q
 517
 518        mov rax, [rdi + 24]
 519        cmp rax, [q + 24]
 520        jc rawMontgomeryMul_mulM_done        ; q is bigget so done.
 521        jnz rawMontgomeryMul_mulM_sq         ; q is lower
 522
 523        mov rax, [rdi + 16]
 524        cmp rax, [q + 16]
 525        jc rawMontgomeryMul_mulM_done        ; q is bigget so done.
 526        jnz rawMontgomeryMul_mulM_sq         ; q is lower
 527
 528        mov rax, [rdi + 8]
 529        cmp rax, [q + 8]
 530        jc rawMontgomeryMul_mulM_done        ; q is bigget so done.
 531        jnz rawMontgomeryMul_mulM_sq         ; q is lower
 532
 533        mov rax, [rdi + 0]
 534        cmp rax, [q + 0]
 535        jc rawMontgomeryMul_mulM_done        ; q is bigget so done.
 536        jnz rawMontgomeryMul_mulM_sq         ; q is lower
 537
 538        ; If equal substract q
 539
 540rawMontgomeryMul_mulM_sq:
 541
 542        mov rax, [q + 0]
 543        sub [rdi + 0], rax
 544
 545        mov rax, [q + 8]
 546        sbb [rdi + 8], rax
 547
 548        mov rax, [q + 16]
 549        sbb [rdi + 16], rax
 550
 551        mov rax, [q + 24]
 552        sbb [rdi + 24], rax
 553
 554
 555rawMontgomeryMul_mulM_done:
 556        mov rdx, rcx            ; recover rdx to its original place.
 557        add rsp, 32   ; recover rsp
 558        ret
 559
 560
 561
 562;;;;;;;;;;;;;;;;;;;;;;
 563; rawMontgomerySquare
 564;;;;;;;;;;;;;;;;;;;;;;
 565; Square an element
 566; Params:
 567;   rsi <= Pointer to the long data of element 1
 568;   rdi <= Pointer to the long data of result
 569; Modified registers:
 570;    r8, r9, 10, r11, rax, rcx
 571;;;;;;;;;;;;;;;;;;;;;;
 572
 573rawMontgomerySquare:
 574        sub     rsp, 32  ; Reserve space for ms
 575        mov     rcx, rdx            ; rdx is needed for multiplications so keep it in cx
 576        mov     r11, 0xc2e1f593efffffff ; np
 577        xor     r8,r8
 578        xor     r9,r9
 579        xor     r10,r10
 580
 581
 582
 583        mov     rax, [rsi + 0]
 584        mul     rax
 585        add     r8, rax
 586        adc     r9, rdx
 587        adc     r10, 0x0
 588
 589
 590
 591
 592
 593
 594
 595        mov     rax, r8
 596        mul     r11
 597        mov     [rsp + 0], rax
 598        mul     qword [q]
 599        add     r8, rax
 600        adc     r9, rdx
 601        adc     r10, 0x0
 602
 603
 604
 605        mov     rax, [rsi + 0]
 606        mul     qword [rsi + 8]
 607        add     r9, rax
 608        adc     r10, rdx
 609        adc     r8, 0x0
 610        add     r9, rax
 611        adc     r10, rdx
 612        adc     r8, 0x0
 613
 614
 615
 616
 617
 618
 619
 620        mov     rax, [rsp + 0]
 621        mul     qword [q + 8]
 622        add     r9, rax
 623        adc     r10, rdx
 624        adc     r8, 0x0
 625
 626
 627
 628        mov     rax, r9
 629        mul     r11
 630        mov     [rsp + 8], rax
 631        mul     qword [q]
 632        add     r9, rax
 633        adc     r10, rdx
 634        adc     r8, 0x0
 635
 636
 637
 638        mov     rax, [rsi + 0]
 639        mul     qword [rsi + 16]
 640        add     r10, rax
 641        adc     r8, rdx
 642        adc     r9, 0x0
 643        add     r10, rax
 644        adc     r8, rdx
 645        adc     r9, 0x0
 646
 647
 648
 649        mov     rax, [rsi + 8]
 650        mul     rax
 651        add     r10, rax
 652        adc     r8, rdx
 653        adc     r9, 0x0
 654
 655
 656
 657
 658
 659        mov     rax, [rsp + 8]
 660        mul     qword [q + 8]
 661        add     r10, rax
 662        adc     r8, rdx
 663        adc     r9, 0x0
 664
 665        mov     rax, [rsp + 0]
 666        mul     qword [q + 16]
 667        add     r10, rax
 668        adc     r8, rdx
 669        adc     r9, 0x0
 670
 671
 672
 673        mov     rax, r10
 674        mul     r11
 675        mov     [rsp + 16], rax
 676        mul     qword [q]
 677        add     r10, rax
 678        adc     r8, rdx
 679        adc     r9, 0x0
 680
 681
 682
 683        mov     rax, [rsi + 0]
 684        mul     qword [rsi + 24]
 685        add     r8, rax
 686        adc     r9, rdx
 687        adc     r10, 0x0
 688        add     r8, rax
 689        adc     r9, rdx
 690        adc     r10, 0x0
 691
 692        mov     rax, [rsi + 8]
 693        mul     qword [rsi + 16]
 694        add     r8, rax
 695        adc     r9, rdx
 696        adc     r10, 0x0
 697        add     r8, rax
 698        adc     r9, rdx
 699        adc     r10, 0x0
 700
 701
 702
 703
 704
 705
 706
 707        mov     rax, [rsp + 16]
 708        mul     qword [q + 8]
 709        add     r8, rax
 710        adc     r9, rdx
 711        adc     r10, 0x0
 712
 713        mov     rax, [rsp + 8]
 714        mul     qword [q + 16]
 715        add     r8, rax
 716        adc     r9, rdx
 717        adc     r10, 0x0
 718
 719        mov     rax, [rsp + 0]
 720        mul     qword [q + 24]
 721        add     r8, rax
 722        adc     r9, rdx
 723        adc     r10, 0x0
 724
 725
 726
 727        mov     rax, r8
 728        mul     r11
 729        mov     [rsp + 24], rax
 730        mul     qword [q]
 731        add     r8, rax
 732        adc     r9, rdx
 733        adc     r10, 0x0
 734
 735
 736
 737        mov     rax, [rsi + 8]
 738        mul     qword [rsi + 24]
 739        add     r9, rax
 740        adc     r10, rdx
 741        adc     r8, 0x0
 742        add     r9, rax
 743        adc     r10, rdx
 744        adc     r8, 0x0
 745
 746
 747
 748        mov     rax, [rsi + 16]
 749        mul     rax
 750        add     r9, rax
 751        adc     r10, rdx
 752        adc     r8, 0x0
 753
 754
 755
 756
 757
 758        mov     rax, [rsp + 24]
 759        mul     qword [q + 8]
 760        add     r9, rax
 761        adc     r10, rdx
 762        adc     r8, 0x0
 763
 764        mov     rax, [rsp + 16]
 765        mul     qword [q + 16]
 766        add     r9, rax
 767        adc     r10, rdx
 768        adc     r8, 0x0
 769
 770        mov     rax, [rsp + 8]
 771        mul     qword [q + 24]
 772        add     r9, rax
 773        adc     r10, rdx
 774        adc     r8, 0x0
 775
 776
 777
 778        mov     [rdi + 0 ], r9
 779        xor     r9,r9
 780
 781
 782
 783        mov     rax, [rsi + 16]
 784        mul     qword [rsi + 24]
 785        add     r10, rax
 786        adc     r8, rdx
 787        adc     r9, 0x0
 788        add     r10, rax
 789        adc     r8, rdx
 790        adc     r9, 0x0
 791
 792
 793
 794
 795
 796
 797
 798        mov     rax, [rsp + 24]
 799        mul     qword [q + 16]
 800        add     r10, rax
 801        adc     r8, rdx
 802        adc     r9, 0x0
 803
 804        mov     rax, [rsp + 16]
 805        mul     qword [q + 24]
 806        add     r10, rax
 807        adc     r8, rdx
 808        adc     r9, 0x0
 809
 810
 811
 812        mov     [rdi + 8 ], r10
 813        xor     r10,r10
 814
 815
 816
 817
 818
 819        mov     rax, [rsi + 24]
 820        mul     rax
 821        add     r8, rax
 822        adc     r9, rdx
 823        adc     r10, 0x0
 824
 825
 826
 827
 828
 829        mov     rax, [rsp + 24]
 830        mul     qword [q + 24]
 831        add     r8, rax
 832        adc     r9, rdx
 833        adc     r10, 0x0
 834
 835
 836
 837        mov     [rdi + 16 ], r8
 838        xor     r8,r8
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850        mov     [rdi + 24 ], r9
 851        xor     r9,r9
 852
 853
 854
 855        test    r10, r10
 856        jnz     rawMontgomerySquare_mulM_sq
 857        ; Compare with q
 858
 859        mov rax, [rdi + 24]
 860        cmp rax, [q + 24]
 861        jc rawMontgomerySquare_mulM_done        ; q is bigget so done.
 862        jnz rawMontgomerySquare_mulM_sq         ; q is lower
 863
 864        mov rax, [rdi + 16]
 865        cmp rax, [q + 16]
 866        jc rawMontgomerySquare_mulM_done        ; q is bigget so done.
 867        jnz rawMontgomerySquare_mulM_sq         ; q is lower
 868
 869        mov rax, [rdi + 8]
 870        cmp rax, [q + 8]
 871        jc rawMontgomerySquare_mulM_done        ; q is bigget so done.
 872        jnz rawMontgomerySquare_mulM_sq         ; q is lower
 873
 874        mov rax, [rdi + 0]
 875        cmp rax, [q + 0]
 876        jc rawMontgomerySquare_mulM_done        ; q is bigget so done.
 877        jnz rawMontgomerySquare_mulM_sq         ; q is lower
 878
 879        ; If equal substract q
 880
 881rawMontgomerySquare_mulM_sq:
 882
 883        mov rax, [q + 0]
 884        sub [rdi + 0], rax
 885
 886        mov rax, [q + 8]
 887        sbb [rdi + 8], rax
 888
 889        mov rax, [q + 16]
 890        sbb [rdi + 16], rax
 891
 892        mov rax, [q + 24]
 893        sbb [rdi + 24], rax
 894
 895
 896rawMontgomerySquare_mulM_done:
 897        mov rdx, rcx            ; recover rdx to its original place.
 898        add rsp, 32   ; recover rsp
 899        ret
 900
 901
 902
 903
 904;;;;;;;;;;;;;;;;;;;;;;
 905; rawMontgomeryMul1
 906;;;;;;;;;;;;;;;;;;;;;;
 907; Multiply two elements in montgomery form
 908; Params:
 909;   rsi <= Pointer to the long data of element 1
 910;   rdx <= second operand
 911;   rdi <= Pointer to the long data of result
 912; Modified registers:
 913;    r8, r9, 10, r11, rax, rcx
 914;;;;;;;;;;;;;;;;;;;;;;
 915
 916rawMontgomeryMul1:
 917        sub     rsp, 32  ; Reserve space for ms
 918        mov     rcx, rdx            ; rdx is needed for multiplications so keep it in cx
 919        mov     r11, 0xc2e1f593efffffff ; np
 920        xor     r8,r8
 921        xor     r9,r9
 922        xor     r10,r10
 923
 924        mov     rax, [rsi + 0]
 925        mul     rcx
 926        add     r8, rax
 927        adc     r9, rdx
 928        adc     r10, 0x0
 929
 930
 931
 932
 933
 934        mov     rax, r8
 935        mul     r11
 936        mov     [rsp + 0], rax
 937        mul     qword [q]
 938        add     r8, rax
 939        adc     r9, rdx
 940        adc     r10, 0x0
 941
 942
 943
 944        mov     rax, [rsi + 8]
 945        mul     rcx
 946        add     r9, rax
 947        adc     r10, rdx
 948        adc     r8, 0x0
 949
 950
 951
 952        mov     rax, [rsp + 0]
 953        mul     qword [q + 8]
 954        add     r9, rax
 955        adc     r10, rdx
 956        adc     r8, 0x0
 957
 958
 959
 960        mov     rax, r9
 961        mul     r11
 962        mov     [rsp + 8], rax
 963        mul     qword [q]
 964        add     r9, rax
 965        adc     r10, rdx
 966        adc     r8, 0x0
 967
 968
 969
 970        mov     rax, [rsi + 16]
 971        mul     rcx
 972        add     r10, rax
 973        adc     r8, rdx
 974        adc     r9, 0x0
 975
 976
 977
 978        mov     rax, [rsp + 8]
 979        mul     qword [q + 8]
 980        add     r10, rax
 981        adc     r8, rdx
 982        adc     r9, 0x0
 983
 984        mov     rax, [rsp + 0]
 985        mul     qword [q + 16]
 986        add     r10, rax
 987        adc     r8, rdx
 988        adc     r9, 0x0
 989
 990
 991
 992        mov     rax, r10
 993        mul     r11
 994        mov     [rsp + 16], rax
 995        mul     qword [q]
 996        add     r10, rax
 997        adc     r8, rdx
 998        adc     r9, 0x0
 999
1000
1001
1002        mov     rax, [rsi + 24]
1003        mul     rcx
1004        add     r8, rax
1005        adc     r9, rdx
1006        adc     r10, 0x0
1007
1008
1009
1010        mov     rax, [rsp + 16]
1011        mul     qword [q + 8]
1012        add     r8, rax
1013        adc     r9, rdx
1014        adc     r10, 0x0
1015
1016        mov     rax, [rsp + 8]
1017        mul     qword [q + 16]
1018        add     r8, rax
1019        adc     r9, rdx
1020        adc     r10, 0x0
1021
1022        mov     rax, [rsp + 0]
1023        mul     qword [q + 24]
1024        add     r8, rax
1025        adc     r9, rdx
1026        adc     r10, 0x0
1027
1028
1029
1030        mov     rax, r8
1031        mul     r11
1032        mov     [rsp + 24], rax
1033        mul     qword [q]
1034        add     r8, rax
1035        adc     r9, rdx
1036        adc     r10, 0x0
1037
1038
1039
1040
1041
1042        mov     rax, [rsp + 24]
1043        mul     qword [q + 8]
1044        add     r9, rax
1045        adc     r10, rdx
1046        adc     r8, 0x0
1047
1048        mov     rax, [rsp + 16]
1049        mul     qword [q + 16]
1050        add     r9, rax
1051        adc     r10, rdx
1052        adc     r8, 0x0
1053
1054        mov     rax, [rsp + 8]
1055        mul     qword [q + 24]
1056        add     r9, rax
1057        adc     r10, rdx
1058        adc     r8, 0x0
1059
1060
1061
1062        mov     [rdi + 0 ], r9
1063        xor     r9,r9
1064
1065
1066
1067
1068
1069        mov     rax, [rsp + 24]
1070        mul     qword [q + 16]
1071        add     r10, rax
1072        adc     r8, rdx
1073        adc     r9, 0x0
1074
1075        mov     rax, [rsp + 16]
1076        mul     qword [q + 24]
1077        add     r10, rax
1078        adc     r8, rdx
1079        adc     r9, 0x0
1080
1081
1082
1083        mov     [rdi + 8 ], r10
1084        xor     r10,r10
1085
1086
1087
1088
1089
1090        mov     rax, [rsp + 24]
1091        mul     qword [q + 24]
1092        add     r8, rax
1093        adc     r9, rdx
1094        adc     r10, 0x0
1095
1096
1097
1098        mov     [rdi + 16 ], r8
1099        xor     r8,r8
1100
1101
1102
1103
1104
1105
1106
1107        mov     [rdi + 24 ], r9
1108        xor     r9,r9
1109
1110
1111
1112        test    r10, r10
1113        jnz     rawMontgomeryMul1_mulM_sq
1114        ; Compare with q
1115
1116        mov rax, [rdi + 24]
1117        cmp rax, [q + 24]
1118        jc rawMontgomeryMul1_mulM_done        ; q is bigget so done.
1119        jnz rawMontgomeryMul1_mulM_sq         ; q is lower
1120
1121        mov rax, [rdi + 16]
1122        cmp rax, [q + 16]
1123        jc rawMontgomeryMul1_mulM_done        ; q is bigget so done.
1124        jnz rawMontgomeryMul1_mulM_sq         ; q is lower
1125
1126        mov rax, [rdi + 8]
1127        cmp rax, [q + 8]
1128        jc rawMontgomeryMul1_mulM_done        ; q is bigget so done.
1129        jnz rawMontgomeryMul1_mulM_sq         ; q is lower
1130
1131        mov rax, [rdi + 0]
1132        cmp rax, [q + 0]
1133        jc rawMontgomeryMul1_mulM_done        ; q is bigget so done.
1134        jnz rawMontgomeryMul1_mulM_sq         ; q is lower
1135
1136        ; If equal substract q
1137
1138rawMontgomeryMul1_mulM_sq:
1139
1140        mov rax, [q + 0]
1141        sub [rdi + 0], rax
1142
1143        mov rax, [q + 8]
1144        sbb [rdi + 8], rax
1145
1146        mov rax, [q + 16]
1147        sbb [rdi + 16], rax
1148
1149        mov rax, [q + 24]
1150        sbb [rdi + 24], rax
1151
1152
1153rawMontgomeryMul1_mulM_done:
1154        mov rdx, rcx            ; recover rdx to its original place.
1155        add rsp, 32   ; recover rsp
1156        ret
1157
1158
1159
1160
1161;;;;;;;;;;;;;;;;;;;;;;
1162; rawFromMontgomery
1163;;;;;;;;;;;;;;;;;;;;;;
1164; Multiply two elements in montgomery form
1165; Params:
1166;   rsi <= Pointer to the long data of element 1
1167;   rdi <= Pointer to the long data of result
1168; Modified registers:
1169;    r8, r9, 10, r11, rax, rcx
1170;;;;;;;;;;;;;;;;;;;;;;
1171
1172rawFromMontgomery:
1173        sub     rsp, 32  ; Reserve space for ms
1174        mov     rcx, rdx            ; rdx is needed for multiplications so keep it in cx
1175        mov     r11, 0xc2e1f593efffffff ; np
1176        xor     r8,r8
1177        xor     r9,r9
1178        xor     r10,r10
1179
1180        add     r8, [rdi + 0]
1181        adc     r9, 0x0
1182        adc     r10, 0x0
1183
1184
1185
1186
1187
1188        mov     rax, r8
1189        mul     r11
1190        mov     [rsp + 0], rax
1191        mul     qword [q]
1192        add     r8, rax
1193        adc     r9, rdx
1194        adc     r10, 0x0
1195
1196
1197
1198        add     r9, [rdi + 8]
1199        adc     r10, 0x0
1200        adc     r8, 0x0
1201
1202
1203
1204        mov     rax, [rsp + 0]
1205        mul     qword [q + 8]
1206        add     r9, rax
1207        adc     r10, rdx
1208        adc     r8, 0x0
1209
1210
1211
1212        mov     rax, r9
1213        mul     r11
1214        mov     [rsp + 8], rax
1215        mul     qword [q]
1216        add     r9, rax
1217        adc     r10, rdx
1218        adc     r8, 0x0
1219
1220
1221
1222        add     r10, [rdi + 16]
1223        adc     r8, 0x0
1224        adc     r9, 0x0
1225
1226
1227
1228        mov     rax, [rsp + 8]
1229        mul     qword [q + 8]
1230        add     r10, rax
1231        adc     r8, rdx
1232        adc     r9, 0x0
1233
1234        mov     rax, [rsp + 0]
1235        mul     qword [q + 16]
1236        add     r10, rax
1237        adc     r8, rdx
1238        adc     r9, 0x0
1239
1240
1241
1242        mov     rax, r10
1243        mul     r11
1244        mov     [rsp + 16], rax
1245        mul     qword [q]
1246        add     r10, rax
1247        adc     r8, rdx
1248        adc     r9, 0x0
1249
1250
1251
1252        add     r8, [rdi + 24]
1253        adc     r9, 0x0
1254        adc     r10, 0x0
1255
1256
1257
1258        mov     rax, [rsp + 16]
1259        mul     qword [q + 8]
1260        add     r8, rax
1261        adc     r9, rdx
1262        adc     r10, 0x0
1263
1264        mov     rax, [rsp + 8]
1265        mul     qword [q + 16]
1266        add     r8, rax
1267        adc     r9, rdx
1268        adc     r10, 0x0
1269
1270        mov     rax, [rsp + 0]
1271        mul     qword [q + 24]
1272        add     r8, rax
1273        adc     r9, rdx
1274        adc     r10, 0x0
1275
1276
1277
1278        mov     rax, r8
1279        mul     r11
1280        mov     [rsp + 24], rax
1281        mul     qword [q]
1282        add     r8, rax
1283        adc     r9, rdx
1284        adc     r10, 0x0
1285
1286
1287
1288
1289
1290        mov     rax, [rsp + 24]
1291        mul     qword [q + 8]
1292        add     r9, rax
1293        adc     r10, rdx
1294        adc     r8, 0x0
1295
1296        mov     rax, [rsp + 16]
1297        mul     qword [q + 16]
1298        add     r9, rax
1299        adc     r10, rdx
1300        adc     r8, 0x0
1301
1302        mov     rax, [rsp + 8]
1303        mul     qword [q + 24]
1304        add     r9, rax
1305        adc     r10, rdx
1306        adc     r8, 0x0
1307
1308
1309
1310        mov     [rdi + 0 ], r9
1311        xor     r9,r9
1312
1313
1314
1315
1316
1317        mov     rax, [rsp + 24]
1318        mul     qword [q + 16]
1319        add     r10, rax
1320        adc     r8, rdx
1321        adc     r9, 0x0
1322
1323        mov     rax, [rsp + 16]
1324        mul     qword [q + 24]
1325        add     r10, rax
1326        adc     r8, rdx
1327        adc     r9, 0x0
1328
1329
1330
1331        mov     [rdi + 8 ], r10
1332        xor     r10,r10
1333
1334
1335
1336
1337
1338        mov     rax, [rsp + 24]
1339        mul     qword [q + 24]
1340        add     r8, rax
1341        adc     r9, rdx
1342        adc     r10, 0x0
1343
1344
1345
1346        mov     [rdi + 16 ], r8
1347        xor     r8,r8
1348
1349
1350
1351
1352
1353
1354
1355        mov     [rdi + 24 ], r9
1356        xor     r9,r9
1357
1358
1359
1360        test    r10, r10
1361        jnz     rawFromMontgomery_mulM_sq
1362        ; Compare with q
1363
1364        mov rax, [rdi + 24]
1365        cmp rax, [q + 24]
1366        jc rawFromMontgomery_mulM_done        ; q is bigget so done.
1367        jnz rawFromMontgomery_mulM_sq         ; q is lower
1368
1369        mov rax, [rdi + 16]
1370        cmp rax, [q + 16]
1371        jc rawFromMontgomery_mulM_done        ; q is bigget so done.
1372        jnz rawFromMontgomery_mulM_sq         ; q is lower
1373
1374        mov rax, [rdi + 8]
1375        cmp rax, [q + 8]
1376        jc rawFromMontgomery_mulM_done        ; q is bigget so done.
1377        jnz rawFromMontgomery_mulM_sq         ; q is lower
1378
1379        mov rax, [rdi + 0]
1380        cmp rax, [q + 0]
1381        jc rawFromMontgomery_mulM_done        ; q is bigget so done.
1382        jnz rawFromMontgomery_mulM_sq         ; q is lower
1383
1384        ; If equal substract q
1385
1386rawFromMontgomery_mulM_sq:
1387
1388        mov rax, [q + 0]
1389        sub [rdi + 0], rax
1390
1391        mov rax, [q + 8]
1392        sbb [rdi + 8], rax
1393
1394        mov rax, [q + 16]
1395        sbb [rdi + 16], rax
1396
1397        mov rax, [q + 24]
1398        sbb [rdi + 24], rax
1399
1400
1401rawFromMontgomery_mulM_done:
1402        mov rdx, rcx            ; recover rdx to its original place.
1403        add rsp, 32   ; recover rsp
1404        ret
1405
1406
1407
1408;;;;;;;;;;;;;;;;;;;;;;
1409; toMontgomery
1410;;;;;;;;;;;;;;;;;;;;;;
1411; Convert a number to Montgomery
1412;   rdi <= Pointer element to convert
1413; Modified registers:
1414;    r8, r9, 10, r11, rax, rcx
1415;;;;;;;;;;;;;;;;;;;;
1416Fr_toMontgomery:
1417    mov     rax, [rdi]
1418    bts     rax, 62                     ; check if montgomery
1419    jc      toMontgomery_doNothing
1420    bts     rax, 63
1421    jc      toMontgomeryLong
1422
1423toMontgomeryShort:
1424    mov     [rdi], rax
1425    add     rdi, 8
1426    push    rsi
1427    lea     rsi, [R2]
1428    movsx   rdx, eax
1429    cmp     rdx, 0
1430    js      negMontgomeryShort
1431posMontgomeryShort:
1432    call    rawMontgomeryMul1
1433    pop     rsi
1434    sub     rdi, 8
1435    ret
1436
1437negMontgomeryShort:
1438    neg     rdx              ; Do the multiplication positive and then negate the result.
1439    call    rawMontgomeryMul1
1440    mov     rsi, rdi
1441    call    rawNegL
1442    pop     rsi
1443    sub     rdi, 8
1444    ret
1445
1446
1447toMontgomeryLong:
1448    mov     [rdi], rax
1449    add     rdi, 8
1450    push    rsi
1451    mov     rdx, rdi
1452    lea     rsi, [R2]
1453    call    rawMontgomeryMul
1454    pop     rsi
1455    sub     rdi, 8
1456
1457toMontgomery_doNothing:
1458    ret
1459
1460;;;;;;;;;;;;;;;;;;;;;;
1461; toNormal
1462;;;;;;;;;;;;;;;;;;;;;;
1463; Convert a number from Montgomery
1464;   rdi <= Pointer element to convert
1465; Modified registers:
1466;    r8, r9, 10, r11, rax, rcx
1467;;;;;;;;;;;;;;;;;;;;
1468Fr_toNormal:
1469    mov     rax, [rdi]
1470    btc     rax, 62                     ; check if montgomery
1471    jnc     toNormal_doNothing
1472    bt      rax, 63                     ; if short, it means it's converted
1473    jnc     toNormal_doNothing
1474
1475toNormalLong:
1476    mov     [rdi], rax
1477    add     rdi, 8
1478    call    rawFromMontgomery
1479    sub     rdi, 8
1480
1481toNormal_doNothing:
1482    ret
1483
1484;;;;;;;;;;;;;;;;;;;;;;
1485; toLongNormal
1486;;;;;;;;;;;;;;;;;;;;;;
1487; Convert a number to long normal
1488;   rdi <= Pointer element to convert
1489; Modified registers:
1490;    r8, r9, 10, r11, rax, rcx
1491;;;;;;;;;;;;;;;;;;;;
1492Fr_toLongNormal:
1493    mov     rax, [rdi]
1494    bt      rax, 62                     ; check if montgomery
1495    jc      toLongNormal_fromMontgomery
1496    bt      rax, 63                     ; check if long
1497    jnc     toLongNormal_fromShort
1498    ret                                 ; It is already long
1499
1500toLongNormal_fromMontgomery:
1501    add     rdi, 8
1502    call    rawFromMontgomery
1503    sub     rdi, 8
1504    ret
1505
1506toLongNormal_fromShort:
1507    mov     r8, rsi                     ; save rsi
1508    movsx   rsi, eax
1509    call    rawCopyS2L
1510    mov     rsi, r8                     ; recover rsi
1511    ret
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524;;;;;;;;;;;;;;;;;;;;;;
1525; add
1526;;;;;;;;;;;;;;;;;;;;;;
1527; Adds two elements of any kind
1528; Params:
1529;   rsi <= Pointer to element 1
1530;   rdx <= Pointer to element 2
1531;   rdi <= Pointer to result
1532; Modified Registers:
1533;    r8, r9, 10, r11, rax, rcx
1534;;;;;;;;;;;;;;;;;;;;;;
1535Fr_add:
1536        mov    rax, [rsi]
1537        mov    rcx, [rdx]
1538        bt     rax, 63          ; Check if is short first operand
1539        jc     add_l1
1540        bt     rcx, 63          ; Check if is short second operand
1541        jc     add_s1l2
1542
1543add_s1s2:                       ; Both operands are short
1544
1545        xor    rdx, rdx
1546        mov    edx, eax
1547        add    edx, ecx
1548        jo     add_manageOverflow   ; rsi already is the 64bits result
1549
1550        mov    [rdi], rdx       ; not necessary to adjust so just save and return
1551        ret
1552
1553add_manageOverflow:                 ; Do the operation in 64 bits
1554        push   rsi
1555        movsx  rsi, eax
1556        movsx  rdx, ecx
1557        add    rsi, rdx
1558        call   rawCopyS2L
1559        pop    rsi
1560        ret
1561
1562add_l1:
1563        bt     rcx, 63          ; Check if is short second operand
1564        jc     add_l1l2
1565
1566;;;;;;;;
1567add_l1s2:
1568        bt     rax, 62          ; check if montgomery first
1569        jc     add_l1ms2
1570add_l1ns2:
1571        mov r11b, 0x80
1572        shl r11, 56
1573        mov [rdi], r11
1574
1575        add rsi, 8
1576        movsx rdx, ecx
1577        add rdi, 8
1578        cmp rdx, 0
1579        
1580        jns tmp_1
1581        neg rdx
1582        call rawSubLS
1583        sub rdi, 8
1584        sub rsi, 8
1585        ret
1586tmp_1:
1587        call rawAddLS
1588        sub rdi, 8
1589        sub rsi, 8
1590        ret
1591
1592
1593
1594add_l1ms2:
1595        bt     rcx, 62          ; check if montgomery second
1596        jc     add_l1ms2m
1597add_l1ms2n:
1598        mov r11b, 0xC0
1599        shl r11, 56
1600        mov [rdi], r11
1601        push rdi
1602        mov  rdi, rdx
1603        call Fr_toMontgomery
1604        mov  rdx, rdi
1605        pop  rdi
1606
1607        add rdi, 8
1608        add rsi, 8
1609        add rdx, 8
1610        call rawAddLL
1611        sub rdi, 8
1612        sub rsi, 8
1613        ret
1614
1615
1616add_l1ms2m:
1617        mov r11b, 0xC0
1618        shl r11, 56
1619        mov [rdi], r11
1620
1621        add rdi, 8
1622        add rsi, 8
1623        add rdx, 8
1624        call rawAddLL
1625        sub rdi, 8
1626        sub rsi, 8
1627        ret
1628
1629
1630
1631;;;;;;;;
1632add_s1l2:
1633        bt     rcx, 62          ; check if montgomery first
1634        jc     add_s1l2m
1635add_s1l2n:
1636        mov r11b, 0x80
1637        shl r11, 56
1638        mov [rdi], r11
1639
1640        lea rsi, [rdx + 8]
1641        movsx rdx, eax
1642        add rdi, 8
1643        cmp rdx, 0
1644        
1645        jns tmp_2
1646        neg rdx
1647        call rawSubLS
1648        sub rdi, 8
1649        sub rsi, 8
1650        ret
1651tmp_2:
1652        call rawAddLS
1653        sub rdi, 8
1654        sub rsi, 8
1655        ret
1656
1657
1658add_s1l2m:
1659        bt     rax, 62          ; check if montgomery second
1660        jc     add_s1ml2m
1661add_s1nl2m:
1662        mov r11b, 0xC0
1663        shl r11, 56
1664        mov [rdi], r11
1665        push rdi
1666        mov  rdi, rsi
1667        mov  rsi, rdx
1668        call Fr_toMontgomery
1669        mov  rdx, rsi
1670        mov  rsi, rdi
1671        pop  rdi
1672
1673        add rdi, 8
1674        add rsi, 8
1675        add rdx, 8
1676        call rawAddLL
1677        sub rdi, 8
1678        sub rsi, 8
1679        ret
1680
1681
1682add_s1ml2m:
1683        mov r11b, 0xC0
1684        shl r11, 56
1685        mov [rdi], r11
1686
1687        add rdi, 8
1688        add rsi, 8
1689        add rdx, 8
1690        call rawAddLL
1691        sub rdi, 8
1692        sub rsi, 8
1693        ret
1694
1695
1696;;;;
1697add_l1l2:
1698        bt     rax, 62          ; check if montgomery first
1699        jc     add_l1ml2
1700add_l1nl2:
1701        bt     rcx, 62          ; check if montgomery second
1702        jc     add_l1nl2m
1703add_l1nl2n:
1704        mov r11b, 0x80
1705        shl r11, 56
1706        mov [rdi], r11
1707
1708        add rdi, 8
1709        add rsi, 8
1710        add rdx, 8
1711        call rawAddLL
1712        sub rdi, 8
1713        sub rsi, 8
1714        ret
1715
1716
1717add_l1nl2m:
1718        mov r11b, 0xC0
1719        shl r11, 56
1720        mov [rdi], r11
1721        push rdi
1722        mov  rdi, rsi
1723        mov  rsi, rdx
1724        call Fr_toMontgomery
1725        mov  rdx, rsi
1726        mov  rsi, rdi
1727        pop  rdi
1728
1729        add rdi, 8
1730        add rsi, 8
1731        add rdx, 8
1732        call rawAddLL
1733        sub rdi, 8
1734        sub rsi, 8
1735        ret
1736
1737
1738add_l1ml2:
1739        bt     rcx, 62          ; check if montgomery seconf
1740        jc     add_l1ml2m
1741add_l1ml2n:
1742        mov r11b, 0xC0
1743        shl r11, 56
1744        mov [rdi], r11
1745        push rdi
1746        mov  rdi, rdx
1747        call Fr_toMontgomery
1748        mov  rdx, rdi
1749        pop  rdi
1750
1751        add rdi, 8
1752        add rsi, 8
1753        add rdx, 8
1754        call rawAddLL
1755        sub rdi, 8
1756        sub rsi, 8
1757        ret
1758
1759
1760add_l1ml2m:
1761        mov r11b, 0xC0
1762        shl r11, 56
1763        mov [rdi], r11
1764
1765        add rdi, 8
1766        add rsi, 8
1767        add rdx, 8
1768        call rawAddLL
1769        sub rdi, 8
1770        sub rsi, 8
1771        ret
1772
1773
1774
1775
1776;;;;;;;;;;;;;;;;;;;;;;
1777; rawAddLL
1778;;;;;;;;;;;;;;;;;;;;;;
1779; Adds two elements of type long
1780; Params:
1781;   rsi <= Pointer to the long data of element 1
1782;   rdx <= Pointer to the long data of element 2
1783;   rdi <= Pointer to the long data of result
1784; Modified Registers:
1785;    rax
1786;;;;;;;;;;;;;;;;;;;;;;
1787rawAddLL:
1788        ; Add component by component with carry
1789
1790        mov rax, [rsi + 0]
1791        add rax, [rdx + 0]
1792        mov [rdi + 0], rax
1793
1794        mov rax, [rsi + 8]
1795        adc rax, [rdx + 8]
1796        mov [rdi + 8], rax
1797
1798        mov rax, [rsi + 16]
1799        adc rax, [rdx + 16]
1800        mov [rdi + 16], rax
1801
1802        mov rax, [rsi + 24]
1803        adc rax, [rdx + 24]
1804        mov [rdi + 24], rax
1805
1806        jc rawAddLL_sq   ; if overflow, substract q
1807
1808        ; Compare with q
1809
1810
1811        cmp rax, [q + 24]
1812        jc rawAddLL_done        ; q is bigget so done.
1813        jnz rawAddLL_sq         ; q is lower
1814
1815
1816        mov rax, [rdi + 16]
1817
1818        cmp rax, [q + 16]
1819        jc rawAddLL_done        ; q is bigget so done.
1820        jnz rawAddLL_sq         ; q is lower
1821
1822
1823        mov rax, [rdi + 8]
1824
1825        cmp rax, [q + 8]
1826        jc rawAddLL_done        ; q is bigget so done.
1827        jnz rawAddLL_sq         ; q is lower
1828
1829
1830        mov rax, [rdi + 0]
1831
1832        cmp rax, [q + 0]
1833        jc rawAddLL_done        ; q is bigget so done.
1834        jnz rawAddLL_sq         ; q is lower
1835
1836        ; If equal substract q
1837rawAddLL_sq:
1838
1839        mov rax, [q + 0]
1840        sub [rdi + 0], rax
1841
1842        mov rax, [q + 8]
1843        sbb [rdi + 8], rax
1844
1845        mov rax, [q + 16]
1846        sbb [rdi + 16], rax
1847
1848        mov rax, [q + 24]
1849        sbb [rdi + 24], rax
1850
1851rawAddLL_done:
1852        ret
1853
1854
1855;;;;;;;;;;;;;;;;;;;;;;
1856; rawAddLS
1857;;;;;;;;;;;;;;;;;;;;;;
1858; Adds two elements of type long
1859; Params:
1860;   rdi <= Pointer to the long data of result
1861;   rsi <= Pointer to the long data of element 1
1862;   rdx <= Value to be added
1863;;;;;;;;;;;;;;;;;;;;;;
1864rawAddLS:
1865        ; Add component by component with carry
1866
1867        add rdx, [rsi]
1868        mov [rdi] ,rdx
1869
1870        mov rdx, 0
1871        adc rdx, [rsi + 8]
1872        mov [rdi + 8], rdx
1873
1874        mov rdx, 0
1875        adc rdx, [rsi + 16]
1876        mov [rdi + 16], rdx
1877
1878        mov rdx, 0
1879        adc rdx, [rsi + 24]
1880        mov [rdi + 24], rdx
1881
1882        jc rawAddLS_sq   ; if overflow, substract q
1883
1884        ; Compare with q
1885
1886        mov rax, [rdi + 24]
1887        cmp rax, [q + 24]
1888        jc rawAddLS_done        ; q is bigget so done.
1889        jnz rawAddLS_sq         ; q is lower
1890
1891        mov rax, [rdi + 16]
1892        cmp rax, [q + 16]
1893        jc rawAddLS_done        ; q is bigget so done.
1894        jnz rawAddLS_sq         ; q is lower
1895
1896        mov rax, [rdi + 8]
1897        cmp rax, [q + 8]
1898        jc rawAddLS_done        ; q is bigget so done.
1899        jnz rawAddLS_sq         ; q is lower
1900
1901        mov rax, [rdi + 0]
1902        cmp rax, [q + 0]
1903        jc rawAddLS_done        ; q is bigget so done.
1904        jnz rawAddLS_sq         ; q is lower
1905
1906        ; If equal substract q
1907rawAddLS_sq:
1908
1909        mov rax, [q + 0]
1910        sub [rdi + 0], rax
1911
1912        mov rax, [q + 8]
1913        sbb [rdi + 8], rax
1914
1915        mov rax, [q + 16]
1916        sbb [rdi + 16], rax
1917
1918        mov rax, [q + 24]
1919        sbb [rdi + 24], rax
1920
1921rawAddLS_done:
1922        ret
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938;;;;;;;;;;;;;;;;;;;;;;
1939; sub
1940;;;;;;;;;;;;;;;;;;;;;;
1941; Substracts two elements of any kind
1942; Params:
1943;   rsi <= Pointer to element 1
1944;   rdx <= Pointer to element 2
1945;   rdi <= Pointer to result
1946; Modified Registers:
1947;    r8, r9, 10, r11, rax, rcx
1948;;;;;;;;;;;;;;;;;;;;;;
1949Fr_sub:
1950        mov    rax, [rsi]
1951        mov    rcx, [rdx]
1952        bt     rax, 63          ; Check if is long first operand
1953        jc     sub_l1
1954        bt     rcx, 63          ; Check if is long second operand
1955        jc     sub_s1l2
1956
1957sub_s1s2:                       ; Both operands are short
1958
1959        xor    rdx, rdx
1960        mov    edx, eax
1961        sub    edx, ecx
1962        jo     sub_manageOverflow   ; rsi already is the 64bits result
1963
1964        mov    [rdi], rdx       ; not necessary to adjust so just save and return
1965        ret
1966
1967sub_manageOverflow:                 ; Do the operation in 64 bits
1968        push   rsi
1969        movsx  rsi, eax
1970        movsx  rdx, ecx
1971        sub    rsi, rdx
1972        call   rawCopyS2L
1973        pop    rsi
1974        ret
1975
1976sub_l1:
1977        bt     rcx, 63          ; Check if is short second operand
1978        jc     sub_l1l2
1979
1980;;;;;;;;
1981sub_l1s2:
1982        bt     rax, 62          ; check if montgomery first
1983        jc     sub_l1ms2
1984sub_l1ns2:
1985        mov r11b, 0x80
1986        shl r11, 56
1987        mov [rdi], r11
1988
1989        add rsi, 8
1990        movsx rdx, ecx
1991        add rdi, 8
1992        cmp rdx, 0
1993        
1994        jns tmp_3
1995        neg rdx
1996        call rawAddLS
1997        sub rdi, 8
1998        sub rsi, 8
1999        ret
2000tmp_3:
2001        call rawSubLS
2002        sub rdi, 8
2003        sub rsi, 8
2004        ret
2005
2006
2007sub_l1ms2:
2008        bt     rcx, 62          ; check if montgomery second
2009        jc     sub_l1ms2m
2010sub_l1ms2n:
2011        mov r11b, 0xC0
2012        shl r11, 56
2013        mov [rdi], r11
2014        push rdi
2015        mov  rdi, rdx
2016        call Fr_toMontgomery
2017        mov  rdx, rdi
2018        pop  rdi
2019
2020        add rdi, 8
2021        add rsi, 8
2022        add rdx, 8
2023        call rawSubLL
2024        sub rdi, 8
2025        sub rsi, 8
2026        ret
2027
2028
2029sub_l1ms2m:
2030        mov r11b, 0xC0
2031        shl r11, 56
2032        mov [rdi], r11
2033
2034        add rdi, 8
2035        add rsi, 8
2036        add rdx, 8
2037        call rawSubLL
2038        sub rdi, 8
2039        sub rsi, 8
2040        ret
2041
2042
2043
2044;;;;;;;;
2045sub_s1l2:
2046        bt     rcx, 62          ; check if montgomery first
2047        jc     sub_s1l2m
2048sub_s1l2n:
2049        mov r11b, 0x80
2050        shl r11, 56
2051        mov [rdi], r11
2052
2053        cmp eax, 0
2054        
2055        js tmp_4
2056
2057        ; First Operand is positive
2058        push rsi
2059        add rdi, 8
2060        movsx rsi, eax
2061        add rdx, 8
2062        call rawSubSL
2063        sub rdi, 8
2064        pop rsi
2065        ret
2066
2067tmp_4:   ; First operand is negative
2068        push rsi
2069        lea rsi, [rdx + 8]
2070        movsx rdx, eax
2071        add rdi, 8
2072        neg rdx
2073        call rawNegLS
2074        sub rdi, 8
2075        pop rsi
2076        ret
2077
2078
2079sub_s1l2m:
2080        bt     rax, 62          ; check if montgomery second
2081        jc     sub_s1ml2m
2082sub_s1nl2m:
2083        mov r11b, 0xC0
2084        shl r11, 56
2085        mov [rdi], r11
2086        push rdi
2087        mov  rdi, rsi
2088        mov  rsi, rdx
2089        call Fr_toMontgomery
2090        mov  rdx, rsi
2091        mov  rsi, rdi
2092        pop  rdi
2093
2094        add rdi, 8
2095        add rsi, 8
2096        add rdx, 8
2097        call rawSubLL
2098        sub rdi, 8
2099        sub rsi, 8
2100        ret
2101
2102
2103sub_s1ml2m:
2104        mov r11b, 0xC0
2105        shl r11, 56
2106        mov [rdi], r11
2107
2108        add rdi, 8
2109        add rsi, 8
2110        add rdx, 8
2111        call rawSubLL
2112        sub rdi, 8
2113        sub rsi, 8
2114        ret
2115
2116
2117;;;;
2118sub_l1l2:
2119        bt     rax, 62          ; check if montgomery first
2120        jc     sub_l1ml2
2121sub_l1nl2:
2122        bt     rcx, 62          ; check if montgomery second
2123        jc     sub_l1nl2m
2124sub_l1nl2n:
2125        mov r11b, 0x80
2126        shl r11, 56
2127        mov [rdi], r11
2128
2129        add rdi, 8
2130        add rsi, 8
2131        add rdx, 8
2132        call rawSubLL
2133        sub rdi, 8
2134        sub rsi, 8
2135        ret
2136
2137
2138sub_l1nl2m:
2139        mov r11b, 0xC0
2140        shl r11, 56
2141        mov [rdi], r11
2142        push rdi
2143        mov  rdi, rsi
2144        mov  rsi, rdx
2145        call Fr_toMontgomery
2146        mov  rdx, rsi
2147        mov  rsi, rdi
2148        pop  rdi
2149
2150        add rdi, 8
2151        add rsi, 8
2152        add rdx, 8
2153        call rawSubLL
2154        sub rdi, 8
2155        sub rsi, 8
2156        ret
2157
2158
2159sub_l1ml2:
2160        bt     rcx, 62          ; check if montgomery seconf
2161        jc     sub_l1ml2m
2162sub_l1ml2n:
2163        mov r11b, 0xC0
2164        shl r11, 56
2165        mov [rdi], r11
2166        push rdi
2167        mov  rdi, rdx
2168        call Fr_toMontgomery
2169        mov  rdx, rdi
2170        pop  rdi
2171
2172        add rdi, 8
2173        add rsi, 8
2174        add rdx, 8
2175        call rawSubLL
2176        sub rdi, 8
2177        sub rsi, 8
2178        ret
2179
2180
2181sub_l1ml2m:
2182        mov r11b, 0xC0
2183        shl r11, 56
2184        mov [rdi], r11
2185
2186        add rdi, 8
2187        add rsi, 8
2188        add rdx, 8
2189        call rawSubLL
2190        sub rdi, 8
2191        sub rsi, 8
2192        ret
2193
2194
2195
2196;;;;;;;;;;;;;;;;;;;;;;
2197; rawSubLS
2198;;;;;;;;;;;;;;;;;;;;;;
2199; Substracts a short element from the long element
2200; Params:
2201;   rdi <= Pointer to the long data of result
2202;   rsi <= Pointer to the long data of element 1 where will be substracted
2203;   rdx <= Value to be substracted
2204;   [rdi] = [rsi] - rdx
2205; Modified Registers:
2206;    rax
2207;;;;;;;;;;;;;;;;;;;;;;
2208rawSubLS:
2209        ; Substract first digit
2210
2211        mov rax, [rsi]
2212        sub rax, rdx
2213        mov [rdi] ,rax
2214        mov rdx, 0
2215
2216        mov rax, [rsi + 8]
2217        sbb rax, rdx
2218        mov [rdi + 8], rax
2219
2220        mov rax, [rsi + 16]
2221        sbb rax, rdx
2222        mov [rdi + 16], rax
2223
2224        mov rax, [rsi + 24]
2225        sbb rax, rdx
2226        mov [rdi + 24], rax
2227
2228        jnc rawSubLS_done   ; if overflow, add q
2229
2230        ; Add q
2231rawSubLS_aq:
2232
2233        mov rax, [q + 0]
2234        add [rdi + 0], rax
2235
2236        mov rax, [q + 8]
2237        adc [rdi + 8], rax
2238
2239        mov rax, [q + 16]
2240        adc [rdi + 16], rax
2241
2242        mov rax, [q + 24]
2243        adc [rdi + 24], rax
2244
2245rawSubLS_done:
2246        ret
2247
2248
2249;;;;;;;;;;;;;;;;;;;;;;
2250; rawSubSL
2251;;;;;;;;;;;;;;;;;;;;;;
2252; Substracts a long element from a short element
2253; Params:
2254;   rdi <= Pointer to the long data of result
2255;   rsi <= Value from where will bo substracted
2256;   rdx <= Pointer to long of the value to be substracted
2257;
2258;   [rdi] = rsi - [rdx]
2259; Modified Registers:
2260;    rax
2261;;;;;;;;;;;;;;;;;;;;;;
2262rawSubSL:
2263        ; Substract first digit
2264        sub rsi, [rdx]
2265        mov [rdi] ,rsi
2266
2267
2268        mov rax, 0
2269        sbb rax, [rdx + 8]
2270        mov [rdi + 8], rax
2271
2272        mov rax, 0
2273        sbb rax, [rdx + 16]
2274        mov [rdi + 16], rax
2275
2276        mov rax, 0
2277        sbb rax, [rdx + 24]
2278        mov [rdi + 24], rax
2279
2280        jnc rawSubSL_done   ; if overflow, add q
2281
2282        ; Add q
2283rawSubSL_aq:
2284
2285        mov rax, [q + 0]
2286        add [rdi + 0], rax
2287
2288        mov rax, [q + 8]
2289        adc [rdi + 8], rax
2290
2291        mov rax, [q + 16]
2292        adc [rdi + 16], rax
2293
2294        mov rax, [q + 24]
2295        adc [rdi + 24], rax
2296
2297rawSubSL_done:
2298        ret
2299
2300;;;;;;;;;;;;;;;;;;;;;;
2301; rawSubLL
2302;;;;;;;;;;;;;;;;;;;;;;
2303; Substracts a long element from a short element
2304; Params:
2305;   rdi <= Pointer to the long data of result
2306;   rsi <= Pointer to long from where substracted
2307;   rdx <= Pointer to long of the value to be substracted
2308;
2309;   [rdi] = [rsi] - [rdx]
2310; Modified Registers:
2311;    rax
2312;;;;;;;;;;;;;;;;;;;;;;
2313rawSubLL:
2314        ; Substract first digit
2315
2316        mov rax, [rsi + 0]
2317        sub rax, [rdx + 0]
2318        mov [rdi + 0], rax
2319
2320        mov rax, [rsi + 8]
2321        sbb rax, [rdx + 8]
2322        mov [rdi + 8], rax
2323
2324        mov rax, [rsi + 16]
2325        sbb rax, [rdx + 16]
2326        mov [rdi + 16], rax
2327
2328        mov rax, [rsi + 24]
2329        sbb rax, [rdx + 24]
2330        mov [rdi + 24], rax
2331
2332        jnc rawSubLL_done   ; if overflow, add q
2333
2334        ; Add q
2335rawSubLL_aq:
2336
2337        mov rax, [q + 0]
2338        add [rdi + 0], rax
2339
2340        mov rax, [q + 8]
2341        adc [rdi + 8], rax
2342
2343        mov rax, [q + 16]
2344        adc [rdi + 16], rax
2345
2346        mov rax, [q + 24]
2347        adc [rdi + 24], rax
2348
2349rawSubLL_done:
2350        ret
2351
2352;;;;;;;;;;;;;;;;;;;;;;
2353; rawNegLS
2354;;;;;;;;;;;;;;;;;;;;;;
2355; Substracts a long element and a short element form 0
2356; Params:
2357;   rdi <= Pointer to the long data of result
2358;   rsi <= Pointer to long from where substracted
2359;   rdx <= short value to be substracted too
2360;
2361;   [rdi] = -[rsi] - rdx
2362; Modified Registers:
2363;    rax
2364;;;;;;;;;;;;;;;;;;;;;;
2365rawNegLS:
2366        mov rax, [q]
2367        sub rax, rdx
2368        mov [rdi], rax
2369
2370        mov rax, [q + 8 ]
2371        sbb rax, 0
2372        mov [rdi + 8], rax
2373
2374        mov rax, [q + 16 ]
2375        sbb rax, 0
2376        mov [rdi + 16], rax
2377
2378        mov rax, [q + 24 ]
2379        sbb rax, 0
2380        mov [rdi + 24], rax
2381
2382        setc dl
2383
2384
2385        mov rax, [rdi + 0 ]
2386        sub rax, [rsi + 0]
2387        mov [rdi + 0], rax
2388
2389        mov rax, [rdi + 8 ]
2390        sbb rax, [rsi + 8]
2391        mov [rdi + 8], rax
2392
2393        mov rax, [rdi + 16 ]
2394        sbb rax, [rsi + 16]
2395        mov [rdi + 16], rax
2396
2397        mov rax, [rdi + 24 ]
2398        sbb rax, [rsi + 24]
2399        mov [rdi + 24], rax
2400
2401
2402        setc dh
2403        or dl, dh
2404        jz rawNegSL_done
2405
2406        ; it is a negative value, so add q
2407
2408        mov rax, [q + 0]
2409        add [rdi + 0], rax
2410
2411        mov rax, [q + 8]
2412        adc [rdi + 8], rax
2413
2414        mov rax, [q + 16]
2415        adc [rdi + 16], rax
2416
2417        mov rax, [q + 24]
2418        adc [rdi + 24], rax
2419
2420
2421rawNegSL_done:
2422        ret
2423
2424
2425
2426
2427
2428
2429
2430;;;;;;;;;;;;;;;;;;;;;;
2431; neg
2432;;;;;;;;;;;;;;;;;;;;;;
2433; Adds two elements of any kind
2434; Params:
2435;   rsi <= Pointer to element to be negated
2436;   rdi <= Pointer to result
2437;   [rdi] = -[rsi]
2438;;;;;;;;;;;;;;;;;;;;;;
2439Fr_neg:
2440        mov    rax, [rsi]
2441        bt     rax, 63          ; Check if is short first operand
2442        jc     neg_l
2443
2444neg_s:                          ; Operand is short
2445
2446        neg    eax
2447        jo     neg_manageOverflow   ; Check if overflow. (0x80000000 is the only case)
2448
2449        mov    [rdi], rax           ; not necessary to adjust so just save and return
2450        ret
2451
2452neg_manageOverflow:                 ; Do the operation in 64 bits
2453        push   rsi
2454        movsx  rsi, eax
2455        neg    rsi
2456        call   rawCopyS2L
2457        pop    rsi
2458        ret
2459
2460
2461
2462neg_l:
2463        mov [rdi], rax          ; Copy the type
2464
2465        add rdi, 8
2466        add rsi, 8
2467        call rawNegL
2468        sub rdi, 8
2469        sub rsi, 8
2470        ret
2471
2472
2473
2474;;;;;;;;;;;;;;;;;;;;;;
2475; rawNeg
2476;;;;;;;;;;;;;;;;;;;;;;
2477; Negates a value
2478; Params:
2479;   rdi <= Pointer to the long data of result
2480;   rsi <= Pointer to the long data of element 1
2481;
2482;   [rdi] = - [rsi]
2483;;;;;;;;;;;;;;;;;;;;;;
2484rawNegL:
2485        ; Compare is zero
2486
2487        xor rax, rax
2488
2489        cmp [rsi + 0], rax
2490        jnz doNegate
2491
2492        cmp [rsi + 8], rax
2493        jnz doNegate
2494
2495        cmp [rsi + 16], rax
2496        jnz doNegate
2497
2498        cmp [rsi + 24], rax
2499        jnz doNegate
2500
2501        ; it's zero so just set to zero
2502
2503        mov [rdi + 0], rax
2504
2505        mov [rdi + 8], rax
2506
2507        mov [rdi + 16], rax
2508
2509        mov [rdi + 24], rax
2510
2511        ret
2512doNegate:
2513
2514        mov rax, [q + 0]
2515        sub rax, [rsi + 0]
2516        mov [rdi + 0], rax
2517
2518        mov rax, [q + 8]
2519        sbb rax, [rsi + 8]
2520        mov [rdi + 8], rax
2521
2522        mov rax, [q + 16]
2523        sbb rax, [rsi + 16]
2524        mov [rdi + 16], rax
2525
2526        mov rax, [q + 24]
2527        sbb rax, [rsi + 24]
2528        mov [rdi + 24], rax
2529
2530        ret
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550;;;;;;;;;;;;;;;;;;;;;;
2551; square
2552;;;;;;;;;;;;;;;;;;;;;;
2553; Squares a field element
2554; Params:
2555;   rsi <= Pointer to element 1
2556;   rdi <= Pointer to result
2557;   [rdi] = [rsi] * [rsi]
2558; Modified Registers:
2559;    r8, r9, 10, r11, rax, rcx
2560;;;;;;;;;;;;;;;;;;;;;;
2561Fr_square:
2562        mov    r8, [rsi]
2563        bt     r8, 63          ; Check if is short first operand
2564        jc     square_l1
2565
2566square_s1:                       ; Both operands are short
2567
2568        xor    rax, rax
2569        mov    eax, r8d
2570        imul   eax
2571        jo     square_manageOverflow   ; rsi already is the 64bits result
2572
2573        mov    [rdi], rax       ; not necessary to adjust so just save and return
2574
2575square_manageOverflow:                 ; Do the operation in 64 bits
2576        push   rsi
2577        movsx  rax, r8d
2578        imul   rax
2579        mov    rsi, rax
2580        call   rawCopyS2L
2581        pop    rsi
2582
2583        ret
2584
2585square_l1:
2586        bt     r8, 62          ; check if montgomery first
2587        jc     square_l1m
2588square_l1n:
2589        mov r11b, 0xC0
2590        shl r11, 56
2591        mov [rdi], r11
2592
2593        add rdi, 8
2594        add rsi, 8
2595        call rawMontgomerySquare
2596        sub rdi, 8
2597        sub rsi, 8
2598
2599
2600        push rsi
2601        add rdi, 8
2602        mov rsi, rdi
2603        lea rdx, [R3]
2604        call rawMontgomeryMul
2605        sub rdi, 8
2606        pop rsi
2607
2608        ret
2609
2610square_l1m:
2611        mov r11b, 0xC0
2612        shl r11, 56
2613        mov [rdi], r11
2614
2615        add rdi, 8
2616        add rsi, 8
2617        call rawMontgomerySquare
2618        sub rdi, 8
2619        sub rsi, 8
2620
2621        ret
2622
2623
2624
2625;;;;;;;;;;;;;;;;;;;;;;
2626; mul
2627;;;;;;;;;;;;;;;;;;;;;;
2628; Multiplies two elements of any kind
2629; Params:
2630;   rsi <= Pointer to element 1
2631;   rdx <= Pointer to element 2
2632;   rdi <= Pointer to result
2633;   [rdi] = [rsi] * [rdi]
2634; Modified Registers:
2635;    r8, r9, 10, r11, rax, rcx
2636;;;;;;;;;;;;;;;;;;;;;;
2637Fr_mul:
2638        mov    r8, [rsi]
2639        mov    r9, [rdx]
2640        bt     r8, 63          ; Check if is short first operand
2641        jc     mul_l1
2642        bt     r9, 63          ; Check if is short second operand
2643        jc     mul_s1l2
2644
2645mul_s1s2:                       ; Both operands are short
2646
2647        xor    rax, rax
2648        mov    eax, r8d
2649        imul   r9d
2650        jo     mul_manageOverflow   ; rsi already is the 64bits result
2651
2652        mov    [rdi], rax       ; not necessary to adjust so just save and return
2653
2654mul_manageOverflow:                 ; Do the operation in 64 bits
2655        push   rsi
2656        movsx  rax, r8d
2657        movsx  rcx, r9d
2658        imul   rcx
2659        mov    rsi, rax
2660        call   rawCopyS2L
2661        pop    rsi
2662
2663        ret
2664
2665mul_l1:
2666        bt     r9, 63          ; Check if is short second operand
2667        jc     mul_l1l2
2668
2669;;;;;;;;
2670mul_l1s2:
2671        bt     r8, 62          ; check if montgomery first
2672        jc     mul_l1ms2
2673mul_l1ns2:
2674        bt     r9, 62          ; check if montgomery first
2675        jc     mul_l1ns2m
2676mul_l1ns2n:
2677        mov r11b, 0xC0
2678        shl r11, 56
2679        mov [rdi], r11
2680
2681        push rsi
2682        add rsi, 8
2683        movsx rdx, r9d
2684        add rdi, 8
2685        cmp rdx, 0
2686        
2687        jns tmp_5
2688        neg rdx
2689        call rawMontgomeryMul1
2690        mov rsi, rdi
2691        call rawNegL
2692        sub rdi, 8
2693        pop rsi
2694        
2695        jmp tmp_6
2696tmp_5:
2697        call rawMontgomeryMul1
2698        sub rdi, 8
2699        pop rsi
2700tmp_6:
2701
2702
2703
2704        push rsi
2705        add rdi, 8
2706        mov rsi, rdi
2707        lea rdx, [R3]
2708        call rawMontgomeryMul
2709        sub rdi, 8
2710        pop rsi
2711
2712        ret
2713
2714
2715mul_l1ns2m:
2716        mov r11b, 0x80
2717        shl r11, 56
2718        mov [rdi], r11
2719
2720        add rdi, 8
2721        add rsi, 8
2722        add rdx, 8
2723        call rawMontgomeryMul
2724        sub rdi, 8
2725        sub rsi, 8
2726
2727        ret
2728
2729
2730mul_l1ms2:
2731        bt     r9, 62          ; check if montgomery second
2732        jc     mul_l1ms2m
2733mul_l1ms2n:
2734        mov r11b, 0x80
2735        shl r11, 56
2736        mov [rdi], r11
2737
2738        push rsi
2739        add rsi, 8
2740        movsx rdx, r9d
2741        add rdi, 8
2742        cmp rdx, 0
2743        
2744        jns tmp_7
2745        neg rdx
2746        call rawMontgomeryMul1
2747        mov rsi, rdi
2748        call rawNegL
2749        sub rdi, 8
2750        pop rsi
2751        
2752        jmp tmp_8
2753tmp_7:
2754        call rawMontgomeryMul1
2755        sub rdi, 8
2756        pop rsi
2757tmp_8:
2758
2759
2760        ret
2761
2762mul_l1ms2m:
2763        mov r11b, 0xC0
2764        shl r11, 56
2765        mov [rdi], r11
2766
2767        add rdi, 8
2768        add rsi, 8
2769        add rdx, 8
2770        call rawMontgomeryMul
2771        sub rdi, 8
2772        sub rsi, 8
2773
2774        ret
2775
2776
2777;;;;;;;;
2778mul_s1l2:
2779        bt     r8, 62          ; check if montgomery first
2780        jc     mul_s1ml2
2781mul_s1nl2:
2782        bt     r9, 62          ; check if montgomery first
2783        jc     mul_s1nl2m
2784mul_s1nl2n:
2785        mov r11b, 0xC0
2786        shl r11, 56
2787        mov [rdi], r11
2788
2789        push rsi
2790        lea rsi, [rdx + 8]
2791        movsx rdx, r8d
2792        add rdi, 8
2793        cmp rdx, 0
2794        
2795        jns tmp_9
2796        neg rdx
2797        call rawMontgomeryMul1
2798        mov rsi, rdi
2799        call rawNegL
2800        sub rdi, 8
2801        pop rsi
2802        
2803        jmp tmp_10
2804tmp_9:
2805        call rawMontgomeryMul1
2806        sub rdi, 8
2807        pop rsi
2808tmp_10:
2809
2810
2811
2812        push rsi
2813        add rdi, 8
2814        mov rsi, rdi
2815        lea rdx, [R3]
2816        call rawMontgomeryMul
2817        sub rdi, 8
2818        pop rsi
2819
2820        ret
2821
2822mul_s1nl2m:
2823        mov r11b, 0x80
2824        shl r11, 56
2825        mov [rdi], r11
2826
2827        push rsi
2828        lea rsi, [rdx + 8]
2829        movsx rdx, r8d
2830        add rdi, 8
2831        cmp rdx, 0
2832        
2833        jns tmp_11
2834        neg rdx
2835        call rawMontgomeryMul1
2836        mov rsi, rdi
2837        call rawNegL
2838        sub rdi, 8
2839        pop rsi
2840        
2841        jmp tmp_12
2842tmp_11:
2843        call rawMontgomeryMul1
2844        sub rdi, 8
2845        pop rsi
2846tmp_12:
2847
2848
2849        ret
2850
2851mul_s1ml2:
2852        bt     r9, 62          ; check if montgomery first
2853        jc     mul_s1ml2m
2854mul_s1ml2n:
2855        mov r11b, 0x80
2856        shl r11, 56
2857        mov [rdi], r11
2858
2859        add rdi, 8
2860        add rsi, 8
2861        add rdx, 8
2862        call rawMontgomeryMul
2863        sub rdi, 8
2864        sub rsi, 8
2865
2866        ret
2867
2868mul_s1ml2m:
2869        mov r11b, 0xC0
2870        shl r11, 56
2871        mov [rdi], r11
2872
2873        add rdi, 8
2874        add rsi, 8
2875        add rdx, 8
2876        call rawMontgomeryMul
2877        sub rdi, 8
2878        sub rsi, 8
2879
2880        ret
2881
2882;;;;
2883mul_l1l2:
2884        bt     r8, 62          ; check if montgomery first
2885        jc     mul_l1ml2
2886mul_l1nl2:
2887        bt     r9, 62          ; check if montgomery second
2888        jc     mul_l1nl2m
2889mul_l1nl2n:
2890        mov r11b, 0xC0
2891        shl r11, 56
2892        mov [rdi], r11
2893
2894        add rdi, 8
2895        add rsi, 8
2896        add rdx, 8
2897        call rawMontgomeryMul
2898        sub rdi, 8
2899        sub rsi, 8
2900
2901
2902        push rsi
2903        add rdi, 8
2904        mov rsi, rdi
2905        lea rdx, [R3]
2906        call rawMontgomeryMul
2907        sub rdi, 8
2908        pop rsi
2909
2910        ret
2911
2912mul_l1nl2m:
2913        mov r11b, 0x80
2914        shl r11, 56
2915        mov [rdi], r11
2916
2917        add rdi, 8
2918        add rsi, 8
2919        add rdx, 8
2920        call rawMontgomeryMul
2921        sub rdi, 8
2922        sub rsi, 8
2923
2924        ret
2925
2926mul_l1ml2:
2927        bt     r9, 62          ; check if montgomery seconf
2928        jc     mul_l1ml2m
2929mul_l1ml2n:
2930        mov r11b, 0x80
2931        shl r11, 56
2932        mov [rdi], r11
2933
2934        add rdi, 8
2935        add rsi, 8
2936        add rdx, 8
2937        call rawMontgomeryMul
2938        sub rdi, 8
2939        sub rsi, 8
2940
2941        ret
2942
2943mul_l1ml2m:
2944        mov r11b, 0xC0
2945        shl r11, 56
2946        mov [rdi], r11
2947
2948        add rdi, 8
2949        add rsi, 8
2950        add rdx, 8
2951        call rawMontgomeryMul
2952        sub rdi, 8
2953        sub rsi, 8
2954
2955        ret
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973;;;;;;;;;;;;;;;;;;;;;;
2974; band
2975;;;;;;;;;;;;;;;;;;;;;;
2976; Adds two elements of any kind
2977; Params:
2978;   rsi <= Pointer to element 1
2979;   rdx <= Pointer to element 2
2980;   rdi <= Pointer to result
2981; Modified Registers:
2982;    r8, r9, 10, r11, rax, rcx
2983;;;;;;;;;;;;;;;;;;;;;;
2984Fr_band:
2985        mov    r8, [rsi]
2986        mov    r9, [rdx]
2987        bt     r8, 63          ; Check if is short first operand
2988        jc     and_l1
2989        bt     r9, 63          ; Check if is short second operand
2990        jc     and_s1l2
2991
2992and_s1s2:
2993
2994        cmp    r8d, 0
2995        
2996        js     tmp_13
2997
2998        cmp    r9d, 0
2999        js     tmp_13
3000        xor    rdx, rdx         ; both ops are positive so do the op and return
3001        mov    edx, r8d
3002        and    edx, r9d
3003        mov    [rdi], rdx       ; not necessary to adjust so just save and return
3004        ret
3005
3006tmp_13:
3007        mov r11b, 0x80
3008        shl r11, 56
3009        mov [rdi], r11
3010        push  rdi
3011        push   rsi
3012        mov   rdi, rdx
3013        movsx rsi, r9d
3014        call  rawCopyS2L
3015        mov   rdx, rdi
3016        pop   rsi
3017        pop   rdi
3018        push  rdi
3019        push  rdx
3020        mov   rdi, rsi
3021        movsx rsi, r8d
3022        call  rawCopyS2L
3023        mov   rsi, rdi
3024        pop   rdx
3025        pop   rdi
3026
3027
3028        mov rax, [rsi + 8]
3029        and rax, [rdx + 8]
3030
3031        mov    [rdi + 8 ], rax
3032
3033        mov rax, [rsi + 16]
3034        and rax, [rdx + 16]
3035
3036        mov    [rdi + 16 ], rax
3037
3038        mov rax, [rsi + 24]
3039        and rax, [rdx + 24]
3040
3041        mov    [rdi + 24 ], rax
3042
3043        mov rax, [rsi + 32]
3044        and rax, [rdx + 32]
3045
3046        and    rax, [lboMask]
3047
3048        mov    [rdi + 32 ], rax
3049
3050        ret
3051
3052
3053
3054
3055
3056
3057and_l1:
3058        bt     r9, 63          ; Check if is short second operand
3059        jc     and_l1l2
3060
3061
3062and_l1s2:
3063        bt     r8, 62          ; check if montgomery first
3064        jc     and_l1ms2
3065and_l1ns2:
3066        mov r11b, 0x80
3067        shl r11, 56
3068        mov [rdi], r11
3069
3070        cmp    r9d, 0
3071        
3072        js     tmp_14
3073        movsx  rax, r9d
3074        and rax, [rsi +8]
3075        mov    [rdi+8], rax
3076
3077        xor    rax, rax
3078        and rax, [rsi + 16];
3079
3080        mov    [rdi + 16 ], rax;
3081
3082        xor    rax, rax
3083        and rax, [rsi + 24];
3084
3085        mov    [rdi + 24 ], rax;
3086
3087        xor    rax, rax
3088        and rax, [rsi + 32];
3089
3090        and    rax, [lboMask] ;
3091
3092        mov    [rdi + 32 ], rax;
3093
3094        ret
3095
3096tmp_14:
3097        push  rdi
3098        push   rsi
3099        mov   rdi, rdx
3100        movsx rsi, r9d
3101        call  rawCopyS2L
3102        mov   rdx, rdi
3103        pop   rsi
3104        pop   rdi
3105        mov r11b, 0x80
3106        shl r11, 56
3107        mov [rdi], r11
3108
3109
3110        mov rax, [rsi + 8]
3111        and rax, [rdx + 8]
3112
3113        mov    [rdi + 8 ], rax
3114
3115        mov rax, [rsi + 16]
3116        and rax, [rdx + 16]
3117
3118        mov    [rdi + 16 ], rax
3119
3120        mov rax, [rsi + 24]
3121        and rax, [rdx + 24]
3122
3123        mov    [rdi + 24 ], rax
3124
3125        mov rax, [rsi + 32]
3126        and rax, [rdx + 32]
3127
3128        and    rax, [lboMask]
3129
3130        mov    [rdi + 32 ], rax
3131
3132        ret
3133
3134
3135
3136
3137and_l1ms2:
3138        mov r11b, 0x80
3139        shl r11, 56
3140        mov [rdi], r11
3141        push   r9              ; r9 is used in montgomery so we need to save it
3142        push rdi
3143        mov  rdi, rsi
3144        mov  rsi, rdx
3145        call Fr_toNormal
3146        mov  rdx, rsi
3147        mov  rsi, rdi
3148        pop  rdi
3149        pop    r9
3150
3151        cmp    r9d, 0
3152        
3153        js     tmp_15
3154        movsx  rax, r9d
3155        and rax, [rsi +8]
3156        mov    [rdi+8], rax
3157
3158        xor    rax, rax
3159        and rax, [rsi + 16];
3160
3161        mov    [rdi + 16 ], rax;
3162
3163        xor    rax, rax
3164        and rax, [rsi + 24];
3165
3166        mov    [rdi + 24 ], rax;
3167
3168        xor    rax, rax
3169        and rax, [rsi + 32];
3170
3171        and    rax, [lboMask] ;
3172
3173        mov    [rdi + 32 ], rax;
3174
3175        ret
3176
3177tmp_15:
3178        push  rdi
3179        push   rsi
3180        mov   rdi, rdx
3181        movsx rsi, r9d
3182        call  rawCopyS2L
3183        mov   rdx, rdi
3184        pop   rsi
3185        pop   rdi
3186        mov r11b, 0x80
3187        shl r11, 56
3188        mov [rdi], r11
3189
3190
3191        mov rax, [rsi + 8]
3192        and rax, [rdx + 8]
3193
3194        mov    [rdi + 8 ], rax
3195
3196        mov rax, [rsi + 16]
3197        and rax, [rdx + 16]
3198
3199        mov    [rdi + 16 ], rax
3200
3201        mov rax, [rsi + 24]
3202        and rax, [rdx + 24]
3203
3204        mov    [rdi + 24 ], rax
3205
3206        mov rax, [rsi + 32]
3207        and rax, [rdx + 32]
3208
3209        and    rax, [lboMask]
3210
3211        mov    [rdi + 32 ], rax
3212
3213        ret
3214
3215
3216
3217
3218
3219and_s1l2:
3220        bt     r9, 62          ; check if montgomery first
3221        jc     and_s1l2m
3222and_s1l2n:
3223        mov r11b, 0x80
3224        shl r11, 56
3225        mov [rdi], r11
3226
3227        cmp    r8d, 0
3228        
3229        js     tmp_16
3230        movsx  rax, r8d
3231        and rax, [rdx +8]
3232        mov    [rdi+8], rax
3233
3234        xor    rax, rax
3235        and rax, [rdx + 16]
3236
3237        mov    [rdi + 16 ], rax
3238
3239        xor    rax, rax
3240        and rax, [rdx + 24]
3241
3242        mov    [rdi + 24 ], rax
3243
3244        xor    rax, rax
3245        and rax, [rdx + 32]
3246
3247        and    rax, [lboMask]
3248
3249        mov    [rdi + 32 ], rax
3250
3251        ret
3252
3253tmp_16:
3254        push  rdi
3255        push  rdx
3256        mov   rdi, rsi
3257        movsx rsi, r8d
3258        call  rawCopyS2L
3259        mov   rsi, rdi
3260        pop   rdx
3261        pop   rdi
3262        mov r11b, 0x80
3263        shl r11, 56
3264        mov [rdi], r11
3265
3266
3267        mov rax, [rsi + 8]
3268        and rax, [rdx + 8]
3269
3270        mov    [rdi + 8 ], rax
3271
3272        mov rax, [rsi + 16]
3273        and rax, [rdx + 16]
3274
3275        mov    [rdi + 16 ], rax
3276
3277        mov rax, [rsi + 24]
3278        and rax, [rdx + 24]
3279
3280        mov    [rdi + 24 ], rax
3281
3282        mov rax, [rsi + 32]
3283        and rax, [rdx + 32]
3284
3285        and    rax, [lboMask]
3286
3287        mov    [rdi + 32 ], rax
3288
3289        ret
3290
3291
3292
3293
3294and_s1l2m:
3295        mov r11b, 0x80
3296        shl r11, 56
3297        mov [rdi], r11
3298        push   r8             ; r8 is used in montgomery so we need to save it
3299        push rdi
3300        mov  rdi, rdx
3301        call Fr_toNormal
3302        mov  rdx, rdi
3303        pop  rdi
3304        pop    r8
3305
3306        cmp    r8d, 0
3307        
3308        js     tmp_17
3309        movsx  rax, r8d
3310        and rax, [rdx +8]
3311        mov    [rdi+8], rax
3312
3313        xor    rax, rax
3314        and rax, [rdx + 16]
3315
3316        mov    [rdi + 16 ], rax
3317
3318        xor    rax, rax
3319        and rax, [rdx + 24]
3320
3321        mov    [rdi + 24 ], rax
3322
3323        xor    rax, rax
3324        and rax, [rdx + 32]
3325
3326        and    rax, [lboMask]
3327
3328        mov    [rdi + 32 ], rax
3329
3330        ret
3331
3332tmp_17:
3333        push  rdi
3334        push  rdx
3335        mov   rdi, rsi
3336        movsx rsi, r8d
3337        call  rawCopyS2L
3338        mov   rsi, rdi
3339        pop   rdx
3340        pop   rdi
3341        mov r11b, 0x80
3342        shl r11, 56
3343        mov [rdi], r11
3344
3345
3346        mov rax, [rsi + 8]
3347        and rax, [rdx + 8]
3348
3349        mov    [rdi + 8 ], rax
3350
3351        mov rax, [rsi + 16]
3352        and rax, [rdx + 16]
3353
3354        mov    [rdi + 16 ], rax
3355
3356        mov rax, [rsi + 24]
3357        and rax, [rdx + 24]
3358
3359        mov    [rdi + 24 ], rax
3360
3361        mov rax, [rsi + 32]
3362        and rax, [rdx + 32]
3363
3364        and    rax, [lboMask]
3365
3366        mov    [rdi + 32 ], rax
3367
3368        ret
3369
3370
3371
3372
3373
3374and_l1l2:
3375        bt     r8, 62          ; check if montgomery first
3376        jc     and_l1ml2
3377        bt     r9, 62          ; check if montgomery first
3378        jc     and_l1nl2m
3379and_l1nl2n:
3380        mov r11b, 0x80
3381        shl r11, 56
3382        mov [rdi], r11
3383
3384
3385        mov rax, [rsi + 8]
3386        and rax, [rdx + 8]
3387
3388        mov    [rdi + 8 ], rax
3389
3390        mov rax, [rsi + 16]
3391        and rax, [rdx + 16]
3392
3393        mov    [rdi + 16 ], rax
3394
3395        mov rax, [rsi + 24]
3396        and rax, [rdx + 24]
3397
3398        mov    [rdi + 24 ], rax
3399
3400        mov rax, [rsi + 32]
3401        and rax, [rdx + 32]
3402
3403        and    rax, [lboMask]
3404
3405        mov    [rdi + 32 ], rax
3406
3407        ret
3408
3409
3410and_l1nl2m:
3411        mov r11b, 0x80
3412        shl r11, 56
3413        mov [rdi], r11
3414        push rdi
3415        mov  rdi, rdx
3416        call Fr_toNormal
3417        mov  rdx, rdi
3418        pop  rdi
3419
3420
3421        mov rax, [rsi + 8]
3422        and rax, [rdx + 8]
3423
3424        mov    [rdi + 8 ], rax
3425
3426        mov rax, [rsi + 16]
3427        and rax, [rdx + 16]
3428
3429        mov    [rdi + 16 ], rax
3430
3431        mov rax, [rsi + 24]
3432        and rax, [rdx + 24]
3433
3434        mov    [rdi + 24 ], rax
3435
3436        mov rax, [rsi + 32]
3437        and rax, [rdx + 32]
3438
3439        and    rax, [lboMask]
3440
3441        mov    [rdi + 32 ], rax
3442
3443        ret
3444
3445
3446and_l1ml2:
3447        bt     r9, 62          ; check if montgomery first
3448        jc     and_l1ml2m
3449and_l1ml2n:
3450        mov r11b, 0x80
3451        shl r11, 56
3452        mov [rdi], r11
3453        push rdi
3454        mov  rdi, rsi
3455        mov  rsi, rdx
3456        call Fr_toNormal
3457        mov  rdx, rsi
3458        mov  rsi, rdi
3459        pop  rdi
3460
3461
3462        mov rax, [rsi + 8]
3463        and rax, [rdx + 8]
3464
3465        mov    [rdi + 8 ], rax
3466
3467        mov rax, [rsi + 16]
3468        and rax, [rdx + 16]
3469
3470        mov    [rdi + 16 ], rax
3471
3472        mov rax, [rsi + 24]
3473        and rax, [rdx + 24]
3474
3475        mov    [rdi + 24 ], rax
3476
3477        mov rax, [rsi + 32]
3478        and rax, [rdx + 32]
3479
3480        and    rax, [lboMask]
3481
3482        mov    [rdi + 32 ], rax
3483
3484        ret
3485
3486
3487and_l1ml2m:
3488        mov r11b, 0x80
3489        shl r11, 56
3490        mov [rdi], r11
3491        push rdi
3492        mov  rdi, rsi
3493        mov  rsi, rdx
3494        call Fr_toNormal
3495        mov  rdx, rsi
3496        mov  rsi, rdi
3497        pop  rdi
3498        push rdi
3499        mov  rdi, rdx
3500        call Fr_toNormal
3501        mov  rdx, rdi
3502        pop  rdi
3503
3504
3505        mov rax, [rsi + 8]
3506        and rax, [rdx + 8]
3507
3508        mov    [rdi + 8 ], rax
3509
3510        mov rax, [rsi + 16]
3511        and rax, [rdx + 16]
3512
3513        mov    [rdi + 16 ], rax
3514
3515        mov rax, [rsi + 24]
3516        and rax, [rdx + 24]
3517
3518        mov    [rdi + 24 ], rax
3519
3520        mov rax, [rsi + 32]
3521        and rax, [rdx + 32]
3522
3523        and    rax, [lboMask]
3524
3525        mov    [rdi + 32 ], rax
3526
3527        ret
3528
3529
3530
3531;;;;;;;;;;;;;;;;;;;;;;
3532; bor
3533;;;;;;;;;;;;;;;;;;;;;;
3534; Adds two elements of any kind
3535; Params:
3536;   rsi <= Pointer to element 1
3537;   rdx <= Pointer to element 2
3538;   rdi <= Pointer to result
3539; Modified Registers:
3540;    r8, r9, 10, r11, rax, rcx
3541;;;;;;;;;;;;;;;;;;;;;;
3542Fr_bor:
3543        mov    r8, [rsi]
3544        mov    r9, [rdx]
3545        bt     r8, 63          ; Check if is short first operand
3546        jc     or_l1
3547        bt     r9, 63          ; Check if is short second operand
3548        jc     or_s1l2
3549
3550or_s1s2:
3551
3552        cmp    r8d, 0
3553        
3554        js     tmp_18
3555
3556        cmp    r9d, 0
3557        js     tmp_18
3558        xor    rdx, rdx         ; both ops are positive so do the op and return
3559        mov    edx, r8d
3560        or    edx, r9d
3561        mov    [rdi], rdx       ; not necessary to adjust so just save and return
3562        ret
3563
3564tmp_18:
3565        mov r11b, 0x80
3566        shl r11, 56
3567        mov [rdi], r11
3568        push  rdi
3569        push   rsi
3570        mov   rdi, rdx
3571        movsx rsi, r9d
3572        call  rawCopyS2L
3573        mov   rdx, rdi
3574        pop   rsi
3575        pop   rdi
3576        push  rdi
3577        push  rdx
3578        mov   rdi, rsi
3579        movsx rsi, r8d
3580        call  rawCopyS2L
3581        mov   rsi, rdi
3582        pop   rdx
3583        pop   rdi
3584
3585
3586        mov rax, [rsi + 8]
3587        or rax, [rdx + 8]
3588
3589        mov    [rdi + 8 ], rax
3590
3591        mov rax, [rsi + 16]
3592        or rax, [rdx + 16]
3593
3594        mov    [rdi + 16 ], rax
3595
3596        mov rax, [rsi + 24]
3597        or rax, [rdx + 24]
3598
3599        mov    [rdi + 24 ], rax
3600
3601        mov rax, [rsi + 32]
3602        or rax, [rdx + 32]
3603
3604        and    rax, [lboMask]
3605
3606        mov    [rdi + 32 ], rax
3607
3608        ret
3609
3610
3611
3612
3613
3614
3615or_l1:
3616        bt     r9, 63          ; Check if is short second operand
3617        jc     or_l1l2
3618
3619
3620or_l1s2:
3621        bt     r8, 62          ; check if montgomery first
3622        jc     or_l1ms2
3623or_l1ns2:
3624        mov r11b, 0x80
3625        shl r11, 56
3626        mov [rdi], r11
3627
3628        cmp    r9d, 0
3629        
3630        js     tmp_19
3631        movsx  rax, r9d
3632        or rax, [rsi +8]
3633        mov    [rdi+8], rax
3634
3635        xor    rax, rax
3636        or rax, [rsi + 16];
3637
3638        mov    [rdi + 16 ], rax;
3639
3640        xor    rax, rax
3641        or rax, [rsi + 24];
3642
3643        mov    [rdi + 24 ], rax;
3644
3645        xor    rax, rax
3646        or rax, [rsi + 32];
3647
3648        and    rax, [lboMask] ;
3649
3650        mov    [rdi + 32 ], rax;
3651
3652        ret
3653
3654tmp_19:
3655        push  rdi
3656        push   rsi
3657        mov   rdi, rdx
3658        movsx rsi, r9d
3659        call  rawCopyS2L
3660        mov   rdx, rdi
3661        pop   rsi
3662        pop   rdi
3663        mov r11b, 0x80
3664        shl r11, 56
3665        mov [rdi], r11
3666
3667
3668        mov rax, [rsi + 8]
3669        or rax, [rdx + 8]
3670
3671        mov    [rdi + 8 ], rax
3672
3673        mov rax, [rsi + 16]
3674        or rax, [rdx + 16]
3675
3676        mov    [rdi + 16 ], rax
3677
3678        mov rax, [rsi + 24]
3679        or rax, [rdx + 24]
3680
3681        mov    [rdi + 24 ], rax
3682
3683        mov rax, [rsi + 32]
3684        or rax, [rdx + 32]
3685
3686        and    rax, [lboMask]
3687
3688        mov    [rdi + 32 ], rax
3689
3690        ret
3691
3692
3693
3694
3695or_l1ms2:
3696        mov r11b, 0x80
3697        shl r11, 56
3698        mov [rdi], r11
3699        push   r9              ; r9 is used in montgomery so we need to save it
3700        push rdi
3701        mov  rdi, rsi
3702        mov  rsi, rdx
3703        call Fr_toNormal
3704        mov  rdx, rsi
3705        mov  rsi, rdi
3706        pop  rdi
3707        pop    r9
3708
3709        cmp    r9d, 0
3710        
3711        js     tmp_20
3712        movsx  rax, r9d
3713        or rax, [rsi +8]
3714        mov    [rdi+8], rax
3715
3716        xor    rax, rax
3717        or rax, [rsi + 16];
3718
3719        mov    [rdi + 16 ], rax;
3720
3721        xor    rax, rax
3722        or rax, [rsi + 24];
3723
3724        mov    [rdi + 24 ], rax;
3725
3726        xor    rax, rax
3727        or rax, [rsi + 32];
3728
3729        and    rax, [lboMask] ;
3730
3731        mov    [rdi + 32 ], rax;
3732
3733        ret
3734
3735tmp_20:
3736        push  rdi
3737        push   rsi
3738        mov   rdi, rdx
3739        movsx rsi, r9d
3740        call  rawCopyS2L
3741        mov   rdx, rdi
3742        pop   rsi
3743        pop   rdi
3744        mov r11b, 0x80
3745        shl r11, 56
3746        mov [rdi], r11
3747
3748
3749        mov rax, [rsi + 8]
3750        or rax, [rdx + 8]
3751
3752        mov    [rdi + 8 ], rax
3753
3754        mov rax, [rsi + 16]
3755        or rax, [rdx + 16]
3756
3757        mov    [rdi + 16 ], rax
3758
3759        mov rax, [rsi + 24]
3760        or rax, [rdx + 24]
3761
3762        mov    [rdi + 24 ], rax
3763
3764        mov rax, [rsi + 32]
3765        or rax, [rdx + 32]
3766
3767        and    rax, [lboMask]
3768
3769        mov    [rdi + 32 ], rax
3770
3771        ret
3772
3773
3774
3775
3776
3777or_s1l2:
3778        bt     r9, 62          ; check if montgomery first
3779        jc     or_s1l2m
3780or_s1l2n:
3781        mov r11b, 0x80
3782        shl r11, 56
3783        mov [rdi], r11
3784
3785        cmp    r8d, 0
3786        
3787        js     tmp_21
3788        movsx  rax, r8d
3789        or rax, [rdx +8]
3790        mov    [rdi+8], rax
3791
3792        xor    rax, rax
3793        or rax, [rdx + 16]
3794
3795        mov    [rdi + 16 ], rax
3796
3797        xor    rax, rax
3798        or rax, [rdx + 24]
3799
3800        mov    [rdi + 24 ], rax
3801
3802        xor    rax, rax
3803        or rax, [rdx + 32]
3804
3805        and    rax, [lboMask]
3806
3807        mov    [rdi + 32 ], rax
3808
3809        ret
3810
3811tmp_21:
3812        push  rdi
3813        push  rdx
3814        mov   rdi, rsi
3815        movsx rsi, r8d
3816        call  rawCopyS2L
3817        mov   rsi, rdi
3818        pop   rdx
3819        pop   rdi
3820        mov r11b, 0x80
3821        shl r11, 56
3822        mov [rdi], r11
3823
3824
3825        mov rax, [rsi + 8]
3826        or rax, [rdx + 8]
3827
3828        mov    [rdi + 8 ], rax
3829
3830        mov rax, [rsi + 16]
3831        or rax, [rdx + 16]
3832
3833        mov    [rdi + 16 ], rax
3834
3835        mov rax, [rsi + 24]
3836        or rax, [rdx + 24]
3837
3838        mov    [rdi + 24 ], rax
3839
3840        mov rax, [rsi + 32]
3841        or rax, [rdx + 32]
3842
3843        and    rax, [lboMask]
3844
3845        mov    [rdi + 32 ], rax
3846
3847        ret
3848
3849
3850
3851
3852or_s1l2m:
3853        mov r11b, 0x80
3854        shl r11, 56
3855        mov [rdi], r11
3856        push   r8             ; r8 is used in montgomery so we need to save it
3857        push rdi
3858        mov  rdi, rdx
3859        call Fr_toNormal
3860        mov  rdx, rdi
3861        pop  rdi
3862        pop    r8
3863
3864        cmp    r8d, 0
3865        
3866        js     tmp_22
3867        movsx  rax, r8d
3868        or rax, [rdx +8]
3869        mov    [rdi+8], rax
3870
3871        xor    rax, rax
3872        or rax, [rdx + 16]
3873
3874        mov    [rdi + 16 ], rax
3875
3876        xor    rax, rax
3877        or rax, [rdx + 24]
3878
3879        mov    [rdi + 24 ], rax
3880
3881        xor    rax, rax
3882        or rax, [rdx + 32]
3883
3884        and    rax, [lboMask]
3885
3886        mov    [rdi + 32 ], rax
3887
3888        ret
3889
3890tmp_22:
3891        push  rdi
3892        push  rdx
3893        mov   rdi, rsi
3894        movsx rsi, r8d
3895        call  rawCopyS2L
3896        mov   rsi, rdi
3897        pop   rdx
3898        pop   rdi
3899        mov r11b, 0x80
3900        shl r11, 56
3901        mov [rdi], r11
3902
3903
3904        mov rax, [rsi + 8]
3905        or rax, [rdx + 8]
3906
3907        mov    [rdi + 8 ], rax
3908
3909        mov rax, [rsi + 16]
3910        or rax, [rdx + 16]
3911
3912        mov    [rdi + 16 ], rax
3913
3914        mov rax, [rsi + 24]
3915        or rax, [rdx + 24]
3916
3917        mov    [rdi + 24 ], rax
3918
3919        mov rax, [rsi + 32]
3920        or rax, [rdx + 32]
3921
3922        and    rax, [lboMask]
3923
3924        mov    [rdi + 32 ], rax
3925
3926        ret
3927
3928
3929
3930
3931
3932or_l1l2:
3933        bt     r8, 62          ; check if montgomery first
3934        jc     or_l1ml2
3935        bt     r9, 62          ; check if montgomery first
3936        jc     or_l1nl2m
3937or_l1nl2n:
3938        mov r11b, 0x80
3939        shl r11, 56
3940        mov [rdi], r11
3941
3942
3943        mov rax, [rsi + 8]
3944        or rax, [rdx + 8]
3945
3946        mov    [rdi + 8 ], rax
3947
3948        mov rax, [rsi + 16]
3949        or rax, [rdx + 16]
3950
3951        mov    [rdi + 16 ], rax
3952
3953        mov rax, [rsi + 24]
3954        or rax, [rdx + 24]
3955
3956        mov    [rdi + 24 ], rax
3957
3958        mov rax, [rsi + 32]
3959        or rax, [rdx + 32]
3960
3961        and    rax, [lboMask]
3962
3963        mov    [rdi + 32 ], rax
3964
3965        ret
3966
3967
3968or_l1nl2m:
3969        mov r11b, 0x80
3970        shl r11, 56
3971        mov [rdi], r11
3972        push rdi
3973        mov  rdi, rdx
3974        call Fr_toNormal
3975        mov  rdx, rdi
3976        pop  rdi
3977
3978
3979        mov rax, [rsi + 8]
3980        or rax, [rdx + 8]
3981
3982        mov    [rdi + 8 ], rax
3983
3984        mov rax, [rsi + 16]
3985        or rax, [rdx + 16]
3986
3987        mov    [rdi + 16 ], rax
3988
3989        mov rax, [rsi + 24]
3990        or rax, [rdx + 24]
3991
3992        mov    [rdi + 24 ], rax
3993
3994        mov rax, [rsi + 32]
3995        or rax, [rdx + 32]
3996
3997        and    rax, [lboMask]
3998
3999        mov    [rdi + 32 ], rax
4000
4001        ret
4002
4003
4004or_l1ml2:
4005        bt     r9, 62          ; check if montgomery first
4006        jc     or_l1ml2m
4007or_l1ml2n:
4008        mov r11b, 0x80
4009        shl r11, 56
4010        mov [rdi], r11
4011        push rdi
4012        mov  rdi, rsi
4013        mov  rsi, rdx
4014        call Fr_toNormal
4015        mov  rdx, rsi
4016        mov  rsi, rdi
4017        pop  rdi
4018
4019
4020        mov rax, [rsi + 8]
4021        or rax, [rdx + 8]
4022
4023        mov    [rdi + 8 ], rax
4024
4025        mov rax, [rsi + 16]
4026        or rax, [rdx + 16]
4027
4028        mov    [rdi + 16 ], rax
4029
4030        mov rax, [rsi + 24]
4031        or rax, [rdx + 24]
4032
4033        mov    [rdi + 24 ], rax
4034
4035        mov rax, [rsi + 32]
4036        or rax, [rdx + 32]
4037
4038        and    rax, [lboMask]
4039
4040        mov    [rdi + 32 ], rax
4041
4042        ret
4043
4044
4045or_l1ml2m:
4046        mov r11b, 0x80
4047        shl r11, 56
4048        mov [rdi], r11
4049        push rdi
4050        mov  rdi, rsi
4051        mov  rsi, rdx
4052        call Fr_toNormal
4053        mov  rdx, rsi
4054        mov  rsi, rdi
4055        pop  rdi
4056        push rdi
4057        mov  rdi, rdx
4058        call Fr_toNormal
4059        mov  rdx, rdi
4060        pop  rdi
4061
4062
4063        mov rax, [rsi + 8]
4064        or rax, [rdx + 8]
4065
4066        mov    [rdi + 8 ], rax
4067
4068        mov rax, [rsi + 16]
4069        or rax, [rdx + 16]
4070
4071        mov    [rdi + 16 ], rax
4072
4073        mov rax, [rsi + 24]
4074        or rax, [rdx + 24]
4075
4076        mov    [rdi + 24 ], rax
4077
4078        mov rax, [rsi + 32]
4079        or rax, [rdx + 32]
4080
4081        and    rax, [lboMask]
4082
4083        mov    [rdi + 32 ], rax
4084
4085        ret
4086
4087
4088
4089;;;;;;;;;;;;;;;;;;;;;;
4090; bxor
4091;;;;;;;;;;;;;;;;;;;;;;
4092; Adds two elements of any kind
4093; Params:
4094;   rsi <= Pointer to element 1
4095;   rdx <= Pointer to element 2
4096;   rdi <= Pointer to result
4097; Modified Registers:
4098;    r8, r9, 10, r11, rax, rcx
4099;;;;;;;;;;;;;;;;;;;;;;
4100Fr_bxor:
4101        mov    r8, [rsi]
4102        mov    r9, [rdx]
4103        bt     r8, 63          ; Check if is short first operand
4104        jc     xor_l1
4105        bt     r9, 63          ; Check if is short second operand
4106        jc     xor_s1l2
4107
4108xor_s1s2:
4109
4110        cmp    r8d, 0
4111        
4112        js     tmp_23
4113
4114        cmp    r9d, 0
4115        js     tmp_23
4116        xor    rdx, rdx         ; both ops are positive so do the op and return
4117        mov    edx, r8d
4118        xor    edx, r9d
4119        mov    [rdi], rdx       ; not necessary to adjust so just save and return
4120        ret
4121
4122tmp_23:
4123        mov r11b, 0x80
4124        shl r11, 56
4125        mov [rdi], r11
4126        push  rdi
4127        push   rsi
4128        mov   rdi, rdx
4129        movsx rsi, r9d
4130        call  rawCopyS2L
4131        mov   rdx, rdi
4132        pop   rsi
4133        pop   rdi
4134        push  rdi
4135        push  rdx
4136        mov   rdi, rsi
4137        movsx rsi, r8d
4138        call  rawCopyS2L
4139        mov   rsi, rdi
4140        pop   rdx
4141        pop   rdi
4142
4143
4144        mov rax, [rsi + 8]
4145        xor rax, [rdx + 8]
4146
4147        mov    [rdi + 8 ], rax
4148
4149        mov rax, [rsi + 16]
4150        xor rax, [rdx + 16]
4151
4152        mov    [rdi + 16 ], rax
4153
4154        mov rax, [rsi + 24]
4155        xor rax, [rdx + 24]
4156
4157        mov    [rdi + 24 ], rax
4158
4159        mov rax, [rsi + 32]
4160        xor rax, [rdx + 32]
4161
4162        and    rax, [lboMask]
4163
4164        mov    [rdi + 32 ], rax
4165
4166        ret
4167
4168
4169
4170
4171
4172
4173xor_l1:
4174        bt     r9, 63          ; Check if is short second operand
4175        jc     xor_l1l2
4176
4177
4178xor_l1s2:
4179        bt     r8, 62          ; check if montgomery first
4180        jc     xor_l1ms2
4181xor_l1ns2:
4182        mov r11b, 0x80
4183        shl r11, 56
4184        mov [rdi], r11
4185
4186        cmp    r9d, 0
4187        
4188        js     tmp_24
4189        movsx  rax, r9d
4190        xor rax, [rsi +8]
4191        mov    [rdi+8], rax
4192
4193        xor    rax, rax
4194        xor rax, [rsi + 16];
4195
4196        mov    [rdi + 16 ], rax;
4197
4198        xor    rax, rax
4199        xor rax, [rsi + 24];
4200
4201        mov    [rdi + 24 ], rax;
4202
4203        xor    rax, rax
4204        xor rax, [rsi + 32];
4205
4206        and    rax, [lboMask] ;
4207
4208        mov    [rdi + 32 ], rax;
4209
4210        ret
4211
4212tmp_24:
4213        push  rdi
4214        push   rsi
4215        mov   rdi, rdx
4216        movsx rsi, r9d
4217        call  rawCopyS2L
4218        mov   rdx, rdi
4219        pop   rsi
4220        pop   rdi
4221        mov r11b, 0x80
4222        shl r11, 56
4223        mov [rdi], r11
4224
4225
4226        mov rax, [rsi + 8]
4227        xor rax, [rdx + 8]
4228
4229        mov    [rdi + 8 ], rax
4230
4231        mov rax, [rsi + 16]
4232        xor rax, [rdx + 16]
4233
4234        mov    [rdi + 16 ], rax
4235
4236        mov rax, [rsi + 24]
4237        xor rax, [rdx + 24]
4238
4239        mov    [rdi + 24 ], rax
4240
4241        mov rax, [rsi + 32]
4242        xor rax, [rdx + 32]
4243
4244        and    rax, [lboMask]
4245
4246        mov    [rdi + 32 ], rax
4247
4248        ret
4249
4250
4251
4252
4253xor_l1ms2:
4254        mov r11b, 0x80
4255        shl r11, 56
4256        mov [rdi], r11
4257        push   r9              ; r9 is used in montgomery so we need to save it
4258        push rdi
4259        mov  rdi, rsi
4260        mov  rsi, rdx
4261        call Fr_toNormal
4262        mov  rdx, rsi
4263        mov  rsi, rdi
4264        pop  rdi
4265        pop    r9
4266
4267        cmp    r9d, 0
4268        
4269        js     tmp_25
4270        movsx  rax, r9d
4271        xor rax, [rsi +8]
4272        mov    [rdi+8], rax
4273
4274        xor    rax, rax
4275        xor rax, [rsi + 16];
4276
4277        mov    [rdi + 16 ], rax;
4278
4279        xor    rax, rax
4280        xor rax, [rsi + 24];
4281
4282        mov    [rdi + 24 ], rax;
4283
4284        xor    rax, rax
4285        xor rax, [rsi + 32];
4286
4287        and    rax, [lboMask] ;
4288
4289        mov    [rdi + 32 ], rax;
4290
4291        ret
4292
4293tmp_25:
4294        push  rdi
4295        push   rsi
4296        mov   rdi, rdx
4297        movsx rsi, r9d
4298        call  rawCopyS2L
4299        mov   rdx, rdi
4300        pop   rsi
4301        pop   rdi
4302        mov r11b, 0x80
4303        shl r11, 56
4304        mov [rdi], r11
4305
4306
4307        mov rax, [rsi + 8]
4308        xor rax, [rdx + 8]
4309
4310        mov    [rdi + 8 ], rax
4311
4312        mov rax, [rsi + 16]
4313        xor rax, [rdx + 16]
4314
4315        mov    [rdi + 16 ], rax
4316
4317        mov rax, [rsi + 24]
4318        xor rax, [rdx + 24]
4319
4320        mov    [rdi + 24 ], rax
4321
4322        mov rax, [rsi + 32]
4323        xor rax, [rdx + 32]
4324
4325        and    rax, [lboMask]
4326
4327        mov    [rdi + 32 ], rax
4328
4329        ret
4330
4331
4332
4333
4334
4335xor_s1l2:
4336        bt     r9, 62          ; check if montgomery first
4337        jc     xor_s1l2m
4338xor_s1l2n:
4339        mov r11b, 0x80
4340        shl r11, 56
4341        mov [rdi], r11
4342
4343        cmp    r8d, 0
4344        
4345        js     tmp_26
4346        movsx  rax, r8d
4347        xor rax, [rdx +8]
4348        mov    [rdi+8], rax
4349
4350        xor    rax, rax
4351        xor rax, [rdx + 16]
4352
4353        mov    [rdi + 16 ], rax
4354
4355        xor    rax, rax
4356        xor rax, [rdx + 24]
4357
4358        mov    [rdi + 24 ], rax
4359
4360        xor    rax, rax
4361        xor rax, [rdx + 32]
4362
4363        and    rax, [lboMask]
4364
4365        mov    [rdi + 32 ], rax
4366
4367        ret
4368
4369tmp_26:
4370        push  rdi
4371        push  rdx
4372        mov   rdi, rsi
4373        movsx rsi, r8d
4374        call  rawCopyS2L
4375        mov   rsi, rdi
4376        pop   rdx
4377        pop   rdi
4378        mov r11b, 0x80
4379        shl r11, 56
4380        mov [rdi], r11
4381
4382
4383        mov rax, [rsi + 8]
4384        xor rax, [rdx + 8]
4385
4386        mov    [rdi + 8 ], rax
4387
4388        mov rax, [rsi + 16]
4389        xor rax, [rdx + 16]
4390
4391        mov    [rdi + 16 ], rax
4392
4393        mov rax, [rsi + 24]
4394        xor rax, [rdx + 24]
4395
4396        mov    [rdi + 24 ], rax
4397
4398        mov rax, [rsi + 32]
4399        xor rax, [rdx + 32]
4400
4401        and    rax, [lboMask]
4402
4403        mov    [rdi + 32 ], rax
4404
4405        ret
4406
4407
4408
4409
4410xor_s1l2m:
4411        mov r11b, 0x80
4412        shl r11, 56
4413        mov [rdi], r11
4414        push   r8             ; r8 is used in montgomery so we need to save it
4415        push rdi
4416        mov  rdi, rdx
4417        call Fr_toNormal
4418        mov  rdx, rdi
4419        pop  rdi
4420        pop    r8
4421
4422        cmp    r8d, 0
4423        
4424        js     tmp_27
4425        movsx  rax, r8d
4426        xor rax, [rdx +8]
4427        mov    [rdi+8], rax
4428
4429        xor    rax, rax
4430        xor rax, [rdx + 16]
4431
4432        mov    [rdi + 16 ], rax
4433
4434        xor    rax, rax
4435        xor rax, [rdx + 24]
4436
4437        mov    [rdi + 24 ], rax
4438
4439        xor    rax, rax
4440        xor rax, [rdx + 32]
4441
4442        and    rax, [lboMask]
4443
4444        mov    [rdi + 32 ], rax
4445
4446        ret
4447
4448tmp_27:
4449        push  rdi
4450        push  rdx
4451        mov   rdi, rsi
4452        movsx rsi, r8d
4453        call  rawCopyS2L
4454        mov   rsi, rdi
4455        pop   rdx
4456        pop   rdi
4457        mov r11b, 0x80
4458        shl r11, 56
4459        mov [rdi], r11
4460
4461
4462        mov rax, [rsi + 8]
4463        xor rax, [rdx + 8]
4464
4465        mov    [rdi + 8 ], rax
4466
4467        mov rax, [rsi + 16]
4468        xor rax, [rdx + 16]
4469
4470        mov    [rdi + 16 ], rax
4471
4472        mov rax, [rsi + 24]
4473        xor rax, [rdx + 24]
4474
4475        mov    [rdi + 24 ], rax
4476
4477        mov rax, [rsi + 32]
4478        xor rax, [rdx + 32]
4479
4480        and    rax, [lboMask]
4481
4482        mov    [rdi + 32 ], rax
4483
4484        ret
4485
4486
4487
4488
4489
4490xor_l1l2:
4491        bt     r8, 62          ; check if montgomery first
4492        jc     xor_l1ml2
4493        bt     r9, 62          ; check if montgomery first
4494        jc     xor_l1nl2m
4495xor_l1nl2n:
4496        mov r11b, 0x80
4497        shl r11, 56
4498        mov [rdi], r11
4499
4500
4501        mov rax, [rsi + 8]
4502        xor rax, [rdx + 8]
4503
4504        mov    [rdi + 8 ], rax
4505
4506        mov rax, [rsi + 16]
4507        xor rax, [rdx + 16]
4508
4509        mov    [rdi + 16 ], rax
4510
4511        mov rax, [rsi + 24]
4512        xor rax, [rdx + 24]
4513
4514        mov    [rdi + 24 ], rax
4515
4516        mov rax, [rsi + 32]
4517        xor rax, [rdx + 32]
4518
4519        and    rax, [lboMask]
4520
4521        mov    [rdi + 32 ], rax
4522
4523        ret
4524
4525
4526xor_l1nl2m:
4527        mov r11b, 0x80
4528        shl r11, 56
4529        mov [rdi], r11
4530        push rdi
4531        mov  rdi, rdx
4532        call Fr_toNormal
4533        mov  rdx, rdi
4534        pop  rdi
4535
4536
4537        mov rax, [rsi + 8]
4538        xor rax, [rdx + 8]
4539
4540        mov    [rdi + 8 ], rax
4541
4542        mov rax, [rsi + 16]
4543        xor rax, [rdx + 16]
4544
4545        mov    [rdi + 16 ], rax
4546
4547        mov rax, [rsi + 24]
4548        xor rax, [rdx + 24]
4549
4550        mov    [rdi + 24 ], rax
4551
4552        mov rax, [rsi + 32]
4553        xor rax, [rdx + 32]
4554
4555        and    rax, [lboMask]
4556
4557        mov    [rdi + 32 ], rax
4558
4559        ret
4560
4561
4562xor_l1ml2:
4563        bt     r9, 62          ; check if montgomery first
4564        jc     xor_l1ml2m
4565xor_l1ml2n:
4566        mov r11b, 0x80
4567        shl r11, 56
4568        mov [rdi], r11
4569        push rdi
4570        mov  rdi, rsi
4571        mov  rsi, rdx
4572        call Fr_toNormal
4573        mov  rdx, rsi
4574        mov  rsi, rdi
4575        pop  rdi
4576
4577
4578        mov rax, [rsi + 8]
4579        xor rax, [rdx + 8]
4580
4581        mov    [rdi + 8 ], rax
4582
4583        mov rax, [rsi + 16]
4584        xor rax, [rdx + 16]
4585
4586        mov    [rdi + 16 ], rax
4587
4588        mov rax, [rsi + 24]
4589        xor rax, [rdx + 24]
4590
4591        mov    [rdi + 24 ], rax
4592
4593        mov rax, [rsi + 32]
4594        xor rax, [rdx + 32]
4595
4596        and    rax, [lboMask]
4597
4598        mov    [rdi + 32 ], rax
4599
4600        ret
4601
4602
4603xor_l1ml2m:
4604        mov r11b, 0x80
4605        shl r11, 56
4606        mov [rdi], r11
4607        push rdi
4608        mov  rdi, rsi
4609        mov  rsi, rdx
4610        call Fr_toNormal
4611        mov  rdx, rsi
4612        mov  rsi, rdi
4613        pop  rdi
4614        push rdi
4615        mov  rdi, rdx
4616        call Fr_toNormal
4617        mov  rdx, rdi
4618        pop  rdi
4619
4620
4621        mov rax, [rsi + 8]
4622        xor rax, [rdx + 8]
4623
4624        mov    [rdi + 8 ], rax
4625
4626        mov rax, [rsi + 16]
4627        xor rax, [rdx + 16]
4628
4629        mov    [rdi + 16 ], rax
4630
4631        mov rax, [rsi + 24]
4632        xor rax, [rdx + 24]
4633
4634        mov    [rdi + 24 ], rax
4635
4636        mov rax, [rsi + 32]
4637        xor rax, [rdx + 32]
4638
4639        and    rax, [lboMask]
4640
4641        mov    [rdi + 32 ], rax
4642
4643        ret
4644
4645
4646
4647
4648;;;;;;;;;;;;;;;;;;;;;;
4649; bnot
4650;;;;;;;;;;;;;;;;;;;;;;
4651; Adds two elements of any kind
4652; Params:
4653;   rsi <= Pointer to element 1
4654;   rdi <= Pointer to result
4655; Modified Registers:
4656;    r8, r9, 10, r11, rax, rcx
4657;;;;;;;;;;;;;;;;;;;;;;
4658Fr_bnot:
4659                mov r11b, 0x80
4660        shl r11, 56
4661        mov [rdi], r11
4662
4663        mov     r8, [rsi]
4664        bt      r8, 63          ; Check if is long operand
4665        jc      bnot_l1
4666bnot_s:
4667                push  rdi
4668        push  rdx
4669        mov   rdi, rsi
4670        movsx rsi, r8d
4671        call  rawCopyS2L
4672        mov   rsi, rdi
4673        pop   rdx
4674        pop   rdi
4675        jmp     bnot_l1n
4676
4677bnot_l1:
4678        bt     r8, 62          ; check if montgomery first
4679        jnc    bnot_l1n
4680
4681bnot_l1m:
4682        push rdi
4683        mov  rdi, rsi
4684        mov  rsi, rdx
4685        call Fr_toNormal
4686        mov  rdx, rsi
4687        mov  rsi, rdi
4688        pop  rdi
4689
4690bnot_l1n:
4691
4692        mov    rax, [rsi + 8]
4693        not    rax
4694
4695        mov    [rdi + 8], rax
4696
4697        mov    rax, [rsi + 16]
4698        not    rax
4699
4700        mov    [rdi + 16], rax
4701
4702        mov    rax, [rsi + 24]
4703        not    rax
4704
4705        mov    [rdi + 24], rax
4706
4707        mov    rax, [rsi + 32]
4708        not    rax
4709
4710        and    rax, [lboMask]
4711
4712        mov    [rdi + 32], rax
4713
4714        ret
4715
4716
4717
4718
4719
4720
4721;;;;;;;;;;;;;;;;;;;;;;
4722; rgt - Raw Greater Than
4723;;;;;;;;;;;;;;;;;;;;;;
4724; returns in ax 1 id *rsi > *rdx
4725; Params:
4726;   rsi <= Pointer to element 1
4727;   rdx <= Pointer to element 2
4728;   rax <= Return 1 or 0
4729; Modified Registers:
4730;    r8, r9, rax
4731;;;;;;;;;;;;;;;;;;;;;;
4732Fr_rgt:
4733        mov    r8, [rsi]
4734        mov    r9, [rdx]
4735        bt     r8, 63          ; Check if is short first operand
4736        jc     rgt_l1
4737        bt     r9, 63          ; Check if is short second operand
4738        jc     rgt_s1l2
4739
4740rgt_s1s2:                       ; Both operands are short
4741        cmp    r8d, r9d
4742        jg     rgt_ret1
4743        jmp    rgt_ret0
4744
4745
4746rgt_l1:
4747        bt     r9, 63          ; Check if is short second operand
4748        jc     rgt_l1l2
4749
4750;;;;;;;;
4751rgt_l1s2:
4752        bt     r8, 62          ; check if montgomery first
4753        jc     rgt_l1ms2
4754rgt_l1ns2:
4755        push  rdi
4756        push   rsi
4757        mov   rdi, rdx
4758        movsx rsi, r9d
4759        call  rawCopyS2L
4760        mov   rdx, rdi
4761        pop   rsi
4762        pop   rdi
4763        jmp rgtL1L2
4764
4765rgt_l1ms2:
4766        push  rdi
4767        push   rsi
4768        mov   rdi, rdx
4769        movsx rsi, r9d
4770        call  rawCopyS2L
4771        mov   rdx, rdi
4772        pop   rsi
4773        pop   rdi
4774        push rdi
4775        mov  rdi, rsi
4776        mov  rsi, rdx
4777        call Fr_toNormal
4778        mov  rdx, rsi
4779        mov  rsi, rdi
4780        pop  rdi
4781        jmp rgtL1L2
4782
4783
4784;;;;;;;;
4785rgt_s1l2:
4786        bt     r9, 62          ; check if montgomery second
4787        jc     rgt_s1l2m
4788rgt_s1l2n:
4789        push  rdi
4790        push  rdx
4791        mov   rdi, rsi
4792        movsx rsi, r8d
4793        call  rawCopyS2L
4794        mov   rsi, rdi
4795        pop   rdx
4796        pop   rdi
4797        jmp rgtL1L2
4798
4799rgt_s1l2m:
4800        push  rdi
4801        push  rdx
4802        mov   rdi, rsi
4803        movsx rsi, r8d
4804        call  rawCopyS2L
4805        mov   rsi, rdi
4806        pop   rdx
4807        pop   rdi
4808        push rdi
4809        mov  rdi, rdx
4810        call Fr_toNormal
4811        mov  rdx, rdi
4812        pop  rdi
4813        jmp rgtL1L2
4814
4815;;;;
4816rgt_l1l2:
4817        bt     r8, 62          ; check if montgomery first
4818        jc     rgt_l1ml2
4819rgt_l1nl2:
4820        bt     r9, 62          ; check if montgomery second
4821        jc     rgt_l1nl2m
4822rgt_l1nl2n:
4823        jmp rgtL1L2
4824
4825rgt_l1nl2m:
4826        push rdi
4827        mov  rdi, rdx
4828        call Fr_toNormal
4829        mov  rdx, rdi
4830        pop  rdi
4831        jmp rgtL1L2
4832
4833rgt_l1ml2:
4834        bt     r9, 62          ; check if montgomery second
4835        jc     rgt_l1ml2m
4836rgt_l1ml2n:
4837        push rdi
4838        mov  rdi, rsi
4839        mov  rsi, rdx
4840        call Fr_toNormal
4841        mov  rdx, rsi
4842        mov  rsi, rdi
4843        pop  rdi
4844        jmp rgtL1L2
4845
4846rgt_l1ml2m:
4847        push rdi
4848        mov  rdi, rsi
4849        mov  rsi, rdx
4850        call Fr_toNormal
4851        mov  rdx, rsi
4852        mov  rsi, rdi
4853        pop  rdi
4854        push rdi
4855        mov  rdi, rdx
4856        call Fr_toNormal
4857        mov  rdx, rdi
4858        pop  rdi
4859        jmp rgtL1L2
4860
4861
4862;;;;;;
4863; rgtL1L2
4864;;;;;;
4865
4866rgtL1L2:
4867
4868
4869        mov     rax, [rsi + 32]
4870        cmp     [half + 24], rax     ; comare with (q-1)/2
4871        jc rgtl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
4872
4873        jnz rgtl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
4874
4875
4876        mov     rax, [rsi + 24]
4877        cmp     [half + 16], rax     ; comare with (q-1)/2
4878        jc rgtl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
4879
4880        jnz rgtl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
4881
4882
4883        mov     rax, [rsi + 16]
4884        cmp     [half + 8], rax     ; comare with (q-1)/2
4885        jc rgtl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
4886
4887        jnz rgtl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
4888
4889
4890        mov     rax, [rsi + 8]
4891        cmp     [half + 0], rax     ; comare with (q-1)/2
4892        jc rgtl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
4893
4894        jmp rgtl1l2_p1
4895
4896
4897
4898rgtl1l2_p1:
4899
4900
4901        mov     rax, [rdx + 32]
4902        cmp     [half + 24], rax     ; comare with (q-1)/2
4903        jc rgt_ret1                           ; half<rax => e1-e2 is neg => e1 < e2
4904
4905        jnz rgtRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
4906
4907
4908        mov     rax, [rdx + 24]
4909        cmp     [half + 16], rax     ; comare with (q-1)/2
4910        jc rgt_ret1                           ; half<rax => e1-e2 is neg => e1 < e2
4911
4912        jnz rgtRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
4913
4914
4915        mov     rax, [rdx + 16]
4916        cmp     [half + 8], rax     ; comare with (q-1)/2
4917        jc rgt_ret1                           ; half<rax => e1-e2 is neg => e1 < e2
4918
4919        jnz rgtRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
4920
4921
4922        mov     rax, [rdx + 8]
4923        cmp     [half + 0], rax     ; comare with (q-1)/2
4924        jc rgt_ret1                           ; half<rax => e1-e2 is neg => e1 < e2
4925
4926        jmp rgtRawL1L2
4927
4928
4929
4930
4931rgtl1l2_n1:
4932
4933
4934        mov     rax, [rdx + 32]
4935        cmp     [half + 24], rax     ; comare with (q-1)/2
4936        jc rgtRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
4937
4938        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
4939
4940
4941        mov     rax, [rdx + 24]
4942        cmp     [half + 16], rax     ; comare with (q-1)/2
4943        jc rgtRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
4944
4945        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
4946
4947
4948        mov     rax, [rdx + 16]
4949        cmp     [half + 8], rax     ; comare with (q-1)/2
4950        jc rgtRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
4951
4952        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
4953
4954
4955        mov     rax, [rdx + 8]
4956        cmp     [half + 0], rax     ; comare with (q-1)/2
4957        jc rgtRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
4958
4959        jmp rgt_ret0
4960
4961
4962
4963
4964
4965rgtRawL1L2:
4966
4967        mov     rax, [rsi + 32]
4968        cmp     [rdx + 32], rax     ; comare with (q-1)/2
4969        jc rgt_ret1                      ; rsi<rdi => 1st > 2nd
4970
4971        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
4972
4973
4974        mov     rax, [rsi + 24]
4975        cmp     [rdx + 24], rax     ; comare with (q-1)/2
4976        jc rgt_ret1                      ; rsi<rdi => 1st > 2nd
4977
4978        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
4979
4980
4981        mov     rax, [rsi + 16]
4982        cmp     [rdx + 16], rax     ; comare with (q-1)/2
4983        jc rgt_ret1                      ; rsi<rdi => 1st > 2nd
4984
4985        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
4986
4987
4988        mov     rax, [rsi + 8]
4989        cmp     [rdx + 8], rax     ; comare with (q-1)/2
4990        jc rgt_ret1                      ; rsi<rdi => 1st > 2nd
4991
4992
4993
4994rgt_ret0:
4995        xor    rax, rax
4996        ret
4997rgt_ret1:
4998        mov    rax, 1
4999        ret
5000
5001
5002
5003;;;;;;;;;;;;;;;;;;;;;;
5004; req - Raw Eq
5005;;;;;;;;;;;;;;;;;;;;;;
5006; returns in ax 1 id *rsi == *rdx
5007; Params:
5008;   rsi <= Pointer to element 1
5009;   rdx <= Pointer to element 2
5010;   rax <= Return 1 or 0
5011; Modified Registers:
5012;    r8, r9, rax
5013;;;;;;;;;;;;;;;;;;;;;;
5014Fr_req:
5015        mov    r8, [rsi]
5016        mov    r9, [rdx]
5017        bt     r8, 63          ; Check if is short first operand
5018        jc     req_l1
5019        bt     r9, 63          ; Check if is short second operand
5020        jc     req_s1l2
5021
5022req_s1s2:                       ; Both operands are short
5023        cmp    r8d, r9d
5024        je     req_ret1
5025        jmp    req_ret0
5026
5027
5028req_l1:
5029        bt     r9, 63          ; Check if is short second operand
5030        jc     req_l1l2
5031
5032;;;;;;;;
5033req_l1s2:
5034        bt     r8, 62          ; check if montgomery first
5035        jc     req_l1ms2
5036req_l1ns2:
5037        push  rdi
5038        push   rsi
5039        mov   rdi, rdx
5040        movsx rsi, r9d
5041        call  rawCopyS2L
5042        mov   rdx, rdi
5043        pop   rsi
5044        pop   rdi
5045        jmp reqL1L2
5046
5047req_l1ms2:
5048        push rdi
5049        mov  rdi, rdx
5050        call Fr_toMontgomery
5051        mov  rdx, rdi
5052        pop  rdi
5053        jmp reqL1L2
5054
5055
5056;;;;;;;;
5057req_s1l2:
5058        bt     r9, 62          ; check if montgomery second
5059        jc     req_s1l2m
5060req_s1l2n:
5061        push  rdi
5062        push  rdx
5063        mov   rdi, rsi
5064        movsx rsi, r8d
5065        call  rawCopyS2L
5066        mov   rsi, rdi
5067        pop   rdx
5068        pop   rdi
5069        jmp reqL1L2
5070
5071req_s1l2m:
5072        push rdi
5073        mov  rdi, rsi
5074        mov  rsi, rdx
5075        call Fr_toMontgomery
5076        mov  rdx, rsi
5077        mov  rsi, rdi
5078        pop  rdi
5079        jmp reqL1L2
5080
5081;;;;
5082req_l1l2:
5083        bt     r8, 62          ; check if montgomery first
5084        jc     req_l1ml2
5085req_l1nl2:
5086        bt     r9, 62          ; check if montgomery second
5087        jc     req_l1nl2m
5088req_l1nl2n:
5089        jmp reqL1L2
5090
5091req_l1nl2m:
5092        push rdi
5093        mov  rdi, rsi
5094        mov  rsi, rdx
5095        call Fr_toMontgomery
5096        mov  rdx, rsi
5097        mov  rsi, rdi
5098        pop  rdi
5099        jmp reqL1L2
5100
5101req_l1ml2:
5102        bt     r9, 62          ; check if montgomery second
5103        jc     req_l1ml2m
5104req_l1ml2n:
5105        push rdi
5106        mov  rdi, rdx
5107        call Fr_toMontgomery
5108        mov  rdx, rdi
5109        pop  rdi
5110        jmp reqL1L2
5111
5112req_l1ml2m:
5113        jmp reqL1L2
5114
5115
5116;;;;;;
5117; eqL1L2
5118;;;;;;
5119
5120reqL1L2:
5121
5122        mov     rax, [rsi + 8]
5123        cmp     [rdx + 8], rax
5124        jne     req_ret0                      ; rsi<rdi => 1st > 2nd
5125
5126        mov     rax, [rsi + 16]
5127        cmp     [rdx + 16], rax
5128        jne     req_ret0                      ; rsi<rdi => 1st > 2nd
5129
5130        mov     rax, [rsi + 24]
5131        cmp     [rdx + 24], rax
5132        jne     req_ret0                      ; rsi<rdi => 1st > 2nd
5133
5134        mov     rax, [rsi + 32]
5135        cmp     [rdx + 32], rax
5136        jne     req_ret0                      ; rsi<rdi => 1st > 2nd
5137
5138
5139req_ret1:
5140        mov    rax, 1
5141        ret
5142
5143req_ret0:
5144        xor    rax, rax
5145        ret
5146
5147
5148;;;;;;;;;;;;;;;;;;;;;;
5149; gt
5150;;;;;;;;;;;;;;;;;;;;;;
5151; Compares two elements of any kind
5152; Params:
5153;   rsi <= Pointer to element 1
5154;   rdx <= Pointer to element 2
5155;   rdi <= Pointer to result can be zero or one.
5156; Modified Registers:
5157;    rax, rcx
5158;;;;;;;;;;;;;;;;;;;;;;
5159Fr_gt:
5160        call Fr_rgt
5161        mov [rdi], rax
5162        ret
5163
5164;;;;;;;;;;;;;;;;;;;;;;
5165; eq
5166;;;;;;;;;;;;;;;;;;;;;;
5167; Compares two elements of any kind
5168; Params:
5169;   rsi <= Pointer to element 1
5170;   rdx <= Pointer to element 2
5171;   rdi <= Pointer to result can be zero or one.
5172; Modified Registers:
5173;    rax, rcx
5174;;;;;;;;;;;;;;;;;;;;;;
5175Fr_eq:
5176        call Fr_req
5177        mov [rdi], rax
5178        ret
5179
5180Fr_geq:
5181Fr_leq:
5182Fr_lt:
5183Fr_neq:
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195;;;;;;;;;;;;;;;;;;;;;;
5196; land
5197;;;;;;;;;;;;;;;;;;;;;;
5198; Logical and between two elements
5199; Params:
5200;   rsi <= Pointer to element 1
5201;   rdx <= Pointer to element 2
5202;   rdi <= Pointer to result zero or one
5203; Modified Registers:
5204;    rax, rcx, r8
5205;;;;;;;;;;;;;;;;;;;;;;
5206Fr_land:
5207
5208
5209
5210
5211
5212
5213    mov     rax, [rsi]
5214    bt      rax, 63
5215    jc      tmp_28
5216
5217    test    eax, eax
5218    jz      retZero_30
5219    jmp     retOne_29
5220
5221tmp_28:
5222
5223    mov     rax, [rsi + 8]
5224    test    rax, rax
5225    jnz     retOne_29
5226
5227    mov     rax, [rsi + 16]
5228    test    rax, rax
5229    jnz     retOne_29
5230
5231    mov     rax, [rsi + 24]
5232    test    rax, rax
5233    jnz     retOne_29
5234
5235    mov     rax, [rsi + 32]
5236    test    rax, rax
5237    jnz     retOne_29
5238
5239
5240retZero_30:
5241    mov     qword r8, 0
5242    jmp     done_31
5243
5244retOne_29:
5245    mov     qword r8, 1
5246
5247done_31:
5248
5249
5250
5251
5252
5253
5254
5255    mov     rax, [rdx]
5256    bt      rax, 63
5257    jc      tmp_32
5258
5259    test    eax, eax
5260    jz      retZero_34
5261    jmp     retOne_33
5262
5263tmp_32:
5264
5265    mov     rax, [rdx + 8]
5266    test    rax, rax
5267    jnz     retOne_33
5268
5269    mov     rax, [rdx + 16]
5270    test    rax, rax
5271    jnz     retOne_33
5272
5273    mov     rax, [rdx + 24]
5274    test    rax, rax
5275    jnz     retOne_33
5276
5277    mov     rax, [rdx + 32]
5278    test    rax, rax
5279    jnz     retOne_33
5280
5281
5282retZero_34:
5283    mov     qword rcx, 0
5284    jmp     done_35
5285
5286retOne_33:
5287    mov     qword rcx, 1
5288
5289done_35:
5290
5291        and rcx, r8
5292        mov [rdi], rcx
5293        ret
5294
5295
5296;;;;;;;;;;;;;;;;;;;;;;
5297; lor
5298;;;;;;;;;;;;;;;;;;;;;;
5299; Logical or between two elements
5300; Params:
5301;   rsi <= Pointer to element 1
5302;   rdx <= Pointer to element 2
5303;   rdi <= Pointer to result zero or one
5304; Modified Registers:
5305;    rax, rcx, r8
5306;;;;;;;;;;;;;;;;;;;;;;
5307Fr_lor:
5308
5309
5310
5311
5312
5313
5314    mov     rax, [rsi]
5315    bt      rax, 63
5316    jc      tmp_36
5317
5318    test    eax, eax
5319    jz      retZero_38
5320    jmp     retOne_37
5321
5322tmp_36:
5323
5324    mov     rax, [rsi + 8]
5325    test    rax, rax
5326    jnz     retOne_37
5327
5328    mov     rax, [rsi + 16]
5329    test    rax, rax
5330    jnz     retOne_37
5331
5332    mov     rax, [rsi + 24]
5333    test    rax, rax
5334    jnz     retOne_37
5335
5336    mov     rax, [rsi + 32]
5337    test    rax, rax
5338    jnz     retOne_37
5339
5340
5341retZero_38:
5342    mov     qword r8, 0
5343    jmp     done_39
5344
5345retOne_37:
5346    mov     qword r8, 1
5347
5348done_39:
5349
5350
5351
5352
5353
5354
5355
5356    mov     rax, [rdx]
5357    bt      rax, 63
5358    jc      tmp_40
5359
5360    test    eax, eax
5361    jz      retZero_42
5362    jmp     retOne_41
5363
5364tmp_40:
5365
5366    mov     rax, [rdx + 8]
5367    test    rax, rax
5368    jnz     retOne_41
5369
5370    mov     rax, [rdx + 16]
5371    test    rax, rax
5372    jnz     retOne_41
5373
5374    mov     rax, [rdx + 24]
5375    test    rax, rax
5376    jnz     retOne_41
5377
5378    mov     rax, [rdx + 32]
5379    test    rax, rax
5380    jnz     retOne_41
5381
5382
5383retZero_42:
5384    mov     qword rcx, 0
5385    jmp     done_43
5386
5387retOne_41:
5388    mov     qword rcx, 1
5389
5390done_43:
5391
5392        or rcx, r8
5393        mov [rdi], rcx
5394        ret
5395
5396
5397;;;;;;;;;;;;;;;;;;;;;;
5398; lnot
5399;;;;;;;;;;;;;;;;;;;;;;
5400; Do the logical not of an element
5401; Params:
5402;   rsi <= Pointer to element to be tested
5403;   rdi <= Pointer to result one if element1 is zero and zero otherwise
5404; Modified Registers:
5405;    rax, rax, r8
5406;;;;;;;;;;;;;;;;;;;;;;
5407Fr_lnot:
5408
5409
5410
5411
5412
5413
5414    mov     rax, [rsi]
5415    bt      rax, 63
5416    jc      tmp_44
5417
5418    test    eax, eax
5419    jz      retZero_46
5420    jmp     retOne_45
5421
5422tmp_44:
5423
5424    mov     rax, [rsi + 8]
5425    test    rax, rax
5426    jnz     retOne_45
5427
5428    mov     rax, [rsi + 16]
5429    test    rax, rax
5430    jnz     retOne_45
5431
5432    mov     rax, [rsi + 24]
5433    test    rax, rax
5434    jnz     retOne_45
5435
5436    mov     rax, [rsi + 32]
5437    test    rax, rax
5438    jnz     retOne_45
5439
5440
5441retZero_46:
5442    mov     qword rcx, 0
5443    jmp     done_47
5444
5445retOne_45:
5446    mov     qword rcx, 1
5447
5448done_47:
5449
5450        test rcx, rcx
5451
5452        jz lnot_retOne
5453lnot_retZero:
5454        mov qword [rdi], 0
5455        ret
5456lnot_retOne:
5457        mov qword [rdi], 1
5458        ret
5459
5460
5461;;;;;;;;;;;;;;;;;;;;;;
5462; isTrue
5463;;;;;;;;;;;;;;;;;;;;;;
5464; Convert a 64 bit integer to a long format field element
5465; Params:
5466;   rsi <= Pointer to the element
5467; Returs:
5468;   rax <= 1 if true 0 if false
5469;;;;;;;;;;;;;;;;;;;;;;;
5470Fr_isTrue:
5471        
5472
5473
5474
5475
5476
5477    mov     rax, [rdi]
5478    bt      rax, 63
5479    jc      tmp_48
5480
5481    test    eax, eax
5482    jz      retZero_50
5483    jmp     retOne_49
5484
5485tmp_48:
5486
5487    mov     rax, [rdi + 8]
5488    test    rax, rax
5489    jnz     retOne_49
5490
5491    mov     rax, [rdi + 16]
5492    test    rax, rax
5493    jnz     retOne_49
5494
5495    mov     rax, [rdi + 24]
5496    test    rax, rax
5497    jnz     retOne_49
5498
5499    mov     rax, [rdi + 32]
5500    test    rax, rax
5501    jnz     retOne_49
5502
5503
5504retZero_50:
5505    mov     qword rax, 0
5506    jmp     done_51
5507
5508retOne_49:
5509    mov     qword rax, 1
5510
5511done_51:
5512
5513        ret
5514
5515
5516
5517
5518
5519        section .data
5520Fr_q:
5521        dd      0
5522        dd      0x80000000
5523q       dq      0x43e1f593f0000001,0x2833e84879b97091,0xb85045b68181585d,0x30644e72e131a029
5524half    dq      0xa1f0fac9f8000000,0x9419f4243cdcb848,0xdc2822db40c0ac2e,0x183227397098d014
5525R2      dq      0x1bb8e645ae216da7,0x53fe3ab1e35c59e3,0x8c49833d53bb8085,0x0216d0b17f4e44a5
5526R3      dq      0x5e94d8e1b4bf0040,0x2a489cbe1cfbb6b8,0x893cc664a19fcfed,0x0cf8594b7fcc657c
5527lboMask dq      0x1fffffffffffffff
5528