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