diff --git a/.github/workflows/jstest.yml b/.github/workflows/jstest.yml new file mode 100644 index 0000000..bbecc76 --- /dev/null +++ b/.github/workflows/jstest.yml @@ -0,0 +1,19 @@ +name: Javascript Tests + +on: + - pull_request + +jobs: + format: + strategy: + matrix: + os: + - ubuntu-latest + runs-on: ${{ matrix.os }} + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run js tests + run: ./example/ci-test.sh + diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..86ffafd --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,29 @@ +name: Formatting + +on: + - pull_request + +jobs: + format: + strategy: + matrix: + os: + - ubuntu-latest + runs-on: ${{ matrix.os }} + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + components: rustfmt, clippy + + - name: Run cargo fmt + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..fbe0778 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: Testing + +on: + - pull_request + +jobs: + test: + strategy: + matrix: + os: + - ubuntu-latest + runs-on: ${{ matrix.os }} + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Run cargo test + run: cargo test --release diff --git a/.gitignore b/.gitignore index 2ebc5ea..4103f0c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -/Cargo.lock \ No newline at end of file +node_modules +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index 6aaf006..1b07e84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,8 @@ description = "x25519 & chacha20poly1305" repository = "https://github.com/entropyxyz/x25519-chacha20poly1305" [dependencies] -bytes = "1.2.1" hex = "*" -# bip39 ={ git="https://github.com/infincia/bip39-rs.git", tag="v0.6.0-beta.1" } +bip39 ={ git="https://github.com/infincia/bip39-rs.git", tag="v0.6.0-beta.1" } wasm-bindgen = "0.2.83" x25519-dalek = "2.0.0-pre.1" serde ={ version="1.0", features=["derive"] } diff --git a/Makefile b/Makefile index 7b9a3b5..421bebf 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ link-local :: build-nodejs cd pkg && npm link # Links the example frontend project with the locally built wasm/js package. -link-project :: link-local +link :: link-local cd example && npm link $(CRATE_NAME) # Another build option for compiling to webpack, builds a typescript library around the WASM for use diff --git a/README.md b/README.md index e806851..08a3138 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,33 @@ Nodejs package for x25519 key exchange and chacha20poly1305 encryption, written in Rust compiled to WASM. +## Development process + ### Install dependencies -Requires `wasm-pack` which can be installed with `cargo install wasm-pack`. +See `example/ci-test.sh` for example of how to install both rust and javascript dependencies. ### Compile +Compile a nodejs/wasm library from the Rust source. + ```sh make ``` + +### Link + +Link the nodejs/wasm library locally. + +```sh +make link +``` + +### Test + +After compiling and linking, run: + +```sh +ts-node example/test.ts +``` + diff --git a/example/ci-test.sh b/example/ci-test.sh new file mode 100755 index 0000000..f063cc3 --- /dev/null +++ b/example/ci-test.sh @@ -0,0 +1,29 @@ +#!/bin/bash +readonly EXEC_DIR=$(dirname "$(realpath $0)") +readonly NODE_VERSION="v18.12.1" +readonly NODE_OS="linux" +readonly NODE_ARCH="x64" +readonly FN="node-$NODE_VERSION-$NODE_OS-$NODE_ARCH" + +# Install rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +rustup update nightly +rustup update stable +rustup default stable +rustup target add wasm32-unknown-unknown --toolchain nightly +cargo install wasm-pack + +# Compile/link typescript library +make +make link + +# Install JS dependencies +cd $EXEC_DIR +wget https://nodejs.org/dist/$NODE_VERSION/$FN.tar.xz +tar xf $FN.tar.xz +export PATH=$PATH:$EXEC_DIR/$FN/bin +npm install -g ts-node + +# Run tests +ts-node test.ts + diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 4044911..0000000 --- a/package-lock.json +++ /dev/null @@ -1,302 +0,0 @@ -{ - "name": "x25519-chacha20poly1305-wasm", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "dependencies": { - "ts-node": "^10.9.1" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" - }, - "node_modules/@types/node": { - "version": "18.8.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.4.tgz", - "integrity": "sha512-WdlVphvfR/GJCLEMbNA8lJ0lhFNBj4SW3O+O5/cEGw9oYrv0al9zTwuQsq+myDUXgNx2jgBynoVgZ2MMJ6pbow==", - "peer": true - }, - "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "engines": { - "node": ">=6" - } - } - }, - "dependencies": { - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" - }, - "@types/node": { - "version": "18.8.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.4.tgz", - "integrity": "sha512-WdlVphvfR/GJCLEMbNA8lJ0lhFNBj4SW3O+O5/cEGw9oYrv0al9zTwuQsq+myDUXgNx2jgBynoVgZ2MMJ6pbow==", - "peer": true - }, - "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "peer": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 06809dd..0000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "ts-node": "^10.9.1" - } -} diff --git a/pkg/.gitignore b/pkg/.gitignore index e69de29..f59ec20 100644 --- a/pkg/.gitignore +++ b/pkg/.gitignore @@ -0,0 +1 @@ +* \ No newline at end of file diff --git a/pkg/x25519_chacha20poly1305.js b/pkg/x25519_chacha20poly1305.js index 8138465..9aff645 100644 --- a/pkg/x25519_chacha20poly1305.js +++ b/pkg/x25519_chacha20poly1305.js @@ -23,15 +23,6 @@ function takeObject(idx) { return ret; } -function addHeapObject(obj) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} - let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); cachedTextDecoder.decode(); @@ -49,6 +40,15 @@ function getStringFromWasm0(ptr, len) { return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); } +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + let WASM_VECTOR_LEN = 0; function passArray8ToWasm0(arg, malloc) { @@ -322,16 +322,16 @@ module.exports.__wbg_getRandomValues_307049345d0bd88c = function(arg0) { return addHeapObject(ret); }; -module.exports.__wbg_randomFillSync_065afffde01daa66 = function() { return handleError(function (arg0, arg1, arg2) { +module.exports.__wbg_randomFillSync_6894564c2c334c42 = function() { return handleError(function (arg0, arg1, arg2) { getObject(arg0).randomFillSync(getArrayU8FromWasm0(arg1, arg2)); }, arguments) }; -module.exports.__wbg_getRandomValues_b99eec4244a475bb = function() { return handleError(function (arg0, arg1) { +module.exports.__wbg_getRandomValues_805f1c3d65988a5a = function() { return handleError(function (arg0, arg1) { getObject(arg0).getRandomValues(getObject(arg1)); }, arguments) }; -module.exports.__wbg_process_0cc2ada8524d6f83 = function(arg0) { - const ret = getObject(arg0).process; +module.exports.__wbg_crypto_e1d53a1d73fb10b8 = function(arg0) { + const ret = getObject(arg0).crypto; return addHeapObject(ret); }; @@ -341,12 +341,17 @@ module.exports.__wbindgen_is_object = function(arg0) { return ret; }; -module.exports.__wbg_versions_c11acceab27a6c87 = function(arg0) { +module.exports.__wbg_process_038c26bf42b093f8 = function(arg0) { + const ret = getObject(arg0).process; + return addHeapObject(ret); +}; + +module.exports.__wbg_versions_ab37218d2f0b24a8 = function(arg0) { const ret = getObject(arg0).versions; return addHeapObject(ret); }; -module.exports.__wbg_node_7ff1ce49caf23815 = function(arg0) { +module.exports.__wbg_node_080f4b19d15bc1fe = function(arg0) { const ret = getObject(arg0).node; return addHeapObject(ret); }; @@ -356,22 +361,22 @@ module.exports.__wbindgen_is_string = function(arg0) { return ret; }; -module.exports.__wbg_static_accessor_NODE_MODULE_cf6401cc1091279e = function() { - const ret = module; - return addHeapObject(ret); -}; - -module.exports.__wbg_require_a746e79b322b9336 = function() { return handleError(function (arg0, arg1, arg2) { - const ret = getObject(arg0).require(getStringFromWasm0(arg1, arg2)); +module.exports.__wbg_require_78a3dcfbdba9cbce = function() { return handleError(function () { + const ret = module.require; return addHeapObject(ret); }, arguments) }; -module.exports.__wbg_crypto_2036bed7c44c25e7 = function(arg0) { - const ret = getObject(arg0).crypto; +module.exports.__wbindgen_is_function = function(arg0) { + const ret = typeof(getObject(arg0)) === 'function'; + return ret; +}; + +module.exports.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); return addHeapObject(ret); }; -module.exports.__wbg_msCrypto_a21fc88caf1ecdc8 = function(arg0) { +module.exports.__wbg_msCrypto_6e7d3e1f92610cbb = function(arg0) { const ret = getObject(arg0).msCrypto; return addHeapObject(ret); }; @@ -411,6 +416,11 @@ module.exports.__wbg_global_ba75c50d1cf384f4 = function() { return handleError(f return addHeapObject(ret); }, arguments) }; +module.exports.__wbg_call_168da88779e35f61 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = getObject(arg0).call(getObject(arg1), getObject(arg2)); + return addHeapObject(ret); +}, arguments) }; + module.exports.__wbg_buffer_3f3d764d4747d564 = function(arg0) { const ret = getObject(arg0).buffer; return addHeapObject(ret); diff --git a/pkg/x25519_chacha20poly1305_bg.wasm b/pkg/x25519_chacha20poly1305_bg.wasm index 50a9db1..5501750 100644 Binary files a/pkg/x25519_chacha20poly1305_bg.wasm and b/pkg/x25519_chacha20poly1305_bg.wasm differ diff --git a/src/lib.rs b/src/lib.rs index f136dc4..f67e233 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +use bip39::Mnemonic; use blake2::{Blake2s256, Digest}; use chacha20poly1305::{ aead::{Aead, Error, KeyInit}, @@ -246,3 +247,77 @@ impl SignedMessage { to_string(self).unwrap() } } + +/// Creates a new random Mnemonic. +pub fn new_mnemonic() -> Mnemonic { + Mnemonic::new(bip39::MnemonicType::Words24, bip39::Language::English) +} + +/// Derives a sr25519::Pair from a Mnemonic +pub fn mnemonic_to_pair(m: &Mnemonic) -> sr25519::Pair { + ::from_phrase(m.phrase(), None) + .unwrap() + .0 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_bad_signatures_fails() { + let plaintext = Bytes(vec![69, 42, 0]); + + let alice = mnemonic_to_pair(&new_mnemonic()); + let alice_secret = derive_static_secret(&alice); + let alice_public_key = PublicKey::from(&alice_secret); + + let bob = mnemonic_to_pair(&new_mnemonic()); + let bob_secret = derive_static_secret(&bob); + let bob_public_key = PublicKey::from(&bob_secret); + + let alice_to_alice = SignedMessage::new(&alice, &plaintext, &alice_public_key).unwrap(); + let mut alice_to_bob = SignedMessage::new(&alice, &plaintext, &bob_public_key).unwrap(); + + // Test that replacing the public key fails to verify the signature. + alice_to_bob.sig = alice_to_alice.sig; + assert!(!alice_to_bob.verify()); + + // Test that decrypting with the wrong private key throws an error. + let res = alice_to_bob.decrypt(&alice); + assert!(res.is_err()); + } + + #[test] + fn test_sign_and_encrypt() { + let plaintext = Bytes(vec![69, 42, 0]); + + let alice = mnemonic_to_pair(&new_mnemonic()); + let alice_secret = derive_static_secret(&alice); + + let bob = mnemonic_to_pair(&new_mnemonic()); + let bob_secret = derive_static_secret(&bob); + let bob_public_key = PublicKey::from(&bob_secret); + + // Test encryption & signing. + let encrypt_result = SignedMessage::new(&alice, &plaintext, &bob_public_key); + // Assert no error received in encryption. + assert!(encrypt_result.is_ok()); + let encrypted_message = encrypt_result.unwrap(); + + // Test signature validity + assert!(encrypted_message.verify()); + + // Test decryption + let decrypt_result = encrypted_message.decrypt(&bob); + // Assert no error received in decryption. + assert!(decrypt_result.is_ok()); + let decrypted_result = decrypt_result.unwrap(); + + // Check the decrypted message equals the plaintext. + assert_eq!(Bytes(decrypted_result), plaintext); + + // Check the encrypted message != the plaintext. + assert_ne!(encrypted_message.msg, plaintext); + } +}