diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index c421777496..3a71d0e676 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -120,6 +120,8 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 + # Keep page update dates without fetching old file contents. + filter: blob:none - uses: ./.github/actions/setup-nix with: disk-key: web diff --git a/.github/workflows/test-sdk.yml b/.github/workflows/test-sdk.yml index 9b88d5a9ea..ab17c4f964 100644 --- a/.github/workflows/test-sdk.yml +++ b/.github/workflows/test-sdk.yml @@ -24,8 +24,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 - with: - fetch-depth: 0 - uses: ./.github/actions/setup-nix with: disk-key: rust diff --git a/Cargo.lock b/Cargo.lock index 243cd998b7..1fd5a5831f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2652,7 +2652,7 @@ version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee3344d349528f449816cfa85e558c439bdca5a6d8a738cfb21e69f0b2b1952f" dependencies = [ - "hax-lib", + "hax-lib 0.3.7", "pastey", "rand 0.10.2", ] @@ -2696,6 +2696,18 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "crabgrind" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "035c801dc4b418e1d857a6536dc88b4d1929c7a1fd163389766e18d322d34a84" +dependencies = [ + "bindgen", + "cc", + "pkg-config", + "rustversion", +] + [[package]] name = "crc" version = "3.4.0" @@ -5001,7 +5013,18 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01a33cb227f97ee5c419064c31d7c55a7d895f28d8019ccdadc311cc036500c4" dependencies = [ - "hax-lib-macros", + "hax-lib-macros 0.3.7", + "num-bigint", + "num-traits", +] + +[[package]] +name = "hax-lib" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb3bfcfc915e894c331662e4ac76706b777a5956535ea24535f4df30da04b1bf" +dependencies = [ + "hax-lib-macros 0.4.2", "num-bigint", "num-traits", ] @@ -5012,13 +5035,25 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28da835a5f153e9f3d0cc1f42ee605a1cfa9093c93348193793d60a1b0908b51" dependencies = [ - "hax-lib-macros-types", + "hax-lib-macros-types 0.3.7", "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.119", ] +[[package]] +name = "hax-lib-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9010990fcba1d1494047fa433a433be0a5df23653a9784c739f7bba270272e" +dependencies = [ + "hax-lib-macros-types 0.4.2", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "hax-lib-macros-types" version = "0.3.7" @@ -5032,6 +5067,19 @@ dependencies = [ "uuid", ] +[[package]] +name = "hax-lib-macros-types" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e053e3a5aeb92df47b07323180c5088edc488ca49883a234f6c73255c54cc520" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_json", + "uuid", +] + [[package]] name = "heapless" version = "0.8.0" @@ -5140,12 +5188,12 @@ dependencies = [ [[package]] name = "hpke-rs" version = "0.6.1" -source = "git+https://github.com/xmtp/hpke-rs?rev=6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2#6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2" +source = "git+https://github.com/xmtp/hpke-rs?rev=78103b02868d6283524d6f7e4105bb85eedac8e2#78103b02868d6283524d6f7e4105bb85eedac8e2" dependencies = [ "hpke-rs-crypto 0.6.1", "hpke-rs-libcrux 0.6.1", "hpke-rs-rust-crypto 0.6.1", - "libcrux-sha3", + "libcrux-sha3 0.0.10", "log", "rand_core 0.9.5", "serde", @@ -5163,7 +5211,7 @@ dependencies = [ "hpke-rs-crypto 0.7.0", "hpke-rs-libcrux 0.7.0", "hpke-rs-rust-crypto 0.7.0", - "libcrux-sha3", + "libcrux-sha3 0.0.10", "log", "serde", "subtle", @@ -5174,7 +5222,7 @@ dependencies = [ [[package]] name = "hpke-rs-crypto" version = "0.6.1" -source = "git+https://github.com/xmtp/hpke-rs?rev=6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2#6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2" +source = "git+https://github.com/xmtp/hpke-rs?rev=78103b02868d6283524d6f7e4105bb85eedac8e2#78103b02868d6283524d6f7e4105bb85eedac8e2" dependencies = [ "rand_core 0.9.5", "zeroize", @@ -5193,14 +5241,14 @@ dependencies = [ [[package]] name = "hpke-rs-libcrux" version = "0.6.1" -source = "git+https://github.com/xmtp/hpke-rs?rev=6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2#6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2" +source = "git+https://github.com/xmtp/hpke-rs?rev=78103b02868d6283524d6f7e4105bb85eedac8e2#78103b02868d6283524d6f7e4105bb85eedac8e2" dependencies = [ "hpke-rs-crypto 0.6.1", "libcrux-aead", - "libcrux-ecdh", + "libcrux-ecdh 0.0.8", "libcrux-hkdf", "libcrux-kem", - "libcrux-traits", + "libcrux-traits 0.0.8", "rand 0.10.2", "rand_chacha 0.10.0", "rand_core 0.10.1", @@ -5210,15 +5258,14 @@ dependencies = [ [[package]] name = "hpke-rs-libcrux" version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c1ace95ef11fbbd84527eada5fc1304f66720fc4c008db30d888d62d3c52613" +source = "git+https://github.com/xmtp/libcrux?rev=fd17d0257acd49f0c73b0dc4c3e9dcd4b42a7102#fd17d0257acd49f0c73b0dc4c3e9dcd4b42a7102" dependencies = [ "hpke-rs-crypto 0.7.0", "libcrux-aead", - "libcrux-ecdh", + "libcrux-ecdh 0.0.8", "libcrux-hkdf", "libcrux-kem", - "libcrux-traits", + "libcrux-traits 0.0.8", "rand 0.10.2", "rand_chacha 0.10.0", "rand_core 0.10.1", @@ -5228,7 +5275,7 @@ dependencies = [ [[package]] name = "hpke-rs-rust-crypto" version = "0.6.1" -source = "git+https://github.com/xmtp/hpke-rs?rev=6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2#6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2" +source = "git+https://github.com/xmtp/hpke-rs?rev=78103b02868d6283524d6f7e4105bb85eedac8e2#78103b02868d6283524d6f7e4105bb85eedac8e2" dependencies = [ "aes-gcm", "chacha20poly1305", @@ -6146,8 +6193,8 @@ checksum = "22acbe68be84b7b41aaba6e39b87036fc4324dee628d94773750bf3d7e906d69" dependencies = [ "libcrux-aes", "libcrux-chacha20poly1305", - "libcrux-secrets", - "libcrux-traits", + "libcrux-secrets 0.0.6", + "libcrux-traits 0.0.8", ] [[package]] @@ -6156,10 +6203,10 @@ version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57cc95b11dbc797b1e169467b1fc4205c4e6ee2ce516a035ad7342ce5f6ae971" dependencies = [ - "libcrux-intrinsics", - "libcrux-platform", - "libcrux-secrets", - "libcrux-traits", + "libcrux-intrinsics 0.0.8", + "libcrux-platform 0.0.3", + "libcrux-secrets 0.0.6", + "libcrux-traits 0.0.8", ] [[package]] @@ -6168,11 +6215,11 @@ version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "537e6eee5cdc9a980014d058784b0be09614f0596df789b114f7833aa9f35d75" dependencies = [ - "libcrux-hacl-rs", - "libcrux-macros", + "libcrux-hacl-rs 0.0.5", + "libcrux-macros 0.0.3", "libcrux-poly1305", - "libcrux-secrets", - "libcrux-traits", + "libcrux-secrets 0.0.6", + "libcrux-traits 0.0.8", ] [[package]] @@ -6181,10 +6228,22 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4f3cfd5e31cb9745e290ee061222c380ec42884654b09fc7d12a5b0ed63e028" dependencies = [ - "libcrux-hacl-rs", - "libcrux-macros", - "libcrux-secrets", - "libcrux-traits", + "libcrux-hacl-rs 0.0.5", + "libcrux-macros 0.0.3", + "libcrux-secrets 0.0.6", + "libcrux-traits 0.0.8", +] + +[[package]] +name = "libcrux-curve25519" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e78d0f36b23bcf258792dcc3a948fc628cb195950afa7b9a954250714688cfd" +dependencies = [ + "libcrux-hacl-rs 0.0.6", + "libcrux-macros 0.0.4", + "libcrux-secrets 0.0.7", + "libcrux-traits 0.0.9", ] [[package]] @@ -6193,8 +6252,20 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a227590b89ff55ce7cd97b5a7468c82d231db8f3b890bb4d4fb6d271e7524d7" dependencies = [ - "libcrux-curve25519", - "libcrux-p256", + "libcrux-curve25519 0.0.8", + "libcrux-p256 0.0.8", + "rand 0.10.2", + "tls_codec 0.5.0", +] + +[[package]] +name = "libcrux-ecdh" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50abafa35c0caade2f358504b7da0a438a7382dc1262f855aa479e89578301b6" +dependencies = [ + "libcrux-curve25519 0.0.9", + "libcrux-p256 0.0.9", "rand 0.10.2", "tls_codec 0.5.0", ] @@ -6205,9 +6276,9 @@ version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc463d32f41c47e03dc664547596928a13cb3d79c03453a9b3fe654649313982" dependencies = [ - "libcrux-hacl-rs", - "libcrux-macros", - "libcrux-sha2", + "libcrux-hacl-rs 0.0.5", + "libcrux-macros 0.0.3", + "libcrux-sha2 0.0.8", "rand_core 0.10.1", ] @@ -6217,7 +6288,16 @@ version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66106db376ae249af86911aee048cf73ea1f394d6653026fc988dd22cf2a4ace" dependencies = [ - "libcrux-macros", + "libcrux-macros 0.0.3", +] + +[[package]] +name = "libcrux-hacl-rs" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27ce64ead37fc67c1039fdbcf1e8c97044e6a644cb3d1f79060b5c9ac8fdfe0a" +dependencies = [ + "libcrux-macros 0.0.4", ] [[package]] @@ -6226,9 +6306,9 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc94e651dca4d47edbcdd88bb2428ce16a2bd86b7a4e7170da87b505478f9839" dependencies = [ - "libcrux-hacl-rs", + "libcrux-hacl-rs 0.0.5", "libcrux-hmac", - "libcrux-secrets", + "libcrux-secrets 0.0.6", ] [[package]] @@ -6237,10 +6317,10 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "500ad9b32c715161b594172ca1fb11503a1c033b393ff4c0c33505ce51c1943c" dependencies = [ - "libcrux-hacl-rs", - "libcrux-macros", - "libcrux-sha2", - "libcrux-traits", + "libcrux-hacl-rs 0.0.5", + "libcrux-macros 0.0.3", + "libcrux-sha2 0.0.8", + "libcrux-traits 0.0.8", ] [[package]] @@ -6260,21 +6340,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98a0c574d4eb81d0814bc2b91e4a433d7e0b35851b1d62eb5dd95c064f1f76d0" dependencies = [ "core-models", - "hax-lib", + "hax-lib 0.3.7", ] [[package]] -name = "libcrux-kem" +name = "libcrux-intrinsics" version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "541a7377fb35060892e0620982e224e47419f10da8c212453bf642dafe529691" +checksum = "de82722c9c7419a311e84ee902e9643a15e39a6fcaade87f21e94f8d0f30fa70" +dependencies = [ + "core-models", + "hax-lib 0.4.2", +] + +[[package]] +name = "libcrux-kem" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31bf62e2a587002bf2ccc022015daeb8457e1e09269b3544aeec12243a3e9b74" dependencies = [ - "libcrux-curve25519", - "libcrux-ecdh", + "libcrux-curve25519 0.0.9", + "libcrux-ecdh 0.0.9", "libcrux-ml-kem", - "libcrux-p256", - "libcrux-sha3", - "libcrux-traits", + "libcrux-p256 0.0.9", + "libcrux-sha3 0.0.11", + "libcrux-traits 0.0.9", "rand 0.10.2", ] @@ -6288,18 +6378,28 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "libcrux-macros" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2afdd4da30d6e23f76bd6f3ad61be5c773720349eef3e791f8b79cfea3fe1436" +dependencies = [ + "quote", + "syn 3.0.3", +] + [[package]] name = "libcrux-ml-kem" -version = "0.0.10" +version = "0.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d8160f7d64fd2716b4fd05cc886a042f8dcda18d9206c0d506e2c67bdf97daa" +checksum = "4ceed00367748ec0b545bc4a7b0521f8c9fd476d02484340f0a95b0f45f828cd" dependencies = [ - "hax-lib", - "libcrux-intrinsics", - "libcrux-platform", - "libcrux-secrets", - "libcrux-sha3", - "libcrux-traits", + "hax-lib 0.4.2", + "libcrux-intrinsics 0.0.9", + "libcrux-platform 0.0.4", + "libcrux-secrets 0.0.7", + "libcrux-sha3 0.0.11", + "libcrux-traits 0.0.9", "rand 0.10.2", "tls_codec 0.5.0", ] @@ -6310,11 +6410,24 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3400732702d578be622257b98cec85e9b0cd34a67f1f06d3ebe9ae34963cdf02" dependencies = [ - "libcrux-hacl-rs", - "libcrux-macros", - "libcrux-secrets", - "libcrux-sha2", - "libcrux-traits", + "libcrux-hacl-rs 0.0.5", + "libcrux-macros 0.0.3", + "libcrux-secrets 0.0.6", + "libcrux-sha2 0.0.8", + "libcrux-traits 0.0.8", +] + +[[package]] +name = "libcrux-p256" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7489aa205be22524e2f6ddbe006c0c4ff5f1dfc7c17b783e3d02f1cb2a01c605" +dependencies = [ + "libcrux-hacl-rs 0.0.6", + "libcrux-macros 0.0.4", + "libcrux-secrets 0.0.7", + "libcrux-sha2 0.0.9", + "libcrux-traits 0.0.9", ] [[package]] @@ -6326,14 +6439,23 @@ dependencies = [ "libc", ] +[[package]] +name = "libcrux-platform" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf8bee8c35d34867a3762d6ee7b74e8523a882855c3cfce30484e9554342206" +dependencies = [ + "libc", +] + [[package]] name = "libcrux-poly1305" version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76a9144949845813a0b8787d08cbba47baabe59c83f3043e558e6e92385c40cc" dependencies = [ - "libcrux-hacl-rs", - "libcrux-macros", + "libcrux-hacl-rs 0.0.5", + "libcrux-macros 0.0.3", ] [[package]] @@ -6342,8 +6464,18 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79054fc9037cb70d6a546cf094cea7d7df06af5e49d230ba24103d27ccc886f1" dependencies = [ - "crabgrind", - "hax-lib", + "crabgrind 0.2.6", + "hax-lib 0.3.7", +] + +[[package]] +name = "libcrux-secrets" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c4ba47b3596f2771213ff162c792e9b93ddc0cdd178a2e407e00bb8ae4afcd" +dependencies = [ + "crabgrind 0.3.1", + "hax-lib 0.4.2", ] [[package]] @@ -6352,9 +6484,20 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "960e46e1be0b77098cc6ce82137864936ecad3a1b9fd4303dd51202ca140dd1e" dependencies = [ - "libcrux-hacl-rs", - "libcrux-macros", - "libcrux-traits", + "libcrux-hacl-rs 0.0.5", + "libcrux-macros 0.0.3", + "libcrux-traits 0.0.8", +] + +[[package]] +name = "libcrux-sha2" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86aa35d8fc9576a41df34af4d95d1f11186c1f65cd6c829329748915ea556d71" +dependencies = [ + "libcrux-hacl-rs 0.0.6", + "libcrux-macros 0.0.4", + "libcrux-traits 0.0.9", ] [[package]] @@ -6363,10 +6506,22 @@ version = "0.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c09f5c39afae0528e1f70a3c1e3c6ee649ec1f19dda26fc9b6ea91108fb879ef" dependencies = [ - "hax-lib", - "libcrux-intrinsics", - "libcrux-platform", - "libcrux-traits", + "hax-lib 0.3.7", + "libcrux-intrinsics 0.0.8", + "libcrux-platform 0.0.3", + "libcrux-traits 0.0.8", +] + +[[package]] +name = "libcrux-sha3" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8117e86e1f03417d8ebe50ed298c6ee0b05557783a75697d0c59a2ef2dcfc6" +dependencies = [ + "hax-lib 0.4.2", + "libcrux-intrinsics 0.0.9", + "libcrux-platform 0.0.4", + "libcrux-traits 0.0.9", ] [[package]] @@ -6375,7 +6530,17 @@ version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fa7a21e8c2e8baa8b40f0b176740f2ca4baadd79d1b00e48d6b1e363c42085a" dependencies = [ - "libcrux-secrets", + "libcrux-secrets 0.0.6", + "rand 0.10.2", +] + +[[package]] +name = "libcrux-traits" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8958bb5c3780eb7c3355aeeb051629b830e47bfefd36befed93c81b53366bbc4" +dependencies = [ + "libcrux-secrets 0.0.7", "rand 0.10.2", ] @@ -7319,8 +7484,8 @@ dependencies = [ "libcrux-hkdf", "libcrux-hmac", "libcrux-hmac-drbg", - "libcrux-sha2", - "libcrux-traits", + "libcrux-sha2 0.0.8", + "libcrux-traits 0.0.8", "openmls_memory_storage", "openmls_traits", "rand 0.10.2", @@ -12452,7 +12617,8 @@ dependencies = [ "itertools 0.14.0", "k256", "libc", - "libcrux-ecdh", + "libcrux-ecdh 0.0.8", + "libcrux-ecdh 0.0.9", "libcrux-kem", "libcrux-ml-kem", "linux-raw-sys 0.12.1", diff --git a/Cargo.toml b/Cargo.toml index 4bc6ccfba5..083e2f5ce8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -327,7 +327,7 @@ lto = true [patch.crates-io] diesel = { git = "https://github.com/ephemerahq/diesel", branch = "coda/copy-to-sqlite" } diesel_migrations = { git = "https://github.com/ephemerahq/diesel", branch = "coda/copy-to-sqlite" } -# xmtp/hpke-rs fork of v0.6.1 with one extra commit adding +# xmtp/hpke-rs fork of v0.6.1 with the patched libcrux KEM and # XWingDraft06Obsolete dispatch in the libcrux backend. Lets the # welcome wrapper pin to the obsolete 0x004D codepoint for wire compat # with v1.9 / v1.10 clients (hpke-rs 0.4). All four sister crates patch @@ -335,10 +335,12 @@ diesel_migrations = { git = "https://github.com/ephemerahq/diesel", branch = "co # only the backend produces two HpkeCrypto trait versions in the graph # and breaks openmls_libcrux_crypto. Remove when the d14n cutover # migrates everyone to 0x647a (#3661). -hpke-rs = { git = "https://github.com/xmtp/hpke-rs", rev = "6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2" } -hpke-rs-crypto = { git = "https://github.com/xmtp/hpke-rs", rev = "6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2" } -hpke-rs-libcrux = { git = "https://github.com/xmtp/hpke-rs", rev = "6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2" } -hpke-rs-rust-crypto = { git = "https://github.com/xmtp/hpke-rs", rev = "6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2" } +hpke-rs = { git = "https://github.com/xmtp/hpke-rs", rev = "78103b02868d6283524d6f7e4105bb85eedac8e2" } +hpke-rs-crypto = { git = "https://github.com/xmtp/hpke-rs", rev = "78103b02868d6283524d6f7e4105bb85eedac8e2" } +hpke-rs-libcrux = { git = "https://github.com/xmtp/hpke-rs", rev = "78103b02868d6283524d6f7e4105bb85eedac8e2" } +hpke-rs-rust-crypto = { git = "https://github.com/xmtp/hpke-rs", rev = "78103b02868d6283524d6f7e4105bb85eedac8e2" } +# OpenMLS uses HPKE 0.7. Keep its registry trait identity while updating the KEM. +hpke-rs-libcrux-07 = { package = "hpke-rs-libcrux", git = "https://github.com/xmtp/libcrux", rev = "fd17d0257acd49f0c73b0dc4c3e9dcd4b42a7102" } tracing-oslog = { git = "https://github.com/xmtp/tracing-oslog", rev = "69cebec3804c33267b8d18aa50a5d9ba18617121" } [patch.crates-io.xmtp-workspace-hack] diff --git a/crates/xmtp-workspace-hack/Cargo.toml b/crates/xmtp-workspace-hack/Cargo.toml index 5183bb7c9e..b9e4565ecd 100644 --- a/crates/xmtp-workspace-hack/Cargo.toml +++ b/crates/xmtp-workspace-hack/Cargo.toml @@ -59,9 +59,10 @@ idna = { version = "1" } indexmap = { version = "2", features = ["serde"] } itertools = { version = "0.14" } k256 = { version = "0.13", default-features = false, features = ["ecdh", "ecdsa", "std"] } -libcrux-ecdh = { version = "0.0.8", default-features = false, features = ["std"] } -libcrux-kem = { version = "0.0.9", default-features = false, features = ["std"] } -libcrux-ml-kem = { version = "0.0.10", default-features = false, features = ["default-no-std", "std"] } +libcrux-ecdh-42067ae6dcec6957 = { package = "libcrux-ecdh", version = "0.0.8", default-features = false, features = ["std"] } +libcrux-ecdh-809e0a33c67ce633 = { package = "libcrux-ecdh", version = "0.0.9", default-features = false, features = ["std"] } +libcrux-kem = { version = "0.0.10", default-features = false, features = ["std"] } +libcrux-ml-kem = { version = "0.0.11", default-features = false, features = ["default-no-std", "std"] } log = { version = "0.4", default-features = false, features = ["std"] } memchr = { version = "2" } nu-ansi-term = { version = "0.50" } @@ -152,9 +153,10 @@ idna = { version = "1" } indexmap = { version = "2", features = ["serde"] } itertools = { version = "0.14" } k256 = { version = "0.13", default-features = false, features = ["ecdh", "ecdsa", "std"] } -libcrux-ecdh = { version = "0.0.8", default-features = false, features = ["std"] } -libcrux-kem = { version = "0.0.9", default-features = false, features = ["std"] } -libcrux-ml-kem = { version = "0.0.10", default-features = false, features = ["default-no-std", "std"] } +libcrux-ecdh-42067ae6dcec6957 = { package = "libcrux-ecdh", version = "0.0.8", default-features = false, features = ["std"] } +libcrux-ecdh-809e0a33c67ce633 = { package = "libcrux-ecdh", version = "0.0.9", default-features = false, features = ["std"] } +libcrux-kem = { version = "0.0.10", default-features = false, features = ["std"] } +libcrux-ml-kem = { version = "0.0.11", default-features = false, features = ["default-no-std", "std"] } log = { version = "0.4", default-features = false, features = ["std"] } memchr = { version = "2" } nu-ansi-term = { version = "0.50" } diff --git a/crates/xmtp_mls_common/src/mls_ext/payload_encryption.rs b/crates/xmtp_mls_common/src/mls_ext/payload_encryption.rs index e357509364..25a3750e71 100644 --- a/crates/xmtp_mls_common/src/mls_ext/payload_encryption.rs +++ b/crates/xmtp_mls_common/src/mls_ext/payload_encryption.rs @@ -179,6 +179,70 @@ mod tests { use openmls_traits::{crypto::OpenMlsCrypto, random::OpenMlsRand}; use xmtp_configuration::{CIPHERSUITE, POST_QUANTUM_CIPHERSUITE, WELCOME_HPKE_LABEL}; + // These public test keys and ciphertexts were made with libcrux-kem 0.0.9. + // See payload_encryption/fixtures/legacy_xwing/README.md for their source. + const LEGACY_XWING_PUBLIC_KEY: &str = + include_str!("payload_encryption/fixtures/legacy_xwing/public_key.hex"); + const LEGACY_XWING_PRIVATE_KEY: &str = + include_str!("payload_encryption/fixtures/legacy_xwing/private_key.hex"); + const LEGACY_XWING_WRAPPED_PAYLOAD: &str = + include_str!("payload_encryption/fixtures/legacy_xwing/wrapped_payload.hex"); + const LEGACY_XWING_SECONDARY_CIPHERTEXT: &str = + include_str!("payload_encryption/fixtures/legacy_xwing/secondary_ciphertext.hex"); + const LEGACY_XWING_PAYLOAD: &[u8] = b"persisted Welcome compatibility fixture"; + const LEGACY_XWING_SECONDARY_PAYLOAD: &[u8] = b"persisted Welcome metadata"; + const LEGACY_XWING_IKM: [u8; 32] = [7; 32]; + + #[xmtp_common::test(unwrap_try = true)] + fn legacy_xwing_opens_persisted_welcome() { + let (payload, secondary) = unwrap_payload_hpke( + &hex::decode(LEGACY_XWING_WRAPPED_PAYLOAD.trim())?, + &hex::decode(LEGACY_XWING_SECONDARY_CIPHERTEXT.trim())?, + &hex::decode(LEGACY_XWING_PRIVATE_KEY.trim())?, + WrapperAlgorithm::XWingMLKEM768Draft6, + WELCOME_HPKE_LABEL, + )?; + + assert_eq!(payload, LEGACY_XWING_PAYLOAD); + assert_eq!(secondary, LEGACY_XWING_SECONDARY_PAYLOAD); + } + + #[xmtp_common::test(unwrap_try = true)] + fn legacy_xwing_key_encoding_is_stable() { + let hpke = WrapperAlgorithm::XWingMLKEM768Draft6.to_hpke_config(); + let pair = hpke.derive_key_pair(&LEGACY_XWING_IKM)?; + + assert_eq!( + pair.public_key().as_slice(), + hex::decode(LEGACY_XWING_PUBLIC_KEY.trim())? + ); + assert_eq!( + pair.private_key().as_slice(), + hex::decode(LEGACY_XWING_PRIVATE_KEY.trim())? + ); + } + + #[xmtp_common::test(unwrap_try = true)] + fn legacy_xwing_stored_keys_accept_new_welcome() { + let (wrapped, metadata) = wrap_payload_hpke( + LEGACY_XWING_PAYLOAD, + LEGACY_XWING_SECONDARY_PAYLOAD, + &hex::decode(LEGACY_XWING_PUBLIC_KEY.trim())?, + WrapperAlgorithm::XWingMLKEM768Draft6, + WELCOME_HPKE_LABEL, + )?; + let (payload, secondary) = unwrap_payload_hpke( + &wrapped, + &metadata, + &hex::decode(LEGACY_XWING_PRIVATE_KEY.trim())?, + WrapperAlgorithm::XWingMLKEM768Draft6, + WELCOME_HPKE_LABEL, + )?; + + assert_eq!(payload, LEGACY_XWING_PAYLOAD); + assert_eq!(secondary, LEGACY_XWING_SECONDARY_PAYLOAD); + } + const TEST_LABEL: &str = "test xmtp payload"; fn fresh_curve25519_keypair() -> (Vec, Vec) { diff --git a/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/README.md b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/README.md new file mode 100644 index 0000000000..82ca63daf2 --- /dev/null +++ b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/README.md @@ -0,0 +1,46 @@ +# Legacy XWing Welcome fixture + +These are public test keys. Do not use them for messages outside tests. + +The fixture uses `hpke-rs` and `hpke-rs-libcrux` 0.6.1 from the XMTP fork, +revision `6dba5c7ff23fa9ad47d56f3207c8f79ff76b67d2`, with +`libcrux-kem` 0.0.9. It was generated before the upgrade to 0.0.10. + +The HPKE suite is Base mode, XWing draft 06 at codepoint `0x004D`, +HKDF-SHA256, and ChaCha20-Poly1305. The key derivation input is `[7; 32]`. +The info is the TLS encoding of the MLS encryption context for `MLS_WELCOME` +with an empty context. AAD is empty. The second ciphertext uses the same +HPKE context after the first ciphertext, as Welcome metadata does. + +- `public_key.hex` and `private_key.hex` contain the stored recipient keys. +- `wrapped_payload.hex` contains a TLS-encoded `HpkeCiphertext`: the KEM + output followed by the first ciphertext, each with a TLS variable-length prefix. +- `secondary_ciphertext.hex` contains the second ciphertext without a prefix. + +## Generation and upgrade check + +`generate.rs` is a standalone harness. Run it in an isolated temporary +Cargo package through `dev/nix-shell`. Use `hpke-rs` from a copy of the +revision above, with the `libcrux`, `hazmat`, and `std` features. Add `hex = +"0.4"` and `serde_json = "1"` to the temporary package. + +For this harness only, change the provider's `prng()` constructor in the +copied `libcrux_provider/src/lib.rs` to initialize its `rng` field with +`rand_chacha::ChaCha20Rng::from_seed([42; 32])`. This controls the RNG passed +to XWing encapsulation. The HPKE test RNG seed does not control this path. +Do not make this change in the real provider or enable a test RNG in libxmtp. + +Run the old harness and save its JSON output. Run an identical harness +against the upgraded provider with the old JSON path as its first argument. +It must produce identical key bytes, KEM output, payload ciphertext, and +metadata ciphertext. It also decrypts the old ciphertexts. Save its output, +then pass that output to the old harness to check decryption in the reverse +direction. All three runs passed for the upgrade to `libcrux-kem` 0.0.10. + +The committed tests use ordinary production randomness. They check that the +current provider opens the old ciphertext, derives the same stored key bytes, +and encrypts new Welcomes under the old public key. To run them: + +```sh +dev/nix-shell 'just test workspace -p xmtp_mls_common legacy_xwing' +``` diff --git a/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/generate.rs b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/generate.rs new file mode 100644 index 0000000000..bc7fdd3889 --- /dev/null +++ b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/generate.rs @@ -0,0 +1,51 @@ +use hpke_rs::{ + Hpke, Mode, + hpke_types::{AeadAlgorithm, KdfAlgorithm, KemAlgorithm}, + libcrux::HpkeLibcrux, +}; +fn main() { + #[allow(deprecated)] + let mut hpke = Hpke::::new( + Mode::Base, + KemAlgorithm::XWingDraft06Obsolete, + KdfAlgorithm::HkdfSha256, + AeadAlgorithm::ChaCha20Poly1305, + ); + let ikm = [7u8; 32]; + let pair = hpke.derive_key_pair(&ikm).unwrap(); + let label = b"MLS 1.0 MLS_WELCOME"; + let mut info = vec![label.len() as u8]; + info.extend_from_slice(label); + info.push(0); + let (enc, mut sender) = hpke + .setup_sender(pair.public_key(), &info, None, None, None) + .unwrap(); + let payload = b"persisted Welcome compatibility fixture"; + let secondary = b"persisted Welcome metadata"; + let ct = sender.seal(&[], payload).unwrap(); + let ct2 = sender.seal(&[], secondary).unwrap(); + let mut receiver = hpke + .setup_receiver(&enc, pair.private_key(), &info, None, None, None) + .unwrap(); + assert_eq!(receiver.open(&[], &ct).unwrap(), payload); + assert_eq!(receiver.open(&[], &ct2).unwrap(), secondary); + let fixture = serde_json::json!({"ikm":hex::encode(ikm),"public_key":hex::encode(pair.public_key().as_slice()),"private_key":hex::encode(pair.private_key().as_slice()),"kem_output":hex::encode(enc),"ciphertext":hex::encode(ct),"secondary_ciphertext":hex::encode(ct2),"payload":hex::encode(payload),"secondary_payload":hex::encode(secondary)}); + let args: Vec<_> = std::env::args().collect(); + if let Some(path) = args.get(1) { + let other: serde_json::Value = + serde_json::from_str(&std::fs::read_to_string(path).unwrap()).unwrap(); + assert_eq!(fixture, other, "old and new bytes must match"); + let enc = hex::decode(other["kem_output"].as_str().unwrap()).unwrap(); + let ct = hex::decode(other["ciphertext"].as_str().unwrap()).unwrap(); + let ct2 = hex::decode(other["secondary_ciphertext"].as_str().unwrap()).unwrap(); + let sk = hpke_rs::HpkePrivateKey::new( + hex::decode(other["private_key"].as_str().unwrap()).unwrap(), + ); + let mut receiver = hpke + .setup_receiver(&enc, &sk, &info, None, None, None) + .unwrap(); + assert_eq!(receiver.open(&[], &ct).unwrap(), payload); + assert_eq!(receiver.open(&[], &ct2).unwrap(), secondary); + } + println!("{}", serde_json::to_string_pretty(&fixture).unwrap()); +} diff --git a/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/private_key.hex b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/private_key.hex new file mode 100644 index 0000000000..23f915e442 --- /dev/null +++ b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/private_key.hex @@ -0,0 +1 @@ +d7b4cf68d3f1b711924ccded71a241faf8162f7ef6ce748370a10e86b94befc1 diff --git a/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/public_key.hex b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/public_key.hex new file mode 100644 index 0000000000..118c1496b8 --- /dev/null +++ b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/public_key.hex @@ -0,0 +1 @@ +f164786092ce5e4b14dd0bc9f1858de52471777507cc0172ca34a67410c0c829c68eeb10cfe2374e9565818c7a49a80fae24b9d0d598b0fac41abcabee55cedac1096b1128782c31bc2a9ecd54305907b40250bb70b07008669bca70c23aac5a4e046d05b56250e214938b4923ab7cd4502f92232c825a4cf7269a4853a1fef256e2c739f8d28461bc218a795badc18d1909964328cc928271535343d2595abed57e76604885a38da8395b78b96b34b4a8bef8a6e6b59bef7a75c067c434bcb8953a9d13fb25610a0003580dd6272ebed9996ef70f28f15fb21c65ba3b0b71e016a3062ed7d9aef6f66b930818b3bc05bc31181cc2ac209772fc0318c9d86f50e1725d3833e0c9b7e21857975cabeb0b802db0b9eac4193526b58e00bbb0fb322ea047f3525600389f339250313168a08c706e6021bb568df5f773fa0b4324535d97f41e24e32c028567437354a8f595c8e9132cb60db6120e2e01549dd71bae8a708a374d8450898d148d5ac328f428c395f96873b45035c62efd919c29c89c02153645d685ba81427121c1c900b55c93045eeb22da2674db573b96c6543f11762643c1e6371378e1c0e2008c68655697b2a0b35077cd0305b6746f5957332f109e4c77b4d159c9e1645ed5acb971f98e879559667a4f0ea9136c9a56b03b2e93254e28902a38797cf10b38ff5038d0cc51c0d63b008a93165b52a710b704856b9f30203b588ac4f1659af94cf11bae815268d8d96773a47359a876006393129b2062b47e384424e6a961b523310f333c7863a7989070ef825f394760d76197bc164c2f2c9ab3281ef7268afcc81a508071052611a9c9cd71ec2668928261643243261522498c4c056100438266e0ab060213e1da8153e749b43a3975f2664fc7158003b68fa63c1a3ac663f6b884699d8f8a1fc5e57b1b19630e694beb57806bec43b2e190cdebb75d3a059d63100f0330a3c20e276c70fbbaab40429699a0883c4860a327659eb2893dd3cdb5b56d0933944d4b98730610bc69596ec2c303a6842758278b06b66b9752eb3709c5115f22c835bebb222a6a1715dc9b6f483870fc3afe4a1aa4759b2afcbb9545610dd0c993d28ae324af9cc77184e1a013699f17c7394da32b94165fdbc293ff23112cb38209886e02216bf5a8683e67855eb007f33102c5849e1522b755b3a920880e42f9c8bd869547e271ad464dd12609a8d76b1fb9757c559556121c08d9853560419e28193d2c96b69ab5259650f2854bcd507bc1c76c1530781066c53ea79df99575c8d717a76a0880fc89dabb6dc820b47387ac0deb9390c2b83cb279e40994accc2c478260f34a41e0f20d688682994b1a32b75f9302bfa924cdc70a11fd6c8f860592daf94b4aac76cf945e540b15355b5758856c741a38da5a2d7b29506467aa23f570def0c1c10c6522f819c3fc2daa91445db52afb388313349fd858b473577d9cba2015189866f456cf6516d554a6b87a96a0ca15547caafb9087d6dc210bd67bd5535937c457228c4e8381c382e8330cc3352df60b9b2518d736002f9a486a705712773de93bb169520425cac9fb135c32aa16839a00a9f40396bca1286845bc8005f85b0a45da44951c9ed48ed7a4219ec9bd4a6d9280b223675976f4ed1964c64710fe2d024080a84da1a75c95eb586d23188320169602e84fa03f81baaa915947d491cae23bbae2b511 diff --git a/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/secondary_ciphertext.hex b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/secondary_ciphertext.hex new file mode 100644 index 0000000000..8d7e2cbc06 --- /dev/null +++ b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/secondary_ciphertext.hex @@ -0,0 +1 @@ +71602124b33a560cc4cbcafd9fd149ebd18ac274dec88781e6cea541cb0936b5fd1d83ee5e8c475acd4d diff --git a/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/wrapped_payload.hex b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/wrapped_payload.hex new file mode 100644 index 0000000000..32df867204 --- /dev/null +++ b/crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures/legacy_xwing/wrapped_payload.hex @@ -0,0 +1 @@ +4460091d7e3ddfd3142a8ad23ab7919e372ea812f1269efead948a4648405fdfdf2f02601a1067c33ca168f4e87e1deb388889a502136196611c8c483e9e868e5f9f60401c60bee9ebcf7c776749d64d89e52b6323068790fb788266fe77280d1736bd7e688d1f36529270cef758b3bb15756fe0658e838490cc320575d95763f5a05a7b074b70ab8fac3ef09c49bc5b217703e31dd0624a6c0fca9e05b490590caa0f5d0caa9ffad939ba03119ddf6aff30ea1c9d63a995095f7a83f0cc1830e99add5a2f078f684124b5d1498edaa52780ee1daa584a4c4715d702afae8b41e6b7fe59e2ed5a26cc3ea9c4b9434f3ef6a25c26e50d603aef840b247e6ec90adde776928adbf6e76f88d7174303c3b477b637a766c31cda9726c957f1ca1708bf8e9ca831846c38bac7f564a078f27d8d18ccea6c805fdb6d43425b04c482b6e7fb1758dfdfc7fe90b7da06e664267a30795ce43b9b83d25588dae9e80a9264cebd6e7b6023f3dba2e77a9b3e092ea8c080cbeb0ddd9b74187fe9773f3a20a116564da1c52c229e6e171df24367610378a8982c13f76500710f1854ad7c1e9148b7316b10d020aa97a5fbfff21c0fc3e7fe0a7c3e343f68c0b27af0824ca2b195e04fe5413d2d34520fdf082932e98b42c52ba7922d3a1b8d209be3098107ba671a33b7a47a122a88c9f55620391f2f3fa80d649cd39bebc0e0d7547d462482f2a60870d2d69d0b2c18b24d487190ca93b0cb057a4fa7ed7f04c6458ff0501e6d3c907c3d881a0349fb009fd41ff40420d6c98e494a4c600e9ea2d75afcfde8801bc04076d4d2427a06f0a2c48f01b2a2c5a974d47594f0310c7d7d02c03b91174ede67e2748da91694f360ab8062abe6129efb5f1fdef267676e5b96808ee6afde89c7ed94c3f409866994e346005536f0db3d31bdb3a7386a2487160533722ef15bf5be5cad1c301f148e00b1e90724933d9de73475dceae9ba9f264d30427f5b095c016d8d310cc7c611ffc63a6dc535027ae209a4ad01b4fe8c5a76a65e476a6369386007e85409402c57175fc86c5a8b3795126798efa5fcfe35abfa2f2b25b1e79c54975be751c62a03e2c8f488d162ecc7d3ad276856fdaa5c7f73ac7fdb4b4a299b73b61ac02a7a76c6a2642834647cb6b6b05b4a56e6b0d9d558b8fa7fae860cba42ec34af1a05e4ef0bbd36ab7bdc657af0ca6e073411de69c03ea7a8944f11b51912fb6ee762316b8471f358b59df727e3dcc2d127fa083c5c7f68d06b5053872a55b2aafd3cd3a85c791e119763b11204fc415d210fbd41915979eb6d1b0d847b2b58c5e6b3eca37193d0889c6e5213a917c347a714f67fd5a09eae166ee937d1dbc7098878c42128b4348c71e39fc61cc14eb02ede8fb321466e54a708cd425b8d1577cd154df72e71ea0adc209e13b232b1957206002dc48c329d5cecab199ab295c9a323ac1969f10d0066c4a35f3c988e5c911c1e01b95741bcebd01b4372a13d3a85ce0ac97aae3845b6439e5aab5bc9863cc405d2bbf0b9ed1c5e231d577ef60c1865870825b1e7a16cc962a6420e2eec7a3d8b486e53113437640c6ffd2eb2a9df9d594762af39605435ce0bac2d06d77e3f516b28fa65f535863c3add9802cd924103b123094d7576278defb4df0f22 diff --git a/deny.toml b/deny.toml index 7dda005f27..1e57d6af06 100644 --- a/deny.toml +++ b/deny.toml @@ -1,5 +1,6 @@ [advisories] ignore = [ + { id = "RUSTSEC-2026-0329", reason = "libcrux-hmac-drbg can panic when an auto-reseed request is a nonzero multiple of 65536 bytes. The fix is in 0.0.2, but the pinned xmtp/openmls provider requires ^0.0.1. Remove when the provider accepts a fixed release." }, { id = "RUSTSEC-2024-0436", reason = "required by uniffi" }, { id = "RUSTSEC-2025-0141", reason = "migrate from bincode" }, { id = "RUSTSEC-2026-0173", reason = "proc-macro-error2 unmaintained; transitive via alloy-sol-macro, no upstream fix yet" }, diff --git a/nix/lib/filesets.nix b/nix/lib/filesets.nix index bc35c8452e..3bd59cbc1e 100644 --- a/nix/lib/filesets.nix +++ b/nix/lib/filesets.nix @@ -49,6 +49,8 @@ let (src + /crates/xmtp_id/src/scw_verifier/chain_urls_default.json) (src + /crates/xmtp_id/artifact) (src + /crates/xmtp_id/src/scw_verifier/signature_validation.hex) + # Welcome compatibility tests read the stored keys and ciphertexts at compile time. + (src + /crates/xmtp_mls_common/src/mls_ext/payload_encryption/fixtures) (src + /crates/xmtp_db/migrations) # The attachment client reads the IANA special-purpose address snapshot at compile time. (src + /crates/xmtp_attachments/src/address-registry.txt)