2 # Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
4 # Licensed under the Apache License 2.0 (the "License"). You may not use
5 # this file except in compliance with the License. You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
9 # ====================================================================
10 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
11 # project. The module is, however, dual licensed under OpenSSL and
12 # CRYPTOGAMS licenses depending on where you obtain it. For further
13 # details see http://www.openssl.org/~appro/cryptogams/.
14 # ====================================================================
16 # X25519 lower-level primitives for x86_64.
20 # This module implements radix 2^51 multiplication and squaring, and
21 # radix 2^64 multiplication, squaring, addition, subtraction and final
22 # reduction. Latter radix is used on ADCX/ADOX-capable processors such
23 # as Broadwell. On related note one should mention that there are
24 # vector implementations that provide significantly better performance
25 # on some processors(*), but they are large and overly complex. Which
26 # in combination with them being effectively processor-specific makes
27 # the undertaking hard to justify. The goal for this implementation
28 # is rather versatility and simplicity [and ultimately formal
31 # (*) For example sandy2x should provide ~30% improvement on Sandy
32 # Bridge, but only nominal ~5% on Haswell [and big loss on
33 # Broadwell and successors].
35 ######################################################################
36 # Improvement coefficients:
38 # amd64-51(*) gcc-5.x(**)
41 # Sandy Bridge -3% +11%
43 # Broadwell(***) +30% +35%
44 # Skylake(***) +33% +47%
45 # Silvermont +20% +26%
48 # Ryzen(***) +43% +40%
51 # (*) amd64-51 is popular assembly implementation with 2^51 radix,
52 # only multiplication and squaring subroutines were linked
53 # for comparison, but not complete ladder step; gain on most
54 # processors is because this module refrains from shld, and
55 # minor regression on others is because this does result in
56 # higher instruction count;
57 # (**) compiler is free to inline functions, in assembly one would
58 # need to implement ladder step to do that, and it will improve
59 # performance by several percent;
60 # (***) ADCX/ADOX result for 2^64 radix, there is no corresponding
61 # C implementation, so that comparison is always against
64 # $output is the last argument if it looks like a file (it has an extension)
65 # $flavour is the first argument if it doesn't look like a file
66 $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m
|\
.\w
+$| ?
pop : undef;
67 $flavour = $#ARGV >= 0 && $ARGV[0] !~ m
|\
.| ?
shift : undef;
69 $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
71 $0 =~ m/(.*[\/\\])[^\
/\\]+$/; $dir=$1;
72 ( $xlate="${dir}x86_64-xlate.pl" and -f
$xlate ) or
73 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f
$xlate) or
74 die "can't locate x86_64-xlate.pl";
76 open OUT
,"| \"$^X\" \"$xlate\" $flavour \"$output\""
77 or die "can't call $xlate: $!";
80 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
81 =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
85 if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM
} =~ /nasm/) &&
86 `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) {
90 if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM
} =~ /ml64/) &&
91 `ml64 2>&1` =~ /Version ([0-9]+)\./) {
95 if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9])\.([0-9]+)/) {
96 my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10
103 .globl x25519_fe51_mul
104 .type x25519_fe51_mul
,\
@function,3
121 .cfi_adjust_cfa_offset
40
124 mov
8*0(%rsi),%rax # f[0]
125 mov
8*0(%rdx),%r11 # load g[0-4]
131 mov
%rdi,8*4(%rsp) # offload 1st argument
133 mulq
%r11 # f[0]*g[0]
134 mov
%r11,8*0(%rsp) # offload g[0]
135 mov
%rax,%rbx # %rbx:%rcx = h0
138 mulq
%r12 # f[0]*g[1]
139 mov
%r12,8*1(%rsp) # offload g[1]
140 mov
%rax,%r8 # %r8:%r9 = h1
142 lea
(%r14,%r14,8),%r15
144 mulq
%r13 # f[0]*g[2]
145 mov
%r13,8*2(%rsp) # offload g[2]
146 mov
%rax,%r10 # %r10:%r11 = h2
148 lea
(%r14,%r15,2),%rdi # g[4]*19
150 mulq
%rbp # f[0]*g[3]
151 mov
%rax,%r12 # %r12:%r13 = h3
152 mov
8*0(%rsi),%rax # f[0]
154 mulq
%r14 # f[0]*g[4]
155 mov
%rax,%r14 # %r14:%r15 = h4
156 mov
8*1(%rsi),%rax # f[1]
159 mulq
%rdi # f[1]*g[4]*19
161 mov
8*2(%rsi),%rax # f[2]
163 mulq
%rdi # f[2]*g[4]*19
165 mov
8*3(%rsi),%rax # f[3]
167 mulq
%rdi # f[3]*g[4]*19
169 mov
8*4(%rsi),%rax # f[4]
171 mulq
%rdi # f[4]*g[4]*19
172 imulq \
$19,%rbp,%rdi # g[3]*19
174 mov
8*1(%rsi),%rax # f[1]
176 mulq
%rbp # f[1]*g[3]
177 mov
8*2(%rsp),%rbp # g[2]
179 mov
8*2(%rsi),%rax # f[2]
182 mulq
%rdi # f[2]*g[3]*19
184 mov
8*3(%rsi),%rax # f[3]
186 mulq
%rdi # f[3]*g[3]*19
188 mov
8*4(%rsi),%rax # f[4]
190 mulq
%rdi # f[4]*g[3]*19
191 imulq \
$19,%rbp,%rdi # g[2]*19
193 mov
8*1(%rsi),%rax # f[1]
195 mulq
%rbp # f[1]*g[2]
197 mov
8*2(%rsi),%rax # f[2]
199 mulq
%rbp # f[2]*g[2]
200 mov
8*1(%rsp),%rbp # g[1]
202 mov
8*3(%rsi),%rax # f[3]
205 mulq
%rdi # f[3]*g[2]*19
207 mov
8*4(%rsi),%rax # f[3]
209 mulq
%rdi # f[4]*g[2]*19
211 mov
8*1(%rsi),%rax # f[1]
213 mulq
%rbp # f[1]*g[1]
216 mov
8*2(%rsi),%rax # f[2]
218 mulq
%rbp # f[2]*g[1]
220 mov
8*3(%rsi),%rax # f[3]
222 mulq
%rbp # f[3]*g[1]
223 mov
8*0(%rsp),%rbp # g[0]
225 mov
8*4(%rsi),%rax # f[4]
228 mulq
%rdi # f[4]*g[1]*19
230 mov
8*1(%rsi),%rax # f[1]
234 mov
8*2(%rsi),%rax # f[2]
238 mov
8*3(%rsi),%rax # f[3]
242 mov
8*4(%rsi),%rax # f[4]
244 mulq
%rbp # f[4]*g[0]
248 mov
8*4(%rsp),%rdi # restore 1st argument
252 .size x25519_fe51_mul
,.-x25519_fe51_mul
254 .globl x25519_fe51_sqr
255 .type x25519_fe51_sqr
,\
@function,2
272 .cfi_adjust_cfa_offset
40
275 mov
8*0(%rsi),%rax # g[0]
276 mov
8*2(%rsi),%r15 # g[2]
277 mov
8*4(%rsi),%rbp # g[4]
279 mov
%rdi,8*4(%rsp) # offload 1st argument
281 mulq
%rax # g[0]*g[0]
283 mov
8*1(%rsi),%rax # g[1]
285 mulq
%r14 # 2*g[0]*g[1]
288 mov
%r15,8*0(%rsp) # offload g[2]
290 mulq
%r14 # 2*g[0]*g[2]
294 imulq \
$19,%rbp,%rdi # g[4]*19
295 mulq
%r14 # 2*g[0]*g[3]
299 mulq
%r14 # 2*g[0]*g[4]
304 mulq
%rdi # g[4]*g[4]*19
306 mov
8*1(%rsi),%rax # g[1]
309 mov
8*3(%rsi),%rsi # g[3]
311 mulq
%rax # g[1]*g[1]
313 mov
8*0(%rsp),%rax # g[2]
315 mulq
%rbp # 2*g[1]*g[2]
319 mulq
%rsi # 2*g[1]*g[3]
323 imulq \
$19,%rsi,%rbp # g[3]*19
324 mulq
%rdi # 2*g[1]*g[4]*19
329 mulq
%rdi # 2*g[3]*g[4]*19
333 mulq
%rbp # g[3]*g[3]*19
335 mov
8*0(%rsp),%rax # g[2]
339 mulq
%rax # g[2]*g[2]
343 mulq
%rsi # 2*g[2]*g[3]*19
347 mulq
%rdi # 2*g[2]*g[4]*19
351 mov
8*4(%rsp),%rdi # restore 1st argument
356 mov \
$0x7ffffffffffff,%rbp
361 and %rbp,%rdx # %rdx = g2 = h2 & mask
362 or %r10,%r11 # h2>>51
364 adc \
$0,%r13 # h3 += h2>>51
369 and %rbp,%rax # %rax = g0 = h0 & mask
370 or %rbx,%rcx # h0>>51
371 add
%rcx,%r8 # h1 += h0>>51
377 and %rbp,%rbx # %rbx = g3 = h3 & mask
378 or %r12,%r13 # h3>>51
379 add
%r13,%r14 # h4 += h3>>51
385 and %rbp,%rcx # %rcx = g1 = h1 & mask
387 add
%r9,%rdx # g2 += h1>>51
392 and %rbp,%r10 # %r10 = g4 = h0 & mask
393 or %r14,%r15 # h0>>51
395 lea
(%r15,%r15,8),%r14
396 lea
(%r15,%r14,2),%r15
397 add
%r15,%rax # g0 += (h0>>51)*19
400 and %rbp,%rdx # g2 &= mask
402 add
%r8,%rbx # g3 += g2>>51
405 and %rbp,%rax # g0 &= mask
407 add
%r9,%rcx # g1 += g0>>51
409 mov
%rax,8*0(%rdi) # save the result
428 .cfi_adjust_cfa_offset
88
432 .size x25519_fe51_sqr
,.-x25519_fe51_sqr
434 .globl x25519_fe51_mul121666
435 .type x25519_fe51_mul121666
,\
@function,2
437 x25519_fe51_mul121666
:
452 .cfi_adjust_cfa_offset
40
453 .Lfe51_mul121666_body
:
457 mov
%rax,%rbx # %rbx:%rcx = h0
461 mov
%rax,%r8 # %r8:%r9 = h1
465 mov
%rax,%r10 # %r10:%r11 = h2
469 mov
%rax,%r12 # %r12:%r13 = h3
470 mov \
$121666,%eax # f[0]
473 mov
%rax,%r14 # %r14:%r15 = h4
477 .Lfe51_mul121666_epilogue
:
479 .size x25519_fe51_mul121666
,.-x25519_fe51_mul121666
481 ########################################################################
482 # Base 2^64 subroutines modulo 2*(2^255-19)
485 my ($acc0,$acc1,$acc2,$acc3,$acc4,$acc5,$acc6,$acc7) = map("%r$_",(8..15));
488 .extern OPENSSL_ia32cap_P
489 .globl x25519_fe64_eligible
490 .type x25519_fe64_eligible
,\
@abi-omnipotent
492 x25519_fe64_eligible
:
494 mov OPENSSL_ia32cap_P
+8(%rip),%ecx
501 .size x25519_fe64_eligible
,.-x25519_fe64_eligible
503 .globl x25519_fe64_mul
504 .type x25519_fe64_mul
,\
@function,3
520 push %rdi # offload dst
523 .cfi_adjust_cfa_offset
16
527 mov
8*0(%rdx),%rbp # b[0]
528 mov
8*0(%rsi),%rdx # a[0]
529 mov
8*1(%rax),%rcx # b[1]
530 mov
8*2(%rax),$acc6 # b[2]
531 mov
8*3(%rax),$acc7 # b[3]
533 mulx
%rbp,$acc0,%rax # a[0]*b[0]
534 xor %edi,%edi # cf=0,of=0
535 mulx
%rcx,$acc1,%rbx # a[0]*b[1]
537 mulx
$acc6,$acc2,%rax # a[0]*b[2]
539 mulx
$acc7,$acc3,$acc4 # a[0]*b[3]
540 mov
8*1(%rsi),%rdx # a[1]
542 mov
$acc6,(%rsp) # offload b[2]
543 adcx
%rdi,$acc4 # cf=0
545 mulx
%rbp,%rax,%rbx # a[1]*b[0]
548 mulx
%rcx,%rax,%rbx # a[1]*b[1]
551 mulx
$acc6,%rax,%rbx # a[1]*b[2]
554 mulx
$acc7,%rax,$acc5 # a[1]*b[3]
555 mov
8*2(%rsi),%rdx # a[2]
557 adcx
%rdi,$acc5 # cf=0
558 adox
%rdi,$acc5 # of=0
560 mulx
%rbp,%rax,%rbx # a[2]*b[0]
563 mulx
%rcx,%rax,%rbx # a[2]*b[1]
566 mulx
$acc6,%rax,%rbx # a[2]*b[2]
569 mulx
$acc7,%rax,$acc6 # a[2]*b[3]
570 mov
8*3(%rsi),%rdx # a[3]
572 adox
%rdi,$acc6 # of=0
573 adcx
%rdi,$acc6 # cf=0
575 mulx
%rbp,%rax,%rbx # a[3]*b[0]
578 mulx
%rcx,%rax,%rbx # a[3]*b[1]
581 mulx
(%rsp),%rax,%rbx # a[3]*b[2]
584 mulx
$acc7,%rax,$acc7 # a[3]*b[3]
587 adcx
%rdi,$acc7 # cf=0
588 adox
%rdi,$acc7 # of=0
593 .size x25519_fe64_mul
,.-x25519_fe64_mul
595 .globl x25519_fe64_sqr
596 .type x25519_fe64_sqr
,\
@function,2
612 push %rdi # offload dst
615 .cfi_adjust_cfa_offset
16
618 mov
8*0(%rsi),%rdx # a[0]
619 mov
8*1(%rsi),%rcx # a[1]
620 mov
8*2(%rsi),%rbp # a[2]
621 mov
8*3(%rsi),%rsi # a[3]
623 ################################################################
624 mulx
%rdx,$acc0,$acc7 # a[0]*a[0]
625 mulx
%rcx,$acc1,%rax # a[0]*a[1]
626 xor %edi,%edi # cf=0,of=0
627 mulx
%rbp,$acc2,%rbx # a[0]*a[2]
629 mulx
%rsi,$acc3,$acc4 # a[0]*a[3]
632 adcx
%rdi,$acc4 # cf=0
634 ################################################################
635 mulx
%rbp,%rax,%rbx # a[1]*a[2]
638 mulx
%rsi,%rax,$acc5 # a[1]*a[3]
643 ################################################################
644 mulx
%rsi,%rax,$acc6 # a[2]*a[3]
647 adcx
%rdi,$acc6 # cf=0
648 adox
%rdi,$acc6 # of=0
650 adcx
$acc1,$acc1 # acc1:6<<1
653 mulx
%rdx,%rax,%rbx # a[1]*a[1]
659 mulx
%rdx,%rax,%rbx # a[2]*a[2]
665 mulx
%rdx,%rax,$acc7 # a[3]*a[3]
668 adcx
%rdi,$acc7 # cf=0
669 adox
%rdi,$acc7 # of=0
683 mulx
$acc7,%rax,$acc4
688 mov
8*2(%rsp),%rdi # restore dst
696 sbb
%rax,%rax # cf -> mask
718 .cfi_adjust_cfa_offset
88
722 .size x25519_fe64_sqr
,.-x25519_fe64_sqr
724 .globl x25519_fe64_mul121666
725 .type x25519_fe64_mul121666
,\
@function,2
727 x25519_fe64_mul121666
:
728 .Lfe64_mul121666_body
:
731 mulx
8*0(%rsi),$acc0,%rcx
732 mulx
8*1(%rsi),$acc1,%rax
734 mulx
8*2(%rsi),$acc2,%rcx
736 mulx
8*3(%rsi),$acc3,%rax
747 sbb
%rax,%rax # cf -> mask
756 .Lfe64_mul121666_epilogue
:
759 .size x25519_fe64_mul121666
,.-x25519_fe64_mul121666
761 .globl x25519_fe64_add
762 .type x25519_fe64_add
,\
@function,3
777 sbb
%rax,%rax # cf -> mask
786 sbb
%rax,%rax # cf -> mask
796 .size x25519_fe64_add
,.-x25519_fe64_add
798 .globl x25519_fe64_sub
799 .type x25519_fe64_sub
,\
@function,3
814 sbb
%rax,%rax # cf -> mask
823 sbb
%rax,%rax # cf -> mask
833 .size x25519_fe64_sub
,.-x25519_fe64_sub
835 .globl x25519_fe64_tobytes
836 .type x25519_fe64_tobytes
,\
@function,2
846 ################################# reduction modulo 2^255-19
847 lea
($acc3,$acc3),%rax
848 sar \
$63,$acc3 # most significant bit -> mask
849 shr \
$1,%rax # most significant bit cleared
851 add \
$19,$acc3 # compare to modulus in the same go
858 lea
(%rax,%rax),$acc3
859 sar \
$63,%rax # most significant bit -> mask
860 shr \
$1,$acc3 # most significant bit cleared
877 .size x25519_fe64_tobytes
,.-x25519_fe64_tobytes
881 .globl x25519_fe64_eligible
882 .type x25519_fe64_eligible
,\
@abi-omnipotent
884 x25519_fe64_eligible
:
889 .size x25519_fe64_eligible
,.-x25519_fe64_eligible
891 .globl x25519_fe64_mul
892 .type x25519_fe64_mul
,\
@abi-omnipotent
893 .globl x25519_fe64_sqr
894 .globl x25519_fe64_mul121666
895 .globl x25519_fe64_add
896 .globl x25519_fe64_sub
897 .globl x25519_fe64_tobytes
900 x25519_fe64_mul121666
:
905 .byte
0x0f,0x0b # ud2
908 .size x25519_fe64_mul
,.-x25519_fe64_mul
912 .asciz
"X25519 primitives for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
915 # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
916 # CONTEXT *context,DISPATCHER_CONTEXT *disp)
924 .extern __imp_RtlVirtualUnwind
926 .type short_handler
,\
@abi-omnipotent
940 mov
120($context),%rax # pull context->Rax
941 mov
248($context),%rbx # pull context->Rip
943 mov
8($disp),%rsi # disp->ImageBase
944 mov
56($disp),%r11 # disp->HandlerData
946 mov
0(%r11),%r10d # HandlerData[0]
947 lea
(%rsi,%r10),%r10 # end of prologue label
948 cmp %r10,%rbx # context->Rip<end of prologue label
951 mov
152($context),%rax # pull context->Rsp
952 jmp
.Lcommon_seh_tail
953 .size short_handler
,.-short_handler
955 .type full_handler
,\
@abi-omnipotent
969 mov
120($context),%rax # pull context->Rax
970 mov
248($context),%rbx # pull context->Rip
972 mov
8($disp),%rsi # disp->ImageBase
973 mov
56($disp),%r11 # disp->HandlerData
975 mov
0(%r11),%r10d # HandlerData[0]
976 lea
(%rsi,%r10),%r10 # end of prologue label
977 cmp %r10,%rbx # context->Rip<end of prologue label
980 mov
152($context),%rax # pull context->Rsp
982 mov
4(%r11),%r10d # HandlerData[1]
983 lea
(%rsi,%r10),%r10 # epilogue label
984 cmp %r10,%rbx # context->Rip>=epilogue label
985 jae
.Lcommon_seh_tail
987 mov
8(%r11),%r10d # HandlerData[2]
996 mov
%rbx,144($context) # restore context->Rbx
997 mov
%rbp,160($context) # restore context->Rbp
998 mov
%r12,216($context) # restore context->R12
999 mov
%r13,224($context) # restore context->R13
1000 mov
%r14,232($context) # restore context->R14
1001 mov
%r15,240($context) # restore context->R15
1006 mov
%rax,152($context) # restore context->Rsp
1007 mov
%rsi,168($context) # restore context->Rsi
1008 mov
%rdi,176($context) # restore context->Rdi
1010 mov
40($disp),%rdi # disp->ContextRecord
1011 mov
$context,%rsi # context
1012 mov \
$154,%ecx # sizeof(CONTEXT)
1013 .long
0xa548f3fc # cld; rep movsq
1016 xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
1017 mov
8(%rsi),%rdx # arg2, disp->ImageBase
1018 mov
0(%rsi),%r8 # arg3, disp->ControlPc
1019 mov
16(%rsi),%r9 # arg4, disp->FunctionEntry
1020 mov
40(%rsi),%r10 # disp->ContextRecord
1021 lea
56(%rsi),%r11 # &disp->HandlerData
1022 lea
24(%rsi),%r12 # &disp->EstablisherFrame
1023 mov
%r10,32(%rsp) # arg5
1024 mov
%r11,40(%rsp) # arg6
1025 mov
%r12,48(%rsp) # arg7
1026 mov
%rcx,56(%rsp) # arg8, (NULL)
1027 call
*__imp_RtlVirtualUnwind
(%rip)
1029 mov \
$1,%eax # ExceptionContinueSearch
1041 .size full_handler
,.-full_handler
1045 .rva
.LSEH_begin_x25519_fe51_mul
1046 .rva
.LSEH_end_x25519_fe51_mul
1047 .rva
.LSEH_info_x25519_fe51_mul
1049 .rva
.LSEH_begin_x25519_fe51_sqr
1050 .rva
.LSEH_end_x25519_fe51_sqr
1051 .rva
.LSEH_info_x25519_fe51_sqr
1053 .rva
.LSEH_begin_x25519_fe51_mul121666
1054 .rva
.LSEH_end_x25519_fe51_mul121666
1055 .rva
.LSEH_info_x25519_fe51_mul121666
1057 $code.=<<___
if ($addx);
1058 .rva
.LSEH_begin_x25519_fe64_mul
1059 .rva
.LSEH_end_x25519_fe64_mul
1060 .rva
.LSEH_info_x25519_fe64_mul
1062 .rva
.LSEH_begin_x25519_fe64_sqr
1063 .rva
.LSEH_end_x25519_fe64_sqr
1064 .rva
.LSEH_info_x25519_fe64_sqr
1066 .rva
.LSEH_begin_x25519_fe64_mul121666
1067 .rva
.LSEH_end_x25519_fe64_mul121666
1068 .rva
.LSEH_info_x25519_fe64_mul121666
1070 .rva
.LSEH_begin_x25519_fe64_add
1071 .rva
.LSEH_end_x25519_fe64_add
1072 .rva
.LSEH_info_x25519_fe64_add
1074 .rva
.LSEH_begin_x25519_fe64_sub
1075 .rva
.LSEH_end_x25519_fe64_sub
1076 .rva
.LSEH_info_x25519_fe64_sub
1078 .rva
.LSEH_begin_x25519_fe64_tobytes
1079 .rva
.LSEH_end_x25519_fe64_tobytes
1080 .rva
.LSEH_info_x25519_fe64_tobytes
1085 .LSEH_info_x25519_fe51_mul
:
1088 .rva
.Lfe51_mul_body
,.Lfe51_mul_epilogue
# HandlerData[]
1090 .LSEH_info_x25519_fe51_sqr
:
1093 .rva
.Lfe51_sqr_body
,.Lfe51_sqr_epilogue
# HandlerData[]
1095 .LSEH_info_x25519_fe51_mul121666
:
1098 .rva
.Lfe51_mul121666_body
,.Lfe51_mul121666_epilogue
# HandlerData[]
1101 $code.=<<___
if ($addx);
1102 .LSEH_info_x25519_fe64_mul
:
1105 .rva
.Lfe64_mul_body
,.Lfe64_mul_epilogue
# HandlerData[]
1107 .LSEH_info_x25519_fe64_sqr
:
1110 .rva
.Lfe64_sqr_body
,.Lfe64_sqr_epilogue
# HandlerData[]
1112 .LSEH_info_x25519_fe64_mul121666
:
1115 .rva
.Lfe64_mul121666_body
,.Lfe64_mul121666_epilogue
# HandlerData[]
1116 .LSEH_info_x25519_fe64_add
:
1119 .rva
.Lfe64_add_body
,.Lfe64_add_epilogue
# HandlerData[]
1120 .LSEH_info_x25519_fe64_sub
:
1123 .rva
.Lfe64_sub_body
,.Lfe64_sub_epilogue
# HandlerData[]
1124 .LSEH_info_x25519_fe64_tobytes
:
1127 .rva
.Lfe64_to_body
,.Lfe64_to_epilogue
# HandlerData[]
1131 $code =~ s/\`([^\`]*)\`/eval $1/gem;