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