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    bt      rax, 62                     ; check if montgomery
1419    jc      toMontgomery_doNothing
1420    bt      rax, 63
1421    jc      toMontgomeryLong
1422
1423toMontgomeryShort:
1424    add     rdi, 8
1425    push    rsi
1426    push    rdx
1427    lea     rsi, [R2]
1428    movsx   rdx, eax
1429    cmp     rdx, 0
1430    js      negMontgomeryShort
1431posMontgomeryShort:
1432    call    rawMontgomeryMul1
1433    pop     rdx
1434    pop     rsi
1435    sub     rdi, 8
1436            mov r11b, 0x40
1437        shl r11d, 24
1438        mov [rdi+4], r11d
1439    ret
1440
1441negMontgomeryShort:
1442    neg     rdx              ; Do the multiplication positive and then negate the result.
1443    call    rawMontgomeryMul1
1444    mov     rsi, rdi
1445    call    rawNegL
1446    pop     rdx
1447    pop     rsi
1448    sub     rdi, 8
1449            mov r11b, 0x40
1450        shl r11d, 24
1451        mov [rdi+4], r11d
1452    ret
1453
1454
1455toMontgomeryLong:
1456    mov     [rdi], rax
1457    add     rdi, 8
1458    push    rsi
1459    mov     rdx, rdi
1460    lea     rsi, [R2]
1461    call    rawMontgomeryMul
1462    pop     rsi
1463    sub     rdi, 8
1464            mov r11b, 0xC0
1465        shl r11d, 24
1466        mov [rdi+4], r11d
1467
1468
1469toMontgomery_doNothing:
1470    ret
1471
1472;;;;;;;;;;;;;;;;;;;;;;
1473; toNormal
1474;;;;;;;;;;;;;;;;;;;;;;
1475; Convert a number from Montgomery
1476;   rdi <= Pointer element to convert
1477; Modified registers:
1478;    r8, r9, 10, r11, rax, rcx
1479;;;;;;;;;;;;;;;;;;;;
1480Fr_toNormal:
1481    mov     rax, [rdi]
1482    bt      rax, 62                     ; check if montgomery
1483    jnc     toNormal_doNothing
1484    bt      rax, 63                     ; if short, it means it's converted
1485    jnc     toNormal_doNothing
1486
1487toNormalLong:
1488    add     rdi, 8
1489    call    rawFromMontgomery
1490    sub     rdi, 8
1491            mov r11b, 0x80
1492        shl r11d, 24
1493        mov [rdi+4], r11d
1494
1495toNormal_doNothing:
1496    ret
1497
1498;;;;;;;;;;;;;;;;;;;;;;
1499; toLongNormal
1500;;;;;;;;;;;;;;;;;;;;;;
1501; Convert a number to long normal
1502;   rdi <= Pointer element to convert
1503; Modified registers:
1504;    r8, r9, 10, r11, rax, rcx
1505;;;;;;;;;;;;;;;;;;;;
1506Fr_toLongNormal:
1507    mov     rax, [rdi]
1508    bt      rax, 62                     ; check if montgomery
1509    jc      toLongNormal_fromMontgomery
1510    bt      rax, 63                     ; check if long
1511    jnc     toLongNormal_fromShort
1512    ret                                 ; It is already long
1513
1514toLongNormal_fromMontgomery:
1515    add     rdi, 8
1516    call    rawFromMontgomery
1517    sub     rdi, 8
1518            mov r11b, 0x80
1519        shl r11d, 24
1520        mov [rdi+4], r11d
1521    ret
1522
1523toLongNormal_fromShort:
1524    mov     r8, rsi                     ; save rsi
1525    movsx   rsi, eax
1526    call    rawCopyS2L
1527    mov     rsi, r8                     ; recover rsi
1528            mov r11b, 0x80
1529        shl r11d, 24
1530        mov [rdi+4], r11d
1531    ret
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544;;;;;;;;;;;;;;;;;;;;;;
1545; add
1546;;;;;;;;;;;;;;;;;;;;;;
1547; Adds two elements of any kind
1548; Params:
1549;   rsi <= Pointer to element 1
1550;   rdx <= Pointer to element 2
1551;   rdi <= Pointer to result
1552; Modified Registers:
1553;    r8, r9, 10, r11, rax, rcx
1554;;;;;;;;;;;;;;;;;;;;;;
1555Fr_add:
1556        mov    rax, [rsi]
1557        mov    rcx, [rdx]
1558        bt     rax, 63          ; Check if is short first operand
1559        jc     add_l1
1560        bt     rcx, 63          ; Check if is short second operand
1561        jc     add_s1l2
1562
1563add_s1s2:                       ; Both operands are short
1564
1565        xor    rdx, rdx
1566        mov    edx, eax
1567        add    edx, ecx
1568        jo     add_manageOverflow   ; rsi already is the 64bits result
1569
1570        mov    [rdi], rdx       ; not necessary to adjust so just save and return
1571        ret
1572
1573add_manageOverflow:                 ; Do the operation in 64 bits
1574        push   rsi
1575        movsx  rsi, eax
1576        movsx  rdx, ecx
1577        add    rsi, rdx
1578        call   rawCopyS2L
1579        pop    rsi
1580        ret
1581
1582add_l1:
1583        bt     rcx, 63          ; Check if is short second operand
1584        jc     add_l1l2
1585
1586;;;;;;;;
1587add_l1s2:
1588        bt     rax, 62          ; check if montgomery first
1589        jc     add_l1ms2
1590add_l1ns2:
1591        mov r11b, 0x80
1592        shl r11d, 24
1593        mov [rdi+4], r11d
1594
1595        add rsi, 8
1596        movsx rdx, ecx
1597        add rdi, 8
1598        cmp rdx, 0
1599        
1600        jns tmp_1
1601        neg rdx
1602        call rawSubLS
1603        sub rdi, 8
1604        sub rsi, 8
1605        ret
1606tmp_1:
1607        call rawAddLS
1608        sub rdi, 8
1609        sub rsi, 8
1610        ret
1611
1612
1613
1614add_l1ms2:
1615        bt     rcx, 62          ; check if montgomery second
1616        jc     add_l1ms2m
1617add_l1ms2n:
1618        mov r11b, 0xC0
1619        shl r11d, 24
1620        mov [rdi+4], r11d
1621        push rdi
1622        mov  rdi, rdx
1623        call Fr_toMontgomery
1624        mov  rdx, rdi
1625        pop  rdi
1626
1627        add rdi, 8
1628        add rsi, 8
1629        add rdx, 8
1630        call rawAddLL
1631        sub rdi, 8
1632        sub rsi, 8
1633        ret
1634
1635
1636add_l1ms2m:
1637        mov r11b, 0xC0
1638        shl r11d, 24
1639        mov [rdi+4], r11d
1640
1641        add rdi, 8
1642        add rsi, 8
1643        add rdx, 8
1644        call rawAddLL
1645        sub rdi, 8
1646        sub rsi, 8
1647        ret
1648
1649
1650
1651;;;;;;;;
1652add_s1l2:
1653        bt     rcx, 62          ; check if montgomery second
1654        jc     add_s1l2m
1655add_s1l2n:
1656        mov r11b, 0x80
1657        shl r11d, 24
1658        mov [rdi+4], r11d
1659
1660        lea rsi, [rdx + 8]
1661        movsx rdx, eax
1662        add rdi, 8
1663        cmp rdx, 0
1664        
1665        jns tmp_2
1666        neg rdx
1667        call rawSubLS
1668        sub rdi, 8
1669        sub rsi, 8
1670        ret
1671tmp_2:
1672        call rawAddLS
1673        sub rdi, 8
1674        sub rsi, 8
1675        ret
1676
1677
1678add_s1l2m:
1679        bt     rax, 62          ; check if montgomery first
1680        jc     add_s1ml2m
1681add_s1nl2m:
1682        mov r11b, 0xC0
1683        shl r11d, 24
1684        mov [rdi+4], r11d
1685        push rdi
1686        mov  rdi, rsi
1687        mov  rsi, rdx
1688        call Fr_toMontgomery
1689        mov  rdx, rsi
1690        mov  rsi, rdi
1691        pop  rdi
1692
1693        add rdi, 8
1694        add rsi, 8
1695        add rdx, 8
1696        call rawAddLL
1697        sub rdi, 8
1698        sub rsi, 8
1699        ret
1700
1701
1702add_s1ml2m:
1703        mov r11b, 0xC0
1704        shl r11d, 24
1705        mov [rdi+4], r11d
1706
1707        add rdi, 8
1708        add rsi, 8
1709        add rdx, 8
1710        call rawAddLL
1711        sub rdi, 8
1712        sub rsi, 8
1713        ret
1714
1715
1716;;;;
1717add_l1l2:
1718        bt     rax, 62          ; check if montgomery first
1719        jc     add_l1ml2
1720add_l1nl2:
1721        bt     rcx, 62          ; check if montgomery second
1722        jc     add_l1nl2m
1723add_l1nl2n:
1724        mov r11b, 0x80
1725        shl r11d, 24
1726        mov [rdi+4], r11d
1727
1728        add rdi, 8
1729        add rsi, 8
1730        add rdx, 8
1731        call rawAddLL
1732        sub rdi, 8
1733        sub rsi, 8
1734        ret
1735
1736
1737add_l1nl2m:
1738        mov r11b, 0xC0
1739        shl r11d, 24
1740        mov [rdi+4], r11d
1741        push rdi
1742        mov  rdi, rsi
1743        mov  rsi, rdx
1744        call Fr_toMontgomery
1745        mov  rdx, rsi
1746        mov  rsi, rdi
1747        pop  rdi
1748
1749        add rdi, 8
1750        add rsi, 8
1751        add rdx, 8
1752        call rawAddLL
1753        sub rdi, 8
1754        sub rsi, 8
1755        ret
1756
1757
1758add_l1ml2:
1759        bt     rcx, 62          ; check if montgomery seconf
1760        jc     add_l1ml2m
1761add_l1ml2n:
1762        mov r11b, 0xC0
1763        shl r11d, 24
1764        mov [rdi+4], r11d
1765        push rdi
1766        mov  rdi, rdx
1767        call Fr_toMontgomery
1768        mov  rdx, rdi
1769        pop  rdi
1770
1771        add rdi, 8
1772        add rsi, 8
1773        add rdx, 8
1774        call rawAddLL
1775        sub rdi, 8
1776        sub rsi, 8
1777        ret
1778
1779
1780add_l1ml2m:
1781        mov r11b, 0xC0
1782        shl r11d, 24
1783        mov [rdi+4], r11d
1784
1785        add rdi, 8
1786        add rsi, 8
1787        add rdx, 8
1788        call rawAddLL
1789        sub rdi, 8
1790        sub rsi, 8
1791        ret
1792
1793
1794
1795
1796;;;;;;;;;;;;;;;;;;;;;;
1797; rawAddLL
1798;;;;;;;;;;;;;;;;;;;;;;
1799; Adds two elements of type long
1800; Params:
1801;   rsi <= Pointer to the long data of element 1
1802;   rdx <= Pointer to the long data of element 2
1803;   rdi <= Pointer to the long data of result
1804; Modified Registers:
1805;    rax
1806;;;;;;;;;;;;;;;;;;;;;;
1807rawAddLL:
1808        ; Add component by component with carry
1809
1810        mov rax, [rsi + 0]
1811        add rax, [rdx + 0]
1812        mov [rdi + 0], rax
1813
1814        mov rax, [rsi + 8]
1815        adc rax, [rdx + 8]
1816        mov [rdi + 8], rax
1817
1818        mov rax, [rsi + 16]
1819        adc rax, [rdx + 16]
1820        mov [rdi + 16], rax
1821
1822        mov rax, [rsi + 24]
1823        adc rax, [rdx + 24]
1824        mov [rdi + 24], rax
1825
1826        jc rawAddLL_sq   ; if overflow, substract q
1827
1828        ; Compare with q
1829
1830
1831        cmp rax, [q + 24]
1832        jc rawAddLL_done        ; q is bigget so done.
1833        jnz rawAddLL_sq         ; q is lower
1834
1835
1836        mov rax, [rdi + 16]
1837
1838        cmp rax, [q + 16]
1839        jc rawAddLL_done        ; q is bigget so done.
1840        jnz rawAddLL_sq         ; q is lower
1841
1842
1843        mov rax, [rdi + 8]
1844
1845        cmp rax, [q + 8]
1846        jc rawAddLL_done        ; q is bigget so done.
1847        jnz rawAddLL_sq         ; q is lower
1848
1849
1850        mov rax, [rdi + 0]
1851
1852        cmp rax, [q + 0]
1853        jc rawAddLL_done        ; q is bigget so done.
1854        jnz rawAddLL_sq         ; q is lower
1855
1856        ; If equal substract q
1857rawAddLL_sq:
1858
1859        mov rax, [q + 0]
1860        sub [rdi + 0], rax
1861
1862        mov rax, [q + 8]
1863        sbb [rdi + 8], rax
1864
1865        mov rax, [q + 16]
1866        sbb [rdi + 16], rax
1867
1868        mov rax, [q + 24]
1869        sbb [rdi + 24], rax
1870
1871rawAddLL_done:
1872        ret
1873
1874
1875;;;;;;;;;;;;;;;;;;;;;;
1876; rawAddLS
1877;;;;;;;;;;;;;;;;;;;;;;
1878; Adds two elements of type long
1879; Params:
1880;   rdi <= Pointer to the long data of result
1881;   rsi <= Pointer to the long data of element 1
1882;   rdx <= Value to be added
1883;;;;;;;;;;;;;;;;;;;;;;
1884rawAddLS:
1885        ; Add component by component with carry
1886
1887        add rdx, [rsi]
1888        mov [rdi] ,rdx
1889
1890        mov rdx, 0
1891        adc rdx, [rsi + 8]
1892        mov [rdi + 8], rdx
1893
1894        mov rdx, 0
1895        adc rdx, [rsi + 16]
1896        mov [rdi + 16], rdx
1897
1898        mov rdx, 0
1899        adc rdx, [rsi + 24]
1900        mov [rdi + 24], rdx
1901
1902        jc rawAddLS_sq   ; if overflow, substract q
1903
1904        ; Compare with q
1905
1906        mov rax, [rdi + 24]
1907        cmp rax, [q + 24]
1908        jc rawAddLS_done        ; q is bigget so done.
1909        jnz rawAddLS_sq         ; q is lower
1910
1911        mov rax, [rdi + 16]
1912        cmp rax, [q + 16]
1913        jc rawAddLS_done        ; q is bigget so done.
1914        jnz rawAddLS_sq         ; q is lower
1915
1916        mov rax, [rdi + 8]
1917        cmp rax, [q + 8]
1918        jc rawAddLS_done        ; q is bigget so done.
1919        jnz rawAddLS_sq         ; q is lower
1920
1921        mov rax, [rdi + 0]
1922        cmp rax, [q + 0]
1923        jc rawAddLS_done        ; q is bigget so done.
1924        jnz rawAddLS_sq         ; q is lower
1925
1926        ; If equal substract q
1927rawAddLS_sq:
1928
1929        mov rax, [q + 0]
1930        sub [rdi + 0], rax
1931
1932        mov rax, [q + 8]
1933        sbb [rdi + 8], rax
1934
1935        mov rax, [q + 16]
1936        sbb [rdi + 16], rax
1937
1938        mov rax, [q + 24]
1939        sbb [rdi + 24], rax
1940
1941rawAddLS_done:
1942        ret
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958;;;;;;;;;;;;;;;;;;;;;;
1959; sub
1960;;;;;;;;;;;;;;;;;;;;;;
1961; Substracts two elements of any kind
1962; Params:
1963;   rsi <= Pointer to element 1
1964;   rdx <= Pointer to element 2
1965;   rdi <= Pointer to result
1966; Modified Registers:
1967;    r8, r9, 10, r11, rax, rcx
1968;;;;;;;;;;;;;;;;;;;;;;
1969Fr_sub:
1970        mov    rax, [rsi]
1971        mov    rcx, [rdx]
1972        bt     rax, 63          ; Check if is long first operand
1973        jc     sub_l1
1974        bt     rcx, 63          ; Check if is long second operand
1975        jc     sub_s1l2
1976
1977sub_s1s2:                       ; Both operands are short
1978
1979        xor    rdx, rdx
1980        mov    edx, eax
1981        sub    edx, ecx
1982        jo     sub_manageOverflow   ; rsi already is the 64bits result
1983
1984        mov    [rdi], rdx       ; not necessary to adjust so just save and return
1985        ret
1986
1987sub_manageOverflow:                 ; Do the operation in 64 bits
1988        push   rsi
1989        movsx  rsi, eax
1990        movsx  rdx, ecx
1991        sub    rsi, rdx
1992        call   rawCopyS2L
1993        pop    rsi
1994        ret
1995
1996sub_l1:
1997        bt     rcx, 63          ; Check if is short second operand
1998        jc     sub_l1l2
1999
2000;;;;;;;;
2001sub_l1s2:
2002        bt     rax, 62          ; check if montgomery first
2003        jc     sub_l1ms2
2004sub_l1ns2:
2005        mov r11b, 0x80
2006        shl r11d, 24
2007        mov [rdi+4], r11d
2008
2009        add rsi, 8
2010        movsx rdx, ecx
2011        add rdi, 8
2012        cmp rdx, 0
2013        
2014        jns tmp_3
2015        neg rdx
2016        call rawAddLS
2017        sub rdi, 8
2018        sub rsi, 8
2019        ret
2020tmp_3:
2021        call rawSubLS
2022        sub rdi, 8
2023        sub rsi, 8
2024        ret
2025
2026
2027sub_l1ms2:
2028        bt     rcx, 62          ; check if montgomery second
2029        jc     sub_l1ms2m
2030sub_l1ms2n:
2031        mov r11b, 0xC0
2032        shl r11d, 24
2033        mov [rdi+4], r11d
2034        push rdi
2035        mov  rdi, rdx
2036        call Fr_toMontgomery
2037        mov  rdx, rdi
2038        pop  rdi
2039
2040        add rdi, 8
2041        add rsi, 8
2042        add rdx, 8
2043        call rawSubLL
2044        sub rdi, 8
2045        sub rsi, 8
2046        ret
2047
2048
2049sub_l1ms2m:
2050        mov r11b, 0xC0
2051        shl r11d, 24
2052        mov [rdi+4], r11d
2053
2054        add rdi, 8
2055        add rsi, 8
2056        add rdx, 8
2057        call rawSubLL
2058        sub rdi, 8
2059        sub rsi, 8
2060        ret
2061
2062
2063
2064;;;;;;;;
2065sub_s1l2:
2066        bt     rcx, 62          ; check if montgomery first
2067        jc     sub_s1l2m
2068sub_s1l2n:
2069        mov r11b, 0x80
2070        shl r11d, 24
2071        mov [rdi+4], r11d
2072
2073        cmp eax, 0
2074        
2075        js tmp_4
2076
2077        ; First Operand is positive
2078        push rsi
2079        add rdi, 8
2080        movsx rsi, eax
2081        add rdx, 8
2082        call rawSubSL
2083        sub rdi, 8
2084        pop rsi
2085        ret
2086
2087tmp_4:   ; First operand is negative
2088        push rsi
2089        lea rsi, [rdx + 8]
2090        movsx rdx, eax
2091        add rdi, 8
2092        neg rdx
2093        call rawNegLS
2094        sub rdi, 8
2095        pop rsi
2096        ret
2097
2098
2099sub_s1l2m:
2100        bt     rax, 62          ; check if montgomery second
2101        jc     sub_s1ml2m
2102sub_s1nl2m:
2103        mov r11b, 0xC0
2104        shl r11d, 24
2105        mov [rdi+4], r11d
2106        push rdi
2107        mov  rdi, rsi
2108        mov  rsi, rdx
2109        call Fr_toMontgomery
2110        mov  rdx, rsi
2111        mov  rsi, rdi
2112        pop  rdi
2113
2114        add rdi, 8
2115        add rsi, 8
2116        add rdx, 8
2117        call rawSubLL
2118        sub rdi, 8
2119        sub rsi, 8
2120        ret
2121
2122
2123sub_s1ml2m:
2124        mov r11b, 0xC0
2125        shl r11d, 24
2126        mov [rdi+4], r11d
2127
2128        add rdi, 8
2129        add rsi, 8
2130        add rdx, 8
2131        call rawSubLL
2132        sub rdi, 8
2133        sub rsi, 8
2134        ret
2135
2136
2137;;;;
2138sub_l1l2:
2139        bt     rax, 62          ; check if montgomery first
2140        jc     sub_l1ml2
2141sub_l1nl2:
2142        bt     rcx, 62          ; check if montgomery second
2143        jc     sub_l1nl2m
2144sub_l1nl2n:
2145        mov r11b, 0x80
2146        shl r11d, 24
2147        mov [rdi+4], r11d
2148
2149        add rdi, 8
2150        add rsi, 8
2151        add rdx, 8
2152        call rawSubLL
2153        sub rdi, 8
2154        sub rsi, 8
2155        ret
2156
2157
2158sub_l1nl2m:
2159        mov r11b, 0xC0
2160        shl r11d, 24
2161        mov [rdi+4], r11d
2162        push rdi
2163        mov  rdi, rsi
2164        mov  rsi, rdx
2165        call Fr_toMontgomery
2166        mov  rdx, rsi
2167        mov  rsi, rdi
2168        pop  rdi
2169
2170        add rdi, 8
2171        add rsi, 8
2172        add rdx, 8
2173        call rawSubLL
2174        sub rdi, 8
2175        sub rsi, 8
2176        ret
2177
2178
2179sub_l1ml2:
2180        bt     rcx, 62          ; check if montgomery seconf
2181        jc     sub_l1ml2m
2182sub_l1ml2n:
2183        mov r11b, 0xC0
2184        shl r11d, 24
2185        mov [rdi+4], r11d
2186        push rdi
2187        mov  rdi, rdx
2188        call Fr_toMontgomery
2189        mov  rdx, rdi
2190        pop  rdi
2191
2192        add rdi, 8
2193        add rsi, 8
2194        add rdx, 8
2195        call rawSubLL
2196        sub rdi, 8
2197        sub rsi, 8
2198        ret
2199
2200
2201sub_l1ml2m:
2202        mov r11b, 0xC0
2203        shl r11d, 24
2204        mov [rdi+4], r11d
2205
2206        add rdi, 8
2207        add rsi, 8
2208        add rdx, 8
2209        call rawSubLL
2210        sub rdi, 8
2211        sub rsi, 8
2212        ret
2213
2214
2215
2216;;;;;;;;;;;;;;;;;;;;;;
2217; rawSubLS
2218;;;;;;;;;;;;;;;;;;;;;;
2219; Substracts a short element from the long element
2220; Params:
2221;   rdi <= Pointer to the long data of result
2222;   rsi <= Pointer to the long data of element 1 where will be substracted
2223;   rdx <= Value to be substracted
2224;   [rdi] = [rsi] - rdx
2225; Modified Registers:
2226;    rax
2227;;;;;;;;;;;;;;;;;;;;;;
2228rawSubLS:
2229        ; Substract first digit
2230
2231        mov rax, [rsi]
2232        sub rax, rdx
2233        mov [rdi] ,rax
2234        mov rdx, 0
2235
2236        mov rax, [rsi + 8]
2237        sbb rax, rdx
2238        mov [rdi + 8], rax
2239
2240        mov rax, [rsi + 16]
2241        sbb rax, rdx
2242        mov [rdi + 16], rax
2243
2244        mov rax, [rsi + 24]
2245        sbb rax, rdx
2246        mov [rdi + 24], rax
2247
2248        jnc rawSubLS_done   ; if overflow, add q
2249
2250        ; Add q
2251rawSubLS_aq:
2252
2253        mov rax, [q + 0]
2254        add [rdi + 0], rax
2255
2256        mov rax, [q + 8]
2257        adc [rdi + 8], rax
2258
2259        mov rax, [q + 16]
2260        adc [rdi + 16], rax
2261
2262        mov rax, [q + 24]
2263        adc [rdi + 24], rax
2264
2265rawSubLS_done:
2266        ret
2267
2268
2269;;;;;;;;;;;;;;;;;;;;;;
2270; rawSubSL
2271;;;;;;;;;;;;;;;;;;;;;;
2272; Substracts a long element from a short element
2273; Params:
2274;   rdi <= Pointer to the long data of result
2275;   rsi <= Value from where will bo substracted
2276;   rdx <= Pointer to long of the value to be substracted
2277;
2278;   [rdi] = rsi - [rdx]
2279; Modified Registers:
2280;    rax
2281;;;;;;;;;;;;;;;;;;;;;;
2282rawSubSL:
2283        ; Substract first digit
2284        sub rsi, [rdx]
2285        mov [rdi] ,rsi
2286
2287
2288        mov rax, 0
2289        sbb rax, [rdx + 8]
2290        mov [rdi + 8], rax
2291
2292        mov rax, 0
2293        sbb rax, [rdx + 16]
2294        mov [rdi + 16], rax
2295
2296        mov rax, 0
2297        sbb rax, [rdx + 24]
2298        mov [rdi + 24], rax
2299
2300        jnc rawSubSL_done   ; if overflow, add q
2301
2302        ; Add q
2303rawSubSL_aq:
2304
2305        mov rax, [q + 0]
2306        add [rdi + 0], rax
2307
2308        mov rax, [q + 8]
2309        adc [rdi + 8], rax
2310
2311        mov rax, [q + 16]
2312        adc [rdi + 16], rax
2313
2314        mov rax, [q + 24]
2315        adc [rdi + 24], rax
2316
2317rawSubSL_done:
2318        ret
2319
2320;;;;;;;;;;;;;;;;;;;;;;
2321; rawSubLL
2322;;;;;;;;;;;;;;;;;;;;;;
2323; Substracts a long element from a short element
2324; Params:
2325;   rdi <= Pointer to the long data of result
2326;   rsi <= Pointer to long from where substracted
2327;   rdx <= Pointer to long of the value to be substracted
2328;
2329;   [rdi] = [rsi] - [rdx]
2330; Modified Registers:
2331;    rax
2332;;;;;;;;;;;;;;;;;;;;;;
2333rawSubLL:
2334        ; Substract first digit
2335
2336        mov rax, [rsi + 0]
2337        sub rax, [rdx + 0]
2338        mov [rdi + 0], rax
2339
2340        mov rax, [rsi + 8]
2341        sbb rax, [rdx + 8]
2342        mov [rdi + 8], rax
2343
2344        mov rax, [rsi + 16]
2345        sbb rax, [rdx + 16]
2346        mov [rdi + 16], rax
2347
2348        mov rax, [rsi + 24]
2349        sbb rax, [rdx + 24]
2350        mov [rdi + 24], rax
2351
2352        jnc rawSubLL_done   ; if overflow, add q
2353
2354        ; Add q
2355rawSubLL_aq:
2356
2357        mov rax, [q + 0]
2358        add [rdi + 0], rax
2359
2360        mov rax, [q + 8]
2361        adc [rdi + 8], rax
2362
2363        mov rax, [q + 16]
2364        adc [rdi + 16], rax
2365
2366        mov rax, [q + 24]
2367        adc [rdi + 24], rax
2368
2369rawSubLL_done:
2370        ret
2371
2372;;;;;;;;;;;;;;;;;;;;;;
2373; rawNegLS
2374;;;;;;;;;;;;;;;;;;;;;;
2375; Substracts a long element and a short element form 0
2376; Params:
2377;   rdi <= Pointer to the long data of result
2378;   rsi <= Pointer to long from where substracted
2379;   rdx <= short value to be substracted too
2380;
2381;   [rdi] = -[rsi] - rdx
2382; Modified Registers:
2383;    rax
2384;;;;;;;;;;;;;;;;;;;;;;
2385rawNegLS:
2386        mov rax, [q]
2387        sub rax, rdx
2388        mov [rdi], rax
2389
2390        mov rax, [q + 8 ]
2391        sbb rax, 0
2392        mov [rdi + 8], rax
2393
2394        mov rax, [q + 16 ]
2395        sbb rax, 0
2396        mov [rdi + 16], rax
2397
2398        mov rax, [q + 24 ]
2399        sbb rax, 0
2400        mov [rdi + 24], rax
2401
2402        setc dl
2403
2404
2405        mov rax, [rdi + 0 ]
2406        sub rax, [rsi + 0]
2407        mov [rdi + 0], rax
2408
2409        mov rax, [rdi + 8 ]
2410        sbb rax, [rsi + 8]
2411        mov [rdi + 8], rax
2412
2413        mov rax, [rdi + 16 ]
2414        sbb rax, [rsi + 16]
2415        mov [rdi + 16], rax
2416
2417        mov rax, [rdi + 24 ]
2418        sbb rax, [rsi + 24]
2419        mov [rdi + 24], rax
2420
2421
2422        setc dh
2423        or dl, dh
2424        jz rawNegSL_done
2425
2426        ; it is a negative value, so add q
2427
2428        mov rax, [q + 0]
2429        add [rdi + 0], rax
2430
2431        mov rax, [q + 8]
2432        adc [rdi + 8], rax
2433
2434        mov rax, [q + 16]
2435        adc [rdi + 16], rax
2436
2437        mov rax, [q + 24]
2438        adc [rdi + 24], rax
2439
2440
2441rawNegSL_done:
2442        ret
2443
2444
2445
2446
2447
2448
2449
2450;;;;;;;;;;;;;;;;;;;;;;
2451; neg
2452;;;;;;;;;;;;;;;;;;;;;;
2453; Adds two elements of any kind
2454; Params:
2455;   rsi <= Pointer to element to be negated
2456;   rdi <= Pointer to result
2457;   [rdi] = -[rsi]
2458;;;;;;;;;;;;;;;;;;;;;;
2459Fr_neg:
2460        mov    rax, [rsi]
2461        bt     rax, 63          ; Check if is short first operand
2462        jc     neg_l
2463
2464neg_s:                          ; Operand is short
2465
2466        neg    eax
2467        jo     neg_manageOverflow   ; Check if overflow. (0x80000000 is the only case)
2468
2469        mov    [rdi], rax           ; not necessary to adjust so just save and return
2470        ret
2471
2472neg_manageOverflow:                 ; Do the operation in 64 bits
2473        push   rsi
2474        movsx  rsi, eax
2475        neg    rsi
2476        call   rawCopyS2L
2477        pop    rsi
2478        ret
2479
2480
2481
2482neg_l:
2483        mov [rdi], rax          ; Copy the type
2484
2485        add rdi, 8
2486        add rsi, 8
2487        call rawNegL
2488        sub rdi, 8
2489        sub rsi, 8
2490        ret
2491
2492
2493
2494;;;;;;;;;;;;;;;;;;;;;;
2495; rawNeg
2496;;;;;;;;;;;;;;;;;;;;;;
2497; Negates a value
2498; Params:
2499;   rdi <= Pointer to the long data of result
2500;   rsi <= Pointer to the long data of element 1
2501;
2502;   [rdi] = - [rsi]
2503;;;;;;;;;;;;;;;;;;;;;;
2504rawNegL:
2505        ; Compare is zero
2506
2507        xor rax, rax
2508
2509        cmp [rsi + 0], rax
2510        jnz doNegate
2511
2512        cmp [rsi + 8], rax
2513        jnz doNegate
2514
2515        cmp [rsi + 16], rax
2516        jnz doNegate
2517
2518        cmp [rsi + 24], rax
2519        jnz doNegate
2520
2521        ; it's zero so just set to zero
2522
2523        mov [rdi + 0], rax
2524
2525        mov [rdi + 8], rax
2526
2527        mov [rdi + 16], rax
2528
2529        mov [rdi + 24], rax
2530
2531        ret
2532doNegate:
2533
2534        mov rax, [q + 0]
2535        sub rax, [rsi + 0]
2536        mov [rdi + 0], rax
2537
2538        mov rax, [q + 8]
2539        sbb rax, [rsi + 8]
2540        mov [rdi + 8], rax
2541
2542        mov rax, [q + 16]
2543        sbb rax, [rsi + 16]
2544        mov [rdi + 16], rax
2545
2546        mov rax, [q + 24]
2547        sbb rax, [rsi + 24]
2548        mov [rdi + 24], rax
2549
2550        ret
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570;;;;;;;;;;;;;;;;;;;;;;
2571; square
2572;;;;;;;;;;;;;;;;;;;;;;
2573; Squares a field element
2574; Params:
2575;   rsi <= Pointer to element 1
2576;   rdi <= Pointer to result
2577;   [rdi] = [rsi] * [rsi]
2578; Modified Registers:
2579;    r8, r9, 10, r11, rax, rcx
2580;;;;;;;;;;;;;;;;;;;;;;
2581Fr_square:
2582        mov    r8, [rsi]
2583        bt     r8, 63          ; Check if is short first operand
2584        jc     square_l1
2585
2586square_s1:                       ; Both operands are short
2587
2588        xor    rax, rax
2589        mov    eax, r8d
2590        imul   eax
2591        jo     square_manageOverflow   ; rsi already is the 64bits result
2592
2593        mov    [rdi], rax       ; not necessary to adjust so just save and return
2594
2595square_manageOverflow:                 ; Do the operation in 64 bits
2596        push   rsi
2597        movsx  rax, r8d
2598        imul   rax
2599        mov    rsi, rax
2600        call   rawCopyS2L
2601        pop    rsi
2602
2603        ret
2604
2605square_l1:
2606        bt     r8, 62          ; check if montgomery first
2607        jc     square_l1m
2608square_l1n:
2609        mov r11b, 0xC0
2610        shl r11d, 24
2611        mov [rdi+4], r11d
2612
2613        add rdi, 8
2614        add rsi, 8
2615        call rawMontgomerySquare
2616        sub rdi, 8
2617        sub rsi, 8
2618
2619
2620        push rsi
2621        add rdi, 8
2622        mov rsi, rdi
2623        lea rdx, [R3]
2624        call rawMontgomeryMul
2625        sub rdi, 8
2626        pop rsi
2627
2628        ret
2629
2630square_l1m:
2631        mov r11b, 0xC0
2632        shl r11d, 24
2633        mov [rdi+4], r11d
2634
2635        add rdi, 8
2636        add rsi, 8
2637        call rawMontgomerySquare
2638        sub rdi, 8
2639        sub rsi, 8
2640
2641        ret
2642
2643
2644
2645;;;;;;;;;;;;;;;;;;;;;;
2646; mul
2647;;;;;;;;;;;;;;;;;;;;;;
2648; Multiplies two elements of any kind
2649; Params:
2650;   rsi <= Pointer to element 1
2651;   rdx <= Pointer to element 2
2652;   rdi <= Pointer to result
2653;   [rdi] = [rsi] * [rdi]
2654; Modified Registers:
2655;    r8, r9, 10, r11, rax, rcx
2656;;;;;;;;;;;;;;;;;;;;;;
2657Fr_mul:
2658        mov    r8, [rsi]
2659        mov    r9, [rdx]
2660        bt     r8, 63          ; Check if is short first operand
2661        jc     mul_l1
2662        bt     r9, 63          ; Check if is short second operand
2663        jc     mul_s1l2
2664
2665mul_s1s2:                       ; Both operands are short
2666
2667        xor    rax, rax
2668        mov    eax, r8d
2669        imul   r9d
2670        jo     mul_manageOverflow   ; rsi already is the 64bits result
2671
2672        mov    [rdi], rax       ; not necessary to adjust so just save and return
2673
2674mul_manageOverflow:                 ; Do the operation in 64 bits
2675        push   rsi
2676        movsx  rax, r8d
2677        movsx  rcx, r9d
2678        imul   rcx
2679        mov    rsi, rax
2680        call   rawCopyS2L
2681        pop    rsi
2682
2683        ret
2684
2685mul_l1:
2686        bt     r9, 63          ; Check if is short second operand
2687        jc     mul_l1l2
2688
2689;;;;;;;;
2690mul_l1s2:
2691        bt     r8, 62          ; check if montgomery first
2692        jc     mul_l1ms2
2693mul_l1ns2:
2694        bt     r9, 62          ; check if montgomery first
2695        jc     mul_l1ns2m
2696mul_l1ns2n:
2697        mov r11b, 0xC0
2698        shl r11d, 24
2699        mov [rdi+4], r11d
2700
2701        push rsi
2702        add rsi, 8
2703        movsx rdx, r9d
2704        add rdi, 8
2705        cmp rdx, 0
2706        
2707        jns tmp_5
2708        neg rdx
2709        call rawMontgomeryMul1
2710        mov rsi, rdi
2711        call rawNegL
2712        sub rdi, 8
2713        pop rsi
2714        
2715        jmp tmp_6
2716tmp_5:
2717        call rawMontgomeryMul1
2718        sub rdi, 8
2719        pop rsi
2720tmp_6:
2721
2722
2723
2724        push rsi
2725        add rdi, 8
2726        mov rsi, rdi
2727        lea rdx, [R3]
2728        call rawMontgomeryMul
2729        sub rdi, 8
2730        pop rsi
2731
2732        ret
2733
2734
2735mul_l1ns2m:
2736        mov r11b, 0x80
2737        shl r11d, 24
2738        mov [rdi+4], r11d
2739
2740        add rdi, 8
2741        add rsi, 8
2742        add rdx, 8
2743        call rawMontgomeryMul
2744        sub rdi, 8
2745        sub rsi, 8
2746
2747        ret
2748
2749
2750mul_l1ms2:
2751        bt     r9, 62          ; check if montgomery second
2752        jc     mul_l1ms2m
2753mul_l1ms2n:
2754        mov r11b, 0x80
2755        shl r11d, 24
2756        mov [rdi+4], r11d
2757
2758        push rsi
2759        add rsi, 8
2760        movsx rdx, r9d
2761        add rdi, 8
2762        cmp rdx, 0
2763        
2764        jns tmp_7
2765        neg rdx
2766        call rawMontgomeryMul1
2767        mov rsi, rdi
2768        call rawNegL
2769        sub rdi, 8
2770        pop rsi
2771        
2772        jmp tmp_8
2773tmp_7:
2774        call rawMontgomeryMul1
2775        sub rdi, 8
2776        pop rsi
2777tmp_8:
2778
2779
2780        ret
2781
2782mul_l1ms2m:
2783        mov r11b, 0xC0
2784        shl r11d, 24
2785        mov [rdi+4], r11d
2786
2787        add rdi, 8
2788        add rsi, 8
2789        add rdx, 8
2790        call rawMontgomeryMul
2791        sub rdi, 8
2792        sub rsi, 8
2793
2794        ret
2795
2796
2797;;;;;;;;
2798mul_s1l2:
2799        bt     r8, 62          ; check if montgomery first
2800        jc     mul_s1ml2
2801mul_s1nl2:
2802        bt     r9, 62          ; check if montgomery first
2803        jc     mul_s1nl2m
2804mul_s1nl2n:
2805        mov r11b, 0xC0
2806        shl r11d, 24
2807        mov [rdi+4], r11d
2808
2809        push rsi
2810        lea rsi, [rdx + 8]
2811        movsx rdx, r8d
2812        add rdi, 8
2813        cmp rdx, 0
2814        
2815        jns tmp_9
2816        neg rdx
2817        call rawMontgomeryMul1
2818        mov rsi, rdi
2819        call rawNegL
2820        sub rdi, 8
2821        pop rsi
2822        
2823        jmp tmp_10
2824tmp_9:
2825        call rawMontgomeryMul1
2826        sub rdi, 8
2827        pop rsi
2828tmp_10:
2829
2830
2831
2832        push rsi
2833        add rdi, 8
2834        mov rsi, rdi
2835        lea rdx, [R3]
2836        call rawMontgomeryMul
2837        sub rdi, 8
2838        pop rsi
2839
2840        ret
2841
2842mul_s1nl2m:
2843        mov r11b, 0x80
2844        shl r11d, 24
2845        mov [rdi+4], r11d
2846
2847        push rsi
2848        lea rsi, [rdx + 8]
2849        movsx rdx, r8d
2850        add rdi, 8
2851        cmp rdx, 0
2852        
2853        jns tmp_11
2854        neg rdx
2855        call rawMontgomeryMul1
2856        mov rsi, rdi
2857        call rawNegL
2858        sub rdi, 8
2859        pop rsi
2860        
2861        jmp tmp_12
2862tmp_11:
2863        call rawMontgomeryMul1
2864        sub rdi, 8
2865        pop rsi
2866tmp_12:
2867
2868
2869        ret
2870
2871mul_s1ml2:
2872        bt     r9, 62          ; check if montgomery first
2873        jc     mul_s1ml2m
2874mul_s1ml2n:
2875        mov r11b, 0x80
2876        shl r11d, 24
2877        mov [rdi+4], r11d
2878
2879        add rdi, 8
2880        add rsi, 8
2881        add rdx, 8
2882        call rawMontgomeryMul
2883        sub rdi, 8
2884        sub rsi, 8
2885
2886        ret
2887
2888mul_s1ml2m:
2889        mov r11b, 0xC0
2890        shl r11d, 24
2891        mov [rdi+4], r11d
2892
2893        add rdi, 8
2894        add rsi, 8
2895        add rdx, 8
2896        call rawMontgomeryMul
2897        sub rdi, 8
2898        sub rsi, 8
2899
2900        ret
2901
2902;;;;
2903mul_l1l2:
2904        bt     r8, 62          ; check if montgomery first
2905        jc     mul_l1ml2
2906mul_l1nl2:
2907        bt     r9, 62          ; check if montgomery second
2908        jc     mul_l1nl2m
2909mul_l1nl2n:
2910        mov r11b, 0xC0
2911        shl r11d, 24
2912        mov [rdi+4], r11d
2913
2914        add rdi, 8
2915        add rsi, 8
2916        add rdx, 8
2917        call rawMontgomeryMul
2918        sub rdi, 8
2919        sub rsi, 8
2920
2921
2922        push rsi
2923        add rdi, 8
2924        mov rsi, rdi
2925        lea rdx, [R3]
2926        call rawMontgomeryMul
2927        sub rdi, 8
2928        pop rsi
2929
2930        ret
2931
2932mul_l1nl2m:
2933        mov r11b, 0x80
2934        shl r11d, 24
2935        mov [rdi+4], r11d
2936
2937        add rdi, 8
2938        add rsi, 8
2939        add rdx, 8
2940        call rawMontgomeryMul
2941        sub rdi, 8
2942        sub rsi, 8
2943
2944        ret
2945
2946mul_l1ml2:
2947        bt     r9, 62          ; check if montgomery seconf
2948        jc     mul_l1ml2m
2949mul_l1ml2n:
2950        mov r11b, 0x80
2951        shl r11d, 24
2952        mov [rdi+4], r11d
2953
2954        add rdi, 8
2955        add rsi, 8
2956        add rdx, 8
2957        call rawMontgomeryMul
2958        sub rdi, 8
2959        sub rsi, 8
2960
2961        ret
2962
2963mul_l1ml2m:
2964        mov r11b, 0xC0
2965        shl r11d, 24
2966        mov [rdi+4], r11d
2967
2968        add rdi, 8
2969        add rsi, 8
2970        add rdx, 8
2971        call rawMontgomeryMul
2972        sub rdi, 8
2973        sub rsi, 8
2974
2975        ret
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994;;;;;;;;;;;;;;;;;;;;;;
2995; band
2996;;;;;;;;;;;;;;;;;;;;;;
2997; Adds two elements of any kind
2998; Params:
2999;   rsi <= Pointer to element 1
3000;   rdx <= Pointer to element 2
3001;   rdi <= Pointer to result
3002; Modified Registers:
3003;    r8, r9, 10, r11, rax, rcx
3004;;;;;;;;;;;;;;;;;;;;;;
3005Fr_band:
3006        mov    r8, [rsi]
3007        mov    r9, [rdx]
3008        bt     r8, 63          ; Check if is short first operand
3009        jc     and_l1
3010        bt     r9, 63          ; Check if is short second operand
3011        jc     and_s1l2
3012
3013and_s1s2:
3014
3015        cmp    r8d, 0
3016        
3017        js     tmp_13
3018
3019        cmp    r9d, 0
3020        js     tmp_13
3021        xor    rdx, rdx         ; both ops are positive so do the op and return
3022        mov    edx, r8d
3023        and    edx, r9d
3024        mov    [rdi], rdx       ; not necessary to adjust so just save and return
3025        ret
3026
3027tmp_13:
3028        mov r11b, 0x80
3029        shl r11d, 24
3030        mov [rdi+4], r11d
3031        push  rdi
3032        push   rsi
3033        mov   rdi, rdx
3034        movsx rsi, r9d
3035        call  rawCopyS2L
3036        mov   rdx, rdi
3037        pop   rsi
3038        pop   rdi
3039        push  rdi
3040        push  rdx
3041        mov   rdi, rsi
3042        movsx rsi, r8d
3043        call  rawCopyS2L
3044        mov   rsi, rdi
3045        pop   rdx
3046        pop   rdi
3047
3048
3049        mov rax, [rsi + 8]
3050        and rax, [rdx + 8]
3051
3052        mov    [rdi + 8 ], rax
3053
3054        mov rax, [rsi + 16]
3055        and rax, [rdx + 16]
3056
3057        mov    [rdi + 16 ], rax
3058
3059        mov rax, [rsi + 24]
3060        and rax, [rdx + 24]
3061
3062        mov    [rdi + 24 ], rax
3063
3064        mov rax, [rsi + 32]
3065        and rax, [rdx + 32]
3066
3067        and    rax, [lboMask]
3068
3069        mov    [rdi + 32 ], rax
3070
3071
3072        
3073        
3074
3075        ; Compare with q
3076
3077        mov rax, [rdi + 32]
3078        cmp rax, [q + 24]
3079        jc tmp_15        ; q is bigget so done.
3080        jnz tmp_14         ; q is lower
3081
3082        mov rax, [rdi + 24]
3083        cmp rax, [q + 16]
3084        jc tmp_15        ; q is bigget so done.
3085        jnz tmp_14         ; q is lower
3086
3087        mov rax, [rdi + 16]
3088        cmp rax, [q + 8]
3089        jc tmp_15        ; q is bigget so done.
3090        jnz tmp_14         ; q is lower
3091
3092        mov rax, [rdi + 8]
3093        cmp rax, [q + 0]
3094        jc tmp_15        ; q is bigget so done.
3095        jnz tmp_14         ; q is lower
3096
3097        ; If equal substract q
3098tmp_14:
3099
3100        mov rax, [q + 0]
3101        sub [rdi + 8], rax
3102
3103        mov rax, [q + 8]
3104        sbb [rdi + 16], rax
3105
3106        mov rax, [q + 16]
3107        sbb [rdi + 24], rax
3108
3109        mov rax, [q + 24]
3110        sbb [rdi + 32], rax
3111
3112tmp_15:
3113
3114        ret
3115
3116
3117
3118
3119
3120
3121and_l1:
3122        bt     r9, 63          ; Check if is short second operand
3123        jc     and_l1l2
3124
3125
3126and_l1s2:
3127        bt     r8, 62          ; check if montgomery first
3128        jc     and_l1ms2
3129and_l1ns2:
3130        mov r11b, 0x80
3131        shl r11d, 24
3132        mov [rdi+4], r11d
3133
3134        cmp    r9d, 0
3135        
3136        js     tmp_16
3137        movsx  rax, r9d
3138        and rax, [rsi +8]
3139        mov    [rdi+8], rax
3140
3141        xor    rax, rax
3142        and rax, [rsi + 16];
3143
3144        mov    [rdi + 16 ], rax;
3145
3146        xor    rax, rax
3147        and rax, [rsi + 24];
3148
3149        mov    [rdi + 24 ], rax;
3150
3151        xor    rax, rax
3152        and rax, [rsi + 32];
3153
3154        and    rax, [lboMask] ;
3155
3156        mov    [rdi + 32 ], rax;
3157
3158
3159        
3160        
3161
3162        ; Compare with q
3163
3164        mov rax, [rdi + 32]
3165        cmp rax, [q + 24]
3166        jc tmp_18        ; q is bigget so done.
3167        jnz tmp_17         ; q is lower
3168
3169        mov rax, [rdi + 24]
3170        cmp rax, [q + 16]
3171        jc tmp_18        ; q is bigget so done.
3172        jnz tmp_17         ; q is lower
3173
3174        mov rax, [rdi + 16]
3175        cmp rax, [q + 8]
3176        jc tmp_18        ; q is bigget so done.
3177        jnz tmp_17         ; q is lower
3178
3179        mov rax, [rdi + 8]
3180        cmp rax, [q + 0]
3181        jc tmp_18        ; q is bigget so done.
3182        jnz tmp_17         ; q is lower
3183
3184        ; If equal substract q
3185tmp_17:
3186
3187        mov rax, [q + 0]
3188        sub [rdi + 8], rax
3189
3190        mov rax, [q + 8]
3191        sbb [rdi + 16], rax
3192
3193        mov rax, [q + 16]
3194        sbb [rdi + 24], rax
3195
3196        mov rax, [q + 24]
3197        sbb [rdi + 32], rax
3198
3199tmp_18:
3200
3201        ret
3202
3203tmp_16:
3204        push  rdi
3205        push   rsi
3206        mov   rdi, rdx
3207        movsx rsi, r9d
3208        call  rawCopyS2L
3209        mov   rdx, rdi
3210        pop   rsi
3211        pop   rdi
3212        mov r11b, 0x80
3213        shl r11d, 24
3214        mov [rdi+4], r11d
3215
3216
3217        mov rax, [rsi + 8]
3218        and rax, [rdx + 8]
3219
3220        mov    [rdi + 8 ], rax
3221
3222        mov rax, [rsi + 16]
3223        and rax, [rdx + 16]
3224
3225        mov    [rdi + 16 ], rax
3226
3227        mov rax, [rsi + 24]
3228        and rax, [rdx + 24]
3229
3230        mov    [rdi + 24 ], rax
3231
3232        mov rax, [rsi + 32]
3233        and rax, [rdx + 32]
3234
3235        and    rax, [lboMask]
3236
3237        mov    [rdi + 32 ], rax
3238
3239
3240        
3241        
3242
3243        ; Compare with q
3244
3245        mov rax, [rdi + 32]
3246        cmp rax, [q + 24]
3247        jc tmp_20        ; q is bigget so done.
3248        jnz tmp_19         ; q is lower
3249
3250        mov rax, [rdi + 24]
3251        cmp rax, [q + 16]
3252        jc tmp_20        ; q is bigget so done.
3253        jnz tmp_19         ; q is lower
3254
3255        mov rax, [rdi + 16]
3256        cmp rax, [q + 8]
3257        jc tmp_20        ; q is bigget so done.
3258        jnz tmp_19         ; q is lower
3259
3260        mov rax, [rdi + 8]
3261        cmp rax, [q + 0]
3262        jc tmp_20        ; q is bigget so done.
3263        jnz tmp_19         ; q is lower
3264
3265        ; If equal substract q
3266tmp_19:
3267
3268        mov rax, [q + 0]
3269        sub [rdi + 8], rax
3270
3271        mov rax, [q + 8]
3272        sbb [rdi + 16], rax
3273
3274        mov rax, [q + 16]
3275        sbb [rdi + 24], rax
3276
3277        mov rax, [q + 24]
3278        sbb [rdi + 32], rax
3279
3280tmp_20:
3281
3282        ret
3283
3284
3285
3286
3287and_l1ms2:
3288        mov r11b, 0x80
3289        shl r11d, 24
3290        mov [rdi+4], r11d
3291        push   r9              ; r9 is used in montgomery so we need to save it
3292        push rdi
3293        mov  rdi, rsi
3294        mov  rsi, rdx
3295        call Fr_toNormal
3296        mov  rdx, rsi
3297        mov  rsi, rdi
3298        pop  rdi
3299        pop    r9
3300
3301        cmp    r9d, 0
3302        
3303        js     tmp_21
3304        movsx  rax, r9d
3305        and rax, [rsi +8]
3306        mov    [rdi+8], rax
3307
3308        xor    rax, rax
3309        and rax, [rsi + 16];
3310
3311        mov    [rdi + 16 ], rax;
3312
3313        xor    rax, rax
3314        and rax, [rsi + 24];
3315
3316        mov    [rdi + 24 ], rax;
3317
3318        xor    rax, rax
3319        and rax, [rsi + 32];
3320
3321        and    rax, [lboMask] ;
3322
3323        mov    [rdi + 32 ], rax;
3324
3325
3326        
3327        
3328
3329        ; Compare with q
3330
3331        mov rax, [rdi + 32]
3332        cmp rax, [q + 24]
3333        jc tmp_23        ; q is bigget so done.
3334        jnz tmp_22         ; q is lower
3335
3336        mov rax, [rdi + 24]
3337        cmp rax, [q + 16]
3338        jc tmp_23        ; q is bigget so done.
3339        jnz tmp_22         ; q is lower
3340
3341        mov rax, [rdi + 16]
3342        cmp rax, [q + 8]
3343        jc tmp_23        ; q is bigget so done.
3344        jnz tmp_22         ; q is lower
3345
3346        mov rax, [rdi + 8]
3347        cmp rax, [q + 0]
3348        jc tmp_23        ; q is bigget so done.
3349        jnz tmp_22         ; q is lower
3350
3351        ; If equal substract q
3352tmp_22:
3353
3354        mov rax, [q + 0]
3355        sub [rdi + 8], rax
3356
3357        mov rax, [q + 8]
3358        sbb [rdi + 16], rax
3359
3360        mov rax, [q + 16]
3361        sbb [rdi + 24], rax
3362
3363        mov rax, [q + 24]
3364        sbb [rdi + 32], rax
3365
3366tmp_23:
3367
3368        ret
3369
3370tmp_21:
3371        push  rdi
3372        push   rsi
3373        mov   rdi, rdx
3374        movsx rsi, r9d
3375        call  rawCopyS2L
3376        mov   rdx, rdi
3377        pop   rsi
3378        pop   rdi
3379        mov r11b, 0x80
3380        shl r11d, 24
3381        mov [rdi+4], r11d
3382
3383
3384        mov rax, [rsi + 8]
3385        and rax, [rdx + 8]
3386
3387        mov    [rdi + 8 ], rax
3388
3389        mov rax, [rsi + 16]
3390        and rax, [rdx + 16]
3391
3392        mov    [rdi + 16 ], rax
3393
3394        mov rax, [rsi + 24]
3395        and rax, [rdx + 24]
3396
3397        mov    [rdi + 24 ], rax
3398
3399        mov rax, [rsi + 32]
3400        and rax, [rdx + 32]
3401
3402        and    rax, [lboMask]
3403
3404        mov    [rdi + 32 ], rax
3405
3406
3407        
3408        
3409
3410        ; Compare with q
3411
3412        mov rax, [rdi + 32]
3413        cmp rax, [q + 24]
3414        jc tmp_25        ; q is bigget so done.
3415        jnz tmp_24         ; q is lower
3416
3417        mov rax, [rdi + 24]
3418        cmp rax, [q + 16]
3419        jc tmp_25        ; q is bigget so done.
3420        jnz tmp_24         ; q is lower
3421
3422        mov rax, [rdi + 16]
3423        cmp rax, [q + 8]
3424        jc tmp_25        ; q is bigget so done.
3425        jnz tmp_24         ; q is lower
3426
3427        mov rax, [rdi + 8]
3428        cmp rax, [q + 0]
3429        jc tmp_25        ; q is bigget so done.
3430        jnz tmp_24         ; q is lower
3431
3432        ; If equal substract q
3433tmp_24:
3434
3435        mov rax, [q + 0]
3436        sub [rdi + 8], rax
3437
3438        mov rax, [q + 8]
3439        sbb [rdi + 16], rax
3440
3441        mov rax, [q + 16]
3442        sbb [rdi + 24], rax
3443
3444        mov rax, [q + 24]
3445        sbb [rdi + 32], rax
3446
3447tmp_25:
3448
3449        ret
3450
3451
3452
3453
3454
3455and_s1l2:
3456        bt     r9, 62          ; check if montgomery first
3457        jc     and_s1l2m
3458and_s1l2n:
3459        mov r11b, 0x80
3460        shl r11d, 24
3461        mov [rdi+4], r11d
3462
3463        cmp    r8d, 0
3464        
3465        js     tmp_26
3466        movsx  rax, r8d
3467        and rax, [rdx +8]
3468        mov    [rdi+8], rax
3469
3470        xor    rax, rax
3471        and rax, [rdx + 16]
3472
3473        mov    [rdi + 16 ], rax
3474
3475        xor    rax, rax
3476        and rax, [rdx + 24]
3477
3478        mov    [rdi + 24 ], rax
3479
3480        xor    rax, rax
3481        and rax, [rdx + 32]
3482
3483        and    rax, [lboMask]
3484
3485        mov    [rdi + 32 ], rax
3486
3487
3488        
3489        
3490
3491        ; Compare with q
3492
3493        mov rax, [rdi + 32]
3494        cmp rax, [q + 24]
3495        jc tmp_28        ; q is bigget so done.
3496        jnz tmp_27         ; q is lower
3497
3498        mov rax, [rdi + 24]
3499        cmp rax, [q + 16]
3500        jc tmp_28        ; q is bigget so done.
3501        jnz tmp_27         ; q is lower
3502
3503        mov rax, [rdi + 16]
3504        cmp rax, [q + 8]
3505        jc tmp_28        ; q is bigget so done.
3506        jnz tmp_27         ; q is lower
3507
3508        mov rax, [rdi + 8]
3509        cmp rax, [q + 0]
3510        jc tmp_28        ; q is bigget so done.
3511        jnz tmp_27         ; q is lower
3512
3513        ; If equal substract q
3514tmp_27:
3515
3516        mov rax, [q + 0]
3517        sub [rdi + 8], rax
3518
3519        mov rax, [q + 8]
3520        sbb [rdi + 16], rax
3521
3522        mov rax, [q + 16]
3523        sbb [rdi + 24], rax
3524
3525        mov rax, [q + 24]
3526        sbb [rdi + 32], rax
3527
3528tmp_28:
3529
3530        ret
3531
3532tmp_26:
3533        push  rdi
3534        push  rdx
3535        mov   rdi, rsi
3536        movsx rsi, r8d
3537        call  rawCopyS2L
3538        mov   rsi, rdi
3539        pop   rdx
3540        pop   rdi
3541        mov r11b, 0x80
3542        shl r11d, 24
3543        mov [rdi+4], r11d
3544
3545
3546        mov rax, [rsi + 8]
3547        and rax, [rdx + 8]
3548
3549        mov    [rdi + 8 ], rax
3550
3551        mov rax, [rsi + 16]
3552        and rax, [rdx + 16]
3553
3554        mov    [rdi + 16 ], rax
3555
3556        mov rax, [rsi + 24]
3557        and rax, [rdx + 24]
3558
3559        mov    [rdi + 24 ], rax
3560
3561        mov rax, [rsi + 32]
3562        and rax, [rdx + 32]
3563
3564        and    rax, [lboMask]
3565
3566        mov    [rdi + 32 ], rax
3567
3568
3569        
3570        
3571
3572        ; Compare with q
3573
3574        mov rax, [rdi + 32]
3575        cmp rax, [q + 24]
3576        jc tmp_30        ; q is bigget so done.
3577        jnz tmp_29         ; q is lower
3578
3579        mov rax, [rdi + 24]
3580        cmp rax, [q + 16]
3581        jc tmp_30        ; q is bigget so done.
3582        jnz tmp_29         ; q is lower
3583
3584        mov rax, [rdi + 16]
3585        cmp rax, [q + 8]
3586        jc tmp_30        ; q is bigget so done.
3587        jnz tmp_29         ; q is lower
3588
3589        mov rax, [rdi + 8]
3590        cmp rax, [q + 0]
3591        jc tmp_30        ; q is bigget so done.
3592        jnz tmp_29         ; q is lower
3593
3594        ; If equal substract q
3595tmp_29:
3596
3597        mov rax, [q + 0]
3598        sub [rdi + 8], rax
3599
3600        mov rax, [q + 8]
3601        sbb [rdi + 16], rax
3602
3603        mov rax, [q + 16]
3604        sbb [rdi + 24], rax
3605
3606        mov rax, [q + 24]
3607        sbb [rdi + 32], rax
3608
3609tmp_30:
3610
3611        ret
3612
3613
3614
3615
3616and_s1l2m:
3617        mov r11b, 0x80
3618        shl r11d, 24
3619        mov [rdi+4], r11d
3620        push   r8             ; r8 is used in montgomery so we need to save it
3621        push rdi
3622        mov  rdi, rdx
3623        call Fr_toNormal
3624        mov  rdx, rdi
3625        pop  rdi
3626        pop    r8
3627
3628        cmp    r8d, 0
3629        
3630        js     tmp_31
3631        movsx  rax, r8d
3632        and rax, [rdx +8]
3633        mov    [rdi+8], rax
3634
3635        xor    rax, rax
3636        and rax, [rdx + 16]
3637
3638        mov    [rdi + 16 ], rax
3639
3640        xor    rax, rax
3641        and rax, [rdx + 24]
3642
3643        mov    [rdi + 24 ], rax
3644
3645        xor    rax, rax
3646        and rax, [rdx + 32]
3647
3648        and    rax, [lboMask]
3649
3650        mov    [rdi + 32 ], rax
3651
3652
3653        
3654        
3655
3656        ; Compare with q
3657
3658        mov rax, [rdi + 32]
3659        cmp rax, [q + 24]
3660        jc tmp_33        ; q is bigget so done.
3661        jnz tmp_32         ; q is lower
3662
3663        mov rax, [rdi + 24]
3664        cmp rax, [q + 16]
3665        jc tmp_33        ; q is bigget so done.
3666        jnz tmp_32         ; q is lower
3667
3668        mov rax, [rdi + 16]
3669        cmp rax, [q + 8]
3670        jc tmp_33        ; q is bigget so done.
3671        jnz tmp_32         ; q is lower
3672
3673        mov rax, [rdi + 8]
3674        cmp rax, [q + 0]
3675        jc tmp_33        ; q is bigget so done.
3676        jnz tmp_32         ; q is lower
3677
3678        ; If equal substract q
3679tmp_32:
3680
3681        mov rax, [q + 0]
3682        sub [rdi + 8], rax
3683
3684        mov rax, [q + 8]
3685        sbb [rdi + 16], rax
3686
3687        mov rax, [q + 16]
3688        sbb [rdi + 24], rax
3689
3690        mov rax, [q + 24]
3691        sbb [rdi + 32], rax
3692
3693tmp_33:
3694
3695        ret
3696
3697tmp_31:
3698        push  rdi
3699        push  rdx
3700        mov   rdi, rsi
3701        movsx rsi, r8d
3702        call  rawCopyS2L
3703        mov   rsi, rdi
3704        pop   rdx
3705        pop   rdi
3706        mov r11b, 0x80
3707        shl r11d, 24
3708        mov [rdi+4], r11d
3709
3710
3711        mov rax, [rsi + 8]
3712        and rax, [rdx + 8]
3713
3714        mov    [rdi + 8 ], rax
3715
3716        mov rax, [rsi + 16]
3717        and rax, [rdx + 16]
3718
3719        mov    [rdi + 16 ], rax
3720
3721        mov rax, [rsi + 24]
3722        and rax, [rdx + 24]
3723
3724        mov    [rdi + 24 ], rax
3725
3726        mov rax, [rsi + 32]
3727        and rax, [rdx + 32]
3728
3729        and    rax, [lboMask]
3730
3731        mov    [rdi + 32 ], rax
3732
3733
3734        
3735        
3736
3737        ; Compare with q
3738
3739        mov rax, [rdi + 32]
3740        cmp rax, [q + 24]
3741        jc tmp_35        ; q is bigget so done.
3742        jnz tmp_34         ; q is lower
3743
3744        mov rax, [rdi + 24]
3745        cmp rax, [q + 16]
3746        jc tmp_35        ; q is bigget so done.
3747        jnz tmp_34         ; q is lower
3748
3749        mov rax, [rdi + 16]
3750        cmp rax, [q + 8]
3751        jc tmp_35        ; q is bigget so done.
3752        jnz tmp_34         ; q is lower
3753
3754        mov rax, [rdi + 8]
3755        cmp rax, [q + 0]
3756        jc tmp_35        ; q is bigget so done.
3757        jnz tmp_34         ; q is lower
3758
3759        ; If equal substract q
3760tmp_34:
3761
3762        mov rax, [q + 0]
3763        sub [rdi + 8], rax
3764
3765        mov rax, [q + 8]
3766        sbb [rdi + 16], rax
3767
3768        mov rax, [q + 16]
3769        sbb [rdi + 24], rax
3770
3771        mov rax, [q + 24]
3772        sbb [rdi + 32], rax
3773
3774tmp_35:
3775
3776        ret
3777
3778
3779
3780
3781
3782and_l1l2:
3783        bt     r8, 62          ; check if montgomery first
3784        jc     and_l1ml2
3785        bt     r9, 62          ; check if montgomery first
3786        jc     and_l1nl2m
3787and_l1nl2n:
3788        mov r11b, 0x80
3789        shl r11d, 24
3790        mov [rdi+4], r11d
3791
3792
3793        mov rax, [rsi + 8]
3794        and rax, [rdx + 8]
3795
3796        mov    [rdi + 8 ], rax
3797
3798        mov rax, [rsi + 16]
3799        and rax, [rdx + 16]
3800
3801        mov    [rdi + 16 ], rax
3802
3803        mov rax, [rsi + 24]
3804        and rax, [rdx + 24]
3805
3806        mov    [rdi + 24 ], rax
3807
3808        mov rax, [rsi + 32]
3809        and rax, [rdx + 32]
3810
3811        and    rax, [lboMask]
3812
3813        mov    [rdi + 32 ], rax
3814
3815
3816        
3817        
3818
3819        ; Compare with q
3820
3821        mov rax, [rdi + 32]
3822        cmp rax, [q + 24]
3823        jc tmp_37        ; q is bigget so done.
3824        jnz tmp_36         ; q is lower
3825
3826        mov rax, [rdi + 24]
3827        cmp rax, [q + 16]
3828        jc tmp_37        ; q is bigget so done.
3829        jnz tmp_36         ; q is lower
3830
3831        mov rax, [rdi + 16]
3832        cmp rax, [q + 8]
3833        jc tmp_37        ; q is bigget so done.
3834        jnz tmp_36         ; q is lower
3835
3836        mov rax, [rdi + 8]
3837        cmp rax, [q + 0]
3838        jc tmp_37        ; q is bigget so done.
3839        jnz tmp_36         ; q is lower
3840
3841        ; If equal substract q
3842tmp_36:
3843
3844        mov rax, [q + 0]
3845        sub [rdi + 8], rax
3846
3847        mov rax, [q + 8]
3848        sbb [rdi + 16], rax
3849
3850        mov rax, [q + 16]
3851        sbb [rdi + 24], rax
3852
3853        mov rax, [q + 24]
3854        sbb [rdi + 32], rax
3855
3856tmp_37:
3857
3858        ret
3859
3860
3861and_l1nl2m:
3862        mov r11b, 0x80
3863        shl r11d, 24
3864        mov [rdi+4], r11d
3865        push rdi
3866        mov  rdi, rdx
3867        call Fr_toNormal
3868        mov  rdx, rdi
3869        pop  rdi
3870
3871
3872        mov rax, [rsi + 8]
3873        and rax, [rdx + 8]
3874
3875        mov    [rdi + 8 ], rax
3876
3877        mov rax, [rsi + 16]
3878        and rax, [rdx + 16]
3879
3880        mov    [rdi + 16 ], rax
3881
3882        mov rax, [rsi + 24]
3883        and rax, [rdx + 24]
3884
3885        mov    [rdi + 24 ], rax
3886
3887        mov rax, [rsi + 32]
3888        and rax, [rdx + 32]
3889
3890        and    rax, [lboMask]
3891
3892        mov    [rdi + 32 ], rax
3893
3894
3895        
3896        
3897
3898        ; Compare with q
3899
3900        mov rax, [rdi + 32]
3901        cmp rax, [q + 24]
3902        jc tmp_39        ; q is bigget so done.
3903        jnz tmp_38         ; q is lower
3904
3905        mov rax, [rdi + 24]
3906        cmp rax, [q + 16]
3907        jc tmp_39        ; q is bigget so done.
3908        jnz tmp_38         ; q is lower
3909
3910        mov rax, [rdi + 16]
3911        cmp rax, [q + 8]
3912        jc tmp_39        ; q is bigget so done.
3913        jnz tmp_38         ; q is lower
3914
3915        mov rax, [rdi + 8]
3916        cmp rax, [q + 0]
3917        jc tmp_39        ; q is bigget so done.
3918        jnz tmp_38         ; q is lower
3919
3920        ; If equal substract q
3921tmp_38:
3922
3923        mov rax, [q + 0]
3924        sub [rdi + 8], rax
3925
3926        mov rax, [q + 8]
3927        sbb [rdi + 16], rax
3928
3929        mov rax, [q + 16]
3930        sbb [rdi + 24], rax
3931
3932        mov rax, [q + 24]
3933        sbb [rdi + 32], rax
3934
3935tmp_39:
3936
3937        ret
3938
3939
3940and_l1ml2:
3941        bt     r9, 62          ; check if montgomery first
3942        jc     and_l1ml2m
3943and_l1ml2n:
3944        mov r11b, 0x80
3945        shl r11d, 24
3946        mov [rdi+4], r11d
3947        push rdi
3948        mov  rdi, rsi
3949        mov  rsi, rdx
3950        call Fr_toNormal
3951        mov  rdx, rsi
3952        mov  rsi, rdi
3953        pop  rdi
3954
3955
3956        mov rax, [rsi + 8]
3957        and rax, [rdx + 8]
3958
3959        mov    [rdi + 8 ], rax
3960
3961        mov rax, [rsi + 16]
3962        and rax, [rdx + 16]
3963
3964        mov    [rdi + 16 ], rax
3965
3966        mov rax, [rsi + 24]
3967        and rax, [rdx + 24]
3968
3969        mov    [rdi + 24 ], rax
3970
3971        mov rax, [rsi + 32]
3972        and rax, [rdx + 32]
3973
3974        and    rax, [lboMask]
3975
3976        mov    [rdi + 32 ], rax
3977
3978
3979        
3980        
3981
3982        ; Compare with q
3983
3984        mov rax, [rdi + 32]
3985        cmp rax, [q + 24]
3986        jc tmp_41        ; q is bigget so done.
3987        jnz tmp_40         ; q is lower
3988
3989        mov rax, [rdi + 24]
3990        cmp rax, [q + 16]
3991        jc tmp_41        ; q is bigget so done.
3992        jnz tmp_40         ; q is lower
3993
3994        mov rax, [rdi + 16]
3995        cmp rax, [q + 8]
3996        jc tmp_41        ; q is bigget so done.
3997        jnz tmp_40         ; q is lower
3998
3999        mov rax, [rdi + 8]
4000        cmp rax, [q + 0]
4001        jc tmp_41        ; q is bigget so done.
4002        jnz tmp_40         ; q is lower
4003
4004        ; If equal substract q
4005tmp_40:
4006
4007        mov rax, [q + 0]
4008        sub [rdi + 8], rax
4009
4010        mov rax, [q + 8]
4011        sbb [rdi + 16], rax
4012
4013        mov rax, [q + 16]
4014        sbb [rdi + 24], rax
4015
4016        mov rax, [q + 24]
4017        sbb [rdi + 32], rax
4018
4019tmp_41:
4020
4021        ret
4022
4023
4024and_l1ml2m:
4025        mov r11b, 0x80
4026        shl r11d, 24
4027        mov [rdi+4], r11d
4028        push rdi
4029        mov  rdi, rsi
4030        mov  rsi, rdx
4031        call Fr_toNormal
4032        mov  rdx, rsi
4033        mov  rsi, rdi
4034        pop  rdi
4035        push rdi
4036        mov  rdi, rdx
4037        call Fr_toNormal
4038        mov  rdx, rdi
4039        pop  rdi
4040
4041
4042        mov rax, [rsi + 8]
4043        and rax, [rdx + 8]
4044
4045        mov    [rdi + 8 ], rax
4046
4047        mov rax, [rsi + 16]
4048        and rax, [rdx + 16]
4049
4050        mov    [rdi + 16 ], rax
4051
4052        mov rax, [rsi + 24]
4053        and rax, [rdx + 24]
4054
4055        mov    [rdi + 24 ], rax
4056
4057        mov rax, [rsi + 32]
4058        and rax, [rdx + 32]
4059
4060        and    rax, [lboMask]
4061
4062        mov    [rdi + 32 ], rax
4063
4064
4065        
4066        
4067
4068        ; Compare with q
4069
4070        mov rax, [rdi + 32]
4071        cmp rax, [q + 24]
4072        jc tmp_43        ; q is bigget so done.
4073        jnz tmp_42         ; q is lower
4074
4075        mov rax, [rdi + 24]
4076        cmp rax, [q + 16]
4077        jc tmp_43        ; q is bigget so done.
4078        jnz tmp_42         ; q is lower
4079
4080        mov rax, [rdi + 16]
4081        cmp rax, [q + 8]
4082        jc tmp_43        ; q is bigget so done.
4083        jnz tmp_42         ; q is lower
4084
4085        mov rax, [rdi + 8]
4086        cmp rax, [q + 0]
4087        jc tmp_43        ; q is bigget so done.
4088        jnz tmp_42         ; q is lower
4089
4090        ; If equal substract q
4091tmp_42:
4092
4093        mov rax, [q + 0]
4094        sub [rdi + 8], rax
4095
4096        mov rax, [q + 8]
4097        sbb [rdi + 16], rax
4098
4099        mov rax, [q + 16]
4100        sbb [rdi + 24], rax
4101
4102        mov rax, [q + 24]
4103        sbb [rdi + 32], rax
4104
4105tmp_43:
4106
4107        ret
4108
4109
4110
4111;;;;;;;;;;;;;;;;;;;;;;
4112; bor
4113;;;;;;;;;;;;;;;;;;;;;;
4114; Adds two elements of any kind
4115; Params:
4116;   rsi <= Pointer to element 1
4117;   rdx <= Pointer to element 2
4118;   rdi <= Pointer to result
4119; Modified Registers:
4120;    r8, r9, 10, r11, rax, rcx
4121;;;;;;;;;;;;;;;;;;;;;;
4122Fr_bor:
4123        mov    r8, [rsi]
4124        mov    r9, [rdx]
4125        bt     r8, 63          ; Check if is short first operand
4126        jc     or_l1
4127        bt     r9, 63          ; Check if is short second operand
4128        jc     or_s1l2
4129
4130or_s1s2:
4131
4132        cmp    r8d, 0
4133        
4134        js     tmp_44
4135
4136        cmp    r9d, 0
4137        js     tmp_44
4138        xor    rdx, rdx         ; both ops are positive so do the op and return
4139        mov    edx, r8d
4140        or    edx, r9d
4141        mov    [rdi], rdx       ; not necessary to adjust so just save and return
4142        ret
4143
4144tmp_44:
4145        mov r11b, 0x80
4146        shl r11d, 24
4147        mov [rdi+4], r11d
4148        push  rdi
4149        push   rsi
4150        mov   rdi, rdx
4151        movsx rsi, r9d
4152        call  rawCopyS2L
4153        mov   rdx, rdi
4154        pop   rsi
4155        pop   rdi
4156        push  rdi
4157        push  rdx
4158        mov   rdi, rsi
4159        movsx rsi, r8d
4160        call  rawCopyS2L
4161        mov   rsi, rdi
4162        pop   rdx
4163        pop   rdi
4164
4165
4166        mov rax, [rsi + 8]
4167        or rax, [rdx + 8]
4168
4169        mov    [rdi + 8 ], rax
4170
4171        mov rax, [rsi + 16]
4172        or rax, [rdx + 16]
4173
4174        mov    [rdi + 16 ], rax
4175
4176        mov rax, [rsi + 24]
4177        or rax, [rdx + 24]
4178
4179        mov    [rdi + 24 ], rax
4180
4181        mov rax, [rsi + 32]
4182        or rax, [rdx + 32]
4183
4184        and    rax, [lboMask]
4185
4186        mov    [rdi + 32 ], rax
4187
4188
4189        
4190        
4191
4192        ; Compare with q
4193
4194        mov rax, [rdi + 32]
4195        cmp rax, [q + 24]
4196        jc tmp_46        ; q is bigget so done.
4197        jnz tmp_45         ; q is lower
4198
4199        mov rax, [rdi + 24]
4200        cmp rax, [q + 16]
4201        jc tmp_46        ; q is bigget so done.
4202        jnz tmp_45         ; q is lower
4203
4204        mov rax, [rdi + 16]
4205        cmp rax, [q + 8]
4206        jc tmp_46        ; q is bigget so done.
4207        jnz tmp_45         ; q is lower
4208
4209        mov rax, [rdi + 8]
4210        cmp rax, [q + 0]
4211        jc tmp_46        ; q is bigget so done.
4212        jnz tmp_45         ; q is lower
4213
4214        ; If equal substract q
4215tmp_45:
4216
4217        mov rax, [q + 0]
4218        sub [rdi + 8], rax
4219
4220        mov rax, [q + 8]
4221        sbb [rdi + 16], rax
4222
4223        mov rax, [q + 16]
4224        sbb [rdi + 24], rax
4225
4226        mov rax, [q + 24]
4227        sbb [rdi + 32], rax
4228
4229tmp_46:
4230
4231        ret
4232
4233
4234
4235
4236
4237
4238or_l1:
4239        bt     r9, 63          ; Check if is short second operand
4240        jc     or_l1l2
4241
4242
4243or_l1s2:
4244        bt     r8, 62          ; check if montgomery first
4245        jc     or_l1ms2
4246or_l1ns2:
4247        mov r11b, 0x80
4248        shl r11d, 24
4249        mov [rdi+4], r11d
4250
4251        cmp    r9d, 0
4252        
4253        js     tmp_47
4254        movsx  rax, r9d
4255        or rax, [rsi +8]
4256        mov    [rdi+8], rax
4257
4258        xor    rax, rax
4259        or rax, [rsi + 16];
4260
4261        mov    [rdi + 16 ], rax;
4262
4263        xor    rax, rax
4264        or rax, [rsi + 24];
4265
4266        mov    [rdi + 24 ], rax;
4267
4268        xor    rax, rax
4269        or rax, [rsi + 32];
4270
4271        and    rax, [lboMask] ;
4272
4273        mov    [rdi + 32 ], rax;
4274
4275
4276        
4277        
4278
4279        ; Compare with q
4280
4281        mov rax, [rdi + 32]
4282        cmp rax, [q + 24]
4283        jc tmp_49        ; q is bigget so done.
4284        jnz tmp_48         ; q is lower
4285
4286        mov rax, [rdi + 24]
4287        cmp rax, [q + 16]
4288        jc tmp_49        ; q is bigget so done.
4289        jnz tmp_48         ; q is lower
4290
4291        mov rax, [rdi + 16]
4292        cmp rax, [q + 8]
4293        jc tmp_49        ; q is bigget so done.
4294        jnz tmp_48         ; q is lower
4295
4296        mov rax, [rdi + 8]
4297        cmp rax, [q + 0]
4298        jc tmp_49        ; q is bigget so done.
4299        jnz tmp_48         ; q is lower
4300
4301        ; If equal substract q
4302tmp_48:
4303
4304        mov rax, [q + 0]
4305        sub [rdi + 8], rax
4306
4307        mov rax, [q + 8]
4308        sbb [rdi + 16], rax
4309
4310        mov rax, [q + 16]
4311        sbb [rdi + 24], rax
4312
4313        mov rax, [q + 24]
4314        sbb [rdi + 32], rax
4315
4316tmp_49:
4317
4318        ret
4319
4320tmp_47:
4321        push  rdi
4322        push   rsi
4323        mov   rdi, rdx
4324        movsx rsi, r9d
4325        call  rawCopyS2L
4326        mov   rdx, rdi
4327        pop   rsi
4328        pop   rdi
4329        mov r11b, 0x80
4330        shl r11d, 24
4331        mov [rdi+4], r11d
4332
4333
4334        mov rax, [rsi + 8]
4335        or rax, [rdx + 8]
4336
4337        mov    [rdi + 8 ], rax
4338
4339        mov rax, [rsi + 16]
4340        or rax, [rdx + 16]
4341
4342        mov    [rdi + 16 ], rax
4343
4344        mov rax, [rsi + 24]
4345        or rax, [rdx + 24]
4346
4347        mov    [rdi + 24 ], rax
4348
4349        mov rax, [rsi + 32]
4350        or rax, [rdx + 32]
4351
4352        and    rax, [lboMask]
4353
4354        mov    [rdi + 32 ], rax
4355
4356
4357        
4358        
4359
4360        ; Compare with q
4361
4362        mov rax, [rdi + 32]
4363        cmp rax, [q + 24]
4364        jc tmp_51        ; q is bigget so done.
4365        jnz tmp_50         ; q is lower
4366
4367        mov rax, [rdi + 24]
4368        cmp rax, [q + 16]
4369        jc tmp_51        ; q is bigget so done.
4370        jnz tmp_50         ; q is lower
4371
4372        mov rax, [rdi + 16]
4373        cmp rax, [q + 8]
4374        jc tmp_51        ; q is bigget so done.
4375        jnz tmp_50         ; q is lower
4376
4377        mov rax, [rdi + 8]
4378        cmp rax, [q + 0]
4379        jc tmp_51        ; q is bigget so done.
4380        jnz tmp_50         ; q is lower
4381
4382        ; If equal substract q
4383tmp_50:
4384
4385        mov rax, [q + 0]
4386        sub [rdi + 8], rax
4387
4388        mov rax, [q + 8]
4389        sbb [rdi + 16], rax
4390
4391        mov rax, [q + 16]
4392        sbb [rdi + 24], rax
4393
4394        mov rax, [q + 24]
4395        sbb [rdi + 32], rax
4396
4397tmp_51:
4398
4399        ret
4400
4401
4402
4403
4404or_l1ms2:
4405        mov r11b, 0x80
4406        shl r11d, 24
4407        mov [rdi+4], r11d
4408        push   r9              ; r9 is used in montgomery so we need to save it
4409        push rdi
4410        mov  rdi, rsi
4411        mov  rsi, rdx
4412        call Fr_toNormal
4413        mov  rdx, rsi
4414        mov  rsi, rdi
4415        pop  rdi
4416        pop    r9
4417
4418        cmp    r9d, 0
4419        
4420        js     tmp_52
4421        movsx  rax, r9d
4422        or rax, [rsi +8]
4423        mov    [rdi+8], rax
4424
4425        xor    rax, rax
4426        or rax, [rsi + 16];
4427
4428        mov    [rdi + 16 ], rax;
4429
4430        xor    rax, rax
4431        or rax, [rsi + 24];
4432
4433        mov    [rdi + 24 ], rax;
4434
4435        xor    rax, rax
4436        or rax, [rsi + 32];
4437
4438        and    rax, [lboMask] ;
4439
4440        mov    [rdi + 32 ], rax;
4441
4442
4443        
4444        
4445
4446        ; Compare with q
4447
4448        mov rax, [rdi + 32]
4449        cmp rax, [q + 24]
4450        jc tmp_54        ; q is bigget so done.
4451        jnz tmp_53         ; q is lower
4452
4453        mov rax, [rdi + 24]
4454        cmp rax, [q + 16]
4455        jc tmp_54        ; q is bigget so done.
4456        jnz tmp_53         ; q is lower
4457
4458        mov rax, [rdi + 16]
4459        cmp rax, [q + 8]
4460        jc tmp_54        ; q is bigget so done.
4461        jnz tmp_53         ; q is lower
4462
4463        mov rax, [rdi + 8]
4464        cmp rax, [q + 0]
4465        jc tmp_54        ; q is bigget so done.
4466        jnz tmp_53         ; q is lower
4467
4468        ; If equal substract q
4469tmp_53:
4470
4471        mov rax, [q + 0]
4472        sub [rdi + 8], rax
4473
4474        mov rax, [q + 8]
4475        sbb [rdi + 16], rax
4476
4477        mov rax, [q + 16]
4478        sbb [rdi + 24], rax
4479
4480        mov rax, [q + 24]
4481        sbb [rdi + 32], rax
4482
4483tmp_54:
4484
4485        ret
4486
4487tmp_52:
4488        push  rdi
4489        push   rsi
4490        mov   rdi, rdx
4491        movsx rsi, r9d
4492        call  rawCopyS2L
4493        mov   rdx, rdi
4494        pop   rsi
4495        pop   rdi
4496        mov r11b, 0x80
4497        shl r11d, 24
4498        mov [rdi+4], r11d
4499
4500
4501        mov rax, [rsi + 8]
4502        or rax, [rdx + 8]
4503
4504        mov    [rdi + 8 ], rax
4505
4506        mov rax, [rsi + 16]
4507        or rax, [rdx + 16]
4508
4509        mov    [rdi + 16 ], rax
4510
4511        mov rax, [rsi + 24]
4512        or rax, [rdx + 24]
4513
4514        mov    [rdi + 24 ], rax
4515
4516        mov rax, [rsi + 32]
4517        or rax, [rdx + 32]
4518
4519        and    rax, [lboMask]
4520
4521        mov    [rdi + 32 ], rax
4522
4523
4524        
4525        
4526
4527        ; Compare with q
4528
4529        mov rax, [rdi + 32]
4530        cmp rax, [q + 24]
4531        jc tmp_56        ; q is bigget so done.
4532        jnz tmp_55         ; q is lower
4533
4534        mov rax, [rdi + 24]
4535        cmp rax, [q + 16]
4536        jc tmp_56        ; q is bigget so done.
4537        jnz tmp_55         ; q is lower
4538
4539        mov rax, [rdi + 16]
4540        cmp rax, [q + 8]
4541        jc tmp_56        ; q is bigget so done.
4542        jnz tmp_55         ; q is lower
4543
4544        mov rax, [rdi + 8]
4545        cmp rax, [q + 0]
4546        jc tmp_56        ; q is bigget so done.
4547        jnz tmp_55         ; q is lower
4548
4549        ; If equal substract q
4550tmp_55:
4551
4552        mov rax, [q + 0]
4553        sub [rdi + 8], rax
4554
4555        mov rax, [q + 8]
4556        sbb [rdi + 16], rax
4557
4558        mov rax, [q + 16]
4559        sbb [rdi + 24], rax
4560
4561        mov rax, [q + 24]
4562        sbb [rdi + 32], rax
4563
4564tmp_56:
4565
4566        ret
4567
4568
4569
4570
4571
4572or_s1l2:
4573        bt     r9, 62          ; check if montgomery first
4574        jc     or_s1l2m
4575or_s1l2n:
4576        mov r11b, 0x80
4577        shl r11d, 24
4578        mov [rdi+4], r11d
4579
4580        cmp    r8d, 0
4581        
4582        js     tmp_57
4583        movsx  rax, r8d
4584        or rax, [rdx +8]
4585        mov    [rdi+8], rax
4586
4587        xor    rax, rax
4588        or rax, [rdx + 16]
4589
4590        mov    [rdi + 16 ], rax
4591
4592        xor    rax, rax
4593        or rax, [rdx + 24]
4594
4595        mov    [rdi + 24 ], rax
4596
4597        xor    rax, rax
4598        or rax, [rdx + 32]
4599
4600        and    rax, [lboMask]
4601
4602        mov    [rdi + 32 ], rax
4603
4604
4605        
4606        
4607
4608        ; Compare with q
4609
4610        mov rax, [rdi + 32]
4611        cmp rax, [q + 24]
4612        jc tmp_59        ; q is bigget so done.
4613        jnz tmp_58         ; q is lower
4614
4615        mov rax, [rdi + 24]
4616        cmp rax, [q + 16]
4617        jc tmp_59        ; q is bigget so done.
4618        jnz tmp_58         ; q is lower
4619
4620        mov rax, [rdi + 16]
4621        cmp rax, [q + 8]
4622        jc tmp_59        ; q is bigget so done.
4623        jnz tmp_58         ; q is lower
4624
4625        mov rax, [rdi + 8]
4626        cmp rax, [q + 0]
4627        jc tmp_59        ; q is bigget so done.
4628        jnz tmp_58         ; q is lower
4629
4630        ; If equal substract q
4631tmp_58:
4632
4633        mov rax, [q + 0]
4634        sub [rdi + 8], rax
4635
4636        mov rax, [q + 8]
4637        sbb [rdi + 16], rax
4638
4639        mov rax, [q + 16]
4640        sbb [rdi + 24], rax
4641
4642        mov rax, [q + 24]
4643        sbb [rdi + 32], rax
4644
4645tmp_59:
4646
4647        ret
4648
4649tmp_57:
4650        push  rdi
4651        push  rdx
4652        mov   rdi, rsi
4653        movsx rsi, r8d
4654        call  rawCopyS2L
4655        mov   rsi, rdi
4656        pop   rdx
4657        pop   rdi
4658        mov r11b, 0x80
4659        shl r11d, 24
4660        mov [rdi+4], r11d
4661
4662
4663        mov rax, [rsi + 8]
4664        or rax, [rdx + 8]
4665
4666        mov    [rdi + 8 ], rax
4667
4668        mov rax, [rsi + 16]
4669        or rax, [rdx + 16]
4670
4671        mov    [rdi + 16 ], rax
4672
4673        mov rax, [rsi + 24]
4674        or rax, [rdx + 24]
4675
4676        mov    [rdi + 24 ], rax
4677
4678        mov rax, [rsi + 32]
4679        or rax, [rdx + 32]
4680
4681        and    rax, [lboMask]
4682
4683        mov    [rdi + 32 ], rax
4684
4685
4686        
4687        
4688
4689        ; Compare with q
4690
4691        mov rax, [rdi + 32]
4692        cmp rax, [q + 24]
4693        jc tmp_61        ; q is bigget so done.
4694        jnz tmp_60         ; q is lower
4695
4696        mov rax, [rdi + 24]
4697        cmp rax, [q + 16]
4698        jc tmp_61        ; q is bigget so done.
4699        jnz tmp_60         ; q is lower
4700
4701        mov rax, [rdi + 16]
4702        cmp rax, [q + 8]
4703        jc tmp_61        ; q is bigget so done.
4704        jnz tmp_60         ; q is lower
4705
4706        mov rax, [rdi + 8]
4707        cmp rax, [q + 0]
4708        jc tmp_61        ; q is bigget so done.
4709        jnz tmp_60         ; q is lower
4710
4711        ; If equal substract q
4712tmp_60:
4713
4714        mov rax, [q + 0]
4715        sub [rdi + 8], rax
4716
4717        mov rax, [q + 8]
4718        sbb [rdi + 16], rax
4719
4720        mov rax, [q + 16]
4721        sbb [rdi + 24], rax
4722
4723        mov rax, [q + 24]
4724        sbb [rdi + 32], rax
4725
4726tmp_61:
4727
4728        ret
4729
4730
4731
4732
4733or_s1l2m:
4734        mov r11b, 0x80
4735        shl r11d, 24
4736        mov [rdi+4], r11d
4737        push   r8             ; r8 is used in montgomery so we need to save it
4738        push rdi
4739        mov  rdi, rdx
4740        call Fr_toNormal
4741        mov  rdx, rdi
4742        pop  rdi
4743        pop    r8
4744
4745        cmp    r8d, 0
4746        
4747        js     tmp_62
4748        movsx  rax, r8d
4749        or rax, [rdx +8]
4750        mov    [rdi+8], rax
4751
4752        xor    rax, rax
4753        or rax, [rdx + 16]
4754
4755        mov    [rdi + 16 ], rax
4756
4757        xor    rax, rax
4758        or rax, [rdx + 24]
4759
4760        mov    [rdi + 24 ], rax
4761
4762        xor    rax, rax
4763        or rax, [rdx + 32]
4764
4765        and    rax, [lboMask]
4766
4767        mov    [rdi + 32 ], rax
4768
4769
4770        
4771        
4772
4773        ; Compare with q
4774
4775        mov rax, [rdi + 32]
4776        cmp rax, [q + 24]
4777        jc tmp_64        ; q is bigget so done.
4778        jnz tmp_63         ; q is lower
4779
4780        mov rax, [rdi + 24]
4781        cmp rax, [q + 16]
4782        jc tmp_64        ; q is bigget so done.
4783        jnz tmp_63         ; q is lower
4784
4785        mov rax, [rdi + 16]
4786        cmp rax, [q + 8]
4787        jc tmp_64        ; q is bigget so done.
4788        jnz tmp_63         ; q is lower
4789
4790        mov rax, [rdi + 8]
4791        cmp rax, [q + 0]
4792        jc tmp_64        ; q is bigget so done.
4793        jnz tmp_63         ; q is lower
4794
4795        ; If equal substract q
4796tmp_63:
4797
4798        mov rax, [q + 0]
4799        sub [rdi + 8], rax
4800
4801        mov rax, [q + 8]
4802        sbb [rdi + 16], rax
4803
4804        mov rax, [q + 16]
4805        sbb [rdi + 24], rax
4806
4807        mov rax, [q + 24]
4808        sbb [rdi + 32], rax
4809
4810tmp_64:
4811
4812        ret
4813
4814tmp_62:
4815        push  rdi
4816        push  rdx
4817        mov   rdi, rsi
4818        movsx rsi, r8d
4819        call  rawCopyS2L
4820        mov   rsi, rdi
4821        pop   rdx
4822        pop   rdi
4823        mov r11b, 0x80
4824        shl r11d, 24
4825        mov [rdi+4], r11d
4826
4827
4828        mov rax, [rsi + 8]
4829        or rax, [rdx + 8]
4830
4831        mov    [rdi + 8 ], rax
4832
4833        mov rax, [rsi + 16]
4834        or rax, [rdx + 16]
4835
4836        mov    [rdi + 16 ], rax
4837
4838        mov rax, [rsi + 24]
4839        or rax, [rdx + 24]
4840
4841        mov    [rdi + 24 ], rax
4842
4843        mov rax, [rsi + 32]
4844        or rax, [rdx + 32]
4845
4846        and    rax, [lboMask]
4847
4848        mov    [rdi + 32 ], rax
4849
4850
4851        
4852        
4853
4854        ; Compare with q
4855
4856        mov rax, [rdi + 32]
4857        cmp rax, [q + 24]
4858        jc tmp_66        ; q is bigget so done.
4859        jnz tmp_65         ; q is lower
4860
4861        mov rax, [rdi + 24]
4862        cmp rax, [q + 16]
4863        jc tmp_66        ; q is bigget so done.
4864        jnz tmp_65         ; q is lower
4865
4866        mov rax, [rdi + 16]
4867        cmp rax, [q + 8]
4868        jc tmp_66        ; q is bigget so done.
4869        jnz tmp_65         ; q is lower
4870
4871        mov rax, [rdi + 8]
4872        cmp rax, [q + 0]
4873        jc tmp_66        ; q is bigget so done.
4874        jnz tmp_65         ; q is lower
4875
4876        ; If equal substract q
4877tmp_65:
4878
4879        mov rax, [q + 0]
4880        sub [rdi + 8], rax
4881
4882        mov rax, [q + 8]
4883        sbb [rdi + 16], rax
4884
4885        mov rax, [q + 16]
4886        sbb [rdi + 24], rax
4887
4888        mov rax, [q + 24]
4889        sbb [rdi + 32], rax
4890
4891tmp_66:
4892
4893        ret
4894
4895
4896
4897
4898
4899or_l1l2:
4900        bt     r8, 62          ; check if montgomery first
4901        jc     or_l1ml2
4902        bt     r9, 62          ; check if montgomery first
4903        jc     or_l1nl2m
4904or_l1nl2n:
4905        mov r11b, 0x80
4906        shl r11d, 24
4907        mov [rdi+4], r11d
4908
4909
4910        mov rax, [rsi + 8]
4911        or rax, [rdx + 8]
4912
4913        mov    [rdi + 8 ], rax
4914
4915        mov rax, [rsi + 16]
4916        or rax, [rdx + 16]
4917
4918        mov    [rdi + 16 ], rax
4919
4920        mov rax, [rsi + 24]
4921        or rax, [rdx + 24]
4922
4923        mov    [rdi + 24 ], rax
4924
4925        mov rax, [rsi + 32]
4926        or rax, [rdx + 32]
4927
4928        and    rax, [lboMask]
4929
4930        mov    [rdi + 32 ], rax
4931
4932
4933        
4934        
4935
4936        ; Compare with q
4937
4938        mov rax, [rdi + 32]
4939        cmp rax, [q + 24]
4940        jc tmp_68        ; q is bigget so done.
4941        jnz tmp_67         ; q is lower
4942
4943        mov rax, [rdi + 24]
4944        cmp rax, [q + 16]
4945        jc tmp_68        ; q is bigget so done.
4946        jnz tmp_67         ; q is lower
4947
4948        mov rax, [rdi + 16]
4949        cmp rax, [q + 8]
4950        jc tmp_68        ; q is bigget so done.
4951        jnz tmp_67         ; q is lower
4952
4953        mov rax, [rdi + 8]
4954        cmp rax, [q + 0]
4955        jc tmp_68        ; q is bigget so done.
4956        jnz tmp_67         ; q is lower
4957
4958        ; If equal substract q
4959tmp_67:
4960
4961        mov rax, [q + 0]
4962        sub [rdi + 8], rax
4963
4964        mov rax, [q + 8]
4965        sbb [rdi + 16], rax
4966
4967        mov rax, [q + 16]
4968        sbb [rdi + 24], rax
4969
4970        mov rax, [q + 24]
4971        sbb [rdi + 32], rax
4972
4973tmp_68:
4974
4975        ret
4976
4977
4978or_l1nl2m:
4979        mov r11b, 0x80
4980        shl r11d, 24
4981        mov [rdi+4], r11d
4982        push rdi
4983        mov  rdi, rdx
4984        call Fr_toNormal
4985        mov  rdx, rdi
4986        pop  rdi
4987
4988
4989        mov rax, [rsi + 8]
4990        or rax, [rdx + 8]
4991
4992        mov    [rdi + 8 ], rax
4993
4994        mov rax, [rsi + 16]
4995        or rax, [rdx + 16]
4996
4997        mov    [rdi + 16 ], rax
4998
4999        mov rax, [rsi + 24]
5000        or rax, [rdx + 24]
5001
5002        mov    [rdi + 24 ], rax
5003
5004        mov rax, [rsi + 32]
5005        or rax, [rdx + 32]
5006
5007        and    rax, [lboMask]
5008
5009        mov    [rdi + 32 ], rax
5010
5011
5012        
5013        
5014
5015        ; Compare with q
5016
5017        mov rax, [rdi + 32]
5018        cmp rax, [q + 24]
5019        jc tmp_70        ; q is bigget so done.
5020        jnz tmp_69         ; q is lower
5021
5022        mov rax, [rdi + 24]
5023        cmp rax, [q + 16]
5024        jc tmp_70        ; q is bigget so done.
5025        jnz tmp_69         ; q is lower
5026
5027        mov rax, [rdi + 16]
5028        cmp rax, [q + 8]
5029        jc tmp_70        ; q is bigget so done.
5030        jnz tmp_69         ; q is lower
5031
5032        mov rax, [rdi + 8]
5033        cmp rax, [q + 0]
5034        jc tmp_70        ; q is bigget so done.
5035        jnz tmp_69         ; q is lower
5036
5037        ; If equal substract q
5038tmp_69:
5039
5040        mov rax, [q + 0]
5041        sub [rdi + 8], rax
5042
5043        mov rax, [q + 8]
5044        sbb [rdi + 16], rax
5045
5046        mov rax, [q + 16]
5047        sbb [rdi + 24], rax
5048
5049        mov rax, [q + 24]
5050        sbb [rdi + 32], rax
5051
5052tmp_70:
5053
5054        ret
5055
5056
5057or_l1ml2:
5058        bt     r9, 62          ; check if montgomery first
5059        jc     or_l1ml2m
5060or_l1ml2n:
5061        mov r11b, 0x80
5062        shl r11d, 24
5063        mov [rdi+4], r11d
5064        push rdi
5065        mov  rdi, rsi
5066        mov  rsi, rdx
5067        call Fr_toNormal
5068        mov  rdx, rsi
5069        mov  rsi, rdi
5070        pop  rdi
5071
5072
5073        mov rax, [rsi + 8]
5074        or rax, [rdx + 8]
5075
5076        mov    [rdi + 8 ], rax
5077
5078        mov rax, [rsi + 16]
5079        or rax, [rdx + 16]
5080
5081        mov    [rdi + 16 ], rax
5082
5083        mov rax, [rsi + 24]
5084        or rax, [rdx + 24]
5085
5086        mov    [rdi + 24 ], rax
5087
5088        mov rax, [rsi + 32]
5089        or rax, [rdx + 32]
5090
5091        and    rax, [lboMask]
5092
5093        mov    [rdi + 32 ], rax
5094
5095
5096        
5097        
5098
5099        ; Compare with q
5100
5101        mov rax, [rdi + 32]
5102        cmp rax, [q + 24]
5103        jc tmp_72        ; q is bigget so done.
5104        jnz tmp_71         ; q is lower
5105
5106        mov rax, [rdi + 24]
5107        cmp rax, [q + 16]
5108        jc tmp_72        ; q is bigget so done.
5109        jnz tmp_71         ; q is lower
5110
5111        mov rax, [rdi + 16]
5112        cmp rax, [q + 8]
5113        jc tmp_72        ; q is bigget so done.
5114        jnz tmp_71         ; q is lower
5115
5116        mov rax, [rdi + 8]
5117        cmp rax, [q + 0]
5118        jc tmp_72        ; q is bigget so done.
5119        jnz tmp_71         ; q is lower
5120
5121        ; If equal substract q
5122tmp_71:
5123
5124        mov rax, [q + 0]
5125        sub [rdi + 8], rax
5126
5127        mov rax, [q + 8]
5128        sbb [rdi + 16], rax
5129
5130        mov rax, [q + 16]
5131        sbb [rdi + 24], rax
5132
5133        mov rax, [q + 24]
5134        sbb [rdi + 32], rax
5135
5136tmp_72:
5137
5138        ret
5139
5140
5141or_l1ml2m:
5142        mov r11b, 0x80
5143        shl r11d, 24
5144        mov [rdi+4], r11d
5145        push rdi
5146        mov  rdi, rsi
5147        mov  rsi, rdx
5148        call Fr_toNormal
5149        mov  rdx, rsi
5150        mov  rsi, rdi
5151        pop  rdi
5152        push rdi
5153        mov  rdi, rdx
5154        call Fr_toNormal
5155        mov  rdx, rdi
5156        pop  rdi
5157
5158
5159        mov rax, [rsi + 8]
5160        or rax, [rdx + 8]
5161
5162        mov    [rdi + 8 ], rax
5163
5164        mov rax, [rsi + 16]
5165        or rax, [rdx + 16]
5166
5167        mov    [rdi + 16 ], rax
5168
5169        mov rax, [rsi + 24]
5170        or rax, [rdx + 24]
5171
5172        mov    [rdi + 24 ], rax
5173
5174        mov rax, [rsi + 32]
5175        or rax, [rdx + 32]
5176
5177        and    rax, [lboMask]
5178
5179        mov    [rdi + 32 ], rax
5180
5181
5182        
5183        
5184
5185        ; Compare with q
5186
5187        mov rax, [rdi + 32]
5188        cmp rax, [q + 24]
5189        jc tmp_74        ; q is bigget so done.
5190        jnz tmp_73         ; q is lower
5191
5192        mov rax, [rdi + 24]
5193        cmp rax, [q + 16]
5194        jc tmp_74        ; q is bigget so done.
5195        jnz tmp_73         ; q is lower
5196
5197        mov rax, [rdi + 16]
5198        cmp rax, [q + 8]
5199        jc tmp_74        ; q is bigget so done.
5200        jnz tmp_73         ; q is lower
5201
5202        mov rax, [rdi + 8]
5203        cmp rax, [q + 0]
5204        jc tmp_74        ; q is bigget so done.
5205        jnz tmp_73         ; q is lower
5206
5207        ; If equal substract q
5208tmp_73:
5209
5210        mov rax, [q + 0]
5211        sub [rdi + 8], rax
5212
5213        mov rax, [q + 8]
5214        sbb [rdi + 16], rax
5215
5216        mov rax, [q + 16]
5217        sbb [rdi + 24], rax
5218
5219        mov rax, [q + 24]
5220        sbb [rdi + 32], rax
5221
5222tmp_74:
5223
5224        ret
5225
5226
5227
5228;;;;;;;;;;;;;;;;;;;;;;
5229; bxor
5230;;;;;;;;;;;;;;;;;;;;;;
5231; Adds two elements of any kind
5232; Params:
5233;   rsi <= Pointer to element 1
5234;   rdx <= Pointer to element 2
5235;   rdi <= Pointer to result
5236; Modified Registers:
5237;    r8, r9, 10, r11, rax, rcx
5238;;;;;;;;;;;;;;;;;;;;;;
5239Fr_bxor:
5240        mov    r8, [rsi]
5241        mov    r9, [rdx]
5242        bt     r8, 63          ; Check if is short first operand
5243        jc     xor_l1
5244        bt     r9, 63          ; Check if is short second operand
5245        jc     xor_s1l2
5246
5247xor_s1s2:
5248
5249        cmp    r8d, 0
5250        
5251        js     tmp_75
5252
5253        cmp    r9d, 0
5254        js     tmp_75
5255        xor    rdx, rdx         ; both ops are positive so do the op and return
5256        mov    edx, r8d
5257        xor    edx, r9d
5258        mov    [rdi], rdx       ; not necessary to adjust so just save and return
5259        ret
5260
5261tmp_75:
5262        mov r11b, 0x80
5263        shl r11d, 24
5264        mov [rdi+4], r11d
5265        push  rdi
5266        push   rsi
5267        mov   rdi, rdx
5268        movsx rsi, r9d
5269        call  rawCopyS2L
5270        mov   rdx, rdi
5271        pop   rsi
5272        pop   rdi
5273        push  rdi
5274        push  rdx
5275        mov   rdi, rsi
5276        movsx rsi, r8d
5277        call  rawCopyS2L
5278        mov   rsi, rdi
5279        pop   rdx
5280        pop   rdi
5281
5282
5283        mov rax, [rsi + 8]
5284        xor rax, [rdx + 8]
5285
5286        mov    [rdi + 8 ], rax
5287
5288        mov rax, [rsi + 16]
5289        xor rax, [rdx + 16]
5290
5291        mov    [rdi + 16 ], rax
5292
5293        mov rax, [rsi + 24]
5294        xor rax, [rdx + 24]
5295
5296        mov    [rdi + 24 ], rax
5297
5298        mov rax, [rsi + 32]
5299        xor rax, [rdx + 32]
5300
5301        and    rax, [lboMask]
5302
5303        mov    [rdi + 32 ], rax
5304
5305
5306        
5307        
5308
5309        ; Compare with q
5310
5311        mov rax, [rdi + 32]
5312        cmp rax, [q + 24]
5313        jc tmp_77        ; q is bigget so done.
5314        jnz tmp_76         ; q is lower
5315
5316        mov rax, [rdi + 24]
5317        cmp rax, [q + 16]
5318        jc tmp_77        ; q is bigget so done.
5319        jnz tmp_76         ; q is lower
5320
5321        mov rax, [rdi + 16]
5322        cmp rax, [q + 8]
5323        jc tmp_77        ; q is bigget so done.
5324        jnz tmp_76         ; q is lower
5325
5326        mov rax, [rdi + 8]
5327        cmp rax, [q + 0]
5328        jc tmp_77        ; q is bigget so done.
5329        jnz tmp_76         ; q is lower
5330
5331        ; If equal substract q
5332tmp_76:
5333
5334        mov rax, [q + 0]
5335        sub [rdi + 8], rax
5336
5337        mov rax, [q + 8]
5338        sbb [rdi + 16], rax
5339
5340        mov rax, [q + 16]
5341        sbb [rdi + 24], rax
5342
5343        mov rax, [q + 24]
5344        sbb [rdi + 32], rax
5345
5346tmp_77:
5347
5348        ret
5349
5350
5351
5352
5353
5354
5355xor_l1:
5356        bt     r9, 63          ; Check if is short second operand
5357        jc     xor_l1l2
5358
5359
5360xor_l1s2:
5361        bt     r8, 62          ; check if montgomery first
5362        jc     xor_l1ms2
5363xor_l1ns2:
5364        mov r11b, 0x80
5365        shl r11d, 24
5366        mov [rdi+4], r11d
5367
5368        cmp    r9d, 0
5369        
5370        js     tmp_78
5371        movsx  rax, r9d
5372        xor rax, [rsi +8]
5373        mov    [rdi+8], rax
5374
5375        xor    rax, rax
5376        xor rax, [rsi + 16];
5377
5378        mov    [rdi + 16 ], rax;
5379
5380        xor    rax, rax
5381        xor rax, [rsi + 24];
5382
5383        mov    [rdi + 24 ], rax;
5384
5385        xor    rax, rax
5386        xor rax, [rsi + 32];
5387
5388        and    rax, [lboMask] ;
5389
5390        mov    [rdi + 32 ], rax;
5391
5392
5393        
5394        
5395
5396        ; Compare with q
5397
5398        mov rax, [rdi + 32]
5399        cmp rax, [q + 24]
5400        jc tmp_80        ; q is bigget so done.
5401        jnz tmp_79         ; q is lower
5402
5403        mov rax, [rdi + 24]
5404        cmp rax, [q + 16]
5405        jc tmp_80        ; q is bigget so done.
5406        jnz tmp_79         ; q is lower
5407
5408        mov rax, [rdi + 16]
5409        cmp rax, [q + 8]
5410        jc tmp_80        ; q is bigget so done.
5411        jnz tmp_79         ; q is lower
5412
5413        mov rax, [rdi + 8]
5414        cmp rax, [q + 0]
5415        jc tmp_80        ; q is bigget so done.
5416        jnz tmp_79         ; q is lower
5417
5418        ; If equal substract q
5419tmp_79:
5420
5421        mov rax, [q + 0]
5422        sub [rdi + 8], rax
5423
5424        mov rax, [q + 8]
5425        sbb [rdi + 16], rax
5426
5427        mov rax, [q + 16]
5428        sbb [rdi + 24], rax
5429
5430        mov rax, [q + 24]
5431        sbb [rdi + 32], rax
5432
5433tmp_80:
5434
5435        ret
5436
5437tmp_78:
5438        push  rdi
5439        push   rsi
5440        mov   rdi, rdx
5441        movsx rsi, r9d
5442        call  rawCopyS2L
5443        mov   rdx, rdi
5444        pop   rsi
5445        pop   rdi
5446        mov r11b, 0x80
5447        shl r11d, 24
5448        mov [rdi+4], r11d
5449
5450
5451        mov rax, [rsi + 8]
5452        xor rax, [rdx + 8]
5453
5454        mov    [rdi + 8 ], rax
5455
5456        mov rax, [rsi + 16]
5457        xor rax, [rdx + 16]
5458
5459        mov    [rdi + 16 ], rax
5460
5461        mov rax, [rsi + 24]
5462        xor rax, [rdx + 24]
5463
5464        mov    [rdi + 24 ], rax
5465
5466        mov rax, [rsi + 32]
5467        xor rax, [rdx + 32]
5468
5469        and    rax, [lboMask]
5470
5471        mov    [rdi + 32 ], rax
5472
5473
5474        
5475        
5476
5477        ; Compare with q
5478
5479        mov rax, [rdi + 32]
5480        cmp rax, [q + 24]
5481        jc tmp_82        ; q is bigget so done.
5482        jnz tmp_81         ; q is lower
5483
5484        mov rax, [rdi + 24]
5485        cmp rax, [q + 16]
5486        jc tmp_82        ; q is bigget so done.
5487        jnz tmp_81         ; q is lower
5488
5489        mov rax, [rdi + 16]
5490        cmp rax, [q + 8]
5491        jc tmp_82        ; q is bigget so done.
5492        jnz tmp_81         ; q is lower
5493
5494        mov rax, [rdi + 8]
5495        cmp rax, [q + 0]
5496        jc tmp_82        ; q is bigget so done.
5497        jnz tmp_81         ; q is lower
5498
5499        ; If equal substract q
5500tmp_81:
5501
5502        mov rax, [q + 0]
5503        sub [rdi + 8], rax
5504
5505        mov rax, [q + 8]
5506        sbb [rdi + 16], rax
5507
5508        mov rax, [q + 16]
5509        sbb [rdi + 24], rax
5510
5511        mov rax, [q + 24]
5512        sbb [rdi + 32], rax
5513
5514tmp_82:
5515
5516        ret
5517
5518
5519
5520
5521xor_l1ms2:
5522        mov r11b, 0x80
5523        shl r11d, 24
5524        mov [rdi+4], r11d
5525        push   r9              ; r9 is used in montgomery so we need to save it
5526        push rdi
5527        mov  rdi, rsi
5528        mov  rsi, rdx
5529        call Fr_toNormal
5530        mov  rdx, rsi
5531        mov  rsi, rdi
5532        pop  rdi
5533        pop    r9
5534
5535        cmp    r9d, 0
5536        
5537        js     tmp_83
5538        movsx  rax, r9d
5539        xor rax, [rsi +8]
5540        mov    [rdi+8], rax
5541
5542        xor    rax, rax
5543        xor rax, [rsi + 16];
5544
5545        mov    [rdi + 16 ], rax;
5546
5547        xor    rax, rax
5548        xor rax, [rsi + 24];
5549
5550        mov    [rdi + 24 ], rax;
5551
5552        xor    rax, rax
5553        xor rax, [rsi + 32];
5554
5555        and    rax, [lboMask] ;
5556
5557        mov    [rdi + 32 ], rax;
5558
5559
5560        
5561        
5562
5563        ; Compare with q
5564
5565        mov rax, [rdi + 32]
5566        cmp rax, [q + 24]
5567        jc tmp_85        ; q is bigget so done.
5568        jnz tmp_84         ; q is lower
5569
5570        mov rax, [rdi + 24]
5571        cmp rax, [q + 16]
5572        jc tmp_85        ; q is bigget so done.
5573        jnz tmp_84         ; q is lower
5574
5575        mov rax, [rdi + 16]
5576        cmp rax, [q + 8]
5577        jc tmp_85        ; q is bigget so done.
5578        jnz tmp_84         ; q is lower
5579
5580        mov rax, [rdi + 8]
5581        cmp rax, [q + 0]
5582        jc tmp_85        ; q is bigget so done.
5583        jnz tmp_84         ; q is lower
5584
5585        ; If equal substract q
5586tmp_84:
5587
5588        mov rax, [q + 0]
5589        sub [rdi + 8], rax
5590
5591        mov rax, [q + 8]
5592        sbb [rdi + 16], rax
5593
5594        mov rax, [q + 16]
5595        sbb [rdi + 24], rax
5596
5597        mov rax, [q + 24]
5598        sbb [rdi + 32], rax
5599
5600tmp_85:
5601
5602        ret
5603
5604tmp_83:
5605        push  rdi
5606        push   rsi
5607        mov   rdi, rdx
5608        movsx rsi, r9d
5609        call  rawCopyS2L
5610        mov   rdx, rdi
5611        pop   rsi
5612        pop   rdi
5613        mov r11b, 0x80
5614        shl r11d, 24
5615        mov [rdi+4], r11d
5616
5617
5618        mov rax, [rsi + 8]
5619        xor rax, [rdx + 8]
5620
5621        mov    [rdi + 8 ], rax
5622
5623        mov rax, [rsi + 16]
5624        xor rax, [rdx + 16]
5625
5626        mov    [rdi + 16 ], rax
5627
5628        mov rax, [rsi + 24]
5629        xor rax, [rdx + 24]
5630
5631        mov    [rdi + 24 ], rax
5632
5633        mov rax, [rsi + 32]
5634        xor rax, [rdx + 32]
5635
5636        and    rax, [lboMask]
5637
5638        mov    [rdi + 32 ], rax
5639
5640
5641        
5642        
5643
5644        ; Compare with q
5645
5646        mov rax, [rdi + 32]
5647        cmp rax, [q + 24]
5648        jc tmp_87        ; q is bigget so done.
5649        jnz tmp_86         ; q is lower
5650
5651        mov rax, [rdi + 24]
5652        cmp rax, [q + 16]
5653        jc tmp_87        ; q is bigget so done.
5654        jnz tmp_86         ; q is lower
5655
5656        mov rax, [rdi + 16]
5657        cmp rax, [q + 8]
5658        jc tmp_87        ; q is bigget so done.
5659        jnz tmp_86         ; q is lower
5660
5661        mov rax, [rdi + 8]
5662        cmp rax, [q + 0]
5663        jc tmp_87        ; q is bigget so done.
5664        jnz tmp_86         ; q is lower
5665
5666        ; If equal substract q
5667tmp_86:
5668
5669        mov rax, [q + 0]
5670        sub [rdi + 8], rax
5671
5672        mov rax, [q + 8]
5673        sbb [rdi + 16], rax
5674
5675        mov rax, [q + 16]
5676        sbb [rdi + 24], rax
5677
5678        mov rax, [q + 24]
5679        sbb [rdi + 32], rax
5680
5681tmp_87:
5682
5683        ret
5684
5685
5686
5687
5688
5689xor_s1l2:
5690        bt     r9, 62          ; check if montgomery first
5691        jc     xor_s1l2m
5692xor_s1l2n:
5693        mov r11b, 0x80
5694        shl r11d, 24
5695        mov [rdi+4], r11d
5696
5697        cmp    r8d, 0
5698        
5699        js     tmp_88
5700        movsx  rax, r8d
5701        xor rax, [rdx +8]
5702        mov    [rdi+8], rax
5703
5704        xor    rax, rax
5705        xor rax, [rdx + 16]
5706
5707        mov    [rdi + 16 ], rax
5708
5709        xor    rax, rax
5710        xor rax, [rdx + 24]
5711
5712        mov    [rdi + 24 ], rax
5713
5714        xor    rax, rax
5715        xor rax, [rdx + 32]
5716
5717        and    rax, [lboMask]
5718
5719        mov    [rdi + 32 ], rax
5720
5721
5722        
5723        
5724
5725        ; Compare with q
5726
5727        mov rax, [rdi + 32]
5728        cmp rax, [q + 24]
5729        jc tmp_90        ; q is bigget so done.
5730        jnz tmp_89         ; q is lower
5731
5732        mov rax, [rdi + 24]
5733        cmp rax, [q + 16]
5734        jc tmp_90        ; q is bigget so done.
5735        jnz tmp_89         ; q is lower
5736
5737        mov rax, [rdi + 16]
5738        cmp rax, [q + 8]
5739        jc tmp_90        ; q is bigget so done.
5740        jnz tmp_89         ; q is lower
5741
5742        mov rax, [rdi + 8]
5743        cmp rax, [q + 0]
5744        jc tmp_90        ; q is bigget so done.
5745        jnz tmp_89         ; q is lower
5746
5747        ; If equal substract q
5748tmp_89:
5749
5750        mov rax, [q + 0]
5751        sub [rdi + 8], rax
5752
5753        mov rax, [q + 8]
5754        sbb [rdi + 16], rax
5755
5756        mov rax, [q + 16]
5757        sbb [rdi + 24], rax
5758
5759        mov rax, [q + 24]
5760        sbb [rdi + 32], rax
5761
5762tmp_90:
5763
5764        ret
5765
5766tmp_88:
5767        push  rdi
5768        push  rdx
5769        mov   rdi, rsi
5770        movsx rsi, r8d
5771        call  rawCopyS2L
5772        mov   rsi, rdi
5773        pop   rdx
5774        pop   rdi
5775        mov r11b, 0x80
5776        shl r11d, 24
5777        mov [rdi+4], r11d
5778
5779
5780        mov rax, [rsi + 8]
5781        xor rax, [rdx + 8]
5782
5783        mov    [rdi + 8 ], rax
5784
5785        mov rax, [rsi + 16]
5786        xor rax, [rdx + 16]
5787
5788        mov    [rdi + 16 ], rax
5789
5790        mov rax, [rsi + 24]
5791        xor rax, [rdx + 24]
5792
5793        mov    [rdi + 24 ], rax
5794
5795        mov rax, [rsi + 32]
5796        xor rax, [rdx + 32]
5797
5798        and    rax, [lboMask]
5799
5800        mov    [rdi + 32 ], rax
5801
5802
5803        
5804        
5805
5806        ; Compare with q
5807
5808        mov rax, [rdi + 32]
5809        cmp rax, [q + 24]
5810        jc tmp_92        ; q is bigget so done.
5811        jnz tmp_91         ; q is lower
5812
5813        mov rax, [rdi + 24]
5814        cmp rax, [q + 16]
5815        jc tmp_92        ; q is bigget so done.
5816        jnz tmp_91         ; q is lower
5817
5818        mov rax, [rdi + 16]
5819        cmp rax, [q + 8]
5820        jc tmp_92        ; q is bigget so done.
5821        jnz tmp_91         ; q is lower
5822
5823        mov rax, [rdi + 8]
5824        cmp rax, [q + 0]
5825        jc tmp_92        ; q is bigget so done.
5826        jnz tmp_91         ; q is lower
5827
5828        ; If equal substract q
5829tmp_91:
5830
5831        mov rax, [q + 0]
5832        sub [rdi + 8], rax
5833
5834        mov rax, [q + 8]
5835        sbb [rdi + 16], rax
5836
5837        mov rax, [q + 16]
5838        sbb [rdi + 24], rax
5839
5840        mov rax, [q + 24]
5841        sbb [rdi + 32], rax
5842
5843tmp_92:
5844
5845        ret
5846
5847
5848
5849
5850xor_s1l2m:
5851        mov r11b, 0x80
5852        shl r11d, 24
5853        mov [rdi+4], r11d
5854        push   r8             ; r8 is used in montgomery so we need to save it
5855        push rdi
5856        mov  rdi, rdx
5857        call Fr_toNormal
5858        mov  rdx, rdi
5859        pop  rdi
5860        pop    r8
5861
5862        cmp    r8d, 0
5863        
5864        js     tmp_93
5865        movsx  rax, r8d
5866        xor rax, [rdx +8]
5867        mov    [rdi+8], rax
5868
5869        xor    rax, rax
5870        xor rax, [rdx + 16]
5871
5872        mov    [rdi + 16 ], rax
5873
5874        xor    rax, rax
5875        xor rax, [rdx + 24]
5876
5877        mov    [rdi + 24 ], rax
5878
5879        xor    rax, rax
5880        xor rax, [rdx + 32]
5881
5882        and    rax, [lboMask]
5883
5884        mov    [rdi + 32 ], rax
5885
5886
5887        
5888        
5889
5890        ; Compare with q
5891
5892        mov rax, [rdi + 32]
5893        cmp rax, [q + 24]
5894        jc tmp_95        ; q is bigget so done.
5895        jnz tmp_94         ; q is lower
5896
5897        mov rax, [rdi + 24]
5898        cmp rax, [q + 16]
5899        jc tmp_95        ; q is bigget so done.
5900        jnz tmp_94         ; q is lower
5901
5902        mov rax, [rdi + 16]
5903        cmp rax, [q + 8]
5904        jc tmp_95        ; q is bigget so done.
5905        jnz tmp_94         ; q is lower
5906
5907        mov rax, [rdi + 8]
5908        cmp rax, [q + 0]
5909        jc tmp_95        ; q is bigget so done.
5910        jnz tmp_94         ; q is lower
5911
5912        ; If equal substract q
5913tmp_94:
5914
5915        mov rax, [q + 0]
5916        sub [rdi + 8], rax
5917
5918        mov rax, [q + 8]
5919        sbb [rdi + 16], rax
5920
5921        mov rax, [q + 16]
5922        sbb [rdi + 24], rax
5923
5924        mov rax, [q + 24]
5925        sbb [rdi + 32], rax
5926
5927tmp_95:
5928
5929        ret
5930
5931tmp_93:
5932        push  rdi
5933        push  rdx
5934        mov   rdi, rsi
5935        movsx rsi, r8d
5936        call  rawCopyS2L
5937        mov   rsi, rdi
5938        pop   rdx
5939        pop   rdi
5940        mov r11b, 0x80
5941        shl r11d, 24
5942        mov [rdi+4], r11d
5943
5944
5945        mov rax, [rsi + 8]
5946        xor rax, [rdx + 8]
5947
5948        mov    [rdi + 8 ], rax
5949
5950        mov rax, [rsi + 16]
5951        xor rax, [rdx + 16]
5952
5953        mov    [rdi + 16 ], rax
5954
5955        mov rax, [rsi + 24]
5956        xor rax, [rdx + 24]
5957
5958        mov    [rdi + 24 ], rax
5959
5960        mov rax, [rsi + 32]
5961        xor rax, [rdx + 32]
5962
5963        and    rax, [lboMask]
5964
5965        mov    [rdi + 32 ], rax
5966
5967
5968        
5969        
5970
5971        ; Compare with q
5972
5973        mov rax, [rdi + 32]
5974        cmp rax, [q + 24]
5975        jc tmp_97        ; q is bigget so done.
5976        jnz tmp_96         ; q is lower
5977
5978        mov rax, [rdi + 24]
5979        cmp rax, [q + 16]
5980        jc tmp_97        ; q is bigget so done.
5981        jnz tmp_96         ; q is lower
5982
5983        mov rax, [rdi + 16]
5984        cmp rax, [q + 8]
5985        jc tmp_97        ; q is bigget so done.
5986        jnz tmp_96         ; q is lower
5987
5988        mov rax, [rdi + 8]
5989        cmp rax, [q + 0]
5990        jc tmp_97        ; q is bigget so done.
5991        jnz tmp_96         ; q is lower
5992
5993        ; If equal substract q
5994tmp_96:
5995
5996        mov rax, [q + 0]
5997        sub [rdi + 8], rax
5998
5999        mov rax, [q + 8]
6000        sbb [rdi + 16], rax
6001
6002        mov rax, [q + 16]
6003        sbb [rdi + 24], rax
6004
6005        mov rax, [q + 24]
6006        sbb [rdi + 32], rax
6007
6008tmp_97:
6009
6010        ret
6011
6012
6013
6014
6015
6016xor_l1l2:
6017        bt     r8, 62          ; check if montgomery first
6018        jc     xor_l1ml2
6019        bt     r9, 62          ; check if montgomery first
6020        jc     xor_l1nl2m
6021xor_l1nl2n:
6022        mov r11b, 0x80
6023        shl r11d, 24
6024        mov [rdi+4], r11d
6025
6026
6027        mov rax, [rsi + 8]
6028        xor rax, [rdx + 8]
6029
6030        mov    [rdi + 8 ], rax
6031
6032        mov rax, [rsi + 16]
6033        xor rax, [rdx + 16]
6034
6035        mov    [rdi + 16 ], rax
6036
6037        mov rax, [rsi + 24]
6038        xor rax, [rdx + 24]
6039
6040        mov    [rdi + 24 ], rax
6041
6042        mov rax, [rsi + 32]
6043        xor rax, [rdx + 32]
6044
6045        and    rax, [lboMask]
6046
6047        mov    [rdi + 32 ], rax
6048
6049
6050        
6051        
6052
6053        ; Compare with q
6054
6055        mov rax, [rdi + 32]
6056        cmp rax, [q + 24]
6057        jc tmp_99        ; q is bigget so done.
6058        jnz tmp_98         ; q is lower
6059
6060        mov rax, [rdi + 24]
6061        cmp rax, [q + 16]
6062        jc tmp_99        ; q is bigget so done.
6063        jnz tmp_98         ; q is lower
6064
6065        mov rax, [rdi + 16]
6066        cmp rax, [q + 8]
6067        jc tmp_99        ; q is bigget so done.
6068        jnz tmp_98         ; q is lower
6069
6070        mov rax, [rdi + 8]
6071        cmp rax, [q + 0]
6072        jc tmp_99        ; q is bigget so done.
6073        jnz tmp_98         ; q is lower
6074
6075        ; If equal substract q
6076tmp_98:
6077
6078        mov rax, [q + 0]
6079        sub [rdi + 8], rax
6080
6081        mov rax, [q + 8]
6082        sbb [rdi + 16], rax
6083
6084        mov rax, [q + 16]
6085        sbb [rdi + 24], rax
6086
6087        mov rax, [q + 24]
6088        sbb [rdi + 32], rax
6089
6090tmp_99:
6091
6092        ret
6093
6094
6095xor_l1nl2m:
6096        mov r11b, 0x80
6097        shl r11d, 24
6098        mov [rdi+4], r11d
6099        push rdi
6100        mov  rdi, rdx
6101        call Fr_toNormal
6102        mov  rdx, rdi
6103        pop  rdi
6104
6105
6106        mov rax, [rsi + 8]
6107        xor rax, [rdx + 8]
6108
6109        mov    [rdi + 8 ], rax
6110
6111        mov rax, [rsi + 16]
6112        xor rax, [rdx + 16]
6113
6114        mov    [rdi + 16 ], rax
6115
6116        mov rax, [rsi + 24]
6117        xor rax, [rdx + 24]
6118
6119        mov    [rdi + 24 ], rax
6120
6121        mov rax, [rsi + 32]
6122        xor rax, [rdx + 32]
6123
6124        and    rax, [lboMask]
6125
6126        mov    [rdi + 32 ], rax
6127
6128
6129        
6130        
6131
6132        ; Compare with q
6133
6134        mov rax, [rdi + 32]
6135        cmp rax, [q + 24]
6136        jc tmp_101        ; q is bigget so done.
6137        jnz tmp_100         ; q is lower
6138
6139        mov rax, [rdi + 24]
6140        cmp rax, [q + 16]
6141        jc tmp_101        ; q is bigget so done.
6142        jnz tmp_100         ; q is lower
6143
6144        mov rax, [rdi + 16]
6145        cmp rax, [q + 8]
6146        jc tmp_101        ; q is bigget so done.
6147        jnz tmp_100         ; q is lower
6148
6149        mov rax, [rdi + 8]
6150        cmp rax, [q + 0]
6151        jc tmp_101        ; q is bigget so done.
6152        jnz tmp_100         ; q is lower
6153
6154        ; If equal substract q
6155tmp_100:
6156
6157        mov rax, [q + 0]
6158        sub [rdi + 8], rax
6159
6160        mov rax, [q + 8]
6161        sbb [rdi + 16], rax
6162
6163        mov rax, [q + 16]
6164        sbb [rdi + 24], rax
6165
6166        mov rax, [q + 24]
6167        sbb [rdi + 32], rax
6168
6169tmp_101:
6170
6171        ret
6172
6173
6174xor_l1ml2:
6175        bt     r9, 62          ; check if montgomery first
6176        jc     xor_l1ml2m
6177xor_l1ml2n:
6178        mov r11b, 0x80
6179        shl r11d, 24
6180        mov [rdi+4], r11d
6181        push rdi
6182        mov  rdi, rsi
6183        mov  rsi, rdx
6184        call Fr_toNormal
6185        mov  rdx, rsi
6186        mov  rsi, rdi
6187        pop  rdi
6188
6189
6190        mov rax, [rsi + 8]
6191        xor rax, [rdx + 8]
6192
6193        mov    [rdi + 8 ], rax
6194
6195        mov rax, [rsi + 16]
6196        xor rax, [rdx + 16]
6197
6198        mov    [rdi + 16 ], rax
6199
6200        mov rax, [rsi + 24]
6201        xor rax, [rdx + 24]
6202
6203        mov    [rdi + 24 ], rax
6204
6205        mov rax, [rsi + 32]
6206        xor rax, [rdx + 32]
6207
6208        and    rax, [lboMask]
6209
6210        mov    [rdi + 32 ], rax
6211
6212
6213        
6214        
6215
6216        ; Compare with q
6217
6218        mov rax, [rdi + 32]
6219        cmp rax, [q + 24]
6220        jc tmp_103        ; q is bigget so done.
6221        jnz tmp_102         ; q is lower
6222
6223        mov rax, [rdi + 24]
6224        cmp rax, [q + 16]
6225        jc tmp_103        ; q is bigget so done.
6226        jnz tmp_102         ; q is lower
6227
6228        mov rax, [rdi + 16]
6229        cmp rax, [q + 8]
6230        jc tmp_103        ; q is bigget so done.
6231        jnz tmp_102         ; q is lower
6232
6233        mov rax, [rdi + 8]
6234        cmp rax, [q + 0]
6235        jc tmp_103        ; q is bigget so done.
6236        jnz tmp_102         ; q is lower
6237
6238        ; If equal substract q
6239tmp_102:
6240
6241        mov rax, [q + 0]
6242        sub [rdi + 8], rax
6243
6244        mov rax, [q + 8]
6245        sbb [rdi + 16], rax
6246
6247        mov rax, [q + 16]
6248        sbb [rdi + 24], rax
6249
6250        mov rax, [q + 24]
6251        sbb [rdi + 32], rax
6252
6253tmp_103:
6254
6255        ret
6256
6257
6258xor_l1ml2m:
6259        mov r11b, 0x80
6260        shl r11d, 24
6261        mov [rdi+4], r11d
6262        push rdi
6263        mov  rdi, rsi
6264        mov  rsi, rdx
6265        call Fr_toNormal
6266        mov  rdx, rsi
6267        mov  rsi, rdi
6268        pop  rdi
6269        push rdi
6270        mov  rdi, rdx
6271        call Fr_toNormal
6272        mov  rdx, rdi
6273        pop  rdi
6274
6275
6276        mov rax, [rsi + 8]
6277        xor rax, [rdx + 8]
6278
6279        mov    [rdi + 8 ], rax
6280
6281        mov rax, [rsi + 16]
6282        xor rax, [rdx + 16]
6283
6284        mov    [rdi + 16 ], rax
6285
6286        mov rax, [rsi + 24]
6287        xor rax, [rdx + 24]
6288
6289        mov    [rdi + 24 ], rax
6290
6291        mov rax, [rsi + 32]
6292        xor rax, [rdx + 32]
6293
6294        and    rax, [lboMask]
6295
6296        mov    [rdi + 32 ], rax
6297
6298
6299        
6300        
6301
6302        ; Compare with q
6303
6304        mov rax, [rdi + 32]
6305        cmp rax, [q + 24]
6306        jc tmp_105        ; q is bigget so done.
6307        jnz tmp_104         ; q is lower
6308
6309        mov rax, [rdi + 24]
6310        cmp rax, [q + 16]
6311        jc tmp_105        ; q is bigget so done.
6312        jnz tmp_104         ; q is lower
6313
6314        mov rax, [rdi + 16]
6315        cmp rax, [q + 8]
6316        jc tmp_105        ; q is bigget so done.
6317        jnz tmp_104         ; q is lower
6318
6319        mov rax, [rdi + 8]
6320        cmp rax, [q + 0]
6321        jc tmp_105        ; q is bigget so done.
6322        jnz tmp_104         ; q is lower
6323
6324        ; If equal substract q
6325tmp_104:
6326
6327        mov rax, [q + 0]
6328        sub [rdi + 8], rax
6329
6330        mov rax, [q + 8]
6331        sbb [rdi + 16], rax
6332
6333        mov rax, [q + 16]
6334        sbb [rdi + 24], rax
6335
6336        mov rax, [q + 24]
6337        sbb [rdi + 32], rax
6338
6339tmp_105:
6340
6341        ret
6342
6343
6344
6345
6346;;;;;;;;;;;;;;;;;;;;;;
6347; bnot
6348;;;;;;;;;;;;;;;;;;;;;;
6349; Adds two elements of any kind
6350; Params:
6351;   rsi <= Pointer to element 1
6352;   rdi <= Pointer to result
6353; Modified Registers:
6354;    r8, r9, 10, r11, rax, rcx
6355;;;;;;;;;;;;;;;;;;;;;;
6356Fr_bnot:
6357                mov r11b, 0x80
6358        shl r11d, 24
6359        mov [rdi+4], r11d
6360
6361        mov     r8, [rsi]
6362        bt      r8, 63          ; Check if is long operand
6363        jc      bnot_l1
6364bnot_s:
6365                push  rdi
6366        push  rdx
6367        mov   rdi, rsi
6368        movsx rsi, r8d
6369        call  rawCopyS2L
6370        mov   rsi, rdi
6371        pop   rdx
6372        pop   rdi
6373        jmp     bnot_l1n
6374
6375bnot_l1:
6376        bt     r8, 62          ; check if montgomery first
6377        jnc    bnot_l1n
6378
6379bnot_l1m:
6380        push rdi
6381        mov  rdi, rsi
6382        mov  rsi, rdx
6383        call Fr_toNormal
6384        mov  rdx, rsi
6385        mov  rsi, rdi
6386        pop  rdi
6387
6388bnot_l1n:
6389
6390        mov    rax, [rsi + 8]
6391        not    rax
6392
6393        mov    [rdi + 8], rax
6394
6395        mov    rax, [rsi + 16]
6396        not    rax
6397
6398        mov    [rdi + 16], rax
6399
6400        mov    rax, [rsi + 24]
6401        not    rax
6402
6403        mov    [rdi + 24], rax
6404
6405        mov    rax, [rsi + 32]
6406        not    rax
6407
6408        and    rax, [lboMask]
6409
6410        mov    [rdi + 32], rax
6411
6412
6413        
6414        
6415
6416        ; Compare with q
6417
6418        mov rax, [rdi + 32]
6419        cmp rax, [q + 24]
6420        jc tmp_107        ; q is bigget so done.
6421        jnz tmp_106         ; q is lower
6422
6423        mov rax, [rdi + 24]
6424        cmp rax, [q + 16]
6425        jc tmp_107        ; q is bigget so done.
6426        jnz tmp_106         ; q is lower
6427
6428        mov rax, [rdi + 16]
6429        cmp rax, [q + 8]
6430        jc tmp_107        ; q is bigget so done.
6431        jnz tmp_106         ; q is lower
6432
6433        mov rax, [rdi + 8]
6434        cmp rax, [q + 0]
6435        jc tmp_107        ; q is bigget so done.
6436        jnz tmp_106         ; q is lower
6437
6438        ; If equal substract q
6439tmp_106:
6440
6441        mov rax, [q + 0]
6442        sub [rdi + 8], rax
6443
6444        mov rax, [q + 8]
6445        sbb [rdi + 16], rax
6446
6447        mov rax, [q + 16]
6448        sbb [rdi + 24], rax
6449
6450        mov rax, [q + 24]
6451        sbb [rdi + 32], rax
6452
6453tmp_107:
6454
6455        ret
6456
6457
6458
6459
6460
6461
6462;;;;;;;;;;;;;;;;;;;;;;
6463; rgt - Raw Greater Than
6464;;;;;;;;;;;;;;;;;;;;;;
6465; returns in ax 1 id *rsi > *rdx
6466; Params:
6467;   rsi <= Pointer to element 1
6468;   rdx <= Pointer to element 2
6469;   rax <= Return 1 or 0
6470; Modified Registers:
6471;    r8, r9, rax
6472;;;;;;;;;;;;;;;;;;;;;;
6473Fr_rgt:
6474        mov    r8, [rsi]
6475        mov    r9, [rdx]
6476        bt     r8, 63          ; Check if is short first operand
6477        jc     rgt_l1
6478        bt     r9, 63          ; Check if is short second operand
6479        jc     rgt_s1l2
6480
6481rgt_s1s2:                       ; Both operands are short
6482        cmp    r8d, r9d
6483        jg     rgt_ret1
6484        jmp    rgt_ret0
6485
6486
6487rgt_l1:
6488        bt     r9, 63          ; Check if is short second operand
6489        jc     rgt_l1l2
6490
6491;;;;;;;;
6492rgt_l1s2:
6493        bt     r8, 62          ; check if montgomery first
6494        jc     rgt_l1ms2
6495rgt_l1ns2:
6496        push  rdi
6497        push   rsi
6498        mov   rdi, rdx
6499        movsx rsi, r9d
6500        call  rawCopyS2L
6501        mov   rdx, rdi
6502        pop   rsi
6503        pop   rdi
6504        jmp rgtL1L2
6505
6506rgt_l1ms2:
6507        push  rdi
6508        push   rsi
6509        mov   rdi, rdx
6510        movsx rsi, r9d
6511        call  rawCopyS2L
6512        mov   rdx, rdi
6513        pop   rsi
6514        pop   rdi
6515        push rdi
6516        mov  rdi, rsi
6517        mov  rsi, rdx
6518        call Fr_toNormal
6519        mov  rdx, rsi
6520        mov  rsi, rdi
6521        pop  rdi
6522        jmp rgtL1L2
6523
6524
6525;;;;;;;;
6526rgt_s1l2:
6527        bt     r9, 62          ; check if montgomery second
6528        jc     rgt_s1l2m
6529rgt_s1l2n:
6530        push  rdi
6531        push  rdx
6532        mov   rdi, rsi
6533        movsx rsi, r8d
6534        call  rawCopyS2L
6535        mov   rsi, rdi
6536        pop   rdx
6537        pop   rdi
6538        jmp rgtL1L2
6539
6540rgt_s1l2m:
6541        push  rdi
6542        push  rdx
6543        mov   rdi, rsi
6544        movsx rsi, r8d
6545        call  rawCopyS2L
6546        mov   rsi, rdi
6547        pop   rdx
6548        pop   rdi
6549        push rdi
6550        mov  rdi, rdx
6551        call Fr_toNormal
6552        mov  rdx, rdi
6553        pop  rdi
6554        jmp rgtL1L2
6555
6556;;;;
6557rgt_l1l2:
6558        bt     r8, 62          ; check if montgomery first
6559        jc     rgt_l1ml2
6560rgt_l1nl2:
6561        bt     r9, 62          ; check if montgomery second
6562        jc     rgt_l1nl2m
6563rgt_l1nl2n:
6564        jmp rgtL1L2
6565
6566rgt_l1nl2m:
6567        push rdi
6568        mov  rdi, rdx
6569        call Fr_toNormal
6570        mov  rdx, rdi
6571        pop  rdi
6572        jmp rgtL1L2
6573
6574rgt_l1ml2:
6575        bt     r9, 62          ; check if montgomery second
6576        jc     rgt_l1ml2m
6577rgt_l1ml2n:
6578        push rdi
6579        mov  rdi, rsi
6580        mov  rsi, rdx
6581        call Fr_toNormal
6582        mov  rdx, rsi
6583        mov  rsi, rdi
6584        pop  rdi
6585        jmp rgtL1L2
6586
6587rgt_l1ml2m:
6588        push rdi
6589        mov  rdi, rsi
6590        mov  rsi, rdx
6591        call Fr_toNormal
6592        mov  rdx, rsi
6593        mov  rsi, rdi
6594        pop  rdi
6595        push rdi
6596        mov  rdi, rdx
6597        call Fr_toNormal
6598        mov  rdx, rdi
6599        pop  rdi
6600        jmp rgtL1L2
6601
6602
6603;;;;;;
6604; rgtL1L2
6605;;;;;;
6606
6607rgtL1L2:
6608
6609
6610        mov     rax, [rsi + 32]
6611        cmp     [half + 24], rax     ; comare with (q-1)/2
6612        jc rgtl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
6613
6614        jnz rgtl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
6615
6616
6617        mov     rax, [rsi + 24]
6618        cmp     [half + 16], rax     ; comare with (q-1)/2
6619        jc rgtl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
6620
6621        jnz rgtl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
6622
6623
6624        mov     rax, [rsi + 16]
6625        cmp     [half + 8], rax     ; comare with (q-1)/2
6626        jc rgtl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
6627
6628        jnz rgtl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
6629
6630
6631        mov     rax, [rsi + 8]
6632        cmp     [half + 0], rax     ; comare with (q-1)/2
6633        jc rgtl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
6634
6635        jmp rgtl1l2_p1
6636
6637
6638
6639rgtl1l2_p1:
6640
6641
6642        mov     rax, [rdx + 32]
6643        cmp     [half + 24], rax     ; comare with (q-1)/2
6644        jc rgt_ret1                           ; half<rax => e1-e2 is neg => e1 < e2
6645
6646        jnz rgtRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
6647
6648
6649        mov     rax, [rdx + 24]
6650        cmp     [half + 16], rax     ; comare with (q-1)/2
6651        jc rgt_ret1                           ; half<rax => e1-e2 is neg => e1 < e2
6652
6653        jnz rgtRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
6654
6655
6656        mov     rax, [rdx + 16]
6657        cmp     [half + 8], rax     ; comare with (q-1)/2
6658        jc rgt_ret1                           ; half<rax => e1-e2 is neg => e1 < e2
6659
6660        jnz rgtRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
6661
6662
6663        mov     rax, [rdx + 8]
6664        cmp     [half + 0], rax     ; comare with (q-1)/2
6665        jc rgt_ret1                           ; half<rax => e1-e2 is neg => e1 < e2
6666
6667        jmp rgtRawL1L2
6668
6669
6670
6671
6672rgtl1l2_n1:
6673
6674
6675        mov     rax, [rdx + 32]
6676        cmp     [half + 24], rax     ; comare with (q-1)/2
6677        jc rgtRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
6678
6679        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
6680
6681
6682        mov     rax, [rdx + 24]
6683        cmp     [half + 16], rax     ; comare with (q-1)/2
6684        jc rgtRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
6685
6686        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
6687
6688
6689        mov     rax, [rdx + 16]
6690        cmp     [half + 8], rax     ; comare with (q-1)/2
6691        jc rgtRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
6692
6693        jnz rgt_ret0                       ; half>rax => e1 -e2 is pos => e1 > e2
6694
6695
6696        mov     rax, [rdx + 8]
6697        cmp     [half + 0], rax     ; comare with (q-1)/2
6698        jc rgtRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
6699
6700        jmp rgt_ret0
6701
6702
6703
6704
6705
6706rgtRawL1L2:
6707
6708        mov     rax, [rsi + 32]
6709        cmp     [rdx + 32], rax     ; comare with (q-1)/2
6710        jc rgt_ret1                      ; rsi<rdx => 1st > 2nd
6711
6712        jnz rgt_ret0
6713
6714
6715        mov     rax, [rsi + 24]
6716        cmp     [rdx + 24], rax     ; comare with (q-1)/2
6717        jc rgt_ret1                      ; rsi<rdx => 1st > 2nd
6718
6719        jnz rgt_ret0
6720
6721
6722        mov     rax, [rsi + 16]
6723        cmp     [rdx + 16], rax     ; comare with (q-1)/2
6724        jc rgt_ret1                      ; rsi<rdx => 1st > 2nd
6725
6726        jnz rgt_ret0
6727
6728
6729        mov     rax, [rsi + 8]
6730        cmp     [rdx + 8], rax     ; comare with (q-1)/2
6731        jc rgt_ret1                      ; rsi<rdx => 1st > 2nd
6732
6733
6734
6735rgt_ret0:
6736        xor    rax, rax
6737        ret
6738rgt_ret1:
6739        mov    rax, 1
6740        ret
6741
6742
6743
6744;;;;;;;;;;;;;;;;;;;;;;
6745; rlt - Raw Less Than
6746;;;;;;;;;;;;;;;;;;;;;;
6747; returns in ax 1 id *rsi > *rdx
6748; Params:
6749;   rsi <= Pointer to element 1
6750;   rdx <= Pointer to element 2
6751;   rax <= Return 1 or 0
6752; Modified Registers:
6753;    r8, r9, rax
6754;;;;;;;;;;;;;;;;;;;;;;
6755Fr_rlt:
6756        mov    r8, [rsi]
6757        mov    r9, [rdx]
6758        bt     r8, 63          ; Check if is short first operand
6759        jc     rlt_l1
6760        bt     r9, 63          ; Check if is short second operand
6761        jc     rlt_s1l2
6762
6763rlt_s1s2:                       ; Both operands are short
6764        cmp    r8d, r9d
6765        jl     rlt_ret1
6766        jmp    rlt_ret0
6767
6768
6769rlt_l1:
6770        bt     r9, 63          ; Check if is short second operand
6771        jc     rlt_l1l2
6772
6773;;;;;;;;
6774rlt_l1s2:
6775        bt     r8, 62          ; check if montgomery first
6776        jc     rlt_l1ms2
6777rlt_l1ns2:
6778        push  rdi
6779        push   rsi
6780        mov   rdi, rdx
6781        movsx rsi, r9d
6782        call  rawCopyS2L
6783        mov   rdx, rdi
6784        pop   rsi
6785        pop   rdi
6786        jmp rltL1L2
6787
6788rlt_l1ms2:
6789        push  rdi
6790        push   rsi
6791        mov   rdi, rdx
6792        movsx rsi, r9d
6793        call  rawCopyS2L
6794        mov   rdx, rdi
6795        pop   rsi
6796        pop   rdi
6797        push rdi
6798        mov  rdi, rsi
6799        mov  rsi, rdx
6800        call Fr_toNormal
6801        mov  rdx, rsi
6802        mov  rsi, rdi
6803        pop  rdi
6804        jmp rltL1L2
6805
6806
6807;;;;;;;;
6808rlt_s1l2:
6809        bt     r9, 62          ; check if montgomery second
6810        jc     rlt_s1l2m
6811rlt_s1l2n:
6812        push  rdi
6813        push  rdx
6814        mov   rdi, rsi
6815        movsx rsi, r8d
6816        call  rawCopyS2L
6817        mov   rsi, rdi
6818        pop   rdx
6819        pop   rdi
6820        jmp rltL1L2
6821
6822rlt_s1l2m:
6823        push  rdi
6824        push  rdx
6825        mov   rdi, rsi
6826        movsx rsi, r8d
6827        call  rawCopyS2L
6828        mov   rsi, rdi
6829        pop   rdx
6830        pop   rdi
6831        push rdi
6832        mov  rdi, rdx
6833        call Fr_toNormal
6834        mov  rdx, rdi
6835        pop  rdi
6836        jmp rltL1L2
6837
6838;;;;
6839rlt_l1l2:
6840        bt     r8, 62          ; check if montgomery first
6841        jc     rlt_l1ml2
6842rlt_l1nl2:
6843        bt     r9, 62          ; check if montgomery second
6844        jc     rlt_l1nl2m
6845rlt_l1nl2n:
6846        jmp rltL1L2
6847
6848rlt_l1nl2m:
6849        push rdi
6850        mov  rdi, rdx
6851        call Fr_toNormal
6852        mov  rdx, rdi
6853        pop  rdi
6854        jmp rltL1L2
6855
6856rlt_l1ml2:
6857        bt     r9, 62          ; check if montgomery second
6858        jc     rlt_l1ml2m
6859rlt_l1ml2n:
6860        push rdi
6861        mov  rdi, rsi
6862        mov  rsi, rdx
6863        call Fr_toNormal
6864        mov  rdx, rsi
6865        mov  rsi, rdi
6866        pop  rdi
6867        jmp rltL1L2
6868
6869rlt_l1ml2m:
6870        push rdi
6871        mov  rdi, rsi
6872        mov  rsi, rdx
6873        call Fr_toNormal
6874        mov  rdx, rsi
6875        mov  rsi, rdi
6876        pop  rdi
6877        push rdi
6878        mov  rdi, rdx
6879        call Fr_toNormal
6880        mov  rdx, rdi
6881        pop  rdi
6882        jmp rltL1L2
6883
6884
6885;;;;;;
6886; rltL1L2
6887;;;;;;
6888
6889rltL1L2:
6890
6891
6892        mov     rax, [rsi + 32]
6893        cmp     [half + 24], rax     ; comare with (q-1)/2
6894        jc rltl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
6895
6896        jnz rltl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
6897
6898
6899        mov     rax, [rsi + 24]
6900        cmp     [half + 16], rax     ; comare with (q-1)/2
6901        jc rltl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
6902
6903        jnz rltl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
6904
6905
6906        mov     rax, [rsi + 16]
6907        cmp     [half + 8], rax     ; comare with (q-1)/2
6908        jc rltl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
6909
6910        jnz rltl1l2_p1                       ; half>rax => e1 -e2 is pos => e1 > e2
6911
6912
6913        mov     rax, [rsi + 8]
6914        cmp     [half + 0], rax     ; comare with (q-1)/2
6915        jc rltl1l2_n1                           ; half<rax => e1-e2 is neg => e1 < e2
6916
6917        jmp rltl1l2_p1
6918
6919
6920
6921rltl1l2_p1:
6922
6923
6924        mov     rax, [rdx + 32]
6925        cmp     [half + 24], rax     ; comare with (q-1)/2
6926        jc rlt_ret0                           ; half<rax => e1-e2 is neg => e1 < e2
6927
6928        jnz rltRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
6929
6930
6931        mov     rax, [rdx + 24]
6932        cmp     [half + 16], rax     ; comare with (q-1)/2
6933        jc rlt_ret0                           ; half<rax => e1-e2 is neg => e1 < e2
6934
6935        jnz rltRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
6936
6937
6938        mov     rax, [rdx + 16]
6939        cmp     [half + 8], rax     ; comare with (q-1)/2
6940        jc rlt_ret0                           ; half<rax => e1-e2 is neg => e1 < e2
6941
6942        jnz rltRawL1L2                       ; half>rax => e1 -e2 is pos => e1 > e2
6943
6944
6945        mov     rax, [rdx + 8]
6946        cmp     [half + 0], rax     ; comare with (q-1)/2
6947        jc rlt_ret0                           ; half<rax => e1-e2 is neg => e1 < e2
6948
6949        jmp rltRawL1L2
6950
6951
6952
6953
6954rltl1l2_n1:
6955
6956
6957        mov     rax, [rdx + 32]
6958        cmp     [half + 24], rax     ; comare with (q-1)/2
6959        jc rltRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
6960
6961        jnz rlt_ret1                       ; half>rax => e1 -e2 is pos => e1 > e2
6962
6963
6964        mov     rax, [rdx + 24]
6965        cmp     [half + 16], rax     ; comare with (q-1)/2
6966        jc rltRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
6967
6968        jnz rlt_ret1                       ; half>rax => e1 -e2 is pos => e1 > e2
6969
6970
6971        mov     rax, [rdx + 16]
6972        cmp     [half + 8], rax     ; comare with (q-1)/2
6973        jc rltRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
6974
6975        jnz rlt_ret1                       ; half>rax => e1 -e2 is pos => e1 > e2
6976
6977
6978        mov     rax, [rdx + 8]
6979        cmp     [half + 0], rax     ; comare with (q-1)/2
6980        jc rltRawL1L2                           ; half<rax => e1-e2 is neg => e1 < e2
6981
6982        jmp rlt_ret1
6983
6984
6985
6986
6987
6988rltRawL1L2:
6989
6990        mov     rax, [rsi + 32]
6991        cmp     [rdx + 32], rax     ; comare with (q-1)/2
6992        jc rlt_ret0                      ; rsi<rdx => 1st > 2nd
6993        jnz rlt_ret1
6994
6995        mov     rax, [rsi + 24]
6996        cmp     [rdx + 24], rax     ; comare with (q-1)/2
6997        jc rlt_ret0                      ; rsi<rdx => 1st > 2nd
6998        jnz rlt_ret1
6999
7000        mov     rax, [rsi + 16]
7001        cmp     [rdx + 16], rax     ; comare with (q-1)/2
7002        jc rlt_ret0                      ; rsi<rdx => 1st > 2nd
7003        jnz rlt_ret1
7004
7005        mov     rax, [rsi + 8]
7006        cmp     [rdx + 8], rax     ; comare with (q-1)/2
7007        jc rlt_ret0                      ; rsi<rdx => 1st > 2nd
7008        jnz rlt_ret1
7009
7010
7011rlt_ret0:
7012        xor    rax, rax
7013        ret
7014rlt_ret1:
7015        mov    rax, 1
7016        ret
7017
7018
7019
7020;;;;;;;;;;;;;;;;;;;;;;
7021; req - Raw Eq
7022;;;;;;;;;;;;;;;;;;;;;;
7023; returns in ax 1 id *rsi == *rdx
7024; Params:
7025;   rsi <= Pointer to element 1
7026;   rdx <= Pointer to element 2
7027;   rax <= Return 1 or 0
7028; Modified Registers:
7029;    r8, r9, rax
7030;;;;;;;;;;;;;;;;;;;;;;
7031Fr_req:
7032        mov    r8, [rsi]
7033        mov    r9, [rdx]
7034        bt     r8, 63          ; Check if is short first operand
7035        jc     req_l1
7036        bt     r9, 63          ; Check if is short second operand
7037        jc     req_s1l2
7038
7039req_s1s2:                       ; Both operands are short
7040        cmp    r8d, r9d
7041        je     req_ret1
7042        jmp    req_ret0
7043
7044
7045req_l1:
7046        bt     r9, 63          ; Check if is short second operand
7047        jc     req_l1l2
7048
7049;;;;;;;;
7050req_l1s2:
7051        bt     r8, 62          ; check if montgomery first
7052        jc     req_l1ms2
7053req_l1ns2:
7054        push  rdi
7055        push   rsi
7056        mov   rdi, rdx
7057        movsx rsi, r9d
7058        call  rawCopyS2L
7059        mov   rdx, rdi
7060        pop   rsi
7061        pop   rdi
7062        jmp reqL1L2
7063
7064req_l1ms2:
7065        push rdi
7066        mov  rdi, rdx
7067        call Fr_toMontgomery
7068        mov  rdx, rdi
7069        pop  rdi
7070        jmp reqL1L2
7071
7072
7073;;;;;;;;
7074req_s1l2:
7075        bt     r9, 62          ; check if montgomery second
7076        jc     req_s1l2m
7077req_s1l2n:
7078        push  rdi
7079        push  rdx
7080        mov   rdi, rsi
7081        movsx rsi, r8d
7082        call  rawCopyS2L
7083        mov   rsi, rdi
7084        pop   rdx
7085        pop   rdi
7086        jmp reqL1L2
7087
7088req_s1l2m:
7089        push rdi
7090        mov  rdi, rsi
7091        mov  rsi, rdx
7092        call Fr_toMontgomery
7093        mov  rdx, rsi
7094        mov  rsi, rdi
7095        pop  rdi
7096        jmp reqL1L2
7097
7098;;;;
7099req_l1l2:
7100        bt     r8, 62          ; check if montgomery first
7101        jc     req_l1ml2
7102req_l1nl2:
7103        bt     r9, 62          ; check if montgomery second
7104        jc     req_l1nl2m
7105req_l1nl2n:
7106        jmp reqL1L2
7107
7108req_l1nl2m:
7109        push rdi
7110        mov  rdi, rsi
7111        mov  rsi, rdx
7112        call Fr_toMontgomery
7113        mov  rdx, rsi
7114        mov  rsi, rdi
7115        pop  rdi
7116        jmp reqL1L2
7117
7118req_l1ml2:
7119        bt     r9, 62          ; check if montgomery second
7120        jc     req_l1ml2m
7121req_l1ml2n:
7122        push rdi
7123        mov  rdi, rdx
7124        call Fr_toMontgomery
7125        mov  rdx, rdi
7126        pop  rdi
7127        jmp reqL1L2
7128
7129req_l1ml2m:
7130        jmp reqL1L2
7131
7132
7133;;;;;;
7134; eqL1L2
7135;;;;;;
7136
7137reqL1L2:
7138
7139        mov     rax, [rsi + 8]
7140        cmp     [rdx + 8], rax
7141        jne     req_ret0                      ; rsi<rdi => 1st > 2nd
7142
7143        mov     rax, [rsi + 16]
7144        cmp     [rdx + 16], rax
7145        jne     req_ret0                      ; rsi<rdi => 1st > 2nd
7146
7147        mov     rax, [rsi + 24]
7148        cmp     [rdx + 24], rax
7149        jne     req_ret0                      ; rsi<rdi => 1st > 2nd
7150
7151        mov     rax, [rsi + 32]
7152        cmp     [rdx + 32], rax
7153        jne     req_ret0                      ; rsi<rdi => 1st > 2nd
7154
7155
7156req_ret1:
7157        mov    rax, 1
7158        ret
7159
7160req_ret0:
7161        xor    rax, rax
7162        ret
7163
7164
7165;;;;;;;;;;;;;;;;;;;;;;
7166; gt
7167;;;;;;;;;;;;;;;;;;;;;;
7168; Compares two elements of any kind
7169; Params:
7170;   rsi <= Pointer to element 1
7171;   rdx <= Pointer to element 2
7172;   rdi <= Pointer to result can be zero or one.
7173; Modified Registers:
7174;    rax, rcx
7175;;;;;;;;;;;;;;;;;;;;;;
7176Fr_gt:
7177        call Fr_rgt
7178        mov [rdi], rax
7179        ret
7180
7181;;;;;;;;;;;;;;;;;;;;;;
7182; lt
7183;;;;;;;;;;;;;;;;;;;;;;
7184; Compares two elements of any kind
7185; Params:
7186;   rsi <= Pointer to element 1
7187;   rdx <= Pointer to element 2
7188;   rdi <= Pointer to result can be zero or one.
7189; Modified Registers:
7190;    rax, rcx
7191;;;;;;;;;;;;;;;;;;;;;;
7192Fr_lt:
7193        call Fr_rlt
7194        mov [rdi], rax
7195        ret
7196
7197;;;;;;;;;;;;;;;;;;;;;;
7198; eq
7199;;;;;;;;;;;;;;;;;;;;;;
7200; Compares two elements of any kind
7201; Params:
7202;   rsi <= Pointer to element 1
7203;   rdx <= Pointer to element 2
7204;   rdi <= Pointer to result can be zero or one.
7205; Modified Registers:
7206;    rax, rcx
7207;;;;;;;;;;;;;;;;;;;;;;
7208Fr_eq:
7209        call Fr_req
7210        mov [rdi], rax
7211        ret
7212
7213;;;;;;;;;;;;;;;;;;;;;;
7214; neq
7215;;;;;;;;;;;;;;;;;;;;;;
7216; Compares two elements of any kind
7217; Params:
7218;   rsi <= Pointer to element 1
7219;   rdx <= Pointer to element 2
7220;   rdi <= Pointer to result can be zero or one.
7221; Modified Registers:
7222;    rax, rcx
7223;;;;;;;;;;;;;;;;;;;;;;
7224Fr_neq:
7225        call Fr_req
7226        xor rax, 1
7227        mov [rdi], rax
7228        ret
7229
7230;;;;;;;;;;;;;;;;;;;;;;
7231; geq
7232;;;;;;;;;;;;;;;;;;;;;;
7233; Compares two elements of any kind
7234; Params:
7235;   rsi <= Pointer to element 1
7236;   rdx <= Pointer to element 2
7237;   rdi <= Pointer to result can be zero or one.
7238; Modified Registers:
7239;    rax, rcx
7240;;;;;;;;;;;;;;;;;;;;;;
7241Fr_geq:
7242        call Fr_rlt
7243        xor rax, 1
7244        mov [rdi], rax
7245        ret
7246
7247;;;;;;;;;;;;;;;;;;;;;;
7248; leq
7249;;;;;;;;;;;;;;;;;;;;;;
7250; Compares two elements of any kind
7251; Params:
7252;   rsi <= Pointer to element 1
7253;   rdx <= Pointer to element 2
7254;   rdi <= Pointer to result can be zero or one.
7255; Modified Registers:
7256;    rax, rcx
7257;;;;;;;;;;;;;;;;;;;;;;
7258Fr_leq:
7259        call Fr_rgt
7260        xor rax, 1
7261        mov [rdi], rax
7262        ret
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274;;;;;;;;;;;;;;;;;;;;;;
7275; land
7276;;;;;;;;;;;;;;;;;;;;;;
7277; Logical and between two elements
7278; Params:
7279;   rsi <= Pointer to element 1
7280;   rdx <= Pointer to element 2
7281;   rdi <= Pointer to result zero or one
7282; Modified Registers:
7283;    rax, rcx, r8
7284;;;;;;;;;;;;;;;;;;;;;;
7285Fr_land:
7286
7287
7288
7289
7290
7291
7292    mov     rax, [rsi]
7293    bt      rax, 63
7294    jc      tmp_108
7295
7296    test    eax, eax
7297    jz      retZero_110
7298    jmp     retOne_109
7299
7300tmp_108:
7301
7302    mov     rax, [rsi + 8]
7303    test    rax, rax
7304    jnz     retOne_109
7305
7306    mov     rax, [rsi + 16]
7307    test    rax, rax
7308    jnz     retOne_109
7309
7310    mov     rax, [rsi + 24]
7311    test    rax, rax
7312    jnz     retOne_109
7313
7314    mov     rax, [rsi + 32]
7315    test    rax, rax
7316    jnz     retOne_109
7317
7318
7319retZero_110:
7320    mov     qword r8, 0
7321    jmp     done_111
7322
7323retOne_109:
7324    mov     qword r8, 1
7325
7326done_111:
7327
7328
7329
7330
7331
7332
7333
7334    mov     rax, [rdx]
7335    bt      rax, 63
7336    jc      tmp_112
7337
7338    test    eax, eax
7339    jz      retZero_114
7340    jmp     retOne_113
7341
7342tmp_112:
7343
7344    mov     rax, [rdx + 8]
7345    test    rax, rax
7346    jnz     retOne_113
7347
7348    mov     rax, [rdx + 16]
7349    test    rax, rax
7350    jnz     retOne_113
7351
7352    mov     rax, [rdx + 24]
7353    test    rax, rax
7354    jnz     retOne_113
7355
7356    mov     rax, [rdx + 32]
7357    test    rax, rax
7358    jnz     retOne_113
7359
7360
7361retZero_114:
7362    mov     qword rcx, 0
7363    jmp     done_115
7364
7365retOne_113:
7366    mov     qword rcx, 1
7367
7368done_115:
7369
7370        and rcx, r8
7371        mov [rdi], rcx
7372        ret
7373
7374
7375;;;;;;;;;;;;;;;;;;;;;;
7376; lor
7377;;;;;;;;;;;;;;;;;;;;;;
7378; Logical or between two elements
7379; Params:
7380;   rsi <= Pointer to element 1
7381;   rdx <= Pointer to element 2
7382;   rdi <= Pointer to result zero or one
7383; Modified Registers:
7384;    rax, rcx, r8
7385;;;;;;;;;;;;;;;;;;;;;;
7386Fr_lor:
7387
7388
7389
7390
7391
7392
7393    mov     rax, [rsi]
7394    bt      rax, 63
7395    jc      tmp_116
7396
7397    test    eax, eax
7398    jz      retZero_118
7399    jmp     retOne_117
7400
7401tmp_116:
7402
7403    mov     rax, [rsi + 8]
7404    test    rax, rax
7405    jnz     retOne_117
7406
7407    mov     rax, [rsi + 16]
7408    test    rax, rax
7409    jnz     retOne_117
7410
7411    mov     rax, [rsi + 24]
7412    test    rax, rax
7413    jnz     retOne_117
7414
7415    mov     rax, [rsi + 32]
7416    test    rax, rax
7417    jnz     retOne_117
7418
7419
7420retZero_118:
7421    mov     qword r8, 0
7422    jmp     done_119
7423
7424retOne_117:
7425    mov     qword r8, 1
7426
7427done_119:
7428
7429
7430
7431
7432
7433
7434
7435    mov     rax, [rdx]
7436    bt      rax, 63
7437    jc      tmp_120
7438
7439    test    eax, eax
7440    jz      retZero_122
7441    jmp     retOne_121
7442
7443tmp_120:
7444
7445    mov     rax, [rdx + 8]
7446    test    rax, rax
7447    jnz     retOne_121
7448
7449    mov     rax, [rdx + 16]
7450    test    rax, rax
7451    jnz     retOne_121
7452
7453    mov     rax, [rdx + 24]
7454    test    rax, rax
7455    jnz     retOne_121
7456
7457    mov     rax, [rdx + 32]
7458    test    rax, rax
7459    jnz     retOne_121
7460
7461
7462retZero_122:
7463    mov     qword rcx, 0
7464    jmp     done_123
7465
7466retOne_121:
7467    mov     qword rcx, 1
7468
7469done_123:
7470
7471        or rcx, r8
7472        mov [rdi], rcx
7473        ret
7474
7475
7476;;;;;;;;;;;;;;;;;;;;;;
7477; lnot
7478;;;;;;;;;;;;;;;;;;;;;;
7479; Do the logical not of an element
7480; Params:
7481;   rsi <= Pointer to element to be tested
7482;   rdi <= Pointer to result one if element1 is zero and zero otherwise
7483; Modified Registers:
7484;    rax, rax, r8
7485;;;;;;;;;;;;;;;;;;;;;;
7486Fr_lnot:
7487
7488
7489
7490
7491
7492
7493    mov     rax, [rsi]
7494    bt      rax, 63
7495    jc      tmp_124
7496
7497    test    eax, eax
7498    jz      retZero_126
7499    jmp     retOne_125
7500
7501tmp_124:
7502
7503    mov     rax, [rsi + 8]
7504    test    rax, rax
7505    jnz     retOne_125
7506
7507    mov     rax, [rsi + 16]
7508    test    rax, rax
7509    jnz     retOne_125
7510
7511    mov     rax, [rsi + 24]
7512    test    rax, rax
7513    jnz     retOne_125
7514
7515    mov     rax, [rsi + 32]
7516    test    rax, rax
7517    jnz     retOne_125
7518
7519
7520retZero_126:
7521    mov     qword rcx, 0
7522    jmp     done_127
7523
7524retOne_125:
7525    mov     qword rcx, 1
7526
7527done_127:
7528
7529        test rcx, rcx
7530
7531        jz lnot_retOne
7532lnot_retZero:
7533        mov qword [rdi], 0
7534        ret
7535lnot_retOne:
7536        mov qword [rdi], 1
7537        ret
7538
7539
7540;;;;;;;;;;;;;;;;;;;;;;
7541; isTrue
7542;;;;;;;;;;;;;;;;;;;;;;
7543; Convert a 64 bit integer to a long format field element
7544; Params:
7545;   rsi <= Pointer to the element
7546; Returs:
7547;   rax <= 1 if true 0 if false
7548;;;;;;;;;;;;;;;;;;;;;;;
7549Fr_isTrue:
7550        
7551
7552
7553
7554
7555
7556    mov     rax, [rdi]
7557    bt      rax, 63
7558    jc      tmp_128
7559
7560    test    eax, eax
7561    jz      retZero_130
7562    jmp     retOne_129
7563
7564tmp_128:
7565
7566    mov     rax, [rdi + 8]
7567    test    rax, rax
7568    jnz     retOne_129
7569
7570    mov     rax, [rdi + 16]
7571    test    rax, rax
7572    jnz     retOne_129
7573
7574    mov     rax, [rdi + 24]
7575    test    rax, rax
7576    jnz     retOne_129
7577
7578    mov     rax, [rdi + 32]
7579    test    rax, rax
7580    jnz     retOne_129
7581
7582
7583retZero_130:
7584    mov     qword rax, 0
7585    jmp     done_131
7586
7587retOne_129:
7588    mov     qword rax, 1
7589
7590done_131:
7591
7592        ret
7593
7594
7595
7596
7597
7598        section .data
7599Fr_q:
7600        dd      0
7601        dd      0x80000000
7602q       dq      0x43e1f593f0000001,0x2833e84879b97091,0xb85045b68181585d,0x30644e72e131a029
7603half    dq      0xa1f0fac9f8000000,0x9419f4243cdcb848,0xdc2822db40c0ac2e,0x183227397098d014
7604R2      dq      0x1bb8e645ae216da7,0x53fe3ab1e35c59e3,0x8c49833d53bb8085,0x0216d0b17f4e44a5
7605R3      dq      0x5e94d8e1b4bf0040,0x2a489cbe1cfbb6b8,0x893cc664a19fcfed,0x0cf8594b7fcc657c
7606lboMask dq      0x3fffffffffffffff
7607