Repo of no-std crates for my personal embedded projects

Sachy's crypto scheme lmao

+768 -59
+405 -59
Cargo.lock
··· 18 18 checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 19 19 20 20 [[package]] 21 + name = "aead" 22 + version = "0.6.0-rc.10" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "6b657e772794c6b04730ea897b66a058ccd866c16d1967da05eeeecec39043fe" 25 + dependencies = [ 26 + "crypto-common 0.2.1", 27 + "inout", 28 + ] 29 + 30 + [[package]] 21 31 name = "aho-corasick" 22 32 version = "1.1.4" 23 33 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 63 73 ] 64 74 65 75 [[package]] 76 + name = "base16ct" 77 + version = "1.0.0" 78 + source = "registry+https://github.com/rust-lang/crates.io-index" 79 + checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" 80 + 81 + [[package]] 66 82 name = "base64ct" 67 83 version = "1.8.3" 68 84 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 90 106 ] 91 107 92 108 [[package]] 109 + name = "block-buffer" 110 + version = "0.12.0" 111 + source = "registry+https://github.com/rust-lang/crates.io-index" 112 + checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" 113 + dependencies = [ 114 + "hybrid-array", 115 + ] 116 + 117 + [[package]] 93 118 name = "byteorder" 94 119 version = "1.5.0" 95 120 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 112 137 113 138 [[package]] 114 139 name = "cc" 115 - version = "1.2.56" 140 + version = "1.2.57" 116 141 source = "registry+https://github.com/rust-lang/crates.io-index" 117 - checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" 142 + checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" 118 143 dependencies = [ 119 144 "find-msvc-tools", 120 145 "shlex", ··· 127 152 checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" 128 153 129 154 [[package]] 155 + name = "chacha20" 156 + version = "0.10.0" 157 + source = "registry+https://github.com/rust-lang/crates.io-index" 158 + checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" 159 + dependencies = [ 160 + "cfg-if", 161 + "cipher", 162 + "cpufeatures 0.3.0", 163 + ] 164 + 165 + [[package]] 166 + name = "chacha20poly1305" 167 + version = "0.11.0-rc.3" 168 + source = "registry+https://github.com/rust-lang/crates.io-index" 169 + checksum = "1c9ed179664f12fd6f155f6dd632edf5f3806d48c228c67ff78366f2a0eb6b5e" 170 + dependencies = [ 171 + "aead", 172 + "chacha20", 173 + "cipher", 174 + "poly1305", 175 + ] 176 + 177 + [[package]] 178 + name = "cipher" 179 + version = "0.5.1" 180 + source = "registry+https://github.com/rust-lang/crates.io-index" 181 + checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" 182 + dependencies = [ 183 + "block-buffer 0.12.0", 184 + "crypto-common 0.2.1", 185 + "inout", 186 + ] 187 + 188 + [[package]] 189 + name = "cmov" 190 + version = "0.5.2" 191 + source = "registry+https://github.com/rust-lang/crates.io-index" 192 + checksum = "de0758edba32d61d1fd9f4d69491b47604b91ee2f7e6b33de7e54ca4ebe55dc3" 193 + 194 + [[package]] 195 + name = "const-oid" 196 + version = "0.10.2" 197 + source = "registry+https://github.com/rust-lang/crates.io-index" 198 + checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" 199 + 200 + [[package]] 130 201 name = "core-foundation" 131 202 version = "0.10.1" 132 203 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 143 214 checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 144 215 145 216 [[package]] 217 + name = "cpubits" 218 + version = "0.1.0" 219 + source = "registry+https://github.com/rust-lang/crates.io-index" 220 + checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" 221 + 222 + [[package]] 146 223 name = "cpufeatures" 147 224 version = "0.2.17" 148 225 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 152 229 ] 153 230 154 231 [[package]] 232 + name = "cpufeatures" 233 + version = "0.3.0" 234 + source = "registry+https://github.com/rust-lang/crates.io-index" 235 + checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" 236 + dependencies = [ 237 + "libc", 238 + ] 239 + 240 + [[package]] 155 241 name = "critical-section" 156 242 version = "1.2.0" 157 243 source = "registry+https://github.com/rust-lang/crates.io-index" 158 244 checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" 159 245 160 246 [[package]] 247 + name = "crypto-bigint" 248 + version = "0.7.2" 249 + source = "registry+https://github.com/rust-lang/crates.io-index" 250 + checksum = "e9b6a7421484856c90cb2e996b91068d608539bb4e6f0a111b16d70678824d09" 251 + dependencies = [ 252 + "cpubits", 253 + "ctutils", 254 + "getrandom", 255 + "hybrid-array", 256 + "num-traits", 257 + "rand_core", 258 + "subtle", 259 + "zeroize", 260 + ] 261 + 262 + [[package]] 161 263 name = "crypto-common" 162 264 version = "0.1.7" 163 265 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 168 270 ] 169 271 170 272 [[package]] 273 + name = "crypto-common" 274 + version = "0.2.1" 275 + source = "registry+https://github.com/rust-lang/crates.io-index" 276 + checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" 277 + dependencies = [ 278 + "getrandom", 279 + "hybrid-array", 280 + "rand_core", 281 + ] 282 + 283 + [[package]] 284 + name = "ctutils" 285 + version = "0.4.0" 286 + source = "registry+https://github.com/rust-lang/crates.io-index" 287 + checksum = "1005a6d4446f5120ef475ad3d2af2b30c49c2c9c6904258e3bb30219bebed5e4" 288 + dependencies = [ 289 + "cmov", 290 + "subtle", 291 + ] 292 + 293 + [[package]] 171 294 name = "darling" 172 295 version = "0.20.11" 173 296 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 244 367 ] 245 368 246 369 [[package]] 370 + name = "der" 371 + version = "0.8.0" 372 + source = "registry+https://github.com/rust-lang/crates.io-index" 373 + checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" 374 + dependencies = [ 375 + "const-oid", 376 + "zeroize", 377 + ] 378 + 379 + [[package]] 247 380 name = "derive_builder" 248 381 version = "0.20.2" 249 382 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 275 408 ] 276 409 277 410 [[package]] 411 + name = "dhkem" 412 + version = "0.1.0-rc.0" 413 + source = "git+https://github.com/RustCrypto/KEMs?rev=2d277162e0c5ed1c53bb315d0c0dace394cba70a#2d277162e0c5ed1c53bb315d0c0dace394cba70a" 414 + dependencies = [ 415 + "elliptic-curve", 416 + "hkdf", 417 + "k256", 418 + "kem", 419 + "rand_core", 420 + "zeroize", 421 + ] 422 + 423 + [[package]] 278 424 name = "digest" 279 425 version = "0.10.7" 280 426 source = "registry+https://github.com/rust-lang/crates.io-index" 281 427 checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 282 428 dependencies = [ 283 - "block-buffer", 284 - "crypto-common", 429 + "block-buffer 0.10.4", 430 + "crypto-common 0.1.7", 431 + ] 432 + 433 + [[package]] 434 + name = "digest" 435 + version = "0.11.2" 436 + source = "registry+https://github.com/rust-lang/crates.io-index" 437 + checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" 438 + dependencies = [ 439 + "block-buffer 0.12.0", 440 + "crypto-common 0.2.1", 441 + "ctutils", 285 442 ] 286 443 287 444 [[package]] ··· 294 451 ] 295 452 296 453 [[package]] 454 + name = "ecdsa" 455 + version = "0.17.0-rc.16" 456 + source = "registry+https://github.com/rust-lang/crates.io-index" 457 + checksum = "91bbdd377139884fafcad8dc43a760a3e1e681aa26db910257fa6535b70e1829" 458 + dependencies = [ 459 + "der", 460 + "elliptic-curve", 461 + "signature", 462 + "zeroize", 463 + ] 464 + 465 + [[package]] 297 466 name = "either" 298 467 version = "1.15.0" 299 468 source = "registry+https://github.com/rust-lang/crates.io-index" 300 469 checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 301 470 302 471 [[package]] 472 + name = "elliptic-curve" 473 + version = "0.14.0-rc.29" 474 + source = "registry+https://github.com/rust-lang/crates.io-index" 475 + checksum = "e84043d573efd4ac9d2d125817979a379204bf7e328b25a4a30487e8d100e618" 476 + dependencies = [ 477 + "base16ct", 478 + "crypto-bigint", 479 + "crypto-common 0.2.1", 480 + "digest 0.11.2", 481 + "hkdf", 482 + "hybrid-array", 483 + "rand_core", 484 + "rustcrypto-ff", 485 + "rustcrypto-group", 486 + "sec1", 487 + "subtle", 488 + "zeroize", 489 + ] 490 + 491 + [[package]] 303 492 name = "embassy-net" 304 493 version = "0.7.1" 305 494 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 338 527 339 528 [[package]] 340 529 name = "embassy-time" 341 - version = "0.5.0" 530 + version = "0.5.1" 342 531 source = "registry+https://github.com/rust-lang/crates.io-index" 343 - checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" 532 + checksum = "592b0c143ec626e821d4d90da51a2bd91d559d6c442b7c74a47d368c9e23d97a" 344 533 dependencies = [ 345 534 "cfg-if", 346 535 "critical-section", ··· 355 544 356 545 [[package]] 357 546 name = "embassy-time-driver" 358 - version = "0.2.1" 547 + version = "0.2.2" 359 548 source = "registry+https://github.com/rust-lang/crates.io-index" 360 - checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" 549 + checksum = "6ee71af1b3a0deaa53eaf2d39252f83504c853646e472400b763060389b9fcc9" 361 550 dependencies = [ 362 551 "document-features", 363 552 ] ··· 521 710 "cfg-if", 522 711 "libc", 523 712 "r-efi", 713 + "rand_core", 524 714 "wasip2", 525 715 "wasip3", 526 716 ] ··· 610 800 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 611 801 612 802 [[package]] 803 + name = "hkdf" 804 + version = "0.13.0-rc.5" 805 + source = "registry+https://github.com/rust-lang/crates.io-index" 806 + checksum = "cbb55385998ae66b8d2d5143c05c94b9025ab863966f0c94ce7a5fde30105092" 807 + dependencies = [ 808 + "hmac", 809 + ] 810 + 811 + [[package]] 812 + name = "hmac" 813 + version = "0.13.0-rc.6" 814 + source = "registry+https://github.com/rust-lang/crates.io-index" 815 + checksum = "60017b071c523c9e5a55dd1253582bff6150c5e96a7e8511e419de1ab5ee97f9" 816 + dependencies = [ 817 + "digest 0.11.2", 818 + ] 819 + 820 + [[package]] 613 821 name = "home" 614 822 version = "0.5.12" 615 823 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 619 827 ] 620 828 621 829 [[package]] 830 + name = "hybrid-array" 831 + version = "0.4.8" 832 + source = "registry+https://github.com/rust-lang/crates.io-index" 833 + checksum = "8655f91cd07f2b9d0c24137bd650fe69617773435ee5ec83022377777ce65ef1" 834 + dependencies = [ 835 + "subtle", 836 + "typenum", 837 + "zeroize", 838 + ] 839 + 840 + [[package]] 622 841 name = "i2cdev" 623 842 version = "0.6.2" 624 843 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 655 874 ] 656 875 657 876 [[package]] 877 + name = "inout" 878 + version = "0.2.2" 879 + source = "registry+https://github.com/rust-lang/crates.io-index" 880 + checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" 881 + dependencies = [ 882 + "hybrid-array", 883 + ] 884 + 885 + [[package]] 658 886 name = "io-kit-sys" 659 887 version = "0.4.1" 660 888 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 681 909 682 910 [[package]] 683 911 name = "itoa" 684 - version = "1.0.17" 912 + version = "1.0.18" 685 913 source = "registry+https://github.com/rust-lang/crates.io-index" 686 - checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" 914 + checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" 687 915 688 916 [[package]] 689 917 name = "jiff" ··· 708 936 ] 709 937 710 938 [[package]] 939 + name = "k256" 940 + version = "0.14.0-rc.8" 941 + source = "registry+https://github.com/rust-lang/crates.io-index" 942 + checksum = "f7d2c6c227649d5ec80eaae541f1736232641a0bcdb3062a52b34edb42054158" 943 + dependencies = [ 944 + "cpubits", 945 + "ecdsa", 946 + "elliptic-curve", 947 + ] 948 + 949 + [[package]] 950 + name = "kem" 951 + version = "0.3.0-rc.6" 952 + source = "registry+https://github.com/rust-lang/crates.io-index" 953 + checksum = "e3ae2c3347ff4a7af4f679a9e397c2c7e6034a00b773dd2dd3c001d7f40897c9" 954 + dependencies = [ 955 + "crypto-common 0.2.1", 956 + "rand_core", 957 + ] 958 + 959 + [[package]] 711 960 name = "leb128fmt" 712 961 version = "0.1.0" 713 962 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 715 964 716 965 [[package]] 717 966 name = "libc" 718 - version = "0.2.182" 967 + version = "0.2.183" 719 968 source = "registry+https://github.com/rust-lang/crates.io-index" 720 - checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" 969 + checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" 721 970 722 971 [[package]] 723 972 name = "libm" ··· 949 1198 950 1199 [[package]] 951 1200 name = "once_cell" 952 - version = "1.21.3" 1201 + version = "1.21.4" 953 1202 source = "registry+https://github.com/rust-lang/crates.io-index" 954 - checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 1203 + checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" 955 1204 956 1205 [[package]] 957 1206 name = "owo-colors" ··· 999 1248 checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" 1000 1249 dependencies = [ 1001 1250 "pest", 1002 - "sha2", 1251 + "sha2 0.10.9", 1003 1252 ] 1004 1253 1005 1254 [[package]] ··· 1020 1269 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1021 1270 1022 1271 [[package]] 1272 + name = "poly1305" 1273 + version = "0.9.0-rc.6" 1274 + source = "registry+https://github.com/rust-lang/crates.io-index" 1275 + checksum = "19feddcbdf17fad33f40041c7f9e768faf19455f32a6d52ba1b8b65ffc7b1cae" 1276 + dependencies = [ 1277 + "cpufeatures 0.3.0", 1278 + "universal-hash", 1279 + ] 1280 + 1281 + [[package]] 1023 1282 name = "portable-atomic" 1024 1283 version = "1.13.1" 1025 1284 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1027 1286 1028 1287 [[package]] 1029 1288 name = "portable-atomic-util" 1030 - version = "0.2.5" 1289 + version = "0.2.6" 1031 1290 source = "registry+https://github.com/rust-lang/crates.io-index" 1032 - checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" 1291 + checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" 1033 1292 dependencies = [ 1034 1293 "portable-atomic", 1035 1294 ] ··· 1178 1437 checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" 1179 1438 1180 1439 [[package]] 1440 + name = "rand_core" 1441 + version = "0.10.0" 1442 + source = "registry+https://github.com/rust-lang/crates.io-index" 1443 + checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" 1444 + 1445 + [[package]] 1181 1446 name = "regex" 1182 1447 version = "1.12.3" 1183 1448 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1213 1478 checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" 1214 1479 1215 1480 [[package]] 1481 + name = "rustcrypto-ff" 1482 + version = "0.14.0-rc.0" 1483 + source = "registry+https://github.com/rust-lang/crates.io-index" 1484 + checksum = "c5db129183b2c139d7d87d08be57cba626c715789db17aec65c8866bfd767d1f" 1485 + dependencies = [ 1486 + "rand_core", 1487 + "subtle", 1488 + ] 1489 + 1490 + [[package]] 1491 + name = "rustcrypto-group" 1492 + version = "0.14.0-rc.0" 1493 + source = "registry+https://github.com/rust-lang/crates.io-index" 1494 + checksum = "57c4b1463f274a3ff6fb2f44da43e576cb9424367bd96f185ead87b52fe00523" 1495 + dependencies = [ 1496 + "rand_core", 1497 + "rustcrypto-ff", 1498 + "subtle", 1499 + ] 1500 + 1501 + [[package]] 1216 1502 name = "rustix" 1217 1503 version = "0.38.44" 1218 1504 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1261 1547 ] 1262 1548 1263 1549 [[package]] 1550 + name = "sachy-crypto" 1551 + version = "0.1.0" 1552 + dependencies = [ 1553 + "chacha20poly1305", 1554 + "dhkem", 1555 + "elliptic-curve", 1556 + "k256", 1557 + "sha2 0.11.0-rc.5", 1558 + ] 1559 + 1560 + [[package]] 1264 1561 name = "sachy-esphome" 1265 1562 version = "0.1.0" 1266 1563 dependencies = [ ··· 1299 1596 "defmt 1.0.1", 1300 1597 "embassy-time", 1301 1598 "sachy-fmt", 1302 - "winnow", 1599 + "winnow 0.7.15", 1303 1600 ] 1304 1601 1305 1602 [[package]] ··· 1331 1628 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1332 1629 1333 1630 [[package]] 1631 + name = "sec1" 1632 + version = "0.8.0" 1633 + source = "registry+https://github.com/rust-lang/crates.io-index" 1634 + checksum = "f46b9a5ab87780a3189a1d704766579517a04ad59de653b7aad7d38e8a15f7dc" 1635 + dependencies = [ 1636 + "base16ct", 1637 + "ctutils", 1638 + "der", 1639 + "hybrid-array", 1640 + "subtle", 1641 + "zeroize", 1642 + ] 1643 + 1644 + [[package]] 1334 1645 name = "semver" 1335 1646 version = "1.0.27" 1336 1647 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1381 1692 1382 1693 [[package]] 1383 1694 name = "serialport" 1384 - version = "4.7.3" 1695 + version = "4.9.0" 1385 1696 source = "registry+https://github.com/rust-lang/crates.io-index" 1386 - checksum = "2acaf3f973e8616d7ceac415f53fc60e190b2a686fbcf8d27d0256c741c5007b" 1697 + checksum = "a4d91116f97173694f1642263b2ff837f80d933aa837e2314969f6728f661df3" 1387 1698 dependencies = [ 1388 1699 "bitflags 2.11.0", 1389 1700 "cfg-if", ··· 1394 1705 "nix 0.26.4", 1395 1706 "scopeguard", 1396 1707 "unescaper", 1397 - "winapi", 1708 + "windows-sys 0.52.0", 1398 1709 ] 1399 1710 1400 1711 [[package]] ··· 1404 1715 checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" 1405 1716 dependencies = [ 1406 1717 "cfg-if", 1407 - "cpufeatures", 1408 - "digest", 1718 + "cpufeatures 0.2.17", 1719 + "digest 0.10.7", 1720 + ] 1721 + 1722 + [[package]] 1723 + name = "sha2" 1724 + version = "0.11.0-rc.5" 1725 + source = "registry+https://github.com/rust-lang/crates.io-index" 1726 + checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" 1727 + dependencies = [ 1728 + "cfg-if", 1729 + "cpufeatures 0.2.17", 1730 + "digest 0.11.2", 1409 1731 ] 1410 1732 1411 1733 [[package]] ··· 1413 1735 version = "1.3.0" 1414 1736 source = "registry+https://github.com/rust-lang/crates.io-index" 1415 1737 checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1738 + 1739 + [[package]] 1740 + name = "signature" 1741 + version = "3.0.0-rc.10" 1742 + source = "registry+https://github.com/rust-lang/crates.io-index" 1743 + checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3" 1744 + dependencies = [ 1745 + "rand_core", 1746 + ] 1416 1747 1417 1748 [[package]] 1418 1749 name = "smoltcp" ··· 1451 1782 checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1452 1783 1453 1784 [[package]] 1785 + name = "subtle" 1786 + version = "2.6.1" 1787 + source = "registry+https://github.com/rust-lang/crates.io-index" 1788 + checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1789 + 1790 + [[package]] 1454 1791 name = "supports-color" 1455 1792 version = "3.0.2" 1456 1793 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1493 1830 1494 1831 [[package]] 1495 1832 name = "tempfile" 1496 - version = "3.26.0" 1833 + version = "3.27.0" 1497 1834 source = "registry+https://github.com/rust-lang/crates.io-index" 1498 - checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" 1835 + checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" 1499 1836 dependencies = [ 1500 1837 "fastrand", 1501 1838 "getrandom", ··· 1566 1903 1567 1904 [[package]] 1568 1905 name = "toml_datetime" 1569 - version = "1.0.0+spec-1.1.0" 1906 + version = "1.0.1+spec-1.1.0" 1570 1907 source = "registry+https://github.com/rust-lang/crates.io-index" 1571 - checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" 1908 + checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" 1572 1909 dependencies = [ 1573 1910 "serde_core", 1574 1911 ] 1575 1912 1576 1913 [[package]] 1577 1914 name = "toml_edit" 1578 - version = "0.25.4+spec-1.1.0" 1915 + version = "0.25.5+spec-1.1.0" 1579 1916 source = "registry+https://github.com/rust-lang/crates.io-index" 1580 - checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" 1917 + checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1" 1581 1918 dependencies = [ 1582 1919 "indexmap", 1583 1920 "toml_datetime", 1584 1921 "toml_parser", 1585 1922 "toml_writer", 1586 - "winnow", 1923 + "winnow 1.0.0", 1587 1924 ] 1588 1925 1589 1926 [[package]] 1590 1927 name = "toml_parser" 1591 - version = "1.0.9+spec-1.1.0" 1928 + version = "1.0.10+spec-1.1.0" 1592 1929 source = "registry+https://github.com/rust-lang/crates.io-index" 1593 - checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" 1930 + checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" 1594 1931 dependencies = [ 1595 - "winnow", 1932 + "winnow 1.0.0", 1596 1933 ] 1597 1934 1598 1935 [[package]] 1599 1936 name = "toml_writer" 1600 - version = "1.0.6+spec-1.1.0" 1937 + version = "1.0.7+spec-1.1.0" 1601 1938 source = "registry+https://github.com/rust-lang/crates.io-index" 1602 - checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" 1939 + checksum = "f17aaa1c6e3dc22b1da4b6bba97d066e354c7945cac2f7852d4e4e7ca7a6b56d" 1603 1940 1604 1941 [[package]] 1605 1942 name = "typenum" ··· 1651 1988 version = "0.2.6" 1652 1989 source = "registry+https://github.com/rust-lang/crates.io-index" 1653 1990 checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 1991 + 1992 + [[package]] 1993 + name = "universal-hash" 1994 + version = "0.6.1" 1995 + source = "registry+https://github.com/rust-lang/crates.io-index" 1996 + checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" 1997 + dependencies = [ 1998 + "crypto-common 0.2.1", 1999 + "ctutils", 2000 + ] 1654 2001 1655 2002 [[package]] 1656 2003 name = "version_check" ··· 1729 2076 ] 1730 2077 1731 2078 [[package]] 1732 - name = "winapi" 1733 - version = "0.3.9" 1734 - source = "registry+https://github.com/rust-lang/crates.io-index" 1735 - checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1736 - dependencies = [ 1737 - "winapi-i686-pc-windows-gnu", 1738 - "winapi-x86_64-pc-windows-gnu", 1739 - ] 1740 - 1741 - [[package]] 1742 - name = "winapi-i686-pc-windows-gnu" 1743 - version = "0.4.0" 1744 - source = "registry+https://github.com/rust-lang/crates.io-index" 1745 - checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1746 - 1747 - [[package]] 1748 - name = "winapi-x86_64-pc-windows-gnu" 1749 - version = "0.4.0" 2079 + name = "windows-link" 2080 + version = "0.2.1" 1750 2081 source = "registry+https://github.com/rust-lang/crates.io-index" 1751 - checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2082 + checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 1752 2083 1753 2084 [[package]] 1754 - name = "windows-link" 1755 - version = "0.2.1" 2085 + name = "windows-sys" 2086 + version = "0.52.0" 1756 2087 source = "registry+https://github.com/rust-lang/crates.io-index" 1757 - checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 2088 + checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2089 + dependencies = [ 2090 + "windows-targets 0.52.6", 2091 + ] 1758 2092 1759 2093 [[package]] 1760 2094 name = "windows-sys" ··· 1914 2248 1915 2249 [[package]] 1916 2250 name = "winnow" 1917 - version = "0.7.14" 2251 + version = "0.7.15" 1918 2252 source = "registry+https://github.com/rust-lang/crates.io-index" 1919 - checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" 2253 + checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" 2254 + 2255 + [[package]] 2256 + name = "winnow" 2257 + version = "1.0.0" 2258 + source = "registry+https://github.com/rust-lang/crates.io-index" 2259 + checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" 1920 2260 dependencies = [ 1921 2261 "memchr", 1922 2262 ] ··· 2008 2348 "unicode-xid", 2009 2349 "wasmparser", 2010 2350 ] 2351 + 2352 + [[package]] 2353 + name = "zeroize" 2354 + version = "1.8.2" 2355 + source = "registry+https://github.com/rust-lang/crates.io-index" 2356 + checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" 2011 2357 2012 2358 [[package]] 2013 2359 name = "zmij"
+4
Cargo.toml
··· 4 4 "sachy-battery", 5 5 "sachy-bthome", 6 6 "sachy-config", 7 + "sachy-crypto", 7 8 "sachy-esphome", 8 9 "sachy-fmt", 9 10 "sachy-fnv", ··· 26 27 embassy-sync = { version = "0.7" } 27 28 embassy-net = { version = "0.7" } 28 29 defmt = { version = "1" } 30 + 31 + [patch.crates-io] 32 + dhkem = { git = "https://github.com/RustCrypto/KEMs", rev = "2d277162e0c5ed1c53bb315d0c0dace394cba70a" }
+15
sachy-crypto/Cargo.toml
··· 1 + [package] 2 + name = "sachy-crypto" 3 + authors.workspace = true 4 + edition.workspace = true 5 + repository.workspace = true 6 + license.workspace = true 7 + version.workspace = true 8 + rust-version.workspace = true 9 + 10 + [dependencies] 11 + chacha20poly1305 = { version = "=0.11.0-rc.3", default-features = false, features = ["getrandom", "alloc"] } 12 + k256 = { version = "=0.14.0-rc.8", default-features = false, features = ["ecdh", "getrandom"] } 13 + sha2 = { version = "=0.11.0-rc.5", default-features = false, features = [] } 14 + dhkem = { version = "0.1.0-rc.0", features = ["getrandom", "k256"] } 15 + elliptic-curve = { version = "0.14.0-rc.28", default-features = false, features = ["ecdh"] }
+344
sachy-crypto/src/lib.rs
··· 1 + #![no_std] 2 + 3 + use core::ops::{AddAssign, Sub}; 4 + 5 + use chacha20poly1305::{ 6 + AeadCore, AeadInOut, ChaCha20Poly1305, KeyInit, 7 + aead::{ 8 + self, Buffer, 9 + array::{Array, ArraySize}, 10 + common::array::typenum::Unsigned, 11 + }, 12 + consts::U8, 13 + }; 14 + use dhkem::{ 15 + Encapsulate, Kem, Secp256k1DecapsulationKey, Secp256k1EncapsulationKey, Secp256k1Kem, 16 + TryDecapsulate, 17 + kem::{Ciphertext, SharedKey}, 18 + }; 19 + use elliptic_curve::sec1::{FromSec1Point, ToSec1Point}; 20 + use k256::{Sec1Point, ecdh::SharedSecret, elliptic_curve::subtle::ConstantTimeEq}; 21 + 22 + extern crate alloc; 23 + 24 + #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 25 + pub struct HandshakeError; 26 + 27 + impl core::fmt::Display for HandshakeError { 28 + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 29 + f.write_str("aead::Error") 30 + } 31 + } 32 + 33 + impl core::error::Error for HandshakeError {} 34 + 35 + pub struct ClientHandshake(Secp256k1DecapsulationKey); 36 + 37 + pub struct EncapsulatedPublicKey(Secp256k1EncapsulationKey); 38 + 39 + impl EncapsulatedPublicKey { 40 + pub fn serialize(&self) -> Sec1Point { 41 + self.0.to_sec1_point(true) 42 + } 43 + 44 + pub fn deserialize(buf: &[u8]) -> Result<Self, HandshakeError> { 45 + Ok(Self( 46 + Secp256k1EncapsulationKey::from_sec1_bytes(buf).map_err(|_| HandshakeError)?, 47 + )) 48 + } 49 + 50 + pub fn encapsulate(&self) -> (Ciphertext<Secp256k1Kem>, SharedKey<Secp256k1Kem>) { 51 + self.0.encapsulate() 52 + } 53 + } 54 + 55 + impl ClientHandshake { 56 + pub fn send() -> (EncapsulatedPublicKey, Self) { 57 + let (decap, encap) = Secp256k1Kem::generate_keypair(); 58 + 59 + (EncapsulatedPublicKey(encap), Self(decap)) 60 + } 61 + 62 + pub fn finish( 63 + self, 64 + ciphertext: &[u8], 65 + psk: &[u8; 32], 66 + ) -> Result<TransportState, HandshakeError> { 67 + let shared = self 68 + .0 69 + .try_decapsulate_slice(ciphertext) 70 + .map_err(|_| HandshakeError)?; 71 + 72 + TransportState::init(psk, shared) 73 + } 74 + } 75 + 76 + pub struct ServerHandshake(SharedKey<Secp256k1Kem>); 77 + 78 + impl ServerHandshake { 79 + pub fn receive(buf: &[u8]) -> Result<(Ciphertext<Secp256k1Kem>, Self), HandshakeError> { 80 + let encap = EncapsulatedPublicKey::deserialize(buf)?; 81 + 82 + let (ciphertext, sk) = encap.encapsulate(); 83 + 84 + Ok((ciphertext, Self(sk))) 85 + } 86 + 87 + pub fn finish(self, psk: &[u8; 32]) -> Result<TransportState, HandshakeError> { 88 + TransportState::init(psk, self.0) 89 + } 90 + } 91 + 92 + /// Error type. 93 + /// 94 + /// This type is deliberately opaque as to avoid potential side-channel 95 + /// leakage (e.g. padding oracle). 96 + #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] 97 + pub struct AeadError; 98 + 99 + impl core::fmt::Display for AeadError { 100 + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 101 + f.write_str("aead::Error") 102 + } 103 + } 104 + 105 + impl core::error::Error for AeadError {} 106 + 107 + impl From<chacha20poly1305::Error> for AeadError { 108 + fn from(_value: chacha20poly1305::Error) -> Self { 109 + AeadError 110 + } 111 + } 112 + 113 + /// Nonce as used by a given AEAD construction and STREAM primitive. 114 + pub type Nonce<A, S> = chacha20poly1305::aead::array::Array<u8, NonceSize<A, S>>; 115 + 116 + /// Size of a nonce as used by a STREAM construction, sans the overhead of 117 + /// the STREAM protocol itself. 118 + pub type NonceSize<A, S> = 119 + <<A as AeadCore>::NonceSize as Sub<<S as StreamPrimitive<A>>::NonceOverhead>>::Output; 120 + 121 + /// Low-level STREAM implementation. 122 + /// 123 + /// This trait provides a particular "flavor" of STREAM, as there are 124 + /// different ways the specifics of the construction can be implemented. 125 + /// 126 + /// Deliberately immutable and stateless to permit parallel operation. 127 + pub trait StreamPrimitive<A> 128 + where 129 + A: AeadInOut, 130 + A::NonceSize: Sub<Self::NonceOverhead>, 131 + NonceSize<A, Self>: ArraySize, 132 + { 133 + /// Number of bytes this STREAM primitive requires from the nonce. 134 + type NonceOverhead: ArraySize; 135 + 136 + /// Type used as the STREAM counter. 137 + type Counter: AddAssign + Copy + Default + Eq; 138 + 139 + /// Value to use when incrementing the STREAM counter (i.e. one) 140 + const COUNTER_INCR: Self::Counter; 141 + 142 + /// Maximum value of the STREAM counter. 143 + const COUNTER_MAX: Self::Counter; 144 + 145 + /// Encrypt an AEAD message in-place at the given position in the STREAM. 146 + fn encrypt_in_place( 147 + &self, 148 + position: Self::Counter, 149 + associated_data: &[u8], 150 + buffer: &mut dyn Buffer, 151 + ) -> Result<(), AeadError>; 152 + 153 + /// Decrypt an AEAD message in-place at the given position in the STREAM. 154 + fn decrypt_in_place( 155 + &self, 156 + position: Self::Counter, 157 + associated_data: &[u8], 158 + buffer: &mut dyn Buffer, 159 + ) -> Result<(), AeadError>; 160 + } 161 + 162 + pub struct TransportState { 163 + aead: ChaCha20Poly1305, 164 + epstein: Nonce<ChaCha20Poly1305, Self>, 165 + counter: u64, 166 + } 167 + 168 + impl StreamPrimitive<ChaCha20Poly1305> for TransportState { 169 + type NonceOverhead = U8; 170 + 171 + type Counter = u64; 172 + 173 + const COUNTER_INCR: Self::Counter = 1; 174 + 175 + const COUNTER_MAX: Self::Counter = u64::MAX; 176 + 177 + fn encrypt_in_place( 178 + &self, 179 + position: Self::Counter, 180 + associated_data: &[u8], 181 + buffer: &mut dyn Buffer, 182 + ) -> Result<(), AeadError> { 183 + let epstein = self.aead_nonce(position); 184 + self.aead 185 + .encrypt_in_place(&epstein, associated_data, buffer)?; 186 + Ok(()) 187 + } 188 + 189 + fn decrypt_in_place( 190 + &self, 191 + position: Self::Counter, 192 + associated_data: &[u8], 193 + buffer: &mut dyn Buffer, 194 + ) -> Result<(), AeadError> { 195 + let epstein = self.aead_nonce(position); 196 + self.aead 197 + .decrypt_in_place(&epstein, associated_data, buffer)?; 198 + Ok(()) 199 + } 200 + } 201 + 202 + impl TransportState { 203 + fn aead_nonce(&self, position: u64) -> aead::Nonce<ChaCha20Poly1305> { 204 + let mut result = Array::default(); 205 + 206 + let (prefix, tail) = result.split_at_mut(NonceSize::<ChaCha20Poly1305, Self>::to_usize()); 207 + 208 + prefix.copy_from_slice(&self.epstein); 209 + 210 + tail[..8].copy_from_slice(&position.to_be_bytes()); 211 + 212 + result 213 + } 214 + 215 + pub fn init(psk: &[u8; 32], shared: impl Into<SharedSecret>) -> Result<Self, HandshakeError> { 216 + let kdf = shared.into().extract::<sha2::Sha256>(Some(psk)); 217 + 218 + let mut key = [0u8; 32]; 219 + 220 + kdf.expand(b"sachy-crypto", &mut key) 221 + .map_err(|_| HandshakeError)?; 222 + 223 + let mut epstein = Nonce::<ChaCha20Poly1305, Self>::default(); 224 + 225 + kdf.expand(b"noncer", &mut epstein) 226 + .map_err(|_| HandshakeError)?; 227 + 228 + Ok(Self { 229 + aead: ChaCha20Poly1305::new(&key.into()), 230 + epstein, 231 + counter: 0, 232 + }) 233 + } 234 + 235 + pub fn encrypt(&mut self, msg: &mut alloc::vec::Vec<u8>) -> Result<(), AeadError> { 236 + let counter_data = self.counter.to_be_bytes(); 237 + 238 + self.encrypt_in_place(self.counter, &counter_data, msg)?; 239 + 240 + self.counter += Self::COUNTER_INCR; 241 + 242 + if self.counter.ct_eq(&Self::COUNTER_MAX).into() { 243 + Err(AeadError) 244 + } else { 245 + Ok(()) 246 + } 247 + } 248 + 249 + pub fn decrypt(&mut self, msg: &mut alloc::vec::Vec<u8>) -> Result<(), AeadError> { 250 + let counter_data = self.counter.to_be_bytes(); 251 + 252 + self.decrypt_in_place(self.counter, &counter_data, msg)?; 253 + 254 + self.counter += Self::COUNTER_INCR; 255 + 256 + if self.counter.ct_eq(&Self::COUNTER_MAX).into() { 257 + Err(AeadError) 258 + } else { 259 + Ok(()) 260 + } 261 + } 262 + } 263 + 264 + #[cfg(test)] 265 + mod tests { 266 + use super::*; 267 + 268 + #[test] 269 + fn handshake_protocol_works() -> Result<(), HandshakeError> { 270 + let psk: [u8; 32] = [ 271 + 31, 48, 29, 177, 88, 236, 186, 84, 65, 51, 214, 243, 174, 24, 45, 101, 229, 129, 62, 272 + 132, 45, 174, 183, 65, 89, 73, 107, 177, 77, 90, 164, 251, 273 + ]; 274 + 275 + let (ek, client) = ClientHandshake::send(); 276 + 277 + // Pretend to send ek across the webz: client -> server 278 + let (ciphertext, server) = ServerHandshake::receive(ek.serialize().as_bytes())?; 279 + 280 + // Pretend to send ciphertext across the webz: server -> client 281 + let client_transport = client.finish(&ciphertext, &psk)?; 282 + let server_transport = server.finish(&psk)?; 283 + 284 + // If the nonces match, then we can assume the rest of the internal state is correct 285 + assert_eq!( 286 + client_transport.epstein.as_slice(), 287 + server_transport.epstein.as_slice() 288 + ); 289 + 290 + Ok(()) 291 + } 292 + 293 + #[test] 294 + fn two_way_transport_sync_works() -> Result<(), AeadError> { 295 + let shared_secret = [ 296 + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 297 + 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 298 + 0x9c, 0x9d, 0x9e, 0x9f, 299 + ]; 300 + 301 + let psk: [u8; 32] = [ 302 + 31, 48, 29, 177, 88, 236, 186, 84, 65, 51, 214, 243, 174, 24, 45, 101, 229, 129, 62, 303 + 132, 45, 174, 183, 65, 89, 73, 107, 177, 77, 90, 164, 251, 304 + ]; 305 + 306 + let mut alice = TransportState::init(&psk, Array(shared_secret)).map_err(|_| AeadError)?; 307 + let mut bob = TransportState::init(&psk, Array(shared_secret)).map_err(|_| AeadError)?; 308 + 309 + let orig = b"Test Message, Please ignore.".to_vec(); 310 + 311 + let mut msg = orig.clone(); 312 + 313 + // a -> b 314 + alice.encrypt(&mut msg)?; 315 + 316 + assert_ne!(orig.as_slice(), msg.as_slice()); 317 + let a1 = msg.clone(); 318 + 319 + bob.decrypt(&mut msg)?; 320 + 321 + // a -> b 322 + alice.encrypt(&mut msg)?; 323 + 324 + assert_ne!(msg.as_slice(), a1.as_slice()); 325 + let a2 = msg.clone(); 326 + 327 + bob.decrypt(&mut msg)?; 328 + 329 + // b -> a 330 + bob.encrypt(&mut msg)?; 331 + 332 + // None of the ciphertexts should match each other 333 + assert_ne!(msg.as_slice(), a1.as_slice()); 334 + assert_ne!(msg.as_slice(), a2.as_slice()); 335 + assert_ne!(a1.as_slice(), a2.as_slice()); 336 + 337 + alice.decrypt(&mut msg)?; 338 + 339 + assert_eq!(orig.as_slice(), msg.as_slice()); 340 + assert_eq!(alice.counter, bob.counter); 341 + 342 + Ok(()) 343 + } 344 + }