Skip to content

Commit

Permalink
wasm init
Browse files Browse the repository at this point in the history
  • Loading branch information
eschorn1 committed Mar 21, 2024
1 parent 797fd67 commit 5ac58d3
Show file tree
Hide file tree
Showing 10 changed files with 226 additions and 10 deletions.
16 changes: 7 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/target
/.idea
/fuzz/corpus/
/fuzz/Cargo.lock
/fuzz/target/
/fuzz/artifacts
/fuzz/coverage
/dudect/Cargo.lock
/dudect/target/
/ct_cm4/target/
**/Cargo.lock
**/artifacts
**/corpus
**/coverate
**/target
**/pkg
**/node_modules
**/package-lock.json
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
workspace = { members = ['ffi'], exclude = ["ct_cm4", "dudect", "fuzz"] }
workspace = { members = ['ffi'], exclude = ["ct_cm4", "dudect", "fuzz", "wasm"] }

[package]
name = "fips203"
Expand Down
34 changes: 34 additions & 0 deletions wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "fips203-wasm"
version = "0.1.3"
authors = ["Eric Schorn <eschorn@integritychain.com>"]
description = "Sample web page utilizing FIPS 203 code"
repository = ""
publish = false
edition = "2021"


[lib]
crate-type = ["cdylib", "rlib"]


[features]
default = ["console_error_panic_hook"]


[dependencies]
wasm-bindgen = "0.2.84"
fips203 = { path = "../../fips203", default-features = false, features = ["ml-kem-512"] }
rand_chacha = "0.3.1"
console_error_panic_hook = { version = "0.1.7", optional = true }
rand = "0.8.5"
getrandom = { version = "0.2", features = ["js"] }
hex = "0.4.3"


[dev-dependencies]
wasm-bindgen-test = "0.3.34"


[profile.release]
opt-level = "s"
17 changes: 17 additions & 0 deletions wasm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
One-off installation

~~~
$ cargo install wasm-pack
$ sudo npm install npm@latest -g
~~~

To run:

~~~
$ cd wasm # this directory
$ wasm-pack build
$ cd www
$ npm install
$ export NODE_OPTIONS=--openssl-legacy-provider
$ npm run start
~~~
51 changes: 51 additions & 0 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use fips203::ml_kem_512;
// Could also be ml_kem_768 or ml_kem_1024.
use fips203::traits::{Decaps, Encaps, KeyGen, SerDes};
use rand_chacha::rand_core::SeedableRng;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn run(seed: &str) -> String {
let seed = seed.parse();
if seed.is_err() { return "Unable to parse number".to_string(); };
let seed = seed.unwrap();

let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(seed);

// Alice runs `key_gen()` and then serializes the encaps key `ek` for Bob (to bytes).
let (alice_ek, alice_dk) = ml_kem_512::KG::try_keygen_with_rng_vt(&mut rng).expect("keygen failed");
let alice_ek_bytes = alice_ek.into_bytes();

// Alice sends the encaps key `ek_bytes` to Bob.
let bob_ek_bytes = alice_ek_bytes;

// Bob deserializes the encaps `ek_bytes` and then runs `encaps() to get the shared
// secret `ssk` and ciphertext `ct`. He serializes the ciphertext `ct` for Alice (to bytes).
let bob_ek = ml_kem_512::EncapsKey::try_from_bytes(bob_ek_bytes).expect("ek deser failed");
let (bob_ssk, bob_ct) = bob_ek.try_encaps_with_rng_vt(&mut rng).expect("encaps failed");
let bob_ct_bytes = bob_ct.into_bytes();

// Bob sends the ciphertext `ct_bytes` to Alice
let alice_ct_bytes = bob_ct_bytes;

// Alice deserializes the ciphertext `ct` and runs `decaps()` with her decaps key
let alice_ct = ml_kem_512::CipherText::try_from_bytes(alice_ct_bytes).expect("ct deser failed");
let alice_ssk = alice_dk.try_decaps_vt(&alice_ct).expect("decaps failed");

// Alice and Bob will now have the same secret key
assert_eq!(bob_ssk.into_bytes(), alice_ssk.clone().into_bytes(), "shared secret not identical");

let ek_hex = hex::encode(&bob_ek_bytes);
let ct_hex = hex::encode(&bob_ct_bytes);
let dk_hex = hex::encode(alice_dk.into_bytes());
let ssk_hex = hex::encode(alice_ssk.into_bytes());

let s0 = format!("The seed used to generate the keys is: {}\n\n", seed);
let s1 = format!("The generated encaps key is: {}\n", ek_hex);
let s2 = format!("The generated decaps key is: {}\n\n", dk_hex);
let s3 = format!("The generated ciphertext is: {}\n", ct_hex);
let s4 = format!("The shared secret is: {}\n", ssk_hex);
let s5 = "Alice and Bob have an identical shared secret."; // because the above assert! passed

(s0 + &s1 + &s2 + &s3 + &s4 + &s5).into()
}
5 changes: 5 additions & 0 deletions wasm/www/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// A dependency graph that contains any wasm must all be imported
// asynchronously. This `bootstrap.js` file does the single async import, so
// that no one else needs to worry about it again.
import("./index.js")
.catch(e => console.error("Error importing `index.js`:", e));
40 changes: 40 additions & 0 deletions wasm/www/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>FIPS 203 WASM Demo</title>
<link href="https://cdn.simplecss.org/simple.min.css" rel="stylesheet">
<style> body {
grid-template-columns: 1fr min(60rem, 90%) 1fr;
}</style>
</head>
<body>
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>

