From 5c936779f78e0da95acd7154c847e398c91af3e8 Mon Sep 17 00:00:00 2001 From: Piotr Roslaniec Date: Fri, 4 Nov 2022 16:00:39 +0100 Subject: [PATCH] add wasm setup --- .github/workflows/build.yaml | 34 ------- .github/workflows/manual.yml | 18 ---- .github/workflows/workspace.yml | 50 +++++++++++ Cargo.lock | 127 +++++++++++++++++++++++---- Cargo.toml | 1 + ferveo-common/src/keypair.rs | 2 + ferveo/benches/benchmarks/pairing.rs | 18 ++-- ferveo/src/dkg.rs | 2 +- ferveo/src/dkg/pv.rs | 4 +- tpke-wasm/.cargo-ok | 0 tpke-wasm/.gitignore | 6 ++ tpke-wasm/Cargo.toml | 33 +++++++ tpke-wasm/README.md | 1 + tpke-wasm/src/lib.rs | 77 ++++++++++++++++ tpke-wasm/src/utils.rs | 10 +++ tpke-wasm/tests/node.rs | 24 +++++ tpke/src/ciphertext.rs | 32 ++++++- 17 files changed, 356 insertions(+), 83 deletions(-) delete mode 100644 .github/workflows/build.yaml delete mode 100644 .github/workflows/manual.yml create mode 100644 .github/workflows/workspace.yml create mode 100644 tpke-wasm/.cargo-ok create mode 100644 tpke-wasm/.gitignore create mode 100644 tpke-wasm/Cargo.toml create mode 100644 tpke-wasm/README.md create mode 100644 tpke-wasm/src/lib.rs create mode 100644 tpke-wasm/src/utils.rs create mode 100644 tpke-wasm/tests/node.rs diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml deleted file mode 100644 index 0fbe83af..00000000 --- a/.github/workflows/build.yaml +++ /dev/null @@ -1,34 +0,0 @@ -name: Build - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - runs-on: ubuntu-latest - container: - image: rustlang/rust:nightly - steps: - - uses: actions/checkout@v2 - - name: Build - run: cargo build --verbose --all --tests --benches - - name: Run tests - run: cargo test --verbose - - security: - runs-on: ubuntu-latest - container: - image: rustlang/rust:nightly - steps: - - uses: actions/checkout@v2 - - name: Install cargo-audit - run: cargo install cargo-audit - - name: Cargo Audit - run: cargo audit - diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml deleted file mode 100644 index 4adce10a..00000000 --- a/.github/workflows/manual.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Manual - -on: [workflow_dispatch] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - runs-on: ubuntu-latest - container: - image: rustlang/rust:nightly - steps: - - uses: actions/checkout@v2 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml new file mode 100644 index 00000000..7a0c7a26 --- /dev/null +++ b/.github/workflows/workspace.yml @@ -0,0 +1,50 @@ +name: Workspace + +on: + pull_request: + paths-ignore: + - README.md + push: + branches: + - main + paths-ignore: + - README.md + tags: + - v* + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: clippy + override: true + profile: minimal + - run: cargo clippy --all --all-features -- -D warnings + + rustfmt: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v1 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: rustfmt + profile: minimal + override: true + + - name: Run cargo fmt + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check diff --git a/Cargo.lock b/Cargo.lock index 7dba5b15..acd132c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -202,7 +202,7 @@ checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" dependencies = [ "addr2line", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide", "object", @@ -349,6 +349,12 @@ version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -361,7 +367,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cipher", "cpufeatures", ] @@ -386,6 +392,16 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -398,7 +414,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -452,7 +468,7 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", ] @@ -462,7 +478,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-epoch", "crossbeam-utils", ] @@ -474,7 +490,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ "autocfg", - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", "memoffset", "once_cell", @@ -487,7 +503,7 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "once_cell", ] @@ -698,7 +714,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -709,9 +725,11 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -814,7 +832,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -884,7 +902,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -921,6 +939,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + [[package]] name = "merlin" version = "2.0.1" @@ -956,7 +980,7 @@ checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ "bitflags", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "memoffset", ] @@ -1107,7 +1131,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "instant", "libc", "redox_syscall", @@ -1165,7 +1189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55f35f865aa964be21fcde114cbd1cfbd9bf8a471460ed965b0f84f96c711401" dependencies = [ "backtrace", - "cfg-if", + "cfg-if 1.0.0", "criterion", "findshlibs", "inferno", @@ -1395,6 +1419,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.1.0" @@ -1476,7 +1506,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest 0.9.0", "opaque-debug", @@ -1577,7 +1607,7 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand", "libc", "redox_syscall", @@ -1633,6 +1663,21 @@ dependencies = [ "serde", ] +[[package]] +name = "tpke-wasm" +version = "0.1.0" +dependencies = [ + "ark-bls12-381", + "ark-ff", + "console_error_panic_hook", + "getrandom 0.2.7", + "group-threshold-cryptography", + "rand 0.8.5", + "wasm-bindgen", + "wasm-bindgen-test", + "wee_alloc", +] + [[package]] name = "typenum" version = "1.15.0" @@ -1704,7 +1749,7 @@ version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -1723,6 +1768,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.82" @@ -1752,6 +1809,30 @@ version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +[[package]] +name = "wasm-bindgen-test" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513df541345bb9fcc07417775f3d51bbb677daf307d8035c0afafd87dc2e6599" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6150d36a03e90a3cf6c12650be10626a9902d70c5270fd47d7a47e5389a10d56" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "web-sys" version = "0.3.59" @@ -1762,6 +1843,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "winapi", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index b9e747e7..8c6c402f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "ferveo-common", "subproductdomain", "tpke", + "tpke-wasm", ] [profile.bench] diff --git a/ferveo-common/src/keypair.rs b/ferveo-common/src/keypair.rs index 68c93a48..b57a3f1c 100644 --- a/ferveo-common/src/keypair.rs +++ b/ferveo-common/src/keypair.rs @@ -22,6 +22,7 @@ impl From> for PreparedPublicKey { Copy, Clone, Debug, + Eq, PartialEq, Serialize, Deserialize, @@ -45,6 +46,7 @@ impl Default for PublicKey { Clone, Copy, Debug, + Eq, PartialEq, Serialize, Deserialize, diff --git a/ferveo/benches/benchmarks/pairing.rs b/ferveo/benches/benchmarks/pairing.rs index 468cdcd1..c33e3577 100644 --- a/ferveo/benches/benchmarks/pairing.rs +++ b/ferveo/benches/benchmarks/pairing.rs @@ -21,10 +21,9 @@ pub fn lagrange(c: &mut Criterion) { b.iter(|| { black_box( subproductdomain::SubproductDomain::::new(u.clone()) - .inverse_lagrange_coefficients() - //.iter() - //.map(|x| x.inverse()) - //.collect::>(), + .inverse_lagrange_coefficients(), //.iter() + //.map(|x| x.inverse()) + //.collect::>(), ) }) }); @@ -39,11 +38,12 @@ pub fn lagrange(c: &mut Criterion) { group.bench_function("Jubjub Fr 8192*2/3 lagrange coefficients", |b| { b.iter(|| { black_box( - subproductdomain::SubproductDomain::::new(u.clone()) - .inverse_lagrange_coefficients() - //.iter() - //.map(|x| x.inverse()) - //.collect::>(), + subproductdomain::SubproductDomain::::new( + u.clone(), + ) + .inverse_lagrange_coefficients(), //.iter() + //.map(|x| x.inverse()) + //.collect::>(), ) }) }); diff --git a/ferveo/src/dkg.rs b/ferveo/src/dkg.rs index f8461684..daba9172 100644 --- a/ferveo/src/dkg.rs +++ b/ferveo/src/dkg.rs @@ -28,7 +28,7 @@ pub struct Params { pub retry_after: u32, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum PvssScheduler { Wait, Issue, diff --git a/ferveo/src/dkg/pv.rs b/ferveo/src/dkg/pv.rs index 345795ae..7ccd7312 100644 --- a/ferveo/src/dkg/pv.rs +++ b/ferveo/src/dkg/pv.rs @@ -175,15 +175,13 @@ impl PubliclyVerifiableDkg { Err( anyhow!("Aggregation failed because the verified weight was insufficient") ) - } else { - if &self.final_key() == final_key { + } else if &self.final_key() == final_key { Ok(()) } else { Err( anyhow!("The final key was not correctly derived from the aggregated transcripts") ) } - } } _ => Err(anyhow!("DKG state machine is not in correct state to verify this message")) } diff --git a/tpke-wasm/.cargo-ok b/tpke-wasm/.cargo-ok new file mode 100644 index 00000000..e69de29b diff --git a/tpke-wasm/.gitignore b/tpke-wasm/.gitignore new file mode 100644 index 00000000..4e301317 --- /dev/null +++ b/tpke-wasm/.gitignore @@ -0,0 +1,6 @@ +/target +**/*.rs.bk +Cargo.lock +bin/ +pkg/ +wasm-pack.log diff --git a/tpke-wasm/Cargo.toml b/tpke-wasm/Cargo.toml new file mode 100644 index 00000000..f5f1f319 --- /dev/null +++ b/tpke-wasm/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "tpke-wasm" +version = "0.1.0" +authors = ["Piotr Roslaniec "] +edition = "2021" +license = "GPL-3.0-only" +readme = "README.md" +categories = ["cryptography", "no-std"] + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["console_error_panic_hook"] + +[dependencies] +wasm-bindgen = "0.2.63" +console_error_panic_hook = { version = "0.1.7", optional = true } +wee_alloc = { version = "0.4.5" } +group-threshold-cryptography = { path = "../tpke"} +getrandom = { version = "0.2", features = ["js"] } +rand = "0.8.5" +ark-bls12-381 = "0.3.0" +ark-ff = "0.3.0" + +[dev-dependencies] +wasm-bindgen-test = "0.3.13" +console_error_panic_hook = "0.1.7" + +# Profiles at non-root packages are ignored +# TODO: Move this configuration to .cargo/config +# [profile.release] +# opt-level = "s" diff --git a/tpke-wasm/README.md b/tpke-wasm/README.md new file mode 100644 index 00000000..855d0191 --- /dev/null +++ b/tpke-wasm/README.md @@ -0,0 +1 @@ +# tpke-wasm \ No newline at end of file diff --git a/tpke-wasm/src/lib.rs b/tpke-wasm/src/lib.rs new file mode 100644 index 00000000..6019c4a0 --- /dev/null +++ b/tpke-wasm/src/lib.rs @@ -0,0 +1,77 @@ +mod utils; + +extern crate group_threshold_cryptography as tpke; + +use ark_ff::{FromBytes, ToBytes}; +use utils::set_panic_hook; +use wasm_bindgen::prelude::*; + +extern crate alloc; +// Use `wee_alloc` as the global allocator. +extern crate wee_alloc; + +type E = ark_bls12_381::Bls12_381; +type PublicKey = ark_bls12_381::G1Affine; +type PrivateKey = ark_bls12_381::G2Affine; +type Ciphertext = tpke::Ciphertext; + +#[wasm_bindgen] +pub struct SetupResult { + public_key: Box<[u8]>, + private_key: Box<[u8]>, + // TODO: Include private contexts + // pub private_contexts: Vec>, +} + +#[wasm_bindgen] +impl SetupResult { + // wasm_bindgen requires public fields to implement the `Clone` trait. + // Instead, we provide getters. + #[wasm_bindgen(getter, js_name = "publicKey")] + pub fn public_key(&self) -> Box<[u8]> { + self.public_key.clone() + } + + #[wasm_bindgen(getter, js_name = "privateKey")] + pub fn private_key(&self) -> Box<[u8]> { + self.private_key.clone() + } +} + +#[wasm_bindgen] +pub fn setup( + threshold: usize, + shares_num: usize, + num_entities: usize, +) -> SetupResult { + set_panic_hook(); + + let (public_key, private_key, _) = + tpke::setup::(threshold, shares_num, num_entities); + let mut public_key_bytes = Vec::new(); + public_key.write(&mut public_key_bytes).unwrap(); + let mut private_key_bytes = Vec::new(); + private_key.write(&mut private_key_bytes).unwrap(); + SetupResult { + public_key: public_key_bytes.into_boxed_slice(), + private_key: private_key_bytes.into_boxed_slice(), + } +} + +#[wasm_bindgen] +pub fn encrypt(message: Vec, pubkey: Vec) -> Vec { + set_panic_hook(); + + let mut rng = rand::thread_rng(); + let pubkey: PublicKey = PublicKey::read(&pubkey[..]).unwrap(); + tpke::encrypt::<_, E>(&message, pubkey, &mut rng).to_bytes() +} + +#[wasm_bindgen] +pub fn decrypt(ciphertext: Vec, privkey: Vec) -> Vec { + set_panic_hook(); + + let privkey: PrivateKey = PrivateKey::read(&privkey[..]).unwrap(); + let ciphertext: Ciphertext = Ciphertext::from_bytes(&ciphertext[..]); + tpke::decrypt(&ciphertext, privkey) +} diff --git a/tpke-wasm/src/utils.rs b/tpke-wasm/src/utils.rs new file mode 100644 index 00000000..b1d7929d --- /dev/null +++ b/tpke-wasm/src/utils.rs @@ -0,0 +1,10 @@ +pub fn set_panic_hook() { + // When the `console_error_panic_hook` feature is enabled, we can call the + // `set_panic_hook` function at least once during initialization, and then + // we will get better error messages if our code ever panics. + // + // For more details see + // https://github.com/rustwasm/console_error_panic_hook#readme + #[cfg(feature = "console_error_panic_hook")] + console_error_panic_hook::set_once(); +} diff --git a/tpke-wasm/tests/node.rs b/tpke-wasm/tests/node.rs new file mode 100644 index 00000000..8dea66e2 --- /dev/null +++ b/tpke-wasm/tests/node.rs @@ -0,0 +1,24 @@ +//! Test suite for the Nodejs. + +extern crate wasm_bindgen_test; +use tpke_wasm::*; +use wasm_bindgen_test::*; + +#[test] +#[wasm_bindgen_test] +fn encrypts_and_decrypts() { + let threshold = 3; + let shares_num = 5; + let num_entities = 5; + let message = "my-secret-message".as_bytes().to_vec(); + + let setup_result = setup(threshold, shares_num, num_entities); + let public_key = setup_result.public_key().to_vec(); + let private_key = setup_result.private_key().to_vec(); + + let ciphertext = encrypt(message.clone(), public_key); + let plaintext = decrypt(ciphertext, private_key); + + // TODO: Plaintext is padded to 32 bytes. Fix this. + assert!(message == plaintext[..message.len()]) +} diff --git a/tpke/src/ciphertext.rs b/tpke/src/ciphertext.rs index 6e8afc91..23c2669d 100644 --- a/tpke/src/ciphertext.rs +++ b/tpke/src/ciphertext.rs @@ -1,5 +1,5 @@ use ark_ec::{AffineCurve, PairingEngine}; -use ark_ff::{One, ToBytes, UniformRand}; +use ark_ff::{FromBytes, One, ToBytes, UniformRand}; use chacha20::cipher::{NewCipher, StreamCipher}; use chacha20::{ChaCha20, Key, Nonce}; use rand_core::RngCore; @@ -22,6 +22,7 @@ impl Ciphertext { (g_inv.clone(), E::G2Prepared::from(self.auth_tag)), ]) == E::Fqk::one() } + fn construct_tag_hash(&self) -> E::G2Affine { let mut hash_input = Vec::::new(); self.nonce.write(&mut hash_input).unwrap(); @@ -29,6 +30,35 @@ impl Ciphertext { hash_to_g2(&hash_input) } + + pub fn to_bytes(&self) -> Vec { + let mut bytes = Vec::new(); + self.nonce.write(&mut bytes).unwrap(); + bytes.extend_from_slice(&self.ciphertext); + self.auth_tag.write(&mut bytes).unwrap(); + bytes + } + + pub fn from_bytes(bytes: &[u8]) -> Self { + const NONCE_LEN: usize = 97; + let mut nonce_bytes = [0u8; NONCE_LEN]; + nonce_bytes.copy_from_slice(&bytes[..NONCE_LEN]); + let nonce = E::G1Affine::read(&nonce_bytes[..]).unwrap(); + + const CIPHERTEXT_LEN: usize = 33; + let ciphertext = bytes[NONCE_LEN..NONCE_LEN + CIPHERTEXT_LEN].to_vec(); + + const AUTH_TAG_LEN: usize = 193; + let mut auth_tag_bytes = [0u8; AUTH_TAG_LEN]; + auth_tag_bytes.copy_from_slice(&bytes[bytes.len() - AUTH_TAG_LEN..]); + let auth_tag = E::G2Affine::read(&auth_tag_bytes[..]).unwrap(); + + Self { + nonce, + ciphertext, + auth_tag, + } + } } pub fn encrypt(