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