
Abstracts MLS and Proteus into a unified API, provides FFI bindings for various platforms, and includes an encrypted keystore using SQLCipher or AES256-GCM. Offers comprehensive build instructions and versioning guidelines.
This repository is part of the source code of Wire. You can find more information at wire.com or by contacting opensource@wire.com.
You can find the published source code at github.com/wireapp/wire.
For licensing information, see the attached LICENSE file and the list of third-party licenses at wire.com/legal/licenses/.
No license is granted to the Wire trademark and its associated logos, all of which will continue to be owned exclusively by Wire Swiss GmbH. Any use of the Wire trademark and/or its associated logos is expressly prohibited without the express prior written consent of Wire Swiss GmbH.
cargo install --locked cargo-nextest
pre-commit framework
pre-commit install to initialize the pre-commit hookscurl -s "https://get.sdkman.io" | bash
sdk install java 17.0.17-tem
sdk install kotlin
make jvm # make the JVM target
make jvm-test # make and test the JVM targetInstall Android SDK and Build-Tools for API level 30+
[!IMPORTANT] If you are building on macOS you'll need to setup
$ANDROID_SDK_ROOTpath variable manually:export ANDROID_SDK_ROOT=~/Android/Sdk
Install the Android NDK. Make sure to set the
ANDROID_NDK_HOME variable to point to the NDK installation.
Install android rust targets:
rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabiBuild:
make androidInstall Xcode & its command-line tools: https://developer.apple.com/xcode/.
Install iOS rust targets:
rustup target add aarch64-apple-ios aarch64-apple-ios-simBuild:
make ios
# Additionally, if you want to export a .XCFramework:
make ios-create-xcframeworkInstall macOS rust targets:
rustup target add aarch64-apple-darwin[!NOTE] If cross-compiling from macOS, you'll need to install https://github.com/messense/homebrew-macos-cross-toolchains.
Install Linux targets:
rustup target add x86_64-unknown-linux-gnuMake sure you have all prerequisites:
Install the wasm32-unknown-unknown toolchain: rustup target add wasm32-unknown-unknown
Install node.js (recommended way is via Volta)
Install Bun (follow the instructions on Bun's website)
Install wasm-bindgen-cli:
wasm_bindgen_version="$(
cargo metadata --format-version 1 |
jq -r '.packages[] | select (.name == "wasm-bindgen") | .version'
)"
cargo install wasm-bindgen-cli --version $wasm_bindgen_versionIt is important to ensure that the wasm-bindgen-cli version always precisely matches the wasm-bindgen version in
Cargo.lock (as shown by cargo info wasm-bindgen), because otherwise the wasm tests will not run.
Install chromedriver
bunx @puppeteer/browsers install --path ~/bin chrome-headless-shell
bunx @puppeteer/browsers install --path ~/bin chromedriverBuild:
make ts # make the typescript target
make ts-test # make the typescript target and run testsBuild bindings for Android, JVM, iOS and WASM
# builds bindings and targets for the JVM (macOS / Linux)
make jvm
# builds bindings and targets for Android
make android
# builds iOS framework
make ios-create-xcframework
# builds wasm binary & TS bindings
make tscargo nextest run[!WARNING] This takes quite a while.
cargo nextest run --features test-all-cipherSometimes for the Keystore it is valuable to run Rust unit/integration tests on the WASM target.
Then, just use cargo test:
cargo test --target wasm32-unknown-unknown -p core-crypto-keystoreUnfortunately it appears that nextest doesn't work well with the wasm runner, so we're stuck with the basic test runner.
make ts-testNote the CC_TEST_LOG_LEVEL environment variable. At 1 it emits browser console logs; at 2 it also emits CoreCrypto
logs.
make jvm-testmake android-testCurrently works on macOS only.
make ios-testchromedriver
make interop-testSome tests require a working container runtime, so make sure to prepare one before running all tests. Platform-specific instructions follow below.
Make sure to start the Docker service if it is not already running:
systemctl start docker.service# start socket activation, which will cause Podman to start once
# anything connects to the socket:
systemctl --user start podman.socket
# check that socket activation works
podman version
# if the above didn't work, depending on the distribution and installed packages,
# it may be necessary to configure the DOCKER_HOST variable to point to Podman's socket
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sockNote: Docker under macOS requires Docker Desktop, which must run as a GUI application.
# install docker and docker-desktop
brew install docker docker-desktop
# start the Docker daemon by launching docker-desktop as a GUI application
# check if everything went fine
docker version# install Podman
brew install podman
# install podman-mac-helper
sudo podman-mac-helper install
# create new VM based on machine-os:5.5; note that we're explicitly specifying
# an older image version because the newest one seems to be broken
podman machine init --image docker://quay.io/podman/machine-os:5.5
# start the machine
podman machine start
# if everything went well, this should print server version `5.5.x`
podman version
# symlink docker to podman (test scripts and code assume existence
# of the `docker` command)
ln -s /opt/homebrew/bin/podman /opt/homebrew/bin/dockerChoose the OIDC identity provider to use in tests by setting the TEST_IDP variable:
# use Keycloak
export TEST_IDP=keycloak
# or Authelia
export TEST_IDP=autheliaSimply execute the run-e2ei-tests.sh script:
bash scripts/run-e2ei-tests.shThe script will take care of cleaning up processes and containers that are started during tests.
run-e2ei-tests.sh forwards its arguments to cargo nextest, which can be used to run a specific test, or any subset
of tests, e.g.
bash scripts/run-e2ei-tests.sh alg::p256First, you need to start test-wire-server:
$ cargo run --locked --bin test-wire-server
[...]
127.0.0.1:20530Note the IP and port printed by test-wire-server and export that as TEST_WIRE_SERVER_ADDR:
export TEST_WIRE_SERVER_ADDR=127.0.0.1:20530Now that the environment is ready, you can run a specific test, or any subset of tests, e.g.
cargo nextest run --locked --ignore-default-filter -p wire-e2e-identity alg::p256Once you are done with testing, terminate the IdP container that has been started:
# if you're using Keycloak
docker kill keycloak && docker rm keycloak
# if you're using Authelia
docker kill authelia.local && docker rm authelia.localas well as the test-wire-server instance.
For all languages we provide make rules for formatting and checking.
make fmt
make rust-fmtmake swift-fmtmake kotlin-fmtmake ts-fmtmake check
make rust-checkmake swift-checkmake kotlin-checkmake ts-checkWe're using swift-format to format swift files and use swiftlint for linting.
We're using ktlint to format and lint kotlin files.
We're using mdformat for consistent formatting of our markdown files. Install it with the following extensions
mdformat-gfmmdformat-frontmattermdformat-footnotemdformat-gfm-alertsmdformat-tocWe're using taplo to format .toml files.
There are benches implemented in crypto/benches for several operations on mls groups with varying
sizes or proteus. Parameters like minimum or maximum group sizes and step sizes are defined in
crypto/benches/utils/mod.rs.
To execute the benches, e.g. for creating commits, run
cargo bench --bench=commit -- --quickwhere commit is the name of the bench specified in crypto/Cargo.toml, and the corresponding
file in crypto/benches. In case you're interested in higher accuracy, and willing to trade it for
execution speed, omit the --quick flag. If you need reporting plots, remove the .without_plots() call in
crypto/benches/utils/mod.rs. The reports generated by criterion will be located in
target/criterion.
main branch is used as the everyday development branch.main.release/<series>, e.g. release/1.x, release/2.x.main.git merge-base main release/2.x must be a commit pointed to by tag v2.0.0.[TICKET_ID].The versioning scheme used is SemVer AKA Semantic Versioning.
main to prepare for release (git checkout -b prepare-release/X.Y.Z)sh scripts/update-versions.sh X.Y.Z to update the versions of
package.jsoncrypto-ffi/bindings/gradle.properties Make sure the result of the script run is correct.e2e-identity/README.md.test:
TEST_IDP=authelia bash scripts/run-e2ei-tests.sh demo_should_succeede2e-identity/README.md and the generated file, update
e2e-identity/README.md and commit the changes.git cliff --bump --unreleasedCHANGELOG.md. Make sure the version number generated by git cliff matches the release
version.## v1.0.2 - 2024-08-16
### Highlights
- foo
- bar
- bazx.x.x with
X.Y.Z.prepare-release/X.Y.Z branch and create a PR for itmain and remove the prepare-release/X.Y.Z branch from the remotemain: git checkout main && git pull
git tag -s vX.Y.Z
git push origin tag vX.Y.Z
CHANGELOG.md
CHANGELOG.md from the release commit itselfCHANGELOG.md and get them
into main
4.x and newer, docs upload happens automatically. If you released from the series 3.x or
older, you need to trigger docs upload manually:
Run workflow buttonUse workflow from dropdown, choose release/5.x, in Tag to checkout provide your release tagThis repository is part of the source code of Wire. You can find more information at wire.com or by contacting opensource@wire.com.
You can find the published source code at github.com/wireapp/wire.
For licensing information, see the attached LICENSE file and the list of third-party licenses at wire.com/legal/licenses/.
No license is granted to the Wire trademark and its associated logos, all of which will continue to be owned exclusively by Wire Swiss GmbH. Any use of the Wire trademark and/or its associated logos is expressly prohibited without the express prior written consent of Wire Swiss GmbH.
cargo install --locked cargo-nextest
pre-commit framework
pre-commit install to initialize the pre-commit hookscurl -s "https://get.sdkman.io" | bash
sdk install java 17.0.17-tem
sdk install kotlin
make jvm # make the JVM target
make jvm-test # make and test the JVM targetInstall Android SDK and Build-Tools for API level 30+
[!IMPORTANT] If you are building on macOS you'll need to setup
$ANDROID_SDK_ROOTpath variable manually:export ANDROID_SDK_ROOT=~/Android/Sdk
Install the Android NDK. Make sure to set the
ANDROID_NDK_HOME variable to point to the NDK installation.
Install android rust targets:
rustup target add x86_64-linux-android aarch64-linux-android armv7-linux-androideabiBuild:
make androidInstall Xcode & its command-line tools: https://developer.apple.com/xcode/.
Install iOS rust targets:
rustup target add aarch64-apple-ios aarch64-apple-ios-simBuild:
make ios
# Additionally, if you want to export a .XCFramework:
make ios-create-xcframeworkInstall macOS rust targets:
rustup target add aarch64-apple-darwin[!NOTE] If cross-compiling from macOS, you'll need to install https://github.com/messense/homebrew-macos-cross-toolchains.
Install Linux targets:
rustup target add x86_64-unknown-linux-gnuMake sure you have all prerequisites:
Install the wasm32-unknown-unknown toolchain: rustup target add wasm32-unknown-unknown
Install node.js (recommended way is via Volta)
Install Bun (follow the instructions on Bun's website)
Install wasm-bindgen-cli:
wasm_bindgen_version="$(
cargo metadata --format-version 1 |
jq -r '.packages[] | select (.name == "wasm-bindgen") | .version'
)"
cargo install wasm-bindgen-cli --version $wasm_bindgen_versionIt is important to ensure that the wasm-bindgen-cli version always precisely matches the wasm-bindgen version in
Cargo.lock (as shown by cargo info wasm-bindgen), because otherwise the wasm tests will not run.
Install chromedriver
bunx @puppeteer/browsers install --path ~/bin chrome-headless-shell
bunx @puppeteer/browsers install --path ~/bin chromedriverBuild:
make ts # make the typescript target
make ts-test # make the typescript target and run testsBuild bindings for Android, JVM, iOS and WASM
# builds bindings and targets for the JVM (macOS / Linux)
make jvm
# builds bindings and targets for Android
make android
# builds iOS framework
make ios-create-xcframework
# builds wasm binary & TS bindings
make tscargo nextest run[!WARNING] This takes quite a while.
cargo nextest run --features test-all-cipherSometimes for the Keystore it is valuable to run Rust unit/integration tests on the WASM target.
Then, just use cargo test:
cargo test --target wasm32-unknown-unknown -p core-crypto-keystoreUnfortunately it appears that nextest doesn't work well with the wasm runner, so we're stuck with the basic test runner.
make ts-testNote the CC_TEST_LOG_LEVEL environment variable. At 1 it emits browser console logs; at 2 it also emits CoreCrypto
logs.
make jvm-testmake android-testCurrently works on macOS only.
make ios-testchromedriver
make interop-testSome tests require a working container runtime, so make sure to prepare one before running all tests. Platform-specific instructions follow below.
Make sure to start the Docker service if it is not already running:
systemctl start docker.service# start socket activation, which will cause Podman to start once
# anything connects to the socket:
systemctl --user start podman.socket
# check that socket activation works
podman version
# if the above didn't work, depending on the distribution and installed packages,
# it may be necessary to configure the DOCKER_HOST variable to point to Podman's socket
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sockNote: Docker under macOS requires Docker Desktop, which must run as a GUI application.
# install docker and docker-desktop
brew install docker docker-desktop
# start the Docker daemon by launching docker-desktop as a GUI application
# check if everything went fine
docker version# install Podman
brew install podman
# install podman-mac-helper
sudo podman-mac-helper install
# create new VM based on machine-os:5.5; note that we're explicitly specifying
# an older image version because the newest one seems to be broken
podman machine init --image docker://quay.io/podman/machine-os:5.5
# start the machine
podman machine start
# if everything went well, this should print server version `5.5.x`
podman version
# symlink docker to podman (test scripts and code assume existence
# of the `docker` command)
ln -s /opt/homebrew/bin/podman /opt/homebrew/bin/dockerChoose the OIDC identity provider to use in tests by setting the TEST_IDP variable:
# use Keycloak
export TEST_IDP=keycloak
# or Authelia
export TEST_IDP=autheliaSimply execute the run-e2ei-tests.sh script:
bash scripts/run-e2ei-tests.shThe script will take care of cleaning up processes and containers that are started during tests.
run-e2ei-tests.sh forwards its arguments to cargo nextest, which can be used to run a specific test, or any subset
of tests, e.g.
bash scripts/run-e2ei-tests.sh alg::p256First, you need to start test-wire-server:
$ cargo run --locked --bin test-wire-server
[...]
127.0.0.1:20530Note the IP and port printed by test-wire-server and export that as TEST_WIRE_SERVER_ADDR:
export TEST_WIRE_SERVER_ADDR=127.0.0.1:20530Now that the environment is ready, you can run a specific test, or any subset of tests, e.g.
cargo nextest run --locked --ignore-default-filter -p wire-e2e-identity alg::p256Once you are done with testing, terminate the IdP container that has been started:
# if you're using Keycloak
docker kill keycloak && docker rm keycloak
# if you're using Authelia
docker kill authelia.local && docker rm authelia.localas well as the test-wire-server instance.
For all languages we provide make rules for formatting and checking.
make fmt
make rust-fmtmake swift-fmtmake kotlin-fmtmake ts-fmtmake check
make rust-checkmake swift-checkmake kotlin-checkmake ts-checkWe're using swift-format to format swift files and use swiftlint for linting.
We're using ktlint to format and lint kotlin files.
We're using mdformat for consistent formatting of our markdown files. Install it with the following extensions
mdformat-gfmmdformat-frontmattermdformat-footnotemdformat-gfm-alertsmdformat-tocWe're using taplo to format .toml files.
There are benches implemented in crypto/benches for several operations on mls groups with varying
sizes or proteus. Parameters like minimum or maximum group sizes and step sizes are defined in
crypto/benches/utils/mod.rs.
To execute the benches, e.g. for creating commits, run
cargo bench --bench=commit -- --quickwhere commit is the name of the bench specified in crypto/Cargo.toml, and the corresponding
file in crypto/benches. In case you're interested in higher accuracy, and willing to trade it for
execution speed, omit the --quick flag. If you need reporting plots, remove the .without_plots() call in
crypto/benches/utils/mod.rs. The reports generated by criterion will be located in
target/criterion.
main branch is used as the everyday development branch.main.release/<series>, e.g. release/1.x, release/2.x.main.git merge-base main release/2.x must be a commit pointed to by tag v2.0.0.[TICKET_ID].The versioning scheme used is SemVer AKA Semantic Versioning.
main to prepare for release (git checkout -b prepare-release/X.Y.Z)sh scripts/update-versions.sh X.Y.Z to update the versions of
package.jsoncrypto-ffi/bindings/gradle.properties Make sure the result of the script run is correct.e2e-identity/README.md.test:
TEST_IDP=authelia bash scripts/run-e2ei-tests.sh demo_should_succeede2e-identity/README.md and the generated file, update
e2e-identity/README.md and commit the changes.git cliff --bump --unreleasedCHANGELOG.md. Make sure the version number generated by git cliff matches the release
version.## v1.0.2 - 2024-08-16
### Highlights
- foo
- bar
- bazx.x.x with
X.Y.Z.prepare-release/X.Y.Z branch and create a PR for itmain and remove the prepare-release/X.Y.Z branch from the remotemain: git checkout main && git pull
git tag -s vX.Y.Z
git push origin tag vX.Y.Z
CHANGELOG.md
CHANGELOG.md from the release commit itselfCHANGELOG.md and get them
into main
4.x and newer, docs upload happens automatically. If you released from the series 3.x or
older, you need to trigger docs upload manually:
Run workflow buttonUse workflow from dropdown, choose release/5.x, in Tag to checkout provide your release tag