forked from
gazagnaire.org/ocaml-crypto
upstream: https://github.com/mirage/mirage-crypto
1open Crypto
2
3module Time = struct
4 let time ~n f a =
5 let t1 = Sys.time () in
6 for _ = 1 to n do
7 ignore (f a)
8 done;
9 let t2 = Sys.time () in
10 t2 -. t1
11
12 let warmup () =
13 let x = ref 0 in
14 let rec go start =
15 if Sys.time () -. start < 1. then begin
16 for i = 0 to 10000 do
17 x := !x + i
18 done;
19 go start
20 end
21 in
22 go (Sys.time ())
23end
24
25let burn_period = 2.0
26let sizes = [ 16; 64; 256; 1024; 8192 ]
27(* let sizes = [16] *)
28
29let burn f n =
30 let buf = Crypto_rng.generate n in
31 let t1, i1 =
32 let rec loop it =
33 let t = Time.time ~n:it f buf in
34 if t > 0.2 then (t, it) else loop (it * 10)
35 in
36 loop 10
37 in
38 let iters = int_of_float (float i1 *. burn_period /. t1) in
39 let time = Time.time ~n:iters f buf in
40 (iters, time, float (n * iters) /. time)
41
42let mb = 1024. *. 1024.
43
44let throughput title f =
45 Printf.printf "\n* [%s]\n%!" title;
46 sizes
47 |> List.iter @@ fun size ->
48 Gc.full_major ();
49 let iters, time, bw = burn f size in
50 Printf.printf " % 5d: %04f MB/s (%d iters in %.03f s)\n%!" size
51 (bw /. mb) iters time
52
53let throughput_into ?(add = 0) title f =
54 Printf.printf "\n* [%s]\n%!" title;
55 sizes
56 |> List.iter @@ fun size ->
57 Gc.full_major ();
58 let dst = Bytes.create (size + add) in
59 let iters, time, bw = burn (f dst) size in
60 Printf.printf " % 5d: %04f MB/s (%d iters in %.03f s)\n%!" size
61 (bw /. mb) iters time
62
63let count_period = 10.
64
65let count f n =
66 ignore (f n);
67 let i1 = 5 in
68 let t1 = Time.time ~n:i1 f n in
69 let iters = int_of_float (float i1 *. count_period /. t1) in
70 let time = Time.time ~n:iters f n in
71 (iters, time)
72
73let count title f to_str args =
74 Printf.printf "\n* [%s]\n%!" title;
75 args
76 |> List.iter @@ fun arg ->
77 Gc.full_major ();
78 let iters, time = count f arg in
79 Printf.printf " %s: %.03f ops per second (%d iters in %.03f)\n%!"
80 (to_str arg)
81 (float iters /. time)
82 iters time
83
84let msg_str = String.make 100 '\xAA'
85let msg_str_32 = String.sub msg_str 0 32
86let msg_str_48 = String.sub msg_str 0 48
87let msg_str_65 = String.sub msg_str 0 65
88
89module PSS = Crypto_pk.Rsa.PSS (Digestif.SHA256)
90
91let rsa_1024 =
92 let p =
93 Z.of_string
94 "10798561676627454710140432432014696449593673631094049392368450463276546091610832740190717321579865870896133380991892468262437092547408603618427685009427773"
95 and q =
96 Z.of_string
97 "10400664760062606994038747844895625872750212488858602663971334563613232045185857177383833781411830934303117994128623611996670112272953487791473086751129863"
98 and e = Z.of_string "65537" in
99 match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with
100 | Ok r -> r
101 | _ -> assert false
102
103let enc_1024 = Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv rsa_1024) msg_str)
104
105let pkcs1_sig_1024 () =
106 Crypto_pk.Rsa.PKCS1.sign ~hash:`SHA256 ~key:rsa_1024 (`Message msg_str)
107
108let pkcs1_enc_1024 () =
109 Crypto_pk.Rsa.(PKCS1.encrypt ~key:(pub_of_priv rsa_1024) msg_str)
110
111let pss_sig_1024 () = PSS.sign ~key:rsa_1024 (`Message msg_str)
112
113let rsa_2048 =
114 let p =
115 Z.of_string
116 "146881832325800831419400417618624202055588545997890787121932184528831630537012732415698782899346395306540669232648045731896347007978622067056705527305566180903122107927148832001099595387953189273726394573803912262323600581299712943797238366745329534148223987933536186022708693674753193534229263584177098260169"
117 and q =
118 Z.of_string
119 "146461957885839900502732892013745315236120923895767594427579857452138451155393985820080680192640369593315439290134409437965406213465262989382655388410330601076036910359057156988645246773259111682038096388585157599977808854893528900530706460128823381760931962351810679571404043148961709991714582814015259432029"
120 and e = Z.of_string "65537" in
121 match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with
122 | Ok r -> r
123 | _ -> assert false
124
125let enc_2048 = Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv rsa_2048) msg_str)
126
127let pkcs1_sig_2048 () =
128 Crypto_pk.Rsa.PKCS1.sign ~hash:`SHA256 ~key:rsa_2048 (`Message msg_str)
129
130let pkcs1_enc_2048 () =
131 Crypto_pk.Rsa.(PKCS1.encrypt ~key:(pub_of_priv rsa_2048) msg_str)
132
133let pss_sig_2048 () = PSS.sign ~key:rsa_2048 (`Message msg_str)
134
135let rsa_4096 =
136 let p =
137 Z.of_string
138 "30773596934476715066776070065844902670036493980016387964275170019397018472432997910667589359581914549510631424565206701540136804180560112829236103459317928059975099687383138310206374921731816027058152009810073337617754052401932141110921176212810704858018214605862299356217860547747262170495777126218319842708093667844701139914958775637423731967187071886349669479192453619522943080948061657926138418380417577129184420732857906610804965319661598089231703183044642635889126023201809407430354992888247464125783088294095728916671050049684448794153783082653555256735912037270303014887722063417225893745458164718800442738569"
139 and q =
140 Z.of_string
141 "25905916162566396401205858643227945415345838368190515936191926936462899261314859092468495558719305083654714669527919862817831941531613073577910643681172802147392797914485263753968375221243705167910636382434485717071007054833155618588980128488599406663210791261135710551020276087851551652652612955553056226986980360600996201307035494196112173475664509878923172924086102889718336621725968169373963280305056864698229857913526607314633711315503607289470716733189135747457446349029256257187264165837635026903463931381823712962360342258652047970731347111703873301687821992467888598546386551115261010493902143134851640738743"
142 and e = Z.of_string "65537" in
143 match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with
144 | Ok r -> r
145 | _ -> assert false
146
147let enc_4096 = Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv rsa_4096) msg_str)
148
149let pkcs1_sig_4096 () =
150 Crypto_pk.Rsa.PKCS1.sign ~hash:`SHA256 ~key:rsa_4096 (`Message msg_str)
151
152let pkcs1_enc_4096 () =
153 Crypto_pk.Rsa.(PKCS1.encrypt ~key:(pub_of_priv rsa_4096) msg_str)
154
155let pss_sig_4096 () = PSS.sign ~key:rsa_4096 (`Message msg_str)
156
157let dsa_1024 =
158 let p =
159 Z.of_string
160 "115320471016337933377056549329182706825658339080795846324118938187917903660539570102468495091957028599543345588517799627361082806070282899880721557018345825086927289316756283826093243695405203187016738458545513419551779925532261196890562077023934735570005318513791942265699098088390517334916527653326493928799"
161 and q = Z.of_string "823267969559752761552104454322087597915195665001"
162 and gg =
163 Z.of_string
164 "107937769619514611906619060647411205822947624664377868769814121409943849987480570028955037310439082345400300825969182219850876363034452830224901430080806055218560008392720388910894912162956691999057850754409178667408425482805161601110189024138168750376391340697351250728689008407981372513900837280131855895453"
165 and x = Z.of_string "33269272469299670210735451373406214067383586377"
166 and y =
167 Z.of_string
168 "43917635707590891841908570055721669604556135044554274942460553515946670787931699807386932177837523342760860376770220825997328312057886461226985675983491441562087492365801663397409369541614646669226917344513472367438132106373179011858311945451923744651780314133078253880297369792145807736223662521868826642853"
169 in
170 match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with
171 | Ok p -> p
172 | _ -> assert false
173
174let dsa_sig_1024 () = Crypto_pk.Dsa.sign ~key:dsa_1024 msg_str
175
176let dsa_2048 =
177 let p =
178 Z.of_string
179 "27787495469795504213817302334103600594688179071059183073859876165757248559489321478170600304273914000462158587756787453177210321379060448141559798652196363556897576291878245650614903612762833777567911000834171168229784178643222849655095281437320492725855855778320111645629834980350492228611813830302209080760811887894272862901026864911346096471199762409562102789142939773632891860019140618313962854554152891445175391927591825205548689170996430765723064763763481336517107917261869303217480777161449935319930795628114622197586510378927239068257979584784079128534248603619156372913573809491691986354447396965646770535701"
180 and q =
181 Z.of_string
182 "69694877308167037149745913456421442195328554169759046914164177549875778020469"
183 and gg =
184 Z.of_string
185 "16749627588066214399529603991445197534749244283120164288067836662918885787186948571007751498897778360267876697044209030527058098259975959998878027668545429739993477399366554325353523024222400972678469229055566504457717513550553993631550406867067991877458269091177591866978827953084168571646688881904998325355571633065354963580984543158204292013550690051754036914978697535194466008409541982818422484127204033337933785318568157008881227465007133605041651516579370726984057624602011504585990465767875831799514375203088558577008613314886723862237337922917306616319550969129882699756566436846243489458865623046875627558535"
186 and x =
187 Z.of_string
188 "52860861934156228997899838985740859941028688506510055821449681896336427977580"
189 and y =
190 Z.of_string
191 "16697822339875604612001674517725789858937385326266245308648897963274039128000291572870559603618903431422492771498840266582664620626826186158140214481920146230768719356298465470274085841064126012204317638870338958089054809559680905413861272320951150917299685355736888023985398767858005440235842845908452598291689850063919053521400020402671375982259094019780813889586357332424647365679629398571364161673401249910198031061651183589601097975488702613291524957230624044246866866974886847601585171352897595544769649242723658395277456627024303041369757410970512818793143517329469213213147704583953410882515213978051041273924"
192 in
193 match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with
194 | Ok p -> p
195 | _ -> assert false
196
197let dsa_sig_2048 () = Crypto_pk.Dsa.sign ~key:dsa_2048 msg_str
198
199let dsa_3072 =
200 let p =
201 Z.of_string
202 "4944862491052787177238323499959371418651354629231656321315236369672827559263545931134286049323485061071828187289578269594065783019111035804017538871324004047710342711620233110167493989997579634523303899794913823240058891327833786211541568251787338957336540247816021098378292806006955851897646808403078979142749428669072523191276645021175423303816467433407072660616741824124536840773744646488191896772232795413707995397140064396495425700133866462410490239713815308709711960470201906326732033816522202617817869465691798938486540955726912350768931476362143768721380759395525951947017232778140349423557015356082357043807910825817719748257213281893007933859227824276579765323175836008193865064772817200047353825332039369252224256435661514851653526942065285711420907389170574343434449883875510985495078384130667046036846831401643151166834922210257258578675547742596423035828159461629721005113634334227074529533688136165903014911127"
203 and q =
204 Z.of_string
205 "72036757532428134359049138716615314032674441223147930984416116642785279309001"
206 and gg =
207 Z.of_string
208 "988301665281495772390013694627509692333967846948672137624515090935924385717634154201978961497509784579332702743535206413508559565302483922898459454403718843912379531742192312937734625047119678718271184170003455506604118936761508195594240052138536667234693864514877750501896049675764191029147963148241546820518065141123555298022010467792468407477159110344370654433269478015817957411602389410658876373667769353995724289566719120654426746425129842353040271693696527020500630012804936844492302532860691617810440827122662134370347136275931360845416833023047973072799739252681873195380321841873819721774703093238289342578739869306714624065593724407718101053836638039267362740083113357679437895609399028133545708736803196232072972950098992845234240283344492163375862712470338417546036591824286944195749933069780384676421299008472374982388004050973085425949637720603596481254386896408204626665775305048865550117840561595366712598318"
209 and x =
210 Z.of_string
211 "57079433780483458942713357293831115449694380253611914431677328021806898761674"
212 and y =
213 Z.of_string
214 "2872172233173100601346399502391482510148300641600207189246652621232656647081281141886455256814187251102030580186748870087277263359506423691023579912476503628426574690699263443704236625550832436226673947182294798279064154375422081421444400893924415563728656687773617245084962617886701420982288621397340217078717788290878177343138178149109067141997920049624616209300715994802074480057682676445987819355778630849636079364539062466859717465892222793824712941403252645431023939220711618233660062829520555618350855085688062241702521140104357981881833598269736147371800258828202964600523335598361833482597511071900975835195171061421945579132277176597724513608746614358311884564512362186106480065540201711903122228315570389409204443391052987813355120223856839756971514334338065850104261467285471383663470187296456006848469765768400814476981451863643010333596484259098557995874127140419649424228480234701334240448168704764430867915060"
215 in
216 match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with
217 | Ok p -> p
218 | _ -> assert false
219
220let dsa_sig_3072 () = Crypto_pk.Dsa.sign ~key:dsa_3072 msg_str
221
222let dh_groups =
223 [
224 ("oakley5 (1536)", Crypto_pk.Dh.Group.oakley_5);
225 ("oakley14 (2048)", Crypto_pk.Dh.Group.oakley_14);
226 ("ffdhe2048", Crypto_pk.Dh.Group.ffdhe2048);
227 ("ffdhe3072", Crypto_pk.Dh.Group.ffdhe3072);
228 ("ffdhe4096", Crypto_pk.Dh.Group.ffdhe4096);
229 ("ffdhe6144", Crypto_pk.Dh.Group.ffdhe6144);
230 ]
231
232let dh_secrets =
233 List.map2
234 (fun (n, group) s -> ((n, group), Crypto_pk.Dh.key_of_secret group ~s))
235 dh_groups
236 (List.map
237 (fun s -> Z.of_string s |> Crypto_pk.Z_extra.to_octets_be)
238 [
239 "31271182055444024732867835946284871743952969208281694762833912267184";
240 "27594341083884344999714422172371027333192426063917478556668524561591";
241 "49745209598738800585479479877345156590922715411063492309021724116430";
242 "54263413298355776701974737228250185414758929445654879795198916482466337662578919821";
243 "38599161911587526396222063388324161227700603198435442693976375015855884010520671067171149524070089";
244 "60057457975706301816395663645420233759377744187465730049174048360108513636349450241008234412972340882517684187851";
245 ])
246
247let ecdsa_p256 =
248 Result.get_ok
249 (Crypto_ec.P256.Dsa.priv_of_octets
250 "\x08\x9f\x4f\xfc\xcc\xf9\xba\x13\xfe\xdd\x09\x42\xef\x08\xcf\x2d\x90\x9f\x32\xe2\x93\x4a\xb5\xc9\x3b\x6c\x99\xbe\x5a\x9f\xf5\x27")
251
252let ecdsa_p256_sig () = Crypto_ec.P256.Dsa.sign ~key:ecdsa_p256 msg_str_32
253
254let ecdsa_p384 =
255 Result.get_ok
256 (Crypto_ec.P384.Dsa.priv_of_octets
257 "\xf5\xc0\xc9\xfb\x95\x17\x86\x41\xaf\x76\xf3\x83\x1f\x41\xe2\xd3\x7c\xfa\xaf\xff\xc7\xe6\x01\x72\xcf\xb0\x89\xfe\x60\x4b\x56\xa6\x1c\x7c\x31\xa6\x90\x4b\x3b\x5d\x08\x20\x7a\x4b\x81\xe2\x5e\xa5")
258
259let ecdsa_p384_sig () = Crypto_ec.P384.Dsa.sign ~key:ecdsa_p384 msg_str_48
260
261let ecdsa_p521 =
262 Result.get_ok
263 (Crypto_ec.P521.Dsa.priv_of_octets
264 "\x00\xb1\x8f\x60\xc0\x35\x2a\xd8\xe3\xef\x98\x2f\x1d\xdf\xcf\x6e\xec\x7f\xa6\xca\xf0\xe6\xf3\x68\x35\x4a\x8b\x02\xb2\xd8\xac\x1e\x05\x9e\x30\x98\x91\xe2\xbf\xa8\x57\x91\xa5\xe7\x1b\x40\xbd\xec\xbf\x90\x2b\xf2\x43\xdc\x3b\x00\x80\x49\x5c\xf4\xd9\x1c\x78\x72\x8b\xd5")
265
266let ecdsa_p521_sig () = Crypto_ec.P521.Dsa.sign ~key:ecdsa_p521 msg_str_65
267
268let ed25519 =
269 Result.get_ok
270 (Crypto_ec.Ed25519.priv_of_octets
271 "\x3e\x0a\xb6\x82\x17\x12\x75\xc5\x69\xfc\xe9\xca\x8b\xcc\xd2\xd2\x77\x14\x54\xa2\x30\x0c\x35\x29\xf7\xa4\xd8\x0b\x84\x38\x83\xbc")
272
273let ed25519_sig () = Crypto_ec.Ed25519.sign ~key:ed25519 msg_str
274
275let ecdsas =
276 [
277 ("P256", `P256 (ecdsa_p256, ecdsa_p256_sig ()));
278 ("P384", `P384 (ecdsa_p384, ecdsa_p384_sig ()));
279 ("P521", `P521 (ecdsa_p521, ecdsa_p521_sig ()));
280 ("Ed25519", `Ed25519 (ed25519, ed25519_sig ()));
281 ]
282
283let ecdh_shares =
284 [
285 ( "P256",
286 `P256
287 ( Crypto_ec.P256.Dh.secret_of_octets
288 "\x47\x0d\x57\x70\x6c\x77\x06\xb6\x8a\x3f\x42\x3a\xea\xf4\xff\x7f\xdd\x02\x49\x4a\x10\xd3\xe3\x81\xc3\xc1\x1f\x72\x76\x80\x2c\xdc"
289 |> Result.get_ok |> fst,
290 "\x04\x11\xb3\xfc\x82\x72\x1c\x26\x9a\x19\x90\x9a\x3b\x2f\xc2\x6d\x98\x95\x82\x6d\x0c\xfc\xbc\x1f\x76\x26\xe4\x88\xf0\x1f\x4c\xa6\xb5\xc5\xed\x76\xad\xee\x7a\xf8\x1b\xb2\x0b\x17\xcf\x23\x1c\xbf\x0c\x67\xdb\x02\x95\xd6\x8d\x1d\x92\xc2\xd2\xa5\xa8\x06\x38\xd7\x8d"
291 ) );
292 ( "P384",
293 `P384
294 ( Crypto_ec.P384.Dh.secret_of_octets
295 "\xee\x55\xe2\x9b\x61\x75\x2d\x5a\x3e\x52\x56\x56\xdb\x8b\xd8\xfe\x6f\x94\xfa\xb8\xaa\xcc\x9e\x92\xac\xff\x4c\x48\x12\xbf\x7a\x61\x87\xab\xa4\x6c\xc6\x0a\xb8\xf0\x8e\xfc\xf2\xd5\x74\x58\x4b\x74"
296 |> Result.get_ok |> fst,
297 "\x04\x04\x89\xcf\x24\xbc\x80\xbf\x89\xfd\xfe\x9c\x05\xec\xc3\x9f\x69\x16\xad\x45\x09\xd9\x39\x85\x97\x95\x0d\x3d\x24\xe8\x28\xf6\xbf\x56\xba\x4a\xd6\xd2\x1e\xd7\x86\x3b\xed\x68\xe4\x13\x36\x4b\xd4\xc7\xb1\xe9\x04\x7d\x36\x12\x4c\x69\x53\xbe\x7c\x61\x20\x9c\xb3\xfc\x56\x45\x2f\x73\x05\x29\x37\x83\xc7\xc0\xed\x92\x9d\x6c\x98\xc7\xbc\x97\xf6\x0a\x72\xed\x22\x69\xa8\xeb\x19\xbb\x7e\xe1\x31"
298 ) );
299 ( "P521",
300 `P521
301 ( Crypto_ec.P521.Dh.secret_of_octets
302 "\x00\xaa\x47\x0b\xa1\xcc\x84\x3b\xa3\x14\x82\x1e\x72\xde\x4c\xd2\x99\xae\xc1\xf2\x6e\x9d\x64\xa0\xd8\x7d\xb1\x8a\x3d\xa9\xf6\x5c\x45\xec\xfc\xc5\x61\x7f\xf0\xd7\x3b\x2e\x0e\x1c\xdf\xf8\x04\x8e\x01\xbe\x5e\x20\x14\x94\x12\xe7\xdb\xfa\xb7\xfe\xae\x24\x9b\x1b\xfa\x4d"
303 |> Result.get_ok |> fst,
304 "\x04\x00\x1d\x16\x29\xee\xb1\xc4\x25\xf9\x04\xd7\x55\x33\x00\x79\xd1\x3c\x77\xda\x92\x1e\x01\xcf\x50\xd7\x17\xe0\xd6\x85\x0a\x81\xa3\x90\x2b\xb9\x2a\x03\xfa\xea\xcb\xd6\x28\x9c\x15\x90\x68\x5a\x60\x44\xb5\xe9\x4d\xcf\xc4\x1d\xeb\x6a\x88\xdb\x62\xa8\x91\xb0\xb8\x93\xbb\x00\xe4\x2a\x66\xb2\xf0\x13\xbd\xd0\xd2\x7d\x8e\x07\xcb\x35\xfc\x3e\x2c\x2b\x22\xf9\x3e\xcf\xd5\xea\xb7\x88\x61\x97\xca\x07\x3c\x2c\x5e\x68\x31\xd6\x5e\x2d\x0b\x8a\xa4\x08\x43\x8e\x49\x54\x2f\x05\xf4\x1c\x57\x6d\xf7\x0e\x3c\xaf\x5b\xb8\x22\x7d\x48\x30\x94\xae\x58"
305 ) );
306 ( "X25519",
307 `X25519
308 ( Crypto_ec.X25519.secret_of_octets
309 "\x4c\x6d\xb7\xcf\x93\x5b\xcf\x84\x02\x61\x78\xd4\x0c\x95\x6a\xf0\x9d\x8e\x36\x32\x03\x49\x0d\x2c\x41\x62\x5a\xcb\x68\xb9\x31\xa4"
310 |> Result.get_ok |> fst,
311 "\xca\x19\x19\x3c\xf5\xc0\xb3\x8c\x61\xaa\x01\xc1\x72\xb2\xe9\x3d\x16\xf7\x50\xd0\x84\x62\x77\xad\x32\x2d\xe5\xe4\xfb\x33\x24\x29"
312 ) );
313 ]
314
315let bm name f = (name, fun () -> f name)
316
317let benchmarks =
318 [
319 bm "rsa-generate" (fun name ->
320 count name
321 (fun bits -> Crypto_pk.Rsa.generate ~bits ())
322 string_of_int [ 1024; 2048; 4096 ]);
323 bm "rsa-encrypt" (fun name ->
324 count name
325 (fun key -> Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv key) msg_str))
326 (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
327 [ rsa_1024; rsa_2048; rsa_4096 ]);
328 bm "rsa-decrypt" (fun name ->
329 count name
330 (fun (key, msg) -> Crypto_pk.Rsa.(decrypt ~key msg))
331 (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
332 [ (rsa_1024, enc_1024); (rsa_2048, enc_2048); (rsa_4096, enc_4096) ]);
333 bm "rsa-pkcs1-encrypt" (fun name ->
334 count name
335 (fun key ->
336 Crypto_pk.Rsa.(PKCS1.encrypt ~key:(pub_of_priv key) msg_str))
337 (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
338 [ rsa_1024; rsa_2048; rsa_4096 ]);
339 bm "rsa-pkcs1-decrypt" (fun name ->
340 count name
341 (fun (key, msg) -> Crypto_pk.Rsa.(PKCS1.decrypt ~key msg))
342 (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
343 [
344 (rsa_1024, pkcs1_enc_1024 ());
345 (rsa_2048, pkcs1_enc_2048 ());
346 (rsa_4096, pkcs1_enc_4096 ());
347 ]);
348 bm "rsa-pkcs1-sign" (fun name ->
349 count name
350 (fun key ->
351 Crypto_pk.Rsa.PKCS1.sign ~hash:`SHA256 ~key (`Message msg_str))
352 (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
353 [ rsa_1024; rsa_2048; rsa_4096 ]);
354 bm "rsa-pkcs1-verify" (fun name ->
355 count name
356 (fun (key, signature) ->
357 Crypto_pk.Rsa.(
358 PKCS1.verify
359 ~hashp:(fun _ -> true)
360 ~key:(pub_of_priv key) ~signature (`Message msg_str)))
361 (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
362 [
363 (rsa_1024, pkcs1_sig_1024 ());
364 (rsa_2048, pkcs1_sig_2048 ());
365 (rsa_4096, pkcs1_sig_4096 ());
366 ]);
367 bm "rsa-pss-sign" (fun name ->
368 count name
369 (fun key -> PSS.sign ~key (`Message msg_str))
370 (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
371 [ rsa_1024; rsa_2048; rsa_4096 ]);
372 bm "rsa-pss-verify" (fun name ->
373 count name
374 (fun (key, signature) ->
375 PSS.verify
376 ~key:(Crypto_pk.Rsa.pub_of_priv key)
377 ~signature (`Message msg_str))
378 (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
379 [
380 (rsa_1024, pss_sig_1024 ());
381 (rsa_2048, pss_sig_2048 ());
382 (rsa_4096, pss_sig_4096 ());
383 ]);
384 bm "dsa-generate" (fun name ->
385 count name
386 (fun ks -> Crypto_pk.Dsa.generate ks)
387 (function
388 | `Fips1024 -> "1024"
389 | `Fips2048 -> "2048"
390 | `Fips3072 -> "3072"
391 | `Exactly (l, _) -> string_of_int l)
392 [ `Fips1024; `Fips2048; `Fips3072 ]);
393 bm "dsa-sign" (fun name ->
394 count name
395 (fun key -> Crypto_pk.Dsa.sign ~key msg_str)
396 (fun k -> string_of_int (Z.numbits k.p))
397 [ dsa_1024; dsa_2048; dsa_3072 ]);
398 bm "dsa-verify" (fun name ->
399 count name
400 (fun (key, signature) ->
401 Crypto_pk.Dsa.(verify ~key:(pub_of_priv key) signature msg_str))
402 (fun (k, _) -> string_of_int (Z.numbits k.p))
403 [
404 (dsa_1024, dsa_sig_1024 ());
405 (dsa_2048, dsa_sig_2048 ());
406 (dsa_3072, dsa_sig_3072 ());
407 ]);
408 bm "ecdsa-generate" (fun name ->
409 let open Crypto_ec in
410 count name
411 (fun (_, x) ->
412 match x with
413 | `P256 _ -> P256.Dsa.generate () |> ignore
414 | `P384 _ -> P384.Dsa.generate () |> ignore
415 | `P521 _ -> P521.Dsa.generate () |> ignore
416 | `Ed25519 _ -> Ed25519.generate () |> ignore)
417 fst ecdsas);
418 bm "ecdsa-sign" (fun name ->
419 let open Crypto_ec in
420 count name
421 (fun (_, x) ->
422 match x with
423 | `P256 (key, _) -> P256.Dsa.sign ~key msg_str_32
424 | `P384 (key, _) -> P384.Dsa.sign ~key msg_str_48
425 | `P521 (key, _) -> P521.Dsa.sign ~key msg_str_65
426 | `Ed25519 (key, _) -> (Ed25519.sign ~key msg_str, ""))
427 fst ecdsas);
428 bm "ecdsa-verify" (fun name ->
429 let open Crypto_ec in
430 count name
431 (fun (_, x) ->
432 match x with
433 | `P256 (key, signature) ->
434 P256.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_32)
435 | `P384 (key, signature) ->
436 P384.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_48)
437 | `P521 (key, signature) ->
438 P521.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_65)
439 | `Ed25519 (key, signature) ->
440 Ed25519.(verify ~key:(pub_of_priv key) signature ~msg:msg_str))
441 fst ecdsas);
442 bm "dh-secret" (fun name ->
443 count name (fun (_, group) -> Crypto_pk.Dh.gen_key group) fst dh_groups);
444 bm "dh-share" (fun name ->
445 count name
446 (fun (_, (sec, share)) -> Crypto_pk.Dh.shared sec share)
447 (fun ((g, _), _) -> g)
448 dh_secrets);
449 bm "ecdh-secret" (fun name ->
450 let open Crypto_ec in
451 count name
452 (fun (_, x) ->
453 match x with
454 | `P256 _ -> P256.Dh.gen_key () |> ignore
455 | `P384 _ -> P384.Dh.gen_key () |> ignore
456 | `P521 _ -> P521.Dh.gen_key () |> ignore
457 | `X25519 _ -> X25519.gen_key () |> ignore)
458 fst ecdh_shares);
459 bm "ecdh-share" (fun name ->
460 let open Crypto_ec in
461 count name
462 (fun (_, x) ->
463 match x with
464 | `P256 (sec, share) ->
465 P256.Dh.key_exchange sec share |> Result.get_ok |> ignore
466 | `P384 (sec, share) ->
467 P384.Dh.key_exchange sec share |> Result.get_ok |> ignore
468 | `P521 (sec, share) ->
469 P521.Dh.key_exchange sec share |> Result.get_ok |> ignore
470 | `X25519 (sec, share) ->
471 X25519.key_exchange sec share |> Result.get_ok |> ignore)
472 fst ecdh_shares);
473 bm "chacha20-poly1305" (fun name ->
474 let key = Chacha20.of_secret (Crypto_rng.generate 32)
475 and nonce = Crypto_rng.generate 8 in
476 throughput_into ~add:Chacha20.tag_size name (fun dst cs ->
477 Chacha20.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst
478 ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
479 bm "chacha20-poly1305-unsafe" (fun name ->
480 let key = Chacha20.of_secret (Crypto_rng.generate 32)
481 and nonce = Crypto_rng.generate 8 in
482 throughput_into ~add:Chacha20.tag_size name (fun dst cs ->
483 Chacha20.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0
484 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
485 bm "aes-128-ecb" (fun name ->
486 let key = AES.ECB.of_secret (Crypto_rng.generate 16) in
487 throughput_into name (fun dst cs ->
488 AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
489 (String.length cs)));
490 bm "aes-192-ecb" (fun name ->
491 let key = AES.ECB.of_secret (Crypto_rng.generate 24) in
492 throughput_into name (fun dst cs ->
493 AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
494 (String.length cs)));
495 bm "aes-192-ecb-unsafe" (fun name ->
496 let key = AES.ECB.of_secret (Crypto_rng.generate 24) in
497 throughput_into name (fun dst cs ->
498 AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
499 (String.length cs)));
500 bm "aes-256-ecb" (fun name ->
501 let key = AES.ECB.of_secret (Crypto_rng.generate 32) in
502 throughput_into name (fun dst cs ->
503 AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
504 (String.length cs)));
505 bm "aes-256-ecb-unsafe" (fun name ->
506 let key = AES.ECB.of_secret (Crypto_rng.generate 32) in
507 throughput_into name (fun dst cs ->
508 AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
509 (String.length cs)));
510 bm "aes-128-ecb-unsafe" (fun name ->
511 let key = AES.ECB.of_secret (Crypto_rng.generate 16) in
512 throughput_into name (fun dst cs ->
513 AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
514 (String.length cs)));
515 bm "aes-128-cbc-e" (fun name ->
516 let key = AES.CBC.of_secret (Crypto_rng.generate 16)
517 and iv = Crypto_rng.generate 16 in
518 throughput_into name (fun dst cs ->
519 AES.CBC.encrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0
520 (String.length cs)));
521 bm "aes-128-cbc-e-unsafe" (fun name ->
522 let key = AES.CBC.of_secret (Crypto_rng.generate 16)
523 and iv = Crypto_rng.generate 16 in
524 throughput_into name (fun dst cs ->
525 AES.CBC.unsafe_encrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0
526 (String.length cs)));
527 bm "aes-128-cbc-e-unsafe-inplace" (fun name ->
528 let key = AES.CBC.of_secret (Crypto_rng.generate 16)
529 and iv = Crypto_rng.generate 16 in
530 throughput name (fun cs ->
531 let b = Bytes.unsafe_of_string cs in
532 AES.CBC.unsafe_encrypt_into_inplace ~key ~iv b ~dst_off:0
533 (String.length cs)));
534 bm "aes-128-cbc-d" (fun name ->
535 let key = AES.CBC.of_secret (Crypto_rng.generate 16)
536 and iv = Crypto_rng.generate 16 in
537 throughput_into name (fun dst cs ->
538 AES.CBC.decrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0
539 (String.length cs)));
540 bm "aes-128-cbc-d-unsafe" (fun name ->
541 let key = AES.CBC.of_secret (Crypto_rng.generate 16)
542 and iv = Crypto_rng.generate 16 in
543 throughput_into name (fun dst cs ->
544 AES.CBC.unsafe_decrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0
545 (String.length cs)));
546 bm "aes-128-ctr" (fun name ->
547 let key = Crypto_rng.generate 16 |> AES.CTR.of_secret
548 and ctr = Crypto_rng.generate 16 |> AES.CTR.ctr_of_octets in
549 throughput_into name (fun dst cs ->
550 AES.CTR.encrypt_into ~key ~ctr cs ~src_off:0 dst ~dst_off:0
551 (String.length cs)));
552 bm "aes-128-ctr-unsafe" (fun name ->
553 let key = Crypto_rng.generate 16 |> AES.CTR.of_secret
554 and ctr = Crypto_rng.generate 16 |> AES.CTR.ctr_of_octets in
555 throughput_into name (fun dst cs ->
556 AES.CTR.unsafe_encrypt_into ~key ~ctr cs ~src_off:0 dst ~dst_off:0
557 (String.length cs)));
558 bm "aes-128-gcm" (fun name ->
559 let key = AES.GCM.of_secret (Crypto_rng.generate 16)
560 and nonce = Crypto_rng.generate 12 in
561 throughput_into ~add:AES.GCM.tag_size name (fun dst cs ->
562 AES.GCM.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst
563 ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
564 bm "aes-128-gcm-unsafe" (fun name ->
565 let key = AES.GCM.of_secret (Crypto_rng.generate 16)
566 and nonce = Crypto_rng.generate 12 in
567 throughput_into ~add:AES.GCM.tag_size name (fun dst cs ->
568 AES.GCM.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0
569 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
570 bm "aes-128-ghash" (fun name ->
571 let key = AES.GCM.of_secret (Crypto_rng.generate 16)
572 and nonce = Crypto_rng.generate 12 in
573 throughput_into ~add:AES.GCM.tag_size name (fun dst cs ->
574 AES.GCM.authenticate_encrypt_into ~key ~nonce ~adata:cs ""
575 ~src_off:0 dst ~dst_off:0 ~tag_off:0 0));
576 bm "aes-128-ghash-unsafe" (fun name ->
577 let key = AES.GCM.of_secret (Crypto_rng.generate 16)
578 and nonce = Crypto_rng.generate 12 in
579 throughput_into ~add:AES.GCM.tag_size name (fun dst cs ->
580 AES.GCM.unsafe_authenticate_encrypt_into ~key ~nonce ~adata:cs ""
581 ~src_off:0 dst ~dst_off:0 ~tag_off:0 0));
582 bm "aes-128-ccm" (fun name ->
583 let key = AES.CCM16.of_secret (Crypto_rng.generate 16)
584 and nonce = Crypto_rng.generate 10 in
585 throughput_into ~add:AES.CCM16.tag_size name (fun dst cs ->
586 AES.CCM16.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst
587 ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
588 bm "aes-128-ccm-unsafe" (fun name ->
589 let key = AES.CCM16.of_secret (Crypto_rng.generate 16)
590 and nonce = Crypto_rng.generate 10 in
591 throughput_into ~add:AES.CCM16.tag_size name (fun dst cs ->
592 AES.CCM16.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0
593 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
594 bm "d3des-ecb" (fun name ->
595 let key = DES.ECB.of_secret (Crypto_rng.generate 24) in
596 throughput_into name (fun dst cs ->
597 DES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
598 (String.length cs)));
599 bm "d3des-ecb-unsafe" (fun name ->
600 let key = DES.ECB.of_secret (Crypto_rng.generate 24) in
601 throughput_into name (fun dst cs ->
602 DES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
603 (String.length cs)));
604 bm "fortuna" (fun name ->
605 begin[@alert "-deprecated"]
606 Crypto_rng_unix.initialize (module Crypto_rng.Fortuna);
607 throughput name (fun buf ->
608 let buf = Bytes.unsafe_of_string buf in
609 Crypto_rng.generate_into buf ~off:0 (Bytes.length buf))
610 end);
611 bm "getentropy" (fun name ->
612 Crypto_rng_unix.use_getentropy ();
613 throughput name (fun buf ->
614 let buf = Bytes.unsafe_of_string buf in
615 Crypto_rng.generate_into buf ~off:0 (Bytes.length buf)));
616 bm "urandom" (fun name ->
617 Crypto_rng_unix.use_dev_urandom ();
618 throughput name (fun buf ->
619 let buf = Bytes.unsafe_of_string buf in
620 Crypto_rng.generate_into buf ~off:0 (Bytes.length buf)));
621 ]
622
623let help () =
624 Printf.printf "available benchmarks:\n ";
625 List.iter (fun (n, _) -> Printf.printf "%s " n) benchmarks;
626 Printf.printf "\n%!"
627
628let runv fs =
629 Format.printf "accel: %a\n%!"
630 (fun ppf ->
631 List.iter @@ fun x ->
632 Format.fprintf ppf "%s "
633 @@ match x with `XOR -> "XOR" | `AES -> "AES" | `GHASH -> "GHASH")
634 accelerated;
635 Time.warmup ();
636 List.iter (fun f -> f ()) fs
637
638let () =
639 let seed = "abcd" in
640 let g = Crypto_rng.(create ~seed (module Fortuna)) in
641 Crypto_rng.set_default_generator g;
642 match Array.to_list Sys.argv with
643 | _ :: (_ :: _ as args) -> begin
644 try
645 let fs =
646 args
647 |> List.map @@ fun n ->
648 snd (benchmarks |> List.find @@ fun (n1, _) -> n = n1)
649 in
650 runv fs
651 with Not_found -> help ()
652 end
653 | _ -> help ()