<h1>FIPS 203 WASM Demo</h1>

<p>This page is a simple demonstration of code from the <a href="https://crates.io/crates/fips203">FIPS 203
Rust crate</a> running in the browser via wasm. This demo has a seedable random number generator so that
its results can be compared to <a href="https://github.com/integritychain/fips203/blob/main/tests/native.rs">
native test cases.</a> Please see section 3.3 of the
<a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.ipd.pdf">FIPS 203 standard</a> for critical
requirements on randomness when utilizing FIPS 203 in production.
</p>

<p>Enter a (u64 decimal) seed number below and click on 'Submit'. The encaps and decaps keys will be generated,
the encaps() function run to generate the ciphertext and shared secret, the decaps() function run to calculate
the 'other' shared secret, the shared secrets confirmed to match, and all resulting values displayed.</p>

<p>
<form action="" id="wasmForm">
<input class="form-control" id="seed" placeholder="Enter the seed number..." type="text">
<button type="submit">Submit</button>
</form>
</p>

<pre id="wasm-canvas"></pre>

<script src="./bootstrap.js"></script>

</body>
</html>
18 changes: 18 additions & 0 deletions wasm/www/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as wasm from "wasm";

let wasmForm = document.getElementById("wasmForm");

wasmForm.addEventListener("submit", (e) => {
e.preventDefault();

let seed = document.getElementById("seed");
let result = "";

if (seed.value) {
result = wasm.run(seed.value);
seed.value = "";
document.getElementById("wasm-canvas").innerHTML = result;
} else {
alert("Please enter a non-empty seed u64 decimal number");
}
});
39 changes: 39 additions & 0 deletions wasm/www/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "create-wasm-app",
"version": "0.1.0",
"description": "create an app to consume rust-generated wasm packages",
"main": "index.js",
"bin": {
"create-wasm-app": ".bin/create-wasm-app.js"
},
"scripts": {
"build": "webpack --config webpack.config.js",
"start": "webpack-dev-server"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rustwasm/create-wasm-app.git"
},
"keywords": [
"webassembly",
"wasm",
"rust",
"webpack"
],
"author": "Ashley Williams <ashley666ashley@gmail.com>",
"license": "(MIT OR Apache-2.0)",
"bugs": {
"url": "https://github.com/rustwasm/create-wasm-app/issues"
},
"homepage": "https://github.com/rustwasm/create-wasm-app#readme",
"dependencies": {
"wasm": "file:../pkg"
},
"devDependencies": {
"hello-wasm-pack": "^0.1.0",
"webpack": "^4.29.3",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5",
"copy-webpack-plugin": "^5.0.0"
}
}
14 changes: 14 additions & 0 deletions wasm/www/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require('path');

module.exports = {
entry: "./bootstrap.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bootstrap.js",
},
mode: "development",
plugins: [
new CopyWebpackPlugin(['index.html'])
],
};

0 comments on commit 5ac58d3

Please sign in to comment.