···11-let () =
22- let vx = Ohex.decode in
33- Crypto_rng_unix.use_default ();
44- (* ARC4 192-bit *)
55- let key = vx "0102030405060708090a0b0c0d0e0f101112131415161718" in
66- let k = Crypto.ARC4.of_secret key in
77- let pt = String.make 16 '\x00' in
88- let r = Crypto.ARC4.encrypt ~key:k pt in
99- Printf.printf "ARC4-192: %s\n" (Ohex.encode r.message);
1010- (* AES-GCM 256 with cafebabe nonce *)
1111- let gkey =
1212- Crypto.AES.GCM.of_secret
1313- (vx "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308")
1414- in
1515- let nonce = vx "cafebabefacedbaddecaf888" in
1616- let p =
1717- vx
1818- "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39"
1919- in
2020- let adata = vx "feedfacedeadbeeffeedfacedeadbeefabaddad2" in
2121- let ct, tag =
2222- Crypto.AES.GCM.authenticate_encrypt_tag ~key:gkey ~nonce ~adata p
2323- in
2424- Printf.printf "GCM-256-CT: %s\n" (Ohex.encode ct);
2525- Printf.printf "GCM-256-Tag: %s\n" (Ohex.encode tag)
···11let vx = Ohex.decode
2233-let test_encrypt_decrypt () =
44- let key = vx "404142434445464748494a4b4c4d4e4f" in
55- let nonce = vx "10111213141516171819202122" in
66- let adata = vx "0001020304050607" in
77- let plaintext = vx "20212223" in
88- let k = Crypto.AES.CCM16.of_secret key in
99- let ct =
1010- Crypto.AES.CCM16.authenticate_encrypt ~key:k ~nonce ~adata plaintext
1111- in
1212- Alcotest.(check int) "ct length" (4 + 16) (String.length ct);
1313- match Crypto.AES.CCM16.authenticate_decrypt ~key:k ~nonce ~adata ct with
1414- | Some pt -> Alcotest.(check string) "decrypt" plaintext pt
1515- | None -> Alcotest.fail "CCM16 decrypt failed"
1616-33+(* CCM16 roundtrip *)
174let test_roundtrip () =
185 let key = Crypto_rng.generate 16 in
196 let nonce = Crypto_rng.generate 12 in
···4128 in
4229 Alcotest.(check bool) "tamper rejected" true (Option.is_none result)
43303131+(* Regression: no AD vs empty AD should produce same ciphertext
3232+ (https://github.com/mirleft/ocaml-nocrypto/issues/166) *)
3333+let test_no_vs_empty_ad () =
3434+ let key =
3535+ Crypto.AES.CCM16.of_secret (vx "000102030405060708090a0b0c0d0e0f")
3636+ in
3737+ let nonce = vx "0001020304050607" in
3838+ let plaintext = "hello" in
3939+ Alcotest.(check string)
4040+ "no vs empty ad"
4141+ (Crypto.AES.CCM16.authenticate_encrypt ~key ~nonce plaintext)
4242+ (Crypto.AES.CCM16.authenticate_encrypt ~adata:"" ~key ~nonce plaintext)
4343+4444+(* Regression: empty message encrypt/decrypt *)
4545+let test_empty_message () =
4646+ let key =
4747+ Crypto.AES.CCM16.of_secret (vx "000102030405060708090a0b0c0d0e0f")
4848+ in
4949+ let nonce = vx "0001020304050607" in
5050+ let adata = "hello" in
5151+ let p = "" in
5252+ let cipher = Crypto.AES.CCM16.authenticate_encrypt ~adata ~key ~nonce p in
5353+ match Crypto.AES.CCM16.authenticate_decrypt ~key ~nonce ~adata cipher with
5454+ | Some x -> Alcotest.(check string) "empty msg" p x
5555+ | None -> Alcotest.fail "empty message decrypt failed"
5656+5757+(* Nonce length validation: valid range is 7..13 *)
5858+let test_short_nonce () =
5959+ let key =
6060+ Crypto.AES.CCM16.of_secret (vx "000102030405060708090a0b0c0d0e0f")
6161+ in
6262+ let plaintext = "hello" in
6363+ Alcotest.check_raises "short nonce"
6464+ (Invalid_argument "Crypto: CCM: nonce length not between 7 and 13: 0")
6565+ (fun () ->
6666+ ignore (Crypto.AES.CCM16.authenticate_encrypt ~key ~nonce:"" plaintext))
6767+6868+let test_long_nonce () =
6969+ let key =
7070+ Crypto.AES.CCM16.of_secret (vx "000102030405060708090a0b0c0d0e0f")
7171+ in
7272+ let nonce = vx "000102030405060708090a0b0c0d" in
7373+ let plaintext = "hello" in
7474+ Alcotest.check_raises "long nonce"
7575+ (Invalid_argument "Crypto: CCM: nonce length not between 7 and 13: 14")
7676+ (fun () ->
7777+ ignore (Crypto.AES.CCM16.authenticate_encrypt ~key ~nonce plaintext))
7878+7979+(* TLS regression test from mirage-crypto
8080+ (discovered while moving ocaml-tls to string) *)
8181+let test_tls_regression () =
8282+ let key =
8383+ Crypto.AES.CCM16.of_secret (vx "063a96fd15f982d55aad5bf9d0987546")
8484+ in
8585+ let nonce = vx "81cd47581880 9de0c6557c31" in
8686+ let adata = vx "1703030017" in
8787+ let data = vx "080000020000 16" in
8888+ let expected = vx "94ca065ac948c5d692fd5fabc8500611a07c4f6e071090" in
8989+ let cipher = Crypto.AES.CCM16.authenticate_encrypt ~adata ~key ~nonce data in
9090+ Alcotest.(check string) "tls encrypt" expected cipher;
9191+ match Crypto.AES.CCM16.authenticate_decrypt ~key ~nonce ~adata expected with
9292+ | None -> Alcotest.fail "tls decrypt failed"
9393+ | Some x -> Alcotest.(check string) "tls decrypt" x data
9494+9595+(* Tag API roundtrip *)
9696+let test_tag_api () =
9797+ let key = Crypto_rng.generate 16 in
9898+ let nonce = Crypto_rng.generate 12 in
9999+ let adata = "tag api" in
100100+ let plaintext = "message" in
101101+ let k = Crypto.AES.CCM16.of_secret key in
102102+ let ct, tag =
103103+ Crypto.AES.CCM16.authenticate_encrypt_tag ~key:k ~nonce ~adata plaintext
104104+ in
105105+ match
106106+ Crypto.AES.CCM16.authenticate_decrypt_tag ~key:k ~nonce ~adata ~tag ct
107107+ with
108108+ | Some pt -> Alcotest.(check string) "tag api" plaintext pt
109109+ | None -> Alcotest.fail "tag API decrypt failed"
110110+44111let suite =
45112 ( "ccm",
46113 [
4747- Alcotest.test_case "encrypt/decrypt" `Quick test_encrypt_decrypt;
48114 Alcotest.test_case "roundtrip" `Quick test_roundtrip;
49115 Alcotest.test_case "tamper" `Quick test_tamper;
116116+ Alcotest.test_case "no vs empty AD" `Quick test_no_vs_empty_ad;
117117+ Alcotest.test_case "empty message" `Quick test_empty_message;
118118+ Alcotest.test_case "short nonce" `Quick test_short_nonce;
119119+ Alcotest.test_case "long nonce" `Quick test_long_nonce;
120120+ Alcotest.test_case "TLS regression" `Quick test_tls_regression;
121121+ Alcotest.test_case "tag API" `Quick test_tag_api;
50122 ] )
+79
test/test_chacha20.ml
···1818 let ct = Crypto.Chacha20.crypt ~key:k ~nonce ~ctr:1L plaintext in
1919 Alcotest.(check string) "rfc8439" expected ct
20202121+(* draft-strombergson-chacha-test-vectors-01: all-zero key and nonce *)
2222+let test_chacha20_zero () =
2323+ let key = vx (String.make 64 '0') in
2424+ let nonce = vx (String.make 16 '0') in
2525+ let plaintext = String.make 128 '\x00' in
2626+ let expected =
2727+ vx
2828+ ("76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586"
2929+ ^ "9f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f"
3030+ )
3131+ in
3232+ let k = Crypto.Chacha20.of_secret key in
3333+ let ct = Crypto.Chacha20.crypt ~key:k ~nonce plaintext in
3434+ Alcotest.(check string) "chacha20 all-zero" expected ct
3535+3636+(* draft-strombergson-chacha-test-vectors-01: key=01000...0 *)
3737+let test_chacha20_key01 () =
3838+ let key = vx ("01" ^ String.make 62 '0') in
3939+ let nonce = vx (String.make 16 '0') in
4040+ let plaintext = String.make 128 '\x00' in
4141+ let expected =
4242+ vx
4343+ ("c5d30a7ce1ec119378c84f487d775a8542f13ece238a9455e8229e888de85bbd29eb63d0a17a5b999b52da22be4023eb07620a54f6fa6ad8737b71eb0464dac0"
4444+ ^ "10f656e6d1fd55053e50c4875c9930a33f6d0263bd14dfd6ab8c70521c19338b2308b95cf8d0bb7d202d2102780ea3528f1cb48560f76b20f382b942500fceac"
4545+ )
4646+ in
4747+ let k = Crypto.Chacha20.of_secret key in
4848+ let ct = Crypto.Chacha20.crypt ~key:k ~nonce plaintext in
4949+ Alcotest.(check string) "chacha20 key01" expected ct
5050+5151+(* draft-strombergson-chacha-test-vectors-01: all-ff key and nonce *)
5252+let test_chacha20_all_ff () =
5353+ let key = vx (String.make 64 'f') in
5454+ let nonce = vx (String.make 16 'f') in
5555+ let plaintext = String.make 128 '\x00' in
5656+ let expected =
5757+ vx
5858+ ("d9bf3f6bce6ed0b54254557767fb57443dd4778911b606055c39cc25e674b8363feabc57fde54f790c52c8ae43240b79d49042b777bfd6cb80e931270b7f50eb"
5959+ ^ "5bac2acd86a836c5dc98c116c1217ec31d3a63a9451319f097f3b4d6dab0778719477d24d24b403a12241d7cca064f790f1d51ccaff6b1667d4bbca1958c4306"
6060+ )
6161+ in
6262+ let k = Crypto.Chacha20.of_secret key in
6363+ let ct = Crypto.Chacha20.crypt ~key:k ~nonce plaintext in
6464+ Alcotest.(check string) "chacha20 all-ff" expected ct
6565+6666+(* RFC 8439 Section 2.8.2 — ChaCha20-Poly1305 AEAD *)
6767+let test_rfc8439_aead () =
6868+ let key =
6969+ Crypto.Chacha20.of_secret
7070+ (vx "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
7171+ in
7272+ let nonce = vx "070000004041424344454647" in
7373+ let adata = vx "50515253c0c1c2c3c4c5c6c7" in
7474+ let plaintext =
7575+ "Ladies and Gentlemen of the class of '99: If I could offer you only one \
7676+ tip for the future, sunscreen would be it."
7777+ in
7878+ let expected_ct =
7979+ vx
8080+ "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116"
8181+ in
8282+ let expected_tag = vx "1ae10b594f09e26a7e902ecbd0600691" in
8383+ let ct, tag =
8484+ Crypto.Chacha20.authenticate_encrypt_tag ~key ~nonce ~adata plaintext
8585+ in
8686+ Alcotest.(check string) "rfc8439 aead ct" expected_ct ct;
8787+ Alcotest.(check string) "rfc8439 aead tag" expected_tag tag;
8888+ match Crypto.Chacha20.authenticate_decrypt_tag ~key ~nonce ~adata ~tag ct with
8989+ | Some pt -> Alcotest.(check string) "rfc8439 aead decrypt" plaintext pt
9090+ | None -> Alcotest.fail "RFC 8439 AEAD decrypt failed"
9191+2192let test_aead_roundtrip () =
2293 let key = Crypto_rng.generate 32 in
2394 let nonce = Crypto_rng.generate 12 in
···64135let suite =
65136 ( "chacha20",
66137 [
138138+ (* RFC 8439 stream cipher *)
67139 Alcotest.test_case "RFC 8439 stream" `Quick test_rfc8439_stream;
140140+ (* draft-strombergson test vectors *)
141141+ Alcotest.test_case "all-zero key/nonce" `Quick test_chacha20_zero;
142142+ Alcotest.test_case "key 01..0" `Quick test_chacha20_key01;
143143+ Alcotest.test_case "all-ff key/nonce" `Quick test_chacha20_all_ff;
144144+ (* RFC 8439 AEAD *)
145145+ Alcotest.test_case "RFC 8439 AEAD" `Quick test_rfc8439_aead;
146146+ (* Roundtrip / tamper *)
68147 Alcotest.test_case "AEAD roundtrip" `Quick test_aead_roundtrip;
69148 Alcotest.test_case "AEAD tamper" `Quick test_aead_tamper;
70149 Alcotest.test_case "AEAD tag API" `Quick test_aead_tag_api;
+269-19
test/test_cipher_block.ml
···55 vx
66 "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"
7788-let test_aes_ecb () =
88+(* -- AES ECB ------------------------------------------------------------ *)
99+1010+let test_aes_ecb_128 () =
911 let key = Crypto.AES.ECB.of_secret (vx "2b7e151628aed2a6abf7158809cf4f3c") in
1012 let expected =
1113 vx
1214 "3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4"
1315 in
1416 let enc = Crypto.AES.ECB.encrypt ~key nist_plaintext in
1515- Alcotest.(check string) "ecb encrypt" expected enc;
1717+ Alcotest.(check string) "ecb-128 encrypt" expected enc;
1618 let dec = Crypto.AES.ECB.decrypt ~key enc in
1717- Alcotest.(check string) "ecb decrypt" nist_plaintext dec
1919+ Alcotest.(check string) "ecb-128 decrypt" nist_plaintext dec
18201919-let test_aes_cbc () =
2121+(* NIST SP 800-38A F.1.3 / F.1.4 — AES-192 ECB *)
2222+let test_aes_ecb_192 () =
2323+ let key =
2424+ Crypto.AES.ECB.of_secret
2525+ (vx "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b")
2626+ in
2727+ let expected =
2828+ vx
2929+ "bd334f1d6e45f25ff712a214571fa5cc974104846d0ad3ad7734ecb3ecee4eefef7afd2270e2e60adce0ba2face6444e9a4b41ba738d6c72fb16691603c18e0e"
3030+ in
3131+ let enc = Crypto.AES.ECB.encrypt ~key nist_plaintext in
3232+ Alcotest.(check string) "ecb-192 encrypt" expected enc;
3333+ let dec = Crypto.AES.ECB.decrypt ~key enc in
3434+ Alcotest.(check string) "ecb-192 decrypt" nist_plaintext dec
3535+3636+(* NIST SP 800-38A F.1.5 / F.1.6 — AES-256 ECB *)
3737+let test_aes_ecb_256 () =
3838+ let key =
3939+ Crypto.AES.ECB.of_secret
4040+ (vx "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4")
4141+ in
4242+ let expected =
4343+ vx
4444+ "f3eed1bdb5d2a03c064b5a7e3db181f8591ccb10d410ed26dc5ba74a31362870b6ed21b99ca6f4f9f153e7b1beafed1d23304b7a39f9f3ff067d8d8f9e24ecc7"
4545+ in
4646+ let enc = Crypto.AES.ECB.encrypt ~key nist_plaintext in
4747+ Alcotest.(check string) "ecb-256 encrypt" expected enc;
4848+ let dec = Crypto.AES.ECB.decrypt ~key enc in
4949+ Alcotest.(check string) "ecb-256 decrypt" nist_plaintext dec
5050+5151+(* -- AES CBC ------------------------------------------------------------ *)
5252+5353+let test_aes_cbc_128 () =
2054 let key = Crypto.AES.CBC.of_secret (vx "2b7e151628aed2a6abf7158809cf4f3c") in
2155 let iv = vx "000102030405060708090a0b0c0d0e0f" in
2256 let expected =
···2458 "7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a7"
2559 in
2660 let enc = Crypto.AES.CBC.encrypt ~key ~iv nist_plaintext in
2727- Alcotest.(check string) "cbc encrypt" expected enc;
6161+ Alcotest.(check string) "cbc-128 encrypt" expected enc;
2862 let dec = Crypto.AES.CBC.decrypt ~key ~iv enc in
2929- Alcotest.(check string) "cbc decrypt" nist_plaintext dec
6363+ Alcotest.(check string) "cbc-128 decrypt" nist_plaintext dec
30643131-let test_aes_ctr () =
6565+(* NIST SP 800-38A F.2.3 / F.2.4 — AES-192 CBC *)
6666+let test_aes_cbc_192 () =
6767+ let key =
6868+ Crypto.AES.CBC.of_secret
6969+ (vx "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b")
7070+ in
7171+ let iv = vx "000102030405060708090a0b0c0d0e0f" in
7272+ let expected =
7373+ vx
7474+ "4f021db243bc633d7178183a9fa071e8b4d9ada9ad7dedf4e5e738763f69145a571b242012fb7ae07fa9baac3df102e008b0e27988598881d920a9e64f5615cd"
7575+ in
7676+ let enc = Crypto.AES.CBC.encrypt ~key ~iv nist_plaintext in
7777+ Alcotest.(check string) "cbc-192 encrypt" expected enc;
7878+ let dec = Crypto.AES.CBC.decrypt ~key ~iv enc in
7979+ Alcotest.(check string) "cbc-192 decrypt" nist_plaintext dec
8080+8181+(* NIST SP 800-38A F.2.5 / F.2.6 — AES-256 CBC *)
8282+let test_aes_cbc_256 () =
8383+ let key =
8484+ Crypto.AES.CBC.of_secret
8585+ (vx "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4")
8686+ in
8787+ let iv = vx "000102030405060708090a0b0c0d0e0f" in
8888+ let expected =
8989+ vx
9090+ "f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b"
9191+ in
9292+ let enc = Crypto.AES.CBC.encrypt ~key ~iv nist_plaintext in
9393+ Alcotest.(check string) "cbc-256 encrypt" expected enc;
9494+ let dec = Crypto.AES.CBC.decrypt ~key ~iv enc in
9595+ Alcotest.(check string) "cbc-256 decrypt" nist_plaintext dec
9696+9797+(* -- AES CTR ------------------------------------------------------------ *)
9898+9999+let test_aes_ctr_128 () =
32100 let key = Crypto.AES.CTR.of_secret (vx "2b7e151628aed2a6abf7158809cf4f3c") in
33101 let ctr =
34102 Crypto.AES.CTR.ctr_of_octets (vx "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
···38106 "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee"
39107 in
40108 let enc = Crypto.AES.CTR.encrypt ~key ~ctr nist_plaintext in
4141- Alcotest.(check string) "ctr encrypt" expected enc;
109109+ Alcotest.(check string) "ctr-128 encrypt" expected enc;
42110 let dec = Crypto.AES.CTR.decrypt ~key ~ctr enc in
4343- Alcotest.(check string) "ctr decrypt" nist_plaintext dec
111111+ Alcotest.(check string) "ctr-128 decrypt" nist_plaintext dec
441124545-let test_aes_gcm_roundtrip () =
113113+(* NIST SP 800-38A F.5.3 / F.5.4 — AES-192 CTR *)
114114+let test_aes_ctr_192 () =
115115+ let key =
116116+ Crypto.AES.CTR.of_secret
117117+ (vx "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b")
118118+ in
119119+ let ctr =
120120+ Crypto.AES.CTR.ctr_of_octets (vx "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
121121+ in
122122+ let expected =
123123+ vx
124124+ "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050"
125125+ in
126126+ let enc = Crypto.AES.CTR.encrypt ~key ~ctr nist_plaintext in
127127+ Alcotest.(check string) "ctr-192 encrypt" expected enc;
128128+ let dec = Crypto.AES.CTR.decrypt ~key ~ctr enc in
129129+ Alcotest.(check string) "ctr-192 decrypt" nist_plaintext dec
130130+131131+(* NIST SP 800-38A F.5.5 / F.5.6 — AES-256 CTR *)
132132+let test_aes_ctr_256 () =
133133+ let key =
134134+ Crypto.AES.CTR.of_secret
135135+ (vx "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4")
136136+ in
137137+ let ctr =
138138+ Crypto.AES.CTR.ctr_of_octets (vx "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
139139+ in
140140+ let expected =
141141+ vx
142142+ "601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c52b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6"
143143+ in
144144+ let enc = Crypto.AES.CTR.encrypt ~key ~ctr nist_plaintext in
145145+ Alcotest.(check string) "ctr-256 encrypt" expected enc;
146146+ let dec = Crypto.AES.CTR.decrypt ~key ~ctr enc in
147147+ Alcotest.(check string) "ctr-256 decrypt" nist_plaintext dec
148148+149149+(* -- AES GCM (NIST SP 800-38D) ----------------------------------------- *)
150150+151151+(* Test Case 1: empty plaintext, no AAD, 128-bit key *)
152152+let test_aes_gcm_nist_1 () =
153153+ let key = Crypto.AES.GCM.of_secret (vx "00000000000000000000000000000000") in
154154+ let nonce = vx "000000000000000000000000" in
155155+ let expected_tag = vx "58e2fccefa7e3061367f1d57a4e7455a" in
156156+ let ct, tag =
157157+ Crypto.AES.GCM.authenticate_encrypt_tag ~key ~nonce ~adata:"" ""
158158+ in
159159+ Alcotest.(check string) "gcm-1 ct" "" ct;
160160+ Alcotest.(check string) "gcm-1 tag" expected_tag tag;
161161+ match
162162+ Crypto.AES.GCM.authenticate_decrypt_tag ~key ~nonce ~adata:"" ~tag ct
163163+ with
164164+ | Some pt -> Alcotest.(check string) "gcm-1 decrypt" "" pt
165165+ | None -> Alcotest.fail "GCM test case 1 decrypt failed"
166166+167167+(* Test Case 2: 16-byte zero plaintext, no AAD *)
168168+let test_aes_gcm_nist_2 () =
169169+ let key = Crypto.AES.GCM.of_secret (vx "00000000000000000000000000000000") in
170170+ let nonce = vx "000000000000000000000000" in
171171+ let p = vx "00000000000000000000000000000000" in
172172+ let expected_ct = vx "0388dace60b6a392f328c2b971b2fe78" in
173173+ let expected_tag = vx "ab6e47d42cec13bdf53a67b21257bddf" in
174174+ let ct, tag =
175175+ Crypto.AES.GCM.authenticate_encrypt_tag ~key ~nonce ~adata:"" p
176176+ in
177177+ Alcotest.(check string) "gcm-2 ct" expected_ct ct;
178178+ Alcotest.(check string) "gcm-2 tag" expected_tag tag;
179179+ match
180180+ Crypto.AES.GCM.authenticate_decrypt_tag ~key ~nonce ~adata:"" ~tag ct
181181+ with
182182+ | Some pt -> Alcotest.(check string) "gcm-2 decrypt" p pt
183183+ | None -> Alcotest.fail "GCM test case 2 decrypt failed"
184184+185185+(* Test Case 3: 64-byte plaintext, no AAD *)
186186+let test_aes_gcm_nist_3 () =
187187+ let key = Crypto.AES.GCM.of_secret (vx "feffe9928665731c6d6a8f9467308308") in
188188+ let nonce = vx "cafebabefacedbaddecaf888" in
189189+ let p =
190190+ vx
191191+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255"
192192+ in
193193+ let expected_ct =
194194+ vx
195195+ "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985"
196196+ in
197197+ let expected_tag = vx "4d5c2af327cd64a62cf35abd2ba6fab4" in
198198+ let ct, tag =
199199+ Crypto.AES.GCM.authenticate_encrypt_tag ~key ~nonce ~adata:"" p
200200+ in
201201+ Alcotest.(check string) "gcm-3 ct" expected_ct ct;
202202+ Alcotest.(check string) "gcm-3 tag" expected_tag tag;
203203+ match
204204+ Crypto.AES.GCM.authenticate_decrypt_tag ~key ~nonce ~adata:"" ~tag ct
205205+ with
206206+ | Some pt -> Alcotest.(check string) "gcm-3 decrypt" p pt
207207+ | None -> Alcotest.fail "GCM test case 3 decrypt failed"
208208+209209+(* Test Case 4: 60-byte plaintext, 20-byte AAD *)
210210+let test_aes_gcm_nist_4 () =
211211+ let key = Crypto.AES.GCM.of_secret (vx "feffe9928665731c6d6a8f9467308308") in
212212+ let nonce = vx "cafebabefacedbaddecaf888" in
213213+ let p =
214214+ vx
215215+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39"
216216+ in
217217+ let adata = vx "feedfacedeadbeeffeedfacedeadbeefabaddad2" in
218218+ let expected_ct =
219219+ vx
220220+ "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091"
221221+ in
222222+ let expected_tag = vx "5bc94fbc3221a5db94fae95ae7121a47" in
223223+ let ct, tag = Crypto.AES.GCM.authenticate_encrypt_tag ~key ~nonce ~adata p in
224224+ Alcotest.(check string) "gcm-4 ct" expected_ct ct;
225225+ Alcotest.(check string) "gcm-4 tag" expected_tag tag;
226226+ match Crypto.AES.GCM.authenticate_decrypt_tag ~key ~nonce ~adata ~tag ct with
227227+ | Some pt -> Alcotest.(check string) "gcm-4 decrypt" p pt
228228+ | None -> Alcotest.fail "GCM test case 4 decrypt failed"
229229+230230+(* Test Case 7: NIST SP 800-38D — 192-bit key, 60-byte PT, 20-byte AAD *)
231231+let test_aes_gcm_nist_192 () =
232232+ let key =
233233+ Crypto.AES.GCM.of_secret
234234+ (vx "feffe9928665731c6d6a8f9467308308feffe9928665731c")
235235+ in
236236+ let nonce = vx "cafebabefacedbaddecaf888" in
237237+ let p =
238238+ vx
239239+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39"
240240+ in
241241+ let adata = vx "feedfacedeadbeeffeedfacedeadbeefabaddad2" in
242242+ let expected_ct =
243243+ vx
244244+ "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710"
245245+ in
246246+ let expected_tag = vx "2519498e80f1478f37ba55bd6d27618c" in
247247+ let ct, tag = Crypto.AES.GCM.authenticate_encrypt_tag ~key ~nonce ~adata p in
248248+ Alcotest.(check string) "gcm-192 ct" expected_ct ct;
249249+ Alcotest.(check string) "gcm-192 tag" expected_tag tag
250250+251251+(* Test Case 14: NIST SP 800-38D — 256-bit key, 60-byte PT, 20-byte AAD *)
252252+let test_aes_gcm_nist_256 () =
253253+ let key =
254254+ Crypto.AES.GCM.of_secret
255255+ (vx "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308")
256256+ in
257257+ let nonce = vx "cafebabefacedbaddecaf888" in
258258+ let p =
259259+ vx
260260+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39"
261261+ in
262262+ let adata = vx "feedfacedeadbeeffeedfacedeadbeefabaddad2" in
263263+ let expected_ct =
264264+ vx
265265+ "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662"
266266+ in
267267+ let expected_tag = vx "76fc6ece0f4e1768cddf8853bb2d551b" in
268268+ let ct, tag = Crypto.AES.GCM.authenticate_encrypt_tag ~key ~nonce ~adata p in
269269+ Alcotest.(check string) "gcm-256 ct" expected_ct ct;
270270+ Alcotest.(check string) "gcm-256 tag" expected_tag tag
271271+272272+(* GCM tamper detection *)
273273+let test_aes_gcm_tamper () =
46274 let key = Crypto_rng.generate 16 in
47275 let nonce = Crypto_rng.generate 12 in
48276 let adata = "gcm associated data" in
4949- let plaintext = "GCM test plaintext block" in
50277 let k = Crypto.AES.GCM.of_secret key in
5151- let ct = Crypto.AES.GCM.authenticate_encrypt ~key:k ~nonce ~adata plaintext in
5252- match Crypto.AES.GCM.authenticate_decrypt ~key:k ~nonce ~adata ct with
5353- | Some pt -> Alcotest.(check string) "gcm roundtrip" plaintext pt
5454- | None -> Alcotest.fail "GCM decrypt failed"
278278+ let ct = Crypto.AES.GCM.authenticate_encrypt ~key:k ~nonce ~adata "secret" in
279279+ let bad = Bytes.of_string ct in
280280+ Bytes.set bad 0 (Char.chr (Char.code (Bytes.get bad 0) lxor 1));
281281+ let result =
282282+ Crypto.AES.GCM.authenticate_decrypt ~key:k ~nonce ~adata
283283+ (Bytes.to_string bad)
284284+ in
285285+ Alcotest.(check bool) "gcm tamper rejected" true (Option.is_none result)
286286+287287+(* -- DES ECB ------------------------------------------------------------ *)
5528856289let test_des_ecb_roundtrip () =
57290 let key = Crypto_rng.generate 24 in
···64297let suite =
65298 ( "cipher_block",
66299 [
6767- Alcotest.test_case "AES ECB NIST" `Quick test_aes_ecb;
6868- Alcotest.test_case "AES CBC NIST" `Quick test_aes_cbc;
6969- Alcotest.test_case "AES CTR NIST" `Quick test_aes_ctr;
7070- Alcotest.test_case "AES GCM roundtrip" `Quick test_aes_gcm_roundtrip;
300300+ (* AES ECB — NIST SP 800-38A *)
301301+ Alcotest.test_case "AES ECB 128 NIST" `Quick test_aes_ecb_128;
302302+ Alcotest.test_case "AES ECB 192 NIST" `Quick test_aes_ecb_192;
303303+ Alcotest.test_case "AES ECB 256 NIST" `Quick test_aes_ecb_256;
304304+ (* AES CBC — NIST SP 800-38A *)
305305+ Alcotest.test_case "AES CBC 128 NIST" `Quick test_aes_cbc_128;
306306+ Alcotest.test_case "AES CBC 192 NIST" `Quick test_aes_cbc_192;
307307+ Alcotest.test_case "AES CBC 256 NIST" `Quick test_aes_cbc_256;
308308+ (* AES CTR — NIST SP 800-38A *)
309309+ Alcotest.test_case "AES CTR 128 NIST" `Quick test_aes_ctr_128;
310310+ Alcotest.test_case "AES CTR 192 NIST" `Quick test_aes_ctr_192;
311311+ Alcotest.test_case "AES CTR 256 NIST" `Quick test_aes_ctr_256;
312312+ (* AES GCM — NIST SP 800-38D *)
313313+ Alcotest.test_case "AES GCM NIST TC1" `Quick test_aes_gcm_nist_1;
314314+ Alcotest.test_case "AES GCM NIST TC2" `Quick test_aes_gcm_nist_2;
315315+ Alcotest.test_case "AES GCM NIST TC3" `Quick test_aes_gcm_nist_3;
316316+ Alcotest.test_case "AES GCM NIST TC4" `Quick test_aes_gcm_nist_4;
317317+ Alcotest.test_case "AES GCM NIST 192" `Quick test_aes_gcm_nist_192;
318318+ Alcotest.test_case "AES GCM NIST 256" `Quick test_aes_gcm_nist_256;
319319+ Alcotest.test_case "AES GCM tamper" `Quick test_aes_gcm_tamper;
320320+ (* DES *)
71321 Alcotest.test_case "DES ECB roundtrip" `Quick test_des_ecb_roundtrip;
72322 ] )
+70-4
test/test_cipher_stream.ml
···11let vx = Ohex.decode
2233-(* RFC 6229 — ARC4 with 40-bit key *)
44-let test_arc4_rfc6229 () =
33+(* RFC 6229 — ARC4 test vectors (keystream applied to zero plaintext) *)
44+55+(* 40-bit key *)
66+let test_arc4_rfc6229_40 () =
57 let key = vx "0102030405" in
68 let k = Crypto.ARC4.of_secret key in
79 let plaintext = String.make 16 '\x00' in
810 let result = Crypto.ARC4.encrypt ~key:k plaintext in
911 let expected = vx "b2396305f03dc027ccc3524a0a1118a8" in
1010- Alcotest.(check string) "rfc6229" expected result.message
1212+ Alcotest.(check string) "rfc6229-40" expected result.message
1313+1414+(* 56-bit key *)
1515+let test_arc4_rfc6229_56 () =
1616+ let key = vx "01020304050607" in
1717+ let k = Crypto.ARC4.of_secret key in
1818+ let plaintext = String.make 16 '\x00' in
1919+ let result = Crypto.ARC4.encrypt ~key:k plaintext in
2020+ let expected = vx "293f02d47f37c9b633f2af5285feb46b" in
2121+ Alcotest.(check string) "rfc6229-56" expected result.message
2222+2323+(* 64-bit key *)
2424+let test_arc4_rfc6229_64 () =
2525+ let key = vx "0102030405060708" in
2626+ let k = Crypto.ARC4.of_secret key in
2727+ let plaintext = String.make 16 '\x00' in
2828+ let result = Crypto.ARC4.encrypt ~key:k plaintext in
2929+ let expected = vx "97ab8a1bf0afb96132f2f67258da15a8" in
3030+ Alcotest.(check string) "rfc6229-64" expected result.message
3131+3232+(* 80-bit key *)
3333+let test_arc4_rfc6229_80 () =
3434+ let key = vx "0102030405060708090a" in
3535+ let k = Crypto.ARC4.of_secret key in
3636+ let plaintext = String.make 16 '\x00' in
3737+ let result = Crypto.ARC4.encrypt ~key:k plaintext in
3838+ let expected = vx "ede3b04643e586cc907dc21851709902" in
3939+ Alcotest.(check string) "rfc6229-80" expected result.message
4040+4141+(* 128-bit key *)
4242+let test_arc4_rfc6229_128 () =
4343+ let key = vx "0102030405060708090a0b0c0d0e0f10" in
4444+ let k = Crypto.ARC4.of_secret key in
4545+ let plaintext = String.make 16 '\x00' in
4646+ let result = Crypto.ARC4.encrypt ~key:k plaintext in
4747+ let expected = vx "9ac7cc9a609d1ef7b2932899cde41b97" in
4848+ Alcotest.(check string) "rfc6229-128" expected result.message
4949+5050+(* 192-bit key *)
5151+let test_arc4_rfc6229_192 () =
5252+ let key = vx "0102030405060708090a0b0c0d0e0f101112131415161718" in
5353+ let k = Crypto.ARC4.of_secret key in
5454+ let plaintext = String.make 16 '\x00' in
5555+ let result = Crypto.ARC4.encrypt ~key:k plaintext in
5656+ let expected = vx "0595e57fe5f0bb3c706edac8a4b2db11" in
5757+ Alcotest.(check string) "rfc6229-192" expected result.message
5858+5959+(* 256-bit key *)
6060+let test_arc4_rfc6229_256 () =
6161+ let key =
6262+ vx "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"
6363+ in
6464+ let k = Crypto.ARC4.of_secret key in
6565+ let plaintext = String.make 16 '\x00' in
6666+ let result = Crypto.ARC4.encrypt ~key:k plaintext in
6767+ let expected = vx "eaa6bd25880bf93d3f5d1e4ca2611d91" in
6868+ Alcotest.(check string) "rfc6229-256" expected result.message
11691270let test_arc4_roundtrip () =
1371 let key = Crypto_rng.generate 16 in
···3290let suite =
3391 ( "cipher_stream",
3492 [
3535- Alcotest.test_case "ARC4 RFC 6229" `Quick test_arc4_rfc6229;
9393+ (* RFC 6229 — ARC4 at various key sizes *)
9494+ Alcotest.test_case "ARC4 RFC 6229 40-bit" `Quick test_arc4_rfc6229_40;
9595+ Alcotest.test_case "ARC4 RFC 6229 56-bit" `Quick test_arc4_rfc6229_56;
9696+ Alcotest.test_case "ARC4 RFC 6229 64-bit" `Quick test_arc4_rfc6229_64;
9797+ Alcotest.test_case "ARC4 RFC 6229 80-bit" `Quick test_arc4_rfc6229_80;
9898+ Alcotest.test_case "ARC4 RFC 6229 128-bit" `Quick test_arc4_rfc6229_128;
9999+ Alcotest.test_case "ARC4 RFC 6229 192-bit" `Quick test_arc4_rfc6229_192;
100100+ Alcotest.test_case "ARC4 RFC 6229 256-bit" `Quick test_arc4_rfc6229_256;
101101+ (* Roundtrip / stateful *)
36102 Alcotest.test_case "ARC4 roundtrip" `Quick test_arc4_roundtrip;
37103 Alcotest.test_case "ARC4 stateful" `Quick test_arc4_stateful;
38104 ] )
+5-6
test/test_crypto_ec.ml
···1111 let bbuf = Bytes.unsafe_of_string buf in
1212 for i = n - 1 downto 0 do
1313 let byte = Bytes.get_uint8 bbuf i in
1414- Format.fprintf fmt "%02x" byte
1414+ Fmt.pf fmt "%02x" byte
1515 done
16161717let pp_result ppf = function
1818 | Ok cs -> pp_hex_le ppf cs
1919- | Error e -> Format.fprintf ppf "%a" pp_error e
1919+ | Error e -> Fmt.pf ppf "%a" pp_error e
20202121let key_exchange =
2222 let test ~name d p ~expected =
2323 ( name,
2424 `Quick,
2525 fun () ->
2626- P256.Dh.key_exchange d p
2727- |> Format.asprintf "%a" pp_result
2626+ P256.Dh.key_exchange d p |> Fmt.str "%a" pp_result
2827 |> Alcotest.check Alcotest.string __LOC__ expected )
2928 in
3029 let kp data =
···6160 | Ok (p, _) -> p
6261 | Error _ -> assert false
6362 in
6464- ( Printf.sprintf "Scalar mult (#%d)" n,
6363+ ( Fmt.str "Scalar mult (#%d)" n,
6564 `Quick,
6665 fun () ->
6766 P256.Dh.key_exchange scalar point
6868- |> Format.asprintf "%a" pp_result
6767+ |> Fmt.str "%a" pp_result
6968 |> Alcotest.check Alcotest.string __LOC__ expected )
7069 in
7170 let point =
+64-1
test/test_poly1305.ml
···1010 let tag = Crypto.Poly1305.mac ~key msg in
1111 Alcotest.(check string) "rfc8439" expected tag
12121313+(* RFC 8439 Appendix A.3 — Test Vector #1: all-zero key, 64-byte zero msg *)
1414+let test_rfc8439_a3_1 () =
1515+ let key = vx (String.make 64 '0') in
1616+ let msg = vx (String.make 128 '0') in
1717+ let expected = vx "00000000000000000000000000000000" in
1818+ let tag = Crypto.Poly1305.mac ~key msg in
1919+ Alcotest.(check string) "rfc8439-a3-1" expected tag
2020+2121+(* RFC 8439 Appendix A.3 — Test Vector #2:
2222+ r=0, s=36e5f6b5c5e06070f0efca96227a863e *)
2323+let test_rfc8439_a3_2 () =
2424+ let key =
2525+ vx "0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e"
2626+ in
2727+ let msg =
2828+ "Any submission to the IETF intended by the Contributor for publication as \
2929+ all or part of an IETF Internet-Draft or RFC and any statement made \
3030+ within the context of an IETF activity is considered an \"IETF \
3131+ Contribution\". Such statements include oral statements in IETF sessions, \
3232+ as well as written and electronic communications made at any time or \
3333+ place, which are addressed to"
3434+ in
3535+ let expected = vx "36e5f6b5c5e06070f0efca96227a863e" in
3636+ let tag = Crypto.Poly1305.mac ~key msg in
3737+ Alcotest.(check string) "rfc8439-a3-2" expected tag
3838+3939+(* RFC 8439 Appendix A.3 — Test Vector #3:
4040+ r=36e5f6b5c5e06070f0efca96227a863e, s=0 *)
4141+let test_rfc8439_a3_3 () =
4242+ let key =
4343+ vx "36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000"
4444+ in
4545+ let msg =
4646+ "Any submission to the IETF intended by the Contributor for publication as \
4747+ all or part of an IETF Internet-Draft or RFC and any statement made \
4848+ within the context of an IETF activity is considered an \"IETF \
4949+ Contribution\". Such statements include oral statements in IETF sessions, \
5050+ as well as written and electronic communications made at any time or \
5151+ place, which are addressed to"
5252+ in
5353+ let expected = vx "f3477e7cd95417af89a6b8794c310cf0" in
5454+ let tag = Crypto.Poly1305.mac ~key msg in
5555+ Alcotest.(check string) "rfc8439-a3-3" expected tag
5656+5757+(* RFC 8439 Appendix A.3 — Test Vector #4 *)
5858+let test_rfc8439_a3_4 () =
5959+ let key =
6060+ vx "1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0"
6161+ in
6262+ let msg =
6363+ "'Twas brillig, and the slithy toves\n\
6464+ Did gyre and gimble in the wabe:\n\
6565+ All mimsy were the borogoves,\n\
6666+ And the mome raths outgrabe."
6767+ in
6868+ let expected = vx "4541669a7eaaee61e708dc7cbcc5eb62" in
6969+ let tag = Crypto.Poly1305.mac ~key msg in
7070+ Alcotest.(check string) "rfc8439-a3-4" expected tag
7171+1372let test_incremental () =
1473 let key =
1574 vx "85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b"
···3998let suite =
4099 ( "poly1305",
41100 [
4242- Alcotest.test_case "RFC 8439" `Quick test_rfc8439;
101101+ Alcotest.test_case "RFC 8439 2.5.2" `Quick test_rfc8439;
102102+ Alcotest.test_case "RFC 8439 A.3 #1" `Quick test_rfc8439_a3_1;
103103+ Alcotest.test_case "RFC 8439 A.3 #2" `Quick test_rfc8439_a3_2;
104104+ Alcotest.test_case "RFC 8439 A.3 #3" `Quick test_rfc8439_a3_3;
105105+ Alcotest.test_case "RFC 8439 A.3 #4" `Quick test_rfc8439_a3_4;
43106 Alcotest.test_case "incremental" `Quick test_incremental;
44107 Alcotest.test_case "maci" `Quick test_maci;
45108 ] )
+1-1
tests/test_crypto.ml
···682682 Alcotest.test_case "long_adata" `Quick long_adata;
683683 ]
684684 @ List.mapi
685685- (fun i f -> Alcotest.test_case (Printf.sprintf "regr_tls_%d" i) `Quick f)
685685+ (fun i f -> Alcotest.test_case (Fmt.str "regr_tls_%d" i) `Quick f)
686686 regr_tls
687687688688let gcm_regressions =
+2-2
tests/test_dh.ml
···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 let pp_opt ppf = function
1212- | None -> Format.fprintf ppf "None"
1313- | Some a -> Format.fprintf ppf "Some(%a)" (Ohex.pp_hexdump ()) a
1212+ | None -> Fmt.pf ppf "None"
1313+ | Some a -> Fmt.pf ppf "Some(%a)" (Ohex.pp_hexdump ()) a
1414 in
1515 match (sh1, sh2) with
1616 | Some a, Some b ->
+1-1
tests/test_dsa.ml
···3217321732183218let to_cases name cases =
32193219 List.mapi
32203220- (fun i f -> Alcotest.test_case (Printf.sprintf "%s %d" name i) `Quick f)
32203220+ (fun i f -> Alcotest.test_case (Fmt.str "%s %d" name i) `Quick f)
32213221 cases
3222322232233223let suite =