···11open Crypto
2233module Time = struct
44-54 let time ~n f a =
65 let t1 = Sys.time () in
77- for _ = 1 to n do ignore (f a) done ;
66+ for _ = 1 to n do
77+ ignore (f a)
88+ done;
89 let t2 = Sys.time () in
99- (t2 -. t1)
1010+ t2 -. t1
10111112 let warmup () =
1213 let x = ref 0 in
1314 let rec go start =
1415 if Sys.time () -. start < 1. then begin
1515- for i = 0 to 10000 do x := !x + i done ;
1616+ for i = 0 to 10000 do
1717+ x := !x + i
1818+ done;
1619 go start
1717- end in
2020+ end
2121+ in
1822 go (Sys.time ())
1919-2023end
21242225let burn_period = 2.0
2323-2424-let sizes = [16; 64; 256; 1024; 8192]
2626+let sizes = [ 16; 64; 256; 1024; 8192 ]
2527(* let sizes = [16] *)
26282729let burn f n =
2830 let buf = Crypto_rng.generate n in
2929- let (t1, i1) =
3131+ let t1, i1 =
3032 let rec loop it =
3133 let t = Time.time ~n:it f buf in
3232- if t > 0.2 then (t, it) else loop (it * 10) in
3333- loop 10 in
3434+ if t > 0.2 then (t, it) else loop (it * 10)
3535+ in
3636+ loop 10
3737+ in
3438 let iters = int_of_float (float i1 *. burn_period /. t1) in
3535- let time = Time.time ~n:iters f buf in
3939+ let time = Time.time ~n:iters f buf in
3640 (iters, time, float (n * iters) /. time)
37413842let mb = 1024. *. 1024.
39434044let throughput title f =
4141- Printf.printf "\n* [%s]\n%!" title ;
4242- sizes |> List.iter @@ fun size ->
4343- Gc.full_major () ;
4444- let (iters, time, bw) = burn f size in
4545- Printf.printf " % 5d: %04f MB/s (%d iters in %.03f s)\n%!"
4646- size (bw /. mb) iters time
4545+ Printf.printf "\n* [%s]\n%!" title;
4646+ sizes
4747+ |> List.iter @@ fun size ->
4848+ Gc.full_major ();
4949+ let iters, time, bw = burn f size in
5050+ Printf.printf " % 5d: %04f MB/s (%d iters in %.03f s)\n%!" size
5151+ (bw /. mb) iters time
47524853let throughput_into ?(add = 0) title f =
4949- Printf.printf "\n* [%s]\n%!" title ;
5050- sizes |> List.iter @@ fun size ->
5151- Gc.full_major () ;
5252- let dst = Bytes.create (size + add) in
5353- let (iters, time, bw) = burn (f dst) size in
5454- Printf.printf " % 5d: %04f MB/s (%d iters in %.03f s)\n%!"
5555- size (bw /. mb) iters time
5454+ Printf.printf "\n* [%s]\n%!" title;
5555+ sizes
5656+ |> List.iter @@ fun size ->
5757+ Gc.full_major ();
5858+ let dst = Bytes.create (size + add) in
5959+ let iters, time, bw = burn (f dst) size in
6060+ Printf.printf " % 5d: %04f MB/s (%d iters in %.03f s)\n%!" size
6161+ (bw /. mb) iters time
56625763let count_period = 10.
5864···6167 let i1 = 5 in
6268 let t1 = Time.time ~n:i1 f n in
6369 let iters = int_of_float (float i1 *. count_period /. t1) in
6464- let time = Time.time ~n:iters f n in
7070+ let time = Time.time ~n:iters f n in
6571 (iters, time)
66726773let count title f to_str args =
6868- Printf.printf "\n* [%s]\n%!" title ;
6969- args |> List.iter @@ fun arg ->
7070- Gc.full_major () ;
7171- let iters, time = count f arg in
7272- Printf.printf " %s: %.03f ops per second (%d iters in %.03f)\n%!"
7373- (to_str arg) (float iters /. time) iters time
7474+ Printf.printf "\n* [%s]\n%!" title;
7575+ args
7676+ |> List.iter @@ fun arg ->
7777+ Gc.full_major ();
7878+ let iters, time = count f arg in
7979+ Printf.printf " %s: %.03f ops per second (%d iters in %.03f)\n%!"
8080+ (to_str arg)
8181+ (float iters /. time)
8282+ iters time
74837584let msg_str = String.make 100 '\xAA'
7676-7785let msg_str_32 = String.sub msg_str 0 32
7886let msg_str_48 = String.sub msg_str 0 48
7987let msg_str_65 = String.sub msg_str 0 65
80888181-module PSS = Crypto_pk.Rsa.PSS(Digestif.SHA256)
8989+module PSS = Crypto_pk.Rsa.PSS (Digestif.SHA256)
82908391let rsa_1024 =
8484- let p = Z.of_string "10798561676627454710140432432014696449593673631094049392368450463276546091610832740190717321579865870896133380991892468262437092547408603618427685009427773"
8585- and q = Z.of_string "10400664760062606994038747844895625872750212488858602663971334563613232045185857177383833781411830934303117994128623611996670112272953487791473086751129863"
8686- and e = Z.of_string "65537"
8787- in
8888- match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with Ok r -> r | _ -> assert false
9292+ let p =
9393+ Z.of_string
9494+ "10798561676627454710140432432014696449593673631094049392368450463276546091610832740190717321579865870896133380991892468262437092547408603618427685009427773"
9595+ and q =
9696+ Z.of_string
9797+ "10400664760062606994038747844895625872750212488858602663971334563613232045185857177383833781411830934303117994128623611996670112272953487791473086751129863"
9898+ and e = Z.of_string "65537" in
9999+ match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with
100100+ | Ok r -> r
101101+ | _ -> assert false
8910290103let enc_1024 = Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv rsa_1024) msg_str)
91104···98111let pss_sig_1024 () = PSS.sign ~key:rsa_1024 (`Message msg_str)
99112100113let rsa_2048 =
101101- let p = Z.of_string "146881832325800831419400417618624202055588545997890787121932184528831630537012732415698782899346395306540669232648045731896347007978622067056705527305566180903122107927148832001099595387953189273726394573803912262323600581299712943797238366745329534148223987933536186022708693674753193534229263584177098260169"
102102- and q = Z.of_string "146461957885839900502732892013745315236120923895767594427579857452138451155393985820080680192640369593315439290134409437965406213465262989382655388410330601076036910359057156988645246773259111682038096388585157599977808854893528900530706460128823381760931962351810679571404043148961709991714582814015259432029"
103103- and e = Z.of_string "65537"
104104- in
105105- match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with Ok r -> r | _ -> assert false
114114+ let p =
115115+ Z.of_string
116116+ "146881832325800831419400417618624202055588545997890787121932184528831630537012732415698782899346395306540669232648045731896347007978622067056705527305566180903122107927148832001099595387953189273726394573803912262323600581299712943797238366745329534148223987933536186022708693674753193534229263584177098260169"
117117+ and q =
118118+ Z.of_string
119119+ "146461957885839900502732892013745315236120923895767594427579857452138451155393985820080680192640369593315439290134409437965406213465262989382655388410330601076036910359057156988645246773259111682038096388585157599977808854893528900530706460128823381760931962351810679571404043148961709991714582814015259432029"
120120+ and e = Z.of_string "65537" in
121121+ match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with
122122+ | Ok r -> r
123123+ | _ -> assert false
106124107125let enc_2048 = Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv rsa_2048) msg_str)
108126···115133let pss_sig_2048 () = PSS.sign ~key:rsa_2048 (`Message msg_str)
116134117135let rsa_4096 =
118118- let p = Z.of_string "30773596934476715066776070065844902670036493980016387964275170019397018472432997910667589359581914549510631424565206701540136804180560112829236103459317928059975099687383138310206374921731816027058152009810073337617754052401932141110921176212810704858018214605862299356217860547747262170495777126218319842708093667844701139914958775637423731967187071886349669479192453619522943080948061657926138418380417577129184420732857906610804965319661598089231703183044642635889126023201809407430354992888247464125783088294095728916671050049684448794153783082653555256735912037270303014887722063417225893745458164718800442738569"
119119- and q = Z.of_string "25905916162566396401205858643227945415345838368190515936191926936462899261314859092468495558719305083654714669527919862817831941531613073577910643681172802147392797914485263753968375221243705167910636382434485717071007054833155618588980128488599406663210791261135710551020276087851551652652612955553056226986980360600996201307035494196112173475664509878923172924086102889718336621725968169373963280305056864698229857913526607314633711315503607289470716733189135747457446349029256257187264165837635026903463931381823712962360342258652047970731347111703873301687821992467888598546386551115261010493902143134851640738743"
120120- and e = Z.of_string "65537"
121121- in
122122- match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with Ok r -> r | _ -> assert false
136136+ let p =
137137+ Z.of_string
138138+ "30773596934476715066776070065844902670036493980016387964275170019397018472432997910667589359581914549510631424565206701540136804180560112829236103459317928059975099687383138310206374921731816027058152009810073337617754052401932141110921176212810704858018214605862299356217860547747262170495777126218319842708093667844701139914958775637423731967187071886349669479192453619522943080948061657926138418380417577129184420732857906610804965319661598089231703183044642635889126023201809407430354992888247464125783088294095728916671050049684448794153783082653555256735912037270303014887722063417225893745458164718800442738569"
139139+ and q =
140140+ Z.of_string
141141+ "25905916162566396401205858643227945415345838368190515936191926936462899261314859092468495558719305083654714669527919862817831941531613073577910643681172802147392797914485263753968375221243705167910636382434485717071007054833155618588980128488599406663210791261135710551020276087851551652652612955553056226986980360600996201307035494196112173475664509878923172924086102889718336621725968169373963280305056864698229857913526607314633711315503607289470716733189135747457446349029256257187264165837635026903463931381823712962360342258652047970731347111703873301687821992467888598546386551115261010493902143134851640738743"
142142+ and e = Z.of_string "65537" in
143143+ match Crypto_pk.Rsa.priv_of_primes ~e ~p ~q with
144144+ | Ok r -> r
145145+ | _ -> assert false
123146124147let enc_4096 = Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv rsa_4096) msg_str)
125148···132155let pss_sig_4096 () = PSS.sign ~key:rsa_4096 (`Message msg_str)
133156134157let dsa_1024 =
135135- let p = Z.of_string "115320471016337933377056549329182706825658339080795846324118938187917903660539570102468495091957028599543345588517799627361082806070282899880721557018345825086927289316756283826093243695405203187016738458545513419551779925532261196890562077023934735570005318513791942265699098088390517334916527653326493928799"
158158+ let p =
159159+ Z.of_string
160160+ "115320471016337933377056549329182706825658339080795846324118938187917903660539570102468495091957028599543345588517799627361082806070282899880721557018345825086927289316756283826093243695405203187016738458545513419551779925532261196890562077023934735570005318513791942265699098088390517334916527653326493928799"
136161 and q = Z.of_string "823267969559752761552104454322087597915195665001"
137137- and gg = Z.of_string "107937769619514611906619060647411205822947624664377868769814121409943849987480570028955037310439082345400300825969182219850876363034452830224901430080806055218560008392720388910894912162956691999057850754409178667408425482805161601110189024138168750376391340697351250728689008407981372513900837280131855895453"
162162+ and gg =
163163+ Z.of_string
164164+ "107937769619514611906619060647411205822947624664377868769814121409943849987480570028955037310439082345400300825969182219850876363034452830224901430080806055218560008392720388910894912162956691999057850754409178667408425482805161601110189024138168750376391340697351250728689008407981372513900837280131855895453"
138165 and x = Z.of_string "33269272469299670210735451373406214067383586377"
139139- and y = Z.of_string "43917635707590891841908570055721669604556135044554274942460553515946670787931699807386932177837523342760860376770220825997328312057886461226985675983491441562087492365801663397409369541614646669226917344513472367438132106373179011858311945451923744651780314133078253880297369792145807736223662521868826642853"
166166+ and y =
167167+ Z.of_string
168168+ "43917635707590891841908570055721669604556135044554274942460553515946670787931699807386932177837523342760860376770220825997328312057886461226985675983491441562087492365801663397409369541614646669226917344513472367438132106373179011858311945451923744651780314133078253880297369792145807736223662521868826642853"
140169 in
141141- match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with Ok p -> p | _ -> assert false
170170+ match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with
171171+ | Ok p -> p
172172+ | _ -> assert false
142173143174let dsa_sig_1024 () = Crypto_pk.Dsa.sign ~key:dsa_1024 msg_str
144175145176let dsa_2048 =
146146- let p = Z.of_string "27787495469795504213817302334103600594688179071059183073859876165757248559489321478170600304273914000462158587756787453177210321379060448141559798652196363556897576291878245650614903612762833777567911000834171168229784178643222849655095281437320492725855855778320111645629834980350492228611813830302209080760811887894272862901026864911346096471199762409562102789142939773632891860019140618313962854554152891445175391927591825205548689170996430765723064763763481336517107917261869303217480777161449935319930795628114622197586510378927239068257979584784079128534248603619156372913573809491691986354447396965646770535701"
147147- and q = Z.of_string "69694877308167037149745913456421442195328554169759046914164177549875778020469"
148148- and gg = Z.of_string "16749627588066214399529603991445197534749244283120164288067836662918885787186948571007751498897778360267876697044209030527058098259975959998878027668545429739993477399366554325353523024222400972678469229055566504457717513550553993631550406867067991877458269091177591866978827953084168571646688881904998325355571633065354963580984543158204292013550690051754036914978697535194466008409541982818422484127204033337933785318568157008881227465007133605041651516579370726984057624602011504585990465767875831799514375203088558577008613314886723862237337922917306616319550969129882699756566436846243489458865623046875627558535"
149149- and x = Z.of_string "52860861934156228997899838985740859941028688506510055821449681896336427977580"
150150- and y = Z.of_string "16697822339875604612001674517725789858937385326266245308648897963274039128000291572870559603618903431422492771498840266582664620626826186158140214481920146230768719356298465470274085841064126012204317638870338958089054809559680905413861272320951150917299685355736888023985398767858005440235842845908452598291689850063919053521400020402671375982259094019780813889586357332424647365679629398571364161673401249910198031061651183589601097975488702613291524957230624044246866866974886847601585171352897595544769649242723658395277456627024303041369757410970512818793143517329469213213147704583953410882515213978051041273924"
177177+ let p =
178178+ Z.of_string
179179+ "27787495469795504213817302334103600594688179071059183073859876165757248559489321478170600304273914000462158587756787453177210321379060448141559798652196363556897576291878245650614903612762833777567911000834171168229784178643222849655095281437320492725855855778320111645629834980350492228611813830302209080760811887894272862901026864911346096471199762409562102789142939773632891860019140618313962854554152891445175391927591825205548689170996430765723064763763481336517107917261869303217480777161449935319930795628114622197586510378927239068257979584784079128534248603619156372913573809491691986354447396965646770535701"
180180+ and q =
181181+ Z.of_string
182182+ "69694877308167037149745913456421442195328554169759046914164177549875778020469"
183183+ and gg =
184184+ Z.of_string
185185+ "16749627588066214399529603991445197534749244283120164288067836662918885787186948571007751498897778360267876697044209030527058098259975959998878027668545429739993477399366554325353523024222400972678469229055566504457717513550553993631550406867067991877458269091177591866978827953084168571646688881904998325355571633065354963580984543158204292013550690051754036914978697535194466008409541982818422484127204033337933785318568157008881227465007133605041651516579370726984057624602011504585990465767875831799514375203088558577008613314886723862237337922917306616319550969129882699756566436846243489458865623046875627558535"
186186+ and x =
187187+ Z.of_string
188188+ "52860861934156228997899838985740859941028688506510055821449681896336427977580"
189189+ and y =
190190+ Z.of_string
191191+ "16697822339875604612001674517725789858937385326266245308648897963274039128000291572870559603618903431422492771498840266582664620626826186158140214481920146230768719356298465470274085841064126012204317638870338958089054809559680905413861272320951150917299685355736888023985398767858005440235842845908452598291689850063919053521400020402671375982259094019780813889586357332424647365679629398571364161673401249910198031061651183589601097975488702613291524957230624044246866866974886847601585171352897595544769649242723658395277456627024303041369757410970512818793143517329469213213147704583953410882515213978051041273924"
151192 in
152152- match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with Ok p -> p | _ -> assert false
193193+ match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with
194194+ | Ok p -> p
195195+ | _ -> assert false
153196154197let dsa_sig_2048 () = Crypto_pk.Dsa.sign ~key:dsa_2048 msg_str
155198156199let dsa_3072 =
157157- let p = Z.of_string "4944862491052787177238323499959371418651354629231656321315236369672827559263545931134286049323485061071828187289578269594065783019111035804017538871324004047710342711620233110167493989997579634523303899794913823240058891327833786211541568251787338957336540247816021098378292806006955851897646808403078979142749428669072523191276645021175423303816467433407072660616741824124536840773744646488191896772232795413707995397140064396495425700133866462410490239713815308709711960470201906326732033816522202617817869465691798938486540955726912350768931476362143768721380759395525951947017232778140349423557015356082357043807910825817719748257213281893007933859227824276579765323175836008193865064772817200047353825332039369252224256435661514851653526942065285711420907389170574343434449883875510985495078384130667046036846831401643151166834922210257258578675547742596423035828159461629721005113634334227074529533688136165903014911127"
158158- and q = Z.of_string "72036757532428134359049138716615314032674441223147930984416116642785279309001"
159159- and gg = Z.of_string "988301665281495772390013694627509692333967846948672137624515090935924385717634154201978961497509784579332702743535206413508559565302483922898459454403718843912379531742192312937734625047119678718271184170003455506604118936761508195594240052138536667234693864514877750501896049675764191029147963148241546820518065141123555298022010467792468407477159110344370654433269478015817957411602389410658876373667769353995724289566719120654426746425129842353040271693696527020500630012804936844492302532860691617810440827122662134370347136275931360845416833023047973072799739252681873195380321841873819721774703093238289342578739869306714624065593724407718101053836638039267362740083113357679437895609399028133545708736803196232072972950098992845234240283344492163375862712470338417546036591824286944195749933069780384676421299008472374982388004050973085425949637720603596481254386896408204626665775305048865550117840561595366712598318"
160160- and x = Z.of_string "57079433780483458942713357293831115449694380253611914431677328021806898761674"
161161- and y = Z.of_string "2872172233173100601346399502391482510148300641600207189246652621232656647081281141886455256814187251102030580186748870087277263359506423691023579912476503628426574690699263443704236625550832436226673947182294798279064154375422081421444400893924415563728656687773617245084962617886701420982288621397340217078717788290878177343138178149109067141997920049624616209300715994802074480057682676445987819355778630849636079364539062466859717465892222793824712941403252645431023939220711618233660062829520555618350855085688062241702521140104357981881833598269736147371800258828202964600523335598361833482597511071900975835195171061421945579132277176597724513608746614358311884564512362186106480065540201711903122228315570389409204443391052987813355120223856839756971514334338065850104261467285471383663470187296456006848469765768400814476981451863643010333596484259098557995874127140419649424228480234701334240448168704764430867915060"
200200+ let p =
201201+ Z.of_string
202202+ "4944862491052787177238323499959371418651354629231656321315236369672827559263545931134286049323485061071828187289578269594065783019111035804017538871324004047710342711620233110167493989997579634523303899794913823240058891327833786211541568251787338957336540247816021098378292806006955851897646808403078979142749428669072523191276645021175423303816467433407072660616741824124536840773744646488191896772232795413707995397140064396495425700133866462410490239713815308709711960470201906326732033816522202617817869465691798938486540955726912350768931476362143768721380759395525951947017232778140349423557015356082357043807910825817719748257213281893007933859227824276579765323175836008193865064772817200047353825332039369252224256435661514851653526942065285711420907389170574343434449883875510985495078384130667046036846831401643151166834922210257258578675547742596423035828159461629721005113634334227074529533688136165903014911127"
203203+ and q =
204204+ Z.of_string
205205+ "72036757532428134359049138716615314032674441223147930984416116642785279309001"
206206+ and gg =
207207+ Z.of_string
208208+ "988301665281495772390013694627509692333967846948672137624515090935924385717634154201978961497509784579332702743535206413508559565302483922898459454403718843912379531742192312937734625047119678718271184170003455506604118936761508195594240052138536667234693864514877750501896049675764191029147963148241546820518065141123555298022010467792468407477159110344370654433269478015817957411602389410658876373667769353995724289566719120654426746425129842353040271693696527020500630012804936844492302532860691617810440827122662134370347136275931360845416833023047973072799739252681873195380321841873819721774703093238289342578739869306714624065593724407718101053836638039267362740083113357679437895609399028133545708736803196232072972950098992845234240283344492163375862712470338417546036591824286944195749933069780384676421299008472374982388004050973085425949637720603596481254386896408204626665775305048865550117840561595366712598318"
209209+ and x =
210210+ Z.of_string
211211+ "57079433780483458942713357293831115449694380253611914431677328021806898761674"
212212+ and y =
213213+ Z.of_string
214214+ "2872172233173100601346399502391482510148300641600207189246652621232656647081281141886455256814187251102030580186748870087277263359506423691023579912476503628426574690699263443704236625550832436226673947182294798279064154375422081421444400893924415563728656687773617245084962617886701420982288621397340217078717788290878177343138178149109067141997920049624616209300715994802074480057682676445987819355778630849636079364539062466859717465892222793824712941403252645431023939220711618233660062829520555618350855085688062241702521140104357981881833598269736147371800258828202964600523335598361833482597511071900975835195171061421945579132277176597724513608746614358311884564512362186106480065540201711903122228315570389409204443391052987813355120223856839756971514334338065850104261467285471383663470187296456006848469765768400814476981451863643010333596484259098557995874127140419649424228480234701334240448168704764430867915060"
162215 in
163163- match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with Ok p -> p | _ -> assert false
216216+ match Crypto_pk.Dsa.priv ~fips:true ~p ~q ~gg ~x ~y () with
217217+ | Ok p -> p
218218+ | _ -> assert false
164219165220let dsa_sig_3072 () = Crypto_pk.Dsa.sign ~key:dsa_3072 msg_str
166221167222let dh_groups =
168168- ["oakley5 (1536)",Crypto_pk.Dh.Group.oakley_5;
169169- "oakley14 (2048)",Crypto_pk.Dh.Group.oakley_14;
170170- "ffdhe2048",Crypto_pk.Dh.Group.ffdhe2048;
171171- "ffdhe3072",Crypto_pk.Dh.Group.ffdhe3072;
172172- "ffdhe4096",Crypto_pk.Dh.Group.ffdhe4096;
173173- "ffdhe6144",Crypto_pk.Dh.Group.ffdhe6144]
223223+ [
224224+ ("oakley5 (1536)", Crypto_pk.Dh.Group.oakley_5);
225225+ ("oakley14 (2048)", Crypto_pk.Dh.Group.oakley_14);
226226+ ("ffdhe2048", Crypto_pk.Dh.Group.ffdhe2048);
227227+ ("ffdhe3072", Crypto_pk.Dh.Group.ffdhe3072);
228228+ ("ffdhe4096", Crypto_pk.Dh.Group.ffdhe4096);
229229+ ("ffdhe6144", Crypto_pk.Dh.Group.ffdhe6144);
230230+ ]
174231175232let dh_secrets =
176176- List.map2 (fun (n, group) s ->
177177- (n, group), Crypto_pk.Dh.key_of_secret group ~s)
233233+ List.map2
234234+ (fun (n, group) s -> ((n, group), Crypto_pk.Dh.key_of_secret group ~s))
178235 dh_groups
179179- (List.map (fun s -> Z.of_string s |> Crypto_pk.Z_extra.to_octets_be)
236236+ (List.map
237237+ (fun s -> Z.of_string s |> Crypto_pk.Z_extra.to_octets_be)
180238 [
181181- "31271182055444024732867835946284871743952969208281694762833912267184" ;
182182- "27594341083884344999714422172371027333192426063917478556668524561591" ;
183183- "49745209598738800585479479877345156590922715411063492309021724116430" ;
184184- "54263413298355776701974737228250185414758929445654879795198916482466337662578919821" ;
185185- "38599161911587526396222063388324161227700603198435442693976375015855884010520671067171149524070089" ;
186186- "60057457975706301816395663645420233759377744187465730049174048360108513636349450241008234412972340882517684187851" ;
239239+ "31271182055444024732867835946284871743952969208281694762833912267184";
240240+ "27594341083884344999714422172371027333192426063917478556668524561591";
241241+ "49745209598738800585479479877345156590922715411063492309021724116430";
242242+ "54263413298355776701974737228250185414758929445654879795198916482466337662578919821";
243243+ "38599161911587526396222063388324161227700603198435442693976375015855884010520671067171149524070089";
244244+ "60057457975706301816395663645420233759377744187465730049174048360108513636349450241008234412972340882517684187851";
187245 ])
188246189247let ecdsa_p256 =
···208266let ecdsa_p521_sig () = Crypto_ec.P521.Dsa.sign ~key:ecdsa_p521 msg_str_65
209267210268let ed25519 =
211211- Result.get_ok (Crypto_ec.Ed25519.priv_of_octets
212212- "\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")
269269+ Result.get_ok
270270+ (Crypto_ec.Ed25519.priv_of_octets
271271+ "\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")
213272214273let ed25519_sig () = Crypto_ec.Ed25519.sign ~key:ed25519 msg_str
215274216216-let ecdsas = [
217217- ("P256", `P256 (ecdsa_p256, ecdsa_p256_sig ()));
218218- ("P384", `P384 (ecdsa_p384, ecdsa_p384_sig ()));
219219- ("P521", `P521 (ecdsa_p521, ecdsa_p521_sig ()));
220220- ("Ed25519", `Ed25519 (ed25519, ed25519_sig ()));
221221-]
275275+let ecdsas =
276276+ [
277277+ ("P256", `P256 (ecdsa_p256, ecdsa_p256_sig ()));
278278+ ("P384", `P384 (ecdsa_p384, ecdsa_p384_sig ()));
279279+ ("P521", `P521 (ecdsa_p521, ecdsa_p521_sig ()));
280280+ ("Ed25519", `Ed25519 (ed25519, ed25519_sig ()));
281281+ ]
222282223283let ecdh_shares =
224284 [
225225- ("P256", `P256 (Crypto_ec.P256.Dh.secret_of_octets "\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" |> Result.get_ok |> fst,
226226- "\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"));
227227- ("P384", `P384 (Crypto_ec.P384.Dh.secret_of_octets "\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" |> Result.get_ok |> fst,
228228- "\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"));
229229- ("P521", `P521 (Crypto_ec.P521.Dh.secret_of_octets "\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" |> Result.get_ok |> fst,
230230- "\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"));
231231- ("X25519", `X25519 (Crypto_ec.X25519.secret_of_octets "\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" |> Result.get_ok |> fst,
232232- "\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"));
285285+ ( "P256",
286286+ `P256
287287+ ( Crypto_ec.P256.Dh.secret_of_octets
288288+ "\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"
289289+ |> Result.get_ok |> fst,
290290+ "\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"
291291+ ) );
292292+ ( "P384",
293293+ `P384
294294+ ( Crypto_ec.P384.Dh.secret_of_octets
295295+ "\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"
296296+ |> Result.get_ok |> fst,
297297+ "\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"
298298+ ) );
299299+ ( "P521",
300300+ `P521
301301+ ( Crypto_ec.P521.Dh.secret_of_octets
302302+ "\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"
303303+ |> Result.get_ok |> fst,
304304+ "\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"
305305+ ) );
306306+ ( "X25519",
307307+ `X25519
308308+ ( Crypto_ec.X25519.secret_of_octets
309309+ "\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"
310310+ |> Result.get_ok |> fst,
311311+ "\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"
312312+ ) );
233313 ]
234314235315let bm name f = (name, fun () -> f name)
236316237237-let benchmarks = [
238238-239239- bm "rsa-generate" (fun name ->
240240- count name (fun bits -> Crypto_pk.Rsa.generate ~bits ())
241241- string_of_int [1024;2048;4096]) ;
242242-243243- bm "rsa-encrypt" (fun name ->
244244- count name (fun key -> Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv key) msg_str))
245245- (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
246246- [rsa_1024;rsa_2048;rsa_4096]) ;
247247-248248- bm "rsa-decrypt" (fun name ->
249249- count name (fun (key, msg) -> Crypto_pk.Rsa.(decrypt ~key msg))
250250- (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
251251- [rsa_1024,enc_1024 ; rsa_2048,enc_2048 ; rsa_4096,enc_4096]) ;
252252-253253- bm "rsa-pkcs1-encrypt" (fun name ->
254254- count name (fun key -> Crypto_pk.Rsa.(PKCS1.encrypt ~key:(pub_of_priv key) msg_str))
255255- (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
256256- [rsa_1024;rsa_2048;rsa_4096]) ;
257257-258258- bm "rsa-pkcs1-decrypt" (fun name ->
259259- count name (fun (key, msg) -> Crypto_pk.Rsa.(PKCS1.decrypt ~key msg))
260260- (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
261261- [rsa_1024,pkcs1_enc_1024 () ; rsa_2048,pkcs1_enc_2048 () ; rsa_4096,pkcs1_enc_4096 ()]) ;
262262-263263- bm "rsa-pkcs1-sign" (fun name ->
264264- count name (fun key -> Crypto_pk.Rsa.PKCS1.sign ~hash:`SHA256 ~key (`Message msg_str))
265265- (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
266266- [rsa_1024;rsa_2048;rsa_4096]) ;
267267-268268- bm "rsa-pkcs1-verify" (fun name ->
269269- count name (fun (key, signature) ->
270270- Crypto_pk.Rsa.(PKCS1.verify ~hashp:(fun _ -> true) ~key:(pub_of_priv key) ~signature (`Message msg_str)))
271271- (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
272272- [rsa_1024,pkcs1_sig_1024 () ; rsa_2048,pkcs1_sig_2048 () ; rsa_4096,pkcs1_sig_4096 ()]) ;
273273-274274- bm "rsa-pss-sign" (fun name ->
275275- count name (fun key -> PSS.sign ~key (`Message msg_str))
276276- (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
277277- [rsa_1024;rsa_2048;rsa_4096]) ;
278278-279279- bm "rsa-pss-verify" (fun name ->
280280- count name (fun (key, signature) ->
281281- PSS.verify ~key:(Crypto_pk.Rsa.pub_of_priv key) ~signature (`Message msg_str))
282282- (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
283283- [rsa_1024,pss_sig_1024 () ; rsa_2048,pss_sig_2048 () ; rsa_4096,pss_sig_4096 ()]) ;
284284-285285- bm "dsa-generate" (fun name ->
286286- count name (fun ks -> Crypto_pk.Dsa.generate ks)
287287- (function `Fips1024 -> "1024" | `Fips2048 -> "2048" | `Fips3072 -> "3072" | `Exactly (l, _) -> string_of_int l)
288288- [`Fips1024;`Fips2048;`Fips3072]);
289289-290290- bm "dsa-sign" (fun name ->
291291- count name (fun key -> Crypto_pk.Dsa.sign ~key msg_str)
292292- (fun k -> string_of_int (Z.numbits k.p))
293293- [dsa_1024;dsa_2048;dsa_3072]);
294294-295295- bm "dsa-verify" (fun name ->
296296- count name (fun (key, signature) ->
297297- Crypto_pk.Dsa.(verify ~key:(pub_of_priv key) signature msg_str))
298298- (fun (k, _) -> string_of_int (Z.numbits k.p))
299299- [dsa_1024,dsa_sig_1024 () ; dsa_2048,dsa_sig_2048 () ; dsa_3072,dsa_sig_3072 ()]);
300300-301301- bm "ecdsa-generate" (fun name ->
302302- let open Crypto_ec in
303303- count name
304304- (fun (_, x) -> match x with
305305- | `P256 _ -> P256.Dsa.generate () |> ignore
306306- | `P384 _ -> P384.Dsa.generate () |> ignore
307307- | `P521 _ -> P521.Dsa.generate () |> ignore
308308- | `Ed25519 _ -> Ed25519.generate () |> ignore
309309- )
310310- fst ecdsas);
311311-312312- bm "ecdsa-sign" (fun name ->
313313- let open Crypto_ec in
314314- count name (fun (_, x) -> match x with
315315- | `P256 (key, _) -> P256.Dsa.sign ~key msg_str_32
316316- | `P384 (key, _) -> P384.Dsa.sign ~key msg_str_48
317317- | `P521 (key, _) -> P521.Dsa.sign ~key msg_str_65
318318- | `Ed25519 (key, _) -> Ed25519.sign ~key msg_str, ""
319319- )
320320- fst ecdsas);
321321-322322- bm "ecdsa-verify" (fun name ->
323323- let open Crypto_ec in
324324- count name (fun (_, x) -> match x with
325325- | `P256 (key, signature) -> P256.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_32)
326326- | `P384 (key, signature) -> P384.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_48)
327327- | `P521 (key, signature) -> P521.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_65)
328328- | `Ed25519 (key, signature) -> Ed25519.(verify ~key:(pub_of_priv key) signature ~msg:msg_str)
329329- ) fst ecdsas);
330330-331331- bm "dh-secret" (fun name ->
332332- count name (fun (_, group) -> Crypto_pk.Dh.gen_key group)
333333- fst dh_groups);
334334-335335- bm "dh-share" (fun name ->
336336- count name (fun (_, (sec, share)) ->
337337- Crypto_pk.Dh.shared sec share)
338338- (fun ((g, _), _) -> g) dh_secrets);
339339-340340- bm "ecdh-secret" (fun name ->
341341- let open Crypto_ec in
342342- count name (fun (_, x) -> match x with
343343- | `P256 _ -> P256.Dh.gen_key () |> ignore
344344- | `P384 _ -> P384.Dh.gen_key () |> ignore
345345- | `P521 _ -> P521.Dh.gen_key () |> ignore
346346- | `X25519 _ -> X25519.gen_key () |> ignore)
347347- fst ecdh_shares);
348348-349349- bm "ecdh-share" (fun name ->
350350- let open Crypto_ec in
351351- count name (fun (_, x) -> match x with
352352- | `P256 (sec, share) -> P256.Dh.key_exchange sec share |> Result.get_ok |> ignore
353353- | `P384 (sec, share) -> P384.Dh.key_exchange sec share |> Result.get_ok |> ignore
354354- | `P521 (sec, share) -> P521.Dh.key_exchange sec share |> Result.get_ok |> ignore
355355- | `X25519 (sec, share) -> X25519.key_exchange sec share |> Result.get_ok |> ignore)
356356- fst ecdh_shares);
357357-358358- bm "chacha20-poly1305" (fun name ->
359359- let key = Chacha20.of_secret (Crypto_rng.generate 32)
360360- and nonce = Crypto_rng.generate 8 in
361361- throughput_into ~add:Chacha20.tag_size name
362362- (fun dst cs -> Chacha20.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs))) ;
363363-364364- bm "chacha20-poly1305-unsafe" (fun name ->
365365- let key = Chacha20.of_secret (Crypto_rng.generate 32)
366366- and nonce = Crypto_rng.generate 8 in
367367- throughput_into ~add:Chacha20.tag_size name
368368- (fun dst cs -> Chacha20.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs))) ;
369369-370370- bm "aes-128-ecb" (fun name ->
371371- let key = AES.ECB.of_secret (Crypto_rng.generate 16) in
372372- throughput_into name
373373- (fun dst cs -> AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
374374-375375- bm "aes-192-ecb" (fun name ->
376376- let key = AES.ECB.of_secret (Crypto_rng.generate 24) in
377377- throughput_into name (fun dst cs -> AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
378378-379379- bm "aes-192-ecb-unsafe" (fun name ->
380380- let key = AES.ECB.of_secret (Crypto_rng.generate 24) in
381381- throughput_into name (fun dst cs -> AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
382382-383383- bm "aes-256-ecb" (fun name ->
384384- let key = AES.ECB.of_secret (Crypto_rng.generate 32) in
385385- throughput_into name (fun dst cs -> AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
386386-387387- bm "aes-256-ecb-unsafe" (fun name ->
388388- let key = AES.ECB.of_secret (Crypto_rng.generate 32) in
389389- throughput_into name (fun dst cs -> AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
390390-391391- bm "aes-128-ecb-unsafe" (fun name ->
392392- let key = AES.ECB.of_secret (Crypto_rng.generate 16) in
393393- throughput_into name
394394- (fun dst cs -> AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
395395-396396- bm "aes-128-cbc-e" (fun name ->
397397- let key = AES.CBC.of_secret (Crypto_rng.generate 16)
398398- and iv = Crypto_rng.generate 16 in
399399- throughput_into name
400400- (fun dst cs -> AES.CBC.encrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
401401-402402- bm "aes-128-cbc-e-unsafe" (fun name ->
403403- let key = AES.CBC.of_secret (Crypto_rng.generate 16)
404404- and iv = Crypto_rng.generate 16 in
405405- throughput_into name
406406- (fun dst cs -> AES.CBC.unsafe_encrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
407407-408408- bm "aes-128-cbc-e-unsafe-inplace" (fun name ->
409409- let key = AES.CBC.of_secret (Crypto_rng.generate 16)
410410- and iv = Crypto_rng.generate 16 in
411411- throughput name
412412- (fun cs ->
413413- let b = Bytes.unsafe_of_string cs in
414414- AES.CBC.unsafe_encrypt_into_inplace ~key ~iv b ~dst_off:0 (String.length cs))) ;
415415-416416- bm "aes-128-cbc-d" (fun name ->
417417- let key = AES.CBC.of_secret (Crypto_rng.generate 16)
418418- and iv = Crypto_rng.generate 16 in
419419- throughput_into name
420420- (fun dst cs -> AES.CBC.decrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
421421-422422- bm "aes-128-cbc-d-unsafe" (fun name ->
423423- let key = AES.CBC.of_secret (Crypto_rng.generate 16)
424424- and iv = Crypto_rng.generate 16 in
425425- throughput_into name
426426- (fun dst cs -> AES.CBC.unsafe_decrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
427427-428428- bm "aes-128-ctr" (fun name ->
429429- let key = Crypto_rng.generate 16 |> AES.CTR.of_secret
430430- and ctr = Crypto_rng.generate 16 |> AES.CTR.ctr_of_octets in
431431- throughput_into name (fun dst cs -> AES.CTR.encrypt_into ~key ~ctr cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
432432-433433- bm "aes-128-ctr-unsafe" (fun name ->
434434- let key = Crypto_rng.generate 16 |> AES.CTR.of_secret
435435- and ctr = Crypto_rng.generate 16 |> AES.CTR.ctr_of_octets in
436436- throughput_into name (fun dst cs -> AES.CTR.unsafe_encrypt_into ~key ~ctr cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
437437-438438- bm "aes-128-gcm" (fun name ->
439439- let key = AES.GCM.of_secret (Crypto_rng.generate 16)
440440- and nonce = Crypto_rng.generate 12 in
441441- throughput_into ~add:AES.GCM.tag_size name
442442- (fun dst cs -> AES.GCM.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
443443-444444- bm "aes-128-gcm-unsafe" (fun name ->
445445- let key = AES.GCM.of_secret (Crypto_rng.generate 16)
446446- and nonce = Crypto_rng.generate 12 in
447447- throughput_into ~add:AES.GCM.tag_size name
448448- (fun dst cs -> AES.GCM.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
449449-450450- bm "aes-128-ghash" (fun name ->
451451- let key = AES.GCM.of_secret (Crypto_rng.generate 16)
452452- and nonce = Crypto_rng.generate 12 in
453453- throughput_into ~add:AES.GCM.tag_size name
454454- (fun dst cs -> AES.GCM.authenticate_encrypt_into ~key ~nonce ~adata:cs "" ~src_off:0 dst ~dst_off:0 ~tag_off:0 0));
455455-456456- bm "aes-128-ghash-unsafe" (fun name ->
457457- let key = AES.GCM.of_secret (Crypto_rng.generate 16)
458458- and nonce = Crypto_rng.generate 12 in
459459- throughput_into ~add:AES.GCM.tag_size name
460460- (fun dst cs -> AES.GCM.unsafe_authenticate_encrypt_into ~key ~nonce ~adata:cs "" ~src_off:0 dst ~dst_off:0 ~tag_off:0 0));
461461-462462- bm "aes-128-ccm" (fun name ->
463463- let key = AES.CCM16.of_secret (Crypto_rng.generate 16)
464464- and nonce = Crypto_rng.generate 10 in
465465- throughput_into ~add:AES.CCM16.tag_size name
466466- (fun dst cs -> AES.CCM16.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
467467-468468- bm "aes-128-ccm-unsafe" (fun name ->
469469- let key = AES.CCM16.of_secret (Crypto_rng.generate 16)
470470- and nonce = Crypto_rng.generate 10 in
471471- throughput_into ~add:AES.CCM16.tag_size name
472472- (fun dst cs -> AES.CCM16.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
473473-474474- bm "d3des-ecb" (fun name ->
475475- let key = DES.ECB.of_secret (Crypto_rng.generate 24) in
476476- throughput_into name (fun dst cs -> DES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
477477-478478- bm "d3des-ecb-unsafe" (fun name ->
479479- let key = DES.ECB.of_secret (Crypto_rng.generate 24) in
480480- throughput_into name (fun dst cs -> DES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ;
481481-482482- bm "fortuna" (fun name ->
483483- begin[@alert "-deprecated"]
484484- Crypto_rng_unix.initialize (module Crypto_rng.Fortuna);
485485- throughput name (fun buf ->
486486- let buf = Bytes.unsafe_of_string buf in
487487- Crypto_rng.generate_into buf ~off:0 (Bytes.length buf))
488488- end);
489489-490490- bm "getentropy" (fun name ->
491491- Crypto_rng_unix.use_getentropy ();
492492- throughput name (fun buf ->
493493- let buf = Bytes.unsafe_of_string buf in
494494- Crypto_rng.generate_into buf ~off:0 (Bytes.length buf))) ;
495495-496496- bm "urandom" (fun name ->
497497- Crypto_rng_unix.use_dev_urandom ();
498498- throughput name (fun buf ->
499499- let buf = Bytes.unsafe_of_string buf in
500500- Crypto_rng.generate_into buf ~off:0 (Bytes.length buf))) ;
501501-]
317317+let benchmarks =
318318+ [
319319+ bm "rsa-generate" (fun name ->
320320+ count name
321321+ (fun bits -> Crypto_pk.Rsa.generate ~bits ())
322322+ string_of_int [ 1024; 2048; 4096 ]);
323323+ bm "rsa-encrypt" (fun name ->
324324+ count name
325325+ (fun key -> Crypto_pk.Rsa.(encrypt ~key:(pub_of_priv key) msg_str))
326326+ (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
327327+ [ rsa_1024; rsa_2048; rsa_4096 ]);
328328+ bm "rsa-decrypt" (fun name ->
329329+ count name
330330+ (fun (key, msg) -> Crypto_pk.Rsa.(decrypt ~key msg))
331331+ (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
332332+ [ (rsa_1024, enc_1024); (rsa_2048, enc_2048); (rsa_4096, enc_4096) ]);
333333+ bm "rsa-pkcs1-encrypt" (fun name ->
334334+ count name
335335+ (fun key ->
336336+ Crypto_pk.Rsa.(PKCS1.encrypt ~key:(pub_of_priv key) msg_str))
337337+ (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
338338+ [ rsa_1024; rsa_2048; rsa_4096 ]);
339339+ bm "rsa-pkcs1-decrypt" (fun name ->
340340+ count name
341341+ (fun (key, msg) -> Crypto_pk.Rsa.(PKCS1.decrypt ~key msg))
342342+ (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
343343+ [
344344+ (rsa_1024, pkcs1_enc_1024 ());
345345+ (rsa_2048, pkcs1_enc_2048 ());
346346+ (rsa_4096, pkcs1_enc_4096 ());
347347+ ]);
348348+ bm "rsa-pkcs1-sign" (fun name ->
349349+ count name
350350+ (fun key ->
351351+ Crypto_pk.Rsa.PKCS1.sign ~hash:`SHA256 ~key (`Message msg_str))
352352+ (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
353353+ [ rsa_1024; rsa_2048; rsa_4096 ]);
354354+ bm "rsa-pkcs1-verify" (fun name ->
355355+ count name
356356+ (fun (key, signature) ->
357357+ Crypto_pk.Rsa.(
358358+ PKCS1.verify
359359+ ~hashp:(fun _ -> true)
360360+ ~key:(pub_of_priv key) ~signature (`Message msg_str)))
361361+ (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
362362+ [
363363+ (rsa_1024, pkcs1_sig_1024 ());
364364+ (rsa_2048, pkcs1_sig_2048 ());
365365+ (rsa_4096, pkcs1_sig_4096 ());
366366+ ]);
367367+ bm "rsa-pss-sign" (fun name ->
368368+ count name
369369+ (fun key -> PSS.sign ~key (`Message msg_str))
370370+ (fun k -> string_of_int (Crypto_pk.Rsa.priv_bits k))
371371+ [ rsa_1024; rsa_2048; rsa_4096 ]);
372372+ bm "rsa-pss-verify" (fun name ->
373373+ count name
374374+ (fun (key, signature) ->
375375+ PSS.verify
376376+ ~key:(Crypto_pk.Rsa.pub_of_priv key)
377377+ ~signature (`Message msg_str))
378378+ (fun (k, _) -> string_of_int (Crypto_pk.Rsa.priv_bits k))
379379+ [
380380+ (rsa_1024, pss_sig_1024 ());
381381+ (rsa_2048, pss_sig_2048 ());
382382+ (rsa_4096, pss_sig_4096 ());
383383+ ]);
384384+ bm "dsa-generate" (fun name ->
385385+ count name
386386+ (fun ks -> Crypto_pk.Dsa.generate ks)
387387+ (function
388388+ | `Fips1024 -> "1024"
389389+ | `Fips2048 -> "2048"
390390+ | `Fips3072 -> "3072"
391391+ | `Exactly (l, _) -> string_of_int l)
392392+ [ `Fips1024; `Fips2048; `Fips3072 ]);
393393+ bm "dsa-sign" (fun name ->
394394+ count name
395395+ (fun key -> Crypto_pk.Dsa.sign ~key msg_str)
396396+ (fun k -> string_of_int (Z.numbits k.p))
397397+ [ dsa_1024; dsa_2048; dsa_3072 ]);
398398+ bm "dsa-verify" (fun name ->
399399+ count name
400400+ (fun (key, signature) ->
401401+ Crypto_pk.Dsa.(verify ~key:(pub_of_priv key) signature msg_str))
402402+ (fun (k, _) -> string_of_int (Z.numbits k.p))
403403+ [
404404+ (dsa_1024, dsa_sig_1024 ());
405405+ (dsa_2048, dsa_sig_2048 ());
406406+ (dsa_3072, dsa_sig_3072 ());
407407+ ]);
408408+ bm "ecdsa-generate" (fun name ->
409409+ let open Crypto_ec in
410410+ count name
411411+ (fun (_, x) ->
412412+ match x with
413413+ | `P256 _ -> P256.Dsa.generate () |> ignore
414414+ | `P384 _ -> P384.Dsa.generate () |> ignore
415415+ | `P521 _ -> P521.Dsa.generate () |> ignore
416416+ | `Ed25519 _ -> Ed25519.generate () |> ignore)
417417+ fst ecdsas);
418418+ bm "ecdsa-sign" (fun name ->
419419+ let open Crypto_ec in
420420+ count name
421421+ (fun (_, x) ->
422422+ match x with
423423+ | `P256 (key, _) -> P256.Dsa.sign ~key msg_str_32
424424+ | `P384 (key, _) -> P384.Dsa.sign ~key msg_str_48
425425+ | `P521 (key, _) -> P521.Dsa.sign ~key msg_str_65
426426+ | `Ed25519 (key, _) -> (Ed25519.sign ~key msg_str, ""))
427427+ fst ecdsas);
428428+ bm "ecdsa-verify" (fun name ->
429429+ let open Crypto_ec in
430430+ count name
431431+ (fun (_, x) ->
432432+ match x with
433433+ | `P256 (key, signature) ->
434434+ P256.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_32)
435435+ | `P384 (key, signature) ->
436436+ P384.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_48)
437437+ | `P521 (key, signature) ->
438438+ P521.Dsa.(verify ~key:(pub_of_priv key) signature msg_str_65)
439439+ | `Ed25519 (key, signature) ->
440440+ Ed25519.(verify ~key:(pub_of_priv key) signature ~msg:msg_str))
441441+ fst ecdsas);
442442+ bm "dh-secret" (fun name ->
443443+ count name (fun (_, group) -> Crypto_pk.Dh.gen_key group) fst dh_groups);
444444+ bm "dh-share" (fun name ->
445445+ count name
446446+ (fun (_, (sec, share)) -> Crypto_pk.Dh.shared sec share)
447447+ (fun ((g, _), _) -> g)
448448+ dh_secrets);
449449+ bm "ecdh-secret" (fun name ->
450450+ let open Crypto_ec in
451451+ count name
452452+ (fun (_, x) ->
453453+ match x with
454454+ | `P256 _ -> P256.Dh.gen_key () |> ignore
455455+ | `P384 _ -> P384.Dh.gen_key () |> ignore
456456+ | `P521 _ -> P521.Dh.gen_key () |> ignore
457457+ | `X25519 _ -> X25519.gen_key () |> ignore)
458458+ fst ecdh_shares);
459459+ bm "ecdh-share" (fun name ->
460460+ let open Crypto_ec in
461461+ count name
462462+ (fun (_, x) ->
463463+ match x with
464464+ | `P256 (sec, share) ->
465465+ P256.Dh.key_exchange sec share |> Result.get_ok |> ignore
466466+ | `P384 (sec, share) ->
467467+ P384.Dh.key_exchange sec share |> Result.get_ok |> ignore
468468+ | `P521 (sec, share) ->
469469+ P521.Dh.key_exchange sec share |> Result.get_ok |> ignore
470470+ | `X25519 (sec, share) ->
471471+ X25519.key_exchange sec share |> Result.get_ok |> ignore)
472472+ fst ecdh_shares);
473473+ bm "chacha20-poly1305" (fun name ->
474474+ let key = Chacha20.of_secret (Crypto_rng.generate 32)
475475+ and nonce = Crypto_rng.generate 8 in
476476+ throughput_into ~add:Chacha20.tag_size name (fun dst cs ->
477477+ Chacha20.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst
478478+ ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
479479+ bm "chacha20-poly1305-unsafe" (fun name ->
480480+ let key = Chacha20.of_secret (Crypto_rng.generate 32)
481481+ and nonce = Crypto_rng.generate 8 in
482482+ throughput_into ~add:Chacha20.tag_size name (fun dst cs ->
483483+ Chacha20.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0
484484+ dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
485485+ bm "aes-128-ecb" (fun name ->
486486+ let key = AES.ECB.of_secret (Crypto_rng.generate 16) in
487487+ throughput_into name (fun dst cs ->
488488+ AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
489489+ (String.length cs)));
490490+ bm "aes-192-ecb" (fun name ->
491491+ let key = AES.ECB.of_secret (Crypto_rng.generate 24) in
492492+ throughput_into name (fun dst cs ->
493493+ AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
494494+ (String.length cs)));
495495+ bm "aes-192-ecb-unsafe" (fun name ->
496496+ let key = AES.ECB.of_secret (Crypto_rng.generate 24) in
497497+ throughput_into name (fun dst cs ->
498498+ AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
499499+ (String.length cs)));
500500+ bm "aes-256-ecb" (fun name ->
501501+ let key = AES.ECB.of_secret (Crypto_rng.generate 32) in
502502+ throughput_into name (fun dst cs ->
503503+ AES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
504504+ (String.length cs)));
505505+ bm "aes-256-ecb-unsafe" (fun name ->
506506+ let key = AES.ECB.of_secret (Crypto_rng.generate 32) in
507507+ throughput_into name (fun dst cs ->
508508+ AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
509509+ (String.length cs)));
510510+ bm "aes-128-ecb-unsafe" (fun name ->
511511+ let key = AES.ECB.of_secret (Crypto_rng.generate 16) in
512512+ throughput_into name (fun dst cs ->
513513+ AES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
514514+ (String.length cs)));
515515+ bm "aes-128-cbc-e" (fun name ->
516516+ let key = AES.CBC.of_secret (Crypto_rng.generate 16)
517517+ and iv = Crypto_rng.generate 16 in
518518+ throughput_into name (fun dst cs ->
519519+ AES.CBC.encrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0
520520+ (String.length cs)));
521521+ bm "aes-128-cbc-e-unsafe" (fun name ->
522522+ let key = AES.CBC.of_secret (Crypto_rng.generate 16)
523523+ and iv = Crypto_rng.generate 16 in
524524+ throughput_into name (fun dst cs ->
525525+ AES.CBC.unsafe_encrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0
526526+ (String.length cs)));
527527+ bm "aes-128-cbc-e-unsafe-inplace" (fun name ->
528528+ let key = AES.CBC.of_secret (Crypto_rng.generate 16)
529529+ and iv = Crypto_rng.generate 16 in
530530+ throughput name (fun cs ->
531531+ let b = Bytes.unsafe_of_string cs in
532532+ AES.CBC.unsafe_encrypt_into_inplace ~key ~iv b ~dst_off:0
533533+ (String.length cs)));
534534+ bm "aes-128-cbc-d" (fun name ->
535535+ let key = AES.CBC.of_secret (Crypto_rng.generate 16)
536536+ and iv = Crypto_rng.generate 16 in
537537+ throughput_into name (fun dst cs ->
538538+ AES.CBC.decrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0
539539+ (String.length cs)));
540540+ bm "aes-128-cbc-d-unsafe" (fun name ->
541541+ let key = AES.CBC.of_secret (Crypto_rng.generate 16)
542542+ and iv = Crypto_rng.generate 16 in
543543+ throughput_into name (fun dst cs ->
544544+ AES.CBC.unsafe_decrypt_into ~key ~iv cs ~src_off:0 dst ~dst_off:0
545545+ (String.length cs)));
546546+ bm "aes-128-ctr" (fun name ->
547547+ let key = Crypto_rng.generate 16 |> AES.CTR.of_secret
548548+ and ctr = Crypto_rng.generate 16 |> AES.CTR.ctr_of_octets in
549549+ throughput_into name (fun dst cs ->
550550+ AES.CTR.encrypt_into ~key ~ctr cs ~src_off:0 dst ~dst_off:0
551551+ (String.length cs)));
552552+ bm "aes-128-ctr-unsafe" (fun name ->
553553+ let key = Crypto_rng.generate 16 |> AES.CTR.of_secret
554554+ and ctr = Crypto_rng.generate 16 |> AES.CTR.ctr_of_octets in
555555+ throughput_into name (fun dst cs ->
556556+ AES.CTR.unsafe_encrypt_into ~key ~ctr cs ~src_off:0 dst ~dst_off:0
557557+ (String.length cs)));
558558+ bm "aes-128-gcm" (fun name ->
559559+ let key = AES.GCM.of_secret (Crypto_rng.generate 16)
560560+ and nonce = Crypto_rng.generate 12 in
561561+ throughput_into ~add:AES.GCM.tag_size name (fun dst cs ->
562562+ AES.GCM.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst
563563+ ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
564564+ bm "aes-128-gcm-unsafe" (fun name ->
565565+ let key = AES.GCM.of_secret (Crypto_rng.generate 16)
566566+ and nonce = Crypto_rng.generate 12 in
567567+ throughput_into ~add:AES.GCM.tag_size name (fun dst cs ->
568568+ AES.GCM.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0
569569+ dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
570570+ bm "aes-128-ghash" (fun name ->
571571+ let key = AES.GCM.of_secret (Crypto_rng.generate 16)
572572+ and nonce = Crypto_rng.generate 12 in
573573+ throughput_into ~add:AES.GCM.tag_size name (fun dst cs ->
574574+ AES.GCM.authenticate_encrypt_into ~key ~nonce ~adata:cs ""
575575+ ~src_off:0 dst ~dst_off:0 ~tag_off:0 0));
576576+ bm "aes-128-ghash-unsafe" (fun name ->
577577+ let key = AES.GCM.of_secret (Crypto_rng.generate 16)
578578+ and nonce = Crypto_rng.generate 12 in
579579+ throughput_into ~add:AES.GCM.tag_size name (fun dst cs ->
580580+ AES.GCM.unsafe_authenticate_encrypt_into ~key ~nonce ~adata:cs ""
581581+ ~src_off:0 dst ~dst_off:0 ~tag_off:0 0));
582582+ bm "aes-128-ccm" (fun name ->
583583+ let key = AES.CCM16.of_secret (Crypto_rng.generate 16)
584584+ and nonce = Crypto_rng.generate 10 in
585585+ throughput_into ~add:AES.CCM16.tag_size name (fun dst cs ->
586586+ AES.CCM16.authenticate_encrypt_into ~key ~nonce cs ~src_off:0 dst
587587+ ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
588588+ bm "aes-128-ccm-unsafe" (fun name ->
589589+ let key = AES.CCM16.of_secret (Crypto_rng.generate 16)
590590+ and nonce = Crypto_rng.generate 10 in
591591+ throughput_into ~add:AES.CCM16.tag_size name (fun dst cs ->
592592+ AES.CCM16.unsafe_authenticate_encrypt_into ~key ~nonce cs ~src_off:0
593593+ dst ~dst_off:0 ~tag_off:(String.length cs) (String.length cs)));
594594+ bm "d3des-ecb" (fun name ->
595595+ let key = DES.ECB.of_secret (Crypto_rng.generate 24) in
596596+ throughput_into name (fun dst cs ->
597597+ DES.ECB.encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
598598+ (String.length cs)));
599599+ bm "d3des-ecb-unsafe" (fun name ->
600600+ let key = DES.ECB.of_secret (Crypto_rng.generate 24) in
601601+ throughput_into name (fun dst cs ->
602602+ DES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0
603603+ (String.length cs)));
604604+ bm "fortuna" (fun name ->
605605+ begin[@alert "-deprecated"]
606606+ Crypto_rng_unix.initialize (module Crypto_rng.Fortuna);
607607+ throughput name (fun buf ->
608608+ let buf = Bytes.unsafe_of_string buf in
609609+ Crypto_rng.generate_into buf ~off:0 (Bytes.length buf))
610610+ end);
611611+ bm "getentropy" (fun name ->
612612+ Crypto_rng_unix.use_getentropy ();
613613+ throughput name (fun buf ->
614614+ let buf = Bytes.unsafe_of_string buf in
615615+ Crypto_rng.generate_into buf ~off:0 (Bytes.length buf)));
616616+ bm "urandom" (fun name ->
617617+ Crypto_rng_unix.use_dev_urandom ();
618618+ throughput name (fun buf ->
619619+ let buf = Bytes.unsafe_of_string buf in
620620+ Crypto_rng.generate_into buf ~off:0 (Bytes.length buf)));
621621+ ]
502622503623let help () =
504624 Printf.printf "available benchmarks:\n ";
505505- List.iter (fun (n, _) -> Printf.printf "%s " n) benchmarks ;
625625+ List.iter (fun (n, _) -> Printf.printf "%s " n) benchmarks;
506626 Printf.printf "\n%!"
507627508628let runv fs =
509629 Format.printf "accel: %a\n%!"
510510- (fun ppf -> List.iter @@ fun x ->
511511- Format.fprintf ppf "%s " @@
512512- match x with `XOR -> "XOR" | `AES -> "AES" | `GHASH -> "GHASH")
630630+ (fun ppf ->
631631+ List.iter @@ fun x ->
632632+ Format.fprintf ppf "%s "
633633+ @@ match x with `XOR -> "XOR" | `AES -> "AES" | `GHASH -> "GHASH")
513634 accelerated;
514514- Time.warmup () ;
635635+ Time.warmup ();
515636 List.iter (fun f -> f ()) fs
516516-517637518638let () =
519639 let seed = "abcd" in
520640 let g = Crypto_rng.(create ~seed (module Fortuna)) in
521641 Crypto_rng.set_default_generator g;
522642 match Array.to_list Sys.argv with
523523- | _::(_::_ as args) -> begin
643643+ | _ :: (_ :: _ as args) -> begin
524644 try
525645 let fs =
526526- args |> List.map @@ fun n ->
527527- snd (benchmarks |> List.find @@ fun (n1, _) -> n = n1) in
646646+ args
647647+ |> List.map @@ fun n ->
648648+ snd (benchmarks |> List.find @@ fun (n1, _) -> n = n1)
649649+ in
528650 runv fs
529651 with Not_found -> help ()
530652 end
+25-26
config/cfg.ml
···33 let ccomp_type_opt = Configurator.V1.ocaml_config_var c "ccomp_type" in
44 let arch =
55 let defines =
66- Configurator.V1.C_define.import
77- c
88- ~includes:[]
99- [("__x86_64__", Switch); ("__i386__", Switch); ("__powerpc64__", Switch);
1010- ("__s390x__", Switch); ("__aarch64__", Switch);
1111- ("_WIN64", Switch); ("_WIN32", Switch)]
66+ Configurator.V1.C_define.import c ~includes:[]
77+ [
88+ ("__x86_64__", Switch);
99+ ("__i386__", Switch);
1010+ ("__powerpc64__", Switch);
1111+ ("__s390x__", Switch);
1212+ ("__aarch64__", Switch);
1313+ ("_WIN64", Switch);
1414+ ("_WIN32", Switch);
1515+ ]
1216 in
1317 match defines with
1418 | (_, Switch true) :: _ -> `x86_64
···2226 in
2327 let os =
2428 let defines =
2525- Configurator.V1.C_define.import
2626- c
2727- ~includes:[]
2828- [("__APPLE__", Switch)]
2929+ Configurator.V1.C_define.import c ~includes:[] [ ("__APPLE__", Switch) ]
2930 in
3030- match defines with
3131- | (_, Switch true) :: _ -> `macos
3232- | _ -> `unknown
3131+ match defines with (_, Switch true) :: _ -> `macos | _ -> `unknown
3332 in
3433 let accelerate_flags =
3535- match arch, ccomp_type_opt with
3434+ match (arch, ccomp_type_opt) with
3635 | `x86_64, Some "msvc" -> [ "-DACCELERATE" ]
3736 | `x86_64, _ -> [ "-DACCELERATE"; "-mssse3"; "-maes"; "-mpclmul" ]
3837 | _ -> []
3938 in
4039 let ent_flags =
4141- match arch, ccomp_type_opt with
4040+ match (arch, ccomp_type_opt) with
4241 | (`x86_64 | `x86), Some "msvc" -> [ "-DENTROPY" ]
4342 | (`x86_64 | `x86), _ -> [ "-DENTROPY"; "-mrdrnd"; "-mrdseed" ]
4443 | _ -> []
4544 in
4645 let std_flags =
4746 match ccomp_type_opt with
4848- | Some "msvc" -> ["/Wall"]
4949- | _ -> ["--std=c11"; "-Wall"; "-Wextra"; "-Wpedantic"; "-O3"]
4747+ | Some "msvc" -> [ "/Wall" ]
4848+ | _ -> [ "--std=c11"; "-Wall"; "-Wextra"; "-Wpedantic"; "-O3" ]
5049 in
5150 let warn_flags =
5251 (* See #178, there may be false positives on ppc&s390 with no-stringop-overflow *)
5353- match arch, ccomp_type_opt with
5252+ match (arch, ccomp_type_opt) with
5453 | _, Some "msvc" -> [ "/WX" ]
5555- | (`ppc64, _) | (`s390x, _) -> [ "-Wno-stringop-overflow"; "-Werror" ]
5454+ | `ppc64, _ | `s390x, _ -> [ "-Wno-stringop-overflow"; "-Werror" ]
5655 | _ -> [ "-Werror" ]
5756 in
5858- let no_instcombine_on_macos = match arch, os with
5757+ let no_instcombine_on_macos =
5858+ match (arch, os) with
5959 | `arm64, `macos ->
6060- let res = Configurator.V1.Process.run c "cc" ["-dumpversion"] in
6161- if String.trim res.stdout = "14.0.3" then
6262- ["-mllvm"; "--instcombine-max-iterations=0"]
6363- (* macOS instcombine miscompilation with clang 14.0.3 *)
6464- else
6565- []
6060+ let res = Configurator.V1.Process.run c "cc" [ "-dumpversion" ] in
6161+ if String.trim res.stdout = "14.0.3" then
6262+ [ "-mllvm"; "--instcombine-max-iterations=0" ]
6363+ (* macOS instcombine miscompilation with clang 14.0.3 *)
6464+ else []
6665 | _ -> []
6766 in
6867 let flags = std_flags @ no_instcombine_on_macos @ ent_flags in
+475-273
ec/crypto_ec.ml
···11-type error = [
22- | `Invalid_format
11+type error =
22+ [ `Invalid_format
33 | `Invalid_length
44 | `Invalid_range
55 | `Not_on_curve
66 | `At_infinity
77- | `Low_order
88-]
77+ | `Low_order ]
98109let error_to_string = function
1110 | `Invalid_format -> "invalid format"
···2322 let res = Bytes.create len in
2423 for i = 0 to len - 1 do
2524 Bytes.set res (len - 1 - i) (String.get buf i)
2626- done ;
2525+ done;
2726 Bytes.unsafe_to_string res
28272928exception Message_too_long
···36353736module type Dh = sig
3837 type secret
3939- val secret_of_octets : ?compress:bool -> string ->
4040- (secret * string, error) result
3838+3939+ val secret_of_octets :
4040+ ?compress:bool -> string -> (secret * string, error) result
4141+4142 val secret_to_octets : secret -> string
4242- val gen_key : ?compress:bool -> ?g:Crypto_rng.g -> unit ->
4343- secret * string
4343+ val gen_key : ?compress:bool -> ?g:Crypto_rng.g -> unit -> secret * string
4444 val key_exchange : secret -> string -> (string, error) result
4545end
46464747module type Dsa = sig
4848 type priv
4949 type pub
5050+5051 val byte_length : int
5152 val bit_length : int
5253 val priv_of_octets : string -> (priv, error) result
···5758 val generate : ?g:Crypto_rng.g -> unit -> priv * pub
5859 val sign : key:priv -> ?k:string -> string -> string * string
5960 val verify : key:pub -> string * string -> string -> bool
6161+6062 module K_gen (H : Digestif.S) : sig
6163 val generate : key:priv -> string -> string
6264 end
6565+6366 module Precompute : sig
6467 val generator_tables : unit -> string array array array
6568 end
···6871module type Point = sig
6972 type point
7073 type scalar
7474+7175 val of_octets : string -> (point, error) result
7276 val to_octets : ?compress:bool -> point -> string
7377 val scalar_of_octets : string -> (scalar, error) result
···8488end
85898690type field_element = string
8787-8891type out_field_element = bytes
89929093module type Parameters = sig
···9497 val g_y : field_element
9598 val p : field_element
9699 val n : field_element
9797- val pident: string
100100+ val pident : string
98101 val byte_length : int
99102 val bit_length : int
100103 val fe_length : int
···103106104107type point = { f_x : field_element; f_y : field_element; f_z : field_element }
105108106106-type out_point = { m_f_x : out_field_element; m_f_y : out_field_element; m_f_z : out_field_element }
109109+type out_point = {
110110+ m_f_x : out_field_element;
111111+ m_f_y : out_field_element;
112112+ m_f_z : out_field_element;
113113+}
107114108115type scalar = Scalar of string
109116···119126 val from_montgomery : out_field_element -> field_element -> unit
120127 val to_octets : bytes -> field_element -> unit
121128 val inv : out_field_element -> field_element -> unit
122122- val select_c : out_field_element -> bool -> field_element -> field_element -> unit
129129+130130+ val select_c :
131131+ out_field_element -> bool -> field_element -> field_element -> unit
123132124133 val double_c : out_point -> point -> unit
125134 val add_c : out_point -> point -> point -> unit
···136145 val nz : field_element -> bool
137146 val sqr : field_element -> field_element
138147 val inv : field_element -> field_element
139139- val select : bool -> then_:field_element -> else_:field_element -> field_element
148148+149149+ val select :
150150+ bool -> then_:field_element -> else_:field_element -> field_element
151151+140152 val from_be_octets : string -> field_element
141153 val to_octets : field_element -> string
142154 val double_point : point -> point
···144156 val scalar_mult_base_point : scalar -> point
145157end
146158147147-module Make_field_element (P : Parameters) (F : Foreign) : Field_element = struct
159159+module Make_field_element (P : Parameters) (F : Foreign) : Field_element =
160160+struct
148161 let b_uts b = Bytes.unsafe_to_string b
149149-150162 let create () = Bytes.create P.fe_length
151163152164 let mul a b =
···202214 F.to_montgomery tmp (b_uts tmp);
203215 b_uts tmp
204216205205- let create_octets () =
206206- Bytes.create P.byte_length
217217+ let create_octets () = Bytes.create P.byte_length
207218208219 let to_octets fe =
209220 let tmp = create_octets () in
210221 F.to_octets tmp fe;
211222 b_uts tmp
212223213213- let out_point () = {
214214- m_f_x = create ();
215215- m_f_y = create ();
216216- m_f_z = create ();
217217- }
224224+ let out_point () = { m_f_x = create (); m_f_y = create (); m_f_z = create () }
218225219219- let out_p_to_p p = {
220220- f_x = b_uts p.m_f_x ;
221221- f_y = b_uts p.m_f_y ;
222222- f_z = b_uts p.m_f_z ;
223223- }
226226+ let out_p_to_p p =
227227+ { f_x = b_uts p.m_f_x; f_y = b_uts p.m_f_y; f_z = b_uts p.m_f_z }
224228225229 let double_point p =
226230 let tmp = out_point () in
···253257end
254258255259module Make_point_ops (P : Parameters) (F : Foreign) : Point_ops = struct
256256- module Fe = Make_field_element(P)(F)
260260+ module Fe = Make_field_element (P) (F)
257261258262 let at_infinity () =
259263 let f_x = Fe.one in
···286290 (** Convert coordinates to a finite point ensuring:
287291 - x < p
288292 - y < p
289289- - y^2 = ax^3 + ax + b
290290- *)
293293+ - y^2 = ax^3 + ax + b *)
291294 let validate_finite_point ~x ~y =
292295 match (check_coordinate x, check_coordinate y) with
293296 | Some f_x, Some f_y ->
294294- if is_solution_to_curve_equation ~x:f_x ~y:f_y then
295295- let f_z = Fe.one in
296296- Ok { f_x; f_y; f_z }
297297- else Error `Not_on_curve
297297+ if is_solution_to_curve_equation ~x:f_x ~y:f_y then
298298+ let f_z = Fe.one in
299299+ Ok { f_x; f_y; f_z }
300300+ else Error `Not_on_curve
298301 | _ -> Error `Invalid_range
299302300303 let to_affine_raw p =
301301- if is_infinity p then
302302- None
304304+ if is_infinity p then None
303305 else
304306 let z1 = Fe.from_montgomery p.f_z in
305307 let z2 = Fe.inv z1 in
···311313 Some (x, y)
312314313315 let to_affine p =
314314- Option.map (fun (x, y) -> Fe.to_octets x, Fe.to_octets y)
316316+ Option.map
317317+ (fun (x, y) -> (Fe.to_octets x, Fe.to_octets y))
315318 (to_affine_raw p)
316319317320 let to_octets ~compress p =
···319322 match to_affine p with
320323 | None -> String.make 1 '\000'
321324 | Some (x, y) ->
322322- let len_x = String.length x and len_y = String.length y in
323323- let res = Bytes.create (1 + len_x + len_y) in
324324- Bytes.set res 0 '\004' ;
325325- let rev_x = rev_string x and rev_y = rev_string y in
326326- Bytes.unsafe_blit_string rev_x 0 res 1 len_x ;
327327- Bytes.unsafe_blit_string rev_y 0 res (1 + len_x) len_y ;
328328- Bytes.unsafe_to_string res
325325+ let len_x = String.length x and len_y = String.length y in
326326+ let res = Bytes.create (1 + len_x + len_y) in
327327+ Bytes.set res 0 '\004';
328328+ let rev_x = rev_string x and rev_y = rev_string y in
329329+ Bytes.unsafe_blit_string rev_x 0 res 1 len_x;
330330+ Bytes.unsafe_blit_string rev_y 0 res (1 + len_x) len_y;
331331+ Bytes.unsafe_to_string res
329332 in
330330- if compress then
333333+ if compress then (
331334 let out = Bytes.create (P.byte_length + 1) in
332332- let ident =
333333- 2 + (String.get_uint8 buf (P.byte_length * 2)) land 1
334334- in
335335+ let ident = 2 + (String.get_uint8 buf (P.byte_length * 2) land 1) in
335336 Bytes.unsafe_blit_string buf 1 out 1 P.byte_length;
336337 Bytes.set_uint8 out 0 ident;
337337- Bytes.unsafe_to_string out
338338- else
339339- buf
338338+ Bytes.unsafe_to_string out)
339339+ else buf
340340341341 let double p = Fe.double_point p
342342-343342 let add p q = Fe.add_point p q
344343345344 let x_of_finite_point p =
···359358360359 let pow x exp =
361360 let r0 = ref Fe.one in
362362- let r1 = ref x in
363363- for i = P.byte_length * 8 - 1 downto 0 do
361361+ let r1 = ref x in
362362+ for i = (P.byte_length * 8) - 1 downto 0 do
364363 let bit = bit_at exp i in
365364 let multiplied = Fe.mul !r0 !r1 in
366365 let r0_sqr = Fe.sqr !r0 in
367366 let r1_sqr = Fe.sqr !r1 in
368367 r0 := Fe.select bit ~then_:multiplied ~else_:r0_sqr;
369369- r1 := Fe.select bit ~then_:r1_sqr ~else_:multiplied;
368368+ r1 := Fe.select bit ~then_:r1_sqr ~else_:multiplied
370369 done;
371370 !r0
372371373372 let decompress =
374374- (* When p = 4*k+3, as is the case of NIST-P256, there is an efficient square
373373+ (* When p = 4*k+3, as is the case of NIST-P256, there is an efficient square
375374 root algorithm to recover the y, as follows:
376375377376 Given the compact representation of Q as x,
···380379 y = min(y',p-y')
381380 Q=(x,y) is the canonical representation of the point
382381 *)
383383- let pident = P.pident (* (Params.p + 1) / 4*) in
382382+ let pident =
383383+ P.pident
384384+ (* (Params.p + 1) / 4*)
385385+ in
384386 let a = Fe.from_be_octets P.a in
385387 let b = Fe.from_be_octets P.b in
386388 let p = Fe.from_be_octets P.p in
387389 fun pk ->
388390 let x = Fe.from_be_octets (String.sub pk 1 P.byte_length) in
389391 let x3 = Fe.mul x x in
390390- let x3 = Fe.mul x3 x in (* x3 *)
391391- let ax = Fe.mul a x in (* ax *)
392392+ let x3 = Fe.mul x3 x in
393393+ (* x3 *)
394394+ let ax = Fe.mul a x in
395395+ (* ax *)
392396 let sum = Fe.add x3 ax in
393393- let sum = Fe.add sum b in (* y^2 *)
394394- let y = pow sum pident in (* https://tools.ietf.org/id/draft-jivsov-ecc-compact-00.xml#sqrt point 4.3*)
397397+ let sum = Fe.add sum b in
398398+ (* y^2 *)
399399+ let y = pow sum pident in
400400+ (* https://tools.ietf.org/id/draft-jivsov-ecc-compact-00.xml#sqrt point 4.3*)
395401 let y' = Fe.sub p y in
396402 let y = Fe.from_montgomery y in
397397- let y_struct = Fe.to_octets y in (* number must not be in montgomery domain*)
403403+ let y_struct = Fe.to_octets y in
404404+ (* number must not be in montgomery domain*)
398405 let y_struct = rev_string y_struct in
399406 let y' = Fe.from_montgomery y' in
400400- let y_struct2 = Fe.to_octets y' in (* number must not be in montgomery domain*)
407407+ let y_struct2 = Fe.to_octets y' in
408408+ (* number must not be in montgomery domain*)
401409 let y_struct2 = rev_string y_struct2 in
402410 let ident = String.get_uint8 pk 0 in
403403- let signY =
404404- 2 + (String.get_uint8 y_struct (P.byte_length - 1)) land 1
405405- in
411411+ let signY = 2 + (String.get_uint8 y_struct (P.byte_length - 1) land 1) in
406412 let res = if Int.equal signY ident then y_struct else y_struct2 in
407413 let out = Bytes.create ((P.byte_length * 2) + 1) in
408414 Bytes.set out 0 '\004';
···412418413419 let of_octets buf =
414420 let len = P.byte_length in
415415- if String.length buf = 0 then
416416- Error `Invalid_format
421421+ if String.length buf = 0 then Error `Invalid_format
417422 else
418423 let of_octets buf =
419424 let x = String.sub buf 1 len in
···421426 validate_finite_point ~x ~y
422427 in
423428 match String.get_uint8 buf 0 with
424424- | 0x00 when String.length buf = 1 ->
425425- Ok (at_infinity ())
426426- | 0x02 | 0x03 when String.length P.pident > 0 ->
427427- let decompressed = decompress buf in
428428- of_octets decompressed
429429- | 0x04 when String.length buf = 1 + len + len ->
430430- of_octets buf
429429+ | 0x00 when String.length buf = 1 -> Ok (at_infinity ())
430430+ | (0x02 | 0x03) when String.length P.pident > 0 ->
431431+ let decompressed = decompress buf in
432432+ of_octets decompressed
433433+ | 0x04 when String.length buf = 1 + len + len -> of_octets buf
431434 | 0x00 | 0x04 -> Error `Invalid_length
432435 | _ -> Error `Invalid_format
433436···465468 let scalar_mult (Scalar s) p =
466469 let r0 = ref (P.at_infinity ()) in
467470 let r1 = ref p in
468468- for i = Param.byte_length * 8 - 1 downto 0 do
471471+ for i = (Param.byte_length * 8) - 1 downto 0 do
469472 let bit = bit_at s i in
470473 let sum = P.add !r0 !r1 in
471474 let r0_double = P.double !r0 in
···495498 base := P.double !base;
496499 base := P.double !base
497500 done;
498498- let convert {f_x; f_y; f_z} = [|f_x; f_y; f_z|] in
501501+ let convert { f_x; f_y; f_z } = [| f_x; f_y; f_z |] in
499502 Array.map (Array.map convert) table
500503end
501504···519522 | Ok p -> Ok (p, share ?compress p)
520523 | Error _ as e -> e
521524522522- let secret_to_octets s =
523523- S.to_octets s
525525+ let secret_to_octets s = S.to_octets s
524526525527 let rec generate_private_key ?g () =
526528 let candidate = Crypto_rng.generate ?g Param.byte_length in
···530532531533 let gen_key ?compress ?g () =
532534 let private_key = generate_private_key ?g () in
533533- private_key, share ?compress private_key
535535+ (private_key, share ?compress private_key)
534536535537 let key_exchange secret received =
536538 match point_of_octets received with
···562564563565module Make_Fn (P : Parameters) (F : Foreign_n) : Fn = struct
564566 let b_uts = Bytes.unsafe_to_string
565565-566567 let create () = Bytes.create P.fe_length
567567-568568 let create_octets () = Bytes.create P.byte_length
569569570570 let from_be_octets v =
···610610 b_uts tmp
611611end
612612613613-module Make_dsa (Param : Parameters) (F : Fn) (P : Point_ops) (S : Scalar) (H : Digestif.S) = struct
613613+module Make_dsa
614614+ (Param : Parameters)
615615+ (F : Fn)
616616+ (P : Point_ops)
617617+ (S : Scalar)
618618+ (H : Digestif.S) =
619619+struct
614620 type priv = scalar
615621616622 let byte_length = Param.byte_length
617617-618623 let bit_length = Param.bit_length
619619-620620- let priv_of_octets= S.of_octets
621621-624624+ let priv_of_octets = S.of_octets
622625 let priv_to_octets = S.to_octets
623626624627 let padded msg =
···627630 let first_byte_ok () =
628631 match Param.first_byte_bits with
629632 | None -> true
630630- | Some m -> (String.get_uint8 msg 0) land (0xFF land (lnot m)) = 0
633633+ | Some m -> String.get_uint8 msg 0 land (0xFF land lnot m) = 0
631634 in
632632- if l > bl || (l = bl && not (first_byte_ok ())) then
633633- raise Message_too_long
634634- else if l = bl then
635635- msg
635635+ if l > bl || (l = bl && not (first_byte_ok ())) then raise Message_too_long
636636+ else if l = bl then msg
636637 else
637637- ( let res = Bytes.make bl '\000' in
638638- Bytes.unsafe_blit_string msg 0 res (bl - l) l ;
639639- Bytes.unsafe_to_string res )
638638+ let res = Bytes.make bl '\000' in
639639+ Bytes.unsafe_blit_string msg 0 res (bl - l) l;
640640+ Bytes.unsafe_to_string res
640641641642 (* RFC 6979: compute a deterministic k *)
642643 module K_gen (H : Digestif.S) = struct
643644 let drbg : 'a Crypto_rng.generator =
644644- let module M = Crypto_rng.Hmac_drbg (H) in (module M)
645645+ let module M = Crypto_rng.Hmac_drbg (H) in
646646+ (module M)
645647646648 let g ~key msg =
647649 let g = Crypto_rng.create ~strict:true drbg in
···654656 let bits2int r =
655657 (* keep qlen *leftmost* bits *)
656658 let shift = (8 * Param.byte_length) - Param.bit_length in
657657- if shift = 0 then
658658- Bytes.unsafe_to_string r
659659+ if shift = 0 then Bytes.unsafe_to_string r
659660 else
660661 (* Assuming shift is < 8 *)
661662 let r' = Bytes.create Param.byte_length in
···682683 let generate ~key buf = gen (g ~key (padded buf))
683684 end
684685685685- module K_gen_default = K_gen(H)
686686+ module K_gen_default = K_gen (H)
686687687688 type pub = point
688689689690 let pub_of_octets = P.of_octets
690690-691691 let pub_to_octets ?(compress = false) pk = P.to_octets ~compress pk
692692693693 let generate ?g () =
···707707 match P.to_affine_raw p with
708708 | None -> None
709709 | Some (x, _) ->
710710- let x = F.to_montgomery x in
711711- let x = F.mul x F.one in
712712- let x = F.from_montgomery x in
713713- Some (F.to_be_octets x)
710710+ let x = F.to_montgomery x in
711711+ let x = F.mul x F.one in
712712+ let x = F.from_montgomery x in
713713+ Some (F.to_be_octets x)
714714715715 let sign ~key ?k msg =
716716 let msg = padded msg in
···723723 | Some _ -> invalid_arg "k not suitable"
724724 in
725725 let k' = match k with None -> K_gen_default.gen g | Some k -> k in
726726- let ksc = match S.of_octets k' with
726726+ let ksc =
727727+ match S.of_octets k' with
727728 | Ok ksc -> ksc
728728- | Error _ -> invalid_arg "k not in range" (* if no k is provided, this cannot happen since K_gen_*.gen already preserves the Scalar invariants *)
729729+ | Error _ -> invalid_arg "k not in range"
730730+ (* if no k is provided, this cannot happen since K_gen_*.gen already preserves the Scalar invariants *)
729731 in
730732 let point = S.scalar_mult_base ksc in
731733 match x_of_finite_point_mod_n point with
732734 | None -> again ()
733735 | Some r ->
734734- let r_mon = F.from_be_octets r in
735735- let kmon = F.from_be_octets k' in
736736- let kinv = F.inv kmon in
737737- let dmon = F.from_be_octets (S.to_octets key) in
738738- let rd = F.mul r_mon dmon in
739739- let cmon = F.add e rd in
740740- let smon = F.mul kinv cmon in
741741- let s = F.from_montgomery smon in
742742- let s = F.to_be_octets s in
743743- if S.not_zero s && S.not_zero r then
744744- r, s
745745- else
746746- again ()
736736+ let r_mon = F.from_be_octets r in
737737+ let kmon = F.from_be_octets k' in
738738+ let kinv = F.inv kmon in
739739+ let dmon = F.from_be_octets (S.to_octets key) in
740740+ let rd = F.mul r_mon dmon in
741741+ let cmon = F.add e rd in
742742+ let smon = F.mul kinv cmon in
743743+ let s = F.from_montgomery smon in
744744+ let s = F.to_be_octets s in
745745+ if S.not_zero s && S.not_zero r then (r, s) else again ()
747746 in
748747 do_sign g
749748···752751 let verify ~key (r, s) msg =
753752 try
754753 let r = padded r and s = padded s in
755755- if not (S.is_in_range r && S.is_in_range s) then
756756- false
754754+ if not (S.is_in_range r && S.is_in_range s) then false
757755 else
758756 let msg = padded msg in
759757 let z = F.from_be_octets msg in
···765763 let u1 = F.from_montgomery u1 in
766764 let u2 = F.from_montgomery u2 in
767765 match
768768- S.of_octets (F.to_be_octets u1),
769769- S.of_octets (F.to_be_octets u2)
766766+ (S.of_octets (F.to_be_octets u1), S.of_octets (F.to_be_octets u2))
770767 with
771768 | Ok u1, Ok u2 ->
772772- let point =
773773- P.add
774774- (S.scalar_mult_base u1)
775775- (S.scalar_mult u2 key)
776776- in
777777- begin match x_of_finite_point_mod_n point with
769769+ let point = P.add (S.scalar_mult_base u1) (S.scalar_mult u2 key) in
770770+ begin match x_of_finite_point_mod_n point with
778771 | None -> false (* point is infinity *)
779772 | Some r' -> String.equal r r'
780780- end
773773+ end
781774 | Error _, _ | _, Error _ -> false
782782- with
783783- | Message_too_long -> false
775775+ with Message_too_long -> false
784776785777 module Precompute = struct
786778 let generator_tables = S.generator_tables
787779 end
788780end
789781790790-module Make_point (P : Point_ops) (S : Scalar) : Point
791791- with type point = point and type scalar = scalar
792792-= struct
782782+module Make_point (P : Point_ops) (S : Scalar) :
783783+ Point with type point = point and type scalar = scalar = struct
793784 type nonrec point = point
794785 type nonrec scalar = scalar
786786+795787 let of_octets = P.of_octets
796788 let to_octets ?(compress = false) p = P.to_octets ~compress p
797789 let scalar_of_octets = S.of_octets
···801793 let scalar_mult = S.scalar_mult
802794end
803795804804-module P256 : Dh_dsa = struct
796796+module P256 : Dh_dsa = struct
805797 module Params = struct
806806- let a = "\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC"
807807- let b = "\x5A\xC6\x35\xD8\xAA\x3A\x93\xE7\xB3\xEB\xBD\x55\x76\x98\x86\xBC\x65\x1D\x06\xB0\xCC\x53\xB0\xF6\x3B\xCE\x3C\x3E\x27\xD2\x60\x4B"
808808- let g_x = "\x6B\x17\xD1\xF2\xE1\x2C\x42\x47\xF8\xBC\xE6\xE5\x63\xA4\x40\xF2\x77\x03\x7D\x81\x2D\xEB\x33\xA0\xF4\xA1\x39\x45\xD8\x98\xC2\x96"
809809- let g_y = "\x4F\xE3\x42\xE2\xFE\x1A\x7F\x9B\x8E\xE7\xEB\x4A\x7C\x0F\x9E\x16\x2B\xCE\x33\x57\x6B\x31\x5E\xCE\xCB\xB6\x40\x68\x37\xBF\x51\xF5"
810810- let p = "\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
811811- let n = "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51"
812812- let pident = "\x3F\xFF\xFF\xFF\xC0\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" |> rev_string (* (Params.p + 1) / 4*)
798798+ let a =
799799+ "\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC"
800800+801801+ let b =
802802+ "\x5A\xC6\x35\xD8\xAA\x3A\x93\xE7\xB3\xEB\xBD\x55\x76\x98\x86\xBC\x65\x1D\x06\xB0\xCC\x53\xB0\xF6\x3B\xCE\x3C\x3E\x27\xD2\x60\x4B"
803803+804804+ let g_x =
805805+ "\x6B\x17\xD1\xF2\xE1\x2C\x42\x47\xF8\xBC\xE6\xE5\x63\xA4\x40\xF2\x77\x03\x7D\x81\x2D\xEB\x33\xA0\xF4\xA1\x39\x45\xD8\x98\xC2\x96"
806806+807807+ let g_y =
808808+ "\x4F\xE3\x42\xE2\xFE\x1A\x7F\x9B\x8E\xE7\xEB\x4A\x7C\x0F\x9E\x16\x2B\xCE\x33\x57\x6B\x31\x5E\xCE\xCB\xB6\x40\x68\x37\xBF\x51\xF5"
809809+810810+ let p =
811811+ "\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
812812+813813+ let n =
814814+ "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84\xF3\xB9\xCA\xC2\xFC\x63\x25\x51"
815815+816816+ let pident =
817817+ "\x3F\xFF\xFF\xFF\xC0\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
818818+ |> rev_string (* (Params.p + 1) / 4*)
819819+813820 let byte_length = 32
814821 let bit_length = 256
815822 let fe_length = 32
···817824 end
818825819826 module Foreign = struct
820820- external mul : out_field_element -> field_element -> field_element -> unit = "mc_p256_mul" [@@noalloc]
821821- external sub : out_field_element -> field_element -> field_element -> unit = "mc_p256_sub" [@@noalloc]
822822- external add : out_field_element -> field_element -> field_element -> unit = "mc_p256_add" [@@noalloc]
823823- external to_montgomery : out_field_element -> field_element -> unit = "mc_p256_to_montgomery" [@@noalloc]
824824- external from_octets : out_field_element -> string -> unit = "mc_p256_from_bytes" [@@noalloc]
827827+ external mul : out_field_element -> field_element -> field_element -> unit
828828+ = "mc_p256_mul"
829829+ [@@noalloc]
830830+831831+ external sub : out_field_element -> field_element -> field_element -> unit
832832+ = "mc_p256_sub"
833833+ [@@noalloc]
834834+835835+ external add : out_field_element -> field_element -> field_element -> unit
836836+ = "mc_p256_add"
837837+ [@@noalloc]
838838+839839+ external to_montgomery : out_field_element -> field_element -> unit
840840+ = "mc_p256_to_montgomery"
841841+ [@@noalloc]
842842+843843+ external from_octets : out_field_element -> string -> unit
844844+ = "mc_p256_from_bytes"
845845+ [@@noalloc]
846846+825847 external set_one : out_field_element -> unit = "mc_p256_set_one" [@@noalloc]
826848 external nz : field_element -> bool = "mc_p256_nz" [@@noalloc]
827827- external sqr : out_field_element -> field_element -> unit = "mc_p256_sqr" [@@noalloc]
828828- external from_montgomery : out_field_element -> field_element -> unit = "mc_p256_from_montgomery" [@@noalloc]
829829- external to_octets : bytes -> field_element -> unit = "mc_p256_to_bytes" [@@noalloc]
830830- external inv : out_field_element -> field_element -> unit = "mc_p256_inv" [@@noalloc]
831831- external select_c : out_field_element -> bool -> field_element -> field_element -> unit = "mc_p256_select" [@@noalloc]
832832- external double_c : out_point -> point -> unit = "mc_p256_point_double" [@@noalloc]
833833- external add_c : out_point -> point -> point -> unit = "mc_p256_point_add" [@@noalloc]
834834- external scalar_mult_base_c : out_point -> string -> unit = "mc_p256_scalar_mult_base" [@@noalloc]
849849+850850+ external sqr : out_field_element -> field_element -> unit = "mc_p256_sqr"
851851+ [@@noalloc]
852852+853853+ external from_montgomery : out_field_element -> field_element -> unit
854854+ = "mc_p256_from_montgomery"
855855+ [@@noalloc]
856856+857857+ external to_octets : bytes -> field_element -> unit = "mc_p256_to_bytes"
858858+ [@@noalloc]
859859+860860+ external inv : out_field_element -> field_element -> unit = "mc_p256_inv"
861861+ [@@noalloc]
862862+863863+ external select_c :
864864+ out_field_element -> bool -> field_element -> field_element -> unit
865865+ = "mc_p256_select"
866866+ [@@noalloc]
867867+868868+ external double_c : out_point -> point -> unit = "mc_p256_point_double"
869869+ [@@noalloc]
870870+871871+ external add_c : out_point -> point -> point -> unit = "mc_p256_point_add"
872872+ [@@noalloc]
873873+874874+ external scalar_mult_base_c : out_point -> string -> unit
875875+ = "mc_p256_scalar_mult_base"
876876+ [@@noalloc]
835877 end
836878837879 module Foreign_n = struct
838838- external mul : out_field_element -> field_element -> field_element -> unit = "mc_np256_mul" [@@noalloc]
839839- external add : out_field_element -> field_element -> field_element -> unit = "mc_np256_add" [@@noalloc]
840840- external inv : out_field_element -> field_element -> unit = "mc_np256_inv" [@@noalloc]
880880+ external mul : out_field_element -> field_element -> field_element -> unit
881881+ = "mc_np256_mul"
882882+ [@@noalloc]
883883+884884+ external add : out_field_element -> field_element -> field_element -> unit
885885+ = "mc_np256_add"
886886+ [@@noalloc]
887887+888888+ external inv : out_field_element -> field_element -> unit = "mc_np256_inv"
889889+ [@@noalloc]
890890+841891 external one : out_field_element -> unit = "mc_np256_one" [@@noalloc]
842842- external from_bytes : out_field_element -> string -> unit = "mc_np256_from_bytes" [@@noalloc]
843843- external to_bytes : bytes -> field_element -> unit = "mc_np256_to_bytes" [@@noalloc]
844844- external from_montgomery : out_field_element -> field_element -> unit = "mc_np256_from_montgomery" [@@noalloc]
845845- external to_montgomery : out_field_element -> field_element -> unit = "mc_np256_to_montgomery" [@@noalloc]
892892+893893+ external from_bytes : out_field_element -> string -> unit
894894+ = "mc_np256_from_bytes"
895895+ [@@noalloc]
896896+897897+ external to_bytes : bytes -> field_element -> unit = "mc_np256_to_bytes"
898898+ [@@noalloc]
899899+900900+ external from_montgomery : out_field_element -> field_element -> unit
901901+ = "mc_np256_from_montgomery"
902902+ [@@noalloc]
903903+904904+ external to_montgomery : out_field_element -> field_element -> unit
905905+ = "mc_np256_to_montgomery"
906906+ [@@noalloc]
846907 end
847908848848- module P = Make_point_ops(Params)(Foreign)
849849- module S = Make_scalar(Params)(P)
850850- module Dh = Make_dh(Params)(P)(S)
851851- module Fn = Make_Fn(Params)(Foreign_n)
852852- module Dsa = Make_dsa(Params)(Fn)(P)(S)(Digestif.SHA256)
853853- module Point = Make_point(P)(S)
909909+ module P = Make_point_ops (Params) (Foreign)
910910+ module S = Make_scalar (Params) (P)
911911+ module Dh = Make_dh (Params) (P) (S)
912912+ module Fn = Make_Fn (Params) (Foreign_n)
913913+ module Dsa = Make_dsa (Params) (Fn) (P) (S) (Digestif.SHA256)
914914+ module Point = Make_point (P) (S)
854915end
855916856917module P384 : Dh_dsa = struct
857918 module Params = struct
858858- let a = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFC"
859859- let b = "\xB3\x31\x2F\xA7\xE2\x3E\xE7\xE4\x98\x8E\x05\x6B\xE3\xF8\x2D\x19\x18\x1D\x9C\x6E\xFE\x81\x41\x12\x03\x14\x08\x8F\x50\x13\x87\x5A\xC6\x56\x39\x8D\x8A\x2E\xD1\x9D\x2A\x85\xC8\xED\xD3\xEC\x2A\xEF"
860860- let g_x = "\xAA\x87\xCA\x22\xBE\x8B\x05\x37\x8E\xB1\xC7\x1E\xF3\x20\xAD\x74\x6E\x1D\x3B\x62\x8B\xA7\x9B\x98\x59\xF7\x41\xE0\x82\x54\x2A\x38\x55\x02\xF2\x5D\xBF\x55\x29\x6C\x3A\x54\x5E\x38\x72\x76\x0A\xB7"
919919+ let a =
920920+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFC"
921921+922922+ let b =
923923+ "\xB3\x31\x2F\xA7\xE2\x3E\xE7\xE4\x98\x8E\x05\x6B\xE3\xF8\x2D\x19\x18\x1D\x9C\x6E\xFE\x81\x41\x12\x03\x14\x08\x8F\x50\x13\x87\x5A\xC6\x56\x39\x8D\x8A\x2E\xD1\x9D\x2A\x85\xC8\xED\xD3\xEC\x2A\xEF"
924924+925925+ let g_x =
926926+ "\xAA\x87\xCA\x22\xBE\x8B\x05\x37\x8E\xB1\xC7\x1E\xF3\x20\xAD\x74\x6E\x1D\x3B\x62\x8B\xA7\x9B\x98\x59\xF7\x41\xE0\x82\x54\x2A\x38\x55\x02\xF2\x5D\xBF\x55\x29\x6C\x3A\x54\x5E\x38\x72\x76\x0A\xB7"
927927+861928 let g_y =
862862-"\x36\x17\xde\x4a\x96\x26\x2c\x6f\x5d\x9e\x98\xbf\x92\x92\xdc\x29\xf8\xf4\x1d\xbd\x28\x9a\x14\x7c\xe9\xda\x31\x13\xb5\xf0\xb8\xc0\x0a\x60\xb1\xce\x1d\x7e\x81\x9d\x7a\x43\x1d\x7c\x90\xea\x0e\x5f"
863863- let p = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
864864- let n = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC7\x63\x4D\x81\xF4\x37\x2D\xDF\x58\x1A\x0D\xB2\x48\xB0\xA7\x7A\xEC\xEC\x19\x6A\xCC\xC5\x29\x73"
865865- let pident = "\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBF\xFF\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00" |> rev_string (* (Params.p + 1) / 4*)
929929+ "\x36\x17\xde\x4a\x96\x26\x2c\x6f\x5d\x9e\x98\xbf\x92\x92\xdc\x29\xf8\xf4\x1d\xbd\x28\x9a\x14\x7c\xe9\xda\x31\x13\xb5\xf0\xb8\xc0\x0a\x60\xb1\xce\x1d\x7e\x81\x9d\x7a\x43\x1d\x7c\x90\xea\x0e\x5f"
930930+931931+ let p =
932932+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF"
933933+934934+ let n =
935935+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC7\x63\x4D\x81\xF4\x37\x2D\xDF\x58\x1A\x0D\xB2\x48\xB0\xA7\x7A\xEC\xEC\x19\x6A\xCC\xC5\x29\x73"
936936+937937+ let pident =
938938+ "\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xBF\xFF\xFF\xFF\xC0\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00"
939939+ |> rev_string (* (Params.p + 1) / 4*)
940940+866941 let byte_length = 48
867942 let bit_length = 384
868943 let fe_length = 48
···870945 end
871946872947 module Foreign = struct
873873- external mul : out_field_element -> field_element -> field_element -> unit = "mc_p384_mul" [@@noalloc]
874874- external sub : out_field_element -> field_element -> field_element -> unit = "mc_p384_sub" [@@noalloc]
875875- external add : out_field_element -> field_element -> field_element -> unit = "mc_p384_add" [@@noalloc]
876876- external to_montgomery : out_field_element -> field_element -> unit = "mc_p384_to_montgomery" [@@noalloc]
877877- external from_octets : out_field_element -> string -> unit = "mc_p384_from_bytes" [@@noalloc]
948948+ external mul : out_field_element -> field_element -> field_element -> unit
949949+ = "mc_p384_mul"
950950+ [@@noalloc]
951951+952952+ external sub : out_field_element -> field_element -> field_element -> unit
953953+ = "mc_p384_sub"
954954+ [@@noalloc]
955955+956956+ external add : out_field_element -> field_element -> field_element -> unit
957957+ = "mc_p384_add"
958958+ [@@noalloc]
959959+960960+ external to_montgomery : out_field_element -> field_element -> unit
961961+ = "mc_p384_to_montgomery"
962962+ [@@noalloc]
963963+964964+ external from_octets : out_field_element -> string -> unit
965965+ = "mc_p384_from_bytes"
966966+ [@@noalloc]
967967+878968 external set_one : out_field_element -> unit = "mc_p384_set_one" [@@noalloc]
879969 external nz : field_element -> bool = "mc_p384_nz" [@@noalloc]
880880- external sqr : out_field_element -> field_element -> unit = "mc_p384_sqr" [@@noalloc]
881881- external from_montgomery : out_field_element -> field_element -> unit = "mc_p384_from_montgomery" [@@noalloc]
882882- external to_octets : bytes -> field_element -> unit = "mc_p384_to_bytes" [@@noalloc]
883883- external inv : out_field_element -> field_element -> unit = "mc_p384_inv" [@@noalloc]
884884- external select_c : out_field_element -> bool -> field_element -> field_element -> unit = "mc_p384_select" [@@noalloc]
885885- external double_c : out_point -> point -> unit = "mc_p384_point_double" [@@noalloc]
886886- external add_c : out_point -> point -> point -> unit = "mc_p384_point_add" [@@noalloc]
887887- external scalar_mult_base_c : out_point -> string -> unit = "mc_p384_scalar_mult_base" [@@noalloc]
970970+971971+ external sqr : out_field_element -> field_element -> unit = "mc_p384_sqr"
972972+ [@@noalloc]
973973+974974+ external from_montgomery : out_field_element -> field_element -> unit
975975+ = "mc_p384_from_montgomery"
976976+ [@@noalloc]
977977+978978+ external to_octets : bytes -> field_element -> unit = "mc_p384_to_bytes"
979979+ [@@noalloc]
980980+981981+ external inv : out_field_element -> field_element -> unit = "mc_p384_inv"
982982+ [@@noalloc]
983983+984984+ external select_c :
985985+ out_field_element -> bool -> field_element -> field_element -> unit
986986+ = "mc_p384_select"
987987+ [@@noalloc]
988988+989989+ external double_c : out_point -> point -> unit = "mc_p384_point_double"
990990+ [@@noalloc]
991991+992992+ external add_c : out_point -> point -> point -> unit = "mc_p384_point_add"
993993+ [@@noalloc]
994994+995995+ external scalar_mult_base_c : out_point -> string -> unit
996996+ = "mc_p384_scalar_mult_base"
997997+ [@@noalloc]
888998 end
8899998901000 module Foreign_n = struct
891891- external mul : out_field_element -> field_element -> field_element -> unit = "mc_np384_mul" [@@noalloc]
892892- external add : out_field_element -> field_element -> field_element -> unit = "mc_np384_add" [@@noalloc]
893893- external inv : out_field_element -> field_element -> unit = "mc_np384_inv" [@@noalloc]
10011001+ external mul : out_field_element -> field_element -> field_element -> unit
10021002+ = "mc_np384_mul"
10031003+ [@@noalloc]
10041004+10051005+ external add : out_field_element -> field_element -> field_element -> unit
10061006+ = "mc_np384_add"
10071007+ [@@noalloc]
10081008+10091009+ external inv : out_field_element -> field_element -> unit = "mc_np384_inv"
10101010+ [@@noalloc]
10111011+8941012 external one : out_field_element -> unit = "mc_np384_one" [@@noalloc]
895895- external from_bytes : out_field_element -> string -> unit = "mc_np384_from_bytes" [@@noalloc]
896896- external to_bytes : bytes -> field_element -> unit = "mc_np384_to_bytes" [@@noalloc]
897897- external from_montgomery : out_field_element -> field_element -> unit = "mc_np384_from_montgomery" [@@noalloc]
898898- external to_montgomery : out_field_element -> field_element -> unit = "mc_np384_to_montgomery" [@@noalloc]
10131013+10141014+ external from_bytes : out_field_element -> string -> unit
10151015+ = "mc_np384_from_bytes"
10161016+ [@@noalloc]
10171017+10181018+ external to_bytes : bytes -> field_element -> unit = "mc_np384_to_bytes"
10191019+ [@@noalloc]
10201020+10211021+ external from_montgomery : out_field_element -> field_element -> unit
10221022+ = "mc_np384_from_montgomery"
10231023+ [@@noalloc]
10241024+10251025+ external to_montgomery : out_field_element -> field_element -> unit
10261026+ = "mc_np384_to_montgomery"
10271027+ [@@noalloc]
8991028 end
9001029901901- module P = Make_point_ops(Params)(Foreign)
902902- module S = Make_scalar(Params)(P)
903903- module Dh = Make_dh(Params)(P)(S)
904904- module Fn = Make_Fn(Params)(Foreign_n)
905905- module Dsa = Make_dsa(Params)(Fn)(P)(S)(Digestif.SHA384)
906906- module Point = Make_point(P)(S)
10301030+ module P = Make_point_ops (Params) (Foreign)
10311031+ module S = Make_scalar (Params) (P)
10321032+ module Dh = Make_dh (Params) (P) (S)
10331033+ module Fn = Make_Fn (Params) (Foreign_n)
10341034+ module Dsa = Make_dsa (Params) (Fn) (P) (S) (Digestif.SHA384)
10351035+ module Point = Make_point (P) (S)
9071036end
90810379091038module P521 : Dh_dsa = struct
9101039 module Params = struct
911911- let a = "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC"
912912- let b = "\x00\x51\x95\x3E\xB9\x61\x8E\x1C\x9A\x1F\x92\x9A\x21\xA0\xB6\x85\x40\xEE\xA2\xDA\x72\x5B\x99\xB3\x15\xF3\xB8\xB4\x89\x91\x8E\xF1\x09\xE1\x56\x19\x39\x51\xEC\x7E\x93\x7B\x16\x52\xC0\xBD\x3B\xB1\xBF\x07\x35\x73\xDF\x88\x3D\x2C\x34\xF1\xEF\x45\x1F\xD4\x6B\x50\x3F\x00"
10401040+ let a =
10411041+ "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC"
10421042+10431043+ let b =
10441044+ "\x00\x51\x95\x3E\xB9\x61\x8E\x1C\x9A\x1F\x92\x9A\x21\xA0\xB6\x85\x40\xEE\xA2\xDA\x72\x5B\x99\xB3\x15\xF3\xB8\xB4\x89\x91\x8E\xF1\x09\xE1\x56\x19\x39\x51\xEC\x7E\x93\x7B\x16\x52\xC0\xBD\x3B\xB1\xBF\x07\x35\x73\xDF\x88\x3D\x2C\x34\xF1\xEF\x45\x1F\xD4\x6B\x50\x3F\x00"
10451045+9131046 let g_x =
914914-"\x00\xC6\x85\x8E\x06\xB7\x04\x04\xE9\xCD\x9E\x3E\xCB\x66\x23\x95\xB4\x42\x9C\x64\x81\x39\x05\x3F\xB5\x21\xF8\x28\xAF\x60\x6B\x4D\x3D\xBA\xA1\x4B\x5E\x77\xEF\xE7\x59\x28\xFE\x1D\xC1\x27\xA2\xFF\xA8\xDE\x33\x48\xB3\xC1\x85\x6A\x42\x9B\xF9\x7E\x7E\x31\xC2\xE5\xBD\x66"
10471047+ "\x00\xC6\x85\x8E\x06\xB7\x04\x04\xE9\xCD\x9E\x3E\xCB\x66\x23\x95\xB4\x42\x9C\x64\x81\x39\x05\x3F\xB5\x21\xF8\x28\xAF\x60\x6B\x4D\x3D\xBA\xA1\x4B\x5E\x77\xEF\xE7\x59\x28\xFE\x1D\xC1\x27\xA2\xFF\xA8\xDE\x33\x48\xB3\xC1\x85\x6A\x42\x9B\xF9\x7E\x7E\x31\xC2\xE5\xBD\x66"
10481048+9151049 let g_y =
916916-"\x01\x18\x39\x29\x6a\x78\x9a\x3b\xc0\x04\x5c\x8a\x5f\xb4\x2c\x7d\x1b\xd9\x98\xf5\x44\x49\x57\x9b\x44\x68\x17\xaf\xbd\x17\x27\x3e\x66\x2c\x97\xee\x72\x99\x5e\xf4\x26\x40\xc5\x50\xb9\x01\x3f\xad\x07\x61\x35\x3c\x70\x86\xa2\x72\xc2\x40\x88\xbe\x94\x76\x9f\xd1\x66\x50"
917917- let p = "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
918918- let n = "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFA\x51\x86\x87\x83\xBF\x2F\x96\x6B\x7F\xCC\x01\x48\xF7\x09\xA5\xD0\x3B\xB5\xC9\xB8\x89\x9C\x47\xAE\xBB\x6F\xB7\x1E\x91\x38\x64\x09"
919919- let pident = "\x01\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" |> rev_string
10501050+ "\x01\x18\x39\x29\x6a\x78\x9a\x3b\xc0\x04\x5c\x8a\x5f\xb4\x2c\x7d\x1b\xd9\x98\xf5\x44\x49\x57\x9b\x44\x68\x17\xaf\xbd\x17\x27\x3e\x66\x2c\x97\xee\x72\x99\x5e\xf4\x26\x40\xc5\x50\xb9\x01\x3f\xad\x07\x61\x35\x3c\x70\x86\xa2\x72\xc2\x40\x88\xbe\x94\x76\x9f\xd1\x66\x50"
10511051+10521052+ let p =
10531053+ "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
10541054+10551055+ let n =
10561056+ "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFA\x51\x86\x87\x83\xBF\x2F\x96\x6B\x7F\xCC\x01\x48\xF7\x09\xA5\xD0\x3B\xB5\xC9\xB8\x89\x9C\x47\xAE\xBB\x6F\xB7\x1E\x91\x38\x64\x09"
10571057+10581058+ let pident =
10591059+ "\x01\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
10601060+ |> rev_string
10611061+9201062 let byte_length = 66
9211063 let bit_length = 521
922922- let fe_length = if Sys.word_size == 64 then 72 else 68 (* TODO: is this congruent with C code? *)
10641064+10651065+ let fe_length =
10661066+ if Sys.word_size == 64 then 72
10671067+ else 68 (* TODO: is this congruent with C code? *)
10681068+9231069 let first_byte_bits = Some 0x01
9241070 end
92510719261072 module Foreign = struct
927927- external mul : out_field_element -> field_element -> field_element -> unit = "mc_p521_mul" [@@noalloc]
928928- external sub : out_field_element -> field_element -> field_element -> unit = "mc_p521_sub" [@@noalloc]
929929- external add : out_field_element -> field_element -> field_element -> unit = "mc_p521_add" [@@noalloc]
930930- external to_montgomery : out_field_element -> field_element -> unit = "mc_p521_to_montgomery" [@@noalloc]
931931- external from_octets : out_field_element -> string -> unit = "mc_p521_from_bytes" [@@noalloc]
10731073+ external mul : out_field_element -> field_element -> field_element -> unit
10741074+ = "mc_p521_mul"
10751075+ [@@noalloc]
10761076+10771077+ external sub : out_field_element -> field_element -> field_element -> unit
10781078+ = "mc_p521_sub"
10791079+ [@@noalloc]
10801080+10811081+ external add : out_field_element -> field_element -> field_element -> unit
10821082+ = "mc_p521_add"
10831083+ [@@noalloc]
10841084+10851085+ external to_montgomery : out_field_element -> field_element -> unit
10861086+ = "mc_p521_to_montgomery"
10871087+ [@@noalloc]
10881088+10891089+ external from_octets : out_field_element -> string -> unit
10901090+ = "mc_p521_from_bytes"
10911091+ [@@noalloc]
10921092+9321093 external set_one : out_field_element -> unit = "mc_p521_set_one" [@@noalloc]
9331094 external nz : field_element -> bool = "mc_p521_nz" [@@noalloc]
934934- external sqr : out_field_element -> field_element -> unit = "mc_p521_sqr" [@@noalloc]
935935- external from_montgomery : out_field_element -> field_element -> unit = "mc_p521_from_montgomery" [@@noalloc]
936936- external to_octets : bytes -> field_element -> unit = "mc_p521_to_bytes" [@@noalloc]
937937- external inv : out_field_element -> field_element -> unit = "mc_p521_inv" [@@noalloc]
938938- external select_c : out_field_element -> bool -> field_element -> field_element -> unit = "mc_p521_select" [@@noalloc]
939939- external double_c : out_point -> point -> unit = "mc_p521_point_double" [@@noalloc]
940940- external add_c : out_point -> point -> point -> unit = "mc_p521_point_add" [@@noalloc]
941941- external scalar_mult_base_c : out_point -> string -> unit = "mc_p521_scalar_mult_base" [@@noalloc]
10951095+10961096+ external sqr : out_field_element -> field_element -> unit = "mc_p521_sqr"
10971097+ [@@noalloc]
10981098+10991099+ external from_montgomery : out_field_element -> field_element -> unit
11001100+ = "mc_p521_from_montgomery"
11011101+ [@@noalloc]
11021102+11031103+ external to_octets : bytes -> field_element -> unit = "mc_p521_to_bytes"
11041104+ [@@noalloc]
11051105+11061106+ external inv : out_field_element -> field_element -> unit = "mc_p521_inv"
11071107+ [@@noalloc]
11081108+11091109+ external select_c :
11101110+ out_field_element -> bool -> field_element -> field_element -> unit
11111111+ = "mc_p521_select"
11121112+ [@@noalloc]
11131113+11141114+ external double_c : out_point -> point -> unit = "mc_p521_point_double"
11151115+ [@@noalloc]
11161116+11171117+ external add_c : out_point -> point -> point -> unit = "mc_p521_point_add"
11181118+ [@@noalloc]
11191119+11201120+ external scalar_mult_base_c : out_point -> string -> unit
11211121+ = "mc_p521_scalar_mult_base"
11221122+ [@@noalloc]
9421123 end
94311249441125 module Foreign_n = struct
945945- external mul : out_field_element -> field_element -> field_element -> unit = "mc_np521_mul" [@@noalloc]
946946- external add : out_field_element -> field_element -> field_element -> unit = "mc_np521_add" [@@noalloc]
947947- external inv : out_field_element -> field_element -> unit = "mc_np521_inv" [@@noalloc]
11261126+ external mul : out_field_element -> field_element -> field_element -> unit
11271127+ = "mc_np521_mul"
11281128+ [@@noalloc]
11291129+11301130+ external add : out_field_element -> field_element -> field_element -> unit
11311131+ = "mc_np521_add"
11321132+ [@@noalloc]
11331133+11341134+ external inv : out_field_element -> field_element -> unit = "mc_np521_inv"
11351135+ [@@noalloc]
11361136+9481137 external one : out_field_element -> unit = "mc_np521_one" [@@noalloc]
949949- external from_bytes : out_field_element -> string -> unit = "mc_np521_from_bytes" [@@noalloc]
950950- external to_bytes : bytes -> field_element -> unit = "mc_np521_to_bytes" [@@noalloc]
951951- external from_montgomery : out_field_element -> field_element -> unit = "mc_np521_from_montgomery" [@@noalloc]
952952- external to_montgomery : out_field_element -> field_element -> unit = "mc_np521_to_montgomery" [@@noalloc]
11381138+11391139+ external from_bytes : out_field_element -> string -> unit
11401140+ = "mc_np521_from_bytes"
11411141+ [@@noalloc]
11421142+11431143+ external to_bytes : bytes -> field_element -> unit = "mc_np521_to_bytes"
11441144+ [@@noalloc]
11451145+11461146+ external from_montgomery : out_field_element -> field_element -> unit
11471147+ = "mc_np521_from_montgomery"
11481148+ [@@noalloc]
11491149+11501150+ external to_montgomery : out_field_element -> field_element -> unit
11511151+ = "mc_np521_to_montgomery"
11521152+ [@@noalloc]
9531153 end
9541154955955- module P = Make_point_ops(Params)(Foreign)
956956- module S = Make_scalar(Params)(P)
957957- module Dh = Make_dh(Params)(P)(S)
958958- module Fn = Make_Fn(Params)(Foreign_n)
959959- module Dsa = Make_dsa(Params)(Fn)(P)(S)(Digestif.SHA512)
960960- module Point = Make_point(P)(S)
11551155+ module P = Make_point_ops (Params) (Foreign)
11561156+ module S = Make_scalar (Params) (P)
11571157+ module Dh = Make_dh (Params) (P) (S)
11581158+ module Fn = Make_Fn (Params) (Foreign_n)
11591159+ module Dsa = Make_dsa (Params) (Fn) (P) (S) (Digestif.SHA512)
11601160+ module Point = Make_point (P) (S)
9611161end
96211629631163module X25519 = struct
9641164 (* RFC 7748 *)
965965- external x25519_scalar_mult_generic : bytes -> string -> string -> unit = "mc_x25519_scalar_mult_generic" [@@noalloc]
11651165+ external x25519_scalar_mult_generic : bytes -> string -> string -> unit
11661166+ = "mc_x25519_scalar_mult_generic"
11671167+ [@@noalloc]
96611689671169 let key_len = 32
9681170···9741176 type secret = string
97511779761178 let basepoint = String.init key_len (function 0 -> '\009' | _ -> '\000')
977977-9781179 let public priv = scalar_mult priv basepoint
97911809801181 let gen_key ?compress:_ ?g () =
9811182 let secret = Crypto_rng.generate ?g key_len in
982982- secret, public secret
11831183+ (secret, public secret)
98311849841185 let secret_of_octets ?compress:_ s =
985985- if String.length s = key_len then
986986- Ok (s, public s)
987987- else
988988- Error `Invalid_length
11861186+ if String.length s = key_len then Ok (s, public s)
11871187+ else Error `Invalid_length
98911889901189 let secret_to_octets s = s
9911190···9971196 if String.length public = key_len then
9981197 let res = scalar_mult secret public in
9991198 if is_zero res then Error `Low_order else Ok res
10001000- else
10011001- Error `Invalid_length
11991199+ else Error `Invalid_length
10021200end
1003120110041202module Ed25519 = struct
10051005- external scalar_mult_base_to_bytes : bytes -> string -> unit = "mc_25519_scalar_mult_base" [@@noalloc]
12031203+ external scalar_mult_base_to_bytes : bytes -> string -> unit
12041204+ = "mc_25519_scalar_mult_base"
12051205+ [@@noalloc]
12061206+10061207 external reduce_l : bytes -> unit = "mc_25519_reduce_l" [@@noalloc]
10071007- external muladd : bytes -> string -> string -> string -> unit = "mc_25519_muladd" [@@noalloc]
10081008- external double_scalar_mult : bytes -> string -> string -> string -> bool = "mc_25519_double_scalar_mult" [@@noalloc]
12081208+12091209+ external muladd : bytes -> string -> string -> string -> unit
12101210+ = "mc_25519_muladd"
12111211+ [@@noalloc]
12121212+12131213+ external double_scalar_mult : bytes -> string -> string -> string -> bool
12141214+ = "mc_25519_double_scalar_mult"
12151215+ [@@noalloc]
12161216+10091217 external pub_ok : string -> bool = "mc_25519_pub_ok" [@@noalloc]
1010121810111219 let key_len = 32
···10231231 let double_scalar_mult a b c =
10241232 let tmp = Bytes.create key_len in
10251233 let s = double_scalar_mult tmp a b c in
10261026- s, Bytes.unsafe_to_string tmp
12341234+ (s, Bytes.unsafe_to_string tmp)
1027123510281236 type pub = string
10291029-10301237 type priv = string
1031123810321239 let sha512 datas =
···10431250 let h = sha512 [ secret ] in
10441251 (* step 2 *)
10451252 let s, rest =
10461046- Bytes.sub h 0 key_len,
10471047- Bytes.unsafe_to_string (Bytes.sub h key_len (Bytes.length h - key_len))
12531253+ ( Bytes.sub h 0 key_len,
12541254+ Bytes.unsafe_to_string (Bytes.sub h key_len (Bytes.length h - key_len))
12551255+ )
10481256 in
10491049- Bytes.set_uint8 s 0 ((Bytes.get_uint8 s 0) land 248);
10501050- Bytes.set_uint8 s 31 (((Bytes.get_uint8 s 31) land 127) lor 64);
12571257+ Bytes.set_uint8 s 0 (Bytes.get_uint8 s 0 land 248);
12581258+ Bytes.set_uint8 s 31 (Bytes.get_uint8 s 31 land 127 lor 64);
10511259 let s = Bytes.unsafe_to_string s in
10521260 (* step 3 and 4 *)
10531261 let public = scalar_mult_base_to_bytes s in
10541054- public, (s, rest)
12621262+ (public, (s, rest))
1055126310561264 let pub_of_priv secret = fst (public secret)
10571265···1062127010631271 let pub_of_octets buf =
10641272 if String.length buf = key_len then
10651065- if pub_ok buf then
10661066- Ok buf
10671067- else
10681068- Error `Not_on_curve
10691069- else
10701070- Error `Invalid_length
12731273+ if pub_ok buf then Ok buf else Error `Not_on_curve
12741274+ else Error `Invalid_length
1071127510721276 let pub_to_octets pub = pub
1073127710741278 let generate ?g () =
10751279 let secret = Crypto_rng.generate ?g key_len in
10761076- secret, pub_of_priv secret
12801280+ (secret, pub_of_priv secret)
1077128110781282 let sign ~key msg =
10791283 (* section 5.1.6 *)
···10821286 reduce_l r;
10831287 let r = Bytes.unsafe_to_string r in
10841288 let r_big = scalar_mult_base_to_bytes r in
10851085- let k = sha512 [ r_big; pub; msg] in
12891289+ let k = sha512 [ r_big; pub; msg ] in
10861290 reduce_l k;
10871291 let k = Bytes.unsafe_to_string k in
10881292 let s_out = muladd k s r in
10891293 let res = Bytes.create (key_len + key_len) in
10901090- Bytes.unsafe_blit_string r_big 0 res 0 key_len ;
10911091- Bytes.unsafe_blit_string s_out 0 res key_len key_len ;
12941294+ Bytes.unsafe_blit_string r_big 0 res 0 key_len;
12951295+ Bytes.unsafe_blit_string s_out 0 res key_len key_len;
10921296 Bytes.unsafe_to_string res
1093129710941298 let verify ~key signature ~msg =
10951299 (* section 5.1.7 *)
10961300 if String.length signature = 2 * key_len then
10971301 let r, s =
10981098- String.sub signature 0 key_len,
10991099- String.sub signature key_len key_len
13021302+ (String.sub signature 0 key_len, String.sub signature key_len key_len)
11001303 in
11011304 let s_smaller_l =
11021305 (* check s within 0 <= s < L *)
···11081311 String.equal s'' s'
11091312 in
11101313 if s_smaller_l then begin
11111111- let k = sha512 [ r ; key ; msg ] in
13141314+ let k = sha512 [ r; key; msg ] in
11121315 reduce_l k;
11131316 let k = Bytes.unsafe_to_string k in
11141317 let success, r' = double_scalar_mult k key s in
11151318 success && String.equal r r'
11161116- end else
11171117- false
11181118- else
11191119- false
13191319+ end
13201320+ else false
13211321+ else false
11201322end
+33-40
ec/crypto_ec.mli
···6677 The arithmetic operations uses code generated by
88 {{:https://github.com/mit-plv/fiat-crypto}fiat-crypto} which is proven to
99- consume a constant amount of time, independent of the input values.
1010-*)
99+ consume a constant amount of time, independent of the input values. *)
11101212-type error = [
1313- | `Invalid_range
1111+type error =
1212+ [ `Invalid_range
1413 | `Invalid_format
1514 | `Invalid_length
1615 | `Not_on_curve
1716 | `At_infinity
1818- | `Low_order
1919-]
1717+ | `Low_order ]
2018(** The type for errors. *)
21192220val pp_error : Format.formatter -> error -> unit
···27252826(** Diffie-Hellman key exchange. *)
2927module type Dh = sig
3030-3128 type secret
3229 (** Type for private keys. *)
33303434- val secret_of_octets : ?compress:bool -> string ->
3535- (secret * string, error) result
3131+ val secret_of_octets :
3232+ ?compress:bool -> string -> (secret * string, error) result
3633 (** [secret_of_octets ~compress secret] decodes the provided buffer as
3737- {!secret}. If [compress] is provided and [true] (defaults to [false]),
3838- the shared part will be compressed. May result in an error if the buffer
3939- had an invalid length or was not in bounds. *)
3434+ {!secret}. If [compress] is provided and [true] (defaults to [false]), the
3535+ shared part will be compressed. May result in an error if the buffer had
3636+ an invalid length or was not in bounds. *)
40374138 val secret_to_octets : secret -> string
4239 (** [secret_to_octets secret] encodes the provided secret into a freshly
4340 allocated buffer. *)
44414545- val gen_key : ?compress:bool -> ?g:Crypto_rng.g -> unit ->
4646- secret * string
4242+ val gen_key : ?compress:bool -> ?g:Crypto_rng.g -> unit -> secret * string
4743 (** [gen_key ~compress ~g ()] generates a private and a public key for
4844 Ephemeral Diffie-Hellman. If [compress] is provided and [true] (defaults
4945 to [false]), the shared part will be compressed. The returned key pair
···5753 (** [key_exchange secret received_public_key] performs Diffie-Hellman key
5854 exchange using your secret and the data received from the other party.
5955 Returns the shared secret or an error if the received data is wrongly
6060- encoded, doesn't represent a point on the curve or represent the point
6161- at infinity.
5656+ encoded, doesn't represent a point on the curve or represent the point at
5757+ infinity.
62586359 The shared secret is returned as is i.e. not stripped from leading 0x00
6460 bytes.
···69657066(** Digital signature algorithm. *)
7167module type Dsa = sig
7272-7368 type priv
7469 (** The type for private keys. *)
7570···9691 provided data is invalid, an error is returned. *)
97929893 val pub_to_octets : ?compress:bool -> pub -> string
9999- (** [pub_to_octets ~compress p] encodes the public key [p] into a buffer.
100100- If [compress] is provided and [true] (default [false]), the compressed
9494+ (** [pub_to_octets ~compress p] encodes the public key [p] into a buffer. If
9595+ [compress] is provided and [true] (default [false]), the compressed
10196 representation is returned. *)
1029710398 (** {2 Deriving the public key} *)
···113108 (** {2 Cryptographic operations} *)
114109115110 val sign : key:priv -> ?k:string -> string -> string * string
116116- (** [sign ~key ~k digest] signs the message [digest] using the private
117117- [key]. The [digest] is not processed further - it should be the hash of
118118- the message to sign. If [k] is not provided, it is computed using the
119119- deterministic construction from RFC 6979. The result is a pair of [r]
120120- and [s].
111111+ (** [sign ~key ~k digest] signs the message [digest] using the private [key].
112112+ The [digest] is not processed further - it should be the hash of the
113113+ message to sign. If [k] is not provided, it is computed using the
114114+ deterministic construction from RFC 6979. The result is a pair of [r] and
115115+ [s].
121116122117 Warning: there {{:https://www.hertzbleed.com/2h2b.pdf}are}
123118 {{:https://www.hertzbleed.com/hertzbleed.pdf}attacks} that recover the
···137132 (** [K_gen] can be instantiated over a hashing module to obtain an RFC6979
138133 compliant [k]-generator for that hash. *)
139134 module K_gen (H : Digestif.S) : sig
140140-141135 val generate : key:priv -> string -> string
142142- (** [generate ~key digest] deterministically takes the given private key
143143- and message digest to a [k] suitable for seeding the signing process. *)
136136+ (** [generate ~key digest] deterministically takes the given private key and
137137+ message digest to a [k] suitable for seeding the signing process. *)
144138 end
145139146140 (** {2 Misc} *)
···168162 SEC 1 format. Returns an error if the point is not on the curve. *)
169163170164 val to_octets : ?compress:bool -> point -> string
171171- (** [to_octets ~compress point] encodes [point] to SEC 1 format. If
172172- [compress] is [true] (default [false]), the compressed format is used. *)
165165+ (** [to_octets ~compress point] encodes [point] to SEC 1 format. If [compress]
166166+ is [true] (default [false]), the compressed format is used. *)
173167174168 val scalar_of_octets : string -> (scalar, error) result
175169 (** [scalar_of_octets buf] decodes a scalar from [buf]. Returns an error if
···191185192186(** Elliptic curve with Diffie-Hellman and DSA. *)
193187module type Dh_dsa = sig
194194-188188+ module Dh : Dh
195189 (** Diffie-Hellman key exchange. *)
196196- module Dh : Dh
197190198198- (** Digital signature algorithm. *)
199191 module Dsa : Dsa
192192+ (** Digital signature algorithm. *)
200193201201- (** Low-level point arithmetic. *)
202194 module Point : Point
195195+ (** Low-level point arithmetic. *)
203196end
204197198198+module P256 : Dh_dsa
205199(** The NIST P-256 curve, also known as SECP256R1. *)
206206-module P256 : Dh_dsa
207200208208-(** The NIST P-384 curve, also known as SECP384R1. *)
209201module P384 : Dh_dsa
202202+(** The NIST P-384 curve, also known as SECP384R1. *)
210203211211-(** The NIST P-521 curve, also known as SECP521R1. *)
212204module P521 : Dh_dsa
205205+(** The NIST P-521 curve, also known as SECP521R1. *)
213206207207+module X25519 : Dh
214208(** Curve 25519 Diffie-Hellman, also known as X25519. *)
215215-module X25519 : Dh
216209217210(** Curve 25519 DSA, also known as Ed25519. *)
218211module Ed25519 : sig
···255248 result is the concatenation of [r] and [s], as specified in RFC 8032. *)
256249257250 val verify : key:pub -> string -> msg:string -> bool
258258- (** [verify ~key signature msg] verifies the [signature] on the message
259259- [msg] with the public [key]. The return value is [true] if verification
260260- was successful, [false] otherwise. *)
251251+ (** [verify ~key signature msg] verifies the [signature] on the message [msg]
252252+ with the public [key]. The return value is [true] if verification was
253253+ successful, [false] otherwise. *)
261254end
+10-5
fuzz/fuzz_crypto.ml
···2828 let pt_len = String.length plaintext in
2929 let padded_len =
3030 if pt_len = 0 then aes_block_size
3131- else ((pt_len + aes_block_size - 1) / aes_block_size) * aes_block_size
3131+ else (pt_len + aes_block_size - 1) / aes_block_size * aes_block_size
3232 in
3333 let padded_pt =
3434 if pt_len >= padded_len then String.sub plaintext 0 padded_len
···5050 let pt_len = String.length plaintext in
5151 let padded_len =
5252 if pt_len = 0 then aes_block_size
5353- else ((pt_len + aes_block_size - 1) / aes_block_size) * aes_block_size
5353+ else (pt_len + aes_block_size - 1) / aes_block_size * aes_block_size
5454 in
5555 let padded_pt =
5656 if pt_len >= padded_len then String.sub plaintext 0 padded_len
···8585 (* GCM nonce should be 12 bytes for optimal performance *)
8686 let nonce = make_key 12 nonce_input in
8787 let adata = "" in
8888- let result = Crypto.AES.GCM.authenticate_encrypt ~key ~nonce ~adata plaintext in
8888+ let result =
8989+ Crypto.AES.GCM.authenticate_encrypt ~key ~nonce ~adata plaintext
9090+ in
8991 match Crypto.AES.GCM.authenticate_decrypt ~key ~nonce ~adata result with
9090- | Some decrypted -> check_eq ~pp:Format.pp_print_string plaintext decrypted
9292+ | Some decrypted ->
9393+ check_eq ~pp:Format.pp_print_string plaintext decrypted
9194 | None -> fail "GCM decryption failed")
9295 valid_aes_key_sizes
9396···105108 let result =
106109 Crypto.AES.CCM16.authenticate_encrypt ~key ~nonce ~adata plaintext
107110 in
108108- match Crypto.AES.CCM16.authenticate_decrypt ~key ~nonce ~adata result with
111111+ match
112112+ Crypto.AES.CCM16.authenticate_decrypt ~key ~nonce ~adata result
113113+ with
109114 | Some decrypted ->
110115 check_eq ~pp:Format.pp_print_string plaintext decrypted
111116 | None -> fail "CCM decryption failed")
+3-2
pk/common.ml
···11-let rec until p f = let r = f () in if p r then r else until p f
11+let rec until p f =
22+ let r = f () in
33+ if p r then r else until p f
2435let guard p err = if p then Ok () else Error err
44-56let ( let* ) = Result.bind
+198-164
pk/crypto_pk.mli
···11111212(** {b RSA} public-key cryptography algorithm. *)
1313module Rsa : sig
1414-1514 (** {1 Keys}
16151716 Messages are checked not to exceed the key size, and this is signalled via
···2524 smaller than the modulus. *)
26252726 type pub = private {
2828- e : Z.t ; (** Public exponent *)
2929- n : Z.t ; (** Modulus *)
2727+ e : Z.t; (** Public exponent *)
2828+ n : Z.t; (** Modulus *)
3029 }
3130 (** The public portion of the key. *)
32313332 val pub : e:Z.t -> n:Z.t -> (pub, [> `Msg of string ]) result
3434- (** [pub ~e ~n] validates the public key: [1 < e < n], [n > 0],
3535- [is_odd n], and [numbits n >= 89] (a requirement for PKCS1 operations). *)
3333+ (** [pub ~e ~n] validates the public key: [1 < e < n], [n > 0], [is_odd n],
3434+ and [numbits n >= 89] (a requirement for PKCS1 operations). *)
36353736 type priv = private {
3838- e : Z.t ; (** Public exponent *)
3939- d : Z.t ; (** Private exponent *)
4040- n : Z.t ; (** Modulus ([p q])*)
4141- p : Z.t ; (** Prime factor [p] *)
4242- q : Z.t ; (** Prime factor [q] *)
4343- dp : Z.t ; (** [d mod (p-1)] *)
4444- dq : Z.t ; (** [d mod (q-1)] *)
4545- q' : Z.t ; (** [q^(-1) mod p] *)
3737+ e : Z.t; (** Public exponent *)
3838+ d : Z.t; (** Private exponent *)
3939+ n : Z.t; (** Modulus ([p q])*)
4040+ p : Z.t; (** Prime factor [p] *)
4141+ q : Z.t; (** Prime factor [q] *)
4242+ dp : Z.t; (** [d mod (p-1)] *)
4343+ dq : Z.t; (** [d mod (q-1)] *)
4444+ q' : Z.t; (** [q^(-1) mod p] *)
4645 }
4746 (** Full private key (two-factor version).
4847···5352 [dq], or re-generate the full private key using
5453 {{!priv_of_primes}[priv_of_primes]}. *)
55545656- val priv : e:Z.t -> d:Z.t -> n:Z.t -> p:Z.t -> q:Z.t -> dp:Z.t -> dq:Z.t ->
5757- q':Z.t -> (priv, [> `Msg of string ]) result
5555+ val priv :
5656+ e:Z.t ->
5757+ d:Z.t ->
5858+ n:Z.t ->
5959+ p:Z.t ->
6060+ q:Z.t ->
6161+ dp:Z.t ->
6262+ dq:Z.t ->
6363+ q':Z.t ->
6464+ (priv, [> `Msg of string ]) result
5865 (** [priv ~e ~d ~n ~p ~q ~dp ~dq ~q'] validates the private key: [e, n] must
5966 be a valid {!type-pub}, [p] and [q] valid prime numbers [> 0], [odd],
6067 probabilistically prime, [p <> q], [n = p * q], [e] probabilistically
6168 prime and coprime to both [p] and [q], [q' = q ^ -1 mod p], [1 < d < n],
6262- [dp = d mod (p - 1)], [dq = d mod (q - 1)],
6363- and [d = e ^ -1 mod (p - 1) (q - 1)]. *)
6969+ [dp = d mod (p - 1)], [dq = d mod (q - 1)], and
7070+ [d = e ^ -1 mod (p - 1) (q - 1)]. *)
64716572 val pub_bits : pub -> int
6673 (** Bit-size of a public key. *)
···6875 val priv_bits : priv -> int
6976 (** Bit-size of a private key. *)
70777171- val priv_of_primes : e:Z.t -> p:Z.t -> q:Z.t ->
7878+ val priv_of_primes :
7979+ e:Z.t -> p:Z.t -> q:Z.t -> (priv, [> `Msg of string ]) result
8080+ (** [priv_of_primes ~e ~p ~q] is the {{!type-priv}private key} derived from
8181+ the minimal description [(e, p, q)]. *)
8282+8383+ val priv_of_exp :
8484+ ?g:Crypto_rng.g ->
8585+ ?attempts:int ->
8686+ e:Z.t ->
8787+ d:Z.t ->
8888+ n:Z.t ->
8989+ unit ->
7290 (priv, [> `Msg of string ]) result
7373- (** [priv_of_primes ~e ~p ~q] is the {{!type-priv}private key} derived from the
7474- minimal description [(e, p, q)]. *)
7575-7676- val priv_of_exp : ?g:Crypto_rng.g -> ?attempts:int -> e:Z.t -> d:Z.t ->
7777- n:Z.t -> unit -> (priv, [> `Msg of string ]) result
7891 (** [priv_of_exp ?g ?attempts ~e ~d n] is the unique {{!type-priv}private key}
7992 characterized by the public ([e]) and private ([d]) exponents, and modulus
8093 [n]. This operation uses a probabilistic process that can fail to recover
···8598 to an unspecified number that yields a very high probability of recovering
8699 valid keys.
871008888- Note that no time masking is done for the computations in this function. *)
101101+ Note that no time masking is done for the computations in this function.
102102+ *)
8910390104 val pub_of_priv : priv -> pub
91105 (** Extract the public component from a private key. *)
···100114 private key. Masking does not change the result, but it does change the
101115 timing profile of the operation.
102116103103- {ul
104104- {- [`No] disables masking. It is slightly faster but it {b exposes the
105105- private key to timing-based attacks}.}
106106- {- [`Yes] uses random masking with the global RNG instance. This is
107107- the sane option.}
108108- {- [`Yes_with g] uses random masking with the generator [g].}} *)
117117+ - [`No] disables masking. It is slightly faster but it
118118+ {b exposes the private key to timing-based attacks}.
119119+ - [`Yes] uses random masking with the global RNG instance. This is the
120120+ sane option.
121121+ - [`Yes_with g] uses random masking with the generator [g]. *)
109122110123 val encrypt : key:pub -> string -> string
111124 (** [encrypt key message] is the encrypted [message].
···114127115128 @raise Invalid_argument if [message] is [0x00] or [0x01]. *)
116129117117- val decrypt : ?crt_hardening:bool -> ?mask:mask -> key:priv ->
118118- string -> string
130130+ val decrypt :
131131+ ?crt_hardening:bool -> ?mask:mask -> key:priv -> string -> string
119132 (** [decrypt ~crt_hardening ~mask key ciphertext] is the decrypted
120133 [ciphertext], left-padded with [0x00] up to [key] size.
121134122122- [~crt_hardening] defaults to [false]. If [true] verifies that the
123123- result is correct. This is to counter Chinese remainder theorem attacks to
135135+ [~crt_hardening] defaults to [false]. If [true] verifies that the result
136136+ is correct. This is to counter Chinese remainder theorem attacks to
124137 factorize primes. If the computed signature is incorrect, it is again
125138 computed in the classical way (c ^ d mod n) without the Chinese remainder
126139 theorem optimization. The deterministic {{!PKCS1.sign}PKCS1 signing},
···133146 (** {1 Key generation} *)
134147135148 val generate : ?g:Crypto_rng.g -> ?e:Z.t -> bits:int -> unit -> priv
136136- (** [generate ~g ~e ~bits ()] is a new {{!type-priv}private key}. The new key is
137137- guaranteed to be well formed, see {!val-priv}.
149149+ (** [generate ~g ~e ~bits ()] is a new {{!type-priv}private key}. The new key
150150+ is guaranteed to be well formed, see {!val-priv}.
138151139152 [e] defaults to [2^16+1].
140153141141- {b Note} This process might diverge if there are no keys for the given
142142- bit size. This can happen when [bits] is extremely small.
154154+ {b Note} This process might diverge if there are no keys for the given bit
155155+ size. This can happen when [bits] is extremely small.
143156144144- @raise Invalid_argument if [e] is not a prime number (checked
145145- probabilistically) or not in the range [1 < e < 2^bits], or if
146146- [bits < 89] (as above, required for PKCS1 operations). *)
157157+ @raise Invalid_argument
158158+ if [e] is not a prime number (checked probabilistically) or not in the
159159+ range [1 < e < 2^bits], or if [bits < 89] (as above, required for PKCS1
160160+ operations). *)
147161148162 (** {1 PKCS#1 padded modes} *)
149163150164 (** {b PKCS v1.5} operations, as defined by {b PKCS #1 v1.5}.
151165152166 For the operations that only add the raw padding, the key size must be at
153153- least 11 bytes larger than the message. For full {{!PKCS1.sign}signing}, the
154154- minimal key size varies according to the hash algorithm. In this case, the
155155- key size is [priv_bits key / 8], rounded up. *)
167167+ least 11 bytes larger than the message. For full {{!PKCS1.sign}signing},
168168+ the minimal key size varies according to the hash algorithm. In this case,
169169+ the key size is [priv_bits key / 8], rounded up. *)
156170 module PKCS1 : sig
157157-158171 val encrypt : ?g:Crypto_rng.g -> key:pub -> string -> string
159172 (** [encrypt g key message] is a PKCS1-padded (type 2) and encrypted
160173 [message].
161174162175 @raise Insufficient_key (see {{!Insufficient_key}Insufficient_key}) *)
163176164164- val decrypt : ?crt_hardening:bool -> ?mask:mask -> key:priv ->
165165- string -> string option
166166- (** [decrypt ~crt_hardening ~mask ~key ciphertext] is [Some message] if
167167- the [ciphertext] was produced by the corresponding {{!encrypt}encrypt}
168168- operation, or [None] otherwise. [crt_hardening] defaults to
169169- [false]. *)
177177+ val decrypt :
178178+ ?crt_hardening:bool -> ?mask:mask -> key:priv -> string -> string option
179179+ (** [decrypt ~crt_hardening ~mask ~key ciphertext] is [Some message] if the
180180+ [ciphertext] was produced by the corresponding {{!encrypt}encrypt}
181181+ operation, or [None] otherwise. [crt_hardening] defaults to [false]. *)
170182171171- val sig_encode : ?crt_hardening:bool -> ?mask:mask -> key:priv ->
172172- string -> string
173173- (** [sig_encode ~crt_hardening ~mask ~key message] is the PKCS1-padded
174174- (type 1) [message] signed by the [key]. [crt_hardening] defaults to
175175- [true] and verifies that the computed signature is correct.
183183+ val sig_encode :
184184+ ?crt_hardening:bool -> ?mask:mask -> key:priv -> string -> string
185185+ (** [sig_encode ~crt_hardening ~mask ~key message] is the PKCS1-padded (type
186186+ 1) [message] signed by the [key]. [crt_hardening] defaults to [true] and
187187+ verifies that the computed signature is correct.
176188177189 {b Note} This operation performs only the padding and RSA transformation
178190 steps of the PKCS 1.5 signature. The full signature is implemented by
···181193 @raise Insufficient_key (see {{!Insufficient_key}Insufficient_key}) *)
182194183195 val sig_decode : key:pub -> string -> string option
184184- (** [sig_decode key signature] is [Some message] when the [signature]
185185- was produced with the given [key] as per {{!sig_encode}sig_encode}, or
196196+ (** [sig_decode key signature] is [Some message] when the [signature] was
197197+ produced with the given [key] as per {{!sig_encode}sig_encode}, or
186198 [None] *)
187199188188- val min_key : [< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] -> int
200200+ val min_key :
201201+ [< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] -> int
189202 (** [min_key hash] is the minimum key size required by {{!sign}[sign]}. *)
190203191191- val sign : ?crt_hardening:bool -> ?mask:mask ->
204204+ val sign :
205205+ ?crt_hardening:bool ->
206206+ ?mask:mask ->
192207 hash:[< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] ->
193193- key:priv -> string or_digest -> string
194194- (** [sign ~crt_hardening ~mask ~hash ~key message] is the PKCS 1.5
195195- signature of [message], signed by the [key], using the hash function
196196- [hash]. This is the full signature, with the ASN-encoded message digest
197197- as the payload. [crt_hardening] defaults to [true] and verifies that
198198- the computed signature is correct.
208208+ key:priv ->
209209+ string or_digest ->
210210+ string
211211+ (** [sign ~crt_hardening ~mask ~hash ~key message] is the PKCS 1.5 signature
212212+ of [message], signed by the [key], using the hash function [hash]. This
213213+ is the full signature, with the ASN-encoded message digest as the
214214+ payload. [crt_hardening] defaults to [true] and verifies that the
215215+ computed signature is correct.
199216200217 [message] is either the actual message, or its digest.
201218202219 @raise Insufficient_key (see {{!Insufficient_key}Insufficient_key})
203220204204- @raise Invalid_argument if message is a [`Digest] of the wrong size. *)
221221+ @raise Invalid_argument if message is a [`Digest] of the wrong size. *)
205222206206- val verify : hashp:([< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] -> bool) ->
207207- key:pub -> signature:string -> string or_digest -> bool
223223+ val verify :
224224+ hashp:
225225+ ([< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] ->
226226+ bool) ->
227227+ key:pub ->
228228+ signature:string ->
229229+ string or_digest ->
230230+ bool
208231 (** [verify ~hashp ~key ~signature message] checks that [signature] is the
209232 PKCS 1.5 signature of the [message] under the given [key].
210233···213236 [hashp] determines the allowed hash algorithms. Whenever [hashp] is
214237 [false], [verify] is also [false].
215238216216- @raise Invalid_argument if message is a [`Digest] of the wrong size. *)
239239+ @raise Invalid_argument if message is a [`Digest] of the wrong size. *)
217240 end
218241219242 (** {1 OAEP padded modes} *)
···226249 Keys must have a minimum of [2 + 2 * hlen + len(message)] bytes, where
227250 [hlen] is the hash length. *)
228251 module OAEP (H : Digestif.S) : sig
229229-230230- val encrypt : ?g:Crypto_rng.g -> ?label:string -> key:pub ->
231231- string -> string
252252+ val encrypt :
253253+ ?g:Crypto_rng.g -> ?label:string -> key:pub -> string -> string
232254 (** [encrypt ~g ~label ~key message] is {b OAEP}-padded and encrypted
233255 [message], using the optional [label].
234256235257 @raise Insufficient_key (see {{!Insufficient_key}Insufficient_key}) *)
236258237237- val decrypt : ?crt_hardening:bool -> ?mask:mask -> ?label:string ->
238238- key:priv -> string -> string option
239239- (** [decrypt ~crt_hardening ~mask ~label ~key ciphertext] is
240240- [Some message] if the [ciphertext] was produced by the corresponding
259259+ val decrypt :
260260+ ?crt_hardening:bool ->
261261+ ?mask:mask ->
262262+ ?label:string ->
263263+ key:priv ->
264264+ string ->
265265+ string option
266266+ (** [decrypt ~crt_hardening ~mask ~label ~key ciphertext] is [Some message]
267267+ if the [ciphertext] was produced by the corresponding
241268 {{!encrypt}encrypt} operation, or [None] otherwise. [crt_hardening]
242269 defaults to [false]. *)
243270 end
···251278252279 Keys must have a minimum of [2 + hlen + slen] bytes, where [hlen] is the
253280 hash length and [slen] is the seed length. *)
254254- module PSS (H: Digestif.S) : sig
255255-256256- val sign : ?g:Crypto_rng.g -> ?crt_hardening:bool ->
257257- ?mask:mask -> ?slen:int -> key:priv -> string or_digest -> string
281281+ module PSS (H : Digestif.S) : sig
282282+ val sign :
283283+ ?g:Crypto_rng.g ->
284284+ ?crt_hardening:bool ->
285285+ ?mask:mask ->
286286+ ?slen:int ->
287287+ key:priv ->
288288+ string or_digest ->
289289+ string
258290 (** [sign ~g ~crt_hardening ~mask ~slen ~key message] the [PSS]-padded
259259- digest of [message], signed with the [key]. [crt_hardening] defaults
260260- to [false].
291291+ digest of [message], signed with the [key]. [crt_hardening] defaults to
292292+ [false].
261293262294 [slen] is the optional seed length and defaults to the size of the
263295 underlying hash function.
···266298267299 @raise Insufficient_key (see {{!Insufficient_key}Insufficient_key})
268300269269- @raise Invalid_argument if message is a [`Digest] of the wrong size. *)
301301+ @raise Invalid_argument if message is a [`Digest] of the wrong size. *)
270302271271- val verify : ?slen:int -> key:pub -> signature:string -> string or_digest -> bool
303303+ val verify :
304304+ ?slen:int -> key:pub -> signature:string -> string or_digest -> bool
272305 (** [verify ~slen ~key ~signature message] checks whether [signature] is a
273306 valid {b PSS} signature of the [message] under the given [key].
274307···277310 @raise Invalid_argument if message is a [`Digest] of the wrong size. *)
278311 end
279312end
280280-281313282314(** {b DSA} digital signature algorithm. *)
283315module Dsa : sig
284284-285316 (** {1 DSA signature algorithm} *)
286317287318 type priv = private {
288288- p : Z.t ; (** Modulus *)
289289- q : Z.t ; (** Subgroup order *)
290290- gg : Z.t ; (** Group Generator *)
291291- x : Z.t ; (** Private key proper *)
292292- y : Z.t ; (** Public component *)
319319+ p : Z.t; (** Modulus *)
320320+ q : Z.t; (** Subgroup order *)
321321+ gg : Z.t; (** Group Generator *)
322322+ x : Z.t; (** Private key proper *)
323323+ y : Z.t; (** Public component *)
293324 }
294325 (** Private key. [p], [q] and [gg] comprise {i domain parameters}. *)
295326296296- val priv : ?fips:bool -> p:Z.t -> q:Z.t -> gg:Z.t -> x:Z.t -> y:Z.t -> unit ->
327327+ val priv :
328328+ ?fips:bool ->
329329+ p:Z.t ->
330330+ q:Z.t ->
331331+ gg:Z.t ->
332332+ x:Z.t ->
333333+ y:Z.t ->
334334+ unit ->
297335 (priv, [> `Msg of string ]) result
298298- (** [priv ~fips ~p ~q ~gg ~x ~y ()] constructs a private DSA key from the given
299299- numbers. Will result in an error if parameters are ill-formed: same as
300300- {!val-pub}, and additionally [0 < x < q] and [y = g ^ x mod p]. Note that no
301301- time masking is done on the modular exponentiation. *)
336336+ (** [priv ~fips ~p ~q ~gg ~x ~y ()] constructs a private DSA key from the
337337+ given numbers. Will result in an error if parameters are ill-formed: same
338338+ as {!val-pub}, and additionally [0 < x < q] and [y = g ^ x mod p]. Note
339339+ that no time masking is done on the modular exponentiation. *)
302340303303- type pub = private {
304304- p : Z.t ;
305305- q : Z.t ;
306306- gg : Z.t ;
307307- y : Z.t ;
308308- }
341341+ type pub = private { p : Z.t; q : Z.t; gg : Z.t; y : Z.t }
309342 (** Public key, a subset of {{!type-priv}private key}. *)
310343311311- val pub : ?fips:bool -> p:Z.t -> q:Z.t -> gg:Z.t -> y:Z.t -> unit ->
344344+ val pub :
345345+ ?fips:bool ->
346346+ p:Z.t ->
347347+ q:Z.t ->
348348+ gg:Z.t ->
349349+ y:Z.t ->
350350+ unit ->
312351 (pub, [> `Msg of string ]) result
313352 (** [pub ~fips ~p ~q ~gg ~y ()] constructs a public DSA key from the given
314353 numbers. Will result in an error if the parameters are not well-formed:
315315- [one < gg < p], [q] probabilistically a prime, [p] probabilistically
316316- prime and odd, [0 < y < p], [q < p], and [p - 1 mod q = 0]. If [fips] is
354354+ [one < gg < p], [q] probabilistically a prime, [p] probabilistically prime
355355+ and odd, [0 < y < p], [q < p], and [p - 1 mod q = 0]. If [fips] is
317356 specified and [true] (defaults to [false]), only FIPS-specified bit length
318357 for [p] and [q] are accepted. *)
319358···329368 (** Extract the public component from a private key. *)
330369331370 val generate : ?g:Crypto_rng.g -> keysize -> priv
332332- (** [generate g size] is a fresh {{!type-priv}private} key. The domain parameters
333333- are derived using a modified FIPS.186-4 probabilistic process, but the
334334- derivation can not be validated. Note that no time masking is done for the
335335- modular exponentiations.
371371+ (** [generate g size] is a fresh {{!type-priv}private} key. The domain
372372+ parameters are derived using a modified FIPS.186-4 probabilistic process,
373373+ but the derivation can not be validated. Note that no time masking is done
374374+ for the modular exponentiations.
336375337376 {b Note} The process might diverge if it is impossible to find parameters
338377 with the given bit sizes. This happens when [n] gets too big for [l], if
339378 the [size] was given as [`Exactly (l, n)].
340379341341- @raise Invalid_argument if [size] is (`Exactly (l, n)), and either [l] or
342342- [n] is ridiculously small. *)
380380+ @raise Invalid_argument
381381+ if [size] is (`Exactly (l, n)), and either [l] or [n] is ridiculously
382382+ small. *)
343383344384 val sign : ?mask:mask -> ?k:Z.t -> key:priv -> string -> string * string
345385 (** [sign ~mask ~k ~key digest] is the signature, a pair of strings
···351391 derived as per RFC6979, using SHA256.
352392353393 @raise Invalid_argument if [k] is unsuitable (leading to r or s being 0).
354354- *)
394394+ *)
355395356396 val verify : key:pub -> string * string -> string -> bool
357357- (** [verify ~key (r, s) digest] verifies that the pair [(r, s)] is the signature
358358- of [digest], the message digest, under the private counterpart to [key]. *)
397397+ (** [verify ~key (r, s) digest] verifies that the pair [(r, s)] is the
398398+ signature of [digest], the message digest, under the private counterpart
399399+ to [key]. *)
359400360401 val massage : key:pub -> string -> string
361402 (** [massage key digest] is the numeric value of [digest] taken modulo [q] and
362403 represented in the leftmost [bits(q)] bits of the result.
363404364364- Both FIPS.186-4 and RFC6979 specify that only the leftmost [bits(q)] bits of
365365- [digest] are to be taken into account, but some implementations consider the
366366- entire [digest]. In cases where {{!sign}sign} and {{!verify}verify} seem
367367- incompatible with a given implementation (esp. if {{!sign}sign} produces
368368- signatures with the [s] component different from the other
369369- implementation's), it might help to pre-process [digest] using this
370370- function (e.g. [sign ~key (massage ~key:(pub_of_priv key) digest)]). *)
405405+ Both FIPS.186-4 and RFC6979 specify that only the leftmost [bits(q)] bits
406406+ of [digest] are to be taken into account, but some implementations
407407+ consider the entire [digest]. In cases where {{!sign}sign} and
408408+ {{!verify}verify} seem incompatible with a given implementation (esp. if
409409+ {{!sign}sign} produces signatures with the [s] component different from
410410+ the other implementation's), it might help to pre-process [digest] using
411411+ this function (e.g. [sign ~key (massage ~key:(pub_of_priv key) digest)]).
412412+ *)
371413372414 (** [K_gen] can be instantiated over a hashing module to obtain an RFC6979
373415 compliant [k]-generator for that hash. *)
374416 module K_gen (H : Digestif.S) : sig
375375-376417 val generate : key:priv -> string -> Z.t
377418 (** [generate key digest] deterministically takes the given private key and
378419 message digest to a [k] suitable for seeding the signing process. *)
379420 end
380421end
381422382382-383423(** Diffie-Hellman, MODP version. *)
384424module Dh : sig
385385-386425 (** {1 Diffie-Hellman key exchange} *)
387426388427 exception Invalid_key
389389- (** Raised if the private key material is degenerate.
390390- The following invariants are checked:
391391- Secret key: [1 < secret < p]
392392- Public key: [1 < public < p-1] && [public <> gg]
393393- *)
428428+ (** Raised if the private key material is degenerate. The following invariants
429429+ are checked: Secret key: [1 < secret < p] Public key: [1 < public < p-1]
430430+ && [public <> gg] *)
394431395432 type group = private {
396396- p : Z.t ; (** modulus *)
397397- gg : Z.t ; (** generator *)
398398- q : Z.t option ; (** subgroup order; potentially unknown *)
433433+ p : Z.t; (** modulus *)
434434+ gg : Z.t; (** generator *)
435435+ q : Z.t option; (** subgroup order; potentially unknown *)
399436 }
400437 (** A DH group. *)
401438402402- val group : p:Z.t -> gg:Z.t -> ?q:Z.t -> unit ->
403403- (group, [> `Msg of string ]) result
404404- (** [group ~p ~gg ~q ()] constructs a group if [p] is odd, a prime number,
405405- and greater than [zero]. [gg] must be in the range [1 < gg < p]. *)
439439+ val group :
440440+ p:Z.t -> gg:Z.t -> ?q:Z.t -> unit -> (group, [> `Msg of string ]) result
441441+ (** [group ~p ~gg ~q ()] constructs a group if [p] is odd, a prime number, and
442442+ greater than [zero]. [gg] must be in the range [1 < gg < p]. *)
406443407407- type secret = private { group : group ; x : Z.t }
444444+ type secret = private { group : group; x : Z.t }
408445 (** A private key. *)
409446410447 val modulus_size : group -> int
411448 (** Bit size of the modulus. *)
412449413450 val key_of_secret : group -> s:string -> secret * string
414414- (** [key_of_secret group s] is the {!secret} and the corresponding public
415415- key which use [s] as the secret exponent.
451451+ (** [key_of_secret group s] is the {!secret} and the corresponding public key
452452+ which use [s] as the secret exponent.
416453417454 @raise Invalid_key if [s] is degenerate. *)
418455419456 val gen_key : ?g:Crypto_rng.g -> ?bits:int -> group -> secret * string
420420- (** Generate a random {!secret} and the corresponding public key.
421421- [bits] is the exact bit-size of {!secret} and defaults to a value
422422- dependent on the {!type-group}'s [p].
457457+ (** Generate a random {!secret} and the corresponding public key. [bits] is
458458+ the exact bit-size of {!secret} and defaults to a value dependent on the
459459+ {!type-group}'s [p].
423460424461 {b Note} The process might diverge when [bits] is extremely small. *)
425462426463 val shared : secret -> string -> string option
427427- (** [shared secret public] is [Some shared_key] given a
428428- a previously generated {!secret} (which specifies the [group])
429429- and the other party's public key.
464464+ (** [shared secret public] is [Some shared_key] given a a previously generated
465465+ {!secret} (which specifies the [group]) and the other party's public key.
430466 [shared_key] is the unpadded big-endian representation of the shared key.
431467 It is [None] if these invariants do not hold for [public]:
432468 [1 < public < p-1] && [public <> gg]. *)
···434470 val gen_group : ?g:Crypto_rng.g -> bits:int -> unit -> group
435471 (** [gen_group ~g ~bits ()] generates a random {!type-group} with modulus size
436472 [bits]. Uses a safe prime [p = 2q + 1] (with [q] prime) for the modulus
437437- and [2] for the generator, such that [2^q = 1 mod p].
438438- Runtime is on the order of a minute for 1024 bits.
439439- Note that no time masking is done for the modular exponentiation.
473473+ and [2] for the generator, such that [2^q = 1 mod p]. Runtime is on the
474474+ order of a minute for 1024 bits. Note that no time masking is done for the
475475+ modular exponentiation.
440476441477 {b Note} The process might diverge if there are no suitable groups. This
442478 happens with extremely small [bits] values. *)
443479444480 (** A small catalog of standardized {!type-group}s. *)
445481 module Group : sig
446446-447482 (** From RFC 2409: *)
448483449484 val oakley_1 : group
···451486452487 (** From RFC 3526: *)
453488454454- val oakley_5 : group
489489+ val oakley_5 : group
455490 val oakley_14 : group
456491 val oakley_15 : group
457492 val oakley_16 : group
···471506 val ffdhe4096 : group
472507 val ffdhe6144 : group
473508 val ffdhe8192 : group
474474-475509 end
476510end
477511···488522489523 Assuming [n] is the number of bits to extract, the [n]-bit in [buf] is
490524 always the least significant bit of the result. Therefore:
491491- {ul
492492- {- if the bit size [k] of [t] is larger than [n], [k - n] most
493493- significant bits in the result are [0]; and}
494494- {- if [k] is smaller than [n], the result contains [k] last of the [n]
495495- first bits of [buf].}} *)
525525+ - if the bit size [k] of [t] is larger than [n], [k - n] most significant
526526+ bits in the result are [0]; and
527527+ - if [k] is smaller than [n], the result contains [k] last of the [n]
528528+ first bits of [buf]. *)
496529497530 val to_octets_be : ?size:int -> Z.t -> string
498531 (** [to_octets_be ~size t] is the big-endian representation of [t].
499532500500- If [~size] is not given, it defaults to the minimal number of bytes
501501- needed to represent [t], which is [bits t / 8] rounded up.
533533+ If [~size] is not given, it defaults to the minimal number of bytes needed
534534+ to represent [t], which is [bits t / 8] rounded up.
502535503503- The least-significant bit of [t] is always the last bit in the result.
504504- If the size is larger than needed, the output is padded with zero bits.
505505- If it is smaller, the high bits in [t] are dropped. *)
536536+ The least-significant bit of [t] is always the last bit in the result. If
537537+ the size is larger than needed, the output is padded with zero bits. If it
538538+ is smaller, the high bits in [t] are dropped. *)
506539507540 val into_octets_be : Z.t -> bytes -> unit
508541 (** [into_octets_be t buf] writes the big-endian representation of [t] into
···512545 (** {1 Random generation} *)
513546514547 val gen : ?g:Crypto_rng.g -> Z.t -> Z.t
515515- (** [gen ~g n] picks a value in the interval [\[0, n - 1\]] uniformly at random. *)
548548+ (** [gen ~g n] picks a value in the interval [[0, n - 1]] uniformly at random.
549549+ *)
516550517551 val gen_r : ?g:Crypto_rng.g -> Z.t -> Z.t -> Z.t
518518- (** [gen_r ~g low high] picks a value from the interval [\[low, high - 1\]]
552552+ (** [gen_r ~g low high] picks a value from the interval [[low, high - 1]]
519553 uniformly at random. *)
520554end
···11open Crypto.Uncommon
22-32open Common
4355-type pub = { p : Z.t ; q : Z.t ; gg : Z.t ; y : Z.t }
44+type pub = { p : Z.t; q : Z.t; gg : Z.t; y : Z.t }
6576let pub ?(fips = false) ~p ~q ~gg ~y () =
87 let* () = guard Z.(one < gg && gg < p) (`Msg "bad generator") in
98 let* () = guard (Z_extra.pseudoprime q) (`Msg "q is not prime") in
1010- let* () = guard (Z.is_odd p && Z_extra.pseudoprime p) (`Msg "p is not prime") in
99+ let* () =
1010+ guard (Z.is_odd p && Z_extra.pseudoprime p) (`Msg "p is not prime")
1111+ in
1112 let* () = guard Z.(zero < y && y < p) (`Msg "y not in 0..p-1") in
1213 let* () = guard (q < p) (`Msg "q is not smaller than p") in
1313- let* () = guard Z.(zero = (pred p) mod q) (`Msg "p - 1 mod q <> 0") in
1414+ let* () = guard Z.(zero = pred p mod q) (`Msg "p - 1 mod q <> 0") in
1415 let* () =
1516 if fips then
1616- match Z.numbits p, Z.numbits q with
1717+ match (Z.numbits p, Z.numbits q) with
1718 | 1024, 160 | 2048, 224 | 2048, 256 | 3072, 256 -> Ok ()
1819 | _ -> Error (`Msg "bit length of p or q not FIPS specified")
1919- else
2020- Ok ()
2020+ else Ok ()
2121 in
2222- Ok { p ; q ; gg ; y }
2222+ Ok { p; q; gg; y }
23232424-type priv =
2525- { p : Z.t ; q : Z.t ; gg : Z.t ; x : Z.t ; y : Z.t }
2424+type priv = { p : Z.t; q : Z.t; gg : Z.t; x : Z.t; y : Z.t }
26252726let priv ?fips ~p ~q ~gg ~x ~y () =
2827 let* _ = pub ?fips ~p ~q ~gg ~y () in
2928 let* () = guard Z.(zero < x && x < q) (`Msg "x not in 1..q-1") in
3029 let* () = guard Z.(y = powm gg x p) (`Msg "y <> g ^ x mod p") in
3131- Ok { p ; q ; gg ; x ; y }
3030+ Ok { p; q; gg; x; y }
32313332let pub_of_priv { p; q; gg; y; _ } = { p; q; gg; y }
34333534type keysize = [ `Fips1024 | `Fips2048 | `Fips3072 | `Exactly of int * int ]
36353736let expand_size = function
3838- | `Fips1024 -> (1024, 160)
3939- | `Fips2048 -> (2048, 256)
4040- | `Fips3072 -> (3072, 256)
3737+ | `Fips1024 -> (1024, 160)
3838+ | `Fips2048 -> (2048, 256)
3939+ | `Fips3072 -> (3072, 256)
4140 | `Exactly (l, n) ->
4242- if 3 <= l && 2 <= n then (l, n) else
4343- invalid_arg "Dsa.generate: bits: `Exactly (%d, %d)" l n
4141+ if 3 <= l && 2 <= n then (l, n)
4242+ else invalid_arg "Dsa.generate: bits: `Exactly (%d, %d)" l n
44434544type mask = [ `No | `Yes | `Yes_with of Crypto_rng.g ]
46454746let expand_mask = function
4848- | `No -> `No
4949- | `Yes -> `Yes None
4747+ | `No -> `No
4848+ | `Yes -> `Yes None
5049 | `Yes_with g -> `Yes (Some g)
51505251(*
···5756 *)
5857let params ?g size =
5958 let two = Z.(~$2) in
6060- let (l, n) = expand_size size in
5959+ let l, n = expand_size size in
6160 let q = Z_extra.prime ?g ~msb:1 n in
6261 let p =
6363- let q_q = Z.(q * two) in
6262+ let q_q = Z.(q * two) in
6463 until Z_extra.pseudoprime @@ fun () ->
6565- let x = Z_extra.gen_bits ?g ~msb:1 l in
6666- Z.(x - (x mod q_q) + one)
6464+ let x = Z_extra.gen_bits ?g ~msb:1 l in
6565+ Z.(x - (x mod q_q) + one)
6766 in
6867 let gg =
6968 let e = Z.(pred p / q) in
7070- until ((<>) Z.one) @@ fun () ->
7171- let h = Z_extra.gen_r ?g two Z.(pred p) in
7272- Z.(powm h e p)
6969+ until (( <> ) Z.one) @@ fun () ->
7070+ let h = Z_extra.gen_r ?g two Z.(pred p) in
7171+ Z.(powm h e p)
7372 in
7473 (* all checks above are already satisfied *)
7574 (p, q, gg)
76757776let generate ?g size =
7878- let (p, q, gg) = params ?g size in
7777+ let p, q, gg = params ?g size in
7978 let x = Z_extra.gen_r ?g Z.one q in
8079 let y = Z.(powm gg x p) in
8180 (* checks are satisfied due to construction *)
8281 { p; q; gg; x; y }
83828484-8583module K_gen (H : Digestif.S) = struct
8686-8784 let drbg : 'a Crypto_rng.generator =
8888- let module M = Crypto_rng.Hmac_drbg (H) in (module M)
8585+ let module M = Crypto_rng.Hmac_drbg (H) in
8686+ (module M)
89879088 let z_gen ~key:{ q; x; _ } z =
9189 let repr = Z_extra.to_octets_be ~size:(Z.numbits q // 8) in
9292- let g = Crypto_rng.create ~strict:true drbg in
9090+ let g = Crypto_rng.create ~strict:true drbg in
9391 Crypto_rng.reseed ~g (repr x ^ repr Z.(z mod q));
9492 Z_extra.gen_r ~g Z.one q
9593···102100let sign_z ?(mask = `Yes) ?k:k0 ~key:({ p; q; gg; x; _ } as key) z =
103101 let k = match k0 with Some k -> k | None -> K_gen_sha256.z_gen ~key z in
104102 let k' = Z.invert k q
105105- and b, b' = match expand_mask mask with
106106- | `No -> Z.one, Z.one
103103+ and b, b' =
104104+ match expand_mask mask with
105105+ | `No -> (Z.one, Z.one)
107106 | `Yes g ->
108108- let m = Z_extra.gen_r ?g Z.one q in
109109- m, Z.invert m q
107107+ let m = Z_extra.gen_r ?g Z.one q in
108108+ (m, Z.invert m q)
110109 in
111110 let r = Z.(powm_sec gg k p mod q) in
112111 (* normal DSA sign is: s = k^-1 * (z + r * x) mod q *)
···125124 in
126125 if r = Z.zero || s = Z.zero then invalid_arg "k unsuitable" else (r, s)
127126128128-let verify_z ~key:({ p; q; gg; y }: pub ) (r, s) z =
127127+let verify_z ~key:({ p; q; gg; y } : pub) (r, s) z =
129128 let v () =
130130- let w = Z.invert s q in
131131- let u1 = Z.(z * w mod q)
132132- and u2 = Z.(r * w mod q) in
133133- Z.((powm gg u1 p * powm y u2 p) mod p mod q) in
129129+ let w = Z.invert s q in
130130+ let u1 = Z.(z * w mod q) and u2 = Z.(r * w mod q) in
131131+ Z.(powm gg u1 p * powm y u2 p mod p mod q)
132132+ in
134133 Z.zero < r && r < q && Z.zero < s && s < q && v () = r
135134136135let sign ?mask ?k ~(key : priv) digest =
137137- let bits = Z.numbits key.q in
138138- let size = bits // 8 in
139139- let (r, s) = sign_z ?mask ?k ~key (Z_extra.of_octets_be ~bits digest) in
136136+ let bits = Z.numbits key.q in
137137+ let size = bits // 8 in
138138+ let r, s = sign_z ?mask ?k ~key (Z_extra.of_octets_be ~bits digest) in
140139 Z_extra.(to_octets_be ~size r, to_octets_be ~size s)
141140142141let verify ~(key : pub) (r, s) digest =
143143- let z = Z_extra.of_octets_be ~bits:(Z.numbits key.q) digest
144144- and (r, s) = Z_extra.(of_octets_be r, of_octets_be s) in
142142+ let z = Z_extra.of_octets_be ~bits:(Z.numbits key.q) digest
143143+ and r, s = Z_extra.(of_octets_be r, of_octets_be s) in
145144 verify_z ~key (r, s) z
146145147146let rec shift_left_inplace buf = function
148147 | 0 -> ()
149148 | bits when bits mod 8 = 0 ->
150150- let off = bits / 8 in
151151- let to_blit = Bytes.length buf - off in
152152- Bytes.unsafe_blit buf off buf 0 to_blit ;
153153- Bytes.unsafe_fill buf to_blit (Bytes.length buf - to_blit) '\x00'
149149+ let off = bits / 8 in
150150+ let to_blit = Bytes.length buf - off in
151151+ Bytes.unsafe_blit buf off buf 0 to_blit;
152152+ Bytes.unsafe_fill buf to_blit (Bytes.length buf - to_blit) '\x00'
154153 | bits when bits < 8 ->
155155- let foo = 8 - bits in
156156- for i = 0 to Bytes.length buf - 2 do
157157- let b1 = Bytes.get_uint8 buf i
158158- and b2 = Bytes.get_uint8 buf (i + 1) in
159159- Bytes.set_uint8 buf i ((b1 lsl bits) lor (b2 lsr foo))
160160- done ;
161161- Bytes.set_uint8 buf (Bytes.length buf - 1)
162162- (Bytes.get_uint8 buf (Bytes.length buf - 1) lsl bits)
154154+ let foo = 8 - bits in
155155+ for i = 0 to Bytes.length buf - 2 do
156156+ let b1 = Bytes.get_uint8 buf i and b2 = Bytes.get_uint8 buf (i + 1) in
157157+ Bytes.set_uint8 buf i ((b1 lsl bits) lor (b2 lsr foo))
158158+ done;
159159+ Bytes.set_uint8 buf
160160+ (Bytes.length buf - 1)
161161+ (Bytes.get_uint8 buf (Bytes.length buf - 1) lsl bits)
163162 | bits ->
164164- shift_left_inplace buf (8 * (bits / 8)) ;
165165- shift_left_inplace buf (bits mod 8)
163163+ shift_left_inplace buf (8 * (bits / 8));
164164+ shift_left_inplace buf (bits mod 8)
166165167167-let (lsl) buf bits =
166166+let ( lsl ) buf bits =
168167 let buf' = Bytes.of_string buf in
169168 shift_left_inplace buf' bits;
170169 Bytes.unsafe_to_string buf'
171170172172-let massage ~key:({ q; _ }: pub) digest =
171171+let massage ~key:({ q; _ } : pub) digest =
173172 let bits = Z.numbits q in
174174- if bits >= String.length digest * 8 then
175175- digest
173173+ if bits >= String.length digest * 8 then digest
176174 else
177175 let buf = Z_extra.(to_octets_be Z.(of_octets_be digest mod q)) in
178178- buf lsl ((8 - bits mod 8) mod 8)
176176+ buf lsl ((8 - (bits mod 8)) mod 8)
+180-149
pk/rsa.ml
···11open Crypto.Uncommon
22-32open Common
4354let two = Z.(~$2)
···109 let res = Eqaf.find_uint8 ?off ~f cs in
1110 Eqaf.select_int (res + 1) default res
12111313-let (&.) f g = fun h -> f (g h)
1212+let ( &. ) f g = fun h -> f (g h)
14131514type 'a or_digest = [ `Message of 'a | `Digest of string ]
16151716module Digest_or (H : Digestif.S) = struct
1817 let digest_or = function
1919- | `Message msg -> H.(digest_string msg |> to_raw_string)
1818+ | `Message msg -> H.(digest_string msg |> to_raw_string)
2019 | `Digest digest ->
2120 let n = String.length digest and m = H.digest_size in
2222- if n = m then digest else
2323- invalid_arg "(`Digest _): %d bytes, expecting %d" n m
2121+ if n = m then digest
2222+ else invalid_arg "(`Digest _): %d bytes, expecting %d" n m
2423end
25242625exception Insufficient_key
27262828-type pub = { e : Z.t ; n : Z.t }
2727+type pub = { e : Z.t; n : Z.t }
29283029(* due to PKCS1 *)
3130let minimum_octets = 12
3232-let minimum_bits = 8 * minimum_octets - 7
3131+let minimum_bits = (8 * minimum_octets) - 7
33323433let pub ~e ~n =
3534 (* We cannot verify a public key being good (this would require to verify "n"
···4039 exceptions, and we avoid tiny public keys where PKCS1 / PSS would lead to
4140 infinite loops or not work due to insufficient space for the header. *)
4241 let* () =
4343- guard Z.(n > zero && is_odd n && numbits n >= minimum_bits)
4242+ guard
4343+ Z.(n > zero && is_odd n && numbits n >= minimum_bits)
4444 (`Msg "invalid modulus")
4545 in
4646 let* () = guard Z.(one < e && e < n) (`Msg "invalid exponent") in
4747 (* NOTE that we could check for e being odd, or a prime, or 2^16+1, but
4848 these are not requirements, neither for RSA nor for powm_sec *)
4949- Ok { e ; n }
4949+ Ok { e; n }
50505151type priv = {
5252- e : Z.t ; d : Z.t ; n : Z.t ;
5353- p : Z.t ; q : Z.t ; dp : Z.t ; dq : Z.t ; q' : Z.t
5252+ e : Z.t;
5353+ d : Z.t;
5454+ n : Z.t;
5555+ p : Z.t;
5656+ q : Z.t;
5757+ dp : Z.t;
5858+ dq : Z.t;
5959+ q' : Z.t;
5460}
55615662let valid_prime name p =
5757- guard Z.(p > zero && is_odd p && Z_extra.pseudoprime p)
6363+ guard
6464+ Z.(p > zero && is_odd p && Z_extra.pseudoprime p)
5865 (`Msg ("invalid prime " ^ name))
59666067let rprime a b = Z.(gcd a b = one)
61686269let valid_e ~e ~p ~q =
6370 let* () =
6464- guard (rprime e (Z.pred p) && rprime e (Z.pred q))
7171+ guard
7272+ (rprime e (Z.pred p) && rprime e (Z.pred q))
6573 (`Msg "e is not coprime of p and q")
6674 in
6775 guard (Z_extra.pseudoprime e) (`Msg "exponent e is not a pseudoprime")
···7482 let* () = valid_e ~e ~p ~q in
7583 (* p and q are prime, and not equal -> multiplicative inverse exists *)
7684 let* () = guard Z.(q' = invert q p) (`Msg "q' <> q ^ -1 mod p") in
7777- let* () = guard Z.(n = p * q) (`Msg "modulus is not the product of p and q") in
8585+ let* () =
8686+ guard Z.(n = p * q) (`Msg "modulus is not the product of p and q")
8787+ in
7888 let* () = guard Z.(one < d && d < n) (`Msg "invalid private exponent") in
7979- let* () = guard Z.(dp = d mod (pred p)) (`Msg "dp <> d mod (p - 1)") in
8080- let* () = guard Z.(dq = d mod (pred q)) (`Msg "dq <> d mod (q - 1)") in
8989+ let* () = guard Z.(dp = d mod pred p) (`Msg "dp <> d mod (p - 1)") in
9090+ let* () = guard Z.(dq = d mod pred q) (`Msg "dq <> d mod (q - 1)") in
8191 (* e has been checked (valid_e) to be coprime to p-1 and q-1 ->
8292 muliplicative inverse exists *)
8393 let* () =
8484- guard Z.(one = d * e mod (lcm (pred p) (pred q)))
9494+ guard
9595+ Z.(one = d * e mod lcm (pred p) (pred q))
8596 (`Msg "1 <> d * e mod lcm (p - 1) (q - 1)")
8697 in
8787- Ok { e ; d ; n ; p ; q ; dp ; dq ; q' }
9898+ Ok { e; d; n; p; q; dp; dq; q' }
889989100let priv_of_primes ~e ~p ~q =
90101 let* () = valid_prime "p" p in
···95106 let* _ = pub ~e ~n in
96107 (* valid_e checks e coprime to p-1 and q-1, a multiplicative inverse exists *)
97108 let d = Z.(invert e (lcm (pred p) (pred q))) in
9898- let dp = Z.(d mod (pred p))
9999- and dq = Z.(d mod (pred q))
100100- in
109109+ let dp = Z.(d mod pred p) and dq = Z.(d mod pred q) in
101110 (* above we checked that p and q both are primes and not equal -> there
102111 should be a multiplicate inverse *)
103112 let q' = Z.invert q p in
···105114 Ok { e; d; n; p; q; dp; dq; q' }
106115107116(* Handbook of applied cryptography, 8.2.2 (i). *)
108108-let priv_of_exp ?g ?(attempts=100) ~e ~d ~n () =
117117+let priv_of_exp ?g ?(attempts = 100) ~e ~d ~n () =
109118 let* _ = pub ~e ~n in
110119 let* () = guard Z.(one < d && d < n) (`Msg "invalid private exponent") in
111120 let rec doit ~attempts =
···113122 let rec go ax = function
114123 | 0 -> None
115124 | i' ->
116116- let ax2 = Z.(ax * ax mod n) in
117117- if Z.(ax <> one && ax <> pred n && ax2 = one) then
118118- Some ax
119119- else
120120- go ax2 (i' - 1)
125125+ let ax2 = Z.(ax * ax mod n) in
126126+ if Z.(ax <> one && ax <> pred n && ax2 = one) then Some ax
127127+ else go ax2 (i' - 1)
121128 in
122129 Option.map Z.(gcd n &. pred) (go Z.(powm (Z_extra.gen ?g n) t n) s)
123130 in
···125132 let* s, t = Z_extra.strip_factor ~f:two Z.(e * d |> pred) in
126133 match s with
127134 | 0 -> Error (`Msg "invalid factor 0")
128128- | _ -> match factor s t with
129129- | None -> doit ~attempts:(attempts - 1)
130130- | Some p ->
131131- let q = Z.(div n p) in
132132- priv_of_primes ~e ~p:(max p q) ~q:(min p q)
135135+ | _ -> (
136136+ match factor s t with
137137+ | None -> doit ~attempts:(attempts - 1)
138138+ | Some p ->
139139+ let q = Z.(div n p) in
140140+ priv_of_primes ~e ~p:(max p q) ~q:(min p q))
133141 else Error (`Msg "attempts exceeded")
134142 in
135143 doit ~attempts
136144137145let rec generate ?g ?(e = Z.(~$0x10001)) ~bits () =
138138- if bits < minimum_bits || e < three ||
139139- (bits <= Z.numbits e || not (Z_extra.pseudoprime e))
140140- then
141141- invalid_arg "Rsa.generate: e: %a, bits: %d" Z.pp_print e bits;
142142- let (pb, qb) = (bits / 2, bits - bits / 2) in
143143- let (p, q) = Z_extra.(prime ?g ~msb:2 pb, prime ?g ~msb:2 qb) in
146146+ if
147147+ bits < minimum_bits || e < three
148148+ || bits <= Z.numbits e
149149+ || not (Z_extra.pseudoprime e)
150150+ then invalid_arg "Rsa.generate: e: %a, bits: %d" Z.pp_print e bits;
151151+ let pb, qb = (bits / 2, bits - (bits / 2)) in
152152+ let p, q = Z_extra.(prime ?g ~msb:2 pb, prime ?g ~msb:2 qb) in
144153 match priv_of_primes ~e ~p:(max p q) ~q:(min p q) with
145154 | Error _ -> generate ?g ~e ~bits ()
146155 | Ok priv -> priv
147156148148-let pub_of_priv ({ e; n; _ } : priv) = { e ; n }
157157+let pub_of_priv ({ e; n; _ } : priv) = { e; n }
149158150150-let pub_bits ({ n; _ } : pub) = Z.numbits n
159159+let pub_bits ({ n; _ } : pub) = Z.numbits n
151160and priv_bits ({ n; _ } : priv) = Z.numbits n
152161153162type mask = [ `No | `Yes | `Yes_with of Crypto_rng.g ]
154163155155-let encrypt_unsafe ~key: ({ e; n } : pub) msg = Z.(powm msg e n)
164164+let encrypt_unsafe ~key:({ e; n } : pub) msg = Z.(powm msg e n)
156165157157-let decrypt_unsafe ~crt_hardening ~key:({ e; d; n; p; q; dp; dq; q'} : priv) c =
158158- let m1 = Z.(powm_sec c dp p)
159159- and m2 = Z.(powm_sec c dq q) in
166166+let decrypt_unsafe ~crt_hardening ~key:({ e; d; n; p; q; dp; dq; q' } : priv) c
167167+ =
168168+ let m1 = Z.(powm_sec c dp p) and m2 = Z.(powm_sec c dq q) in
160169 (* NOTE: neither erem, nor the multiplications (addition, subtraction) are
161170 guaranteed to be constant time by gmp *)
162162- let h = Z.(erem (q' * (m1 - m2)) p) in
163163- let m = Z.(h * q + m2) in
171171+ let h = Z.(erem (q' * (m1 - m2)) p) in
172172+ let m = Z.((h * q) + m2) in
164173 (* counter Arjen Lenstra's CRT attack by verifying the signature. Since the
165174 public exponent is small, this is not very expensive. Mentioned again
166175 "Factoring RSA keys with TLS Perfect Forward Secrecy" (Weimer, 2015). *)
167167- if not crt_hardening || Z.(powm_sec m e n) = c then
168168- m
169169- else
170170- Z.(powm_sec c d n)
176176+ if (not crt_hardening) || Z.(powm_sec m e n) = c then m
177177+ else Z.(powm_sec c d n)
171178172172-let decrypt_blinded_unsafe ~crt_hardening ?g ~key:({ e; n; _} as key : priv) c =
173173- let r = until (rprime n) (fun _ -> Z_extra.gen_r ?g two n) in
179179+let decrypt_blinded_unsafe ~crt_hardening ?g ~key:({ e; n; _ } as key : priv) c
180180+ =
181181+ let r = until (rprime n) (fun _ -> Z_extra.gen_r ?g two n) in
174182 (* since r and n are coprime, there must be a multiplicative inverse *)
175183 let r' = Z.(invert r n) in
176184 let c' = Z.(powm_sec r e n * c mod n) in
177177- let x = decrypt_unsafe ~crt_hardening ~key c' in
185185+ let x = decrypt_unsafe ~crt_hardening ~key c' in
178186 Z.(r' * x mod n)
179187180180-let (encrypt_z, decrypt_z) =
188188+let encrypt_z, decrypt_z =
181189 let check_params n msg =
182190 if msg < two then invalid_arg "Rsa: message: %a" Z.pp_print msg;
183183- if n <= msg then raise Insufficient_key in
184184- (fun ~(key : pub) msg -> check_params key.n msg ; encrypt_unsafe ~key msg),
185185- (fun ~crt_hardening ~mask ~(key : priv) msg ->
186186- check_params key.n msg ;
187187- match mask with
188188- | `No -> decrypt_unsafe ~crt_hardening ~key msg
189189- | `Yes -> decrypt_blinded_unsafe ~crt_hardening ~key msg
190190- | `Yes_with g -> decrypt_blinded_unsafe ~crt_hardening ~g ~key msg )
191191+ if n <= msg then raise Insufficient_key
192192+ in
193193+ ( (fun ~(key : pub) msg ->
194194+ check_params key.n msg;
195195+ encrypt_unsafe ~key msg),
196196+ fun ~crt_hardening ~mask ~(key : priv) msg ->
197197+ check_params key.n msg;
198198+ match mask with
199199+ | `No -> decrypt_unsafe ~crt_hardening ~key msg
200200+ | `Yes -> decrypt_blinded_unsafe ~crt_hardening ~key msg
201201+ | `Yes_with g -> decrypt_blinded_unsafe ~crt_hardening ~g ~key msg )
191202192203let reformat out f msg =
193204 Z_extra.(of_octets_be msg |> f |> to_octets_be ~size:(out // 8))
194205195195-let encrypt ~key = reformat (pub_bits key) (encrypt_z ~key)
206206+let encrypt ~key = reformat (pub_bits key) (encrypt_z ~key)
196207197197-let decrypt ?(crt_hardening=false) ?(mask=`Yes) ~key =
208208+let decrypt ?(crt_hardening = false) ?(mask = `Yes) ~key =
198209 reformat (priv_bits key) (decrypt_z ~crt_hardening ~mask ~key)
199210200200-let bx00, bx01 = "\x00", "\x01"
211211+let bx00, bx01 = ("\x00", "\x01")
201212202213module PKCS1 = struct
203203-204214 let min_pad = 8
205215206216 (* XXX Generalize this into `Rng.samplev` or something. *)
207217 let generate_with ?g ~f n =
208218 let buf = Bytes.create n
209209- and k = let b = Crypto_rng.block g in (n // b * b) in
219219+ and k =
220220+ let b = Crypto_rng.block g in
221221+ n // b * b
222222+ in
210223 let rec go nonce i j =
211211- if i = n then Bytes.unsafe_to_string buf else
212212- if j = k then go Crypto_rng.(generate ?g k) i 0 else
213213- match String.get_uint8 nonce j with
214214- | b when f b -> Bytes.set_uint8 buf i b ; go nonce (succ i) (succ j)
215215- | _ -> go nonce i (succ j) in
224224+ if i = n then Bytes.unsafe_to_string buf
225225+ else if j = k then go Crypto_rng.(generate ?g k) i 0
226226+ else
227227+ match String.get_uint8 nonce j with
228228+ | b when f b ->
229229+ Bytes.set_uint8 buf i b;
230230+ go nonce (succ i) (succ j)
231231+ | _ -> go nonce i (succ j)
232232+ in
216233 go Crypto_rng.(generate ?g k) 0 0
217234218235 let pad ~mark ~padding k msg =
219236 let pad = padding (k - String.length msg - 3 |> imax min_pad) in
220220- String.concat "" [ bx00 ; mark ; pad ; bx00 ; msg ]
237237+ String.concat "" [ bx00; mark; pad; bx00; msg ]
221238222239 let unpad ~mark ~is_pad buf =
223240 let f = not &. is_pad in
···230247 Some (String.sub buf (i + 1) (String.length buf - i - 1))
231248 else None
232249233233- let pad_01 =
250250+ let pad_01 =
234251 let padding size = String.make size '\xff' in
235252 pad ~mark:"\x01" ~padding
236236- let pad_02 ?g = pad ~mark:"\x02" ~padding:(generate_with ?g ~f:((<>) 0x00))
237253238238- let unpad_01 = unpad ~mark:0x01 ~is_pad:((=) 0xff)
239239- let unpad_02 = unpad ~mark:0x02 ~is_pad:((<>) 0x00)
254254+ let pad_02 ?g = pad ~mark:"\x02" ~padding:(generate_with ?g ~f:(( <> ) 0x00))
255255+ let unpad_01 = unpad ~mark:0x01 ~is_pad:(( = ) 0xff)
256256+ let unpad_02 = unpad ~mark:0x02 ~is_pad:(( <> ) 0x00)
240257241258 let padded pad transform keybits msg =
242259 let n = keybits // 8 in
···251268 let sig_encode ?(crt_hardening = true) ?mask ~key msg =
252269 padded pad_01 (decrypt ~crt_hardening ?mask ~key) (priv_bits key) msg
253270254254- let sig_decode ~key msg =
255255- unpadded unpad_01 (encrypt ~key) (pub_bits key) msg
256256-257257- let encrypt ?g ~key msg =
258258- padded (pad_02 ?g) (encrypt ~key) (pub_bits key) msg
271271+ let sig_decode ~key msg = unpadded unpad_01 (encrypt ~key) (pub_bits key) msg
272272+ let encrypt ?g ~key msg = padded (pad_02 ?g) (encrypt ~key) (pub_bits key) msg
259273260274 let decrypt ?(crt_hardening = false) ?mask ~key msg =
261275 unpadded unpad_02 (decrypt ~crt_hardening ?mask ~key) (priv_bits key) msg
262276263277 let asn_of_hash, detect =
264264- let map = [
265265- `MD5, "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10" ;
266266- `SHA1, "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14" ;
267267- `SHA224, "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c" ;
268268- `SHA256, "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20" ;
269269- `SHA384, "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30" ;
270270- `SHA512, "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"
271271- ]
278278+ let map =
279279+ [
280280+ ( `MD5,
281281+ "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"
282282+ );
283283+ (`SHA1, "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14");
284284+ ( `SHA224,
285285+ "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c"
286286+ );
287287+ ( `SHA256,
288288+ "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"
289289+ );
290290+ ( `SHA384,
291291+ "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"
292292+ );
293293+ ( `SHA512,
294294+ "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"
295295+ );
296296+ ]
272297 in
273273- (fun h -> List.assoc h map),
274274- (fun buf -> List.find_opt (fun (_, d) -> String.starts_with ~prefix:d buf) map)
298298+ ( (fun h -> List.assoc h map),
299299+ fun buf ->
300300+ List.find_opt (fun (_, d) -> String.starts_with ~prefix:d buf) map )
275301276302 let sign ?(crt_hardening = true) ?mask ~hash ~key msg =
277303 let module H = (val Digestif.module_of_hash' (hash :> Digestif.hash')) in
278278- let module D = Digest_or(H) in
304304+ let module D = Digest_or (H) in
279305 let msg' = asn_of_hash hash ^ D.digest_or msg in
280306 sig_encode ~crt_hardening ?mask ~key msg'
281307282308 let verify ~hashp ~key ~signature msg =
283283- let (>>=) = Option.bind
284284- and (>>|) = Fun.flip Option.map
285285- in
309309+ let ( >>= ) = Option.bind and ( >>| ) = Fun.flip Option.map in
286310 Option.value
287287- (sig_decode ~key signature >>= fun buf ->
288288- detect buf >>| fun (hash, asn) ->
289289- let module H = (val Digestif.module_of_hash' (hash :> Digestif.hash')) in
290290- let module D = Digest_or(H) in
291291- hashp hash && Eqaf.equal (asn ^ D.digest_or msg) buf)
311311+ ( sig_decode ~key signature >>= fun buf ->
312312+ detect buf >>| fun (hash, asn) ->
313313+ let module H = (val Digestif.module_of_hash' (hash :> Digestif.hash'))
314314+ in
315315+ let module D = Digest_or (H) in
316316+ hashp hash && Eqaf.equal (asn ^ D.digest_or msg) buf )
292317 ~default:false
293318294319 let min_key hash =
295320 let module H = (val Digestif.module_of_hash' (hash :> Digestif.hash')) in
296296- (String.length (asn_of_hash hash) + H.digest_size + min_pad + 2) * 8 + 1
321321+ ((String.length (asn_of_hash hash) + H.digest_size + min_pad + 2) * 8) + 1
297322end
298323299324module MGF1 (H : Digestif.S) = struct
300300-301325 let repr n =
302326 let buf = Bytes.create 4 in
303327 Bytes.set_int32_be buf 0 n;
···308332 let rec go acc c = function
309333 | 0 -> Bytes.sub (Bytes.concat Bytes.empty (List.rev acc)) 0 len
310334 | n ->
311311- let h = Bytes.create H.digest_size in
312312- H.get_into_bytes (H.feedi_string H.empty (iter2 seed (repr c))) h;
313313- go (h :: acc) Int32.(succ c) (pred n)
335335+ let h = Bytes.create H.digest_size in
336336+ H.get_into_bytes (H.feedi_string H.empty (iter2 seed (repr c))) h;
337337+ go (h :: acc) Int32.(succ c) (pred n)
314338 in
315339 go [] 0l (len // H.digest_size)
316340···321345end
322346323347module OAEP (H : Digestif.S) = struct
324324-325348 module MGF = MGF1 (H)
326349327350 let hlen = H.digest_size
328328-329329- let max_msg_bytes k = k - 2 * hlen - 2
351351+ let max_msg_bytes k = k - (2 * hlen) - 2
330352331353 let eme_oaep_encode ?g ?(label = "") k msg =
332332- let seed = Crypto_rng.generate ?g hlen
333333- and pad = String.make (max_msg_bytes k - String.length msg) '\x00' in
334334- let db = String.concat "" [ H.(digest_string label |> to_raw_string) ; pad ; bx01 ; msg ] in
335335- let mdb = Bytes.unsafe_to_string (MGF.mask ~seed db) in
354354+ let seed = Crypto_rng.generate ?g hlen
355355+ and pad = String.make (max_msg_bytes k - String.length msg) '\x00' in
356356+ let db =
357357+ String.concat ""
358358+ [ H.(digest_string label |> to_raw_string); pad; bx01; msg ]
359359+ in
360360+ let mdb = Bytes.unsafe_to_string (MGF.mask ~seed db) in
336361 let mseed = Bytes.unsafe_to_string (MGF.mask ~seed:mdb seed) in
337337- String.concat "" [ bx00 ; mseed ; mdb ]
362362+ String.concat "" [ bx00; mseed; mdb ]
338363339364 let eme_oaep_decode ?(label = "") msg =
340365 let b0 = String.sub msg 0 1
341366 and ms = String.sub msg 1 hlen
342342- and mdb = String.sub msg (1 + hlen) (String.length msg - 1 - hlen)
367367+ and mdb = String.sub msg (1 + hlen) (String.length msg - 1 - hlen) in
368368+ let db =
369369+ Bytes.unsafe_to_string
370370+ (MGF.mask ~seed:(Bytes.unsafe_to_string (MGF.mask ~seed:mdb ms)) mdb)
343371 in
344344- let db = Bytes.unsafe_to_string (MGF.mask ~seed:(Bytes.unsafe_to_string (MGF.mask ~seed:mdb ms)) mdb) in
345345- let i = ct_find_uint8 ~default:0 ~off:hlen ~f:((<>) 0x00) db in
346346- let c1 = Eqaf.equal (String.sub db 0 hlen) H.(digest_string label |> to_raw_string)
372372+ let i = ct_find_uint8 ~default:0 ~off:hlen ~f:(( <> ) 0x00) db in
373373+ let c1 =
374374+ Eqaf.equal (String.sub db 0 hlen) H.(digest_string label |> to_raw_string)
347375 and c2 = String.get_uint8 b0 0 = 0x00
348376 and c3 = String.get_uint8 db i = 0x01 in
349349- if c1 && c2 && c3 then Some (String.sub db (i + 1) (String.length db - i - 1)) else None
377377+ if c1 && c2 && c3 then
378378+ Some (String.sub db (i + 1) (String.length db - i - 1))
379379+ else None
350380351381 let encrypt ?g ?label ~key msg =
352382 let k = pub_bits key // 8 in
···355385356386 let decrypt ?(crt_hardening = false) ?mask ?label ~key em =
357387 let k = priv_bits key // 8 in
358358- if String.length em <> k || max_msg_bytes k < 0 then None else
388388+ if String.length em <> k || max_msg_bytes k < 0 then None
389389+ else
359390 try eme_oaep_decode ?label @@ decrypt ~crt_hardening ?mask ~key em
360391 with Insufficient_key -> None
361392···366397 (* XXX expose seed for deterministic testing? *)
367398end
368399369369-module PSS (H: Digestif.S) = struct
400400+module PSS (H : Digestif.S) = struct
370401 module MGF = MGF1 (H)
371371- module H1 = Digest_or (H)
402402+ module H1 = Digest_or (H)
372403373404 let hlen = H.digest_size
374374-375405 let bxbc = "\xbc"
376376-377377- let b0mask embits = 0xff lsr ((8 - embits mod 8) mod 8)
378378-406406+ let b0mask embits = 0xff lsr ((8 - (embits mod 8)) mod 8)
379407 let zero_8 = String.make 8 '\x00'
380408381409 let digest ~salt msg =
382410 H.to_raw_string @@ H.digesti_string @@ iter3 zero_8 (H1.digest_or msg) salt
383411384412 let emsa_pss_encode ?g slen emlen msg =
385385- let n = emlen // 8
386386- and salt = Crypto_rng.generate ?g slen in
387387- let h = digest ~salt msg in
388388- let db = String.concat "" [ String.make (n - slen - hlen - 2) '\x00' ; bx01 ; salt ] in
389389- let mdb = MGF.mask ~seed:h db in
390390- Bytes.set_uint8 mdb 0 @@ Bytes.get_uint8 mdb 0 land b0mask emlen ;
391391- String.concat "" [ Bytes.unsafe_to_string mdb ; h ; bxbc ]
413413+ let n = emlen // 8 and salt = Crypto_rng.generate ?g slen in
414414+ let h = digest ~salt msg in
415415+ let db =
416416+ String.concat "" [ String.make (n - slen - hlen - 2) '\x00'; bx01; salt ]
417417+ in
418418+ let mdb = MGF.mask ~seed:h db in
419419+ Bytes.set_uint8 mdb 0 @@ (Bytes.get_uint8 mdb 0 land b0mask emlen);
420420+ String.concat "" [ Bytes.unsafe_to_string mdb; h; bxbc ]
392421393422 let emsa_pss_verify slen emlen em msg =
394423 let mdb = String.sub em 0 (String.length em - hlen - 1)
395424 and h = String.sub em (String.length em - hlen - 1) hlen
396396- and bxx = String.get_uint8 em (String.length em - 1)
397397- in
398398- let db = MGF.mask ~seed:h mdb in
399399- Bytes.set_uint8 db 0 (Bytes.get_uint8 db 0 land b0mask emlen) ;
400400- let db = Bytes.unsafe_to_string db in
425425+ and bxx = String.get_uint8 em (String.length em - 1) in
426426+ let db = MGF.mask ~seed:h mdb in
427427+ Bytes.set_uint8 db 0 (Bytes.get_uint8 db 0 land b0mask emlen);
428428+ let db = Bytes.unsafe_to_string db in
401429 let salt = String.sub db (String.length db - slen) slen in
402402- let h' = digest ~salt:salt msg
403403- and i = ct_find_uint8 ~default:0 ~f:((<>) 0x00) db in
430430+ let h' = digest ~salt msg
431431+ and i = ct_find_uint8 ~default:0 ~f:(( <> ) 0x00) db in
404432 let c1 = lnot (b0mask emlen) land String.get_uint8 mdb 0 = 0x00
405433 and c2 = i = String.length em - hlen - slen - 2
406406- and c3 = String.get_uint8 db i = 0x01
434434+ and c3 = String.get_uint8 db i = 0x01
407435 and c4 = bxx = 0xbc
408436 and c5 = Eqaf.equal h h' in
409437 c1 && c2 && c3 && c4 && c5
···419447 decrypt ~crt_hardening ?mask ~key msg'
420448421449 let verify ?(slen = hlen) ~key ~signature msg =
422422- let b = pub_bits key
423423- and s = String.length signature in
424424- s = b // 8 && sufficient_key ~slen b && try
425425- let em = encrypt ~key signature in
426426- let to_see = s - (b - 1) // 8 in
427427- emsa_pss_verify (imax 0 slen) (b - 1) (String.sub em to_see (String.length em - to_see)) msg
428428- with Insufficient_key -> false
429429-450450+ let b = pub_bits key and s = String.length signature in
451451+ s = b // 8
452452+ && sufficient_key ~slen b
453453+ &&
454454+ try
455455+ let em = encrypt ~key signature in
456456+ let to_see = s - ((b - 1) // 8) in
457457+ emsa_pss_verify (imax 0 slen) (b - 1)
458458+ (String.sub em to_see (String.length em - to_see))
459459+ msg
460460+ with Insufficient_key -> false
430461end
+66-61
pk/z_extra.ml
···55let of_octets_be ?bits buf =
66 let rec loop acc i = function
77 | b when b >= 64 ->
88- let x = String.get_int64_be buf i in
99- let x = Z.of_int64_unsigned Int64.(shift_right_logical x 8) in
1010- loop Z.(x + acc lsl 56) (i + 7) (b - 56)
88+ let x = String.get_int64_be buf i in
99+ let x = Z.of_int64_unsigned Int64.(shift_right_logical x 8) in
1010+ loop Z.(x + (acc lsl 56)) (i + 7) (b - 56)
1111 | b when b >= 32 ->
1212- let x = String.get_int32_be buf i in
1313- let x = Z.of_int32_unsigned Int32.(shift_right_logical x 8) in
1414- loop Z.(x + acc lsl 24) (i + 3) (b - 24)
1212+ let x = String.get_int32_be buf i in
1313+ let x = Z.of_int32_unsigned Int32.(shift_right_logical x 8) in
1414+ loop Z.(x + (acc lsl 24)) (i + 3) (b - 24)
1515 | b when b >= 16 ->
1616- let x = Z.of_int (String.get_uint16_be buf i) in
1717- loop Z.(x + acc lsl 16) (i + 2) (b - 16)
1818- | b when b >= 8 ->
1919- let x = Z.of_int (String.get_uint8 buf i) in
2020- loop Z.(x + acc lsl 8 ) (i + 1) (b - 8 )
2121- | b when b > 0 ->
2222- let x = String.get_uint8 buf i and b' = 8 - b in
2323- Z.(of_int x asr b' + acc lsl b)
2424- | _ -> acc in
2525- loop Z.zero 0 @@ match bits with
2626- | None -> String.length buf * 8
1616+ let x = Z.of_int (String.get_uint16_be buf i) in
1717+ loop Z.(x + (acc lsl 16)) (i + 2) (b - 16)
1818+ | b when b >= 8 ->
1919+ let x = Z.of_int (String.get_uint8 buf i) in
2020+ loop Z.(x + (acc lsl 8)) (i + 1) (b - 8)
2121+ | b when b > 0 ->
2222+ let x = String.get_uint8 buf i and b' = 8 - b in
2323+ Z.((of_int x asr b') + (acc lsl b))
2424+ | _ -> acc
2525+ in
2626+ loop Z.zero 0
2727+ @@
2828+ match bits with
2929+ | None -> String.length buf * 8
2730 | Some b -> imin b (String.length buf * 8)
28312932let byte1 = Z.of_int64 0xffL
···3437let into_octets_be n buf =
3538 let rec write n = function
3639 | i when i >= 7 ->
3737- Bytes.set_int64_be buf (i - 7) Z.(to_int64_unsigned (n land byte7)) ;
3838- write Z.(n asr 56) (i - 7)
4040+ Bytes.set_int64_be buf (i - 7) Z.(to_int64_unsigned (n land byte7));
4141+ write Z.(n asr 56) (i - 7)
3942 | i when i >= 3 ->
4040- Bytes.set_int32_be buf (i - 3) Z.(to_int32_unsigned (n land byte3)) ;
4141- write Z.(n asr 24) (i - 3)
4343+ Bytes.set_int32_be buf (i - 3) Z.(to_int32_unsigned (n land byte3));
4444+ write Z.(n asr 24) (i - 3)
4245 | i when i >= 1 ->
4343- Bytes.set_uint16_be buf (i - 1) Z.(to_int (n land byte2)) ;
4444- write Z.(n asr 16) (i - 2)
4545- | 0 -> Bytes.set_uint8 buf 0 Z.(to_int (n land byte1)) ;
4646+ Bytes.set_uint16_be buf (i - 1) Z.(to_int (n land byte2));
4747+ write Z.(n asr 16) (i - 2)
4848+ | 0 -> Bytes.set_uint8 buf 0 Z.(to_int (n land byte1))
4649 | _ -> ()
4750 in
4851 write n (Bytes.length buf - 1)
49525053let to_octets_be ?size n =
5151- let buf = Bytes.create @@ match size with
5252- | Some s -> imax 0 s
5353- | None -> Z.numbits n // 8 in
5454+ let buf =
5555+ Bytes.create
5656+ @@ match size with Some s -> imax 0 s | None -> Z.numbits n // 8
5757+ in
5458 into_octets_be n buf;
5559 Bytes.unsafe_to_string buf
56605761(* Handbook of Applied Cryptography, Table 4.4:
5862 * Miller-Rabin rounds for composite probability <= 1/2^80. *)
5963let pseudoprime z =
6060- let i = match Z.numbits z with
6161- | i when i >= 1300 -> 2
6262- | i when i >= 850 -> 3
6363- | i when i >= 650 -> 4
6464- | i when i >= 350 -> 8
6565- | i when i >= 250 -> 12
6666- | i when i >= 150 -> 18
6767- | _ -> 27 in
6464+ let i =
6565+ match Z.numbits z with
6666+ | i when i >= 1300 -> 2
6767+ | i when i >= 850 -> 3
6868+ | i when i >= 650 -> 4
6969+ | i when i >= 350 -> 8
7070+ | i when i >= 250 -> 12
7171+ | i when i >= 150 -> 18
7272+ | _ -> 27
7373+ in
6874 Z.probab_prime z i <> 0
69757076(* strip_factor ~f x = (s, t), where x = f^s t *)
7177let strip_factor ~f x =
7278 let rec go n x =
7373- let (x1, r) = Z.div_rem x f in
7979+ let x1, r = Z.div_rem x f in
7480 if r = Z.zero then go (succ n) x1 else Ok (n, x)
7581 in
7676- if Z.(~$2) <= f then
7777- go 0 x
7878- else
7979- Error (`Msg ("factor_count: f: " ^ Z.to_string f))
8282+ if Z.(~$2) <= f then go 0 x
8383+ else Error (`Msg ("factor_count: f: " ^ Z.to_string f))
80848185let gen ?g n =
8286 if n < Z.one then invalid_arg "Rng.gen: non-positive: %a" Z.pp_print n;
8383- let bs = Crypto_rng.block g in
8484- let bits = Z.(numbits (pred n)) in
8585- let octets = bits // 8 in
8686- let batch =
8787- if Crypto_rng.strict g then octets else 2 * octets // bs * bs
8888- in
8989- let rec attempt buf =
9090- if String.length buf >= octets then
9191- let x = of_octets_be ~bits buf in
9292- if x < n then x else attempt (String.sub buf octets (String.length buf - octets))
9393- else attempt (Crypto_rng.generate ?g batch) in
9494- attempt (Crypto_rng.generate ?g batch)
8787+ let bs = Crypto_rng.block g in
8888+ let bits = Z.(numbits (pred n)) in
8989+ let octets = bits // 8 in
9090+ let batch = if Crypto_rng.strict g then octets else 2 * octets // bs * bs in
9191+ let rec attempt buf =
9292+ if String.length buf >= octets then
9393+ let x = of_octets_be ~bits buf in
9494+ if x < n then x
9595+ else attempt (String.sub buf octets (String.length buf - octets))
9696+ else attempt (Crypto_rng.generate ?g batch)
9797+ in
9898+ attempt (Crypto_rng.generate ?g batch)
959996100let rec gen_r ?g a b =
97101 if Crypto_rng.strict g then
9898- let x = gen ?g b in if x < a then gen_r ?g a b else x
102102+ let x = gen ?g b in
103103+ if x < a then gen_r ?g a b else x
99104 else Z.(a + gen ?g (b - a))
100100-101105102106let set_msb bits buf =
103107 if bits > 0 then
104108 let n = Bytes.length buf in
105109 let rec go width = function
106106- | i when i = n -> ()
110110+ | i when i = n -> ()
107111 | i when width < 8 ->
108108- Bytes.set_uint8 buf i (Bytes.get_uint8 buf i lor (0xff lsl (8 - width)))
112112+ Bytes.set_uint8 buf i
113113+ (Bytes.get_uint8 buf i lor (0xff lsl (8 - width)))
109114 | i ->
110110- Bytes.set_uint8 buf i 0xff ;
111111- go (width - 8) (succ i)
115115+ Bytes.set_uint8 buf i 0xff;
116116+ go (width - 8) (succ i)
112117 in
113118 go bits 0
114119···116121 let bytelen = bits // 8 in
117122 let buf = Bytes.create bytelen in
118123 Crypto_rng.generate_into ?g buf ~off:0 bytelen;
119119- set_msb msb buf ;
124124+ set_msb msb buf;
120125 of_octets_be ~bits (Bytes.unsafe_to_string buf)
121126122127(* Invalid combinations of ~bits and ~msb will loop forever, but there is no
123128 * way to quickly determine upfront whether there are any primes in the
124129 * interval.
125130 * XXX Probability is distributed as inter-prime gaps. So?
126126-*)
131131+ *)
127132let rec prime ?g ?(msb = 1) bits =
128133 let p = Z.(nextprime @@ gen_bits ?g ~msb bits) in
129134 if p < Z.(one lsl bits) then p else prime ?g ~msb bits
···131136(* XXX Add ~msb param for p? *)
132137let rec safe_prime ?g bits =
133138 let q = prime ?g ~msb:1 (bits - 1) in
134134- let p = Z.(q * ~$2 + ~$1) in
139139+ let p = Z.((q * ~$2) + ~$1) in
135140 if pseudoprime p then (q, p) else safe_prime ?g bits
···4455 There are several parts of this module:
6677- {ul
88- {- The {{!Generator}signature} of generator modules, together with a
99- facility to convert such modules into actual {{!g}generators}, and
1010- functions that operate on this representation.}
1111- {- A global generator instance, which needs to be initialized by calling
1212- {!set_default_generator}.}}
1313-*)
77+ - The {{!Generator}signature} of generator modules, together with a facility
88+ to convert such modules into actual {{!g}generators}, and functions that
99+ operate on this representation.
1010+ - A global generator instance, which needs to be initialized by calling
1111+ {!set_default_generator}. *)
14121513(** {1 Usage notes} *)
1614···2119 Linux, getentropy() on macOS and BSD systems, BCryptGenRandom on Windows).
22202321 Please ensure to call [Crypto_rng_unix.use_default], or
2424- [Crypto_rng_unix.use_dev_urandom] (if you only want to use
2525- /dev/urandom), or [Crypto_rng_unix.use_getentropy] (if you only want
2626- to use getrandom/getentropy/BCryptGenRandom).
2222+ [Crypto_rng_unix.use_dev_urandom] (if you only want to use /dev/urandom), or
2323+ [Crypto_rng_unix.use_getentropy] (if you only want to use
2424+ getrandom/getentropy/BCryptGenRandom).
27252826 For fine-grained control (doing entropy harvesting, etc.), please continue
2929- reading the documentation below. {b Please be aware that the feeding of
3030- Fortuna and producing random numbers is not thread-safe} (it is on Miou_unix
3131- via Pfortuna).
2727+ reading the documentation below.
2828+ {b Please be aware that the feeding of Fortuna and producing random numbers
2929+ is not thread-safe} (it is on Miou_unix via Pfortuna).
32303331 Suitable entropy feeding of generators are provided by other libraries
3434- {{!Crypto_rng_mirage}mirage-crypto-rng-mirage} (for MirageOS),
3535- and {{!Crypto_rng_miou_unix}mirage-crypto-miou-unix} (for Miou_unix).
3232+ {{!Crypto_rng_mirage}mirage-crypto-rng-mirage} (for MirageOS), and
3333+ {{!Crypto_rng_miou_unix}mirage-crypto-miou-unix} (for Miou_unix).
36343735 The intention is that "initialize" in the respective sub-library is called
3838- once, which sets the default generator and registers entropy
3939- harvesting asynchronous tasks. The semantics is that the entropy is always
4040- fed to the {{!default_generator}default generator}, which is not necessarily
4141- the one set by "initialize". The reasoning behind this is that the default
4242- generator should be used in most setting, and that should be fed a constant
4343- stream of entropy.
3636+ once, which sets the default generator and registers entropy harvesting
3737+ asynchronous tasks. The semantics is that the entropy is always fed to the
3838+ {{!default_generator}default generator}, which is not necessarily the one
3939+ set by "initialize". The reasoning behind this is that the default generator
4040+ should be used in most setting, and that should be fed a constant stream of
4141+ entropy.
44424543 The RNGs here are merely the deterministic part of a full random number
4644 generation suite. For proper operation, they need to be seeded with a
···66646765 The recommended way to use these functions is either to accept an optional
6866 generator and pass it down, or to ignore the generator altogether, as
6969- illustrated in the {{!rng_examples}examples}.
7070-*)
6767+ illustrated in the {{!rng_examples}examples}. *)
71687269(** {1 Interface} *)
7370···82798380(** Entropy sources and collection *)
8481module Entropy : sig
8585-8282+ type source
8683 (** Entropy sources. *)
8787- type source
88848985 val sources : unit -> source list
9086 (** [sources ()] returns the list of available sources. *)
···999510096 val whirlwind_bootstrap : int -> string
10197 (** [whirlwind_bootstrap id] exploits CPU-level data races which lead to
102102- execution-time variability. It returns 200 bytes random data prefixed
103103- by [id].
9898+ execution-time variability. It returns 200 bytes random data prefixed by
9999+ [id].
104100105105- See {{:http://www.ieee-security.org/TC/SP2014/papers/Not-So-RandomNumbersinVirtualizedLinuxandtheWhirlwindRNG.pdf}}
101101+ See
102102+ {:http://www.ieee-security.org/TC/SP2014/papers/Not-So-RandomNumbersinVirtualizedLinuxandtheWhirlwindRNG.pdf}
106103 for further details. *)
107104108108- val cpu_rng_bootstrap : (int -> string, [`Not_supported]) Result.t
109109- (** [cpu_rng_bootstrap id] returns 8 bytes of random data using the CPU
110110- RNG (rdseed). On 32bit platforms, only 4 bytes are filled.
111111- The [id] is used as prefix. If only rdrand is available, the return
112112- value is the concatenation of 512 calls to rdrand.
105105+ val cpu_rng_bootstrap : (int -> string, [ `Not_supported ]) Result.t
106106+ (** [cpu_rng_bootstrap id] returns 8 bytes of random data using the CPU RNG
107107+ (rdseed). On 32bit platforms, only 4 bytes are filled. The [id] is used as
108108+ prefix. If only rdrand is available, the return value is the concatenation
109109+ of 512 calls to rdrand.
113110114114- @raise Failure if rdrand fails 512 times, or if rdseed fails and rdrand
115115- is not available.
116116- *)
111111+ @raise Failure
112112+ if rdrand fails 512 times, or if rdseed fails and rdrand is not
113113+ available. *)
117114118115 val bootstrap : int -> string
119116 (** [bootstrap id] is either [cpu_rng_bootstrap], if the CPU supports it, or
···122119 (** {1 Timer source} *)
123120124121 val interrupt_hook : unit -> string
125125- (** [interrupt_hook] collects lower bytes from the cycle counter, to be
126126- used for entropy collection in the event loop. *)
122122+ (** [interrupt_hook] collects lower bytes from the cycle counter, to be used
123123+ for entropy collection in the event loop. *)
127124128125 val timer_accumulator : g option -> unit -> unit
129129- (** [timer_accumulator g] is the accumulator for the timer source,
130130- applying {!interrupt_hook} on each call. *)
126126+ (** [timer_accumulator g] is the accumulator for the timer source, applying
127127+ {!interrupt_hook} on each call. *)
131128132129 (** {1 Periodic pulled sources} *)
133130134134- val feed_pools : g option -> source -> (unit -> (string, [ `No_random_available ]) result) -> unit
131131+ val feed_pools :
132132+ g option ->
133133+ source ->
134134+ (unit -> (string, [ `No_random_available ]) result) ->
135135+ unit
135136 (** [feed_pools g source f] feeds all pools of [g] using [source] by executing
136137 [f] for each pool. *)
137138138138- val cpu_rng : (g option -> unit -> unit, [`Not_supported]) Result.t
139139- (** [cpu_rng g] uses the CPU RNG (rdrand or rdseed) to feed all pools
140140- of [g]. It uses {!feed_pools} internally. If neither rdrand nor rdseed
141141- are available, [`Not_supported] is returned. *)
139139+ val cpu_rng : (g option -> unit -> unit, [ `Not_supported ]) Result.t
140140+ (** [cpu_rng g] uses the CPU RNG (rdrand or rdseed) to feed all pools of [g].
141141+ It uses {!feed_pools} internally. If neither rdrand nor rdseed are
142142+ available, [`Not_supported] is returned. *)
142143143144 val rdrand_calls : unit -> int
144145 (** [rdrand_calls ()] returns the number of rdrand calls. *)
···153154 (** [rdseed_failures ()] returns the number of rdseed failures. *)
154155155156 (**/**)
157157+156158 val id : source -> int
157159 (** [id source] is the identifier used for [source]. *)
158160159161 val header : int -> string -> string
160162 (** [header id data] constructs a unique header with [id], length of [data],
161163 and [data]. *)
164164+162165 (**/**)
163166end
164167165168(** A single PRNG algorithm. *)
166169module type Generator = sig
167167-168170 type g
169171 (** State type for this generator. *)
170172···176178 (** Create a new, unseeded {{!g}g}. *)
177179178180 val generate_into : g:g -> bytes -> off:int -> int -> unit
179179- [@@alert unsafe "Does not do bounds checks. Use Crypto_rng.generate_into instead."]
181181+ [@@alert
182182+ unsafe "Does not do bounds checks. Use Crypto_rng.generate_into instead."]
180183 (** [generate_into ~g buf ~off n] produces [n] uniformly distributed random
181184 bytes into [buf] at offset [off], updating the state of [g].
182185183186 Assumes that [buf] is at least [off + n] bytes long. Also assumes that
184187 [off] and [n] are positive integers. Caution: do not use in your
185185- application, use [Crypto_rng.generate_into] instead.
186186- *)
188188+ application, use [Crypto_rng.generate_into] instead. *)
187189188190 val reseed : g:g -> string -> unit
189191 (** [reseed ~g bytes] directly updates [g]. Its new state depends both on
···191193192194 A generator is seded after a single application of [reseed]. *)
193195194194- val accumulate : g:g -> Entropy.source -> [`Acc of string -> unit]
195195- (** [accumulate ~g] is a closure suitable for incrementally feeding
196196- small amounts of environmentally sourced entropy into [g].
196196+ val accumulate : g:g -> Entropy.source -> [ `Acc of string -> unit ]
197197+ (** [accumulate ~g] is a closure suitable for incrementally feeding small
198198+ amounts of environmentally sourced entropy into [g].
197199198198- Its operation should be fast enough for repeated calling from e.g.
199199- event loops. Systems with several distinct, stable entropy sources
200200- should use stable [source] to distinguish their sources. *)
200200+ Its operation should be fast enough for repeated calling from e.g. event
201201+ loops. Systems with several distinct, stable entropy sources should use
202202+ stable [source] to distinguish their sources. *)
201203202204 val seeded : g:g -> bool
203205 (** [seeded ~g] is [true] iff operations won't throw
···211213212214(** Ready-to-use RNG algorithms. *)
213215214214-(** {b Fortuna}, a CSPRNG {{: https://www.schneier.com/fortuna.html} proposed}
215215- by Schneier. *)
216216module Fortuna : Generator
217217+(** {b Fortuna}, a CSPRNG {{:https://www.schneier.com/fortuna.html} proposed} by
218218+ Schneier. *)
217219218220(** {b HMAC_DRBG}: A NIST-specified RNG based on HMAC construction over the
219221 provided hash. *)
220222module Hmac_drbg (H : Digestif.S) : Generator
221223222222-val create : ?g:'a -> ?seed:string -> ?strict:bool ->
223223- ?time:(unit -> int64) -> 'a generator -> g
224224+val create :
225225+ ?g:'a ->
226226+ ?seed:string ->
227227+ ?strict:bool ->
228228+ ?time:(unit -> int64) ->
229229+ 'a generator ->
230230+ g
224231(** [create ~g ~seed ~strict ~time module] uses a module conforming to the
225232 {{!Generator}Generator} signature to instantiate the generic generator
226233 {{!g}g}.
···239246(** [default_generator ()] is the default generator. Functions in this module
240247 use this generator when not explicitly supplied one.
241248242242- @raise No_default_generator if {!set_default_generator} has not been called. *)
249249+ @raise No_default_generator if {!set_default_generator} has not been called.
250250+*)
243251244252val set_default_generator : g -> unit
245253(** [set_default_generator g] sets the default generator to [g]. This function
246254 must be called once. *)
247255248256(**/**)
257257+249258(* This function is only used by eio to set the default generator to None when
250259 the entropy harvesting tasks are finished. *)
251260val unset_default_generator : unit -> unit
252261(** [unset_default_generator ()] sets the default generator to [None]. *)
262262+253263(**/**)
254264255265val generate_into : ?g:g -> bytes -> ?off:int -> int -> unit
···258268 {{!generator}default generator}. The random data is put into [buf] starting
259269 at [off] (defaults to 0) with [len] bytes.
260270261261- @raise Invalid_argument if buffer is too small (it must be: [Bytes.length
262262- buf - off >= n]) or [off] or [n] are negative.
263263-*)
271271+ @raise Invalid_argument
272272+ if buffer is too small (it must be: [Bytes.length buf - off >= n]) or
273273+ [off] or [n] are negative. *)
264274265275val generate : ?g:g -> int -> string
266276(** Invoke {!generate_into} on [g] or {{!generator}default generator} and a
267277 freshly allocated string. *)
268278269279val block : g option -> int
270270-(** {{!Generator.block}Block} size of [g] or
271271- {{!generator}default generator}. *)
280280+(** {{!Generator.block}Block} size of [g] or {{!generator}default generator}. *)
272281273282(**/**)
274283···276285 * connect the RNG with entropy-providing libraries and subject to change.
277286 * Client applications should not use them directly. *)
278287279279-val reseed : ?g:g -> string -> unit
280280-val accumulate : g option -> Entropy.source -> [`Acc of string -> unit]
281281-val seeded : g option -> bool
282282-val pools : g option -> int
288288+val reseed : ?g:g -> string -> unit
289289+val accumulate : g option -> Entropy.source -> [ `Acc of string -> unit ]
290290+val seeded : g option -> bool
291291+val pools : g option -> int
283292val strict : g option -> bool
293293+284294(**/**)
285285-286295287296(** {1:rng_examples Examples}
288297289298 Generating a random 13-byte string:
290290-{[let cs = Rng.generate 13]}
299299+ {[
300300+ let cs = Rng.generate 13
301301+ ]}
291302292303 Generating a list of string, passing down an optional {{!g}generator}:
293293-{[let rec f1 ?g ~n i =
294294- if i < 1 then [] else Rng.generate ?g n :: f1 ?g ~n (i - 1)]}
304304+ {[
305305+ let rec f1 ?g ~n i =
306306+ if i < 1 then [] else Rng.generate ?g n :: f1 ?g ~n (i - 1)
307307+ ]}
295308296309 Generating a [Z.t] smaller than [10]:
297297-{[let f2 ?g () = Crypto_pk.Z_extra.gen ?g Z.(~$10)]}
310310+ {[
311311+ let f2 ?g () = Crypto_pk.Z_extra.gen ?g Z.(~$10)
312312+ ]}
298313299314 Creating a local Fortuna instance and using it as a key-derivation function:
300300-{[let f3 secret =
301301- let g = Rng.(create ~seed:secret (module Generators.Fortuna)) in
302302- Rng.generate ~g 32]}
303303-*)
315315+ {[
316316+ let f3 secret =
317317+ let g = Rng.(create ~seed:secret (module Generators.Fortuna)) in
318318+ Rng.generate ~g 32
319319+ ]} *)
+78-86
rng/entropy.ml
···2727 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828 *)
29293030-let src = Logs.Src.create "mirage-crypto-rng-entropy" ~doc:"Mirage crypto RNG Entropy"
3030+let src =
3131+ Logs.Src.create "mirage-crypto-rng-entropy" ~doc:"Mirage crypto RNG Entropy"
3232+3133module Log = (val Logs.src_log src : Logs.LOG)
32343335let rdrand_calls = Atomic.make 0
···3638let rdseed_failures = Atomic.make 0
37393840module Cpu_native = struct
3939-4040- external cycles : unit -> int = "mc_cycle_counter" [@@noalloc]
4141- external rdseed : bytes -> int -> bool = "mc_cpu_rdseed" [@@noalloc]
4242- external rdrand : bytes -> int -> bool = "mc_cpu_rdrand" [@@noalloc]
4343- external rng_type : unit -> int = "mc_cpu_rng_type" [@@noalloc]
4141+ external cycles : unit -> int = "mc_cycle_counter" [@@noalloc]
4242+ external rdseed : bytes -> int -> bool = "mc_cpu_rdseed" [@@noalloc]
4343+ external rdrand : bytes -> int -> bool = "mc_cpu_rdrand" [@@noalloc]
4444+ external rng_type : unit -> int = "mc_cpu_rng_type" [@@noalloc]
44454546 let cpu_rng =
4647 match rng_type () with
4748 | 0 -> []
4849 | 1 -> [ `Rdrand ]
4950 | 2 -> [ `Rdseed ]
5050- | 3 -> [ `Rdrand ; `Rdseed ]
5151+ | 3 -> [ `Rdrand; `Rdseed ]
5152 | _ -> assert false
5253end
53545454-module S = Set.Make(struct
5555- type t = int * string
5656- (* only the name is relevant for comparison - the idx not *)
5757- let compare ((_a, an) : int * string) ((_b, bn) : int * string) =
5858- String.compare an bn
5959- end)
5555+module S = Set.Make (struct
5656+ type t = int * string
5757+5858+ (* only the name is relevant for comparison - the idx not *)
5959+ let compare ((_a, an) : int * string) ((_b, bn) : int * string) =
6060+ String.compare an bn
6161+end)
60626163let _sources = Atomic.make S.empty
6264···6971 let source = (n, name) in
7072 if Atomic.compare_and_set _sources sources (S.add source sources) then
7173 source
7272- else
7373- set ()
7474+ else set ()
7475 in
7576 set ()
76777778let id (idx, _) = idx
7878-7979let sources () = S.elements (Atomic.get _sources)
8080-8180let pp_source ppf (idx, name) = Format.fprintf ppf "[%d] %s" idx name
82818383-let cpu_rng isn buf off = match isn with
8282+let cpu_rng isn buf off =
8383+ match isn with
8484 | `Rdseed ->
8585- Atomic.incr rdseed_calls;
8686- let success = Cpu_native.rdseed buf off in
8787- if not success then Atomic.incr rdseed_failures;
8888- success
8585+ Atomic.incr rdseed_calls;
8686+ let success = Cpu_native.rdseed buf off in
8787+ if not success then Atomic.incr rdseed_failures;
8888+ success
8989 | `Rdrand ->
9090- Atomic.incr rdrand_calls;
9191- let success = Cpu_native.rdrand buf off in
9292- if not success then Atomic.incr rdrand_failures;
9393- success
9090+ Atomic.incr rdrand_calls;
9191+ let success = Cpu_native.rdrand buf off in
9292+ if not success then Atomic.incr rdrand_failures;
9393+ success
94949595let random preferred =
9696 match Cpu_native.cpu_rng with
9797 | [] -> None
9898 | xs when List.mem preferred xs -> Some preferred
9999- | y::_ -> Some y
9999+ | y :: _ -> Some y
100100101101let write_header source data =
102102 Bytes.set_uint8 data 0 source;
···113113 * data races that lead to execution-time variability of identical instructions.
114114 * See Whirlwind RNG:
115115 * http://www.ieee-security.org/TC/SP2014/papers/Not-So-RandomNumbersinVirtualizedLinuxandtheWhirlwindRNG.pdf
116116-*)
116116+ *)
117117let whirlwind_bootstrap id =
118118- let outer = 100
119119- and inner_max = 1024
120120- and a = ref 0
121121- in
122122- let buf = Bytes.create (outer * 2 + 2) in
118118+ let outer = 100 and inner_max = 1024 and a = ref 0 in
119119+ let buf = Bytes.create ((outer * 2) + 2) in
123120 for i = 0 to outer - 1 do
124121 let tsc = Cpu_native.cycles () in
125122 Bytes.set_uint16_le buf ((i + 1) * 2) tsc;
126123 for j = 1 to tsc mod inner_max do
127127- a := tsc / j - !a * i + 1
124124+ a := (tsc / j) - (!a * i) + 1
128125 done
129126 done;
130127 write_header id buf;
···135132 let rec go acc = function
136133 | 0 -> acc
137134 | n ->
138138- let buf = Bytes.create 10 in
139139- let r = cpu_rng `Rdrand buf 2 in
140140- write_header id buf;
141141- if not r then
142142- go acc (pred n)
143143- else
144144- go (Bytes.unsafe_to_string buf :: acc) (pred n)
135135+ let buf = Bytes.create 10 in
136136+ let r = cpu_rng `Rdrand buf 2 in
137137+ write_header id buf;
138138+ if not r then go acc (pred n)
139139+ else go (Bytes.unsafe_to_string buf :: acc) (pred n)
145140 in
146141 let result = go [] 512 |> String.concat "" in
147147- if String.length result = 0 then
148148- failwith "Too many RDRAND failures"
149149- else
150150- result
142142+ if String.length result = 0 then failwith "Too many RDRAND failures"
143143+ else result
151144 in
152145 match random `Rdseed with
153146 | None -> Error `Not_supported
154147 | Some `Rdseed ->
155155- let cpu_rng_bootstrap id =
156156- let buf = Bytes.create 10 in
157157- let r = cpu_rng `Rdseed buf 2 in
158158- write_header id buf;
159159- if not r then
160160- if List.mem `Rdrand Cpu_native.cpu_rng then
161161- rdrand_bootstrap id
162162- else
163163- failwith "RDSEED failed, and RDRAND not available"
164164- else
165165- Bytes.unsafe_to_string buf
166166- in
167167- Ok cpu_rng_bootstrap
148148+ let cpu_rng_bootstrap id =
149149+ let buf = Bytes.create 10 in
150150+ let r = cpu_rng `Rdseed buf 2 in
151151+ write_header id buf;
152152+ if not r then
153153+ if List.mem `Rdrand Cpu_native.cpu_rng then rdrand_bootstrap id
154154+ else failwith "RDSEED failed, and RDRAND not available"
155155+ else Bytes.unsafe_to_string buf
156156+ in
157157+ Ok cpu_rng_bootstrap
168158 | Some `Rdrand -> Ok rdrand_bootstrap
169159170160let bootstrap id =
171161 match cpu_rng_bootstrap with
172162 | Error `Not_supported -> whirlwind_bootstrap id
173173- | Ok cpu_rng_bootstrap ->
174174- try cpu_rng_bootstrap id with
175175- | Failure f ->
176176- Log.err (fun m -> m "CPU RNG bootstrap failed: %s, using whirlwind" f);
177177- whirlwind_bootstrap id
163163+ | Ok cpu_rng_bootstrap -> (
164164+ try cpu_rng_bootstrap id
165165+ with Failure f ->
166166+ Log.err (fun m -> m "CPU RNG bootstrap failed: %s, using whirlwind" f);
167167+ whirlwind_bootstrap id)
178168179169let interrupt_hook () =
180170 let buf = Bytes.create 4 in
181171 let a = Cpu_native.cycles () in
182182- Bytes.set_int32_le buf 0 (Int32.of_int a) ;
172172+ Bytes.set_int32_le buf 0 (Int32.of_int a);
183173 Bytes.unsafe_to_string buf
184174185175let timer_accumulator g =
186186- let g = match g with None -> Some (Rng.default_generator ()) | Some g -> Some g in
176176+ let g =
177177+ match g with None -> Some (Rng.default_generator ()) | Some g -> Some g
178178+ in
187179 let source = register_source "timer" in
188188- let `Acc handle = Rng.accumulate g source in
189189- (fun () -> handle (interrupt_hook ()))
180180+ let (`Acc handle) = Rng.accumulate g source in
181181+ fun () -> handle (interrupt_hook ())
190182191183let feed_pools g source f =
192192- let g = match g with None -> Some (Rng.default_generator ()) | Some g -> Some g in
193193- let `Acc handle = Rng.accumulate g source in
184184+ let g =
185185+ match g with None -> Some (Rng.default_generator ()) | Some g -> Some g
186186+ in
187187+ let (`Acc handle) = Rng.accumulate g source in
194188 for _i = 0 to pred (Rng.pools g) do
195189 match f () with
196190 | Ok data -> handle data
197191 | Error `No_random_available ->
198198- (* should we log a message? *)
199199- ()
192192+ (* should we log a message? *)
193193+ ()
200194 done
201195202196let cpu_rng =
203197 match random `Rdrand with
204198 | None -> Error `Not_supported
205199 | Some insn ->
206206- let cpu_rng g =
207207- let randomf = cpu_rng insn
208208- and source =
209209- let s = match insn with `Rdrand -> "rdrand" | `Rdseed -> "rdseed" in
210210- register_source s
211211- in
212212- let f () =
213213- let buf = Bytes.create 8 in
214214- if randomf buf 0 then
215215- Ok (Bytes.unsafe_to_string buf)
216216- else
217217- Error `No_random_available
200200+ let cpu_rng g =
201201+ let randomf = cpu_rng insn
202202+ and source =
203203+ let s = match insn with `Rdrand -> "rdrand" | `Rdseed -> "rdseed" in
204204+ register_source s
205205+ in
206206+ let f () =
207207+ let buf = Bytes.create 8 in
208208+ if randomf buf 0 then Ok (Bytes.unsafe_to_string buf)
209209+ else Error `No_random_available
210210+ in
211211+ fun () -> feed_pools g source f
218212 in
219219- fun () -> feed_pools g source f
220220- in
221221- Ok cpu_rng
213213+ Ok cpu_rng
222214223215let rdrand_calls () = Atomic.get rdrand_calls
224216let rdrand_failures () = Atomic.get rdrand_failures
+61-46
rng/fortuna.ml
···6677module SHAd256 = struct
88 open Digestif
99+910 type t = SHA256.t
1011 type ctx = SHA256.ctx
1111- let empty = SHA256.empty
1212- let get t = SHA256.(get t |> to_raw_string |> digest_string |> to_raw_string)
1313- let digest x = SHA256.(digest_string x |> to_raw_string |> digest_string |> to_raw_string)
1414- let digesti i = SHA256.(digesti_string i |> to_raw_string |> digest_string |> to_raw_string)
1515- let feedi = SHA256.feedi_string
1212+1313+ let empty = SHA256.empty
1414+ let get t = SHA256.(get t |> to_raw_string |> digest_string |> to_raw_string)
1515+1616+ let digest x =
1717+ SHA256.(digest_string x |> to_raw_string |> digest_string |> to_raw_string)
1818+1919+ let digesti i =
2020+ SHA256.(digesti_string i |> to_raw_string |> digest_string |> to_raw_string)
2121+2222+ let feedi = SHA256.feedi_string
1623end
17241825let block = 16
19262027(* the minimal amount of bytes in a pool to trigger a reseed *)
2128let min_pool_size = 64
2929+2230(* the minimal duration between two reseeds *)
2331let min_time_duration = 1_000_000_000L
3232+2433(* number of pools *)
2534let pools = 32
26352736(* XXX Locking!! *)
2828-type g =
2929- { mutable ctr : AES.CTR.ctr
3030- ; mutable secret : string
3131- ; mutable key : AES.CTR.key
3232- ; pools : SHAd256.ctx array
3333- ; mutable pool0_size : int
3434- ; mutable reseed_count : int
3535- ; mutable last_reseed : int64
3636- ; time : (unit -> int64) option
3737- }
3737+type g = {
3838+ mutable ctr : AES.CTR.ctr;
3939+ mutable secret : string;
4040+ mutable key : AES.CTR.key;
4141+ pools : SHAd256.ctx array;
4242+ mutable pool0_size : int;
4343+ mutable reseed_count : int;
4444+ mutable last_reseed : int64;
4545+ time : (unit -> int64) option;
4646+}
38473948let create ?time () =
4049 let k = String.make 32 '\x00' in
4141- { ctr = (0L, 0L)
4242- ; secret = k
4343- ; key = AES.CTR.of_secret k
4444- ; pools = Array.make pools SHAd256.empty
4545- ; pool0_size = 0
4646- ; reseed_count = 0
4747- ; last_reseed = 0L
4848- ; time
5050+ {
5151+ ctr = (0L, 0L);
5252+ secret = k;
5353+ key = AES.CTR.of_secret k;
5454+ pools = Array.make pools SHAd256.empty;
5555+ pool0_size = 0;
5656+ reseed_count = 0;
5757+ last_reseed = 0L;
5858+ time;
4959 }
50605161let seeded ~g =
···54645565(* XXX We might want to erase the old key. *)
5666let set_key ~g sec =
5757- g.secret <- sec ;
5858- g.key <- AES.CTR.of_secret sec
6767+ g.secret <- sec;
6868+ g.key <- AES.CTR.of_secret sec
59696070let reseedi ~g iter =
6161- set_key ~g @@ SHAd256.digesti (fun f -> f g.secret; iter f);
7171+ set_key ~g
7272+ @@ SHAd256.digesti (fun f ->
7373+ f g.secret;
7474+ iter f);
6275 g.ctr <- AES.CTR.add_ctr g.ctr 1L
63766464-let iter1 a f = f a
6565-7777+let iter1 a f = f a
6678let reseed ~g cs = reseedi ~g (iter1 cs)
67796880let generate_rekey ~g buf ~off len =
6969- let b = len // block + 2 in
7070- let n = b * block in
7171- let r = AES.CTR.stream ~key:g.key ~ctr:g.ctr n in
8181+ let b = (len // block) + 2 in
8282+ let n = b * block in
8383+ let r = AES.CTR.stream ~key:g.key ~ctr:g.ctr n in
7284 Bytes.unsafe_blit_string r 0 buf off len;
7385 let r2 = String.sub r (n - 32) 32 in
7474- set_key ~g r2 ;
8686+ set_key ~g r2;
7587 g.ctr <- AES.CTR.add_ctr g.ctr (Int64.of_int b)
76887789let add_pool_entropy g =
7890 if g.pool0_size > min_pool_size then
7991 let should_reseed, now =
8092 match g.time with
8181- | None -> true, 0L
9393+ | None -> (true, 0L)
8294 | Some f ->
8383- let now = f () in
8484- Int64.(sub now g.last_reseed > min_time_duration), now
9595+ let now = f () in
9696+ (Int64.(sub now g.last_reseed > min_time_duration), now)
8597 in
8698 if should_reseed then begin
8799 g.reseed_count <- g.reseed_count + 1;
···89101 g.pool0_size <- 0;
90102 reseedi ~g @@ fun add ->
91103 for i = 0 to pools - 1 do
9292- if g.reseed_count land ((1 lsl i) - 1) = 0 then
9393- (SHAd256.get g.pools.(i) |> add; g.pools.(i) <- SHAd256.empty)
104104+ if g.reseed_count land ((1 lsl i) - 1) = 0 then (
105105+ SHAd256.get g.pools.(i) |> add;
106106+ g.pools.(i) <- SHAd256.empty)
94107 done
95108 end
9610997110let generate_into ~g buf ~off len =
98111 add_pool_entropy g;
9999- if not (seeded ~g) then raise Rng.Unseeded_generator ;
112112+ if not (seeded ~g) then raise Rng.Unseeded_generator;
100113 let rec chunk off = function
101114 | i when i <= 0 -> ()
102115 | n ->
103103- let n' = imin n 0x10000 in
104104- generate_rekey ~g buf ~off n';
105105- chunk (off + n') (n - n')
116116+ let n' = imin n 0x10000 in
117117+ generate_rekey ~g buf ~off n';
118118+ chunk (off + n') (n - n')
106119 in
107120 chunk off len
108121109122let add ~g (source, _) ~pool data =
110123 let buf = Bytes.create 2
111111- and pool = pool land (pools - 1)
124124+ and pool = pool land (pools - 1)
112125 and source = source land 0xff in
113126 Bytes.set_uint8 buf 0 source;
114127 Bytes.set_uint8 buf 1 (String.length data);
115115- g.pools.(pool) <- SHAd256.feedi g.pools.(pool) (iter2 (Bytes.unsafe_to_string buf) data);
128128+ g.pools.(pool) <-
129129+ SHAd256.feedi g.pools.(pool) (iter2 (Bytes.unsafe_to_string buf) data);
116130 if pool = 0 then g.pool0_size <- g.pool0_size + String.length data
117131118132(* XXX
···121135 *)
122136let accumulate ~g source =
123137 let pool = ref 0 in
124124- `Acc (fun buf ->
125125- add ~g source ~pool:!pool buf ;
126126- incr pool)
138138+ `Acc
139139+ (fun buf ->
140140+ add ~g source ~pool:!pool buf;
141141+ incr pool)
+26-25
rng/hmac_drbg.ml
···11module Make (H : Digestif.S) = struct
22- type g =
33- { mutable k : string
44- ; mutable v : string
55- ; mutable seeded : bool
66- }
22+ type g = { mutable k : string; mutable v : string; mutable seeded : bool }
7384 let block = H.digest_size
99-1010- let (bx00, bx01) = "\x00", "\x01"
55+ let bx00, bx01 = ("\x00", "\x01")
116127 let k0 = String.make H.digest_size '\x00'
138 and v0 = String.make H.digest_size '\x01'
1491515- let create ?time:_ () = { k = k0 ; v = v0 ; seeded = false }
1616-1010+ let create ?time:_ () = { k = k0; v = v0; seeded = false }
1711 let seeded ~g = g.seeded
18121913 let reseed ~g buf =
2020- let (k, v) = (g.k, g.v) in
2121- let k = H.hmac_string ~key:k @@ String.concat "" [v; bx00; buf] |> H.to_raw_string in
1414+ let k, v = (g.k, g.v) in
1515+ let k =
1616+ H.hmac_string ~key:k @@ String.concat "" [ v; bx00; buf ]
1717+ |> H.to_raw_string
1818+ in
2219 let v = H.hmac_string ~key:k v |> H.to_raw_string in
2323- let k = H.hmac_string ~key:k @@ String.concat "" [v; bx01; buf] |> H.to_raw_string in
2020+ let k =
2121+ H.hmac_string ~key:k @@ String.concat "" [ v; bx01; buf ]
2222+ |> H.to_raw_string
2323+ in
2424 let v = H.hmac_string ~key:k v |> H.to_raw_string in
2525- g.k <- k ; g.v <- v ; g.seeded <- true
2525+ g.k <- k;
2626+ g.v <- v;
2727+ g.seeded <- true
26282729 let generate_into ~g buf ~off len =
2828- if not g.seeded then raise Rng.Unseeded_generator ;
3030+ if not g.seeded then raise Rng.Unseeded_generator;
2931 let rec go off k v = function
3032 | 0 -> v
3133 | 1 ->
3232- let v = H.hmac_string ~key:k v |> H.to_raw_string in
3333- let len =
3434- let rem = len mod H.digest_size in
3535- if rem = 0 then H.digest_size else rem
3636- in
3737- Bytes.unsafe_blit_string v 0 buf off len;
3838- v
3434+ let v = H.hmac_string ~key:k v |> H.to_raw_string in
3535+ let len =
3636+ let rem = len mod H.digest_size in
3737+ if rem = 0 then H.digest_size else rem
3838+ in
3939+ Bytes.unsafe_blit_string v 0 buf off len;
4040+ v
3941 | i ->
4040- let v = H.hmac_string ~key:k v |> H.to_raw_string in
4141- Bytes.unsafe_blit_string v 0 buf off H.digest_size;
4242- go (off + H.digest_size) k v (pred i)
4242+ let v = H.hmac_string ~key:k v |> H.to_raw_string in
4343+ Bytes.unsafe_blit_string v 0 buf off H.digest_size;
4444+ go (off + H.digest_size) k v (pred i)
4345 in
4446 let v = go off g.k g.v Crypto.Uncommon.(len // H.digest_size) in
4547 g.k <- H.hmac_string ~key:g.k (v ^ bx00) |> H.to_raw_string;
···47494850 (* XXX *)
4951 let accumulate ~g:_ = invalid_arg "Implement Hmac_drbg.accumulate..."
5050-5152 let pools = 0
5253end
+42-35
rng/rng.ml
···11type source = int * string
2233exception Unseeded_generator
44-54exception No_default_generator
6576let setup_rng =
88- "\nPlease setup your default random number generator. On Unix, the best \
99- path is to call [Crypto_rng_unix.use_default ()].\
1010- \nBut you can use Fortuna (or any other RNG) and setup the seeding \
1111- (done by default in MirageOS): \
1212- \n\
1313- \nTo initialize the RNG with a default generator, and set up entropy \
1414- collection and periodic reseeding as a background task, do the \
1515- following:\
1616- \n If you are using MirageOS, use the random device in config.ml: \
1717- `let main = Mirage.main \"Unikernel.Main\" (random @-> job)`, \
1818- and `let () = register \"my_unikernel\" [main $ default_random]`. \
1919- \n If you are using miou, execute \
2020- `Crypto_rng_miou_unix.initialize (module Crypto_rng.Fortuna)` \
2121- at startup."
77+ "\n\
88+ Please setup your default random number generator. On Unix, the best path \
99+ is to call [Crypto_rng_unix.use_default ()].\n\
1010+ But you can use Fortuna (or any other RNG) and setup the seeding (done by \
1111+ default in MirageOS): \n\n\
1212+ To initialize the RNG with a default generator, and set up entropy \
1313+ collection and periodic reseeding as a background task, do the following:\n\
1414+ \ If you are using MirageOS, use the random device in config.ml: `let main \
1515+ = Mirage.main \"Unikernel.Main\" (random @-> job)`, and `let () = register \
1616+ \"my_unikernel\" [main $ default_random]`. \n\
1717+ \ If you are using miou, execute `Crypto_rng_miou_unix.initialize (module \
1818+ Crypto_rng.Fortuna)` at startup."
22192323-let () = Printexc.register_printer (function
2424- | Unseeded_generator ->
2525- Some ("The RNG has not been seeded." ^ setup_rng)
2020+let () =
2121+ Printexc.register_printer (function
2222+ | Unseeded_generator -> Some ("The RNG has not been seeded." ^ setup_rng)
2623 | No_default_generator ->
2727- Some ("The default generator is not yet initialized. " ^ setup_rng)
2424+ Some ("The default generator is not yet initialized. " ^ setup_rng)
2825 | _ -> None)
29263027module type Generator = sig
3128 type g
2929+3230 val block : int
3331 val create : ?time:(unit -> int64) -> unit -> g
3232+3433 val generate_into : g:g -> bytes -> off:int -> int -> unit
3535- [@@alert unsafe "Does not do bounds checks. Use Crypto_rng.generate_into instead."]
3434+ [@@alert
3535+ unsafe "Does not do bounds checks. Use Crypto_rng.generate_into instead."]
3636+3637 val reseed : g:g -> string -> unit
3737- val accumulate : g:g -> source -> [`Acc of string -> unit]
3838+ val accumulate : g:g -> source -> [ `Acc of string -> unit ]
3839 val seeded : g:g -> bool
3940 val pools : int
4041end
···4243type 'a generator = (module Generator with type g = 'a)
4344type g = Generator : ('a * bool * 'a generator) -> g
44454545-let create (type a) ?g ?seed ?(strict=false) ?time (m : a generator) =
4646+let create (type a) ?g ?seed ?(strict = false) ?time (m : a generator) =
4647 let module M = (val m) in
4748 let g = Option.value g ~default:(M.create ?time ()) in
4849 Option.iter (M.reseed ~g) seed;
4950 Generator (g, strict, m)
50515152let _default_generator = Atomic.make None
5252-5353let set_default_generator g = Atomic.set _default_generator (Some g)
5454-5554let unset_default_generator () = Atomic.set _default_generator None
56555756let default_generator () =
···6261let get = function Some g -> g | None -> default_generator ()
63626463let generate_into ?(g = default_generator ()) b ?(off = 0) n =
6565- let Generator (g, _, m) = g in
6464+ let (Generator (g, _, m)) = g in
6665 let module M = (val m) in
6766 if off < 0 || n < 0 then
6868- invalid_arg ("negative offset " ^ string_of_int off ^ " or length " ^
6969- string_of_int n);
7070- if Bytes.length b - off < n then
7171- invalid_arg "buffer too short";
6767+ invalid_arg
6868+ ("negative offset " ^ string_of_int off ^ " or length " ^ string_of_int n);
6969+ if Bytes.length b - off < n then invalid_arg "buffer too short";
7270 begin[@alert "-unsafe"]
7371 M.generate_into ~g b ~off n
7472 end
···7977 Bytes.unsafe_to_string data
80788179let reseed ?(g = default_generator ()) cs =
8282- let Generator (g, _, m) = g in let module M = (val m) in M.reseed ~g cs
8080+ let (Generator (g, _, m)) = g in
8181+ let module M = (val m) in
8282+ M.reseed ~g cs
83838484let accumulate g source =
8585- let Generator (g, _, m) = get g in
8585+ let (Generator (g, _, m)) = get g in
8686 let module M = (val m) in
8787 M.accumulate ~g source
88888989let seeded g =
9090- let Generator (g, _, m) = get g in let module M = (val m) in M.seeded ~g
9090+ let (Generator (g, _, m)) = get g in
9191+ let module M = (val m) in
9292+ M.seeded ~g
91939294let block g =
9393- let Generator (_, _, m) = get g in let module M = (val m) in M.block
9595+ let (Generator (_, _, m)) = get g in
9696+ let module M = (val m) in
9797+ M.block
94989599let pools g =
9696- let Generator (_, _, m) = get g in let module M = (val m) in M.pools
100100+ let (Generator (_, _, m)) = get g in
101101+ let module M = (val m) in
102102+ M.pools
9710398104let strict g =
9999- let Generator (_, s, _) = get g in s
105105+ let (Generator (_, s, _)) = get g in
106106+ s
+15-15
rng/unix/crypto_rng_unix.ml
···11open Crypto_rng
22-32module Urandom = Urandom
44-53module Getentropy = Getentropy
6475let use_dev_urandom () =
···1311 set_default_generator g
14121513let use_default () = use_getentropy ()
1616-1714let src = Logs.Src.create "crypto-rng.unix" ~doc:"Mirage crypto RNG Unix"
1515+1816module Log = (val Logs.src_log src : Logs.LOG)
19172020-external getrandom_buf : bytes -> int -> int -> unit = "mc_getrandom" [@@noalloc]
1818+external getrandom_buf : bytes -> int -> int -> unit = "mc_getrandom"
1919+[@@noalloc]
21202222-let getrandom_into buf ~off ~len =
2323- getrandom_buf buf off len
2121+let getrandom_into buf ~off ~len = getrandom_buf buf off len
24222523let getrandom size =
2624 let buf = Bytes.create size in
···35333634let initialize (type a) ?g (rng : a generator) =
3735 if Atomic.get running then
3838- Log.debug
3939- (fun m -> m "Crypto_rng_unix.initialize has already been called, \
4040- ignoring this call.")
3636+ Log.debug (fun m ->
3737+ m
3838+ "Crypto_rng_unix.initialize has already been called, ignoring this \
3939+ call.")
4140 else begin
4241 (try
4342 let _ = default_generator () in
4444- Log.warn (fun m -> m "Crypto_rng.default_generator has already \
4545- been set, check that this call is intentional");
4646- with
4747- No_default_generator -> ());
4848- Atomic.set running true ;
4343+ Log.warn (fun m ->
4444+ m
4545+ "Crypto_rng.default_generator has already been set, check that \
4646+ this call is intentional")
4747+ with No_default_generator -> ());
4848+ Atomic.set running true;
4949 let seed =
5050 let init =
5151- Entropy.[ bootstrap ; whirlwind_bootstrap ; bootstrap ; getrandom_init ]
5151+ Entropy.[ bootstrap; whirlwind_bootstrap; bootstrap; getrandom_init ]
5252 in
5353 List.mapi (fun i f -> f i) init |> String.concat ""
5454 in
+17-18
rng/unix/crypto_rng_unix.mli
···11(** {b RNG} seeding on {b Unix}.
2233- This module initializes a Fortuna RNG with [getrandom()], and CPU RNG.
44- On BSD systems (FreeBSD, OpenBSD, macOS) [getentropy ()] is used instead
55- of [getrandom ()]. On Windows 10 or higher, [BCryptGenRandom()] is used
66- with the default RNG. Windows 8 or lower are not supported by this library.
77-*)
33+ This module initializes a Fortuna RNG with [getrandom()], and CPU RNG. On
44+ BSD systems (FreeBSD, OpenBSD, macOS) [getentropy ()] is used instead of
55+ [getrandom ()]. On Windows 10 or higher, [BCryptGenRandom()] is used with
66+ the default RNG. Windows 8 or lower are not supported by this library. *)
8799-(** [initialize ~g rng] will bring the RNG into a working state. *)
108val initialize : ?g:'a -> 'a Crypto_rng.generator -> unit
119[@@deprecated "Use 'Crypto_rng_unix.use_default ()' instead."]
1010+(** [initialize ~g rng] will bring the RNG into a working state. *)
12111212+val getrandom : int -> string
1313(** [getrandom size] returns a buffer of [size] filled with random bytes. *)
1414-val getrandom : int -> string
15141616-(** A generator that opens /dev/urandom and reads from that file descriptor
1717- data whenever random data is needed. The file descriptor is closed in
1818- [at_exit]. *)
1915module Urandom : Crypto_rng.Generator
1616+(** A generator that opens /dev/urandom and reads from that file descriptor data
1717+ whenever random data is needed. The file descriptor is closed in [at_exit].
1818+*)
20192020+module Getentropy : Crypto_rng.Generator
2121(** A generator using [getrandom(3)] on Linux, [getentropy(3)] on BSD and macOS,
2222 and [BCryptGenRandom()] on Windows. *)
2323-module Getentropy : Crypto_rng.Generator
24232525-(** [use_default ()] initializes the RNG [Crypto_rng.default_generator]
2626- with a sensible default, at the moment using [Getentropy]. *)
2724val use_default : unit -> unit
2525+(** [use_default ()] initializes the RNG [Crypto_rng.default_generator] with a
2626+ sensible default, at the moment using [Getentropy]. *)
28272929-(** [use_dev_random ()] initializes the RNG
3030- [Crypto_rng.default_generator] with the [Urandom] generator. This
3131- raises an exception if "/dev/urandom" cannot be opened. *)
3228val use_dev_urandom : unit -> unit
2929+(** [use_dev_random ()] initializes the RNG [Crypto_rng.default_generator] with
3030+ the [Urandom] generator. This raises an exception if "/dev/urandom" cannot
3131+ be opened. *)
33323434-(** [use_getentropy ()] initializes the RNG [Crypto_rng.default_generator]
3535- with the [Getentropy] generator. *)
3633val use_getentropy : unit -> unit
3434+(** [use_getentropy ()] initializes the RNG [Crypto_rng.default_generator] with
3535+ the [Getentropy] generator. *)
+4-7
rng/unix/discover.ml
···11let () =
22 let open Configurator.V1 in
33 main ~name:"rng_flags" (fun _t ->
44- let c_lib_flags =
55- match Sys.os_type with
66- | "Win32" | "Cygwin" -> ["-lbcrypt"]
77- | _ -> []
88- in
99- Flags.write_sexp "rng_c_flags.sexp" c_lib_flags
1010- )
44+ let c_lib_flags =
55+ match Sys.os_type with "Win32" | "Cygwin" -> [ "-lbcrypt" ] | _ -> []
66+ in
77+ Flags.write_sexp "rng_c_flags.sexp" c_lib_flags)
+4-12
rng/unix/getentropy.ml
···11-22-external getrandom_buf : bytes -> int -> int -> unit = "mc_getrandom" [@@noalloc]
11+external getrandom_buf : bytes -> int -> int -> unit = "mc_getrandom"
22+[@@noalloc]
3344type g = unit
55···99 The actual implementation may be one of `getrandom`, `getentropy`, or `BCryptGenRandom`, and will internally limit the maximum bytes read in one go and loop as needed if more bytes are requested and we get a short read.
1010 *)
1111let block = 256
1212-1312let create ?time:_ () = ()
1414-1515-let generate_into ~g:_ buf ~off len =
1616- getrandom_buf buf off len
1717-1313+let generate_into ~g:_ buf ~off len = getrandom_buf buf off len
1814let reseed ~g:_ _data = ()
1919-2020-let accumulate ~g:_ _source =
2121- `Acc (fun _data -> ())
2222-1515+let accumulate ~g:_ _source = `Acc (fun _data -> ())
2316let seeded ~g:_ = true
2424-2517let pools = 0
+2-9
rng/unix/urandom.ml
···11-21type g = In_channel.t * Mutex.t
3243(* The OCaml runtime always reads at least IO_BUFFER_SIZE from an input channel, which is currently 64 KiB *)
54let block = 65536
6576let create ?time:_ () =
88- let ic = In_channel.open_bin "/dev/urandom"
99- and mutex = Mutex.create ()
1010- in
77+ let ic = In_channel.open_bin "/dev/urandom" and mutex = Mutex.create () in
118 at_exit (fun () -> In_channel.close ic);
129 (ic, mutex)
1310···2017 | Some () -> ())
21182219let reseed ~g:_ _data = ()
2323-2424-let accumulate ~g:_ _source =
2525- `Acc (fun _data -> ())
2626-2020+let accumulate ~g:_ _source = `Acc (fun _data -> ())
2721let seeded ~g:_ = true
2828-2922let pools = 0
···11open Uncommon
2233let block_size = 16
44-55-let flags bit6 len1 len2 =
66- bit6 lsl 6 + len1 lsl 3 + len2
44+let flags bit6 len1 len2 = (bit6 lsl 6) + (len1 lsl 3) + len2
7586let encode_len buf ~off size value =
97 let rec ass num = function
108 | 0 -> Bytes.set_uint8 buf off num
119 | m ->
1212- Bytes.set_uint8 buf (off + m) (num land 0xff);
1313- (ass [@tailcall]) (num lsr 8) (pred m)
1010+ Bytes.set_uint8 buf (off + m) (num land 0xff);
1111+ (ass [@tailcall]) (num lsr 8) (pred m)
1412 in
1513 ass value (pred size)
1614···2826let gen_adata a =
2927 let llen, set_llen =
3028 match String.length a with
3131- | x when x < (1 lsl 16 - 1 lsl 8) ->
3232- 2, (fun buf off -> Bytes.set_uint16_be buf off x)
3333- | x when Sys.int_size < 32 || x < (1 lsl 32) ->
3434- 6, (fun buf off ->
3535- Bytes.set_uint16_be buf off 0xfffe;
3636- Bytes.set_int32_be buf (off + 2) (Int32.of_int x))
2929+ | x when x < (1 lsl 16) - (1 lsl 8) ->
3030+ (2, fun buf off -> Bytes.set_uint16_be buf off x)
3131+ | x when Sys.int_size < 32 || x < 1 lsl 32 ->
3232+ ( 6,
3333+ fun buf off ->
3434+ Bytes.set_uint16_be buf off 0xfffe;
3535+ Bytes.set_int32_be buf (off + 2) (Int32.of_int x) )
3736 | x ->
3838- 10, (fun buf off ->
3939- Bytes.set_uint16_be buf off 0xffff;
4040- Bytes.set_int64_be buf (off + 2) (Int64.of_int x))
3737+ ( 10,
3838+ fun buf off ->
3939+ Bytes.set_uint16_be buf off 0xffff;
4040+ Bytes.set_int64_be buf (off + 2) (Int64.of_int x) )
4141 in
4242 let to_pad =
4343 let leftover = (llen + String.length a) mod block_size in
4444 block_size - leftover
4545 in
4646- llen + String.length a + to_pad,
4747- fun buf off ->
4848- set_llen buf off;
4949- Bytes.unsafe_blit_string a 0 buf (off + llen) (String.length a);
5050- Bytes.unsafe_fill buf (off + llen + String.length a) to_pad '\000'
4646+ ( llen + String.length a + to_pad,
4747+ fun buf off ->
4848+ set_llen buf off;
4949+ Bytes.unsafe_blit_string a 0 buf (off + llen) (String.length a);
5050+ Bytes.unsafe_fill buf (off + llen + String.length a) to_pad '\000' )
51515252let gen_ctr nonce i =
5353 let n = String.length nonce in
···6161 let small_q = 15 - String.length nonce in
6262 let b6 = if String.length adata = 0 then 0 else 1 in
6363 let flag_val = flags b6 ((tlen - 2) / 2) (small_q - 1) in
6464- if String.length adata = 0 then
6464+ if String.length adata = 0 then (
6565 let hdr = Bytes.create 16 in
6666 set_format hdr nonce flag_val plen;
6767- hdr
6767+ hdr)
6868 else
6969 let len, set = gen_adata adata in
7070 let buf = Bytes.create (16 + len) in
···74747575type mode = Encrypt | Decrypt
76767777-let crypto_core_into ~cipher ~mode ~key ~nonce ~adata src ~src_off dst ~dst_off len =
7777+let crypto_core_into ~cipher ~mode ~key ~nonce ~adata src ~src_off dst ~dst_off
7878+ len =
7879 let cbcheader = prepare_header nonce adata len block_size in
79808081 let small_q = 15 - String.length nonce in
···8788 in
88898990 let cbc iv src_off block dst_off =
9090- unsafe_xor_into iv ~src_off block ~dst_off block_size ;
9191+ unsafe_xor_into iv ~src_off block ~dst_off block_size;
9192 cipher ~key (Bytes.unsafe_to_string block) ~src_off:dst_off block ~dst_off
9293 in
9394···9697 match Bytes.length block - block_off with
9798 | 0 -> Bytes.sub iv iv_off block_size
9899 | _ ->
9999- cbc (Bytes.unsafe_to_string iv) iv_off block block_off;
100100- (doit [@tailcall]) block block_off block (block_off + block_size)
100100+ cbc (Bytes.unsafe_to_string iv) iv_off block block_off;
101101+ (doit [@tailcall]) block block_off block (block_off + block_size)
101102 in
102103 doit (Bytes.make block_size '\x00') 0 cbcheader 0
103104 in
···105106 let rec loop ctr src src_off dst dst_off len =
106107 let cbcblock, cbc_off =
107108 match mode with
108108- | Encrypt -> src, src_off
109109- | Decrypt -> Bytes.unsafe_to_string dst, dst_off
109109+ | Encrypt -> (src, src_off)
110110+ | Decrypt -> (Bytes.unsafe_to_string dst, dst_off)
110111 in
111111- if len = 0 then
112112- ()
112112+ if len = 0 then ()
113113 else if len < block_size then begin
114114 let buf = Bytes.make block_size '\x00' in
115115- Bytes.unsafe_blit dst dst_off buf 0 len ;
116116- ctrblock ctr buf 0 ;
117117- Bytes.unsafe_blit buf 0 dst dst_off len ;
118118- unsafe_xor_into src ~src_off dst ~dst_off len ;
119119- Bytes.unsafe_blit_string cbcblock cbc_off buf 0 len ;
115115+ Bytes.unsafe_blit dst dst_off buf 0 len;
116116+ ctrblock ctr buf 0;
117117+ Bytes.unsafe_blit buf 0 dst dst_off len;
118118+ unsafe_xor_into src ~src_off dst ~dst_off len;
119119+ Bytes.unsafe_blit_string cbcblock cbc_off buf 0 len;
120120 Bytes.unsafe_fill buf len (block_size - len) '\x00';
121121 cbc (Bytes.unsafe_to_string buf) 0 iv 0
122122- end else begin
123123- ctrblock ctr dst dst_off ;
124124- unsafe_xor_into src ~src_off dst ~dst_off block_size ;
125125- cbc cbcblock cbc_off iv 0 ;
126126- (loop [@tailcall]) (succ ctr) src (src_off + block_size) dst (dst_off + block_size) (len - block_size)
122122+ end
123123+ else begin
124124+ ctrblock ctr dst dst_off;
125125+ unsafe_xor_into src ~src_off dst ~dst_off block_size;
126126+ cbc cbcblock cbc_off iv 0;
127127+ (loop [@tailcall]) (succ ctr) src (src_off + block_size) dst
128128+ (dst_off + block_size) (len - block_size)
127129 end
128130 in
129131 loop 1 src src_off dst dst_off len;
···132134let crypto_core ~cipher ~mode ~key ~nonce ~adata data =
133135 let datalen = String.length data in
134136 let dst = Bytes.create datalen in
135135- let t = crypto_core_into ~cipher ~mode ~key ~nonce ~adata data ~src_off:0 dst ~dst_off:0 datalen in
136136- dst, t
137137+ let t =
138138+ crypto_core_into ~cipher ~mode ~key ~nonce ~adata data ~src_off:0 dst
139139+ ~dst_off:0 datalen
140140+ in
141141+ (dst, t)
137142138143let crypto_t t nonce cipher key =
139144 let ctr = gen_ctr nonce 0 in
140140- cipher ~key (Bytes.unsafe_to_string ctr) ~src_off:0 ctr ~dst_off:0 ;
141141- unsafe_xor_into (Bytes.unsafe_to_string ctr) ~src_off:0 t ~dst_off:0 (Bytes.length t)
145145+ cipher ~key (Bytes.unsafe_to_string ctr) ~src_off:0 ctr ~dst_off:0;
146146+ unsafe_xor_into
147147+ (Bytes.unsafe_to_string ctr)
148148+ ~src_off:0 t ~dst_off:0 (Bytes.length t)
142149143143-let unsafe_generation_encryption_into ~cipher ~key ~nonce ~adata src ~src_off dst ~dst_off ~tag_off len =
144144- let t = crypto_core_into ~cipher ~mode:Encrypt ~key ~nonce ~adata src ~src_off dst ~dst_off len in
145145- crypto_t t nonce cipher key ;
150150+let unsafe_generation_encryption_into ~cipher ~key ~nonce ~adata src ~src_off
151151+ dst ~dst_off ~tag_off len =
152152+ let t =
153153+ crypto_core_into ~cipher ~mode:Encrypt ~key ~nonce ~adata src ~src_off dst
154154+ ~dst_off len
155155+ in
156156+ crypto_t t nonce cipher key;
146157 Bytes.unsafe_blit t 0 dst tag_off block_size
147158148148-let unsafe_decryption_verification_into ~cipher ~key ~nonce ~adata src ~src_off ~tag_off dst ~dst_off len =
159159+let unsafe_decryption_verification_into ~cipher ~key ~nonce ~adata src ~src_off
160160+ ~tag_off dst ~dst_off len =
149161 let tag = String.sub src tag_off block_size in
150150- let t = crypto_core_into ~cipher ~mode:Decrypt ~key ~nonce ~adata src ~src_off dst ~dst_off len in
151151- crypto_t t nonce cipher key ;
162162+ let t =
163163+ crypto_core_into ~cipher ~mode:Decrypt ~key ~nonce ~adata src ~src_off dst
164164+ ~dst_off len
165165+ in
166166+ crypto_t t nonce cipher key;
152167 Eqaf.equal tag (Bytes.unsafe_to_string t)
+67-52
src/chacha20.ml
···1414let init ctr ~key ~nonce =
1515 let ctr_off = 48 in
1616 let set_ctr32 b v = Bytes.set_int32_le b ctr_off v
1717- and set_ctr64 b v = Bytes.set_int64_le b ctr_off v
1818- in
1717+ and set_ctr64 b v = Bytes.set_int64_le b ctr_off v in
1918 let inc32 b = set_ctr32 b (Int32.add (Bytes.get_int32_le b ctr_off) 1l)
2020- and inc64 b = set_ctr64 b (Int64.add (Bytes.get_int64_le b ctr_off) 1L)
2121- in
1919+ and inc64 b = set_ctr64 b (Int64.add (Bytes.get_int64_le b ctr_off) 1L) in
2220 let s, key, init_ctr, nonce_off, inc =
2323- match String.length key, String.length nonce, Int64.shift_right ctr 32 = 0L with
2121+ match
2222+ (String.length key, String.length nonce, Int64.shift_right ctr 32 = 0L)
2323+ with
2424 | 32, 12, true ->
2525- let ctr = Int64.to_int32 ctr in
2626- "expand 32-byte k", key, (fun b -> set_ctr32 b ctr), 52, inc32
2525+ let ctr = Int64.to_int32 ctr in
2626+ ("expand 32-byte k", key, (fun b -> set_ctr32 b ctr), 52, inc32)
2727 | 32, 12, false ->
2828- invalid_arg "Counter too big for IETF mode (32 bit counter)"
2828+ invalid_arg "Counter too big for IETF mode (32 bit counter)"
2929 | 32, 8, _ ->
3030- "expand 32-byte k", key, (fun b -> set_ctr64 b ctr), 56, inc64
3030+ ("expand 32-byte k", key, (fun b -> set_ctr64 b ctr), 56, inc64)
3131 | 16, 8, _ ->
3232- let k = key ^ key in
3333- "expand 16-byte k", k, (fun b -> set_ctr64 b ctr), 56, inc64
3434- | _ -> invalid_arg "Valid parameters are nonce 12 bytes and key 32 bytes \
3535- (counter 32 bit), or nonce 8 byte and key 16 or 32 \
3636- bytes (counter 64 bit)."
3232+ let k = key ^ key in
3333+ ("expand 16-byte k", k, (fun b -> set_ctr64 b ctr), 56, inc64)
3434+ | _ ->
3535+ invalid_arg
3636+ "Valid parameters are nonce 12 bytes and key 32 bytes (counter 32 \
3737+ bit), or nonce 8 byte and key 16 or 32 bytes (counter 64 bit)."
3738 in
3839 let state = Bytes.create block in
3939- Bytes.unsafe_blit_string s 0 state 0 16 ;
4040- Bytes.unsafe_blit_string key 0 state 16 32 ;
4141- init_ctr state ;
4242- Bytes.unsafe_blit_string nonce 0 state nonce_off (String.length nonce) ;
4343- state, inc
4040+ Bytes.unsafe_blit_string s 0 state 0 16;
4141+ Bytes.unsafe_blit_string key 0 state 16 32;
4242+ init_ctr state;
4343+ Bytes.unsafe_blit_string nonce 0 state nonce_off (String.length nonce);
4444+ (state, inc)
44454546let crypt_into ~key ~nonce ~ctr src ~src_off dst ~dst_off len =
4647 let state, inc = init ctr ~key ~nonce in
···5253 let rec loop i = function
5354 | 0 -> ()
5455 | 1 ->
5555- if last_len = block then begin
5656- chacha20_block state (dst_off + i) dst ;
5757- Native.xor_into_bytes src (src_off + i) dst (dst_off + i) block
5858- end else begin
5959- let buf = Bytes.create block in
6060- chacha20_block state 0 buf ;
6161- Native.xor_into_bytes src (src_off + i) buf 0 last_len ;
6262- Bytes.unsafe_blit buf 0 dst (dst_off + i) last_len
6363- end
5656+ if last_len = block then begin
5757+ chacha20_block state (dst_off + i) dst;
5858+ Native.xor_into_bytes src (src_off + i) dst (dst_off + i) block
5959+ end
6060+ else begin
6161+ let buf = Bytes.create block in
6262+ chacha20_block state 0 buf;
6363+ Native.xor_into_bytes src (src_off + i) buf 0 last_len;
6464+ Bytes.unsafe_blit buf 0 dst (dst_off + i) last_len
6565+ end
6466 | n ->
6565- chacha20_block state (dst_off + i) dst ;
6666- Native.xor_into_bytes src (src_off + i) dst (dst_off + i) block ;
6767- inc state;
6868- (loop [@tailcall]) (i + block) (n - 1)
6767+ chacha20_block state (dst_off + i) dst;
6868+ Native.xor_into_bytes src (src_off + i) dst (dst_off + i) block;
6969+ inc state;
7070+ (loop [@tailcall]) (i + block) (n - 1)
6971 in
7072 loop 0 block_count
7173···9395 Bytes.unsafe_to_string data
9496 in
9597 let p1 = pad16 (String.length adata) and p2 = pad16 len in
9696- P.unsafe_mac_into ~key [ adata, 0, String.length adata ;
9797- p1, 0, String.length p1 ;
9898- src, src_off, len ;
9999- p2, 0, String.length p2 ;
100100- len_buf, 0, String.length len_buf ]
9898+ P.unsafe_mac_into ~key
9999+ [
100100+ (adata, 0, String.length adata);
101101+ (p1, 0, String.length p1);
102102+ (src, src_off, len);
103103+ (p2, 0, String.length p2);
104104+ (len_buf, 0, String.length len_buf);
105105+ ]
101106 dst ~dst_off
102107103103-let unsafe_authenticate_encrypt_into ~key ~nonce ?(adata = "") src ~src_off dst ~dst_off ~tag_off len =
108108+let unsafe_authenticate_encrypt_into ~key ~nonce ?(adata = "") src ~src_off dst
109109+ ~dst_off ~tag_off len =
104110 let poly1305_key = generate_poly1305_key ~key ~nonce in
105111 crypt_into ~key ~nonce ~ctr:1L src ~src_off dst ~dst_off len;
106106- mac_into ~key:poly1305_key ~adata (Bytes.unsafe_to_string dst) ~src_off:dst_off len dst ~dst_off:tag_off
112112+ mac_into ~key:poly1305_key ~adata
113113+ (Bytes.unsafe_to_string dst)
114114+ ~src_off:dst_off len dst ~dst_off:tag_off
107115108108-let authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off ~tag_off len =
116116+let authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off
117117+ ~tag_off len =
109118 if String.length src - src_off < len then
110119 invalid_arg "Chacha20: src length %u - src_off %u < len %u"
111120 (String.length src) src_off len;
···115124 if Bytes.length dst - tag_off < tag_size then
116125 invalid_arg "Chacha20: dst length %u - tag_off %u < tag_size %u"
117126 (Bytes.length dst) tag_off tag_size;
118118- unsafe_authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off ~tag_off len
127127+ unsafe_authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off
128128+ ~tag_off len
119129120130let authenticate_encrypt ~key ~nonce ?adata data =
121131 let l = String.length data in
122132 let dst = Bytes.create (l + tag_size) in
123123- unsafe_authenticate_encrypt_into ~key ~nonce ?adata data ~src_off:0 dst ~dst_off:0 ~tag_off:l l;
133133+ unsafe_authenticate_encrypt_into ~key ~nonce ?adata data ~src_off:0 dst
134134+ ~dst_off:0 ~tag_off:l l;
124135 Bytes.unsafe_to_string dst
125136126137let authenticate_encrypt_tag ~key ~nonce ?adata data =
127138 let r = authenticate_encrypt ~key ~nonce ?adata data in
128128- String.sub r 0 (String.length data), String.sub r (String.length data) tag_size
139139+ ( String.sub r 0 (String.length data),
140140+ String.sub r (String.length data) tag_size )
129141130130-let unsafe_authenticate_decrypt_into ~key ~nonce ?(adata = "") src ~src_off ~tag_off dst ~dst_off len =
142142+let unsafe_authenticate_decrypt_into ~key ~nonce ?(adata = "") src ~src_off
143143+ ~tag_off dst ~dst_off len =
131144 let poly1305_key = generate_poly1305_key ~key ~nonce in
132145 let ctag = Bytes.create tag_size in
133146 mac_into ~key:poly1305_key ~adata src ~src_off len ctag ~dst_off:0;
134147 crypt_into ~key ~nonce ~ctr:1L src ~src_off dst ~dst_off len;
135148 Eqaf.equal (String.sub src tag_off tag_size) (Bytes.unsafe_to_string ctag)
136149137137-let authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst ~dst_off len =
150150+let authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst
151151+ ~dst_off len =
138152 if String.length src - src_off < len then
139153 invalid_arg "Chacha20: src length %u - src_off %u < len %u"
140154 (String.length src) src_off len;
···144158 if String.length src - tag_off < tag_size then
145159 invalid_arg "Chacha20: src length %u - tag_off %u < tag_size %u"
146160 (String.length src) tag_off tag_size;
147147- unsafe_authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst ~dst_off len
161161+ unsafe_authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst
162162+ ~dst_off len
148163149164let authenticate_decrypt ~key ~nonce ?adata data =
150150- if String.length data < tag_size then
151151- None
165165+ if String.length data < tag_size then None
152166 else
153167 let l = String.length data - tag_size in
154168 let r = Bytes.create l in
155155- if unsafe_authenticate_decrypt_into ~key ~nonce ?adata data ~src_off:0 ~tag_off:l r ~dst_off:0 l then
156156- Some (Bytes.unsafe_to_string r)
157157- else
158158- None
169169+ if
170170+ unsafe_authenticate_decrypt_into ~key ~nonce ?adata data ~src_off:0
171171+ ~tag_off:l r ~dst_off:0 l
172172+ then Some (Bytes.unsafe_to_string r)
173173+ else None
159174160175let authenticate_decrypt_tag ~key ~nonce ?adata ~tag data =
161176 let cdata = data ^ tag in
+265-162
src/cipher_block.ml
···11open Uncommon
2233module Block = struct
44-54 module type Core = sig
66-75 type ekey
86 type dkey
971010- val of_secret : string -> ekey * dkey
88+ val of_secret : string -> ekey * dkey
119 val e_of_secret : string -> ekey
1210 val d_of_secret : string -> dkey
1313-1414- val key : int array
1111+ val key : int array
1512 val block : int
16131714 (* XXX currently unsafe point *)
1818- val encrypt : key:ekey -> blocks:int -> string -> int -> bytes -> int -> unit
1919- val decrypt : key:dkey -> blocks:int -> string -> int -> bytes -> int -> unit
1515+ val encrypt :
1616+ key:ekey -> blocks:int -> string -> int -> bytes -> int -> unit
1717+1818+ val decrypt :
1919+ key:dkey -> blocks:int -> string -> int -> bytes -> int -> unit
2020 end
21212222 module type ECB = sig
2323-2423 type key
2525- val of_secret : string -> key
26242727- val key_sizes : int array
2525+ val of_secret : string -> key
2626+ val key_sizes : int array
2827 val block_size : int
2928 val encrypt : key:key -> string -> string
3029 val decrypt : key:key -> string -> string
3131- val encrypt_into : key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3232- val decrypt_into : key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3333- val unsafe_encrypt_into : key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3434- val unsafe_decrypt_into : key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3030+3131+ val encrypt_into :
3232+ key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3333+3434+ val decrypt_into :
3535+ key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3636+3737+ val unsafe_encrypt_into :
3838+ key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3939+4040+ val unsafe_decrypt_into :
4141+ key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3542 end
36433744 module type CBC = sig
3838-3945 type key
4646+4047 val of_secret : string -> key
4141-4242- val key_sizes : int array
4848+ val key_sizes : int array
4349 val block_size : int
4444-4550 val encrypt : key:key -> iv:string -> string -> string
4651 val decrypt : key:key -> iv:string -> string -> string
4752 val next_iv : ?off:int -> string -> iv:string -> string
48534949- val encrypt_into : key:key -> iv:string -> string -> src_off:int ->
5050- bytes -> dst_off:int -> int -> unit
5151- val decrypt_into : key:key -> iv:string -> string -> src_off:int ->
5252- bytes -> dst_off:int -> int -> unit
5454+ val encrypt_into :
5555+ key:key ->
5656+ iv:string ->
5757+ string ->
5858+ src_off:int ->
5959+ bytes ->
6060+ dst_off:int ->
6161+ int ->
6262+ unit
6363+6464+ val decrypt_into :
6565+ key:key ->
6666+ iv:string ->
6767+ string ->
6868+ src_off:int ->
6969+ bytes ->
7070+ dst_off:int ->
7171+ int ->
7272+ unit
7373+7474+ val unsafe_encrypt_into :
7575+ key:key ->
7676+ iv:string ->
7777+ string ->
7878+ src_off:int ->
7979+ bytes ->
8080+ dst_off:int ->
8181+ int ->
8282+ unit
8383+8484+ val unsafe_decrypt_into :
8585+ key:key ->
8686+ iv:string ->
8787+ string ->
8888+ src_off:int ->
8989+ bytes ->
9090+ dst_off:int ->
9191+ int ->
9292+ unit
53935454- val unsafe_encrypt_into : key:key -> iv:string -> string -> src_off:int ->
5555- bytes -> dst_off:int -> int -> unit
5656- val unsafe_decrypt_into : key:key -> iv:string -> string -> src_off:int ->
5757- bytes -> dst_off:int -> int -> unit
5858- val unsafe_encrypt_into_inplace : key:key -> iv:string ->
5959- bytes -> dst_off:int -> int -> unit
9494+ val unsafe_encrypt_into_inplace :
9595+ key:key -> iv:string -> bytes -> dst_off:int -> int -> unit
6096 end
61976298 module type CTR = sig
6363-6499 type key
6565- val of_secret : string -> key
661006767- val key_sizes : int array
101101+ val of_secret : string -> key
102102+ val key_sizes : int array
68103 val block_size : int
6910470105 type ctr
7171- val add_ctr : ctr -> int64 -> ctr
7272- val next_ctr : ?off:int -> string -> ctr:ctr -> ctr
7373- val ctr_of_octets : string -> ctr
741067575- val stream : key:key -> ctr:ctr -> int -> string
107107+ val add_ctr : ctr -> int64 -> ctr
108108+ val next_ctr : ?off:int -> string -> ctr:ctr -> ctr
109109+ val ctr_of_octets : string -> ctr
110110+ val stream : key:key -> ctr:ctr -> int -> string
76111 val encrypt : key:key -> ctr:ctr -> string -> string
77112 val decrypt : key:key -> ctr:ctr -> string -> string
113113+ val stream_into : key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
781147979- val stream_into : key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
8080- val encrypt_into : key:key -> ctr:ctr -> string -> src_off:int ->
8181- bytes -> dst_off:int -> int -> unit
8282- val decrypt_into : key:key -> ctr:ctr -> string -> src_off:int ->
8383- bytes -> dst_off:int -> int -> unit
115115+ val encrypt_into :
116116+ key:key ->
117117+ ctr:ctr ->
118118+ string ->
119119+ src_off:int ->
120120+ bytes ->
121121+ dst_off:int ->
122122+ int ->
123123+ unit
841248585- val unsafe_stream_into : key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
8686- val unsafe_encrypt_into : key:key -> ctr:ctr -> string -> src_off:int ->
8787- bytes -> dst_off:int -> int -> unit
8888- val unsafe_decrypt_into : key:key -> ctr:ctr -> string -> src_off:int ->
8989- bytes -> dst_off:int -> int -> unit
125125+ val decrypt_into :
126126+ key:key ->
127127+ ctr:ctr ->
128128+ string ->
129129+ src_off:int ->
130130+ bytes ->
131131+ dst_off:int ->
132132+ int ->
133133+ unit
134134+135135+ val unsafe_stream_into :
136136+ key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
137137+138138+ val unsafe_encrypt_into :
139139+ key:key ->
140140+ ctr:ctr ->
141141+ string ->
142142+ src_off:int ->
143143+ bytes ->
144144+ dst_off:int ->
145145+ int ->
146146+ unit
147147+148148+ val unsafe_decrypt_into :
149149+ key:key ->
150150+ ctr:ctr ->
151151+ string ->
152152+ src_off:int ->
153153+ bytes ->
154154+ dst_off:int ->
155155+ int ->
156156+ unit
90157 end
9115892159 module type GCM = sig
93160 include Aead.AEAD
941619595- val key_sizes : int array
162162+ val key_sizes : int array
96163 val block_size : int
97164 end
9816599166 module type CCM16 = sig
100167 include Aead.AEAD
101168102102- val key_sizes : int array
169169+ val key_sizes : int array
103170 val block_size : int
104171 end
105172end
···107174module Counters = struct
108175 module type S = sig
109176 type ctr
177177+110178 val size : int
111111- val add : ctr -> int64 -> ctr
179179+ val add : ctr -> int64 -> ctr
112180 val of_octets : string -> ctr
113181 val unsafe_count_into : ctr -> bytes -> off:int -> blocks:int -> unit
114182 end
115183116184 module C64be = struct
117185 type ctr = int64
186186+118187 let size = 8
119188 let of_octets cs = String.get_int64_be cs 0
120189 let add = Int64.add
190190+121191 let unsafe_count_into t buf ~off ~blocks =
122192 let ctr = Bytes.create 8 in
123193 Bytes.set_int64_be ctr 0 t;
···126196127197 module C128be = struct
128198 type ctr = int64 * int64
199199+129200 let size = 16
201201+130202 let of_octets cs =
131203 let buf = Bytes.unsafe_of_string cs in
132204 Bytes.(get_int64_be buf 0, get_int64_be buf 8)
205205+133206 let add (w1, w0) n =
134134- let w0' = Int64.add w0 n in
207207+ let w0' = Int64.add w0 n in
135208 let flip = if Int64.logxor w0 w0' < 0L then w0' > w0 else w0' < w0 in
136209 ((if flip then Int64.succ w1 else w1), w0')
210210+137211 let unsafe_count_into (w1, w0) buf ~off ~blocks =
138212 let ctr = Bytes.create 16 in
139139- Bytes.set_int64_be ctr 0 w1; Bytes.set_int64_be ctr 8 w0;
213213+ Bytes.set_int64_be ctr 0 w1;
214214+ Bytes.set_int64_be ctr 8 w0;
140215 Native.count16be ~ctr buf ~off ~blocks
141216 end
142217143218 module C128be32 = struct
144219 include C128be
220220+145221 let add (w1, w0) n =
146222 let hi = 0xffffffff00000000L and lo = 0x00000000ffffffffL in
147223 (w1, Int64.(logor (logand hi w0) (add n w0 |> logand lo)))
224224+148225 let unsafe_count_into (w1, w0) buf ~off ~blocks =
149226 let ctr = Bytes.create 16 in
150150- Bytes.set_int64_be ctr 0 w1; Bytes.set_int64_be ctr 8 w0;
227227+ Bytes.set_int64_be ctr 0 w1;
228228+ Bytes.set_int64_be ctr 8 w0;
151229 Native.count16be4 ~ctr buf ~off ~blocks
152230 end
153231end
154232155233let check_offset ~tag ~buf ~off ~len actual_len =
156156- if off < 0 then
157157- invalid_arg "%s: %s off %u < 0"
158158- tag buf off;
234234+ if off < 0 then invalid_arg "%s: %s off %u < 0" tag buf off;
159235 if actual_len - off < len then
160160- invalid_arg "%s: %s length %u - off %u < len %u"
161161- tag buf actual_len off len
236236+ invalid_arg "%s: %s length %u - off %u < len %u" tag buf actual_len off len
162237[@@inline]
163238164239module Modes = struct
165240 module ECB_of (Core : Block.Core) : Block.ECB = struct
166166-167241 type key = Core.ekey * Core.dkey
168242169169- let (key_sizes, block_size) = Core.(key, block)
170170-243243+ let key_sizes, block_size = Core.(key, block)
171244 let of_secret = Core.of_secret
172245173246 let unsafe_ecb xform key src src_off dst dst_off len =
···206279 end
207280208281 module CBC_of (Core : Block.Core) : Block.CBC = struct
209209-210282 type key = Core.ekey * Core.dkey
211283212212- let (key_sizes, block_size) = Core.(key, block)
284284+ let key_sizes, block_size = Core.(key, block)
213285 let block = block_size
214214-215286 let of_secret = Core.of_secret
216287217288 let check_block_size ~iv len =
218289 if String.length iv <> block then
219290 invalid_arg "CBC: IV length %u not of block size" (String.length iv);
220291 if len mod block <> 0 then
221221- invalid_arg "CBC: argument length %u not of block size"
222222- len
292292+ invalid_arg "CBC: argument length %u not of block size" len
223293 [@@inline]
224294225295 let next_iv ?(off = 0) cs ~iv =
226226- check_block_size ~iv (String.length cs - off) ;
296296+ check_block_size ~iv (String.length cs - off);
227297 if String.length cs > off then
228298 String.sub cs (String.length cs - block_size) block_size
229299 else iv
···232302 let rec loop iv iv_i dst_i = function
233303 | 0 -> ()
234304 | b ->
235235- Native.xor_into_bytes iv iv_i dst dst_i block ;
236236- Core.encrypt ~key ~blocks:1 (Bytes.unsafe_to_string dst) dst_i dst dst_i ;
237237- (loop [@tailcall]) (Bytes.unsafe_to_string dst) dst_i (dst_i + block) (b - 1)
305305+ Native.xor_into_bytes iv iv_i dst dst_i block;
306306+ Core.encrypt ~key ~blocks:1
307307+ (Bytes.unsafe_to_string dst)
308308+ dst_i dst dst_i;
309309+ (loop [@tailcall])
310310+ (Bytes.unsafe_to_string dst)
311311+ dst_i (dst_i + block) (b - 1)
238312 in
239313 loop iv 0 dst_off (len / block)
240314···256330 let unsafe_decrypt_into ~key:(_, key) ~iv src ~src_off dst ~dst_off len =
257331 let b = len / block in
258332 if b > 0 then begin
259259- Core.decrypt ~key ~blocks:b src src_off dst dst_off ;
260260- Native.xor_into_bytes iv 0 dst dst_off block ;
261261- Native.xor_into_bytes src src_off dst (dst_off + block) ((b - 1) * block) ;
333333+ Core.decrypt ~key ~blocks:b src src_off dst dst_off;
334334+ Native.xor_into_bytes iv 0 dst dst_off block;
335335+ Native.xor_into_bytes src src_off dst (dst_off + block) ((b - 1) * block)
262336 end
263337264338 let decrypt_into ~key ~iv src ~src_off dst ~dst_off len =
···275349 end
276350277351 module CTR_of (Core : Block.Core) (Ctr : Counters.S) :
278278- Block.CTR with type key = Core.ekey and type ctr = Ctr.ctr =
279279- struct
352352+ Block.CTR with type key = Core.ekey and type ctr = Ctr.ctr = struct
280353 (* FIXME: CTR has more room for speedups. Like stitching. *)
281354282282- assert (Core.block = Ctr.size)
355355+ assert (Core.block = Ctr.size);;
356356+283357 type key = Core.ekey
284358 type ctr = Ctr.ctr
285359286286- let (key_sizes, block_size) = Core.(key, block)
360360+ let key_sizes, block_size = Core.(key, block)
287361 let of_secret = Core.e_of_secret
288362289363 let unsafe_stream_into ~key ~ctr buf ~off len =
290364 let blocks = imax 0 len / block_size in
291291- Ctr.unsafe_count_into ctr buf ~off ~blocks ;
292292- Core.encrypt ~key ~blocks (Bytes.unsafe_to_string buf) off buf off ;
365365+ Ctr.unsafe_count_into ctr buf ~off ~blocks;
366366+ Core.encrypt ~key ~blocks (Bytes.unsafe_to_string buf) off buf off;
293367 let slack = imax 0 len mod block_size in
294368 if slack <> 0 then begin
295369 let buf' = Bytes.create block_size in
296370 let ctr = Ctr.add ctr (Int64.of_int blocks) in
297297- Ctr.unsafe_count_into ctr buf' ~off:0 ~blocks:1 ;
298298- Core.encrypt ~key ~blocks:1 (Bytes.unsafe_to_string buf') 0 buf' 0 ;
299299- Bytes.unsafe_blit buf' 0 buf (off + blocks * block_size) slack
371371+ Ctr.unsafe_count_into ctr buf' ~off:0 ~blocks:1;
372372+ Core.encrypt ~key ~blocks:1 (Bytes.unsafe_to_string buf') 0 buf' 0;
373373+ Bytes.unsafe_blit buf' 0 buf (off + (blocks * block_size)) slack
300374 end
301375302376 let stream_into ~key ~ctr buf ~off len =
···324398 Bytes.unsafe_to_string dst
325399326400 let decrypt = encrypt
327327-328401 let decrypt_into = encrypt_into
329329-330402 let unsafe_decrypt_into = unsafe_encrypt_into
331331-332403 let add_ctr = Ctr.add
404404+333405 let next_ctr ?(off = 0) msg ~ctr =
334334- add_ctr ctr (Int64.of_int @@ (String.length msg - off) // block_size)
406406+ add_ctr ctr (Int64.of_int @@ ((String.length msg - off) // block_size))
407407+335408 let ctr_of_octets = Ctr.of_octets
336409 end
337410338411 module GHASH : sig
339412 type key
340340- val derive : string -> key
341341- val digesti : key:key -> (string Uncommon.iter) -> string
342342- val digesti_off_len : key:key -> (string * int * int) Uncommon.iter -> string
413413+414414+ val derive : string -> key
415415+ val digesti : key:key -> string Uncommon.iter -> string
416416+417417+ val digesti_off_len :
418418+ key:key -> (string * int * int) Uncommon.iter -> string
419419+343420 val tagsize : int
344421 end = struct
345422 type key = string
423423+346424 let keysize = Native.GHASH.keysize ()
347425 let tagsize = 16
426426+348427 let derive cs =
349428 assert (String.length cs >= tagsize);
350429 let k = Bytes.create keysize in
351430 Native.GHASH.keyinit cs k;
352431 Bytes.unsafe_to_string k
432432+353433 let digesti_off_len ~key i =
354434 let res = Bytes.make tagsize '\x00' in
355435 i (fun (cs, off, len) -> Native.GHASH.ghash key res cs off len);
356436 Bytes.unsafe_to_string res
437437+357438 let digesti ~key i =
358439 let res = Bytes.make tagsize '\x00' in
359440 i (fun cs -> Native.GHASH.ghash key res cs 0 (String.length cs));
360441 Bytes.unsafe_to_string res
361361-362442 end
363443364444 module GCM_of (C : Block.Core) : Block.GCM = struct
445445+ assert (C.block = 16);;
365446366366- assert (C.block = 16)
367447 module CTR = CTR_of (C) (Counters.C128be32)
368448369369- type key = { key : C.ekey ; hkey : GHASH.key }
449449+ type key = { key : C.ekey; hkey : GHASH.key }
370450371451 let tag_size = GHASH.tagsize
372452 let key_sizes, block_size = C.(key, block)
···376456 let h = Bytes.create block_size in
377457 let key = C.e_of_secret cs in
378458 C.encrypt ~key ~blocks:1 z128 0 h 0;
379379- { key ; hkey = GHASH.derive (Bytes.unsafe_to_string h) }
459459+ { key; hkey = GHASH.derive (Bytes.unsafe_to_string h) }
380460381461 let bits64 cs = Int64.of_int (String.length cs * 8)
382462···386466 Bytes.set_int64_be cs 8 b;
387467 Bytes.unsafe_to_string cs
388468389389- let counter ~hkey nonce = match String.length nonce with
469469+ let counter ~hkey nonce =
470470+ match String.length nonce with
390471 | 0 -> invalid_arg "GCM: invalid nonce of length 0"
391472 | 12 ->
392392- let (w1, w2) = String.get_int64_be nonce 0, String.get_int32_be nonce 8 in
393393- (w1, Int64.(shift_left (of_int32 w2) 32 |> add 1L))
394394- | _ ->
395395- CTR.ctr_of_octets @@
396396- GHASH.digesti ~key:hkey @@ iter2 nonce (pack64s 0L (bits64 nonce))
473473+ let w1, w2 =
474474+ (String.get_int64_be nonce 0, String.get_int32_be nonce 8)
475475+ in
476476+ (w1, Int64.(shift_left (of_int32 w2) 32 |> add 1L))
477477+ | _ ->
478478+ CTR.ctr_of_octets @@ GHASH.digesti ~key:hkey
479479+ @@ iter2 nonce (pack64s 0L (bits64 nonce))
397480398398- let unsafe_tag_into ~key ~hkey ~ctr ?(adata = "") cdata ~off ~len dst ~tag_off =
481481+ let unsafe_tag_into ~key ~hkey ~ctr ?(adata = "") cdata ~off ~len dst
482482+ ~tag_off =
399483 CTR.unsafe_encrypt_into ~key ~ctr
400484 (GHASH.digesti_off_len ~key:hkey
401401- (iter3 (adata, 0, String.length adata) (cdata, off, len)
485485+ (iter3
486486+ (adata, 0, String.length adata)
487487+ (cdata, off, len)
402488 (pack64s (bits64 adata) (Int64.of_int (len * 8)), 0, 16)))
403489 ~src_off:0 dst ~dst_off:tag_off tag_size
404490405405- let unsafe_authenticate_encrypt_into ~key:{ key; hkey } ~nonce ?adata src ~src_off dst ~dst_off ~tag_off len =
491491+ let unsafe_authenticate_encrypt_into ~key:{ key; hkey } ~nonce ?adata src
492492+ ~src_off dst ~dst_off ~tag_off len =
406493 let ctr = counter ~hkey nonce in
407407- CTR.(unsafe_encrypt_into ~key ~ctr:(add_ctr ctr 1L) src ~src_off dst ~dst_off len);
408408- unsafe_tag_into ~key ~hkey ~ctr ?adata (Bytes.unsafe_to_string dst) ~off:dst_off ~len dst ~tag_off
494494+ CTR.(
495495+ unsafe_encrypt_into ~key ~ctr:(add_ctr ctr 1L) src ~src_off dst ~dst_off
496496+ len);
497497+ unsafe_tag_into ~key ~hkey ~ctr ?adata
498498+ (Bytes.unsafe_to_string dst)
499499+ ~off:dst_off ~len dst ~tag_off
409500410410- let authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off ~tag_off len =
501501+ let authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off
502502+ ~tag_off len =
411503 check_offset ~tag:"GCM" ~buf:"src" ~off:src_off ~len (String.length src);
412504 check_offset ~tag:"GCM" ~buf:"dst" ~off:dst_off ~len (Bytes.length dst);
413413- check_offset ~tag:"GCM" ~buf:"dst tag" ~off:tag_off ~len:tag_size (Bytes.length dst);
414414- unsafe_authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off ~tag_off len
505505+ check_offset ~tag:"GCM" ~buf:"dst tag" ~off:tag_off ~len:tag_size
506506+ (Bytes.length dst);
507507+ unsafe_authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst
508508+ ~dst_off ~tag_off len
415509416510 let authenticate_encrypt ~key ~nonce ?adata data =
417511 let l = String.length data in
418512 let dst = Bytes.create (l + tag_size) in
419419- unsafe_authenticate_encrypt_into ~key ~nonce ?adata data ~src_off:0 dst ~dst_off:0 ~tag_off:l l;
513513+ unsafe_authenticate_encrypt_into ~key ~nonce ?adata data ~src_off:0 dst
514514+ ~dst_off:0 ~tag_off:l l;
420515 Bytes.unsafe_to_string dst
421516422517 let authenticate_encrypt_tag ~key ~nonce ?adata data =
423518 let r = authenticate_encrypt ~key ~nonce ?adata data in
424424- String.sub r 0 (String.length data),
425425- String.sub r (String.length data) tag_size
519519+ ( String.sub r 0 (String.length data),
520520+ String.sub r (String.length data) tag_size )
426521427427- let unsafe_authenticate_decrypt_into ~key:{ key; hkey } ~nonce ?adata src ~src_off ~tag_off dst ~dst_off len =
522522+ let unsafe_authenticate_decrypt_into ~key:{ key; hkey } ~nonce ?adata src
523523+ ~src_off ~tag_off dst ~dst_off len =
428524 let ctr = counter ~hkey nonce in
429429- CTR.(unsafe_encrypt_into ~key ~ctr:(add_ctr ctr 1L) src ~src_off dst ~dst_off len);
525525+ CTR.(
526526+ unsafe_encrypt_into ~key ~ctr:(add_ctr ctr 1L) src ~src_off dst ~dst_off
527527+ len);
430528 let ctag = Bytes.create tag_size in
431431- unsafe_tag_into ~key ~hkey ~ctr ?adata src ~off:src_off ~len ctag ~tag_off:0;
529529+ unsafe_tag_into ~key ~hkey ~ctr ?adata src ~off:src_off ~len ctag
530530+ ~tag_off:0;
432531 Eqaf.equal (String.sub src tag_off tag_size) (Bytes.unsafe_to_string ctag)
433532434434- let authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst ~dst_off len =
533533+ let authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst
534534+ ~dst_off len =
435535 check_offset ~tag:"GCM" ~buf:"src" ~off:src_off ~len (String.length src);
436436- check_offset ~tag:"GCM" ~buf:"src tag" ~off:tag_off ~len:tag_size (String.length src);
536536+ check_offset ~tag:"GCM" ~buf:"src tag" ~off:tag_off ~len:tag_size
537537+ (String.length src);
437538 check_offset ~tag:"GCM" ~buf:"dst" ~off:dst_off ~len (Bytes.length dst);
438438- unsafe_authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst ~dst_off len
539539+ unsafe_authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off
540540+ dst ~dst_off len
439541440542 let authenticate_decrypt ~key ~nonce ?adata cdata =
441441- if String.length cdata < tag_size then
442442- None
543543+ if String.length cdata < tag_size then None
443544 else
444545 let l = String.length cdata - tag_size in
445546 let data = Bytes.create l in
446446- if unsafe_authenticate_decrypt_into ~key ~nonce ?adata cdata ~src_off:0 ~tag_off:l data ~dst_off:0 l then
447447- Some (Bytes.unsafe_to_string data)
448448- else
449449- None
547547+ if
548548+ unsafe_authenticate_decrypt_into ~key ~nonce ?adata cdata ~src_off:0
549549+ ~tag_off:l data ~dst_off:0 l
550550+ then Some (Bytes.unsafe_to_string data)
551551+ else None
450552451553 let authenticate_decrypt_tag ~key ~nonce ?adata ~tag:tag_data cipher =
452554 let cdata = cipher ^ tag_data in
···454556 end
455557456558 module CCM16_of (C : Block.Core) : Block.CCM16 = struct
457457-458458- assert (C.block = 16)
559559+ assert (C.block = 16);;
459560460561 let tag_size = C.block
461562462563 type key = C.ekey
463564464565 let of_secret sec = C.e_of_secret sec
465465-466466- let (key_sizes, block_size) = C.(key, block)
566566+ let key_sizes, block_size = C.(key, block)
467567468568 let cipher ~key src ~src_off dst ~dst_off =
469569 C.encrypt ~key ~blocks:1 src src_off dst dst_off
470570471471- let unsafe_authenticate_encrypt_into ~key ~nonce ?(adata = "") src ~src_off dst ~dst_off ~tag_off len =
472472- Ccm.unsafe_generation_encryption_into ~cipher ~key ~nonce ~adata
473473- src ~src_off dst ~dst_off ~tag_off len
571571+ let unsafe_authenticate_encrypt_into ~key ~nonce ?(adata = "") src ~src_off
572572+ dst ~dst_off ~tag_off len =
573573+ Ccm.unsafe_generation_encryption_into ~cipher ~key ~nonce ~adata src
574574+ ~src_off dst ~dst_off ~tag_off len
474575475576 let valid_nonce nonce =
476577 let nsize = String.length nonce in
477578 if nsize < 7 || nsize > 13 then
478579 invalid_arg "CCM: nonce length not between 7 and 13: %u" nsize
479580480480- let authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off ~tag_off len =
581581+ let authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off
582582+ ~tag_off len =
481583 check_offset ~tag:"CCM" ~buf:"src" ~off:src_off ~len (String.length src);
482584 check_offset ~tag:"CCM" ~buf:"dst" ~off:dst_off ~len (Bytes.length dst);
483483- check_offset ~tag:"CCM" ~buf:"dst tag" ~off:tag_off ~len:tag_size (Bytes.length dst);
585585+ check_offset ~tag:"CCM" ~buf:"dst tag" ~off:tag_off ~len:tag_size
586586+ (Bytes.length dst);
484587 valid_nonce nonce;
485485- unsafe_authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst ~dst_off ~tag_off len
588588+ unsafe_authenticate_encrypt_into ~key ~nonce ?adata src ~src_off dst
589589+ ~dst_off ~tag_off len
486590487591 let authenticate_encrypt ~key ~nonce ?adata cs =
488592 valid_nonce nonce;
489593 let l = String.length cs in
490594 let dst = Bytes.create (l + tag_size) in
491491- unsafe_authenticate_encrypt_into ~key ~nonce ?adata cs ~src_off:0 dst ~dst_off:0 ~tag_off:l l;
595595+ unsafe_authenticate_encrypt_into ~key ~nonce ?adata cs ~src_off:0 dst
596596+ ~dst_off:0 ~tag_off:l l;
492597 Bytes.unsafe_to_string dst
493598494599 let authenticate_encrypt_tag ~key ~nonce ?adata cs =
495600 let res = authenticate_encrypt ~key ~nonce ?adata cs in
496496- String.sub res 0 (String.length cs), String.sub res (String.length cs) tag_size
601601+ ( String.sub res 0 (String.length cs),
602602+ String.sub res (String.length cs) tag_size )
497603498498- let unsafe_authenticate_decrypt_into ~key ~nonce ?(adata = "") src ~src_off ~tag_off dst ~dst_off len =
499499- Ccm.unsafe_decryption_verification_into ~cipher ~key ~nonce ~adata src ~src_off ~tag_off dst ~dst_off len
604604+ let unsafe_authenticate_decrypt_into ~key ~nonce ?(adata = "") src ~src_off
605605+ ~tag_off dst ~dst_off len =
606606+ Ccm.unsafe_decryption_verification_into ~cipher ~key ~nonce ~adata src
607607+ ~src_off ~tag_off dst ~dst_off len
500608501501- let authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst ~dst_off len =
609609+ let authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst
610610+ ~dst_off len =
502611 check_offset ~tag:"CCM" ~buf:"src" ~off:src_off ~len (String.length src);
503503- check_offset ~tag:"CCM" ~buf:"src tag" ~off:tag_off ~len:tag_size (String.length src);
612612+ check_offset ~tag:"CCM" ~buf:"src tag" ~off:tag_off ~len:tag_size
613613+ (String.length src);
504614 check_offset ~tag:"CCM" ~buf:"dst" ~off:dst_off ~len (Bytes.length dst);
505615 valid_nonce nonce;
506506- unsafe_authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off dst ~dst_off len
616616+ unsafe_authenticate_decrypt_into ~key ~nonce ?adata src ~src_off ~tag_off
617617+ dst ~dst_off len
507618508619 let authenticate_decrypt ~key ~nonce ?adata data =
509509- if String.length data < tag_size then
510510- None
620620+ if String.length data < tag_size then None
511621 else
512622 let dlen = String.length data - tag_size in
513623 let dst = Bytes.create dlen in
514514- if authenticate_decrypt_into ~key ~nonce ?adata data ~src_off:0 ~tag_off:dlen dst ~dst_off:0 dlen then
515515- Some (Bytes.unsafe_to_string dst)
516516- else
517517- None
624624+ if
625625+ authenticate_decrypt_into ~key ~nonce ?adata data ~src_off:0
626626+ ~tag_off:dlen dst ~dst_off:0 dlen
627627+ then Some (Bytes.unsafe_to_string dst)
628628+ else None
518629519630 let authenticate_decrypt_tag ~key ~nonce ?adata ~tag cs =
520631 authenticate_decrypt ~key ~nonce ?adata (cs ^ tag)
···522633end
523634524635module AES = struct
525525-526636 module Core : Block.Core = struct
527527-528528- let key = [| 16; 24; 32 |]
637637+ let key = [| 16; 24; 32 |]
529638 let block = 16
530639531640 type ekey = string * int
···534643 let of_secret_with init key =
535644 let rounds =
536645 match String.length key with
537537- | 16 | 24 | 32 -> String.length key / 4 + 6
646646+ | 16 | 24 | 32 -> (String.length key / 4) + 6
538647 | _ -> invalid_arg "AES.of_secret: key length %u" (String.length key)
539648 in
540649 let rk = Bytes.create (Native.AES.rk_s rounds) in
541541- init key rk rounds ;
542542- Bytes.unsafe_to_string rk, rounds
650650+ init key rk rounds;
651651+ (Bytes.unsafe_to_string rk, rounds)
543652544653 let derive_d ?e buf rk rs = Native.AES.derive_d buf rk rs e
545545-546654 let e_of_secret = of_secret_with Native.AES.derive_e
547655 let d_of_secret = of_secret_with (derive_d ?e:None)
548656549657 let of_secret secret =
550550- let (e, _) as ekey = e_of_secret secret in
658658+ let ((e, _) as ekey) = e_of_secret secret in
551659 (ekey, of_secret_with (derive_d ~e) secret)
552660553661 (* XXX arg order ocaml<->c slows down *)
···558666559667 let decrypt ~key:(d, rounds) ~blocks src off1 dst off2 =
560668 Native.AES.dec src off1 dst off2 d rounds blocks
561561-562669 end
563670564671 module ECB = Modes.ECB_of (Core)
···566673 module CTR = Modes.CTR_of (Core) (Counters.C128be)
567674 module GCM = Modes.GCM_of (Core)
568675 module CCM16 = Modes.CCM16_of (Core)
569569-570676end
571677572678module DES = struct
573573-574679 module Core : Block.Core = struct
575575-576576- let key = [| 24 |]
680680+ let key = [| 24 |]
577681 let block = 8
578682579683 type ekey = string
···583687584688 let gen_of_secret ~direction key =
585689 if String.length key <> 24 then
586586- invalid_arg "DES.of_secret: key length %u" (String.length key) ;
690690+ invalid_arg "DES.of_secret: key length %u" (String.length key);
587691 let key = Bytes.of_string key in
588692 let keybuf = Bytes.create k_s in
589693 Native.DES.des3key key direction keybuf;
···591695592696 let e_of_secret = gen_of_secret ~direction:0
593697 let d_of_secret = gen_of_secret ~direction:1
594594-595698 let of_secret secret = (e_of_secret secret, d_of_secret secret)
596699597700 let encrypt ~key ~blocks src off1 dst off2 =
···603706 module ECB = Modes.ECB_of (Core)
604707 module CBC = Modes.CBC_of (Core)
605708 module CTR = Modes.CTR_of (Core) (Counters.C64be)
606606-607709end
608710609711let accelerated =
610712 let flags =
611611- (match Native.misc_mode () with 1 -> [`XOR] | _ -> []) @
612612- (match Native.AES.mode () with 1 -> [`AES] | _ -> []) @
613613- (match Native.GHASH.mode () with 1 -> [`GHASH] | _ -> []) in
713713+ (match Native.misc_mode () with 1 -> [ `XOR ] | _ -> [])
714714+ @ (match Native.AES.mode () with 1 -> [ `AES ] | _ -> [])
715715+ @ match Native.GHASH.mode () with 1 -> [ `GHASH ] | _ -> []
716716+ in
614717 flags
+14-14
src/cipher_stream.ml
···2233module type Stream = sig
44 type key
55- type result = { message : string ; key : key }
55+ type result = { message : string; key : key }
66+67 val of_secret : string -> key
78 val encrypt : key:key -> string -> result
89 val decrypt : key:key -> string -> result
910end
10111112module ARC4 = struct
1212-1313 type key = int * int * int array
1414-1515- type result = { message : string ; key : key }
1414+ type result = { message : string; key : key }
16151716 let of_secret buf =
1817 let len = String.length buf in
···2524 let si = s.(i) in
2625 let j = (j + si + x) land 0xff in
2726 let sj = s.(j) in
2828- s.(i) <- sj ; s.(j) <- si ;
2727+ s.(i) <- sj;
2828+ s.(j) <- si;
2929 (loop [@tailcall]) j (succ i)
3030 in
3131- ( loop 0 0 ; (0, 0, s) )
3131+ loop 0 0;
3232+ (0, 0, s)
32333334 let encrypt ~key:(i, j, s') buf =
3434- let s = Array.copy s'
3535- and len = String.length buf in
3535+ let s = Array.copy s' and len = String.length buf in
3636 let res = Bytes.create len in
3737 let rec mix i j = function
3838 | n when n = len -> (i, j, s)
3939 | n ->
4040- let i = succ i land 0xff in
4040+ let i = succ i land 0xff in
4141 let si = s.(i) in
4242- let j = (j + si) land 0xff in
4242+ let j = (j + si) land 0xff in
4343 let sj = s.(j) in
4444- s.(i) <- sj ; s.(j) <- si ;
4545- let k = s.((si + sj) land 0xff) in
4444+ s.(i) <- sj;
4545+ s.(j) <- si;
4646+ let k = s.((si + sj) land 0xff) in
4647 Bytes.set_uint8 res n (k lxor String.get_uint8 buf n);
4748 (mix [@tailcall]) i j (succ n)
4849 in
4950 let key' = mix i j 0 in
5050- { key = key' ; message = Bytes.unsafe_to_string res }
5151+ { key = key'; message = Bytes.unsafe_to_string res }
51525253 let decrypt = encrypt
5353-5454end
···1010 the same signature.
11111212 The opam package mirage-crypto-rng provides a cryptographically secure
1313- pseudo-random number generator, the package mirage-crypto-pk provides
1414- public key cryptography.
1515-*)
1313+ pseudo-random number generator, the package mirage-crypto-pk provides public
1414+ key cryptography. *)
16151716(**/**)
1817···2120 This is largely an internal API used in related sub-libraries or tests. As
2221 such, it is prone to breakage. *)
2322module Uncommon : sig
2424-2525- val (//) : int -> int -> int
2323+ val ( // ) : int -> int -> int
2624 (** [x // y] is the ceiling division [ceil (x / y)].
27252826 [x // y] is [0] for any non-positive [x].
···3331 val imax : int -> int -> int
3432 val iter2 : 'a -> 'a -> ('a -> unit) -> unit
3533 val iter3 : 'a -> 'a -> 'a -> ('a -> unit) -> unit
3434+ val xor : string -> string -> string
36353737- val xor : string -> string -> string
3838- val unsafe_xor_into : string -> src_off:int -> bytes -> dst_off:int -> int -> unit
3636+ val unsafe_xor_into :
3737+ string -> src_off:int -> bytes -> dst_off:int -> int -> unit
39384039 val invalid_arg : ('a, Format.formatter, unit, unit, unit, 'b) format6 -> 'a
4140end
···7473 (** [maci ~key iter] is the all-in-one mac computation:
7574 [get (feedi (empty ~key) iter)]. *)
76757777- val mac_into : key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
7676+ val mac_into :
7777+ key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
7878 (** [mac_into ~key datas dst dst_off] computes the [mac] of [datas]. *)
79798080 (**/**)
8181- val unsafe_mac_into : key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
8282- (** [unsafe_mac_into ~key datas dst dst_off] is {!mac_into} without bounds checks. *)
8181+8282+ val unsafe_mac_into :
8383+ key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
8484+ (** [unsafe_mac_into ~key datas dst dst_off] is {!mac_into} without bounds
8585+ checks. *)
8686+8387 (**/**)
8488end
8589···9296 only used for integrity protection, not encrypted and not part of the
9397 ciphertext, can be passed in optionally. This prevents the same ciphertext
9498 being used at a different location. See
9595- {{:https://tools.ietf.org/html/rfc5116}RFC 5116} for further description.
9696-*)
9999+ {{:https://tools.ietf.org/html/rfc5116}RFC 5116} for further description. *)
97100module type AEAD = sig
9898-99101 val tag_size : int
100102 (** The size of the authentication tag. *)
101103···111113112114 (** {1 Authenticated encryption and decryption with inline tag} *)
113115114114- val authenticate_encrypt : key:key -> nonce:string -> ?adata:string ->
115115- string -> string
116116+ val authenticate_encrypt :
117117+ key:key -> nonce:string -> ?adata:string -> string -> string
116118 (** [authenticate_encrypt ~key ~nonce ~adata msg] encrypts [msg] with [key]
117119 and [nonce], and appends an authentication tag computed over the encrypted
118120 [msg], using [key], [nonce], and [adata].
119121120122 @raise Invalid_argument if [nonce] is not of the right size. *)
121123122122- val authenticate_decrypt : key:key -> nonce:string -> ?adata:string ->
123123- string -> string option
124124+ val authenticate_decrypt :
125125+ key:key -> nonce:string -> ?adata:string -> string -> string option
124126 (** [authenticate_decrypt ~key ~nonce ~adata msg] splits [msg] into encrypted
125127 data and authentication tag, computes the authentication tag using [key],
126128 [nonce], and [adata], and decrypts the encrypted data. If the
···128130129131 @raise Invalid_argument if [nonce] is not of the right size. *)
130132131131- (** {1 Authenticated encryption and decryption with tag provided separately} *)
133133+ (** {1 Authenticated encryption and decryption with tag provided separately}
134134+ *)
132135133133- val authenticate_encrypt_tag : key:key -> nonce:string ->
134134- ?adata:string -> string -> string * string
135135- (** [authenticate_encrypt_tag ~key ~nonce ~adata msg] encrypts [msg] with [key]
136136- and [nonce]. The computed authentication tag is returned separately as
137137- second part of the tuple.
136136+ val authenticate_encrypt_tag :
137137+ key:key -> nonce:string -> ?adata:string -> string -> string * string
138138+ (** [authenticate_encrypt_tag ~key ~nonce ~adata msg] encrypts [msg] with
139139+ [key] and [nonce]. The computed authentication tag is returned separately
140140+ as second part of the tuple.
138141139142 @raise Invalid_argument if [nonce] is not of the right size. *)
140143141141- val authenticate_decrypt_tag : key:key -> nonce:string ->
142142- ?adata:string -> tag:string -> string -> string option
144144+ val authenticate_decrypt_tag :
145145+ key:key ->
146146+ nonce:string ->
147147+ ?adata:string ->
148148+ tag:string ->
149149+ string ->
150150+ string option
143151 (** [authenticate_decrypt ~key ~nonce ~adata ~tag msg] computes the
144152 authentication tag using [key], [nonce], and [adata], and decrypts the
145153 encrypted data. If the authentication tags match, the decrypted data is
···149157150158 (** {1 Authenticated encryption and decryption into existing buffers} *)
151159152152- val authenticate_encrypt_into : key:key -> nonce:string ->
153153- ?adata:string -> string -> src_off:int -> bytes -> dst_off:int ->
154154- tag_off:int -> int -> unit
155155- (** [authenticate_encrypt_into ~key ~nonce ~adata msg ~src_off dst ~dst_off ~tag_off len]
156156- encrypts [len] bytes of [msg] starting at [src_off] with [key] and [nonce]. The output
157157- is put into [dst] at [dst_off], the tag into [dst] at [tag_off].
160160+ val authenticate_encrypt_into :
161161+ key:key ->
162162+ nonce:string ->
163163+ ?adata:string ->
164164+ string ->
165165+ src_off:int ->
166166+ bytes ->
167167+ dst_off:int ->
168168+ tag_off:int ->
169169+ int ->
170170+ unit
171171+ (** [authenticate_encrypt_into ~key ~nonce ~adata msg ~src_off dst ~dst_off
172172+ ~tag_off len] encrypts [len] bytes of [msg] starting at [src_off] with
173173+ [key] and [nonce]. The output is put into [dst] at [dst_off], the tag into
174174+ [dst] at [tag_off].
158175159176 @raise Invalid_argument if [nonce] is not of the right size.
160177 @raise Invalid_argument if [String.length msg - src_off < len].
161178 @raise Invalid_argument if [Bytes.length dst - dst_off < len].
162162- @raise Invalid_argument if [Bytes.length dst - tag_off < tag_size].
163163- *)
179179+ @raise Invalid_argument if [Bytes.length dst - tag_off < tag_size]. *)
164180165165- val authenticate_decrypt_into : key:key -> nonce:string ->
166166- ?adata:string -> string -> src_off:int -> tag_off:int -> bytes ->
167167- dst_off:int -> int -> bool
168168- (** [authenticate_decrypt_into ~key ~nonce ~adata msg ~src_off ~tag_off dst ~dst_off len]
169169- computes the authentication tag using [key], [nonce], and [adata], and
170170- decrypts the [len] bytes encrypted data from [msg] starting at [src_off] into [dst]
171171- starting at [dst_off]. If the authentication tags match, [true] is
172172- returned, and the decrypted data is in [dst].
181181+ val authenticate_decrypt_into :
182182+ key:key ->
183183+ nonce:string ->
184184+ ?adata:string ->
185185+ string ->
186186+ src_off:int ->
187187+ tag_off:int ->
188188+ bytes ->
189189+ dst_off:int ->
190190+ int ->
191191+ bool
192192+ (** [authenticate_decrypt_into ~key ~nonce ~adata msg ~src_off ~tag_off dst
193193+ ~dst_off len] computes the authentication tag using [key], [nonce], and
194194+ [adata], and decrypts the [len] bytes encrypted data from [msg] starting
195195+ at [src_off] into [dst] starting at [dst_off]. If the authentication tags
196196+ match, [true] is returned, and the decrypted data is in [dst].
173197174198 @raise Invalid_argument if [nonce] is not of the right size.
175199 @raise Invalid_argument if [String.length msg - src_off < len].
···177201 @raise Invalid_argument if [String.length msg - tag_off < tag_size]. *)
178202179203 (**/**)
180180- val unsafe_authenticate_encrypt_into : key:key -> nonce:string ->
181181- ?adata:string -> string -> src_off:int -> bytes -> dst_off:int ->
182182- tag_off:int -> int -> unit
204204+205205+ val unsafe_authenticate_encrypt_into :
206206+ key:key ->
207207+ nonce:string ->
208208+ ?adata:string ->
209209+ string ->
210210+ src_off:int ->
211211+ bytes ->
212212+ dst_off:int ->
213213+ tag_off:int ->
214214+ int ->
215215+ unit
183216 (** [unsafe_authenticate_encrypt_into] is {!authenticate_encrypt_into}, but
184217 without bounds checks.
185218186219 @raise Invalid_argument if [nonce] is not of the right size.
187220188221 This may cause memory issues if an invariant is violated:
189189- {ul
190190- {- [String.length msg - src_off >= len].}
191191- {- [Bytes.length dst - dst_off >= len].}
192192- {- [Bytes.length dst - tag_off >= tag_size].}} *)
222222+ - [String.length msg - src_off >= len].
223223+ - [Bytes.length dst - dst_off >= len].
224224+ - [Bytes.length dst - tag_off >= tag_size]. *)
193225194194- val unsafe_authenticate_decrypt_into : key:key -> nonce:string ->
195195- ?adata:string -> string -> src_off:int -> tag_off:int -> bytes ->
196196- dst_off:int -> int -> bool
226226+ val unsafe_authenticate_decrypt_into :
227227+ key:key ->
228228+ nonce:string ->
229229+ ?adata:string ->
230230+ string ->
231231+ src_off:int ->
232232+ tag_off:int ->
233233+ bytes ->
234234+ dst_off:int ->
235235+ int ->
236236+ bool
197237 (** [unsafe_authenticate_decrypt_into] is {!authenticate_decrypt_into}, but
198238 without bounds checks.
199239200240 @raise Invalid_argument if [nonce] is not of the right size.
201241202242 This may cause memory issues if an invariant is violated:
203203- {ul
204204- {- [String.length msg - src_off >= len].}
205205- {- [Bytes.length dst - dst_off >= len].}
206206- {- [String.length msg - tag_off >= tag_size].}} *)
243243+ - [String.length msg - src_off >= len].
244244+ - [Bytes.length dst - dst_off >= len].
245245+ - [String.length msg - tag_off >= tag_size]. *)
246246+207247 (**/**)
208248end
209249···214254215255(** Module types for various block cipher modes of operation. *)
216256module Block : sig
217217-218257 (** Modes of operation: *)
219258220259 (** {e Electronic Codebook} "mode". *)
221260 module type ECB = sig
222222-223261 type key
224262225263 val of_secret : string -> key
226264 (** Construct the encryption key corresponding to [secret].
227265228228- @raise Invalid_argument if the length of [secret] is not in
229229- {{!key_sizes}[key_sizes]}. *)
266266+ @raise Invalid_argument
267267+ if the length of [secret] is not in {{!key_sizes}[key_sizes]}. *)
230268231231- val key_sizes : int array
269269+ val key_sizes : int array
232270 (** Key sizes allowed with this cipher. *)
233271234272 val block_size : int
···238276 (** [encrypt ~key src] encrypts [src] into a freshly allocated buffer of the
239277 same size using [key].
240278241241- @raise Invalid_argument if the length of [src] is not a multiple of
242242- {!block_size}. *)
279279+ @raise Invalid_argument
280280+ if the length of [src] is not a multiple of {!block_size}. *)
243281244282 val decrypt : key:key -> string -> string
245283 (** [decrypt ~key src] decrypts [src] into a freshly allocated buffer of the
246284 same size using [key].
247285248248- @raise Invalid_argument if the length of [src] is not a multiple of
249249- {!block_size}. *)
286286+ @raise Invalid_argument
287287+ if the length of [src] is not a multiple of {!block_size}. *)
250288251251- val encrypt_into : key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
289289+ val encrypt_into :
290290+ key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
252291 (** [encrypt_into ~key src ~src_off dst dst_off len] encrypts [len] octets
253292 from [src] starting at [src_off] into [dst] starting at [dst_off].
254293255294 @raise Invalid_argument if [len] is not a multiple of {!block_size}.
256256- @raise Invalid_argument if [src_off < 0 || String.length src - src_off < len].
257257- @raise Invalid_argument if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
295295+ @raise Invalid_argument
296296+ if [src_off < 0 || String.length src - src_off < len].
297297+ @raise Invalid_argument
298298+ if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
258299259259- val decrypt_into : key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
300300+ val decrypt_into :
301301+ key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
260302 (** [decrypt_into ~key src ~src_off dst dst_off len] decrypts [len] octets
261303 from [src] starting at [src_off] into [dst] starting at [dst_off].
262304263305 @raise Invalid_argument if [len] is not a multiple of {!block_size}.
264264- @raise Invalid_argument if [src_off < 0 || String.length src - src_off < len].
265265- @raise Invalid_argument if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
306306+ @raise Invalid_argument
307307+ if [src_off < 0 || String.length src - src_off < len].
308308+ @raise Invalid_argument
309309+ if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
266310267311 (**/**)
268268- val unsafe_encrypt_into : key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
312312+313313+ val unsafe_encrypt_into :
314314+ key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
269315 (** [unsafe_encrypt_into] is {!encrypt_into}, but without bounds checks.
270316271317 This may cause memory issues if an invariant is violated:
272272- {ul
273273- {- [len] must be a multiple of {!block_size},}
274274- {- [src_off >= 0 && String.length src - src_off >= len],}
275275- {- [dst_off >= 0 && Bytes.length dst - dst_off >= len].}} *)
318318+ - [len] must be a multiple of {!block_size},
319319+ - [src_off >= 0 && String.length src - src_off >= len],
320320+ - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
276321277277- val unsafe_decrypt_into : key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
322322+ val unsafe_decrypt_into :
323323+ key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
278324 (** [unsafe_decrypt_into] is {!decrypt_into}, but without bounds checks.
279325280326 This may cause memory issues if an invariant is violated:
281281- {ul
282282- {- [len] must be a multiple of {!block_size},}
283283- {- [src_off >= 0 && String.length src - src_off >= len],}
284284- {- [dst_off >= 0 && Bytes.length dst - dst_off >= len].}} *)
327327+ - [len] must be a multiple of {!block_size},
328328+ - [src_off >= 0 && String.length src - src_off >= len],
329329+ - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
330330+285331 (**/**)
286332 end
287333288334 (** {e Cipher-block chaining} mode. *)
289335 module type CBC = sig
290290-291336 type key
292337293338 val of_secret : string -> key
294339 (** Construct the encryption key corresponding to [secret].
295340296296- @raise Invalid_argument if the length of [secret] is not in
297297- {{!key_sizes}[key_sizes]}. *)
341341+ @raise Invalid_argument
342342+ if the length of [secret] is not in {{!key_sizes}[key_sizes]}. *)
298343299344 val key_sizes : int array
300345 (** Key sizes allowed with this cipher. *)
···306351 (** [encrypt ~key ~iv msg] is [msg] encrypted under [key], using [iv] as the
307352 CBC initialization vector.
308353309309- @raise Invalid_argument if [iv] is not [block_size], or [msg] is not
310310- [k * block_size] long. *)
354354+ @raise Invalid_argument
355355+ if [iv] is not [block_size], or [msg] is not [k * block_size] long. *)
311356312357 val decrypt : key:key -> iv:string -> string -> string
313358 (** [decrypt ~key ~iv msg] is the inverse of [encrypt].
314359315315- @raise Invalid_argument if [iv] is not [block_size], or [msg] is not
316316- [k * block_size] long. *)
360360+ @raise Invalid_argument
361361+ if [iv] is not [block_size], or [msg] is not [k * block_size] long. *)
317362318363 val next_iv : ?off:int -> string -> iv:string -> string
319364 (** [next_iv ~iv ciphertext ~off] is the first [iv] {e following} the
320365 encryption that used [iv] to produce [ciphertext].
321366322322- For protocols which perform inter-message chaining, this is the [iv]
323323- for the next message.
367367+ For protocols which perform inter-message chaining, this is the [iv] for
368368+ the next message.
324369325370 It is either [iv], when [String.length ciphertext - off = 0], or the
326371 last block of [ciphertext]. Note that
327372328328-{[encrypt ~iv msg1 || encrypt ~iv:(next_iv ~iv (encrypt ~iv msg1)) msg2
329329- == encrypt ~iv (msg1 || msg2)]}
373373+ {[
374374+ encrypt ~iv msg1
375375+ || encrypt ~iv:(next_iv ~iv (encrypt ~iv msg1)) msg2
376376+ == encrypt ~iv (msg1 || msg2)
377377+ ]}
330378331379 @raise Invalid_argument if the length of [iv] is not [block_size].
332332- @raise Invalid_argument if the length of [ciphertext] is not a multiple
333333- of [block_size]. *)
380380+ @raise Invalid_argument
381381+ if the length of [ciphertext] is not a multiple of [block_size]. *)
334382335335- val encrypt_into : key:key -> iv:string -> string -> src_off:int ->
336336- bytes -> dst_off:int -> int -> unit
383383+ val encrypt_into :
384384+ key:key ->
385385+ iv:string ->
386386+ string ->
387387+ src_off:int ->
388388+ bytes ->
389389+ dst_off:int ->
390390+ int ->
391391+ unit
337392 (** [encrypt_into ~key ~iv src ~src_off dst dst_off len] encrypts [len]
338338- octets from [src] starting at [src_off] into [dst] starting at [dst_off].
393393+ octets from [src] starting at [src_off] into [dst] starting at
394394+ [dst_off].
339395340396 @raise Invalid_argument if the length of [iv] is not {!block_size}.
341397 @raise Invalid_argument if [len] is not a multiple of {!block_size}.
342342- @raise Invalid_argument if [src_off < 0 || String.length src - src_off < len].
343343- @raise Invalid_argument if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
398398+ @raise Invalid_argument
399399+ if [src_off < 0 || String.length src - src_off < len].
400400+ @raise Invalid_argument
401401+ if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
344402345345- val decrypt_into : key:key -> iv:string -> string -> src_off:int ->
346346- bytes -> dst_off:int -> int -> unit
403403+ val decrypt_into :
404404+ key:key ->
405405+ iv:string ->
406406+ string ->
407407+ src_off:int ->
408408+ bytes ->
409409+ dst_off:int ->
410410+ int ->
411411+ unit
347412 (** [decrypt_into ~key ~iv src ~src_off dst dst_off len] decrypts [len]
348348- octets from [src] starting at [src_off] into [dst] starting at [dst_off].
413413+ octets from [src] starting at [src_off] into [dst] starting at
414414+ [dst_off].
349415350416 @raise Invalid_argument if the length of [iv] is not {!block_size}.
351417 @raise Invalid_argument if [len] is not a multiple of {!block_size}.
352352- @raise Invalid_argument if [src_off < 0 || String.length src - src_off < len].
353353- @raise Invalid_argument if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
418418+ @raise Invalid_argument
419419+ if [src_off < 0 || String.length src - src_off < len].
420420+ @raise Invalid_argument
421421+ if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
354422355423 (**/**)
356356- val unsafe_encrypt_into : key:key -> iv:string -> string -> src_off:int ->
357357- bytes -> dst_off:int -> int -> unit
424424+425425+ val unsafe_encrypt_into :
426426+ key:key ->
427427+ iv:string ->
428428+ string ->
429429+ src_off:int ->
430430+ bytes ->
431431+ dst_off:int ->
432432+ int ->
433433+ unit
358434 (** [unsafe_encrypt_into] is {!encrypt_into}, but without bounds checks.
359435360436 This may casue memory issues if an invariant is violated:
361361- {ul
362362- {- the length of [iv] must be {!block_size},}
363363- {- [len] must be a multiple of {!block_size},}
364364- {- [src_off >= 0 && String.length src - src_off >= len],}
365365- {- [dst_off >= 0 && Bytes.length dst - dst_off >= len].}} *)
437437+ - the length of [iv] must be {!block_size},
438438+ - [len] must be a multiple of {!block_size},
439439+ - [src_off >= 0 && String.length src - src_off >= len],
440440+ - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
366441367367- val unsafe_decrypt_into : key:key -> iv:string -> string -> src_off:int ->
368368- bytes -> dst_off:int -> int -> unit
442442+ val unsafe_decrypt_into :
443443+ key:key ->
444444+ iv:string ->
445445+ string ->
446446+ src_off:int ->
447447+ bytes ->
448448+ dst_off:int ->
449449+ int ->
450450+ unit
369451 (** [unsafe_decrypt_into] is {!decrypt_into}, but without bounds checks.
370452371453 This may casue memory issues if an invariant is violated:
372372- {ul
373373- {- the length of [iv] must be {!block_size},}
374374- {- [len] must be a multiple of {!block_size},}
375375- {- [src_off >= 0 && String.length src - src_off >= len],}
376376- {- [dst_off >= 0 && Bytes.length dst - dst_off >= len].}} *)
454454+ - the length of [iv] must be {!block_size},
455455+ - [len] must be a multiple of {!block_size},
456456+ - [src_off >= 0 && String.length src - src_off >= len],
457457+ - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
377458378378- val unsafe_encrypt_into_inplace : key:key -> iv:string ->
379379- bytes -> dst_off:int -> int -> unit
459459+ val unsafe_encrypt_into_inplace :
460460+ key:key -> iv:string -> bytes -> dst_off:int -> int -> unit
380461 (** [unsafe_encrypt_into_inplace] is {!unsafe_encrypt_into}, but assumes
381462 that [dst] already contains the mesage to be encrypted.
382463383464 This may casue memory issues if an invariant is violated:
384384- {ul
385385- {- the length of [iv] must be {!block_size},}
386386- {- [len] must be a multiple of {!block_size},}
387387- {- [src_off >= 0 && String.length src - src_off >= len],}
388388- {- [dst_off >= 0 && Bytes.length dst - dst_off >= len].}} *)
465465+ - the length of [iv] must be {!block_size},
466466+ - [len] must be a multiple of {!block_size},
467467+ - [src_off >= 0 && String.length src - src_off >= len],
468468+ - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
469469+389470 (**/**)
390390-end
471471+ end
391472392473 (** {e Counter} mode. *)
393474 module type CTR = sig
394394-395475 type key
396476397477 val of_secret : string -> key
398478 (** Construct the encryption key corresponding to [secret].
399479400400- @raise Invalid_argument if the length of [secret] is not in
401401- {{!key_sizes}[key_sizes]}. *)
480480+ @raise Invalid_argument
481481+ if the length of [secret] is not in {{!key_sizes}[key_sizes]}. *)
402482403483 val key_sizes : int array
404484 (** Key sizes allowed with this cipher. *)
···415495 (** [next_ctr ~off msg ~ctr] is the state of the counter after encrypting or
416496 decrypting [msg] at offset [off] with the counter [ctr].
417497418418- For protocols which perform inter-message chaining, this is the
419419- counter for the next message.
498498+ For protocols which perform inter-message chaining, this is the counter
499499+ for the next message.
420500421501 It is computed as [C.add ctr (ceil (len msg / block_size))]. Note that
422502 if [len msg1 = k * block_size],
423503424424-{[encrypt ~ctr msg1 || encrypt ~ctr:(next_ctr ~ctr msg1) msg2
425425- == encrypt ~ctr (msg1 || msg2)]}
426426-427427- *)
504504+ {[
505505+ encrypt ~ctr msg1
506506+ || encrypt ~ctr:(next_ctr ~ctr msg1) msg2
507507+ == encrypt ~ctr (msg1 || msg2)
508508+ ]} *)
428509429510 val ctr_of_octets : string -> ctr
430511 (** [ctr_of_octets buf] converts the value of [buf] into a counter. *)
···439520440521 Note that
441522442442-{[stream ~key ~ctr (k * block_size) || stream ~key ~ctr:(add ctr k) x
443443- == stream ~key ~ctr (k * block_size + x)]}
523523+ {[
524524+ stream ~key ~ctr (k * block_size)
525525+ || stream ~key ~ctr:(add ctr k) x
526526+ == stream ~key ~ctr ((k * block_size) + x)
527527+ ]}
444528445529 In other words, it is possible to restart a keystream at [block_size]
446530 boundaries by manipulating the counter. *)
447531448532 val encrypt : key:key -> ctr:ctr -> string -> string
449449- (** [encrypt ~key ~ctr msg] is
450450- [stream ~key ~ctr (len msg) lxor msg]. *)
533533+ (** [encrypt ~key ~ctr msg] is [stream ~key ~ctr (len msg) lxor msg]. *)
451534452535 val decrypt : key:key -> ctr:ctr -> string -> string
453536 (** [decrypt] is [encrypt]. *)
454537455455- val stream_into : key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
538538+ val stream_into : key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
456539 (** [stream_into ~key ~ctr dst ~off len] is the raw key stream put into
457540 [dst] starting at [off].
458541459542 @raise Invalid_argument if [Bytes.length dst - off < len]. *)
460543461461- val encrypt_into : key:key -> ctr:ctr -> string -> src_off:int ->
462462- bytes -> dst_off:int -> int -> unit
463463- (** [encrypt_into ~key ~ctr src ~src_off dst ~dst_off len] produces the
464464- key stream into [dst] at [dst_off], and then xors it with [src] at
544544+ val encrypt_into :
545545+ key:key ->
546546+ ctr:ctr ->
547547+ string ->
548548+ src_off:int ->
549549+ bytes ->
550550+ dst_off:int ->
551551+ int ->
552552+ unit
553553+ (** [encrypt_into ~key ~ctr src ~src_off dst ~dst_off len] produces the key
554554+ stream into [dst] at [dst_off], and then xors it with [src] at
465555 [src_off].
466556467467- @raise Invalid_argument if [dst_off < 0 || Bytes.length dst - dst_off < len].
468468- @raise Invalid_argument if [src_off < 0 || String.length src - src_off < len]. *)
557557+ @raise Invalid_argument
558558+ if [dst_off < 0 || Bytes.length dst - dst_off < len].
559559+ @raise Invalid_argument
560560+ if [src_off < 0 || String.length src - src_off < len]. *)
469561470470- val decrypt_into : key:key -> ctr:ctr -> string -> src_off:int ->
471471- bytes -> dst_off:int -> int -> unit
562562+ val decrypt_into :
563563+ key:key ->
564564+ ctr:ctr ->
565565+ string ->
566566+ src_off:int ->
567567+ bytes ->
568568+ dst_off:int ->
569569+ int ->
570570+ unit
472571 (** [decrypt_into] is {!encrypt_into}. *)
473572474573 (**/**)
475475- val unsafe_stream_into : key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
574574+575575+ val unsafe_stream_into :
576576+ key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
476577 (** [unsafe_stream_into] is {!stream_into}, but without bounds checks.
477578478579 This may cause memory issues if the invariant is violated:
479479- {ul
480480- {- [off >= 0 && Bytes.length buf - off >= len].}} *)
580580+ - [off >= 0 && Bytes.length buf - off >= len]. *)
481581482482- val unsafe_encrypt_into : key:key -> ctr:ctr -> string -> src_off:int ->
483483- bytes -> dst_off:int -> int -> unit
582582+ val unsafe_encrypt_into :
583583+ key:key ->
584584+ ctr:ctr ->
585585+ string ->
586586+ src_off:int ->
587587+ bytes ->
588588+ dst_off:int ->
589589+ int ->
590590+ unit
484591 (** [unsafe_encrypt_into] is {!encrypt_into}, but without bounds checks.
485592486593 This may cause memory issues if an invariant is violated:
487487- {ul
488488- {- [dst_off >= 0 && Bytes.length dst - dst_off >= len],}
489489- {- [src_off >= 0 && String.length src - src_off >= len].}} *)
594594+ - [dst_off >= 0 && Bytes.length dst - dst_off >= len],
595595+ - [src_off >= 0 && String.length src - src_off >= len]. *)
490596491491- val unsafe_decrypt_into : key:key -> ctr:ctr -> string -> src_off:int ->
492492- bytes -> dst_off:int -> int -> unit
597597+ val unsafe_decrypt_into :
598598+ key:key ->
599599+ ctr:ctr ->
600600+ string ->
601601+ src_off:int ->
602602+ bytes ->
603603+ dst_off:int ->
604604+ int ->
605605+ unit
493606 (** [unsafe_decrypt_into] is {!unsafe_encrypt_into}. *)
607607+494608 (**/**)
495609 end
496610497611 (** {e Galois/Counter Mode}. *)
498612 module type GCM = sig
499499-500613 include AEAD
501614502502- val key_sizes : int array
615615+ val key_sizes : int array
503616 (** Key sizes allowed with this cipher. *)
504617505618 val block_size : int
···508621509622 (** {e Counter with CBC-MAC} mode. *)
510623 module type CCM16 = sig
511511-512624 include AEAD
513625514514- val key_sizes : int array
626626+ val key_sizes : int array
515627 (** Key sizes allowed with this cipher. *)
516628517629 val block_size : int
···533645 module CTR : Block.CTR with type ctr = int64
534646end
535647536536-val accelerated : [`XOR | `AES | `GHASH] list
537537-(** Operations using non-portable, hardware-dependent implementation in
538538- this build of the library. *)
648648+val accelerated : [ `XOR | `AES | `GHASH ] list
649649+(** Operations using non-portable, hardware-dependent implementation in this
650650+ build of the library. *)
539651540652(** The ChaCha20 cipher proposed by D.J. Bernstein. *)
541653module Chacha20 : sig
542654 include AEAD
543655544656 val crypt : key:key -> nonce:string -> ?ctr:int64 -> string -> string
545545- (** [crypt ~key ~nonce ~ctr data] generates a ChaCha20 key stream using
546546- the [key], and [nonce]. The [ctr] defaults to 0. The generated key
547547- stream is of the same length as [data], and the output is the XOR
548548- of the key stream and [data]. This implements, depending on the size
549549- of the [nonce] (8 or 12 bytes) both the original specification (where
550550- the counter is 8 byte, same as the nonce) and the IETF RFC 8439
551551- specification (where nonce is 12 bytes, and counter 4 bytes).
657657+ (** [crypt ~key ~nonce ~ctr data] generates a ChaCha20 key stream using the
658658+ [key], and [nonce]. The [ctr] defaults to 0. The generated key stream is
659659+ of the same length as [data], and the output is the XOR of the key stream
660660+ and [data]. This implements, depending on the size of the [nonce] (8 or 12
661661+ bytes) both the original specification (where the counter is 8 byte, same
662662+ as the nonce) and the IETF RFC 8439 specification (where nonce is 12
663663+ bytes, and counter 4 bytes).
552664553553- @raise Invalid_argument if invalid parameters are provided. Valid
554554- parameters are: [key] must be 32 bytes and [nonce] 12 bytes for the
555555- IETF mode (and counter fit into 32 bits), or [key] must be either 16
556556- bytes or 32 bytes and [nonce] 8 bytes.
665665+ @raise Invalid_argument
666666+ if invalid parameters are provided. Valid parameters are: [key] must be
667667+ 32 bytes and [nonce] 12 bytes for the IETF mode (and counter fit into 32
668668+ bits), or [key] must be either 16 bytes or 32 bytes and [nonce] 8 bytes.
557669 *)
558670end
559671560672(** General stream cipher type. *)
561673module type Stream = sig
562674 type key
563563- type result = { message : string ; key : key }
675675+ type result = { message : string; key : key }
676676+564677 val of_secret : string -> key
565678 val encrypt : key:key -> string -> result
566679 val decrypt : key:key -> string -> result
567680end
568681569569-(** {e Alleged Rivest Cipher 4}. *)
570682module ARC4 : Stream
683683+(** {e Alleged Rivest Cipher 4}. *)
+56-20
src/native.ml
···11+module AES = struct
22+ external enc : string -> int -> bytes -> int -> string -> int -> int -> unit
33+ = "mc_aes_enc_bc" "mc_aes_enc"
44+ [@@noalloc]
1522-module AES = struct
33- external enc : string -> int -> bytes -> int -> string -> int -> int -> unit = "mc_aes_enc_bc" "mc_aes_enc" [@@noalloc]
44- external dec : string -> int -> bytes -> int -> string -> int -> int -> unit = "mc_aes_dec_bc" "mc_aes_dec" [@@noalloc]
55- external derive_e : string -> bytes -> int -> unit = "mc_aes_derive_e_key" [@@noalloc]
66- external derive_d : string -> bytes -> int -> string option -> unit = "mc_aes_derive_d_key" [@@noalloc]
77- external rk_s : int -> int = "mc_aes_rk_size" [@@noalloc]
88- external mode : unit -> int = "mc_aes_mode" [@@noalloc]
66+ external dec : string -> int -> bytes -> int -> string -> int -> int -> unit
77+ = "mc_aes_dec_bc" "mc_aes_dec"
88+ [@@noalloc]
99+1010+ external derive_e : string -> bytes -> int -> unit = "mc_aes_derive_e_key"
1111+ [@@noalloc]
1212+1313+ external derive_d : string -> bytes -> int -> string option -> unit
1414+ = "mc_aes_derive_d_key"
1515+ [@@noalloc]
1616+1717+ external rk_s : int -> int = "mc_aes_rk_size" [@@noalloc]
1818+ external mode : unit -> int = "mc_aes_mode" [@@noalloc]
919end
10201121module DES = struct
1212- external ddes : string -> int -> bytes -> int -> int -> string -> unit = "mc_des_ddes_bc" "mc_des_ddes" [@@noalloc]
1313- external des3key : bytes -> int -> bytes -> unit = "mc_des_des3key" [@@noalloc]
1414- external k_s : unit -> int = "mc_des_key_size" [@@noalloc]
2222+ external ddes : string -> int -> bytes -> int -> int -> string -> unit
2323+ = "mc_des_ddes_bc" "mc_des_ddes"
2424+ [@@noalloc]
2525+2626+ external des3key : bytes -> int -> bytes -> unit = "mc_des_des3key"
2727+ [@@noalloc]
2828+2929+ external k_s : unit -> int = "mc_des_key_size" [@@noalloc]
1530end
16311732module Chacha = struct
1818- external round : int -> bytes -> bytes -> int -> unit = "mc_chacha_round" [@@noalloc]
3333+ external round : int -> bytes -> bytes -> int -> unit = "mc_chacha_round"
3434+ [@@noalloc]
1935end
20362137module Poly1305 = struct
2222- external init : bytes -> string -> unit = "mc_poly1305_init" [@@noalloc]
2323- external update : bytes -> string -> int -> int -> unit = "mc_poly1305_update" [@@noalloc]
2424- external finalize : bytes -> bytes -> int -> unit = "mc_poly1305_finalize" [@@noalloc]
3838+ external init : bytes -> string -> unit = "mc_poly1305_init" [@@noalloc]
3939+4040+ external update : bytes -> string -> int -> int -> unit = "mc_poly1305_update"
4141+ [@@noalloc]
4242+4343+ external finalize : bytes -> bytes -> int -> unit = "mc_poly1305_finalize"
4444+ [@@noalloc]
4545+2546 external ctx_size : unit -> int = "mc_poly1305_ctx_size" [@@noalloc]
2647 external mac_size : unit -> int = "mc_poly1305_mac_size" [@@noalloc]
2748end
···2950module GHASH = struct
3051 external keysize : unit -> int = "mc_ghash_key_size" [@@noalloc]
3152 external keyinit : string -> bytes -> unit = "mc_ghash_init_key" [@@noalloc]
3232- external ghash : string -> bytes -> string -> int -> int -> unit = "mc_ghash" [@@noalloc]
5353+5454+ external ghash : string -> bytes -> string -> int -> int -> unit = "mc_ghash"
5555+ [@@noalloc]
5656+3357 external mode : unit -> int = "mc_ghash_mode" [@@noalloc]
3458end
35593660(* XXX TODO
3761 * Unsolved: bounds-checked XORs are slowing things down considerably... *)
3838-external xor_into_bytes : string -> int -> bytes -> int -> int -> unit = "mc_xor_into_bytes" [@@noalloc]
6262+external xor_into_bytes : string -> int -> bytes -> int -> int -> unit
6363+ = "mc_xor_into_bytes"
6464+[@@noalloc]
39654040-external count8be : ctr:bytes -> bytes -> off:int -> blocks:int -> unit = "mc_count_8_be" [@@noalloc]
4141-external count16be : ctr:bytes -> bytes -> off:int -> blocks:int -> unit = "mc_count_16_be" [@@noalloc]
4242-external count16be4 : ctr:bytes -> bytes -> off:int -> blocks:int -> unit = "mc_count_16_be_4" [@@noalloc]
6666+external count8be : ctr:bytes -> bytes -> off:int -> blocks:int -> unit
6767+ = "mc_count_8_be"
6868+[@@noalloc]
6969+7070+external count16be : ctr:bytes -> bytes -> off:int -> blocks:int -> unit
7171+ = "mc_count_16_be"
7272+[@@noalloc]
7373+7474+external count16be4 : ctr:bytes -> bytes -> off:int -> blocks:int -> unit
7575+ = "mc_count_16_be_4"
7676+[@@noalloc]
43774478external misc_mode : unit -> int = "mc_misc_mode" [@@noalloc]
45794646-external _detect_cpu_features : unit -> unit = "mc_detect_cpu_features" [@@noalloc]
8080+external _detect_cpu_features : unit -> unit = "mc_detect_cpu_features"
8181+[@@noalloc]
8282+4783external _detect_entropy : unit -> unit = "mc_entropy_detect"
48844985let () =
+17-18
src/poly1305.ml
···11module type S = sig
22 type 'a iter = 'a Uncommon.iter
33-43 type t
44+55 val mac_size : int
66-76 val empty : key:string -> t
87 val feed : t -> string -> t
98 val feedi : t -> string iter -> t
109 val get : t -> string
1111-1210 val mac : key:string -> string -> string
1311 val maci : key:string -> string iter -> string
1414- val mac_into : key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
1515- val unsafe_mac_into : key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
1212+1313+ val mac_into :
1414+ key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
1515+1616+ val unsafe_mac_into :
1717+ key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
1618end
17191820module It : S = struct
1921 type 'a iter = 'a Uncommon.iter
20222123 module P = Native.Poly1305
2424+2225 let mac_size = P.mac_size ()
23262427 type t = bytes
···27302831 let empty ~key =
2932 let ctx = Bytes.create (P.ctx_size ()) in
3030- if String.length key <> 32 then invalid_arg "Poly1305 key must be 32 bytes" ;
3131- P.init ctx key ;
3333+ if String.length key <> 32 then invalid_arg "Poly1305 key must be 32 bytes";
3434+ P.init ctx key;
3235 ctx
33363434- let update ctx data =
3535- P.update ctx data 0 (String.length data)
3737+ let update ctx data = P.update ctx data 0 (String.length data)
36383739 let feed ctx cs =
3840 let t = dup ctx in
3939- update t cs ;
4141+ update t cs;
4042 t
41434244 let feedi ctx iter =
4345 let t = dup ctx in
4444- iter (update t) ;
4646+ iter (update t);
4547 t
46484749 let final ctx =
···5052 Bytes.unsafe_to_string res
51535254 let get ctx = final (dup ctx)
5353-5455 let mac ~key data = feed (empty ~key) data |> final
5555-5656 let maci ~key iter = feedi (empty ~key) iter |> final
57575858 let unsafe_mac_into ~key datas dst ~dst_off =
···6464 if Bytes.length dst - dst_off < mac_size then
6565 Uncommon.invalid_arg "Poly1305: dst length %u - off %u < len %u"
6666 (Bytes.length dst) dst_off mac_size;
6767- if dst_off < 0 then
6868- Uncommon.invalid_arg "Poly1305: dst_off %u < 0" dst_off;
6767+ if dst_off < 0 then Uncommon.invalid_arg "Poly1305: dst_off %u < 0" dst_off;
6968 let ctx = empty ~key in
7070- List.iter (fun (d, off, len) ->
7171- if off < 0 then
7272- Uncommon.invalid_arg "Poly1305: d off %u < 0" off;
6969+ List.iter
7070+ (fun (d, off, len) ->
7171+ if off < 0 then Uncommon.invalid_arg "Poly1305: d off %u < 0" off;
7372 if String.length d - off < len then
7473 Uncommon.invalid_arg "Poly1305: d length %u - off %u < len %u"
7574 (String.length d) off len;
+13-5
src/uncommon.ml
···5566let invalid_arg fmt = kasprintf invalid_arg ("Crypto: " ^^ fmt)
7788-let (//) x y =
99- if y < 1 then raise Division_by_zero else
1010- if x > 0 then 1 + ((x - 1) / y) else 0 [@@inline]
88+let ( // ) x y =
99+ if y < 1 then raise Division_by_zero
1010+ else if x > 0 then 1 + ((x - 1) / y)
1111+ else 0
1212+[@@inline]
11131214let imin (a : int) b = if a < b then a else b
1315let imax (a : int) b = if a < b then b else a
14161517type 'a iter = ('a -> unit) -> unit
16181717-let iter2 a b f = f a; f b
1818-let iter3 a b c f = f a; f b; f c
1919+let iter2 a b f =
2020+ f a;
2121+ f b
2222+2323+let iter3 a b c f =
2424+ f a;
2525+ f b;
2626+ f c
19272028let unsafe_xor_into src ~src_off dst ~dst_off n =
2129 Native.xor_into_bytes src src_off dst dst_off n
+38-46
tests/misc_pk.ml
···11-21let mem f =
32 let t = Hashtbl.create 100 in
43 fun x ->
55- try Hashtbl.find t x with
66- | Not_found ->
77- let r = f x in ( Hashtbl.add t x r ; r )
88-44+ try Hashtbl.find t x
55+ with Not_found ->
66+ let r = f x in
77+ Hashtbl.add t x r;
88+ r
991010(* An [admittedly primitive] implementation of Pollards p-1 factoring method. *)
11111212module Pollard = struct
1313-1413 let primes_to n =
1514 let rec scan = function
1615 | p when p > n -> []
1717- | p -> p :: scan Z.(nextprime p) in
1616+ | p -> p :: scan Z.(nextprime p)
1717+ in
1818 scan (Z.of_int 2)
19192020 let max_pow limit x =
···2222 if Z.(pow x upper) > limit then (lower, upper)
2323 else expand upper (upper * 2)
2424 and narrow lower upper =
2525- if upper - lower = 1 then lower else
2525+ if upper - lower = 1 then lower
2626+ else
2627 let mid = (lower + upper) / 2 in
2727- if Z.(pow x mid) > limit then
2828- narrow lower mid
2929- else narrow mid upper
2828+ if Z.(pow x mid) > limit then narrow lower mid else narrow mid upper
3029 in
3131- let (l, u) = expand 1 2 in
3030+ let l, u = expand 1 2 in
3231 narrow l u
33323433 let ppowers_to n =
···3635 | p when p > n -> []
3736 | p ->
3837 let pp = Z.pow p (max_pow n p) in
3939- pp :: scan Z.(nextprime p) in
3838+ pp :: scan Z.(nextprime p)
3939+ in
4040 scan (Z.of_int 2)
41414242 let note ~msg f =
4343- Printf.printf "[%s] ->\n%!" msg ;
4343+ Printf.printf "[%s] ->\n%!" msg;
4444 let r = f () in
4545- Printf.printf "[%s] <-\n%!" msg ;
4545+ Printf.printf "[%s] <-\n%!" msg;
4646 r
47474848- let prime_pows_to_prod = mem @@ fun n ->
4848+ let prime_pows_to_prod =
4949+ mem @@ fun n ->
4950 let rec scan acc = function
5051 | p when p > n -> acc
5151- | p -> scan Z.(acc * (pow p (max_pow n p)))
5252- Z.(nextprime p) in
5353- note ~msg:"powers" @@ fun () ->
5454- scan Z.one Z.(of_int 2)
5252+ | p -> scan Z.(acc * pow p (max_pow n p)) Z.(nextprime p)
5353+ in
5454+ note ~msg:"powers" @@ fun () -> scan Z.one Z.(of_int 2)
55555656 let split ~limit n =
5757 let a = Nums.Z.gen n in
···6161 let rec scan a m =
6262 let x = Z.(powm a (m * n) n) in
6363 if Z.(x = one) then
6464- if Z.(m mod of_int 2 = zero) then
6565- scan a Z.(m / of_int 2)
6464+ if Z.(m mod of_int 2 = zero) then scan a Z.(m / of_int 2)
6665 else raise Not_found
6766 else
6867 let d = Z.(gcd (x - one) n) in
6968 if Z.(d > one) then d else raise Not_found
7069 in
7170 scan a (prime_pows_to_prod limit)
7272-7371end
74727573module RSA_misc = struct
7676-7774 let slack = 8
78757976 (* Rivest's p-minus strong prime generator. *)
80778178 let rec pm_strong_prime ?g ~bits =
8282- let a_lim = Z.(pow z_two slack - one)
8383- in
7979+ let a_lim = Z.(pow z_two slack - one) in
8480 let rec mul_seq p = function
8581 | a when a > a_lim ->
8682 Printf.printf "++ mul seq: falling off the cliff.\n%!";
8783 None
8888- | a ->
8989- let p' = Z.(a * p + one) in
8484+ | a -> (
8585+ let p' = Z.((a * p) + one) in
9086 match Z.probab_prime p' 25 with
9187 | 0 ->
9288 Printf.printf "+ mul seq: climb.\n%!";
9389 mul_seq p Z.(a + z_two)
9490 | _ ->
9591 Printf.printf "** mul seq: prime with %s\n%!" Z.(to_string a);
9696- Some p'
9292+ Some p')
9793 in
9894 let pmm = prime ?g ~bits in
9995 match mul_seq pmm z_two with
100100- | None -> pm_strong_prime ?g ~bits
101101- | Some pm ->
9696+ | None -> pm_strong_prime ?g ~bits
9797+ | Some pm -> (
10298 match mul_seq pm z_two with
103103- | None -> pm_strong_prime ?g ~bits
104104- | Some p -> (pmm, pm, p)
9999+ | None -> pm_strong_prime ?g ~bits
100100+ | Some p -> (pmm, pm, p))
105101106102 let slim = Z.(pow z_two 8)
107103108104 (* Williams/Schmid strong prime generator. *)
109105110106 let rec p_strong_prime1 ?g ~bits =
111111- let (bits1, bits2) = (bits / 2, bits - bits / 2)
112112- in
113113- let pmm = prime ?g ~bits:bits1
114114- and pp = prime ?g ~bits:bits2 in
115115- let r = Z.(pp - invert pmm pp)
116116- in
107107+ let bits1, bits2 = (bits / 2, bits - (bits / 2)) in
108108+ let pmm = prime ?g ~bits:bits1 and pp = prime ?g ~bits:bits2 in
109109+ let r = Z.(pp - invert pmm pp) in
117110 let rec find_a = function
118111 | a when a >= slim ->
119119- Printf.printf "off the cliff...\n%!" ;
112112+ Printf.printf "off the cliff...\n%!";
120113 p_strong_prime1 ?g ~bits
121121- | a ->
122122- let pm = Z.(z_two * a * pmm * pp + z_two * r * pmm + one) in
114114+ | a -> (
115115+ let pm = Z.((z_two * a * pmm * pp) + (z_two * r * pmm) + one) in
123116 match Z.probab_prime pm 25 with
124117 | 0 -> find_a Z.(a + one)
125125- | _ ->
126126- let p = Z.(z_two * pm + one) in
118118+ | _ -> (
119119+ let p = Z.((z_two * pm) + one) in
127120 match Z.probab_prime p 25 with
128121 | 0 -> find_a Z.(a + one)
129122 | _ ->
130123 Printf.printf "found pm, p with %s\n%!" Z.(to_string a);
131131- (pmm, pm, pp, p)
124124+ (pmm, pm, pp, p)))
132125 in
133126 find_a z_two
134134-135127end
···11open OUnit2
22-32open Crypto
44-53open Test_common
6475let des_ecb_cases =
88- let case ~data ~key ~out = vx data, DES.ECB.of_secret (vx key), vx out
99-66+ let case ~data ~key ~out = (vx data, DES.ECB.of_secret (vx key), vx out)
107 and check (data, key, out) _ =
118 let enc = DES.ECB.encrypt ~key data in
129 let dec = DES.ECB.decrypt ~key enc in
1313- assert_oct_equal ~msg:"ciphertext" out enc ;
1414- assert_oct_equal ~msg:"plaintext" data dec in
1010+ assert_oct_equal ~msg:"ciphertext" out enc;
1111+ assert_oct_equal ~msg:"plaintext" data dec
1212+ in
15131616- cases_of check [
1717- case
1818- ~data:"3f87 9123 0058 8d88 e784 d52a 5d0f 2038
1919- f523 6889 bbce ce1f a7bf 7aa8 6fcc 8245
2020- 0576 2144 8f11 94d7 07bc 1bba 9b92 5e45
2121- 3190 c42b 758f 3d91 f68e ebbb ce62 b8e7"
2222- ~key: "3f47 f79c c120 7188 4700 217e fd88 bbe4 6f51 27fb 7340 81e5"
2323- ~out: "b43b 3ae3 d765 b299 06ea 7c35 ceeb 9e52
2424- 946c 06e7 0d50 193e 5a22 1ff0 afe9 abe0
2525- 3b82 ce7d c42a 465d 0f19 45f0 5382 7006
2626- b4cd 21f0 5b0f 6843 de2a 67b6 9fb4 6a8f"
2727-]
1414+ cases_of check
1515+ [
1616+ case
1717+ ~data:
1818+ "3f87 9123 0058 8d88 e784 d52a 5d0f 2038\n\
1919+ \ f523 6889 bbce ce1f a7bf 7aa8 6fcc 8245\n\
2020+ \ 0576 2144 8f11 94d7 07bc 1bba 9b92 5e45\n\
2121+ \ 3190 c42b 758f 3d91 f68e ebbb ce62 b8e7"
2222+ ~key:"3f47 f79c c120 7188 4700 217e fd88 bbe4 6f51 27fb 7340 81e5"
2323+ ~out:
2424+ "b43b 3ae3 d765 b299 06ea 7c35 ceeb 9e52\n\
2525+ \ 946c 06e7 0d50 193e 5a22 1ff0 afe9 abe0\n\
2626+ \ 3b82 ce7d c42a 465d 0f19 45f0 5382 7006\n\
2727+ \ b4cd 21f0 5b0f 6843 de2a 67b6 9fb4 6a8f";
2828+ ]
28292930let des_cbc_cases =
3030- let case ~data ~key ~iv ~out = vx data, DES.CBC.of_secret (vx key), vx iv, vx out
3131-3131+ let case ~data ~key ~iv ~out =
3232+ (vx data, DES.CBC.of_secret (vx key), vx iv, vx out)
3233 and check (data, key, iv, out) _ =
3334 let enc = DES.CBC.encrypt ~key ~iv data in
3435 let dec = DES.CBC.decrypt ~key ~iv enc in
3535- assert_oct_equal ~msg:"ciphertext" out enc ;
3636- assert_oct_equal ~msg:"plaintext" data dec in
3636+ assert_oct_equal ~msg:"ciphertext" out enc;
3737+ assert_oct_equal ~msg:"plaintext" data dec
3838+ in
37393838- cases_of check [
3939- case
4040- ~data:
4141-"8f8c 1e0a c8fb 1614 3cec ed1c 28ac fd6f
4242-ae6d 3686 5365 511d 6707 68d9 7928 0479
4343-cacd 6808 1540 d5fc 2971 2a8a c2b1 17c2
4444-f0e6 a329 e190 44ff 54e7 5eec 8296 6a58"
4545- ~iv:"b219 ef93 4c37 aadf"
4646- ~key:"7ecd 2240 a2ac a10a e713 f467 7ea5 d327 e04c cfe0 5cb4 bb09"
4747-~out:
4848-"3110 3904 faa1 4ef4 e404 d3d0 f2ee ae58
4949-5fe9 e6b7 9552 b4f4 3608 03ca 395a f6e9
5050-2330 69d6 2c6f a52a d083 faab 3306 b794
5151-89f6 6671 e3dd 3368 0b13 f8d9 7136 9674"
5252- ]
4040+ cases_of check
4141+ [
4242+ case
4343+ ~data:
4444+ "8f8c 1e0a c8fb 1614 3cec ed1c 28ac fd6f\n\
4545+ ae6d 3686 5365 511d 6707 68d9 7928 0479\n\
4646+ cacd 6808 1540 d5fc 2971 2a8a c2b1 17c2\n\
4747+ f0e6 a329 e190 44ff 54e7 5eec 8296 6a58"
4848+ ~iv:"b219 ef93 4c37 aadf"
4949+ ~key:"7ecd 2240 a2ac a10a e713 f467 7ea5 d327 e04c cfe0 5cb4 bb09"
5050+ ~out:
5151+ "3110 3904 faa1 4ef4 e404 d3d0 f2ee ae58\n\
5252+ 5fe9 e6b7 9552 b4f4 3608 03ca 395a f6e9\n\
5353+ 2330 69d6 2c6f a52a d083 faab 3306 b794\n\
5454+ 89f6 6671 e3dd 3368 0b13 f8d9 7136 9674";
5555+ ]
53565457let des_ctr_cases =
5555- let case ~data ~key ~ctr ~out = test_case @@ fun _ ->
5858+ let case ~data ~key ~ctr ~out =
5959+ test_case @@ fun _ ->
5660 let open DES.CTR in
5757- let key = vx key |> of_secret
5858- and ctr = vx ctr |> ctr_of_octets
5959- and out = vx out
6161+ let key = vx key |> of_secret
6262+ and ctr = vx ctr |> ctr_of_octets
6363+ and out = vx out
6064 and data = vx data in
6165 let enc = encrypt ~key ~ctr data in
6266 let dec = decrypt ~key ~ctr enc in
6367 assert_oct_equal ~msg:"cipher" out enc;
6468 assert_oct_equal ~msg:"plain" data dec
6569 in
6666- [ case
7070+ [
7171+ case
6772 ~data:
6868-"e9ee ce61 7b75 4c70 79f3 3e5b 036a 7d5b
6969-4bee f693 0eb3 fa50 9fe3 61d8 713a a487
7070-a692 21b0 8627 5e6f d021 4030 7c58 507a
7171-5fea ca64 d17d a493 7337 8c17 ae05 f3c4
7272-c6dc 15cc 49c4 3ab0 dab3 9c9b e964 a3c8
7373-5865 7bb8 6e4d 8507 3866 b805 02c2 4970
7474-dbbd 3554 20b1 76b2 ee6c 98b3 f7ce 9035
7575-1e5f 880e"
7676-~key:"76b9 d4ff d52f 5024 6d24 a3e1 4ebd e605 b82c d81f 0c07 2da1"
7777-~ctr:"6318 a132 cafd aac0"
7878-~out:
7979-"b8d8 aeec d583 009c f042 ec4d 7ddf c5e5
8080-386f 89e6 d975 02bc 7583 e113 4899 dabc
8181-bd93 871b 774b e5ce 4e12 6778 f208 0c53
8282-52cb a3ac 7567 cdb9 ae81 fc46 25d4 7f9d
8383-6f3f fbec 4512 8845 3739 1014 2b39 d293
8484-845a 8505 91a6 f644 5168 bf00 ca4d 4603
8585-6e5f 418f c43f fabd 272e 1009 c69b 2a6b
8686-7d2c edb2"
8787-7373+ "e9ee ce61 7b75 4c70 79f3 3e5b 036a 7d5b\n\
7474+ 4bee f693 0eb3 fa50 9fe3 61d8 713a a487\n\
7575+ a692 21b0 8627 5e6f d021 4030 7c58 507a\n\
7676+ 5fea ca64 d17d a493 7337 8c17 ae05 f3c4\n\
7777+ c6dc 15cc 49c4 3ab0 dab3 9c9b e964 a3c8\n\
7878+ 5865 7bb8 6e4d 8507 3866 b805 02c2 4970\n\
7979+ dbbd 3554 20b1 76b2 ee6c 98b3 f7ce 9035\n\
8080+ 1e5f 880e"
8181+ ~key:"76b9 d4ff d52f 5024 6d24 a3e1 4ebd e605 b82c d81f 0c07 2da1"
8282+ ~ctr:"6318 a132 cafd aac0"
8383+ ~out:
8484+ "b8d8 aeec d583 009c f042 ec4d 7ddf c5e5\n\
8585+ 386f 89e6 d975 02bc 7583 e113 4899 dabc\n\
8686+ bd93 871b 774b e5ce 4e12 6778 f208 0c53\n\
8787+ 52cb a3ac 7567 cdb9 ae81 fc46 25d4 7f9d\n\
8888+ 6f3f fbec 4512 8845 3739 1014 2b39 d293\n\
8989+ 845a 8505 91a6 f644 5168 bf00 ca4d 4603\n\
9090+ 6e5f 418f c43f fabd 272e 1009 c69b 2a6b\n\
9191+ 7d2c edb2";
8892 ]
89939090-9194(* NIST SP 800-38A test vectors for block cipher modes of operation *)
92959393-let nist_sp_800_38a = vx
9494- "6b c1 be e2 2e 40 9f 96 e9 3d 7e 11 73 93 17 2a
9595- ae 2d 8a 57 1e 03 ac 9c 9e b7 6f ac 45 af 8e 51
9696- 30 c8 1c 46 a3 5c e4 11 e5 fb c1 19 1a 0a 52 ef
9797- f6 9f 24 45 df 4f 9b 17 ad 2b 41 7b e6 6c 37 10"
9696+let nist_sp_800_38a =
9797+ vx
9898+ "6b c1 be e2 2e 40 9f 96 e9 3d 7e 11 73 93 17 2a\n\
9999+ \ ae 2d 8a 57 1e 03 ac 9c 9e b7 6f ac 45 af 8e 51\n\
100100+ \ 30 c8 1c 46 a3 5c e4 11 e5 fb c1 19 1a 0a 52 ef\n\
101101+ \ f6 9f 24 45 df 4f 9b 17 ad 2b 41 7b e6 6c 37 10"
9810299103let aes_ecb_cases =
100104 let case ~key ~out = (AES.ECB.of_secret (vx key), vx out)
101101-102105 and check (key, out) _ =
103106 let enc = AES.ECB.encrypt ~key nist_sp_800_38a in
104107 let dec = AES.ECB.decrypt ~key enc in
105105- assert_oct_equal ~msg:"ciphertext" out enc ;
106106- assert_oct_equal ~msg:"plaintext" nist_sp_800_38a dec in
108108+ assert_oct_equal ~msg:"ciphertext" out enc;
109109+ assert_oct_equal ~msg:"plaintext" nist_sp_800_38a dec
110110+ in
107111108108- cases_of check [
109109- case ~key: "2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c"
110110- ~out: "3a d7 7b b4 0d 7a 36 60 a8 9e ca f3 24 66 ef 97
111111- f5 d3 d5 85 03 b9 69 9d e7 85 89 5a 96 fd ba af
112112- 43 b1 cd 7f 59 8e ce 23 88 1b 00 e3 ed 03 06 88
113113- 7b 0c 78 5e 27 e8 ad 3f 82 23 20 71 04 72 5d d4"
114114-115115- ; case ~key: "8e 73 b0 f7 da 0e 64 52 c8 10 f3 2b 80 90 79 e5
116116- 62 f8 ea d2 52 2c 6b 7b"
117117- ~out: "bd 33 4f 1d 6e 45 f2 5f f7 12 a2 14 57 1f a5 cc
118118- 97 41 04 84 6d 0a d3 ad 77 34 ec b3 ec ee 4e ef
119119- ef 7a fd 22 70 e2 e6 0a dc e0 ba 2f ac e6 44 4e
120120- 9a 4b 41 ba 73 8d 6c 72 fb 16 69 16 03 c1 8e 0e"
121121-122122- ; case ~key: "60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81
123123- 1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4"
124124- ~out: "f3 ee d1 bd b5 d2 a0 3c 06 4b 5a 7e 3d b1 81 f8
125125- 59 1c cb 10 d4 10 ed 26 dc 5b a7 4a 31 36 28 70
126126- b6 ed 21 b9 9c a6 f4 f9 f1 53 e7 b1 be af ed 1d
127127- 23 30 4b 7a 39 f9 f3 ff 06 7d 8d 8f 9e 24 ec c7"
128128- ]
112112+ cases_of check
113113+ [
114114+ case ~key:"2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c"
115115+ ~out:
116116+ "3a d7 7b b4 0d 7a 36 60 a8 9e ca f3 24 66 ef 97\n\
117117+ \ f5 d3 d5 85 03 b9 69 9d e7 85 89 5a 96 fd ba af\n\
118118+ \ 43 b1 cd 7f 59 8e ce 23 88 1b 00 e3 ed 03 06 88\n\
119119+ \ 7b 0c 78 5e 27 e8 ad 3f 82 23 20 71 04 72 5d d4";
120120+ case
121121+ ~key:
122122+ "8e 73 b0 f7 da 0e 64 52 c8 10 f3 2b 80 90 79 e5\n\
123123+ \ 62 f8 ea d2 52 2c 6b 7b"
124124+ ~out:
125125+ "bd 33 4f 1d 6e 45 f2 5f f7 12 a2 14 57 1f a5 cc\n\
126126+ \ 97 41 04 84 6d 0a d3 ad 77 34 ec b3 ec ee 4e ef\n\
127127+ \ ef 7a fd 22 70 e2 e6 0a dc e0 ba 2f ac e6 44 4e\n\
128128+ \ 9a 4b 41 ba 73 8d 6c 72 fb 16 69 16 03 c1 8e 0e";
129129+ case
130130+ ~key:
131131+ "60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81\n\
132132+ \ 1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4"
133133+ ~out:
134134+ "f3 ee d1 bd b5 d2 a0 3c 06 4b 5a 7e 3d b1 81 f8\n\
135135+ \ 59 1c cb 10 d4 10 ed 26 dc 5b a7 4a 31 36 28 70\n\
136136+ \ b6 ed 21 b9 9c a6 f4 f9 f1 53 e7 b1 be af ed 1d\n\
137137+ \ 23 30 4b 7a 39 f9 f3 ff 06 7d 8d 8f 9e 24 ec c7";
138138+ ]
129139130140let aes_cbc_cases =
131141 let case ~key ~iv ~out = (AES.CBC.of_secret (vx key), vx iv, vx out)
132132-133142 and check (key, iv, out) _ =
134143 let enc = AES.CBC.encrypt ~key ~iv nist_sp_800_38a in
135144 let dec = AES.CBC.decrypt ~key ~iv enc in
136136- assert_oct_equal ~msg:"ciphertext" out enc ;
137137- assert_oct_equal ~msg:"plaintext" nist_sp_800_38a dec in
138138-139139- cases_of check [
140140- case ~key: "2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c"
141141- ~iv: "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"
142142- ~out: "76 49 ab ac 81 19 b2 46 ce e9 8e 9b 12 e9 19 7d
143143- 50 86 cb 9b 50 72 19 ee 95 db 11 3a 91 76 78 b2
144144- 73 be d6 b8 e3 c1 74 3b 71 16 e6 9e 22 22 95 16
145145- 3f f1 ca a1 68 1f ac 09 12 0e ca 30 75 86 e1 a7"
146146-147147- ; case ~key: "8e 73 b0 f7 da 0e 64 52 c8 10 f3 2b 80 90 79 e5
148148- 62 f8 ea d2 52 2c 6b 7b"
149149- ~iv: "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"
150150- ~out: "4f 02 1d b2 43 bc 63 3d 71 78 18 3a 9f a0 71 e8
151151- b4 d9 ad a9 ad 7d ed f4 e5 e7 38 76 3f 69 14 5a
152152- 57 1b 24 20 12 fb 7a e0 7f a9 ba ac 3d f1 02 e0
153153- 08 b0 e2 79 88 59 88 81 d9 20 a9 e6 4f 56 15 cd"
145145+ assert_oct_equal ~msg:"ciphertext" out enc;
146146+ assert_oct_equal ~msg:"plaintext" nist_sp_800_38a dec
147147+ in
154148155155- ; case ~key: "60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81
156156- 1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4"
157157- ~iv: "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"
158158- ~out: "f5 8c 4c 04 d6 e5 f1 ba 77 9e ab fb 5f 7b fb d6
159159- 9c fc 4e 96 7e db 80 8d 67 9f 77 7b c6 70 2c 7d
160160- 39 f2 33 69 a9 d9 ba cf a5 30 e2 63 04 23 14 61
161161- b2 eb 05 e2 c3 9b e9 fc da 6c 19 07 8c 6a 9d 1b"
162162- ]
149149+ cases_of check
150150+ [
151151+ case ~key:"2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c"
152152+ ~iv:"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"
153153+ ~out:
154154+ "76 49 ab ac 81 19 b2 46 ce e9 8e 9b 12 e9 19 7d\n\
155155+ \ 50 86 cb 9b 50 72 19 ee 95 db 11 3a 91 76 78 b2\n\
156156+ \ 73 be d6 b8 e3 c1 74 3b 71 16 e6 9e 22 22 95 16\n\
157157+ \ 3f f1 ca a1 68 1f ac 09 12 0e ca 30 75 86 e1 a7";
158158+ case
159159+ ~key:
160160+ "8e 73 b0 f7 da 0e 64 52 c8 10 f3 2b 80 90 79 e5\n\
161161+ \ 62 f8 ea d2 52 2c 6b 7b"
162162+ ~iv:"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"
163163+ ~out:
164164+ "4f 02 1d b2 43 bc 63 3d 71 78 18 3a 9f a0 71 e8\n\
165165+ \ b4 d9 ad a9 ad 7d ed f4 e5 e7 38 76 3f 69 14 5a\n\
166166+ \ 57 1b 24 20 12 fb 7a e0 7f a9 ba ac 3d f1 02 e0\n\
167167+ \ 08 b0 e2 79 88 59 88 81 d9 20 a9 e6 4f 56 15 cd";
168168+ case
169169+ ~key:
170170+ "60 3d eb 10 15 ca 71 be 2b 73 ae f0 85 7d 77 81\n\
171171+ \ 1f 35 2c 07 3b 61 08 d7 2d 98 10 a3 09 14 df f4"
172172+ ~iv:"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"
173173+ ~out:
174174+ "f5 8c 4c 04 d6 e5 f1 ba 77 9e ab fb 5f 7b fb d6\n\
175175+ \ 9c fc 4e 96 7e db 80 8d 67 9f 77 7b c6 70 2c 7d\n\
176176+ \ 39 f2 33 69 a9 d9 ba cf a5 30 e2 63 04 23 14 61\n\
177177+ \ b2 eb 05 e2 c3 9b e9 fc da 6c 19 07 8c 6a 9d 1b";
178178+ ]
163179164180let aes_ctr_cases =
165165- let case ~key ~ctr ~out ~ctr1 = test_case @@ fun _ ->
181181+ let case ~key ~ctr ~out ~ctr1 =
182182+ test_case @@ fun _ ->
166183 let open AES.CTR in
167167- let key = vx key |> of_secret
168168- and ctr = vx ctr |> ctr_of_octets
184184+ let key = vx key |> of_secret
185185+ and ctr = vx ctr |> ctr_of_octets
169186 and ctr1 = vx ctr1 |> ctr_of_octets
170170- and out = vx out in
187187+ and out = vx out in
171188 let enc = encrypt ~key ~ctr nist_sp_800_38a in
172189 let dec = decrypt ~key ~ctr enc in
173190 assert_oct_equal ~msg:"cipher" out enc;
···175192 let blocks = String.length nist_sp_800_38a / block_size in
176193 assert_equal ~msg:"counters" ctr1 (add_ctr ctr (Int64.of_int blocks))
177194 in
178178- [ case ~key: "2b7e1516 28aed2a6 abf71588 09cf4f3c"
179179- ~ctr: "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"
180180- ~out: "874d6191 b620e326 1bef6864 990db6ce
181181- 9806f66b 7970fdff 8617187b b9fffdff
182182- 5ae4df3e dbd5d35e 5b4f0902 0db03eab
183183- 1e031dda 2fbe03d1 792170a0 f3009cee"
184184- ~ctr1: "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdff03"
185185-186186- ; case ~key: "8e73b0f7 da0e6452 c810f32b 809079e5
187187- 62f8ead2 522c6b7b"
188188- ~ctr: "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"
189189- ~out: "1abc9324 17521ca2 4f2b0459 fe7e6e0b
190190- 090339ec 0aa6faef d5ccc2c6 f4ce8e94
191191- 1e36b26b d1ebc670 d1bd1d66 5620abf7
192192- 4f78a7f6 d2980958 5a97daec 58c6b050"
193193- ~ctr1: "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdff03"
194194-195195- ; case ~key: "603deb10 15ca71be 2b73aef0 857d7781
196196- 1f352c07 3b6108d7 2d9810a3 0914dff4"
197197- ~ctr: "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"
198198- ~out: "601ec313 775789a5 b7a7f504 bbf3d228
199199- f443e3ca 4d62b59a ca84e990 cacaf5c5
200200- 2b0930da a23de94c e87017ba 2d84988d
201201- dfc9c58d b67aada6 13c2dd08 457941a6"
202202- ~ctr1: "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdff03"
203203-204204- ; case ~key: "00010203 04050607 08090a0b 0c0d0e0f" (* ctr rollover *)
205205- ~ctr: "00000000 00000000 ffffffff fffffffe"
206206- ~out: "5d0a5645 378f579a 988ff186 d42eaa2f
207207- 978a655d 145bfe34 21656c8f 01101a43
208208- 23d0862c 47f7e3bf 95586ba4 2ab4cb31
209209- 790b0d01 93c0d022 3469534e 537ce82d"
210210- ~ctr1: "00000000 00000001 00000000 00000002"
195195+ [
196196+ case ~key:"2b7e1516 28aed2a6 abf71588 09cf4f3c"
197197+ ~ctr:"f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"
198198+ ~out:
199199+ "874d6191 b620e326 1bef6864 990db6ce\n\
200200+ \ 9806f66b 7970fdff 8617187b b9fffdff\n\
201201+ \ 5ae4df3e dbd5d35e 5b4f0902 0db03eab\n\
202202+ \ 1e031dda 2fbe03d1 792170a0 f3009cee"
203203+ ~ctr1:"f0f1f2f3 f4f5f6f7 f8f9fafb fcfdff03";
204204+ case
205205+ ~key:
206206+ "8e73b0f7 da0e6452 c810f32b 809079e5\n\
207207+ \ 62f8ead2 522c6b7b"
208208+ ~ctr:"f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"
209209+ ~out:
210210+ "1abc9324 17521ca2 4f2b0459 fe7e6e0b\n\
211211+ \ 090339ec 0aa6faef d5ccc2c6 f4ce8e94\n\
212212+ \ 1e36b26b d1ebc670 d1bd1d66 5620abf7\n\
213213+ \ 4f78a7f6 d2980958 5a97daec 58c6b050"
214214+ ~ctr1:"f0f1f2f3 f4f5f6f7 f8f9fafb fcfdff03";
215215+ case
216216+ ~key:
217217+ "603deb10 15ca71be 2b73aef0 857d7781\n\
218218+ \ 1f352c07 3b6108d7 2d9810a3 0914dff4"
219219+ ~ctr:"f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"
220220+ ~out:
221221+ "601ec313 775789a5 b7a7f504 bbf3d228\n\
222222+ \ f443e3ca 4d62b59a ca84e990 cacaf5c5\n\
223223+ \ 2b0930da a23de94c e87017ba 2d84988d\n\
224224+ \ dfc9c58d b67aada6 13c2dd08 457941a6"
225225+ ~ctr1:"f0f1f2f3 f4f5f6f7 f8f9fafb fcfdff03";
226226+ case ~key:"00010203 04050607 08090a0b 0c0d0e0f" (* ctr rollover *)
227227+ ~ctr:"00000000 00000000 ffffffff fffffffe"
228228+ ~out:
229229+ "5d0a5645 378f579a 988ff186 d42eaa2f\n\
230230+ \ 978a655d 145bfe34 21656c8f 01101a43\n\
231231+ \ 23d0862c 47f7e3bf 95586ba4 2ab4cb31\n\
232232+ \ 790b0d01 93c0d022 3469534e 537ce82d"
233233+ ~ctr1:"00000000 00000001 00000000 00000002";
211234 ]
212235213236(* aes gcm *)
214237215238let gcm_cases =
216239 let case ~key ~p ~a ~nonce ~c ~t =
217217- (AES.GCM.of_secret (vx key), vx p, vx a, vx nonce, vx c, vx t) in
240240+ (AES.GCM.of_secret (vx key), vx p, vx a, vx nonce, vx c, vx t)
241241+ in
218242219243 let check (key, p, adata, nonce, c, t) _ =
220244 let cipher = AES.GCM.authenticate_encrypt ~key ~nonce ~adata p in
···223247 | None -> assert_failure "GCM decryption broken"
224248 | Some data -> data
225249 in
226226- assert_oct_equal ~msg:"ciphertext" (c ^ t) cipher ;
250250+ assert_oct_equal ~msg:"ciphertext" (c ^ t) cipher;
227251 assert_oct_equal ~msg:"decrypted plaintext" p pdata
228252 in
229253230230- cases_of check [
231231-232232- case ~key: "00000000000000000000000000000000"
233233- ~p: ""
234234- ~a: ""
235235- ~nonce: "000000000000000000000000"
236236- ~c: ""
237237- ~t: "58e2fccefa7e3061367f1d57a4e7455a" ;
238238- case ~key: "00000000000000000000000000000000"
239239- ~p: "00000000000000000000000000000000"
240240- ~a: ""
241241- ~nonce: "000000000000000000000000"
242242- ~c: "0388dace60b6a392f328c2b971b2fe78"
243243- ~t: "ab6e47d42cec13bdf53a67b21257bddf" ;
244244- case ~key: "feffe9928665731c6d6a8f9467308308"
245245- ~p: "d9313225f88406e5a55909c5aff5269a
246246- 86a7a9531534f7da2e4c303d8a318a72
247247- 1c3c0c95956809532fcf0e2449a6b525
248248- b16aedf5aa0de657ba637b391aafd255"
249249- ~a: ""
250250- ~nonce: "cafebabefacedbaddecaf888"
251251- ~c: "42831ec2217774244b7221b784d0d49c
252252- e3aa212f2c02a4e035c17e2329aca12e
253253- 21d514b25466931c7d8f6a5aac84aa05
254254- 1ba30b396a0aac973d58e091473f5985"
255255- ~t: "4d5c2af327cd64a62cf35abd2ba6fab4" ;
256256- case ~key: "feffe9928665731c6d6a8f9467308308"
257257- ~p: "d9313225f88406e5a55909c5aff5269a
258258- 86a7a9531534f7da2e4c303d8a318a72
259259- 1c3c0c95956809532fcf0e2449a6b525
260260- b16aedf5aa0de657ba637b39"
261261- ~a: "feedfacedeadbeeffeedfacedeadbeef
262262- abaddad2"
263263- ~nonce: "cafebabefacedbaddecaf888"
264264- ~c: "42831ec2217774244b7221b784d0d49c
265265- e3aa212f2c02a4e035c17e2329aca12e
266266- 21d514b25466931c7d8f6a5aac84aa05
267267- 1ba30b396a0aac973d58e091"
268268- ~t: "5bc94fbc3221a5db94fae95ae7121a47" ;
269269- case ~key: "feffe9928665731c6d6a8f9467308308"
270270- ~p: "d9313225f88406e5a55909c5aff5269a
271271- 86a7a9531534f7da2e4c303d8a318a72
272272- 1c3c0c95956809532fcf0e2449a6b525
273273- b16aedf5aa0de657ba637b39"
274274- ~a: "feedfacedeadbeeffeedfacedeadbeef
275275- abaddad2"
276276- ~nonce: "cafebabefacedbad"
277277- ~c: "61353b4c2806934a777ff51fa22a4755
278278- 699b2a714fcdc6f83766e5f97b6c7423
279279- 73806900e49f24b22b097544d4896b42
280280- 4989b5e1ebac0f07c23f4598"
281281- ~t: "3612d2e79e3b0785561be14aaca2fccb" ;
282282- case ~key: "feffe9928665731c6d6a8f9467308308"
283283- ~p: "d9313225f88406e5a55909c5aff5269a
284284- 86a7a9531534f7da2e4c303d8a318a72
285285- 1c3c0c95956809532fcf0e2449a6b525
286286- b16aedf5aa0de657ba637b39"
287287- ~a: "feedfacedeadbeeffeedfacedeadbeef
288288- abaddad2"
289289- ~nonce: "9313225df88406e555909c5aff5269aa
290290- 6a7a9538534f7da1e4c303d2a318a728
291291- c3c0c95156809539fcf0e2429a6b5254
292292- 16aedbf5a0de6a57a637b39b"
293293- ~c: "8ce24998625615b603a033aca13fb894
294294- be9112a5c3a211a8ba262a3cca7e2ca7
295295- 01e4a9a4fba43c90ccdcb281d48c7c6f
296296- d62875d2aca417034c34aee5"
297297- ~t: "619cc5aefffe0bfa462af43c1699d050" ;
298298- case ~key: "feffe9928665731c6d6a8f9467308308
299299- feffe9928665731c"
300300- ~p: "d9313225f88406e5a55909c5aff5269a
301301- 86a7a9531534f7da2e4c303d8a318a72
302302- 1c3c0c95956809532fcf0e2449a6b525
303303- b16aedf5aa0de657ba637b39"
304304- ~a: "feedfacedeadbeeffeedfacedeadbeef
305305- abaddad2"
306306- ~nonce: "cafebabefacedbaddecaf888"
307307- ~c: "3980ca0b3c00e841eb06fac4872a2757
308308- 859e1ceaa6efd984628593b40ca1e19c
309309- 7d773d00c144c525ac619d18c84a3f47
310310- 18e2448b2fe324d9ccda2710"
311311- ~t: "2519498e80f1478f37ba55bd6d27618c" ;
312312- case ~key: "feffe9928665731c6d6a8f9467308308
313313- feffe9928665731c6d6a8f9467308308"
314314- ~p: "d9313225f88406e5a55909c5aff5269a
315315- 86a7a9531534f7da2e4c303d8a318a72
316316- 1c3c0c95956809532fcf0e2449a6b525
317317- b16aedf5aa0de657ba637b39"
318318- ~a: "feedfacedeadbeeffeedfacedeadbeef
319319- abaddad2"
320320- ~nonce: "9313225df88406e555909c5aff5269aa
321321- 6a7a9538534f7da1e4c303d2a318a728
322322- c3c0c95156809539fcf0e2429a6b5254
323323- 16aedbf5a0de6a57a637b39b"
324324- ~c: "5a8def2f0c9e53f1f75d7853659e2a20
325325- eeb2b22aafde6419a058ab4f6f746bf4
326326- 0fc0c3b780f244452da3ebf1c5d82cde
327327- a2418997200ef82e44ae7e3f"
328328- ~t: "a44a8266ee1c8eb0c8b5d4cf5ae9f19a";
329329- case ~key: "00000000000000000000000000000000" (* large GHASH batch *)
330330- ~p: ""
331331- ~a: "f0f0f0f0f0f0f0f00f0f0f0f0f0f0f0f
332332- e0e0e0e0e0e0e0e00e0e0e0e0e0e0e0e
333333- d0d0d0d0d0d0d0d00d0d0d0d0d0d0d0d
334334- c0c0c0c0c0c0c0c00c0c0c0c0c0c0c0c
335335- b0b0b0b0b0b0b0b00b0b0b0b0b0b0b0b
336336- a0a0a0a0a0a0a0a00a0a0a0a0a0a0a0a
337337- 90909090909090900909090909090909
338338- 80808080808080800808080808080808
339339- 70707070707070700707070707070707
340340- 60606060606060600606060606060606
341341- 50505050505050500505050505050505
342342- 40404040404040400404040404040404
343343- 30303030303030300303030303030303
344344- 20202020202020200202020202020202
345345- 10101010101010100101010101010101
346346- 00000000000000000000000000000000
347347- ff"
348348- ~nonce: "000000000000000000000000"
349349- ~c: ""
350350- ~t: "9bfdb8fdac1be65739780c41703c0fb6";
351351- case ~key: "00000000000000000000000000000002" (* ctr rollover *)
352352- ~nonce: "3222415d"
353353- ~p: "deadbeefdeadbeefdeadbeefdeadbeef
354354- deadbeefdeadbeefdeadbeefdeadbeef
355355- deadbeef"
356356- ~a: ""
357357- ~c: "42627ce3de61b5c105c7f01629c031c1
358358- b890bb273b6b6bc26b56c801f87fa95c
359359- a8b37503"
360360- ~t: "3631cbe44782713b93b1c7d93c3c8638"
361361-]
362362-254254+ cases_of check
255255+ [
256256+ case ~key:"00000000000000000000000000000000" ~p:"" ~a:""
257257+ ~nonce:"000000000000000000000000" ~c:""
258258+ ~t:"58e2fccefa7e3061367f1d57a4e7455a";
259259+ case ~key:"00000000000000000000000000000000"
260260+ ~p:"00000000000000000000000000000000" ~a:""
261261+ ~nonce:"000000000000000000000000" ~c:"0388dace60b6a392f328c2b971b2fe78"
262262+ ~t:"ab6e47d42cec13bdf53a67b21257bddf";
263263+ case ~key:"feffe9928665731c6d6a8f9467308308"
264264+ ~p:
265265+ "d9313225f88406e5a55909c5aff5269a\n\
266266+ \ 86a7a9531534f7da2e4c303d8a318a72\n\
267267+ \ 1c3c0c95956809532fcf0e2449a6b525\n\
268268+ \ b16aedf5aa0de657ba637b391aafd255"
269269+ ~a:"" ~nonce:"cafebabefacedbaddecaf888"
270270+ ~c:
271271+ "42831ec2217774244b7221b784d0d49c\n\
272272+ \ e3aa212f2c02a4e035c17e2329aca12e\n\
273273+ \ 21d514b25466931c7d8f6a5aac84aa05\n\
274274+ \ 1ba30b396a0aac973d58e091473f5985"
275275+ ~t:"4d5c2af327cd64a62cf35abd2ba6fab4";
276276+ case ~key:"feffe9928665731c6d6a8f9467308308"
277277+ ~p:
278278+ "d9313225f88406e5a55909c5aff5269a\n\
279279+ \ 86a7a9531534f7da2e4c303d8a318a72\n\
280280+ \ 1c3c0c95956809532fcf0e2449a6b525\n\
281281+ \ b16aedf5aa0de657ba637b39"
282282+ ~a:"feedfacedeadbeeffeedfacedeadbeef\n abaddad2"
283283+ ~nonce:"cafebabefacedbaddecaf888"
284284+ ~c:
285285+ "42831ec2217774244b7221b784d0d49c\n\
286286+ \ e3aa212f2c02a4e035c17e2329aca12e\n\
287287+ \ 21d514b25466931c7d8f6a5aac84aa05\n\
288288+ \ 1ba30b396a0aac973d58e091"
289289+ ~t:"5bc94fbc3221a5db94fae95ae7121a47";
290290+ case ~key:"feffe9928665731c6d6a8f9467308308"
291291+ ~p:
292292+ "d9313225f88406e5a55909c5aff5269a\n\
293293+ \ 86a7a9531534f7da2e4c303d8a318a72\n\
294294+ \ 1c3c0c95956809532fcf0e2449a6b525\n\
295295+ \ b16aedf5aa0de657ba637b39"
296296+ ~a:"feedfacedeadbeeffeedfacedeadbeef\n abaddad2"
297297+ ~nonce:"cafebabefacedbad"
298298+ ~c:
299299+ "61353b4c2806934a777ff51fa22a4755\n\
300300+ \ 699b2a714fcdc6f83766e5f97b6c7423\n\
301301+ \ 73806900e49f24b22b097544d4896b42\n\
302302+ \ 4989b5e1ebac0f07c23f4598"
303303+ ~t:"3612d2e79e3b0785561be14aaca2fccb";
304304+ case ~key:"feffe9928665731c6d6a8f9467308308"
305305+ ~p:
306306+ "d9313225f88406e5a55909c5aff5269a\n\
307307+ \ 86a7a9531534f7da2e4c303d8a318a72\n\
308308+ \ 1c3c0c95956809532fcf0e2449a6b525\n\
309309+ \ b16aedf5aa0de657ba637b39"
310310+ ~a:"feedfacedeadbeeffeedfacedeadbeef\n abaddad2"
311311+ ~nonce:
312312+ "9313225df88406e555909c5aff5269aa\n\
313313+ \ 6a7a9538534f7da1e4c303d2a318a728\n\
314314+ \ c3c0c95156809539fcf0e2429a6b5254\n\
315315+ \ 16aedbf5a0de6a57a637b39b"
316316+ ~c:
317317+ "8ce24998625615b603a033aca13fb894\n\
318318+ \ be9112a5c3a211a8ba262a3cca7e2ca7\n\
319319+ \ 01e4a9a4fba43c90ccdcb281d48c7c6f\n\
320320+ \ d62875d2aca417034c34aee5"
321321+ ~t:"619cc5aefffe0bfa462af43c1699d050";
322322+ case
323323+ ~key:
324324+ "feffe9928665731c6d6a8f9467308308\n feffe9928665731c"
325325+ ~p:
326326+ "d9313225f88406e5a55909c5aff5269a\n\
327327+ \ 86a7a9531534f7da2e4c303d8a318a72\n\
328328+ \ 1c3c0c95956809532fcf0e2449a6b525\n\
329329+ \ b16aedf5aa0de657ba637b39"
330330+ ~a:"feedfacedeadbeeffeedfacedeadbeef\n abaddad2"
331331+ ~nonce:"cafebabefacedbaddecaf888"
332332+ ~c:
333333+ "3980ca0b3c00e841eb06fac4872a2757\n\
334334+ \ 859e1ceaa6efd984628593b40ca1e19c\n\
335335+ \ 7d773d00c144c525ac619d18c84a3f47\n\
336336+ \ 18e2448b2fe324d9ccda2710"
337337+ ~t:"2519498e80f1478f37ba55bd6d27618c";
338338+ case
339339+ ~key:
340340+ "feffe9928665731c6d6a8f9467308308\n\
341341+ \ feffe9928665731c6d6a8f9467308308"
342342+ ~p:
343343+ "d9313225f88406e5a55909c5aff5269a\n\
344344+ \ 86a7a9531534f7da2e4c303d8a318a72\n\
345345+ \ 1c3c0c95956809532fcf0e2449a6b525\n\
346346+ \ b16aedf5aa0de657ba637b39"
347347+ ~a:"feedfacedeadbeeffeedfacedeadbeef\n abaddad2"
348348+ ~nonce:
349349+ "9313225df88406e555909c5aff5269aa\n\
350350+ \ 6a7a9538534f7da1e4c303d2a318a728\n\
351351+ \ c3c0c95156809539fcf0e2429a6b5254\n\
352352+ \ 16aedbf5a0de6a57a637b39b"
353353+ ~c:
354354+ "5a8def2f0c9e53f1f75d7853659e2a20\n\
355355+ \ eeb2b22aafde6419a058ab4f6f746bf4\n\
356356+ \ 0fc0c3b780f244452da3ebf1c5d82cde\n\
357357+ \ a2418997200ef82e44ae7e3f"
358358+ ~t:"a44a8266ee1c8eb0c8b5d4cf5ae9f19a";
359359+ case ~key:"00000000000000000000000000000000" (* large GHASH batch *) ~p:""
360360+ ~a:
361361+ "f0f0f0f0f0f0f0f00f0f0f0f0f0f0f0f\n\
362362+ \ e0e0e0e0e0e0e0e00e0e0e0e0e0e0e0e\n\
363363+ \ d0d0d0d0d0d0d0d00d0d0d0d0d0d0d0d\n\
364364+ \ c0c0c0c0c0c0c0c00c0c0c0c0c0c0c0c\n\
365365+ \ b0b0b0b0b0b0b0b00b0b0b0b0b0b0b0b\n\
366366+ \ a0a0a0a0a0a0a0a00a0a0a0a0a0a0a0a\n\
367367+ \ 90909090909090900909090909090909\n\
368368+ \ 80808080808080800808080808080808\n\
369369+ \ 70707070707070700707070707070707\n\
370370+ \ 60606060606060600606060606060606\n\
371371+ \ 50505050505050500505050505050505\n\
372372+ \ 40404040404040400404040404040404\n\
373373+ \ 30303030303030300303030303030303\n\
374374+ \ 20202020202020200202020202020202\n\
375375+ \ 10101010101010100101010101010101\n\
376376+ \ 00000000000000000000000000000000\n\
377377+ \ ff"
378378+ ~nonce:"000000000000000000000000" ~c:""
379379+ ~t:"9bfdb8fdac1be65739780c41703c0fb6";
380380+ case ~key:"00000000000000000000000000000002" (* ctr rollover *)
381381+ ~nonce:"3222415d"
382382+ ~p:
383383+ "deadbeefdeadbeefdeadbeefdeadbeef\n\
384384+ \ deadbeefdeadbeefdeadbeefdeadbeef\n\
385385+ \ deadbeef"
386386+ ~a:""
387387+ ~c:
388388+ "42627ce3de61b5c105c7f01629c031c1\n\
389389+ \ b890bb273b6b6bc26b56c801f87fa95c\n\
390390+ \ a8b37503"
391391+ ~t:"3631cbe44782713b93b1c7d93c3c8638";
392392+ ]
363393364394(*
365395(* from SP800-38C_updated-July20_2007.pdf appendix C *)
···408438 (* see RFC 3610 Section 2.1, AD of length 0 should be same as no AD *)
409439 let key = of_secret (vx "000102030405060708090a0b0c0d0e0f")
410440 and nonce = vx "0001020304050607"
411411- and plaintext = "hello"
412412- in
441441+ and plaintext = "hello" in
413442 assert_oct_equal ~msg:"CCM no vs empty ad"
414443 (authenticate_encrypt ~key ~nonce plaintext)
415444 (authenticate_encrypt ~adata:"" ~key ~nonce plaintext)
···419448 (* see RFC3610 Section 2.1 *)
420449 let key = of_secret (vx "000102030405060708090a0b0c0d0e0f")
421450 and nonce = ""
422422- and plaintext = "hello"
423423- in
451451+ and plaintext = "hello" in
424452 assert_raises ~msg:"CCM with short nonce raises"
425453 (Invalid_argument "Crypto: CCM: nonce length not between 7 and 13: 0")
426454 (fun () -> authenticate_encrypt ~key ~nonce plaintext)
427455 and short_nonce_enc2 _ =
428456 let key = of_secret (vx "000102030405060708090a0b0c0d0e0f")
429457 and nonce = vx "00"
430430- and plaintext = "hello"
431431- in
458458+ and plaintext = "hello" in
432459 assert_raises ~msg:"CCM with short nonce raises"
433460 (Invalid_argument "Crypto: CCM: nonce length not between 7 and 13: 1")
434461 (fun () -> authenticate_encrypt ~key ~nonce plaintext)
435462 and short_nonce_enc3 _ =
436463 let key = of_secret (vx "000102030405060708090a0b0c0d0e0f")
437464 and nonce = vx "000102030405"
438438- and plaintext = "hello"
439439- in
465465+ and plaintext = "hello" in
440466 assert_raises ~msg:"CCM with short nonce raises"
441467 (Invalid_argument "Crypto: CCM: nonce length not between 7 and 13: 6")
442468 (fun () -> authenticate_encrypt ~key ~nonce plaintext)
443469 and long_nonce_enc _ =
444470 let key = of_secret (vx "000102030405060708090a0b0c0d0e0f")
445471 and nonce = vx "000102030405060708090a0b0c0d"
446446- and plaintext = "hello"
447447- in
472472+ and plaintext = "hello" in
448473 assert_raises ~msg:"CCM with short nonce raises"
449474 (Invalid_argument "Crypto: CCM: nonce length not between 7 and 13: 14")
450475 (fun () -> authenticate_encrypt ~key ~nonce plaintext)
···453478 let key = of_secret (vx "000102030405060708090a0b0c0d0e0f")
454479 and nonce = vx "0001020304050607"
455480 and adata = "hello"
456456- and p = ""
457457- in
481481+ and p = "" in
458482 let cipher = authenticate_encrypt ~adata ~key ~nonce p in
459483 match authenticate_decrypt ~key ~nonce ~adata cipher with
460484 | Some x -> assert_oct_equal ~msg:"CCM decrypt of empty message" p x
···465489 and plaintext = "hello"
466490 (* [adata] is greater than [1 lsl 16 - 1 lsl 8] *)
467491 and adata = String.make 65280 '\x00'
468468- and expected = vx "6592169e946f98973bc06d080f7c9dbb493a536f8a"
469469- in
492492+ and expected = vx "6592169e946f98973bc06d080f7c9dbb493a536f8a" in
470493 let cipher = authenticate_encrypt ~adata ~key ~nonce plaintext in
471494 assert_oct_equal ~msg:"CCM encrypt of >=65280 adata" expected cipher
472495 in
···476499 let nonce = vx "81cd 4758 1880 9de0 c655 7c31"
477500 and adata = vx "1703 0300 17"
478501 and data = vx "0800 0002 0000 16"
479479- and expected = vx "94ca 065a c948 c5d6 92fd 5fab c850 0611 a07c 4f6e 0710 90"
502502+ and expected =
503503+ vx "94ca 065a c948 c5d6 92fd 5fab c850 0611 a07c 4f6e 0710 90"
480504 in
481505 let a _ =
482506 let cipher = authenticate_encrypt ~adata ~key ~nonce data in
···488512 in
489513 let nonce = vx "81cd 4758 1880 9de0 c655 7c30"
490514 and adata = vx "1703 0302 85"
491491- and data = vx {|
515515+ and data =
516516+ vx
517517+ {|
4925180b00 0270 0000 026c 0002 6730 8202 6330
4935198201 cc02 0900 cb6c 4e84 4b58 a1d4 300d
494520|}
495495- and expected = vx {|
521521+ and expected =
522522+ vx
523523+ {|
4965241e59 904e e6d5 c2ac e538 78d7 e24f 6e46
4975256169 f8e2 d3dd 8b5d 788c 78ff ea9f e1d0
4985269885 ac1a c6d9 fb88 b66a 3a11 5ba5 6e7c
···506534 | None -> assert_failure "TLS regression 1, decrypt broken"
507535 | Some x -> assert_oct_equal ~msg:"TLS regression 1 decrypt" x data
508536 in
509509- let data = vx {|
537537+ let data =
538538+ vx
539539+ {|
5105400b00 0270 0000 026c 0002 6730 8202 6330
5115418201 cc02 0900 cb6c 4e84 4b58 a1d4 300d
5125428201 cc02 0900
513543|}
514514- and expected = vx {|
544544+ and expected =
545545+ vx
546546+ {|
5155471e59 904e e6d5 c2ac e538 78d7 e24f 6e46
5165486169 f8e2 d3dd 8b5d 788c 78ff ea9f e1d0
5175497c8d 9993 6bfd cf76 9799 473b 58f4 ed69
···526558 | None -> assert_failure "TLS regression 2, decrypt broken"
527559 | Some x -> assert_oct_equal ~msg:"TLS regression 2 decrypt" x data
528560 in
529529- let data = vx {|
561561+ let data =
562562+ vx
563563+ {|
5305640b00 0270 0000 026c 0002 6730 8202 6330
5315658201 cc02 0900 cb6c 4e84 4b58 a1d4 300d
5325660609 2a86 4886 f70d 0101 0505 0030 7631
···5686021be5 55f8 7083 4e09 4d41 cf9f 74b3 342e
5696038345 0000 16
570604 |}
571571- and expected = vx {|
605605+ and expected =
606606+ vx
607607+ {|
5726081e59 904e e6d5 c2ac e538 78d7 e24f 6e46
5736096169 f8e2 d3dd 8b5d 788c 78ff ea9f e1d0
574610f885 7f17 2a7b f163 d29e 0a8e 8636 418f
···620656 | None -> assert_failure "TLS regression 3, decrypt broken"
621657 | Some x -> assert_oct_equal ~msg:"TLS regression 3 decrypt" x data
622658 in
623623- [ a ; b ; c ; d ; e ; f ; g ; h ]
659659+ [ a; b; c; d; e; f; g; h ]
624660 in
625661 [
626626- test_case no_vs_empty_ad ;
627627- test_case short_nonce_enc ;
628628- test_case short_nonce_enc2 ;
629629- test_case short_nonce_enc3 ;
630630- test_case long_nonce_enc ;
631631- test_case enc_dec_empty_message ;
632632- test_case long_adata ;
633633- ] @ List.map test_case regr_tls
662662+ test_case no_vs_empty_ad;
663663+ test_case short_nonce_enc;
664664+ test_case short_nonce_enc2;
665665+ test_case short_nonce_enc3;
666666+ test_case long_nonce_enc;
667667+ test_case enc_dec_empty_message;
668668+ test_case long_adata;
669669+ ]
670670+ @ List.map test_case regr_tls
634671635672let gcm_regressions =
636673 let open AES.GCM in
637674 let msg = vx "000102030405060708090a0b0c0d0e0f" in
638638- let key = of_secret msg
639639- and nonce = ""
640640- in
675675+ let key = of_secret msg and nonce = "" in
641676 let nonce_zero_length_enc _ =
642677 (* reported in https://github.com/mirleft/ocaml-nocrypto/issues/169 *)
643678 assert_raises ~msg:"GCM with nonce of length 0"
644644- (Invalid_argument "Crypto: GCM: invalid nonce of length 0")
645645- (fun () -> authenticate_encrypt ~key ~nonce msg)
679679+ (Invalid_argument "Crypto: GCM: invalid nonce of length 0") (fun () ->
680680+ authenticate_encrypt ~key ~nonce msg)
646681 and nonce_zero_length_dec _ =
647682 assert_raises ~msg:"GCM with nonce of 0"
648648- (Invalid_argument "Crypto: GCM: invalid nonce of length 0")
649649- (fun () -> authenticate_decrypt ~key ~nonce msg)
683683+ (Invalid_argument "Crypto: GCM: invalid nonce of length 0") (fun () ->
684684+ authenticate_decrypt ~key ~nonce msg)
650685 in
651651- [
652652- test_case nonce_zero_length_enc ;
653653- test_case nonce_zero_length_dec ;
654654- ]
655655-686686+ [ test_case nonce_zero_length_enc; test_case nonce_zero_length_dec ]
656687657688let chacha20_cases =
658689 let case msg ?ctr ~key ~nonce ?(input = String.make 128 '\000') output =
659690 let key = Chacha20.of_secret (vx key)
660691 and nonce = vx nonce
661661- and output = vx output
662662- in
692692+ and output = vx output in
663693 assert_oct_equal ~msg (Chacha20.crypt ~key ~nonce ?ctr input) output
664694 in
665665- let rfc8439_input = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it." in
695695+ let rfc8439_input =
696696+ "Ladies and Gentlemen of the class of '99: If I could offer you only one \
697697+ tip for the future, sunscreen would be it."
698698+ in
666699 let rfc8439_test_2_4_2 _ =
667700 let key = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
668701 and nonce = "000000000000004a00000000"
669702 and output =
670670-{|6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81
703703+ {|6e 2e 35 9a 25 68 f9 80 41 ba 07 28 dd 0d 69 81
671704 e9 7e 7a ec 1d 43 60 c2 0a 27 af cc fd 9f ae 0b
672705 f9 1b 65 c5 52 47 33 ab 8f 59 3d ab cd 62 b3 57
673706 16 39 d6 24 e6 51 52 ab 8f 53 0c 35 9f 08 61 d8
···676709 5a f9 0b bf 74 a3 5b e6 b4 0b 8e ed f2 78 5e 42
677710 87 4d|}
678711 in
679679- case "Chacha20 RFC 8439 2.4.2" ~ctr:1L ~key ~nonce ~input:rfc8439_input output
712712+ case "Chacha20 RFC 8439 2.4.2" ~ctr:1L ~key ~nonce ~input:rfc8439_input
713713+ output
680714 and rfc8439_test_2_8_2 _ =
681681- let key = Chacha20.of_secret (vx "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
715715+ let key =
716716+ Chacha20.of_secret
717717+ (vx "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
682718 and adata = vx "50515253c0c1c2c3c4c5c6c7"
683719 and nonce = vx "0700000040 41424344454647"
684684- and output = vx {|
720720+ and output =
721721+ vx
722722+ {|
685723 d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c2
686724 a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6
687725 3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b
···697735 output;
698736 assert_oct_equal ~msg:"Chacha20/Poly1305 RFC 8439 2.8.2 decrypt"
699737 (match Chacha20.authenticate_decrypt ~key ~nonce ~adata output with
700700- | Some cs -> cs | None -> assert_failure "Chacha20/poly1305 decryption broken")
701701- rfc8439_input;
738738+ | Some cs -> cs
739739+ | None -> assert_failure "Chacha20/poly1305 decryption broken")
740740+ rfc8439_input
702741 in
703742 (* from https://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01 *)
704743 let case ~key ~nonce ~output0 ~output1 _ =
···706745 in
707746 List.map test_case
708747 [
709709- rfc8439_test_2_4_2 ;
710710-711711- rfc8439_test_2_8_2 ;
712712-713713- case
714714- ~key:(String.make 64 '0')
715715- ~nonce:(String.make 16 '0')
716716- ~output0:("76b8e0ada0f13d90405d6ae55386bd28" ^
717717- "bdd219b8a08ded1aa836efcc8b770dc7" ^
718718- "da41597c5157488d7724e03fb8d84a37" ^
719719- "6a43b8f41518a11cc387b669b2ee6586")
720720- ~output1:("9f07e7be5551387a98ba977c732d080d" ^
721721- "cb0f29a048e3656912c6533e32ee7aed" ^
722722- "29b721769ce64e43d57133b074d839d5" ^
723723- "31ed1f28510afb45ace10a1f4b794d6f") ;
724724-748748+ rfc8439_test_2_4_2;
749749+ rfc8439_test_2_8_2;
750750+ case ~key:(String.make 64 '0') ~nonce:(String.make 16 '0')
751751+ ~output0:
752752+ ("76b8e0ada0f13d90405d6ae55386bd28"
753753+ ^ "bdd219b8a08ded1aa836efcc8b770dc7"
754754+ ^ "da41597c5157488d7724e03fb8d84a37"
755755+ ^ "6a43b8f41518a11cc387b669b2ee6586")
756756+ ~output1:
757757+ ("9f07e7be5551387a98ba977c732d080d"
758758+ ^ "cb0f29a048e3656912c6533e32ee7aed"
759759+ ^ "29b721769ce64e43d57133b074d839d5"
760760+ ^ "31ed1f28510afb45ace10a1f4b794d6f");
725761 case
726762 ~key:("01" ^ String.make 62 '0')
727763 ~nonce:(String.make 16 '0')
728728- ~output0:("c5d30a7ce1ec119378c84f487d775a85" ^
729729- "42f13ece238a9455e8229e888de85bbd" ^
730730- "29eb63d0a17a5b999b52da22be4023eb" ^
731731- "07620a54f6fa6ad8737b71eb0464dac0")
732732- ~output1:("10f656e6d1fd55053e50c4875c9930a3" ^
733733- "3f6d0263bd14dfd6ab8c70521c19338b" ^
734734- "2308b95cf8d0bb7d202d2102780ea352" ^
735735- "8f1cb48560f76b20f382b942500fceac") ;
736736-737737- case
738738- ~key:(String.make 64 '0')
764764+ ~output0:
765765+ ("c5d30a7ce1ec119378c84f487d775a85"
766766+ ^ "42f13ece238a9455e8229e888de85bbd"
767767+ ^ "29eb63d0a17a5b999b52da22be4023eb"
768768+ ^ "07620a54f6fa6ad8737b71eb0464dac0")
769769+ ~output1:
770770+ ("10f656e6d1fd55053e50c4875c9930a3"
771771+ ^ "3f6d0263bd14dfd6ab8c70521c19338b"
772772+ ^ "2308b95cf8d0bb7d202d2102780ea352"
773773+ ^ "8f1cb48560f76b20f382b942500fceac");
774774+ case ~key:(String.make 64 '0')
739775 ~nonce:("01" ^ String.make 14 '0')
740740- ~output0:("ef3fdfd6c61578fbf5cf35bd3dd33b80" ^
741741- "09631634d21e42ac33960bd138e50d32" ^
742742- "111e4caf237ee53ca8ad6426194a8854" ^
743743- "5ddc497a0b466e7d6bbdb0041b2f586b")
744744- ~output1:("5305e5e44aff19b235936144675efbe4" ^
745745- "409eb7e8e5f1430f5f5836aeb49bb532" ^
746746- "8b017c4b9dc11f8a03863fa803dc71d5" ^
747747- "726b2b6b31aa32708afe5af1d6b69058") ;
748748-749749- case
750750- ~key:(String.make 64 'f')
751751- ~nonce:(String.make 16 'f')
752752- ~output0:("d9bf3f6bce6ed0b54254557767fb5744" ^
753753- "3dd4778911b606055c39cc25e674b836" ^
754754- "3feabc57fde54f790c52c8ae43240b79" ^
755755- "d49042b777bfd6cb80e931270b7f50eb")
756756- ~output1:("5bac2acd86a836c5dc98c116c1217ec3" ^
757757- "1d3a63a9451319f097f3b4d6dab07787" ^
758758- "19477d24d24b403a12241d7cca064f79" ^
759759- "0f1d51ccaff6b1667d4bbca1958c4306") ;
760760-761761- case
762762- ~key:(String.make 64 '5')
763763- ~nonce:(String.make 16 '5')
764764- ~output0:("bea9411aa453c5434a5ae8c92862f564" ^
765765- "396855a9ea6e22d6d3b50ae1b3663311" ^
766766- "a4a3606c671d605ce16c3aece8e61ea1" ^
767767- "45c59775017bee2fa6f88afc758069f7")
768768- ~output1:("e0b8f676e644216f4d2a3422d7fa36c6" ^
769769- "c4931aca950e9da42788e6d0b6d1cd83" ^
770770- "8ef652e97b145b14871eae6c6804c700" ^
771771- "4db5ac2fce4c68c726d004b10fcaba86") ;
772772-773773- case
774774- ~key:(String.make 64 'a')
775775- ~nonce:(String.make 16 'a')
776776- ~output0:("9aa2a9f656efde5aa7591c5fed4b35ae" ^
777777- "a2895dec7cb4543b9e9f21f5e7bcbcf3" ^
778778- "c43c748a970888f8248393a09d43e0b7" ^
779779- "e164bc4d0b0fb240a2d72115c4808906")
780780- ~output1:("72184489440545d021d97ef6b693dfe5" ^
781781- "b2c132d47e6f041c9063651f96b623e6" ^
782782- "2a11999a23b6f7c461b2153026ad5e86" ^
783783- "6a2e597ed07b8401dec63a0934c6b2a9") ;
784784-776776+ ~output0:
777777+ ("ef3fdfd6c61578fbf5cf35bd3dd33b80"
778778+ ^ "09631634d21e42ac33960bd138e50d32"
779779+ ^ "111e4caf237ee53ca8ad6426194a8854"
780780+ ^ "5ddc497a0b466e7d6bbdb0041b2f586b")
781781+ ~output1:
782782+ ("5305e5e44aff19b235936144675efbe4"
783783+ ^ "409eb7e8e5f1430f5f5836aeb49bb532"
784784+ ^ "8b017c4b9dc11f8a03863fa803dc71d5"
785785+ ^ "726b2b6b31aa32708afe5af1d6b69058");
786786+ case ~key:(String.make 64 'f') ~nonce:(String.make 16 'f')
787787+ ~output0:
788788+ ("d9bf3f6bce6ed0b54254557767fb5744"
789789+ ^ "3dd4778911b606055c39cc25e674b836"
790790+ ^ "3feabc57fde54f790c52c8ae43240b79"
791791+ ^ "d49042b777bfd6cb80e931270b7f50eb")
792792+ ~output1:
793793+ ("5bac2acd86a836c5dc98c116c1217ec3"
794794+ ^ "1d3a63a9451319f097f3b4d6dab07787"
795795+ ^ "19477d24d24b403a12241d7cca064f79"
796796+ ^ "0f1d51ccaff6b1667d4bbca1958c4306");
797797+ case ~key:(String.make 64 '5') ~nonce:(String.make 16 '5')
798798+ ~output0:
799799+ ("bea9411aa453c5434a5ae8c92862f564"
800800+ ^ "396855a9ea6e22d6d3b50ae1b3663311"
801801+ ^ "a4a3606c671d605ce16c3aece8e61ea1"
802802+ ^ "45c59775017bee2fa6f88afc758069f7")
803803+ ~output1:
804804+ ("e0b8f676e644216f4d2a3422d7fa36c6"
805805+ ^ "c4931aca950e9da42788e6d0b6d1cd83"
806806+ ^ "8ef652e97b145b14871eae6c6804c700"
807807+ ^ "4db5ac2fce4c68c726d004b10fcaba86");
808808+ case ~key:(String.make 64 'a') ~nonce:(String.make 16 'a')
809809+ ~output0:
810810+ ("9aa2a9f656efde5aa7591c5fed4b35ae"
811811+ ^ "a2895dec7cb4543b9e9f21f5e7bcbcf3"
812812+ ^ "c43c748a970888f8248393a09d43e0b7"
813813+ ^ "e164bc4d0b0fb240a2d72115c4808906")
814814+ ~output1:
815815+ ("72184489440545d021d97ef6b693dfe5"
816816+ ^ "b2c132d47e6f041c9063651f96b623e6"
817817+ ^ "2a11999a23b6f7c461b2153026ad5e86"
818818+ ^ "6a2e597ed07b8401dec63a0934c6b2a9");
785819 case
786820 ~key:"00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100"
787821 ~nonce:"0f1e2d3c4b5a6978"
788788- ~output0:("9fadf409c00811d00431d67efbd88fba" ^
789789- "59218d5d6708b1d685863fabbb0e961e" ^
790790- "ea480fd6fb532bfd494b215101505742" ^
791791- "3ab60a63fe4f55f7a212e2167ccab931")
792792- ~output1:("fbfd29cf7bc1d279eddf25dd316bb884" ^
793793- "3d6edee0bd1ef121d12fa17cbc2c574c" ^
794794- "ccab5e275167b08bd686f8a09df87ec3" ^
795795- "ffb35361b94ebfa13fec0e4889d18da5") ;
796796-822822+ ~output0:
823823+ ("9fadf409c00811d00431d67efbd88fba"
824824+ ^ "59218d5d6708b1d685863fabbb0e961e"
825825+ ^ "ea480fd6fb532bfd494b215101505742"
826826+ ^ "3ab60a63fe4f55f7a212e2167ccab931")
827827+ ~output1:
828828+ ("fbfd29cf7bc1d279eddf25dd316bb884"
829829+ ^ "3d6edee0bd1ef121d12fa17cbc2c574c"
830830+ ^ "ccab5e275167b08bd686f8a09df87ec3"
831831+ ^ "ffb35361b94ebfa13fec0e4889d18da5");
797832 case
798833 ~key:"c46ec1b18ce8a878725a37e780dfb7351f68ed2e194c79fbc6aebee1a667975d"
799834 ~nonce:"1ada31d5cf688221"
800800- ~output0:("f63a89b75c2271f9368816542ba52f06" ^
801801- "ed49241792302b00b5e8f80ae9a473af" ^
802802- "c25b218f519af0fdd406362e8d69de7f" ^
803803- "54c604a6e00f353f110f771bdca8ab92")
804804- ~output1:("e5fbc34e60a1d9a9db17345b0a402736" ^
805805- "853bf910b060bdf1f897b6290f01d138" ^
806806- "ae2c4c90225ba9ea14d518f55929dea0" ^
807807- "98ca7a6ccfe61227053c84e49a4a3332") ;
808808-809809- case
810810- ~key:(String.make 32 '0')
811811- ~nonce:(String.make 16 '0')
812812- ~output0:("89670952608364fd00b2f90936f031c8" ^
813813- "e756e15dba04b8493d00429259b20f46" ^
814814- "cc04f111246b6c2ce066be3bfb32d9aa" ^
815815- "0fddfbc12123d4b9e44f34dca05a103f")
816816- ~output1:("6cd135c2878c832b5896b134f6142a9d" ^
817817- "4d8d0d8f1026d20a0a81512cbce6e975" ^
818818- "8a7143d021978022a384141a80cea306" ^
819819- "2f41f67a752e66ad3411984c787e30ad") ;
820820-835835+ ~output0:
836836+ ("f63a89b75c2271f9368816542ba52f06"
837837+ ^ "ed49241792302b00b5e8f80ae9a473af"
838838+ ^ "c25b218f519af0fdd406362e8d69de7f"
839839+ ^ "54c604a6e00f353f110f771bdca8ab92")
840840+ ~output1:
841841+ ("e5fbc34e60a1d9a9db17345b0a402736"
842842+ ^ "853bf910b060bdf1f897b6290f01d138"
843843+ ^ "ae2c4c90225ba9ea14d518f55929dea0"
844844+ ^ "98ca7a6ccfe61227053c84e49a4a3332");
845845+ case ~key:(String.make 32 '0') ~nonce:(String.make 16 '0')
846846+ ~output0:
847847+ ("89670952608364fd00b2f90936f031c8"
848848+ ^ "e756e15dba04b8493d00429259b20f46"
849849+ ^ "cc04f111246b6c2ce066be3bfb32d9aa"
850850+ ^ "0fddfbc12123d4b9e44f34dca05a103f")
851851+ ~output1:
852852+ ("6cd135c2878c832b5896b134f6142a9d"
853853+ ^ "4d8d0d8f1026d20a0a81512cbce6e975"
854854+ ^ "8a7143d021978022a384141a80cea306"
855855+ ^ "2f41f67a752e66ad3411984c787e30ad");
821856 case
822857 ~key:("01" ^ String.make 30 '0')
823858 ~nonce:(String.make 16 '0')
824824- ~output0:("ae56060d04f5b597897ff2af1388dbce" ^
825825- "ff5a2a4920335dc17a3cb1b1b10fbe70" ^
826826- "ece8f4864d8c7cdf0076453a8291c7db" ^
827827- "eb3aa9c9d10e8ca36be4449376ed7c42")
828828- ~output1:("fc3d471c34a36fbbf616bc0a0e7c5230" ^
829829- "30d944f43ec3e78dd6a12466547cb4f7" ^
830830- "b3cebd0a5005e762e562d1375b7ac445" ^
831831- "93a991b85d1a60fba2035dfaa2a642d5") ;
832832-833833- case
834834- ~key:(String.make 32 '0')
859859+ ~output0:
860860+ ("ae56060d04f5b597897ff2af1388dbce"
861861+ ^ "ff5a2a4920335dc17a3cb1b1b10fbe70"
862862+ ^ "ece8f4864d8c7cdf0076453a8291c7db"
863863+ ^ "eb3aa9c9d10e8ca36be4449376ed7c42")
864864+ ~output1:
865865+ ("fc3d471c34a36fbbf616bc0a0e7c5230"
866866+ ^ "30d944f43ec3e78dd6a12466547cb4f7"
867867+ ^ "b3cebd0a5005e762e562d1375b7ac445"
868868+ ^ "93a991b85d1a60fba2035dfaa2a642d5");
869869+ case ~key:(String.make 32 '0')
835870 ~nonce:("01" ^ String.make 14 '0')
836836- ~output0:("1663879eb3f2c9949e2388caa343d361" ^
837837- "bb132771245ae6d027ca9cb010dc1fa7" ^
838838- "178dc41f8278bc1f64b3f12769a24097" ^
839839- "f40d63a86366bdb36ac08abe60c07fe8")
840840- ~output1:("b057375c89144408cc744624f69f7f4c" ^
841841- "cbd93366c92fc4dfcada65f1b959d8c6" ^
842842- "4dfc50de711fb46416c2553cc60f21bb" ^
843843- "fd006491cb17888b4fb3521c4fdd8745") ;
844844-845845- case
846846- ~key:(String.make 32 'f')
847847- ~nonce:(String.make 16 'f')
848848- ~output0:("992947c3966126a0e660a3e95db048de" ^
849849- "091fb9e0185b1e41e41015bb7ee50150" ^
850850- "399e4760b262f9d53f26d8dd19e56f5c" ^
851851- "506ae0c3619fa67fb0c408106d0203ee")
852852- ~output1:("40ea3cfa61fa32a2fda8d1238a2135d9" ^
853853- "d4178775240f99007064a6a7f0c731b6" ^
854854- "7c227c52ef796b6bed9f9059ba0614bc" ^
855855- "f6dd6e38917f3b150e576375be50ed67") ;
856856-857857- case
858858- ~key:(String.make 32 '5')
859859- ~nonce:(String.make 16 '5')
860860- ~output0:("357d7d94f966778f5815a2051dcb0413" ^
861861- "3b26b0ead9f57dd09927837bc3067e4b" ^
862862- "6bf299ad81f7f50c8da83c7810bfc17b" ^
863863- "b6f4813ab6c326957045fd3fd5e19915")
864864- ~output1:("ec744a6b9bf8cbdcb36d8b6a5499c68a" ^
865865- "08ef7be6cc1e93f2f5bcd2cad4e47c18" ^
866866- "a3e5d94b5666382c6d130d822dd56aac" ^
867867- "b0f8195278e7b292495f09868ddf12cc") ;
868868-869869- case
870870- ~key:(String.make 32 'a')
871871- ~nonce:(String.make 16 'a')
872872- ~output0:("fc79acbd58526103862776aab20f3b7d" ^
873873- "8d3149b2fab65766299316b6e5b16684" ^
874874- "de5de548c1b7d083efd9e3052319e0c6" ^
875875- "254141da04a6586df800f64d46b01c87")
876876- ~output1:("1f05bc67e07628ebe6f6865a2177e0b6" ^
877877- "6a558aa7cc1e8ff1a98d27f7071f8335" ^
878878- "efce4537bb0ef7b573b32f32765f2900" ^
879879- "7da53bba62e7a44d006f41eb28fe15d6") ;
880880-881881- case
882882- ~key:"00112233445566778899aabbccddeeff"
883883- ~nonce:"0f1e2d3c4b5a6978"
884884- ~output0:("d1abf630467eb4f67f1cfb47cd626aae" ^
885885- "8afedbbe4ff8fc5fe9cfae307e74ed45" ^
886886- "1f1404425ad2b54569d5f18148939971" ^
887887- "abb8fafc88ce4ac7fe1c3d1f7a1eb7ca")
888888- ~output1:("e76ca87b61a9713541497760dd9ae059" ^
889889- "350cad0dcedfaa80a883119a1a6f987f" ^
890890- "d1ce91fd8ee0828034b411200a9745a2" ^
891891- "85554475d12afc04887fef3516d12a2c") ;
892892-893893- case
894894- ~key:"c46ec1b18ce8a878725a37e780dfb735"
895895- ~nonce:"1ada31d5cf688221"
896896- ~output0:("826abdd84460e2e9349f0ef4af5b179b" ^
897897- "426e4b2d109a9c5bb44000ae51bea90a" ^
898898- "496beeef62a76850ff3f0402c4ddc99f" ^
899899- "6db07f151c1c0dfac2e56565d6289625")
900900- ~output1:("5b23132e7b469c7bfb88fa95d44ca5ae" ^
901901- "3e45e848a4108e98bad7a9eb15512784" ^
902902- "a6a9e6e591dce674120acaf9040ff50f" ^
903903- "f3ac30ccfb5e14204f5e4268b90a8804")
871871+ ~output0:
872872+ ("1663879eb3f2c9949e2388caa343d361"
873873+ ^ "bb132771245ae6d027ca9cb010dc1fa7"
874874+ ^ "178dc41f8278bc1f64b3f12769a24097"
875875+ ^ "f40d63a86366bdb36ac08abe60c07fe8")
876876+ ~output1:
877877+ ("b057375c89144408cc744624f69f7f4c"
878878+ ^ "cbd93366c92fc4dfcada65f1b959d8c6"
879879+ ^ "4dfc50de711fb46416c2553cc60f21bb"
880880+ ^ "fd006491cb17888b4fb3521c4fdd8745");
881881+ case ~key:(String.make 32 'f') ~nonce:(String.make 16 'f')
882882+ ~output0:
883883+ ("992947c3966126a0e660a3e95db048de"
884884+ ^ "091fb9e0185b1e41e41015bb7ee50150"
885885+ ^ "399e4760b262f9d53f26d8dd19e56f5c"
886886+ ^ "506ae0c3619fa67fb0c408106d0203ee")
887887+ ~output1:
888888+ ("40ea3cfa61fa32a2fda8d1238a2135d9"
889889+ ^ "d4178775240f99007064a6a7f0c731b6"
890890+ ^ "7c227c52ef796b6bed9f9059ba0614bc"
891891+ ^ "f6dd6e38917f3b150e576375be50ed67");
892892+ case ~key:(String.make 32 '5') ~nonce:(String.make 16 '5')
893893+ ~output0:
894894+ ("357d7d94f966778f5815a2051dcb0413"
895895+ ^ "3b26b0ead9f57dd09927837bc3067e4b"
896896+ ^ "6bf299ad81f7f50c8da83c7810bfc17b"
897897+ ^ "b6f4813ab6c326957045fd3fd5e19915")
898898+ ~output1:
899899+ ("ec744a6b9bf8cbdcb36d8b6a5499c68a"
900900+ ^ "08ef7be6cc1e93f2f5bcd2cad4e47c18"
901901+ ^ "a3e5d94b5666382c6d130d822dd56aac"
902902+ ^ "b0f8195278e7b292495f09868ddf12cc");
903903+ case ~key:(String.make 32 'a') ~nonce:(String.make 16 'a')
904904+ ~output0:
905905+ ("fc79acbd58526103862776aab20f3b7d"
906906+ ^ "8d3149b2fab65766299316b6e5b16684"
907907+ ^ "de5de548c1b7d083efd9e3052319e0c6"
908908+ ^ "254141da04a6586df800f64d46b01c87")
909909+ ~output1:
910910+ ("1f05bc67e07628ebe6f6865a2177e0b6"
911911+ ^ "6a558aa7cc1e8ff1a98d27f7071f8335"
912912+ ^ "efce4537bb0ef7b573b32f32765f2900"
913913+ ^ "7da53bba62e7a44d006f41eb28fe15d6");
914914+ case ~key:"00112233445566778899aabbccddeeff" ~nonce:"0f1e2d3c4b5a6978"
915915+ ~output0:
916916+ ("d1abf630467eb4f67f1cfb47cd626aae"
917917+ ^ "8afedbbe4ff8fc5fe9cfae307e74ed45"
918918+ ^ "1f1404425ad2b54569d5f18148939971"
919919+ ^ "abb8fafc88ce4ac7fe1c3d1f7a1eb7ca")
920920+ ~output1:
921921+ ("e76ca87b61a9713541497760dd9ae059"
922922+ ^ "350cad0dcedfaa80a883119a1a6f987f"
923923+ ^ "d1ce91fd8ee0828034b411200a9745a2"
924924+ ^ "85554475d12afc04887fef3516d12a2c");
925925+ case ~key:"c46ec1b18ce8a878725a37e780dfb735" ~nonce:"1ada31d5cf688221"
926926+ ~output0:
927927+ ("826abdd84460e2e9349f0ef4af5b179b"
928928+ ^ "426e4b2d109a9c5bb44000ae51bea90a"
929929+ ^ "496beeef62a76850ff3f0402c4ddc99f"
930930+ ^ "6db07f151c1c0dfac2e56565d6289625")
931931+ ~output1:
932932+ ("5b23132e7b469c7bfb88fa95d44ca5ae"
933933+ ^ "3e45e848a4108e98bad7a9eb15512784"
934934+ ^ "a6a9e6e591dce674120acaf9040ff50f"
935935+ ^ "f3ac30ccfb5e14204f5e4268b90a8804");
904936 ]
905937906938let poly1305_rfc8439_2_5_2 _ =
907907- let key = vx "85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b"
939939+ let key =
940940+ vx "85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b"
908941 and data = "Cryptographic Forum Research Group"
909909- and output = vx "a8061dc1305136c6c22b8baf0c0127a9"
910910- in
942942+ and output = vx "a8061dc1305136c6c22b8baf0c0127a9" in
911943 assert_oct_equal ~msg:"poly 1305 RFC8439 Section 2.5.2"
912944 (Poly1305.mac ~key data) output
913945914946let empty_cases _ =
915915- let plain = ""
916916- and cipher = ""
917917- in
947947+ let plain = "" and cipher = "" in
918948 (* 3DES ECB CBC CTR *)
919919- Array.iter (fun key_size ->
949949+ Array.iter
950950+ (fun key_size ->
920951 let key = DES.ECB.of_secret (String.make key_size '\x00') in
921921- assert_oct_equal ~msg:"DES ECB encrypt" cipher (DES.ECB.encrypt ~key plain) ;
922922- assert_oct_equal ~msg:"DES ECB decrypt" plain (DES.ECB.decrypt ~key cipher))
923923- DES.ECB.key_sizes ;
924924- Array.iter (fun key_size ->
952952+ assert_oct_equal ~msg:"DES ECB encrypt" cipher
953953+ (DES.ECB.encrypt ~key plain);
954954+ assert_oct_equal ~msg:"DES ECB decrypt" plain
955955+ (DES.ECB.decrypt ~key cipher))
956956+ DES.ECB.key_sizes;
957957+ Array.iter
958958+ (fun key_size ->
925959 let key = DES.CBC.of_secret (String.make key_size '\x00')
926926- and iv = String.make DES.CBC.block_size '\x00'
927927- in
928928- assert_oct_equal ~msg:"DES CBC encrypt" cipher (DES.CBC.encrypt ~key ~iv plain) ;
929929- assert_oct_equal ~msg:"DES CBC decrypt" plain (DES.CBC.decrypt ~key ~iv cipher))
930930- DES.CBC.key_sizes ;
931931- Array.iter (fun key_size ->
960960+ and iv = String.make DES.CBC.block_size '\x00' in
961961+ assert_oct_equal ~msg:"DES CBC encrypt" cipher
962962+ (DES.CBC.encrypt ~key ~iv plain);
963963+ assert_oct_equal ~msg:"DES CBC decrypt" plain
964964+ (DES.CBC.decrypt ~key ~iv cipher))
965965+ DES.CBC.key_sizes;
966966+ Array.iter
967967+ (fun key_size ->
932968 let key = DES.CTR.of_secret (String.make key_size '\x00')
933933- and ctr = DES.CTR.ctr_of_octets (String.make DES.CTR.block_size '\x00')
934934- in
935935- assert_oct_equal ~msg:"DES CTR encrypt" cipher (DES.CTR.encrypt ~key ~ctr plain) ;
936936- assert_oct_equal ~msg:"DES CTR decrypt" plain (DES.CTR.decrypt ~key ~ctr cipher))
937937- DES.CTR.key_sizes ;
969969+ and ctr = DES.CTR.ctr_of_octets (String.make DES.CTR.block_size '\x00') in
970970+ assert_oct_equal ~msg:"DES CTR encrypt" cipher
971971+ (DES.CTR.encrypt ~key ~ctr plain);
972972+ assert_oct_equal ~msg:"DES CTR decrypt" plain
973973+ (DES.CTR.decrypt ~key ~ctr cipher))
974974+ DES.CTR.key_sizes;
938975939976 (* AES ECB CBC CTR GCM CCM16 *)
940940- Array.iter (fun key_size ->
977977+ Array.iter
978978+ (fun key_size ->
941979 let key = AES.ECB.of_secret (String.make key_size '\x00') in
942942- assert_oct_equal ~msg:"AES ECB encrypt" cipher (AES.ECB.encrypt ~key plain) ;
943943- assert_oct_equal ~msg:"AES ECB decrypt" plain (AES.ECB.decrypt ~key cipher))
944944- AES.ECB.key_sizes ;
945945- Array.iter (fun key_size ->
980980+ assert_oct_equal ~msg:"AES ECB encrypt" cipher
981981+ (AES.ECB.encrypt ~key plain);
982982+ assert_oct_equal ~msg:"AES ECB decrypt" plain
983983+ (AES.ECB.decrypt ~key cipher))
984984+ AES.ECB.key_sizes;
985985+ Array.iter
986986+ (fun key_size ->
946987 let key = AES.CBC.of_secret (String.make key_size '\x00')
947947- and iv = String.make AES.CBC.block_size '\x00'
948948- in
949949- assert_oct_equal ~msg:"AES CBC encrypt" cipher (AES.CBC.encrypt ~key ~iv plain) ;
950950- assert_oct_equal ~msg:"AES CBC decrypt" plain (AES.CBC.decrypt ~key ~iv cipher))
951951- AES.CBC.key_sizes ;
952952- Array.iter (fun key_size ->
988988+ and iv = String.make AES.CBC.block_size '\x00' in
989989+ assert_oct_equal ~msg:"AES CBC encrypt" cipher
990990+ (AES.CBC.encrypt ~key ~iv plain);
991991+ assert_oct_equal ~msg:"AES CBC decrypt" plain
992992+ (AES.CBC.decrypt ~key ~iv cipher))
993993+ AES.CBC.key_sizes;
994994+ Array.iter
995995+ (fun key_size ->
953996 let key = AES.CTR.of_secret (String.make key_size '\x00')
954954- and ctr = AES.CTR.ctr_of_octets (String.make AES.CTR.block_size '\x00')
955955- in
956956- assert_oct_equal ~msg:"AES CTR encrypt" cipher (AES.CTR.encrypt ~key ~ctr plain) ;
957957- assert_oct_equal ~msg:"AES CTR decrypt" plain (AES.CTR.decrypt ~key ~ctr cipher))
958958- AES.CTR.key_sizes ;
959959- Array.iter (fun key_size ->
997997+ and ctr = AES.CTR.ctr_of_octets (String.make AES.CTR.block_size '\x00') in
998998+ assert_oct_equal ~msg:"AES CTR encrypt" cipher
999999+ (AES.CTR.encrypt ~key ~ctr plain);
10001000+ assert_oct_equal ~msg:"AES CTR decrypt" plain
10011001+ (AES.CTR.decrypt ~key ~ctr cipher))
10021002+ AES.CTR.key_sizes;
10031003+ Array.iter
10041004+ (fun key_size ->
9601005 let key = AES.CCM16.of_secret (String.make key_size '\x00') in
9611006 let test_one nonce =
9621007 let c, tag = AES.CCM16.authenticate_encrypt_tag ~key ~nonce plain in
963963- assert_oct_equal ~msg:"AES CCM16 encrypt" cipher c ;
10081008+ assert_oct_equal ~msg:"AES CCM16 encrypt" cipher c;
9641009 match AES.CCM16.authenticate_decrypt_tag ~key ~nonce ~tag cipher with
9651010 | None -> assert false
9661011 | Some p -> assert_oct_equal ~msg:"AES CCM16 decrypt" plain p
···9681013 test_one (String.make 7 '\x00');
9691014 test_one (String.make 8 '\x00');
9701015 test_one (String.make 13 '\x00'))
971971- AES.CCM16.key_sizes ;
10161016+ AES.CCM16.key_sizes;
97210179731018 (* ChaCha20 *)
974974- Array.iter (fun key_size ->
10191019+ Array.iter
10201020+ (fun key_size ->
9751021 let key = Chacha20.of_secret (String.make key_size '\x00') in
9761022 let test_one nonce =
9771023 let c, tag = Chacha20.authenticate_encrypt_tag ~key ~nonce plain in
978978- assert_oct_equal ~msg:"Chacha20 encrypt" cipher c ;
10241024+ assert_oct_equal ~msg:"Chacha20 encrypt" cipher c;
9791025 match Chacha20.authenticate_decrypt_tag ~key ~nonce ~tag cipher with
9801026 | None -> assert false
9811027 | Some p -> assert_oct_equal ~msg:"Chacha20 decrypt" plain p
9821028 in
9831029 test_one (String.make 8 '\x00');
984984- if key_size = 32 then
985985- test_one (String.make 12 '\x00'))
986986- [| 16 ; 32 |] ;
10301030+ if key_size = 32 then test_one (String.make 12 '\x00'))
10311031+ [| 16; 32 |];
98710329881033 (* ARC4 *)
9891034 let key = ARC4.of_secret (String.make 16 '\x00') in
990990- assert_oct_equal ~msg:"ARC4 encrypt" cipher (ARC4.(encrypt ~key plain).message) ;
991991- assert_oct_equal ~msg:"ARC4 decrypt" plain (ARC4.(decrypt ~key cipher).message)
10351035+ assert_oct_equal ~msg:"ARC4 encrypt" cipher ARC4.(encrypt ~key plain).message;
10361036+ assert_oct_equal ~msg:"ARC4 decrypt" plain ARC4.(decrypt ~key cipher).message
9921037993993-let suite = [
994994- "3DES-ECB" >::: des_ecb_cases ;
995995- "3DES-CBC" >::: des_cbc_cases ;
996996- "3DES-CTR" >::: des_ctr_cases ;
997997- "AES-ECB" >::: [ "SP 300-38A" >::: aes_ecb_cases ] ;
998998- "AES-CBC" >::: [ "SP 300-38A" >::: aes_cbc_cases ] ;
999999- "AES-CTR" >::: [ "SP 300-38A" >::: aes_ctr_cases; ] ;
10001000- "AES-GCM" >::: gcm_cases ;
10011001- (* "AES-CCM" >::: ccm_cases ; *)
10021002- "AES-CCM-REGRESSION" >::: ccm_regressions ;
10031003- "AES-GCM-REGRESSION" >::: gcm_regressions ;
10041004- "Chacha20" >::: chacha20_cases ;
10051005- "poly1305" >:: poly1305_rfc8439_2_5_2 ;
10061006- "empty" >:: empty_cases ;
10071007-]
10381038+let suite =
10391039+ [
10401040+ "3DES-ECB" >::: des_ecb_cases;
10411041+ "3DES-CBC" >::: des_cbc_cases;
10421042+ "3DES-CTR" >::: des_ctr_cases;
10431043+ "AES-ECB" >::: [ "SP 300-38A" >::: aes_ecb_cases ];
10441044+ "AES-CBC" >::: [ "SP 300-38A" >::: aes_cbc_cases ];
10451045+ "AES-CTR" >::: [ "SP 300-38A" >::: aes_ctr_cases ];
10461046+ "AES-GCM" >::: gcm_cases;
10471047+ (* "AES-CCM" >::: ccm_cases ; *)
10481048+ "AES-CCM-REGRESSION" >::: ccm_regressions;
10491049+ "AES-GCM-REGRESSION" >::: gcm_regressions;
10501050+ "Chacha20" >::: chacha20_cases;
10511051+ "poly1305" >:: poly1305_rfc8439_2_5_2;
10521052+ "empty" >:: empty_cases;
10531053+ ]
+21-28
tests/test_common.ml
···11open OUnit2
2233-let (prf, strf) = Format.(fprintf, asprintf)
33+let prf, strf = Format.(fprintf, asprintf)
44let pp_map pp f ppf x = pp ppf (f x)
55let pp_diff pp ppf (a, b) = prf ppf "@[<v>want: %a@,have: %a@]" pp a pp b
66···1111 !st
1212 and digit c =
1313 match c with
1414- | '0'..'9' -> int_of_char c - 0x30
1515- | 'A'..'F' -> int_of_char c - 0x41 + 10
1616- | 'a'..'f' -> int_of_char c - 0x61 + 10
1414+ | '0' .. '9' -> int_of_char c - 0x30
1515+ | 'A' .. 'F' -> int_of_char c - 0x41 + 10
1616+ | 'a' .. 'f' -> int_of_char c - 0x61 + 10
1717 | _ -> invalid_arg "bad character"
1818 and is_space = function
1919 | ' ' | '\012' | '\n' | '\r' | '\t' -> true
2020 | _ -> false
2121 in
2222 let chars, leftover =
2323- fold (fun (chars, leftover) c ->
2424- if skip_ws && is_space c then
2525- chars, leftover
2323+ fold
2424+ (fun (chars, leftover) c ->
2525+ if skip_ws && is_space c then (chars, leftover)
2626 else
2727 let c = digit c in
2828 match leftover with
2929- | None -> chars, Some (c lsl 4)
3030- | Some c' -> (c' lor c) :: chars, None)
2929+ | None -> (chars, Some (c lsl 4))
3030+ | Some c' -> ((c' lor c) :: chars, None))
3131 ([], None) s
3232 in
3333 let chars = List.rev chars in
3434 assert (leftover = None);
3535 String.init (List.length chars) (fun i -> char_of_int (List.nth chars i))
36363737-let rec range a b =
3838- if a > b then [] else a :: range (succ a) b
3737+let rec range a b = if a > b then [] else a :: range (succ a) b
39384039let rec times ~n f a =
4141- if n > 0 then ( ignore (f a) ; times ~n:(pred n) f a )
4040+ if n > 0 then (
4141+ ignore (f a);
4242+ times ~n:(pred n) f a)
42434343-let pp_opt pp ppf = Format.(function
4444- | Some x -> fprintf ppf "Some(%a)" pp x
4545- | None -> fprintf ppf "None")
4646-4747-let eq_opt eq a b = match (a, b) with
4848- | (Some x, Some y) -> eq x y
4949- | _ -> false
4444+let pp_opt pp ppf =
4545+ Format.(
4646+ function
4747+ | Some x -> fprintf ppf "Some(%a)" pp x
4848+ | None -> fprintf ppf "None")
50495050+let eq_opt eq a b = match (a, b) with Some x, Some y -> eq x y | _ -> false
5151let pp_octets pp = pp (Ohex.pp_hexdump ())
52525353let assert_oct_equal ?msg =
5454 assert_equal ~cmp:String.equal ?msg ~pp_diff:(pp_octets pp_diff)
55555656let iter_list xs f = List.iter f xs
5757-5858-let cases_of f =
5959- List.map @@ fun params -> test_case (f params)
6060-5757+let cases_of f = List.map @@ fun params -> test_case (f params)
6158let any _ = true
6262-6359let vx = Ohex.decode
6464-6565-let f1_eq ?msg f (a, b) _ =
6666- assert_oct_equal ?msg (f (vx a)) (vx b)
6767-6060+let f1_eq ?msg f (a, b) _ = assert_oct_equal ?msg (f (vx a)) (vx b)
6861let f2_eq ?msg f (a, b, c) = f1_eq ?msg (f (vx a)) (b, c)
+60-64
tests/test_dh.ml
···11open OUnit2
22-32open Crypto_pk
44-53open Test_common
6475let dh_selftest ~bits n =
88- "selftest" >:: times ~n @@ fun _ ->
99- let p = Dh.gen_group ~bits () in
1010- let (s1, m1) = Dh.gen_key p
1111- and (s2, m2) = Dh.gen_key p in
1212- let sh1 = Dh.shared s1 m2
1313- and sh2 = Dh.shared s2 m1 in
1414- assert_equal sh1 sh2
1515- ~cmp:(eq_opt String.equal)
1616- ~pp_diff:(pp_diff (fun ppf -> function
1717- | None -> Format.fprintf ppf "None"
1818- | Some a -> Format.fprintf ppf "Some(%a)" (Ohex.pp_hexdump ()) a))
1919- ~msg:"shared secret"
66+ "selftest"
77+ >:: times ~n @@ fun _ ->
88+ let p = Dh.gen_group ~bits () in
99+ let s1, m1 = Dh.gen_key p and s2, m2 = Dh.gen_key p in
1010+ let sh1 = Dh.shared s1 m2 and sh2 = Dh.shared s2 m1 in
1111+ assert_equal sh1 sh2 ~cmp:(eq_opt String.equal)
1212+ ~pp_diff:
1313+ (pp_diff (fun ppf -> function
1414+ | None -> Format.fprintf ppf "None"
1515+ | Some a -> Format.fprintf ppf "Some(%a)" (Ohex.pp_hexdump ()) a))
1616+ ~msg:"shared secret"
20172118let dh_shared_0 =
2219 "shared_0" >:: fun _ ->
2323- let gy = vx
2424- "14 ac e2 c0 9c c0 0c 25 89 71 b2 d0 1c 94 58 21
2525- 02 23 b7 23 ec 3e 24 e5 a3 c2 fd 16 cc 49 f0 e2
2626- 87 62 a5 a0 73 f5 de 5b 9b eb c3 60 0b a4 03 38
2727- 0f e1 8c f2 80 b3 64 16 f2 af ab 2e ec 25 81 2c
2828- 84 ae 92 0a 0f 15 9b f3 d9 1f dc 08 7d 8d 27 3a
2929- 91 7d a5 89 dc 94 d6 bc 3f 9d 6d b3 f8 8e f2 37
3030- 86 54 ec 85 ea 4c a0 4c b1 f6 49 83 1c 62 a7 79
3131- 2b 8b 9c e7 fa 47 3e 34 6c c5 ae 12 a3 4e d5 ce
3232- 4b da ea 72 7a 8d c6 67 ef 7e f2 00 24 d7 21 42
3333- a5 23 69 38 7e ec b5 fc 4b 89 42 c4 32 fa e5 58
3434- 6f 39 5d a7 4e cd b5 da dc 1e 52 fe a4 33 72 c1
3535- 82 48 8a 5b c1 44 bc 60 9b 38 5b 80 5f 44 14 93"
3636- and s = vx
3737- "f9 47 87 95 d2 a1 6d d1 7c c8 a9 c0 71 28 a2 82
3838- 71 95 7e 79 87 0b fc 34 a2 42 ec 42 ac cc 42 81
3939- 7b f6 c4 f5 80 a9 70 e3 35 93 9b a3 21 81 a4 e3
4040- 6b 65 3f 1c 5c ab 87 23 86 eb 76 29 66 26 5b e9
4141- c4 d0 26 05 3f de 6c 2f a6 14 f6 bf 77 74 a0 e8
4242- ef e7 12 62 a3 83 e5 66 d8 6c e5 c6 58 67 2a 61
4343- f5 7b 7c 15 15 63 22 55 96 92 9e bd cc b3 bc 2b
4444- 5e e1 ac 5f 75 23 ca 2f 19 5a f1 18 6e 17 f8 c2
4545- f7 11 c7 14 1d 81 bd be 02 31 3f 49 62 7d 02 11
4646- 29 22 63 6e bb 1a 7f 93 bd 98 db 20 94 f8 f0 2e
4747- db ce 9d 79 db b9 a7 41 5f e5 29 a2 31 f8 e2 c3
4848- 30 6a 09 f2 16 a7 30 8c 2f 36 7b 71 99 1e 28 54"
4949- and shared = vx
5050- "a7 40 0d eb f0 4b 2b ec cb 90 3c 55 2d 3c 17 63
5151- b2 4b 4e 1a ff 1e a0 24 c6 56 e3 5e 44 7b d0 01
5252- ef b3 6b 57 20 0e 15 95 b1 53 1a 83 16 3a b1 61
5353- 06 65 f1 7e 64 63 6f 23 86 22 34 c3 fe a9 60 87
5454- 3f 18 c6 5d 44 3e ac e3 85 34 86 6f db aa 31 3b
5555- 4b 4d 68 f7 19 d7 91 a3 12 27 d6 5a ce 29 c8 1b
5656- 5a 59 74 10 8c ff 98 4e 4f 37 ef 5b 43 e8 e2 ad
5757- a8 49 c9 7e c3 c5 3d 35 40 30 8e a4 41 69 1d 16
5858- 34 ba 9a 7e f3 ab d1 0e bb f2 81 15 e9 04 63 ee
5959- 1b bf cc 24 6d cb 41 c4 06 b2 f3 01 1b 31 3a 1e
6060- dc e3 3b c7 cc 1d 19 95 d9 fe 6a 5c a7 57 46 dd
6161- 84 69 0c 45 37 2e 1f 52 96 05 d7 e5 01 9a c8"
6262- in
6363- let grp = Dh.Group.oakley_5 in
6464- match Dh.(shared (fst (key_of_secret grp ~s)) gy) with
6565- | None -> assert_failure "degenerate shared secret"
6666- | Some shared' ->
6767- assert_oct_equal ~msg:"shared secret" shared shared'
2020+ let gy =
2121+ vx
2222+ "14 ac e2 c0 9c c0 0c 25 89 71 b2 d0 1c 94 58 21\n\
2323+ \ 02 23 b7 23 ec 3e 24 e5 a3 c2 fd 16 cc 49 f0 e2\n\
2424+ \ 87 62 a5 a0 73 f5 de 5b 9b eb c3 60 0b a4 03 38\n\
2525+ \ 0f e1 8c f2 80 b3 64 16 f2 af ab 2e ec 25 81 2c\n\
2626+ \ 84 ae 92 0a 0f 15 9b f3 d9 1f dc 08 7d 8d 27 3a\n\
2727+ \ 91 7d a5 89 dc 94 d6 bc 3f 9d 6d b3 f8 8e f2 37\n\
2828+ \ 86 54 ec 85 ea 4c a0 4c b1 f6 49 83 1c 62 a7 79\n\
2929+ \ 2b 8b 9c e7 fa 47 3e 34 6c c5 ae 12 a3 4e d5 ce\n\
3030+ \ 4b da ea 72 7a 8d c6 67 ef 7e f2 00 24 d7 21 42\n\
3131+ \ a5 23 69 38 7e ec b5 fc 4b 89 42 c4 32 fa e5 58\n\
3232+ \ 6f 39 5d a7 4e cd b5 da dc 1e 52 fe a4 33 72 c1\n\
3333+ \ 82 48 8a 5b c1 44 bc 60 9b 38 5b 80 5f 44 14 93"
3434+ and s =
3535+ vx
3636+ "f9 47 87 95 d2 a1 6d d1 7c c8 a9 c0 71 28 a2 82\n\
3737+ \ 71 95 7e 79 87 0b fc 34 a2 42 ec 42 ac cc 42 81\n\
3838+ \ 7b f6 c4 f5 80 a9 70 e3 35 93 9b a3 21 81 a4 e3\n\
3939+ \ 6b 65 3f 1c 5c ab 87 23 86 eb 76 29 66 26 5b e9\n\
4040+ \ c4 d0 26 05 3f de 6c 2f a6 14 f6 bf 77 74 a0 e8\n\
4141+ \ ef e7 12 62 a3 83 e5 66 d8 6c e5 c6 58 67 2a 61\n\
4242+ \ f5 7b 7c 15 15 63 22 55 96 92 9e bd cc b3 bc 2b\n\
4343+ \ 5e e1 ac 5f 75 23 ca 2f 19 5a f1 18 6e 17 f8 c2\n\
4444+ \ f7 11 c7 14 1d 81 bd be 02 31 3f 49 62 7d 02 11\n\
4545+ \ 29 22 63 6e bb 1a 7f 93 bd 98 db 20 94 f8 f0 2e\n\
4646+ \ db ce 9d 79 db b9 a7 41 5f e5 29 a2 31 f8 e2 c3\n\
4747+ \ 30 6a 09 f2 16 a7 30 8c 2f 36 7b 71 99 1e 28 54"
4848+ and shared =
4949+ vx
5050+ "a7 40 0d eb f0 4b 2b ec cb 90 3c 55 2d 3c 17 63\n\
5151+ \ b2 4b 4e 1a ff 1e a0 24 c6 56 e3 5e 44 7b d0 01\n\
5252+ \ ef b3 6b 57 20 0e 15 95 b1 53 1a 83 16 3a b1 61\n\
5353+ \ 06 65 f1 7e 64 63 6f 23 86 22 34 c3 fe a9 60 87\n\
5454+ \ 3f 18 c6 5d 44 3e ac e3 85 34 86 6f db aa 31 3b\n\
5555+ \ 4b 4d 68 f7 19 d7 91 a3 12 27 d6 5a ce 29 c8 1b\n\
5656+ \ 5a 59 74 10 8c ff 98 4e 4f 37 ef 5b 43 e8 e2 ad\n\
5757+ \ a8 49 c9 7e c3 c5 3d 35 40 30 8e a4 41 69 1d 16\n\
5858+ \ 34 ba 9a 7e f3 ab d1 0e bb f2 81 15 e9 04 63 ee\n\
5959+ \ 1b bf cc 24 6d cb 41 c4 06 b2 f3 01 1b 31 3a 1e\n\
6060+ \ dc e3 3b c7 cc 1d 19 95 d9 fe 6a 5c a7 57 46 dd\n\
6161+ \ 84 69 0c 45 37 2e 1f 52 96 05 d7 e5 01 9a c8"
6262+ in
6363+ let grp = Dh.Group.oakley_5 in
6464+ match Dh.(shared (fst (key_of_secret grp ~s)) gy) with
6565+ | None -> assert_failure "degenerate shared secret"
6666+ | Some shared' -> assert_oct_equal ~msg:"shared secret" shared shared'
68676969-let suite = [
7070- dh_selftest ~bits:16 1000 ;
7171- dh_selftest ~bits:128 100 ;
7272- dh_shared_0
7373-]
6868+let suite =
6969+ [ dh_selftest ~bits:16 1000; dh_selftest ~bits:128 100; dh_shared_0 ]
···2929 in
3030 let kp data =
3131 match P256.Dh.secret_of_octets data with
3232- | Ok (p, s) -> p, s
3232+ | Ok (p, s) -> (p, s)
3333 | Error _ -> assert false
3434 in
3535 let d_a, p_a =
3636- kp (of_hex "200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
3636+ kp
3737+ (of_hex "200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
3738 and d_b, p_b =
3838- kp (of_hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
3939+ kp
4040+ (of_hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
3941 in
4042 [
4143 test ~name:"b*A" d_b p_a
···6769 |> Alcotest.check Alcotest.string __LOC__ expected )
6870 in
6971 let point =
7070- of_hex "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
7272+ of_hex
7373+ "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"
7174 in
7275 [
7376 test ~n:0
7474- ~scalar:(of_hex "0000000000000000000000000000000000000000000000000000000000000001")
7777+ ~scalar:
7878+ (of_hex
7979+ "0000000000000000000000000000000000000000000000000000000000000001")
7580 ~point
7676- ~expected:"96c298d84539a1f4a033eb2d817d0377f240a463e5e6bcf847422ce1f2d1176b";
8181+ ~expected:
8282+ "96c298d84539a1f4a033eb2d817d0377f240a463e5e6bcf847422ce1f2d1176b";
7783 test ~n:1
7878- ~scalar:(of_hex "0000000000000000000000000000000000000000000000000000000000000002")
8484+ ~scalar:
8585+ (of_hex
8686+ "0000000000000000000000000000000000000000000000000000000000000002")
7987 ~point
8080- ~expected:"78996647fc480ba6351bf277e26989c0c31ab5040338528a7e4f038d187bf27c";
8888+ ~expected:
8989+ "78996647fc480ba6351bf277e26989c0c31ab5040338528a7e4f038d187bf27c";
8190 test ~n:2
8282- ~scalar:(of_hex "0000000000000000000000000000000000000000000000000000000000000004")
9191+ ~scalar:
9292+ (of_hex
9393+ "0000000000000000000000000000000000000000000000000000000000000004")
8394 ~point
8484- ~expected:"5208036b44029350ef965578dbe21f03d02be69e65de2da0bb8fd032354a53e2";
9595+ ~expected:
9696+ "5208036b44029350ef965578dbe21f03d02be69e65de2da0bb8fd032354a53e2";
8597 test ~n:3
8686- ~scalar:(of_hex "0612465c89a023ab17855b0a6bcebfd3febb53aef84138647b5352e02c10c346")
8787- ~point:(of_hex "0462d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26ac333a93a9e70a81cd5a95b5bf8d13990eb741c8c38872b4a07d275a014e30cf")
8888- ~expected:"854271e19508bc935ab22b95cd2be13a0e78265f528b658b3219028b900d0253";
9898+ ~scalar:
9999+ (of_hex
100100+ "0612465c89a023ab17855b0a6bcebfd3febb53aef84138647b5352e02c10c346")
101101+ ~point:
102102+ (of_hex
103103+ "0462d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26ac333a93a9e70a81cd5a95b5bf8d13990eb741c8c38872b4a07d275a014e30cf")
104104+ ~expected:
105105+ "854271e19508bc935ab22b95cd2be13a0e78265f528b658b3219028b900d0253";
89106 test ~n:4
9090- ~scalar:(of_hex "0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a")
9191- ~point:(of_hex "043cbc1b31b43f17dc200dd70c2944c04c6cb1b082820c234a300b05b7763844c74fde0a4ef93887469793270eb2ff148287da9265b0334f9e2609aac16e8ad503")
9292- ~expected:"ffffffffffffffffffffffffffffffff3022cfeeffffffffffffffffffffff7f";
107107+ ~scalar:
108108+ (of_hex
109109+ "0a0d622a47e48f6bc1038ace438c6f528aa00ad2bd1da5f13ee46bf5f633d71a")
110110+ ~point:
111111+ (of_hex
112112+ "043cbc1b31b43f17dc200dd70c2944c04c6cb1b082820c234a300b05b7763844c74fde0a4ef93887469793270eb2ff148287da9265b0334f9e2609aac16e8ad503")
113113+ ~expected:
114114+ "ffffffffffffffffffffffffffffffff3022cfeeffffffffffffffffffffff7f";
93115 test ~n:5
9494- ~scalar:(of_hex "55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48")
9595- ~point:(of_hex "04000000000000000000000000000000000000000000000000000000000000000066485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4")
9696- ~expected:"48e82c9b82c88cb9fc2a5cff9e7c41bc4255ff6bd3814538c9b130877c07e4cf";
116116+ ~scalar:
117117+ (of_hex
118118+ "55d55f11bb8da1ea318bca7266f0376662441ea87270aa2077f1b770c4854a48")
119119+ ~point:
120120+ (of_hex
121121+ "04000000000000000000000000000000000000000000000000000000000000000066485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4")
122122+ ~expected:
123123+ "48e82c9b82c88cb9fc2a5cff9e7c41bc4255ff6bd3814538c9b130877c07e4cf";
97124 ]
9812599126let to_ok_or_error = function Ok _ -> Ok () | Error _ as e -> e
···101128let point_validation =
102129 let test ~name ~x ~y ~expected =
103130 let scalar =
104104- match P256.Dh.secret_of_octets (of_hex "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") with
131131+ match
132132+ P256.Dh.secret_of_octets
133133+ (of_hex
134134+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
135135+ with
105136 | Ok (p, _) -> p
106137 | _ -> assert false
107138 in
···117148 |> Alcotest.check Testable.ok_or_error __LOC__ expected )
118149 in
119150 let zero = String.make 32 '\000' in
120120- let sb = of_hex "66485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4"
151151+ let sb =
152152+ of_hex "66485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4"
121153 in
122154 [
123155 test ~name:"Ok"
124124- ~x:(of_hex "62d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26")
125125- ~y:(of_hex "ac333a93a9e70a81cd5a95b5bf8d13990eb741c8c38872b4a07d275a014e30cf")
156156+ ~x:
157157+ (of_hex
158158+ "62d5bd3372af75fe85a040715d0f502428e07046868b0bfdfa61d731afe44f26")
159159+ ~y:
160160+ (of_hex
161161+ "ac333a93a9e70a81cd5a95b5bf8d13990eb741c8c38872b4a07d275a014e30cf")
126162 ~expected:(Ok ());
127163 test ~name:"P=0"
128128- ~x:(of_hex "0000000000000000000000000000000000000000000000000000000000000000")
129129- ~y:(of_hex "0000000000000000000000000000000000000000000000000000000000000000")
164164+ ~x:
165165+ (of_hex
166166+ "0000000000000000000000000000000000000000000000000000000000000000")
167167+ ~y:
168168+ (of_hex
169169+ "0000000000000000000000000000000000000000000000000000000000000000")
130170 ~expected:(Error `Not_on_curve);
131171 test ~name:"(0, sqrt(b))" ~x:zero ~y:sb ~expected:(Ok ());
132172 test ~name:"out of range"
133133- ~x:(of_hex "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")
134134- ~y:sb
135135- ~expected:(Error `Invalid_range);
173173+ ~x:
174174+ (of_hex
175175+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")
176176+ ~y:sb ~expected:(Error `Invalid_range);
136177 ]
137178138179let scalar_validation =
···141182 | Ok _ -> Ok ()
142183 | Error _ as e -> e
143184 in
144144- [ ("0", `Quick, fun () ->
145145- Alcotest.check Testable.ok_or_error __LOC__
146146- (Error `Invalid_range)
147147- (ign_sec "0000000000000000000000000000000000000000000000000000000000000000")) ;
148148- ("1", `Quick, fun () ->
149149- Alcotest.check Testable.ok_or_error __LOC__
150150- (Ok ())
151151- (ign_sec "0000000000000000000000000000000000000000000000000000000000000001")) ;
152152- ("n-1", `Quick, fun () ->
153153- Alcotest.check Testable.ok_or_error __LOC__
154154- (Ok ())
155155- (ign_sec "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550")) ;
156156- ("n", `Quick, fun () ->
157157- Alcotest.check Testable.ok_or_error __LOC__
158158- (Error `Invalid_range)
159159- (ign_sec "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")) ;
185185+ [
186186+ ( "0",
187187+ `Quick,
188188+ fun () ->
189189+ Alcotest.check Testable.ok_or_error __LOC__ (Error `Invalid_range)
190190+ (ign_sec
191191+ "0000000000000000000000000000000000000000000000000000000000000000")
192192+ );
193193+ ( "1",
194194+ `Quick,
195195+ fun () ->
196196+ Alcotest.check Testable.ok_or_error __LOC__ (Ok ())
197197+ (ign_sec
198198+ "0000000000000000000000000000000000000000000000000000000000000001")
199199+ );
200200+ ( "n-1",
201201+ `Quick,
202202+ fun () ->
203203+ Alcotest.check Testable.ok_or_error __LOC__ (Ok ())
204204+ (ign_sec
205205+ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550")
206206+ );
207207+ ( "n",
208208+ `Quick,
209209+ fun () ->
210210+ Alcotest.check Testable.ok_or_error __LOC__ (Error `Invalid_range)
211211+ (ign_sec
212212+ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551")
213213+ );
160214 ]
161215162216let ecdsa_gen () =
163163- let d = of_hex "C477F9F6 5C22CCE2 0657FAA5 B2D1D812 2336F851 A508A1ED 04E479C3 4985BF96" in
164164- let p = match
217217+ let d =
218218+ of_hex
219219+ "C477F9F6 5C22CCE2 0657FAA5 B2D1D812 2336F851 A508A1ED 04E479C3 4985BF96"
220220+ in
221221+ let p =
222222+ match
165223 P256.Dsa.pub_of_octets
166166- (of_hex {|04
224224+ (of_hex
225225+ {|04
167226 B7E08AFD FE94BAD3 F1DC8C73 4798BA1C 62B3A0AD 1E9EA2A3 8201CD08 89BC7A19
168227 3603F747 959DBF7A 4BB226E4 19287290 63ADC7AE 43529E61 B563BBC6 06CC5E09|})
169228 with
170229 | Ok a -> a
171230 | Error _ -> assert false
172231 in
173173- let pub = match P256.Dsa.priv_of_octets d with
232232+ let pub =
233233+ match P256.Dsa.priv_of_octets d with
174234 | Ok p -> P256.Dsa.pub_of_priv p
175235 | Error _ -> Alcotest.fail "couldn't decode private key"
176236 in
···180240 Alcotest.(check bool __LOC__ true (pub_eq pub p))
181241182242let ecdsa_sign () =
183183- let d = of_hex "C477F9F6 5C22CCE2 0657FAA5 B2D1D812 2336F851 A508A1ED 04E479C3 4985BF96"
184184- and k = of_hex "7A1A7E52 797FC8CA AA435D2A 4DACE391 58504BF2 04FBE19F 14DBB427 FAEE50AE"
185185- and e = of_hex "A41A41A1 2A799548 211C410C 65D8133A FDE34D28 BDD542E4 B680CF28 99C8A8C4"
243243+ let d =
244244+ of_hex
245245+ "C477F9F6 5C22CCE2 0657FAA5 B2D1D812 2336F851 A508A1ED 04E479C3 4985BF96"
246246+ and k =
247247+ of_hex
248248+ "7A1A7E52 797FC8CA AA435D2A 4DACE391 58504BF2 04FBE19F 14DBB427 FAEE50AE"
249249+ and e =
250250+ of_hex
251251+ "A41A41A1 2A799548 211C410C 65D8133A FDE34D28 BDD542E4 B680CF28 99C8A8C4"
186252 in
187187- let r = of_hex "2B42F576 D07F4165 FF65D1F3 B1500F81 E44C316F 1F0B3EF5 7325B69A CA46104F"
188188- and s = of_hex "DC42C212 2D6392CD 3E3A993A 89502A81 98C1886F E69D262C 4B329BDB 6B63FAF1"
253253+ let r =
254254+ of_hex
255255+ "2B42F576 D07F4165 FF65D1F3 B1500F81 E44C316F 1F0B3EF5 7325B69A CA46104F"
256256+ and s =
257257+ of_hex
258258+ "DC42C212 2D6392CD 3E3A993A 89502A81 98C1886F E69D262C 4B329BDB 6B63FAF1"
189259 in
190190- let key = match P256.Dsa.priv_of_octets d with
260260+ let key =
261261+ match P256.Dsa.priv_of_octets d with
191262 | Ok p -> p
192263 | Error _ -> Alcotest.fail "couldn't decode private key"
193264 in
194194- let (r', s') = P256.Dsa.sign ~key ~k e in
265265+ let r', s' = P256.Dsa.sign ~key ~k e in
195266 Alcotest.(check bool __LOC__ true (String.equal r r' && String.equal s s'))
196267197268let ecdsa_verify () =
198269 let key =
199199- match P256.Dsa.pub_of_octets
200200- (of_hex {|04
270270+ match
271271+ P256.Dsa.pub_of_octets
272272+ (of_hex
273273+ {|04
201274 B7E08AFD FE94BAD3 F1DC8C73 4798BA1C 62B3A0AD 1E9EA2A3 8201CD08 89BC7A19
202275 3603F747 959DBF7A 4BB226E4 19287290 63ADC7AE 43529E61 B563BBC6 06CC5E09|})
203276 with
204277 | Ok a -> a
205278 | Error _ -> assert false
206206- and e = of_hex "A41A41A1 2A799548 211C410C 65D8133A FDE34D28 BDD542E4 B680CF28 99C8A8C4"
207207- and r = of_hex "2B42F576 D07F4165 FF65D1F3 B1500F81 E44C316F 1F0B3EF5 7325B69A CA46104F"
208208- and s = of_hex "DC42C212 2D6392CD 3E3A993A 89502A81 98C1886F E69D262C 4B329BDB 6B63FAF1"
279279+ and e =
280280+ of_hex
281281+ "A41A41A1 2A799548 211C410C 65D8133A FDE34D28 BDD542E4 B680CF28 99C8A8C4"
282282+ and r =
283283+ of_hex
284284+ "2B42F576 D07F4165 FF65D1F3 B1500F81 E44C316F 1F0B3EF5 7325B69A CA46104F"
285285+ and s =
286286+ of_hex
287287+ "DC42C212 2D6392CD 3E3A993A 89502A81 98C1886F E69D262C 4B329BDB 6B63FAF1"
209288 in
210289 Alcotest.(check bool __LOC__ true (P256.Dsa.verify ~key (r, s) e))
211290212212-let ecdsa = [
213213- (* from https://csrc.nist.rip/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf *)
214214- "ECDSA gen", `Quick, ecdsa_gen ;
215215- "ECDSA sign", `Quick, ecdsa_sign ;
216216- "ECDSA verify", `Quick, ecdsa_verify ;
217217-]
291291+let ecdsa =
292292+ [
293293+ (* from https://csrc.nist.rip/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf *)
294294+ ("ECDSA gen", `Quick, ecdsa_gen);
295295+ ("ECDSA sign", `Quick, ecdsa_sign);
296296+ ("ECDSA verify", `Quick, ecdsa_verify);
297297+ ]
218298219219-let pub_key_compression (module Dsa:Crypto_ec.Dsa) () =
299299+let pub_key_compression (module Dsa : Crypto_ec.Dsa) () =
220300 for _ = 1 to 20 do
221301 let _, pub = Dsa.generate () in
222302 let compressed = Dsa.pub_to_octets ~compress:true pub in
223303 let decompressed = Dsa.pub_of_octets compressed in
224304 match decompressed with
225225- | Ok decompressed ->
305305+ | Ok decompressed ->
226306 let p1 = Dsa.pub_to_octets pub in
227307 let p2 = Dsa.pub_to_octets decompressed in
228308 Alcotest.(check string __LOC__ p1 p2);
229309 let prefix = String.get_uint8 compressed 0 in
230230- let expected = 2 + String.(get_uint8 p1 (length p1 - 1)) land 1 in
231231- Alcotest.(check int __LOC__ expected prefix);
232232- | Error e -> Alcotest.failf "%a" pp_error e
310310+ let expected = 2 + (String.(get_uint8 p1 (length p1 - 1)) land 1) in
311311+ Alcotest.(check int __LOC__ expected prefix)
312312+ | Error e -> Alcotest.failf "%a" pp_error e
233313 done
234314235315let ecdsa_rfc6979_p256 =
236316 (* A.2.5 - P 256 *)
237317 let priv, pub =
238238- let data = of_hex "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721" in
318318+ let data =
319319+ of_hex "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721"
320320+ in
239321 match P256.Dsa.priv_of_octets data with
240240- | Ok p -> p, P256.Dsa.pub_of_priv p
322322+ | Ok p -> (p, P256.Dsa.pub_of_priv p)
241323 | Error _ -> assert false
242324 in
243325 let pub_rfc () =
244326 let fst = String.make 1 '\004' in
245245- let ux = of_hex "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
246246- and uy = of_hex "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299"
327327+ let ux =
328328+ of_hex "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
329329+ and uy =
330330+ of_hex "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299"
247331 in
248332 match P256.Dsa.pub_of_octets (fst ^ ux ^ uy) with
249333 | Ok p ->
250250- let pub_eq =
251251- String.equal (P256.Dsa.pub_to_octets pub) (P256.Dsa.pub_to_octets p)
252252- in
253253- Alcotest.(check bool __LOC__ true pub_eq)
334334+ let pub_eq =
335335+ String.equal (P256.Dsa.pub_to_octets pub) (P256.Dsa.pub_to_octets p)
336336+ in
337337+ Alcotest.(check bool __LOC__ true pub_eq)
254338 | Error _ -> Alcotest.fail "bad public key"
255339 in
256340 let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () =
257341 let msg =
258342 let h = Digestif.(digest_string hash message |> to_raw_string hash) in
259343 String.sub h 0 (min (String.length h) 32)
260260- and k = of_hex k
261261- in
344344+ and k = of_hex k in
262345 let k' =
263346 let module H = (val Digestif.module_of hash) in
264347 let module K = P256.Dsa.K_gen (H) in
···271354 let sig' = P256.Dsa.sign ~key:priv ~k msg in
272355 Alcotest.(check bool __LOC__ true (sig_eq sig'))
273356 in
274274- let cases = [
275275- case Digestif.sha1 ~message:"sample"
276276- ~k:"882905F1227FD620FBF2ABF21244F0BA83D0DC3A9103DBBEE43A1FB858109DB4"
277277- ~r:"61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32"
278278- ~s:"6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB" ;
279279- case Digestif.sha224 ~message:"sample"
280280- ~k:"103F90EE9DC52E5E7FB5132B7033C63066D194321491862059967C715985D473"
281281- ~r:"53B2FFF5D1752B2C689DF257C04C40A587FABABB3F6FC2702F1343AF7CA9AA3F"
282282- ~s:"B9AFB64FDC03DC1A131C7D2386D11E349F070AA432A4ACC918BEA988BF75C74C" ;
283283- case Digestif.sha256 ~message:"sample"
284284- ~k:"A6E3C57DD01ABE90086538398355DD4C3B17AA873382B0F24D6129493D8AAD60"
285285- ~r:"EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716"
286286- ~s:"F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8" ;
287287- case Digestif.sha384 ~message:"sample"
288288- ~k:"09F634B188CEFD98E7EC88B1AA9852D734D0BC272F7D2A47DECC6EBEB375AAD4"
289289- ~r:"0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719"
290290- ~s:"4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954" ;
291291- case Digestif.sha512 ~message:"sample"
292292- ~k:"5FA81C63109BADB88C1F367B47DA606DA28CAD69AA22C4FE6AD7DF73A7173AA5"
293293- ~r:"8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00"
294294- ~s:"2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE" ;
295295- case Digestif.sha1 ~message:"test"
296296- ~k:"8C9520267C55D6B980DF741E56B4ADEE114D84FBFA2E62137954164028632A2E"
297297- ~r:"0CBCC86FD6ABD1D99E703E1EC50069EE5C0B4BA4B9AC60E409E8EC5910D81A89"
298298- ~s:"01B9D7B73DFAA60D5651EC4591A0136F87653E0FD780C3B1BC872FFDEAE479B1" ;
299299- case Digestif.sha224 ~message:"test"
300300- ~k:"669F4426F2688B8BE0DB3A6BD1989BDAEFFF84B649EEB84F3DD26080F667FAA7"
301301- ~r:"C37EDB6F0AE79D47C3C27E962FA269BB4F441770357E114EE511F662EC34A692"
302302- ~s:"C820053A05791E521FCAAD6042D40AEA1D6B1A540138558F47D0719800E18F2D" ;
303303- case Digestif.sha256 ~message:"test"
304304- ~k:"D16B6AE827F17175E040871A1C7EC3500192C4C92677336EC2537ACAEE0008E0"
305305- ~r:"F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367"
306306- ~s:"019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083" ;
307307- case Digestif.sha384 ~message:"test"
308308- ~k:"16AEFFA357260B04B1DD199693960740066C1A8F3E8EDD79070AA914D361B3B8"
309309- ~r:"83910E8B48BB0C74244EBDF7F07A1C5413D61472BD941EF3920E623FBCCEBEB6"
310310- ~s:"8DDBEC54CF8CD5874883841D712142A56A8D0F218F5003CB0296B6B509619F2C" ;
311311- case Digestif.sha512 ~message:"test"
312312- ~k:"6915D11632ACA3C40D5D51C08DAF9C555933819548784480E93499000D9F0B7F"
313313- ~r:"461D93F31B6540894788FD206C07CFA0CC35F46FA3C91816FFF1040AD1581A04"
314314- ~s:"39AF9F15DE0DB8D97E72719C74820D304CE5226E32DEDAE67519E840D1194E55" ;
315315- ] in
316316- ("public key matches", `Quick, pub_rfc) ::
317317- ("public key compression and decompression", `Quick, (pub_key_compression (module P256.Dsa))) ::
318318- List.mapi (fun i c -> "RFC 6979 A.2.5 " ^ string_of_int i, `Quick, c) cases
357357+ let cases =
358358+ [
359359+ case Digestif.sha1 ~message:"sample"
360360+ ~k:"882905F1227FD620FBF2ABF21244F0BA83D0DC3A9103DBBEE43A1FB858109DB4"
361361+ ~r:"61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32"
362362+ ~s:"6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB";
363363+ case Digestif.sha224 ~message:"sample"
364364+ ~k:"103F90EE9DC52E5E7FB5132B7033C63066D194321491862059967C715985D473"
365365+ ~r:"53B2FFF5D1752B2C689DF257C04C40A587FABABB3F6FC2702F1343AF7CA9AA3F"
366366+ ~s:"B9AFB64FDC03DC1A131C7D2386D11E349F070AA432A4ACC918BEA988BF75C74C";
367367+ case Digestif.sha256 ~message:"sample"
368368+ ~k:"A6E3C57DD01ABE90086538398355DD4C3B17AA873382B0F24D6129493D8AAD60"
369369+ ~r:"EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716"
370370+ ~s:"F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8";
371371+ case Digestif.sha384 ~message:"sample"
372372+ ~k:"09F634B188CEFD98E7EC88B1AA9852D734D0BC272F7D2A47DECC6EBEB375AAD4"
373373+ ~r:"0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719"
374374+ ~s:"4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954";
375375+ case Digestif.sha512 ~message:"sample"
376376+ ~k:"5FA81C63109BADB88C1F367B47DA606DA28CAD69AA22C4FE6AD7DF73A7173AA5"
377377+ ~r:"8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00"
378378+ ~s:"2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE";
379379+ case Digestif.sha1 ~message:"test"
380380+ ~k:"8C9520267C55D6B980DF741E56B4ADEE114D84FBFA2E62137954164028632A2E"
381381+ ~r:"0CBCC86FD6ABD1D99E703E1EC50069EE5C0B4BA4B9AC60E409E8EC5910D81A89"
382382+ ~s:"01B9D7B73DFAA60D5651EC4591A0136F87653E0FD780C3B1BC872FFDEAE479B1";
383383+ case Digestif.sha224 ~message:"test"
384384+ ~k:"669F4426F2688B8BE0DB3A6BD1989BDAEFFF84B649EEB84F3DD26080F667FAA7"
385385+ ~r:"C37EDB6F0AE79D47C3C27E962FA269BB4F441770357E114EE511F662EC34A692"
386386+ ~s:"C820053A05791E521FCAAD6042D40AEA1D6B1A540138558F47D0719800E18F2D";
387387+ case Digestif.sha256 ~message:"test"
388388+ ~k:"D16B6AE827F17175E040871A1C7EC3500192C4C92677336EC2537ACAEE0008E0"
389389+ ~r:"F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367"
390390+ ~s:"019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083";
391391+ case Digestif.sha384 ~message:"test"
392392+ ~k:"16AEFFA357260B04B1DD199693960740066C1A8F3E8EDD79070AA914D361B3B8"
393393+ ~r:"83910E8B48BB0C74244EBDF7F07A1C5413D61472BD941EF3920E623FBCCEBEB6"
394394+ ~s:"8DDBEC54CF8CD5874883841D712142A56A8D0F218F5003CB0296B6B509619F2C";
395395+ case Digestif.sha512 ~message:"test"
396396+ ~k:"6915D11632ACA3C40D5D51C08DAF9C555933819548784480E93499000D9F0B7F"
397397+ ~r:"461D93F31B6540894788FD206C07CFA0CC35F46FA3C91816FFF1040AD1581A04"
398398+ ~s:"39AF9F15DE0DB8D97E72719C74820D304CE5226E32DEDAE67519E840D1194E55";
399399+ ]
400400+ in
401401+ ("public key matches", `Quick, pub_rfc)
402402+ :: ( "public key compression and decompression",
403403+ `Quick,
404404+ pub_key_compression (module P256.Dsa) )
405405+ :: List.mapi
406406+ (fun i c -> ("RFC 6979 A.2.5 " ^ string_of_int i, `Quick, c))
407407+ cases
319408320409let ecdsa_rfc6979_p384 =
321410 (* A.2.6 - P 384 *)
322411 let priv, pub =
323323- let data = of_hex "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5" in
412412+ let data =
413413+ of_hex
414414+ "6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5"
415415+ in
324416 match P384.Dsa.priv_of_octets data with
325325- | Ok p -> p, P384.Dsa.pub_of_priv p
417417+ | Ok p -> (p, P384.Dsa.pub_of_priv p)
326418 | Error _ -> assert false
327419 in
328420 let pub_rfc () =
329421 let fst = String.make 1 '\004' in
330330- let ux = of_hex "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13"
331331- and uy = of_hex "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720"
422422+ let ux =
423423+ of_hex
424424+ "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13"
425425+ and uy =
426426+ of_hex
427427+ "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720"
332428 in
333429 match P384.Dsa.pub_of_octets (fst ^ ux ^ uy) with
334430 | Ok p ->
335335- let pub_eq =
336336- String.equal (P384.Dsa.pub_to_octets pub) (P384.Dsa.pub_to_octets p)
337337- in
338338- Alcotest.(check bool __LOC__ true pub_eq)
431431+ let pub_eq =
432432+ String.equal (P384.Dsa.pub_to_octets pub) (P384.Dsa.pub_to_octets p)
433433+ in
434434+ Alcotest.(check bool __LOC__ true pub_eq)
339435 | Error _ -> Alcotest.fail "bad public key"
340436 in
341437 let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () =
342438 let msg =
343439 let h = Digestif.(digest_string hash message |> to_raw_string hash) in
344440 String.sub h 0 (min (String.length h) 48)
345345- and k = of_hex k
346346- in
441441+ and k = of_hex k in
347442 let k' =
348443 let module H = (val Digestif.module_of hash) in
349444 let module K = P384.Dsa.K_gen (H) in
···356451 let sig' = P384.Dsa.sign ~key:priv ~k msg in
357452 Alcotest.(check bool __LOC__ true (sig_eq sig'))
358453 in
359359- let cases = [
360360- case Digestif.sha1 ~message:"sample"
361361- ~k:"4471EF7518BB2C7C20F62EAE1C387AD0C5E8E470995DB4ACF694466E6AB09663
362362- 0F29E5938D25106C3C340045A2DB01A7"
363363- ~r:"EC748D839243D6FBEF4FC5C4859A7DFFD7F3ABDDF72014540C16D73309834FA3
364364- 7B9BA002899F6FDA3A4A9386790D4EB2"
365365- ~s:"A3BCFA947BEEF4732BF247AC17F71676CB31A847B9FF0CBC9C9ED4C1A5B3FACF
366366- 26F49CA031D4857570CCB5CA4424A443";
367367-368368- case Digestif.sha224 ~message:"sample"
369369- ~k:"A4E4D2F0E729EB786B31FC20AD5D849E304450E0AE8E3E341134A5C1AFA03CAB
370370- 8083EE4E3C45B06A5899EA56C51B5879"
371371- ~r:"42356E76B55A6D9B4631C865445DBE54E056D3B3431766D0509244793C3F9366
372372- 450F76EE3DE43F5A125333A6BE060122"
373373- ~s:"9DA0C81787064021E78DF658F2FBB0B042BF304665DB721F077A4298B095E483
374374- 4C082C03D83028EFBF93A3C23940CA8D";
375375-376376- case Digestif.sha256 ~message:"sample"
377377- ~k:"180AE9F9AEC5438A44BC159A1FCB277C7BE54FA20E7CF404B490650A8ACC414E
378378- 375572342863C899F9F2EDF9747A9B60"
379379- ~r:"21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33
380380- BDE1E888E63355D92FA2B3C36D8FB2CD"
381381- ~s:"F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEB
382382- EFDC63ECCD1AC42EC0CB8668A4FA0AB0";
383383-384384- case Digestif.sha384 ~message:"sample"
385385- ~k:"94ED910D1A099DAD3254E9242AE85ABDE4BA15168EAF0CA87A555FD56D10FBCA
386386- 2907E3E83BA95368623B8C4686915CF9"
387387- ~r:"94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C
388388- 81A648152E44ACF96E36DD1E80FABE46"
389389- ~s:"99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94F
390390- A329C145786E679E7B82C71A38628AC8";
391391-392392- case Digestif.sha512 ~message:"sample"
393393- ~k:"92FC3C7183A883E24216D1141F1A8976C5B0DD797DFA597E3D7B32198BD35331
394394- A4E966532593A52980D0E3AAA5E10EC3"
395395- ~r:"ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799C
396396- FE30F35CC900056D7C99CD7882433709"
397397- ~s:"512C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112
398398- DC7CC3EF3446DEFCEB01A45C2667FDD5";
399399-400400- case Digestif.sha1 ~message:"test"
401401- ~k:"66CC2C8F4D303FC962E5FF6A27BD79F84EC812DDAE58CF5243B64A4AD8094D47
402402- EC3727F3A3C186C15054492E30698497"
403403- ~r:"4BC35D3A50EF4E30576F58CD96CE6BF638025EE624004A1F7789A8B8E43D0678
404404- ACD9D29876DAF46638645F7F404B11C7"
405405- ~s:"D5A6326C494ED3FF614703878961C0FDE7B2C278F9A65FD8C4B7186201A29916
406406- 95BA1C84541327E966FA7B50F7382282";
407407-408408- case Digestif.sha224 ~message:"test"
409409- ~k:"18FA39DB95AA5F561F30FA3591DC59C0FA3653A80DAFFA0B48D1A4C6DFCBFF6E
410410- 3D33BE4DC5EB8886A8ECD093F2935726"
411411- ~r:"E8C9D0B6EA72A0E7837FEA1D14A1A9557F29FAA45D3E7EE888FC5BF954B5E624
412412- 64A9A817C47FF78B8C11066B24080E72"
413413- ~s:"07041D4A7A0379AC7232FF72E6F77B6DDB8F09B16CCE0EC3286B2BD43FA8C614
414414- 1C53EA5ABEF0D8231077A04540A96B66";
415415-416416- case Digestif.sha256 ~message:"test"
417417- ~k:"0CFAC37587532347DC3389FDC98286BBA8C73807285B184C83E62E26C401C0FA
418418- A48DD070BA79921A3457ABFF2D630AD7"
419419- ~r:"6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559
420420- F918EEDAF2293BE5B475CC8F0188636B"
421421- ~s:"2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D
422422- 51AB373F9845C0514EEFB14024787265";
423423-424424- case Digestif.sha384 ~message:"test"
425425- ~k:"015EE46A5BF88773ED9123A5AB0807962D193719503C527B031B4C2D225092AD
426426- A71F4A459BC0DA98ADB95837DB8312EA"
427427- ~r:"8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB
428428- 0542A7F0812998DA8F1DD3CA3CF023DB"
429429- ~s:"DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E0
430430- 6A739F040649A667BF3B828246BAA5A5";
431431-432432- case Digestif.sha512 ~message:"test"
433433- ~k:"3780C4F67CB15518B6ACAE34C9F83568D2E12E47DEAB6C50A4E4EE5319D1E8CE
434434- 0E2CC8A136036DC4B9C00E6888F66B6C"
435435- ~r:"A0D5D090C9980FAF3C2CE57B7AE951D31977DD11C775D314AF55F76C676447D0
436436- 6FB6495CD21B4B6E340FC236584FB277"
437437- ~s:"976984E59B4C77B0E8E4460DCA3D9F20E07B9BB1F63BEEFAF576F6B2E8B22463
438438- 4A2092CD3792E0159AD9CEE37659C736"
439439- ] in
440440- ("public key matches", `Quick, pub_rfc) ::
441441- ("public key compression and decompression", `Quick, pub_key_compression (module P384.Dsa)) ::
442442- List.mapi (fun i c -> "RFC 6979 A.2.6 " ^ string_of_int i, `Quick, c) cases
454454+ let cases =
455455+ [
456456+ case Digestif.sha1 ~message:"sample"
457457+ ~k:
458458+ "4471EF7518BB2C7C20F62EAE1C387AD0C5E8E470995DB4ACF694466E6AB09663\n\
459459+ \ 0F29E5938D25106C3C340045A2DB01A7"
460460+ ~r:
461461+ "EC748D839243D6FBEF4FC5C4859A7DFFD7F3ABDDF72014540C16D73309834FA3\n\
462462+ \ 7B9BA002899F6FDA3A4A9386790D4EB2"
463463+ ~s:
464464+ "A3BCFA947BEEF4732BF247AC17F71676CB31A847B9FF0CBC9C9ED4C1A5B3FACF\n\
465465+ \ 26F49CA031D4857570CCB5CA4424A443";
466466+ case Digestif.sha224 ~message:"sample"
467467+ ~k:
468468+ "A4E4D2F0E729EB786B31FC20AD5D849E304450E0AE8E3E341134A5C1AFA03CAB\n\
469469+ \ 8083EE4E3C45B06A5899EA56C51B5879"
470470+ ~r:
471471+ "42356E76B55A6D9B4631C865445DBE54E056D3B3431766D0509244793C3F9366\n\
472472+ \ 450F76EE3DE43F5A125333A6BE060122"
473473+ ~s:
474474+ "9DA0C81787064021E78DF658F2FBB0B042BF304665DB721F077A4298B095E483\n\
475475+ \ 4C082C03D83028EFBF93A3C23940CA8D";
476476+ case Digestif.sha256 ~message:"sample"
477477+ ~k:
478478+ "180AE9F9AEC5438A44BC159A1FCB277C7BE54FA20E7CF404B490650A8ACC414E\n\
479479+ \ 375572342863C899F9F2EDF9747A9B60"
480480+ ~r:
481481+ "21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33\n\
482482+ \ BDE1E888E63355D92FA2B3C36D8FB2CD"
483483+ ~s:
484484+ "F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEB\n\
485485+ \ EFDC63ECCD1AC42EC0CB8668A4FA0AB0";
486486+ case Digestif.sha384 ~message:"sample"
487487+ ~k:
488488+ "94ED910D1A099DAD3254E9242AE85ABDE4BA15168EAF0CA87A555FD56D10FBCA\n\
489489+ \ 2907E3E83BA95368623B8C4686915CF9"
490490+ ~r:
491491+ "94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C\n\
492492+ \ 81A648152E44ACF96E36DD1E80FABE46"
493493+ ~s:
494494+ "99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94F\n\
495495+ \ A329C145786E679E7B82C71A38628AC8";
496496+ case Digestif.sha512 ~message:"sample"
497497+ ~k:
498498+ "92FC3C7183A883E24216D1141F1A8976C5B0DD797DFA597E3D7B32198BD35331\n\
499499+ \ A4E966532593A52980D0E3AAA5E10EC3"
500500+ ~r:
501501+ "ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799C\n\
502502+ \ FE30F35CC900056D7C99CD7882433709"
503503+ ~s:
504504+ "512C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112\n\
505505+ \ DC7CC3EF3446DEFCEB01A45C2667FDD5";
506506+ case Digestif.sha1 ~message:"test"
507507+ ~k:
508508+ "66CC2C8F4D303FC962E5FF6A27BD79F84EC812DDAE58CF5243B64A4AD8094D47\n\
509509+ \ EC3727F3A3C186C15054492E30698497"
510510+ ~r:
511511+ "4BC35D3A50EF4E30576F58CD96CE6BF638025EE624004A1F7789A8B8E43D0678\n\
512512+ \ ACD9D29876DAF46638645F7F404B11C7"
513513+ ~s:
514514+ "D5A6326C494ED3FF614703878961C0FDE7B2C278F9A65FD8C4B7186201A29916\n\
515515+ \ 95BA1C84541327E966FA7B50F7382282";
516516+ case Digestif.sha224 ~message:"test"
517517+ ~k:
518518+ "18FA39DB95AA5F561F30FA3591DC59C0FA3653A80DAFFA0B48D1A4C6DFCBFF6E\n\
519519+ \ 3D33BE4DC5EB8886A8ECD093F2935726"
520520+ ~r:
521521+ "E8C9D0B6EA72A0E7837FEA1D14A1A9557F29FAA45D3E7EE888FC5BF954B5E624\n\
522522+ \ 64A9A817C47FF78B8C11066B24080E72"
523523+ ~s:
524524+ "07041D4A7A0379AC7232FF72E6F77B6DDB8F09B16CCE0EC3286B2BD43FA8C614\n\
525525+ \ 1C53EA5ABEF0D8231077A04540A96B66";
526526+ case Digestif.sha256 ~message:"test"
527527+ ~k:
528528+ "0CFAC37587532347DC3389FDC98286BBA8C73807285B184C83E62E26C401C0FA\n\
529529+ \ A48DD070BA79921A3457ABFF2D630AD7"
530530+ ~r:
531531+ "6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559\n\
532532+ \ F918EEDAF2293BE5B475CC8F0188636B"
533533+ ~s:
534534+ "2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D\n\
535535+ \ 51AB373F9845C0514EEFB14024787265";
536536+ case Digestif.sha384 ~message:"test"
537537+ ~k:
538538+ "015EE46A5BF88773ED9123A5AB0807962D193719503C527B031B4C2D225092AD\n\
539539+ \ A71F4A459BC0DA98ADB95837DB8312EA"
540540+ ~r:
541541+ "8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB\n\
542542+ \ 0542A7F0812998DA8F1DD3CA3CF023DB"
543543+ ~s:
544544+ "DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E0\n\
545545+ \ 6A739F040649A667BF3B828246BAA5A5";
546546+ case Digestif.sha512 ~message:"test"
547547+ ~k:
548548+ "3780C4F67CB15518B6ACAE34C9F83568D2E12E47DEAB6C50A4E4EE5319D1E8CE\n\
549549+ \ 0E2CC8A136036DC4B9C00E6888F66B6C"
550550+ ~r:
551551+ "A0D5D090C9980FAF3C2CE57B7AE951D31977DD11C775D314AF55F76C676447D0\n\
552552+ \ 6FB6495CD21B4B6E340FC236584FB277"
553553+ ~s:
554554+ "976984E59B4C77B0E8E4460DCA3D9F20E07B9BB1F63BEEFAF576F6B2E8B22463\n\
555555+ \ 4A2092CD3792E0159AD9CEE37659C736";
556556+ ]
557557+ in
558558+ ("public key matches", `Quick, pub_rfc)
559559+ :: ( "public key compression and decompression",
560560+ `Quick,
561561+ pub_key_compression (module P384.Dsa) )
562562+ :: List.mapi
563563+ (fun i c -> ("RFC 6979 A.2.6 " ^ string_of_int i, `Quick, c))
564564+ cases
443565444566let ecdsa_rfc6979_p521 =
445567 (* A.2.7 - P 521 *)
446446- let of_h b = of_hex ((String.make 1 '0') ^ b) in
568568+ let of_h b = of_hex (String.make 1 '0' ^ b) in
447569 let priv, pub =
448448- let data = of_h
449449- "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75C
450450- AA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83
451451- 538"
570570+ let data =
571571+ of_h
572572+ "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75C\n\
573573+ \ \
574574+ AA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83\n\
575575+ \ 538"
452576 in
453577 match P521.Dsa.priv_of_octets data with
454454- | Ok p -> p, P521.Dsa.pub_of_priv p
578578+ | Ok p -> (p, P521.Dsa.pub_of_priv p)
455579 | Error _ -> assert false
456580 in
457581 let pub_rfc () =
458582 let fst = String.make 1 '\004' in
459459- let ux = of_h
460460- "1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD3
461461- 71123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F502
462462- 3A4"
463463- and uy = of_h
464464- "0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A2
465465- 8A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDF
466466- CF5"
583583+ let ux =
584584+ of_h
585585+ "1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD3\n\
586586+ \ \
587587+ 71123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F502\n\
588588+ \ 3A4"
589589+ and uy =
590590+ of_h
591591+ "0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A2\n\
592592+ \ \
593593+ 8A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDF\n\
594594+ \ CF5"
467595 in
468596 match P521.Dsa.pub_of_octets (fst ^ ux ^ uy) with
469597 | Ok p ->
470470- let pub_eq =
471471- String.equal (P521.Dsa.pub_to_octets pub) (P521.Dsa.pub_to_octets p)
472472- in
473473- Alcotest.(check bool __LOC__ true pub_eq)
598598+ let pub_eq =
599599+ String.equal (P521.Dsa.pub_to_octets pub) (P521.Dsa.pub_to_octets p)
600600+ in
601601+ Alcotest.(check bool __LOC__ true pub_eq)
474602 | Error _ -> Alcotest.fail "bad public key"
475603 in
476604 let case (type a) (hash : a Digestif.hash) ~message ~k ~r ~s () =
477605 let msg = Digestif.(digest_string hash message |> to_raw_string hash)
478478- and k = of_h k
479479- in
606606+ and k = of_h k in
480607 let k' =
481608 let module H = (val Digestif.module_of hash) in
482609 let module K = P521.Dsa.K_gen (H) in
···489616 let sig' = P521.Dsa.sign ~key:priv ~k msg in
490617 Alcotest.(check bool __LOC__ true (sig_eq sig'))
491618 in
492492- let cases = [
493493-494494- case Digestif.sha1 ~message:"sample"
495495- ~k:"089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB
496496- 42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D
497497- 0F9"
498498- ~r:"0343B6EC45728975EA5CBA6659BBB6062A5FF89EEA58BE3C80B619F322C87910
499499- FE092F7D45BB0F8EEE01ED3F20BABEC079D202AE677B243AB40B5431D497C55D
500500- 75D"
501501- ~s:"0E7B0E675A9B24413D448B8CC119D2BF7B2D2DF032741C096634D6D65D0DBE3D
502502- 5694625FB9E8104D3B842C1B0E2D0B98BEA19341E8676AEF66AE4EBA3D5475D5
503503- D16";
504504-505505- case Digestif.sha224 ~message:"sample"
506506- ~k:"121415EC2CD7726330A61F7F3FA5DE14BE9436019C4DB8CB4041F3B54CF31BE0
507507- 493EE3F427FB906393D895A19C9523F3A1D54BB8702BD4AA9C99DAB2597B9211
508508- 3F3"
509509- ~r:"1776331CFCDF927D666E032E00CF776187BC9FDD8E69D0DABB4109FFE1B5E2A3
510510- 0715F4CC923A4A5E94D2503E9ACFED92857B7F31D7152E0F8C00C15FF3D87E2E
511511- D2E"
512512- ~s:"050CB5265417FE2320BBB5A122B8E1A32BD699089851128E360E620A30C7E17B
513513- A41A666AF126CE100E5799B153B60528D5300D08489CA9178FB610A2006C254B
514514- 41F";
515515-516516- case Digestif.sha256 ~message:"sample"
517517- ~k:"0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C3257576
518518- 1793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E
519519- 1A0"
520520- ~r:"1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659
521521- D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E
522522- 1A7"
523523- ~s:"04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916
524524- E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7E
525525- CFC";
526526-527527- case Digestif.sha384 ~message:"sample"
528528- ~k:"1546A108BC23A15D6F21872F7DED661FA8431DDBD922D0DCDB77CC878C8553FF
529529- AD064C95A920A750AC9137E527390D2D92F153E66196966EA554D9ADFCB109C4
530530- 211"
531531- ~r:"1EA842A0E17D2DE4F92C15315C63DDF72685C18195C2BB95E572B9C5136CA4B4
532532- B576AD712A52BE9730627D16054BA40CC0B8D3FF035B12AE75168397F5D50C67
533533- 451"
534534- ~s:"1F21A3CEE066E1961025FB048BD5FE2B7924D0CD797BABE0A83B66F1E35EEAF5
535535- FDE143FA85DC394A7DEE766523393784484BDF3E00114A1C857CDE1AA203DB65
536536- D61";
537537-538538- case Digestif.sha512 ~message:"sample"
539539- ~k:"1DAE2EA071F8110DC26882D4D5EAE0621A3256FC8847FB9022E2B7D28E6F1019
540540- 8B1574FDD03A9053C08A1854A168AA5A57470EC97DD5CE090124EF52A2F7ECBF
541541- FD3"
542542- ~r:"0C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F1
543543- 74E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E37
544544- 7FA"
545545- ~s:"0617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF2
546546- 82623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A
547547- 67A";
548548-549549- case Digestif.sha1 ~message:"test"
550550- ~k:"0BB9F2BF4FE1038CCF4DABD7139A56F6FD8BB1386561BD3C6A4FC818B20DF5DD
551551- BA80795A947107A1AB9D12DAA615B1ADE4F7A9DC05E8E6311150F47F5C57CE8B
552552- 222"
553553- ~r:"13BAD9F29ABE20DE37EBEB823C252CA0F63361284015A3BF430A46AAA80B87B0
554554- 693F0694BD88AFE4E661FC33B094CD3B7963BED5A727ED8BD6A3A202ABE009D0
555555- 367"
556556- ~s:"1E9BB81FF7944CA409AD138DBBEE228E1AFCC0C890FC78EC8604639CB0DBDC90
557557- F717A99EAD9D272855D00162EE9527567DD6A92CBD629805C0445282BBC91679
558558- 7FF";
559559-560560- case Digestif.sha224 ~message:"test"
561561- ~k:"040D09FCF3C8A5F62CF4FB223CBBB2B9937F6B0577C27020A99602C25A011369
562562- 87E452988781484EDBBCF1C47E554E7FC901BC3085E5206D9F619CFF07E73D6F
563563- 706"
564564- ~r:"1C7ED902E123E6815546065A2C4AF977B22AA8EADDB68B2C1110E7EA44D42086
565565- BFE4A34B67DDC0E17E96536E358219B23A706C6A6E16BA77B65E1C595D43CAE1
566566- 7FB"
567567- ~s:"177336676304FCB343CE028B38E7B4FBA76C1C1B277DA18CAD2A8478B2A9A9F5
568568- BEC0F3BA04F35DB3E4263569EC6AADE8C92746E4C82F8299AE1B8F1739F8FD51
569569- 9A4";
570570-571571- case Digestif.sha256 ~message:"test"
572572- ~k:"01DE74955EFAABC4C4F17F8E84D881D1310B5392D7700275F82F145C61E84384
573573- 1AF09035BF7A6210F5A431A6A9E81C9323354A9E69135D44EBD2FCAA7731B909
574574- 258"
575575- ~r:"00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D807104
576576- 2EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656
577577- AA8"
578578- ~s:"0CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9
579579- FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694
580580- E86";
581581-582582- case Digestif.sha384 ~message:"test"
583583- ~k:"1F1FC4A349A7DA9A9E116BFDD055DC08E78252FF8E23AC276AC88B1770AE0B5D
584584- CEB1ED14A4916B769A523CE1E90BA22846AF11DF8B300C38818F713DADD85DE0
585585- C88"
586586- ~r:"14BEE21A18B6D8B3C93FAB08D43E739707953244FDBE924FA926D76669E7AC8C
587587- 89DF62ED8975C2D8397A65A49DCC09F6B0AC62272741924D479354D74FF60755
588588- 78C"
589589- ~s:"133330865C067A0EAF72362A65E2D7BC4E461E8C8995C3B6226A21BD1AA78F0E
590590- D94FE536A0DCA35534F0CD1510C41525D163FE9D74D134881E35141ED5E8E95B
591591- 979";
592592-593593- case Digestif.sha512 ~message:"test"
594594- ~k:"16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1
595595- B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC
596596- 56D"
597597- ~r:"13E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10
598598- CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47E
599599- E6D"
600600- ~s:"1FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78
601601- A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4D
602602- CE3"
603603-604604- ] in
605605- ("public key matches", `Quick, pub_rfc) ::
606606- ("public key compression and decompression", `Quick, pub_key_compression (module P521.Dsa)) ::
607607- List.mapi (fun i c -> "RFC 6979 A.2.7 " ^ string_of_int i, `Quick, c) cases
619619+ let cases =
620620+ [
621621+ case Digestif.sha1 ~message:"sample"
622622+ ~k:
623623+ "089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB\n\
624624+ \ \
625625+ 42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D\n\
626626+ \ 0F9"
627627+ ~r:
628628+ "0343B6EC45728975EA5CBA6659BBB6062A5FF89EEA58BE3C80B619F322C87910\n\
629629+ \ \
630630+ FE092F7D45BB0F8EEE01ED3F20BABEC079D202AE677B243AB40B5431D497C55D\n\
631631+ \ 75D"
632632+ ~s:
633633+ "0E7B0E675A9B24413D448B8CC119D2BF7B2D2DF032741C096634D6D65D0DBE3D\n\
634634+ \ \
635635+ 5694625FB9E8104D3B842C1B0E2D0B98BEA19341E8676AEF66AE4EBA3D5475D5\n\
636636+ \ D16";
637637+ case Digestif.sha224 ~message:"sample"
638638+ ~k:
639639+ "121415EC2CD7726330A61F7F3FA5DE14BE9436019C4DB8CB4041F3B54CF31BE0\n\
640640+ \ \
641641+ 493EE3F427FB906393D895A19C9523F3A1D54BB8702BD4AA9C99DAB2597B9211\n\
642642+ \ 3F3"
643643+ ~r:
644644+ "1776331CFCDF927D666E032E00CF776187BC9FDD8E69D0DABB4109FFE1B5E2A3\n\
645645+ \ \
646646+ 0715F4CC923A4A5E94D2503E9ACFED92857B7F31D7152E0F8C00C15FF3D87E2E\n\
647647+ \ D2E"
648648+ ~s:
649649+ "050CB5265417FE2320BBB5A122B8E1A32BD699089851128E360E620A30C7E17B\n\
650650+ \ \
651651+ A41A666AF126CE100E5799B153B60528D5300D08489CA9178FB610A2006C254B\n\
652652+ \ 41F";
653653+ case Digestif.sha256 ~message:"sample"
654654+ ~k:
655655+ "0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C3257576\n\
656656+ \ \
657657+ 1793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E\n\
658658+ \ 1A0"
659659+ ~r:
660660+ "1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659\n\
661661+ \ \
662662+ D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E\n\
663663+ \ 1A7"
664664+ ~s:
665665+ "04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916\n\
666666+ \ \
667667+ E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7E\n\
668668+ \ CFC";
669669+ case Digestif.sha384 ~message:"sample"
670670+ ~k:
671671+ "1546A108BC23A15D6F21872F7DED661FA8431DDBD922D0DCDB77CC878C8553FF\n\
672672+ \ \
673673+ AD064C95A920A750AC9137E527390D2D92F153E66196966EA554D9ADFCB109C4\n\
674674+ \ 211"
675675+ ~r:
676676+ "1EA842A0E17D2DE4F92C15315C63DDF72685C18195C2BB95E572B9C5136CA4B4\n\
677677+ \ \
678678+ B576AD712A52BE9730627D16054BA40CC0B8D3FF035B12AE75168397F5D50C67\n\
679679+ \ 451"
680680+ ~s:
681681+ "1F21A3CEE066E1961025FB048BD5FE2B7924D0CD797BABE0A83B66F1E35EEAF5\n\
682682+ \ \
683683+ FDE143FA85DC394A7DEE766523393784484BDF3E00114A1C857CDE1AA203DB65\n\
684684+ \ D61";
685685+ case Digestif.sha512 ~message:"sample"
686686+ ~k:
687687+ "1DAE2EA071F8110DC26882D4D5EAE0621A3256FC8847FB9022E2B7D28E6F1019\n\
688688+ \ \
689689+ 8B1574FDD03A9053C08A1854A168AA5A57470EC97DD5CE090124EF52A2F7ECBF\n\
690690+ \ FD3"
691691+ ~r:
692692+ "0C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F1\n\
693693+ \ \
694694+ 74E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E37\n\
695695+ \ 7FA"
696696+ ~s:
697697+ "0617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF2\n\
698698+ \ \
699699+ 82623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A\n\
700700+ \ 67A";
701701+ case Digestif.sha1 ~message:"test"
702702+ ~k:
703703+ "0BB9F2BF4FE1038CCF4DABD7139A56F6FD8BB1386561BD3C6A4FC818B20DF5DD\n\
704704+ \ \
705705+ BA80795A947107A1AB9D12DAA615B1ADE4F7A9DC05E8E6311150F47F5C57CE8B\n\
706706+ \ 222"
707707+ ~r:
708708+ "13BAD9F29ABE20DE37EBEB823C252CA0F63361284015A3BF430A46AAA80B87B0\n\
709709+ \ \
710710+ 693F0694BD88AFE4E661FC33B094CD3B7963BED5A727ED8BD6A3A202ABE009D0\n\
711711+ \ 367"
712712+ ~s:
713713+ "1E9BB81FF7944CA409AD138DBBEE228E1AFCC0C890FC78EC8604639CB0DBDC90\n\
714714+ \ \
715715+ F717A99EAD9D272855D00162EE9527567DD6A92CBD629805C0445282BBC91679\n\
716716+ \ 7FF";
717717+ case Digestif.sha224 ~message:"test"
718718+ ~k:
719719+ "040D09FCF3C8A5F62CF4FB223CBBB2B9937F6B0577C27020A99602C25A011369\n\
720720+ \ \
721721+ 87E452988781484EDBBCF1C47E554E7FC901BC3085E5206D9F619CFF07E73D6F\n\
722722+ \ 706"
723723+ ~r:
724724+ "1C7ED902E123E6815546065A2C4AF977B22AA8EADDB68B2C1110E7EA44D42086\n\
725725+ \ \
726726+ BFE4A34B67DDC0E17E96536E358219B23A706C6A6E16BA77B65E1C595D43CAE1\n\
727727+ \ 7FB"
728728+ ~s:
729729+ "177336676304FCB343CE028B38E7B4FBA76C1C1B277DA18CAD2A8478B2A9A9F5\n\
730730+ \ \
731731+ BEC0F3BA04F35DB3E4263569EC6AADE8C92746E4C82F8299AE1B8F1739F8FD51\n\
732732+ \ 9A4";
733733+ case Digestif.sha256 ~message:"test"
734734+ ~k:
735735+ "01DE74955EFAABC4C4F17F8E84D881D1310B5392D7700275F82F145C61E84384\n\
736736+ \ \
737737+ 1AF09035BF7A6210F5A431A6A9E81C9323354A9E69135D44EBD2FCAA7731B909\n\
738738+ \ 258"
739739+ ~r:
740740+ "00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D807104\n\
741741+ \ \
742742+ 2EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656\n\
743743+ \ AA8"
744744+ ~s:
745745+ "0CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9\n\
746746+ \ \
747747+ FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694\n\
748748+ \ E86";
749749+ case Digestif.sha384 ~message:"test"
750750+ ~k:
751751+ "1F1FC4A349A7DA9A9E116BFDD055DC08E78252FF8E23AC276AC88B1770AE0B5D\n\
752752+ \ \
753753+ CEB1ED14A4916B769A523CE1E90BA22846AF11DF8B300C38818F713DADD85DE0\n\
754754+ \ C88"
755755+ ~r:
756756+ "14BEE21A18B6D8B3C93FAB08D43E739707953244FDBE924FA926D76669E7AC8C\n\
757757+ \ \
758758+ 89DF62ED8975C2D8397A65A49DCC09F6B0AC62272741924D479354D74FF60755\n\
759759+ \ 78C"
760760+ ~s:
761761+ "133330865C067A0EAF72362A65E2D7BC4E461E8C8995C3B6226A21BD1AA78F0E\n\
762762+ \ \
763763+ D94FE536A0DCA35534F0CD1510C41525D163FE9D74D134881E35141ED5E8E95B\n\
764764+ \ 979";
765765+ case Digestif.sha512 ~message:"test"
766766+ ~k:
767767+ "16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1\n\
768768+ \ \
769769+ B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC\n\
770770+ \ 56D"
771771+ ~r:
772772+ "13E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10\n\
773773+ \ \
774774+ CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47E\n\
775775+ \ E6D"
776776+ ~s:
777777+ "1FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78\n\
778778+ \ \
779779+ A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4D\n\
780780+ \ CE3";
781781+ ]
782782+ in
783783+ ("public key matches", `Quick, pub_rfc)
784784+ :: ( "public key compression and decompression",
785785+ `Quick,
786786+ pub_key_compression (module P521.Dsa) )
787787+ :: List.mapi
788788+ (fun i c -> ("RFC 6979 A.2.7 " ^ string_of_int i, `Quick, c))
789789+ cases
608790609791let x25519 () =
610792 (* RFC 7748, 6.1 *)
611611- let a = of_hex "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
612612- and apub = of_hex "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
613613- and b = of_hex "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"
614614- and bpub = of_hex "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"
615615- and shared = of_hex "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
793793+ let a =
794794+ of_hex "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
795795+ and apub =
796796+ of_hex "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
797797+ and b =
798798+ of_hex "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"
799799+ and bpub =
800800+ of_hex "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"
801801+ and shared =
802802+ of_hex "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
616803 in
617617- let of_octets cs = match X25519.secret_of_octets cs with
618618- | Ok (a, b) -> a, b
804804+ let of_octets cs =
805805+ match X25519.secret_of_octets cs with
806806+ | Ok (a, b) -> (a, b)
619807 | Error _ -> Alcotest.fail "couldn't decode secret"
620808 in
621809 let apriv, apub' = of_octets a in
···623811 let bpriv, bpub' = of_octets b in
624812 Alcotest.(check bool __LOC__ true (String.equal bpub bpub'));
625813 (match X25519.key_exchange apriv bpub with
626626- | Ok shared' ->
627627- Alcotest.(check bool __LOC__ true (String.equal shared shared'))
628628- | Error e ->
629629- Alcotest.failf "X25519 key exchange apriv bpub failed %a" pp_error e);
814814+ | Ok shared' ->
815815+ Alcotest.(check bool __LOC__ true (String.equal shared shared'))
816816+ | Error e ->
817817+ Alcotest.failf "X25519 key exchange apriv bpub failed %a" pp_error e);
630818 match X25519.key_exchange bpriv apub with
631819 | Ok shared' ->
632632- Alcotest.(check bool __LOC__ true (String.equal shared shared'))
820820+ Alcotest.(check bool __LOC__ true (String.equal shared shared'))
633821 | Error e ->
634634- Alcotest.failf "X25519 key exchange bpriv apub failed %a" pp_error e
822822+ Alcotest.failf "X25519 key exchange bpriv apub failed %a" pp_error e
635823636824let ed25519 =
637825 let test secret public msg signature =
638826 Alcotest.(
639639- check string "public key is ok" (Ed25519.pub_to_octets public)
827827+ check string "public key is ok"
828828+ (Ed25519.pub_to_octets public)
640829 Ed25519.(pub_to_octets (pub_of_priv secret)));
641641- Alcotest.(check string "signature is ok" signature (Ed25519.sign ~key:secret msg));
642642- Alcotest.(check bool "verify is ok" true
643643- (Ed25519.verify ~key:public signature ~msg))
830830+ Alcotest.(
831831+ check string "signature is ok" signature (Ed25519.sign ~key:secret msg));
832832+ Alcotest.(
833833+ check bool "verify is ok" true (Ed25519.verify ~key:public signature ~msg))
644834 in
645835 let case i ~secret ~public ~msg ~signature =
646646- "RFC 8032 " ^ string_of_int i, `Quick, fun () ->
647647- let s =
648648- match Ed25519.priv_of_octets (of_hex secret) with
649649- | Ok p ->
650650- Alcotest.(check string "private key encoding is good"
651651- (of_hex secret) (Ed25519.priv_to_octets p));
652652- p
653653- | Error _ -> Alcotest.fail "failed to decode private key"
654654- and p =
655655- match Ed25519.pub_of_octets (of_hex public) with
656656- | Ok p ->
657657- Alcotest.(check string "public key encoding is good"
658658- (of_hex public) (Ed25519.pub_to_octets p));
659659- p
660660- | Error _ -> Alcotest.fail "failed to decode public key"
661661- and m = of_hex msg
662662- and si = of_hex signature
663663- in
664664- test s p m si
836836+ ( "RFC 8032 " ^ string_of_int i,
837837+ `Quick,
838838+ fun () ->
839839+ let s =
840840+ match Ed25519.priv_of_octets (of_hex secret) with
841841+ | Ok p ->
842842+ Alcotest.(
843843+ check string "private key encoding is good" (of_hex secret)
844844+ (Ed25519.priv_to_octets p));
845845+ p
846846+ | Error _ -> Alcotest.fail "failed to decode private key"
847847+ and p =
848848+ match Ed25519.pub_of_octets (of_hex public) with
849849+ | Ok p ->
850850+ Alcotest.(
851851+ check string "public key encoding is good" (of_hex public)
852852+ (Ed25519.pub_to_octets p));
853853+ p
854854+ | Error _ -> Alcotest.fail "failed to decode public key"
855855+ and m = of_hex msg
856856+ and si = of_hex signature in
857857+ test s p m si )
665858 in
666859 [
667860 case 1
···8101003 let g = Point.generator in
8111004 let g_bytes = Point.to_octets g in
8121005 (* Generator serialized should not be just the identity point *)
813813- Alcotest.(check bool) "generator has non-trivial encoding"
814814- true (String.length g_bytes > 1)
10061006+ Alcotest.(check bool)
10071007+ "generator has non-trivial encoding" true
10081008+ (String.length g_bytes > 1)
8151009 in
8161010 let test_point_serialization_roundtrip () =
8171011 (* Generate a key pair and check that the public key roundtrips through Point *)
···8191013 let pub_bytes = Dsa.pub_to_octets pub in
8201014 match Point.of_octets pub_bytes with
8211015 | Ok point ->
822822- let point_bytes = Point.to_octets point in
823823- Alcotest.(check string) "point roundtrip" pub_bytes point_bytes
10161016+ let point_bytes = Point.to_octets point in
10171017+ Alcotest.(check string) "point roundtrip" pub_bytes point_bytes
8241018 | Error e -> Alcotest.failf "of_octets failed: %a" pp_error e
8251019 in
8261020 let test_point_compressed_serialization () =
8271021 let _priv, pub = Dsa.generate () in
8281022 let pub_bytes = Dsa.pub_to_octets pub in
8291023 match Point.of_octets pub_bytes with
830830- | Ok point ->
831831- let compressed = Point.to_octets ~compress:true point in
832832- (* Compressed form should be shorter *)
833833- Alcotest.(check bool) "compressed is shorter"
834834- true (String.length compressed < String.length pub_bytes);
835835- (* Should be able to decode compressed form *)
836836- (match Point.of_octets compressed with
837837- | Ok point' ->
838838- let uncompressed = Point.to_octets point' in
839839- Alcotest.(check string) "compressed roundtrip" pub_bytes uncompressed
840840- | Error e -> Alcotest.failf "compressed of_octets failed: %a" pp_error e)
10241024+ | Ok point -> (
10251025+ let compressed = Point.to_octets ~compress:true point in
10261026+ (* Compressed form should be shorter *)
10271027+ Alcotest.(check bool)
10281028+ "compressed is shorter" true
10291029+ (String.length compressed < String.length pub_bytes);
10301030+ (* Should be able to decode compressed form *)
10311031+ match Point.of_octets compressed with
10321032+ | Ok point' ->
10331033+ let uncompressed = Point.to_octets point' in
10341034+ Alcotest.(check string)
10351035+ "compressed roundtrip" pub_bytes uncompressed
10361036+ | Error e -> Alcotest.failf "compressed of_octets failed: %a" pp_error e
10371037+ )
8411038 | Error e -> Alcotest.failf "of_octets failed: %a" pp_error e
8421039 in
8431040 let test_scalar_serialization_roundtrip () =
···8461043 let secret_bytes = Dh.secret_to_octets secret in
8471044 match Point.scalar_of_octets secret_bytes with
8481045 | Ok scalar ->
849849- let scalar_bytes = Point.scalar_to_octets scalar in
850850- Alcotest.(check string) "scalar roundtrip" secret_bytes scalar_bytes
10461046+ let scalar_bytes = Point.scalar_to_octets scalar in
10471047+ Alcotest.(check string) "scalar roundtrip" secret_bytes scalar_bytes
8511048 | Error e -> Alcotest.failf "scalar_of_octets failed: %a" pp_error e
8521049 in
8531050 let test_scalar_mult_with_generator () =
···8571054 let pub_bytes = Dsa.pub_to_octets pub in
8581055 match Point.scalar_of_octets priv_bytes with
8591056 | Ok scalar ->
860860- let computed_pub = Point.scalar_mult scalar Point.generator in
861861- let computed_bytes = Point.to_octets computed_pub in
862862- Alcotest.(check string) "scalar_mult generator" pub_bytes computed_bytes
10571057+ let computed_pub = Point.scalar_mult scalar Point.generator in
10581058+ let computed_bytes = Point.to_octets computed_pub in
10591059+ Alcotest.(check string) "scalar_mult generator" pub_bytes computed_bytes
8631060 | Error e -> Alcotest.failf "scalar_of_octets failed: %a" pp_error e
8641061 in
8651062 let test_point_add () =
···8741071 in
8751072 match Point.scalar_of_octets two with
8761073 | Ok scalar_2 ->
877877- let two_g = Point.scalar_mult scalar_2 g in
878878- Alcotest.(check string) "G + G = 2G"
879879- (Point.to_octets g_plus_g) (Point.to_octets two_g)
10741074+ let two_g = Point.scalar_mult scalar_2 g in
10751075+ Alcotest.(check string)
10761076+ "G + G = 2G" (Point.to_octets g_plus_g) (Point.to_octets two_g)
8801077 | Error e -> Alcotest.failf "scalar_of_octets 2 failed: %a" pp_error e
8811078 in
8821079 [
883883- name ^ " Point generator", `Quick, test_generator_not_identity;
884884- name ^ " Point serialization roundtrip", `Quick, test_point_serialization_roundtrip;
885885- name ^ " Point compressed serialization", `Quick, test_point_compressed_serialization;
886886- name ^ " Scalar serialization roundtrip", `Quick, test_scalar_serialization_roundtrip;
887887- name ^ " scalar_mult with generator", `Quick, test_scalar_mult_with_generator;
888888- name ^ " Point add", `Quick, test_point_add;
10801080+ (name ^ " Point generator", `Quick, test_generator_not_identity);
10811081+ ( name ^ " Point serialization roundtrip",
10821082+ `Quick,
10831083+ test_point_serialization_roundtrip );
10841084+ ( name ^ " Point compressed serialization",
10851085+ `Quick,
10861086+ test_point_compressed_serialization );
10871087+ ( name ^ " Scalar serialization roundtrip",
10881088+ `Quick,
10891089+ test_scalar_serialization_roundtrip );
10901090+ ( name ^ " scalar_mult with generator",
10911091+ `Quick,
10921092+ test_scalar_mult_with_generator );
10931093+ (name ^ " Point add", `Quick, test_point_add);
8891094 ]
89010958911096let p521_regression () =
892892- let key = of_hex
893893-"04 01 e4 f8 8a 40 3d fe 2f 65 a0 20 50 01 9b 87
894894-86 2c 30 2f 64 58 de 68 63 ab 92 72 88 04 c6 20
895895-7b 6f 9a 52 95 2d ff c7 80 df 50 44 b1 c4 91 e3
896896-a7 65 39 e6 9c cf ed d2 2a eb 47 84 ea 0f 3d 05
897897-dd 25 0e 00 95 6e 19 fb 7f b7 ce 47 5a 59 01 5f
898898-35 33 fc 85 ac 34 1a b0 7a 67 86 e8 3e 31 fe 38
899899-35 5c bb a1 b5 74 f4 47 a3 4c 0a f0 5f 6d 68 47
900900-85 0f e9 79 74 23 e8 75 47 6e 2b e5 ea 1b 0a 36
901901-b9 c3 94 ca b0"
902902- and data = of_hex
903903-"a8 98 57 b9 3f 58 02 c7 9a 37 e2 d7 89 d8 0b f4
904904-2d 84 c2 24 7c 7f ff 5f 7b 65 c5 17 cf 79 7d 36
905905-ff d3 9d 47 5e 68 90 57 f1 61 48 18 04 c3 fe ee
906906-59 b2 15 2d 75 8b 9a 3c 52 60 96 5c 52 a8 55 9c"
907907- and sigr = of_hex
908908-"3a 2c 99 0b 61 a1 da 06 20 bf 6c fe 1f d3 f8 2a
909909-cb f1 e5 0f 78 11 61 58 22 e4 a0 5f 18 81 8d 98
910910-f8 7a ca 8b f8 f8 cc b8 95 f7 6f 03 54 1b 66 6e
911911-cf c5 cb f1 7b 48 82 d2 c3 0e 0e 1b b4 ad e6 a4
912912-5c"
913913- and sigs = of_hex
914914-"01 7b 8c 82 a5 aa 80 c5 ee 23 0f 91 55 89 a7 b0
915915-3c 46 7f 56 ff b4 52 89 52 99 59 1e 5e b7 f2 c1
916916-df f8 a0 4f d3 dd 1d f0 07 78 3a 2f 29 d6 61 61
917917-55 dc 3b be 14 82 93 75 c2 0d be 7e ca 50 e4 3c
918918-98 88"
10971097+ let key =
10981098+ of_hex
10991099+ "04 01 e4 f8 8a 40 3d fe 2f 65 a0 20 50 01 9b 87\n\
11001100+ 86 2c 30 2f 64 58 de 68 63 ab 92 72 88 04 c6 20\n\
11011101+ 7b 6f 9a 52 95 2d ff c7 80 df 50 44 b1 c4 91 e3\n\
11021102+ a7 65 39 e6 9c cf ed d2 2a eb 47 84 ea 0f 3d 05\n\
11031103+ dd 25 0e 00 95 6e 19 fb 7f b7 ce 47 5a 59 01 5f\n\
11041104+ 35 33 fc 85 ac 34 1a b0 7a 67 86 e8 3e 31 fe 38\n\
11051105+ 35 5c bb a1 b5 74 f4 47 a3 4c 0a f0 5f 6d 68 47\n\
11061106+ 85 0f e9 79 74 23 e8 75 47 6e 2b e5 ea 1b 0a 36\n\
11071107+ b9 c3 94 ca b0"
11081108+ and data =
11091109+ of_hex
11101110+ "a8 98 57 b9 3f 58 02 c7 9a 37 e2 d7 89 d8 0b f4\n\
11111111+ 2d 84 c2 24 7c 7f ff 5f 7b 65 c5 17 cf 79 7d 36\n\
11121112+ ff d3 9d 47 5e 68 90 57 f1 61 48 18 04 c3 fe ee\n\
11131113+ 59 b2 15 2d 75 8b 9a 3c 52 60 96 5c 52 a8 55 9c"
11141114+ and sigr =
11151115+ of_hex
11161116+ "3a 2c 99 0b 61 a1 da 06 20 bf 6c fe 1f d3 f8 2a\n\
11171117+ cb f1 e5 0f 78 11 61 58 22 e4 a0 5f 18 81 8d 98\n\
11181118+ f8 7a ca 8b f8 f8 cc b8 95 f7 6f 03 54 1b 66 6e\n\
11191119+ cf c5 cb f1 7b 48 82 d2 c3 0e 0e 1b b4 ad e6 a4\n\
11201120+ 5c"
11211121+ and sigs =
11221122+ of_hex
11231123+ "01 7b 8c 82 a5 aa 80 c5 ee 23 0f 91 55 89 a7 b0\n\
11241124+ 3c 46 7f 56 ff b4 52 89 52 99 59 1e 5e b7 f2 c1\n\
11251125+ df f8 a0 4f d3 dd 1d f0 07 78 3a 2f 29 d6 61 61\n\
11261126+ 55 dc 3b be 14 82 93 75 c2 0d be 7e ca 50 e4 3c\n\
11271127+ 98 88"
9191128 in
9201129 match P521.Dsa.pub_of_octets key with
9211130 | Ok key ->
922922- Alcotest.check Alcotest.bool "regression 1" true
923923- (P521.Dsa.verify ~key (sigr, sigs) data)
11311131+ Alcotest.check Alcotest.bool "regression 1" true
11321132+ (P521.Dsa.verify ~key (sigr, sigs) data)
9241133 | Error _ -> Alcotest.fail "regression failed"
92511349261135let () =
···9351144 ("ECDSA RFC 6979 P256", ecdsa_rfc6979_p256);
9361145 ("ECDSA RFC 6979 P384", ecdsa_rfc6979_p384);
9371146 ("ECDSA RFC 6979 P521", ecdsa_rfc6979_p521);
938938- ("X25519", [ "RFC 7748", `Quick, x25519 ]);
11471147+ ("X25519", [ ("RFC 7748", `Quick, x25519) ]);
9391148 ("ED25519", ed25519);
940940- ("ECDSA P521 regression", [ "regreesion1", `Quick, p521_regression ]);
11491149+ ("ECDSA P521 regression", [ ("regreesion1", `Quick, p521_regression) ]);
9411150 ("P256 Point module", point_module_tests (module P256) "P256");
9421151 ("P384 Point module", point_module_tests (module P384) "P384");
9431152 ("P521 Point module", point_module_tests (module P521) "P521");
+132-137
tests/test_ec_wycheproof.ml
···11open Wycheproof
22-32open Crypto_ec
4354let ( let* ) = Result.bind
66-75let hex = Alcotest.testable Wycheproof.pp_hex Wycheproof.equal_hex
8697module Asn = struct
···119 let seq2 a b = Asn.S.(sequence2 (required a) (required b)) in
1210 let term = Asn.S.(seq2 (seq2 oid oid) bit_string_octets) in
1311 let ec_public_key = Asn.OID.(base 1 2 <|| [ 840; 10045; 2; 1 ]) in
1414- let prime_oid = match curve with
1212+ let prime_oid =
1313+ match curve with
1514 | "secp256r1" -> Asn.OID.(base 1 2 <|| [ 840; 10045; 3; 1; 7 ])
1615 | "secp384r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 34 ])
1716 | "secp521r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 35 ])
···2019 match Asn.decode (Asn.codec Asn.ber term) s with
2120 | Error _ -> Error "ASN1 parse error"
2221 | Ok (((oid1, oid2), data), rest) ->
2323- if String.length rest <> 0 then Error "ASN1 leftover"
2424- else if not (Asn.OID.equal oid1 ec_public_key) then
2525- Error "ASN1: wrong oid 1"
2626- else if not (Asn.OID.equal oid2 prime_oid) then Error "ASN1: wrong oid 2"
2727- else Ok data
2222+ if String.length rest <> 0 then Error "ASN1 leftover"
2323+ else if not (Asn.OID.equal oid1 ec_public_key) then
2424+ Error "ASN1: wrong oid 1"
2525+ else if not (Asn.OID.equal oid2 prime_oid) then
2626+ Error "ASN1: wrong oid 2"
2727+ else Ok data
28282929 let parse_signature cs =
3030- let asn = Asn.S.(sequence2 (required unsigned_integer) (required unsigned_integer)) in
3030+ let asn =
3131+ Asn.S.(sequence2 (required unsigned_integer) (required unsigned_integer))
3232+ in
3133 match Asn.(decode (codec der asn) cs) with
3234 | Error _ -> Error "ASN1 parse error"
3335 | Ok (r_s, rest) ->
3434- if String.length rest <> 0 then Error "ASN1 leftover"
3535- else
3636- Ok r_s
3636+ if String.length rest <> 0 then Error "ASN1 leftover" else Ok r_s
3737end
38383939let to_string_result ~pp_error = function
···4646 match total_len - String.length buf with
4747 | 0 -> Ok buf
4848 | n when n < 0 ->
4949- let is_zero = ref true in
5050- for i = 0 to abs n - 1 do
5151- if Bytes.(get_uint8 (Bytes.unsafe_of_string buf) i) <> 0 then
5252- is_zero := false
5353- done;
5454- if !is_zero then
5555- Ok (String.sub buf (abs n) total_len)
5656- else
5757- Error "input is too long"
5858- | pad_len ->
5959- Ok (String.make pad_len '\000' ^ buf)
4949+ let is_zero = ref true in
5050+ for i = 0 to abs n - 1 do
5151+ if Bytes.(get_uint8 (Bytes.unsafe_of_string buf) i) <> 0 then
5252+ is_zero := false
5353+ done;
5454+ if !is_zero then Ok (String.sub buf (abs n) total_len)
5555+ else Error "input is too long"
5656+ | pad_len -> Ok (String.make pad_len '\000' ^ buf)
60576158let len = function
6259 | "secp256r1" -> 32
···6865 let total_len = len curve in
6966 pad ~total_len s
70677171-type test = {
7272- public_key : string;
7373- raw_private_key : string;
7474- expected : string;
7575-}
6868+type test = { public_key : string; raw_private_key : string; expected : string }
76697770let perform_key_exchange curve ~public_key ~raw_private_key =
7871 to_string_result ~pp_error
7972 (match curve with
8080- | "secp256r1" ->
8181- begin match P256.Dh.secret_of_octets raw_private_key with
8282- | Ok (p, _) -> P256.Dh.key_exchange p public_key
8383- | Error _ -> assert false
8484- end
8585- | "secp384r1" ->
8686- begin match P384.Dh.secret_of_octets raw_private_key with
8787- | Ok (p, _) -> P384.Dh.key_exchange p public_key
8888- | Error _ -> assert false
8989- end
9090- | "secp521r1" ->
9191- begin match P521.Dh.secret_of_octets raw_private_key with
9292- | Ok (p, _) -> P521.Dh.key_exchange p public_key
9393- | Error _ -> assert false
9494- end
9595- | _ -> assert false)
7373+ | "secp256r1" -> begin
7474+ match P256.Dh.secret_of_octets raw_private_key with
7575+ | Ok (p, _) -> P256.Dh.key_exchange p public_key
7676+ | Error _ -> assert false
7777+ end
7878+ | "secp384r1" -> begin
7979+ match P384.Dh.secret_of_octets raw_private_key with
8080+ | Ok (p, _) -> P384.Dh.key_exchange p public_key
8181+ | Error _ -> assert false
8282+ end
8383+ | "secp521r1" -> begin
8484+ match P521.Dh.secret_of_octets raw_private_key with
8585+ | Ok (p, _) -> P521.Dh.key_exchange p public_key
8686+ | Error _ -> assert false
8787+ end
8888+ | _ -> assert false)
96899790let interpret_test ~tcId curve { public_key; raw_private_key; expected } () =
9891 match perform_key_exchange curve ~public_key ~raw_private_key with
9992 | Ok got -> Alcotest.check hex __LOC__ expected got
10093 | Error err ->
101101- Printf.ksprintf (fun s -> Alcotest.fail s) "While parsing %d: %s" tcId err
9494+ Printf.ksprintf (fun s -> Alcotest.fail s) "While parsing %d: %s" tcId err
1029510396type invalid_test = { public : string; private_ : string }
10497···115108type strategy = Test of test | Invalid_test of invalid_test | Skip
116109117110let make_ecdh_test curve (test : ecdh_test) =
118118- let ignored_flags = ["UnnamedCurve"] in
111111+ let ignored_flags = [ "UnnamedCurve" ] in
119112 let curve_compression_test curve =
120120- let curves = ["secp256r1"; "secp384r1"; "secp521r1"] in
113113+ let curves = [ "secp256r1"; "secp384r1"; "secp521r1" ] in
121114 test.tcId = 2 && List.exists (fun x -> String.equal x curve) curves
122115 in
123116 match test.result with
···125118 | Invalid ->
126119 Ok (Invalid_test { public = test.public; private_ = test.private_ })
127120 | Acceptable when curve_compression_test curve ->
128128- let* public_key = Asn.parse_point curve test.public in
129129- let* raw_private_key = parse_secret curve test.private_ in
130130- Ok (Test { public_key; raw_private_key; expected = test.shared })
121121+ let* public_key = Asn.parse_point curve test.public in
122122+ let* raw_private_key = parse_secret curve test.private_ in
123123+ Ok (Test { public_key; raw_private_key; expected = test.shared })
131124 | Acceptable -> Ok Skip
132125 | Valid ->
133133- let* public_key = Asn.parse_point curve test.public in
134134- let* raw_private_key = parse_secret curve test.private_ in
135135- Ok (Test { public_key; raw_private_key; expected = test.shared })
126126+ let* public_key = Asn.parse_point curve test.public in
127127+ let* raw_private_key = parse_secret curve test.private_ in
128128+ Ok (Test { public_key; raw_private_key; expected = test.shared })
136129137130let to_ecdh_tests curve (x : ecdh_test) =
138131 let name = Printf.sprintf "%d - %s" x.tcId x.comment in
···147140 let groups : ecdh_test_group list =
148141 List.map ecdh_test_group_exn data.testGroups
149142 in
150150- List.concat_map (fun (group : ecdh_test_group) ->
143143+ List.concat_map
144144+ (fun (group : ecdh_test_group) ->
151145 List.concat_map (to_ecdh_tests group.curve) group.tests)
152146 groups
153147···165159 in
166160 String.sub dgst 0 (min size (String.length dgst))
167161 in
168168- let verified (r,s) =
162162+ let verified (r, s) =
169163 match curve with
170170- | "secp256r1" ->
171171- begin match P256.Dsa.pub_of_octets key with
164164+ | "secp256r1" -> begin
165165+ match P256.Dsa.pub_of_octets key with
172166 | Ok key -> P256.Dsa.verify ~key (r, s) msg
173167 | Error _ -> assert false
174168 end
175175- | "secp384r1" ->
176176- begin match P384.Dsa.pub_of_octets key with
169169+ | "secp384r1" -> begin
170170+ match P384.Dsa.pub_of_octets key with
177171 | Ok key -> P384.Dsa.verify ~key (r, s) msg
178172 | Error _ -> assert false
179173 end
180180- | "secp521r1" ->
181181- begin match P521.Dsa.pub_of_octets key with
174174+ | "secp521r1" -> begin
175175+ match P521.Dsa.pub_of_octets key with
182176 | Ok key -> P521.Dsa.verify ~key (r, s) msg
183177 | Error _ -> assert false
184178 end
185179 | _ -> assert false
186180 in
187181 match tst.result with
188188- | Acceptable
189189- | Invalid ->
190190- let f () =
191191- match Asn.parse_signature tst.sig_ with
192192- | Ok (r, s) -> Alcotest.(check bool __LOC__ false (verified (r, s)))
193193- | Error _s -> ()
194194- in
195195- name, `Quick, f
182182+ | Acceptable | Invalid ->
183183+ let f () =
184184+ match Asn.parse_signature tst.sig_ with
185185+ | Ok (r, s) -> Alcotest.(check bool __LOC__ false (verified (r, s)))
186186+ | Error _s -> ()
187187+ in
188188+ (name, `Quick, f)
196189 | Valid ->
197197- let f () =
198198- match Asn.parse_signature tst.sig_ with
199199- | Ok (r, s) -> Alcotest.(check bool __LOC__ true (verified (r, s)))
200200- | Error s -> Alcotest.fail s
201201- in
202202- name, `Quick, f
190190+ let f () =
191191+ match Asn.parse_signature tst.sig_ with
192192+ | Ok (r, s) -> Alcotest.(check bool __LOC__ true (verified (r, s)))
193193+ | Error s -> Alcotest.fail s
194194+ in
195195+ (name, `Quick, f)
203196204197let to_ecdsa_tests (x : ecdsa_test_group) =
205205- List.map
206206- (make_ecdsa_test x.key.curve x.key.uncompressed x.sha)
207207- x.tests
198198+ List.map (make_ecdsa_test x.key.curve x.key.uncompressed x.sha) x.tests
208199209200let ecdsa_tests file =
210201 let data = load_file_exn file in
···222213 in
223214 match x.result with
224215 | Acceptable ->
225225- let f () =
226226- match
227227- X25519.key_exchange priv x.public,
228228- has_ignored_flag x ~ignored_flags:[ "LowOrderPublic" ]
229229- with
230230- | Ok _, true -> Alcotest.fail "acceptable should have errored"
231231- | Ok r, false ->
232232- Alcotest.(check bool __LOC__ true (String.equal r x.shared))
233233- | Error _, true -> ()
234234- | Error e, false -> Alcotest.failf "acceptable errored %a" pp_error e
235235- in
236236- name, `Quick, f
216216+ let f () =
217217+ match
218218+ ( X25519.key_exchange priv x.public,
219219+ has_ignored_flag x ~ignored_flags:[ "LowOrderPublic" ] )
220220+ with
221221+ | Ok _, true -> Alcotest.fail "acceptable should have errored"
222222+ | Ok r, false ->
223223+ Alcotest.(check bool __LOC__ true (String.equal r x.shared))
224224+ | Error _, true -> ()
225225+ | Error e, false -> Alcotest.failf "acceptable errored %a" pp_error e
226226+ in
227227+ (name, `Quick, f)
237228 | Invalid ->
238238- let f () =
239239- match X25519.key_exchange priv x.public with
240240- | Ok r -> Alcotest.(check bool __LOC__ false (String.equal r x.shared))
241241- | Error e -> Alcotest.failf "invalid errored %a" pp_error e
242242- in
243243- name, `Quick, f
229229+ let f () =
230230+ match X25519.key_exchange priv x.public with
231231+ | Ok r -> Alcotest.(check bool __LOC__ false (String.equal r x.shared))
232232+ | Error e -> Alcotest.failf "invalid errored %a" pp_error e
233233+ in
234234+ (name, `Quick, f)
244235 | Valid ->
245245- let f () =
246246- match X25519.key_exchange priv x.public with
247247- | Ok r -> Alcotest.(check bool __LOC__ true (String.equal r x.shared))
248248- | Error e -> Alcotest.failf "valid errored %a" pp_error e
249249- in
250250- name, `Quick, f
236236+ let f () =
237237+ match X25519.key_exchange priv x.public with
238238+ | Ok r -> Alcotest.(check bool __LOC__ true (String.equal r x.shared))
239239+ | Error e -> Alcotest.failf "valid errored %a" pp_error e
240240+ in
241241+ (name, `Quick, f)
251242252243let x25519_tests =
253244 let data = load_file_exn "x25519_test.json" in
254245 let groups : ecdh_test_group list =
255246 List.map ecdh_test_group_exn data.testGroups
256247 in
257257- List.concat_map (fun (group : ecdh_test_group) ->
258258- List.map to_x25519_test group.tests)
248248+ List.concat_map
249249+ (fun (group : ecdh_test_group) -> List.map to_x25519_test group.tests)
259250 groups
260251261252let to_ed25519_test (priv, pub) (x : dsa_test) =
262253 let name = Printf.sprintf "%d - %s" x.tcId x.comment in
263254 match x.result with
264255 | Invalid ->
265265- let f () =
266266- Alcotest.(check bool __LOC__ false (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg));
267267- let s = Ed25519.sign ~key:priv x.msg in
268268- Alcotest.(check bool __LOC__ false (String.equal s x.sig_))
269269- in
270270- name, `Quick, f
256256+ let f () =
257257+ Alcotest.(
258258+ check bool __LOC__ false (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg));
259259+ let s = Ed25519.sign ~key:priv x.msg in
260260+ Alcotest.(check bool __LOC__ false (String.equal s x.sig_))
261261+ in
262262+ (name, `Quick, f)
271263 | Valid ->
272272- let f () =
273273- Alcotest.(check bool __LOC__ true (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg));
274274- let s = Ed25519.sign ~key:priv x.msg in
275275- Alcotest.(check bool __LOC__ true (String.equal s x.sig_))
276276- in
277277- name, `Quick, f
264264+ let f () =
265265+ Alcotest.(
266266+ check bool __LOC__ true (Ed25519.verify ~key:pub x.sig_ ~msg:x.msg));
267267+ let s = Ed25519.sign ~key:priv x.msg in
268268+ Alcotest.(check bool __LOC__ true (String.equal s x.sig_))
269269+ in
270270+ (name, `Quick, f)
278271 | Acceptable -> assert false
279272280273let to_ed25519_keys (key : eddsa_key) =
281281- match Ed25519.priv_of_octets key.sk, Ed25519.pub_of_octets key.pk with
274274+ match (Ed25519.priv_of_octets key.sk, Ed25519.pub_of_octets key.pk) with
282275 | Ok priv, Ok pub ->
283283- assert (String.equal Ed25519.(pub_to_octets (pub_of_priv priv)) key.pk);
284284- priv, pub
276276+ assert (String.equal Ed25519.(pub_to_octets (pub_of_priv priv)) key.pk);
277277+ (priv, pub)
285278 | _ -> assert false
286279287280let ed25519_tests =
···289282 let groups : eddsa_test_group list =
290283 List.map eddsa_test_group_exn data.testGroups
291284 in
292292- List.concat_map (fun (group : eddsa_test_group) ->
285285+ List.concat_map
286286+ (fun (group : eddsa_test_group) ->
293287 let keys = to_ed25519_keys group.key in
294288 List.map (to_ed25519_test keys) group.tests)
295289 groups
296290297291let () =
298298- Alcotest.run "Wycheproof NIST curves" [
299299- ("ECDH P256 test vectors", ecdh_tests "ecdh_secp256r1_test.json") ;
300300- ("ECDSA P256 test vectors (SHA256)",
301301- ecdsa_tests "ecdsa_secp256r1_sha256_test.json") ;
302302- ("ECDSA P256 test vectors (SHA512)",
303303- ecdsa_tests "ecdsa_secp256r1_sha512_test.json") ;
304304- ("ECDH P384 test vectors", ecdh_tests "ecdh_secp384r1_test.json") ;
305305- ("ECDSA P384 test vectors (SHA384)",
306306- ecdsa_tests "ecdsa_secp384r1_sha384_test.json") ;
307307- ("ECDSA P384 test vectors (SHA512)",
308308- ecdsa_tests "ecdsa_secp384r1_sha512_test.json") ;
309309- ("ECDH P521 test vectors", ecdh_tests "ecdh_secp521r1_test.json") ;
310310- ("ECDSA P521 test vectors (SHA512)",
311311- ecdsa_tests "ecdsa_secp521r1_sha512_test.json") ;
312312- ("X25519 test vectors", x25519_tests) ;
313313- ("ED25519 test vectors", ed25519_tests) ;
314314- ]
292292+ Alcotest.run "Wycheproof NIST curves"
293293+ [
294294+ ("ECDH P256 test vectors", ecdh_tests "ecdh_secp256r1_test.json");
295295+ ( "ECDSA P256 test vectors (SHA256)",
296296+ ecdsa_tests "ecdsa_secp256r1_sha256_test.json" );
297297+ ( "ECDSA P256 test vectors (SHA512)",
298298+ ecdsa_tests "ecdsa_secp256r1_sha512_test.json" );
299299+ ("ECDH P384 test vectors", ecdh_tests "ecdh_secp384r1_test.json");
300300+ ( "ECDSA P384 test vectors (SHA384)",
301301+ ecdsa_tests "ecdsa_secp384r1_sha384_test.json" );
302302+ ( "ECDSA P384 test vectors (SHA512)",
303303+ ecdsa_tests "ecdsa_secp384r1_sha512_test.json" );
304304+ ("ECDH P521 test vectors", ecdh_tests "ecdh_secp521r1_test.json");
305305+ ( "ECDSA P521 test vectors (SHA512)",
306306+ ecdsa_tests "ecdsa_secp521r1_sha512_test.json" );
307307+ ("X25519 test vectors", x25519_tests);
308308+ ("ED25519 test vectors", ed25519_tests);
309309+ ]
+18-18
tests/test_entropy.ml
···11-21let data = ref ""
3243let cpu_bootstrap_check () =
54 match Crypto_rng.Entropy.cpu_rng_bootstrap with
65 | Error `Not_supported -> print_endline "no CPU RNG available"
77- | Ok cpu_rng_bootstrap ->
88- match cpu_rng_bootstrap 1 with
99- | exception Failure _ -> print_endline "bad CPU RNG"
1010- | data' ->
1111- data := data';
1212- for i = 0 to 10 do
1313- try
1414- let data' = cpu_rng_bootstrap 1 in
1515- if String.equal !data data' then begin
1616- Ohex.pp Format.std_formatter data';
1717- failwith ("same data from CPU bootstrap at " ^ string_of_int i);
1818- end;
1919- data := data'
2020- with Failure _ -> print_endline ("CPU RNG failed at " ^ string_of_int i)
2121- done
66+ | Ok cpu_rng_bootstrap -> (
77+ match cpu_rng_bootstrap 1 with
88+ | exception Failure _ -> print_endline "bad CPU RNG"
99+ | data' ->
1010+ data := data';
1111+ for i = 0 to 10 do
1212+ try
1313+ let data' = cpu_rng_bootstrap 1 in
1414+ if String.equal !data data' then begin
1515+ Ohex.pp Format.std_formatter data';
1616+ failwith ("same data from CPU bootstrap at " ^ string_of_int i)
1717+ end;
1818+ data := data'
1919+ with Failure _ ->
2020+ print_endline ("CPU RNG failed at " ^ string_of_int i)
2121+ done)
22222323let whirlwind_bootstrap_check () =
2424 for i = 0 to 10 do
2525 let data' = Crypto_rng.Entropy.whirlwind_bootstrap 1 in
2626 if String.equal !data data' then begin
2727 Ohex.pp Format.std_formatter data';
2828- failwith ("same data from whirlwind bootstrap at " ^ string_of_int i);
2828+ failwith ("same data from whirlwind bootstrap at " ^ string_of_int i)
2929 end;
3030 data := data'
3131 done
···3535 let data' = Crypto_rng.Entropy.interrupt_hook () in
3636 if String.equal !data data' then begin
3737 Ohex.pp Format.std_formatter data';
3838- failwith ("same data from timer at " ^ string_of_int i);
3838+ failwith ("same data from timer at " ^ string_of_int i)
3939 end;
4040 data := data'
4141 done
+39-36
tests/test_numeric.ml
···11open OUnit2
22-32open Crypto.Uncommon
43open Crypto_pk
55-64open Test_common
7586let n_encode_decode_selftest ~typ ~bound n =
99- typ ^ "selftest" >:: times ~n @@ fun _ ->
1010- let r = Z_extra.gen bound in
1111- let s = Z_extra.(of_octets_be @@ to_octets_be r)
1212- and t = Z_extra.(of_octets_be @@ to_octets_be ~size:24 r) in
1313- assert_equal r s;
1414- assert_equal r t
77+ typ ^ "selftest"
88+ >:: times ~n @@ fun _ ->
99+ let r = Z_extra.gen bound in
1010+ let s = Z_extra.(of_octets_be @@ to_octets_be r)
1111+ and t = Z_extra.(of_octets_be @@ to_octets_be ~size:24 r) in
1212+ assert_equal r s;
1313+ assert_equal r t
15141615let n_decode_reencode_selftest ~typ ~bytes n =
1717- typ ^ " selftest" >:: times ~n @@ fun _ ->
1818- let cs = Crypto_rng.generate bytes in
1919- let cs' = Z_extra.(to_octets_be ~size:bytes @@ of_octets_be cs) in
2020- assert_oct_equal cs cs'
1616+ typ ^ " selftest"
1717+ >:: times ~n @@ fun _ ->
1818+ let cs = Crypto_rng.generate bytes in
1919+ let cs' = Z_extra.(to_octets_be ~size:bytes @@ of_octets_be cs) in
2020+ assert_oct_equal cs cs'
21212222let random_n_selftest ~typ n bounds =
2323- typ ^ " selftest" >::: (
2424- bounds |> List.map @@ fun (lo, hi) ->
2525- "selftest" >:: times ~n @@ fun _ ->
2626- let x = Z_extra.gen_r lo hi in
2727- if x < lo || x >= hi then assert_failure "range error"
2828- )
2323+ typ ^ " selftest"
2424+ >::: (bounds
2525+ |> List.map @@ fun (lo, hi) ->
2626+ "selftest"
2727+ >:: times ~n @@ fun _ ->
2828+ let x = Z_extra.gen_r lo hi in
2929+ if x < lo || x >= hi then assert_failure "range error")
29303030-let int_safe_bytes = Sys.word_size // 8 - 1
3131+let int_safe_bytes = (Sys.word_size // 8) - 1
31323232-let suite = [
3333- "Numeric extraction 1" >::: [
3434- n_encode_decode_selftest
3535- ~typ:"z" ~bound:Z.(of_int64 Int64.max_int) 2000 ;
3636- ] ;
3737-3838- "Numeric extraction 2" >::: [
3939- n_decode_reencode_selftest ~typ:"z" ~bytes:37 2000 ;
4040- ];
4141-4242- "RNG extraction" >::: [
4343- random_n_selftest ~typ:"Z" 1000 [
4444- Z.(of_int 7, of_int 135);
4545- Z.(of_int 0, of_int 536870913);
4646- Z.(of_int 0, of_int64 2305843009213693953L)
4747- ] ;
3333+let suite =
3434+ [
3535+ "Numeric extraction 1"
3636+ >::: [
3737+ n_encode_decode_selftest ~typ:"z"
3838+ ~bound:Z.(of_int64 Int64.max_int)
3939+ 2000;
4040+ ];
4141+ "Numeric extraction 2"
4242+ >::: [ n_decode_reencode_selftest ~typ:"z" ~bytes:37 2000 ];
4343+ "RNG extraction"
4444+ >::: [
4545+ random_n_selftest ~typ:"Z" 1000
4646+ [
4747+ Z.(of_int 7, of_int 135);
4848+ Z.(of_int 0, of_int 536870913);
4949+ Z.(of_int 0, of_int64 2305843009213693953L);
5050+ ];
5151+ ];
4852 ]
4949-]