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