VirtualBox

source: vbox/trunk/src/libs/openssl-3.1.0/crypto/bn/asm/via-mont.pl@ 99507

最後變更 在這個檔案從99507是 99366,由 vboxsync 提交於 2 年 前

openssl-3.1.0: Applied and adjusted our OpenSSL changes to 3.0.7. bugref:10418

檔案大小: 9.1 KB
 
1#! /usr/bin/env perl
2# Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
3#
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
8
9#
10# ====================================================================
11# Written by Andy Polyakov <[email protected]> for the OpenSSL
12# project. The module is, however, dual licensed under OpenSSL and
13# CRYPTOGAMS licenses depending on where you obtain it. For further
14# details see http://www.openssl.org/~appro/cryptogams/.
15# ====================================================================
16#
17# Wrapper around 'rep montmul', VIA-specific instruction accessing
18# PadLock Montgomery Multiplier. The wrapper is designed as drop-in
19# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9].
20#
21# Below are interleaved outputs from 'openssl speed rsa dsa' for 4
22# different software configurations on 1.5GHz VIA Esther processor.
23# Lines marked with "software integer" denote performance of hand-
24# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2"
25# refers to hand-coded SSE2 Montgomery multiplication procedure found
26# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from
27# Padlock SDK 2.0.1 available for download from VIA, which naturally
28# utilizes the magic 'repz montmul' instruction. And finally "hardware
29# this" refers to *this* implementation which also uses 'repz montmul'
30#
31# sign verify sign/s verify/s
32# rsa 512 bits 0.001720s 0.000140s 581.4 7149.7 software integer
33# rsa 512 bits 0.000690s 0.000086s 1450.3 11606.0 software SSE2
34# rsa 512 bits 0.006136s 0.000201s 163.0 4974.5 hardware VIA SDK
35# rsa 512 bits 0.000712s 0.000050s 1404.9 19858.5 hardware this
36#
37# rsa 1024 bits 0.008518s 0.000413s 117.4 2420.8 software integer
38# rsa 1024 bits 0.004275s 0.000277s 233.9 3609.7 software SSE2
39# rsa 1024 bits 0.012136s 0.000260s 82.4 3844.5 hardware VIA SDK
40# rsa 1024 bits 0.002522s 0.000116s 396.5 8650.9 hardware this
41#
42# rsa 2048 bits 0.050101s 0.001371s 20.0 729.6 software integer
43# rsa 2048 bits 0.030273s 0.001008s 33.0 991.9 software SSE2
44# rsa 2048 bits 0.030833s 0.000976s 32.4 1025.1 hardware VIA SDK
45# rsa 2048 bits 0.011879s 0.000342s 84.2 2921.7 hardware this
46#
47# rsa 4096 bits 0.327097s 0.004859s 3.1 205.8 software integer
48# rsa 4096 bits 0.229318s 0.003859s 4.4 259.2 software SSE2
49# rsa 4096 bits 0.233953s 0.003274s 4.3 305.4 hardware VIA SDK
50# rsa 4096 bits 0.070493s 0.001166s 14.2 857.6 hardware this
51#
52# dsa 512 bits 0.001342s 0.001651s 745.2 605.7 software integer
53# dsa 512 bits 0.000844s 0.000987s 1185.3 1013.1 software SSE2
54# dsa 512 bits 0.001902s 0.002247s 525.6 444.9 hardware VIA SDK
55# dsa 512 bits 0.000458s 0.000524s 2182.2 1909.1 hardware this
56#
57# dsa 1024 bits 0.003964s 0.004926s 252.3 203.0 software integer
58# dsa 1024 bits 0.002686s 0.003166s 372.3 315.8 software SSE2
59# dsa 1024 bits 0.002397s 0.002823s 417.1 354.3 hardware VIA SDK
60# dsa 1024 bits 0.000978s 0.001170s 1022.2 855.0 hardware this
61#
62# dsa 2048 bits 0.013280s 0.016518s 75.3 60.5 software integer
63# dsa 2048 bits 0.009911s 0.011522s 100.9 86.8 software SSE2
64# dsa 2048 bits 0.009542s 0.011763s 104.8 85.0 hardware VIA SDK
65# dsa 2048 bits 0.002884s 0.003352s 346.8 298.3 hardware this
66#
67# To give you some other reference point here is output for 2.4GHz P4
68# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software
69# SSE2" in above terms.
70#
71# rsa 512 bits 0.000407s 0.000047s 2454.2 21137.0
72# rsa 1024 bits 0.002426s 0.000141s 412.1 7100.0
73# rsa 2048 bits 0.015046s 0.000491s 66.5 2034.9
74# rsa 4096 bits 0.109770s 0.002379s 9.1 420.3
75# dsa 512 bits 0.000438s 0.000525s 2281.1 1904.1
76# dsa 1024 bits 0.001346s 0.001595s 742.7 627.0
77# dsa 2048 bits 0.004745s 0.005582s 210.7 179.1
78#
79# Conclusions:
80# - VIA SDK leaves a *lot* of room for improvement (which this
81# implementation successfully fills:-);
82# - 'rep montmul' gives up to >3x performance improvement depending on
83# key length;
84# - in terms of absolute performance it delivers approximately as much
85# as modern out-of-order 32-bit cores [again, for longer keys].
86
87$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
88push(@INC,"${dir}","${dir}../../perlasm");
89require "x86asm.pl";
90
91$output = pop and open STDOUT,">$output";
92
93&asm_init($ARGV[0]);
94
95# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
96$func="bn_mul_mont_padlock";
97
98$pad=16*1; # amount of reserved bytes on top of every vector
99
100# stack layout
101$mZeroPrime=&DWP(0,"esp"); # these are specified by VIA
102$A=&DWP(4,"esp");
103$B=&DWP(8,"esp");
104$T=&DWP(12,"esp");
105$M=&DWP(16,"esp");
106$scratch=&DWP(20,"esp");
107$rp=&DWP(24,"esp"); # these are mine
108$sp=&DWP(28,"esp");
109# &DWP(32,"esp") # 32 byte scratch area
110# &DWP(64+(4*$num+$pad)*0,"esp") # padded tp[num]
111# &DWP(64+(4*$num+$pad)*1,"esp") # padded copy of ap[num]
112# &DWP(64+(4*$num+$pad)*2,"esp") # padded copy of bp[num]
113# &DWP(64+(4*$num+$pad)*3,"esp") # padded copy of np[num]
114# Note that SDK suggests to unconditionally allocate 2K per vector. This
115# has quite an impact on performance. It naturally depends on key length,
116# but to give an example 1024 bit private RSA key operations suffer >30%
117# penalty. I allocate only as much as actually required...
118
119&function_begin($func);
120 &xor ("eax","eax");
121 &mov ("ecx",&wparam(5)); # num
122 # meet VIA's limitations for num [note that the specification
123 # expresses them in bits, while we work with amount of 32-bit words]
124 &test ("ecx",3);
125 &jnz (&label("leave")); # num % 4 != 0
126 &cmp ("ecx",8);
127 &jb (&label("leave")); # num < 8
128 &cmp ("ecx",1024);
129 &ja (&label("leave")); # num > 1024
130
131 &pushf ();
132 &cld ();
133
134 &mov ("edi",&wparam(0)); # rp
135 &mov ("eax",&wparam(1)); # ap
136 &mov ("ebx",&wparam(2)); # bp
137 &mov ("edx",&wparam(3)); # np
138 &mov ("esi",&wparam(4)); # n0
139 &mov ("esi",&DWP(0,"esi")); # *n0
140
141 &lea ("ecx",&DWP($pad,"","ecx",4)); # ecx becomes vector size in bytes
142 &lea ("ebp",&DWP(64,"","ecx",4)); # allocate 4 vectors + 64 bytes
143 &neg ("ebp");
144 &add ("ebp","esp");
145 &and ("ebp",-64); # align to cache-line
146 &xchg ("ebp","esp"); # alloca
147
148 &mov ($rp,"edi"); # save rp
149 &mov ($sp,"ebp"); # save esp
150
151 &mov ($mZeroPrime,"esi");
152 &lea ("esi",&DWP(64,"esp")); # tp
153 &mov ($T,"esi");
154 &lea ("edi",&DWP(32,"esp")); # scratch area
155 &mov ($scratch,"edi");
156 &mov ("esi","eax");
157
158 &lea ("ebp",&DWP(-$pad,"ecx"));
159 &shr ("ebp",2); # restore original num value in ebp
160
161 &xor ("eax","eax");
162
163 &mov ("ecx","ebp");
164 &lea ("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch
165 &data_byte(0xf3,0xab); # rep stosl, bzero
166
167 &mov ("ecx","ebp");
168 &lea ("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy
169 &mov ($A,"edi");
170 &data_byte(0xf3,0xa5); # rep movsl, memcpy
171 &mov ("ecx",$pad/4);
172 &data_byte(0xf3,0xab); # rep stosl, bzero pad
173 # edi points at the end of padded ap copy...
174
175 &mov ("ecx","ebp");
176 &mov ("esi","ebx");
177 &mov ($B,"edi");
178 &data_byte(0xf3,0xa5); # rep movsl, memcpy
179 &mov ("ecx",$pad/4);
180 &data_byte(0xf3,0xab); # rep stosl, bzero pad
181 # edi points at the end of padded bp copy...
182
183 &mov ("ecx","ebp");
184 &mov ("esi","edx");
185 &mov ($M,"edi");
186 &data_byte(0xf3,0xa5); # rep movsl, memcpy
187 &mov ("ecx",$pad/4);
188 &data_byte(0xf3,0xab); # rep stosl, bzero pad
189 # edi points at the end of padded np copy...
190
191 # let magic happen...
192 &mov ("ecx","ebp");
193 &mov ("esi","esp");
194 &shl ("ecx",5); # convert word counter to bit counter
195 &align (4);
196 &data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul
197
198 &mov ("ecx","ebp");
199 &lea ("esi",&DWP(64,"esp")); # tp
200 # edi still points at the end of padded np copy...
201 &neg ("ebp");
202 &lea ("ebp",&DWP(-$pad,"edi","ebp",4)); # so just "rewind"
203 &mov ("edi",$rp); # restore rp
204 &xor ("edx","edx"); # i=0 and clear CF
205
206&set_label("sub",8);
207 &mov ("eax",&DWP(0,"esi","edx",4));
208 &sbb ("eax",&DWP(0,"ebp","edx",4));
209 &mov (&DWP(0,"edi","edx",4),"eax"); # rp[i]=tp[i]-np[i]
210 &lea ("edx",&DWP(1,"edx")); # i++
211 &loop (&label("sub")); # doesn't affect CF!
212
213 &mov ("eax",&DWP(0,"esi","edx",4)); # upmost overflow bit
214 &sbb ("eax",0);
215
216 &mov ("ecx","edx"); # num
217 &mov ("edx",0); # i=0
218
219&set_label("copy",8);
220 &mov ("ebx",&DWP(0,"esi","edx",4));
221 &mov ("eax",&DWP(0,"edi","edx",4));
222 &mov (&DWP(0,"esi","edx",4),"ecx"); # zap tp
223 &cmovc ("eax","ebx");
224 &mov (&DWP(0,"edi","edx",4),"eax");
225 &lea ("edx",&DWP(1,"edx")); # i++
226 &loop (&label("copy"));
227
228 &mov ("ebp",$sp);
229 &xor ("eax","eax");
230
231 &mov ("ecx",64/4);
232 &mov ("edi","esp"); # zap frame including scratch area
233 &data_byte(0xf3,0xab); # rep stosl, bzero
234
235 # zap copies of ap, bp and np
236 &lea ("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap
237 &lea ("ecx",&DWP(3*$pad/4,"edx","edx",2));
238 &data_byte(0xf3,0xab); # rep stosl, bzero
239
240 &mov ("esp","ebp");
241 &inc ("eax"); # signal "done"
242 &popf ();
243&set_label("leave");
244&function_end($func);
245
246&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by <appro\@openssl.org>");
247
248&asm_finish();
249
250close STDOUT or die "error closing STDOUT: $!";
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette