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