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