From fd87e15ccdd12854a9bccc5e5704d2626ee9a8b3 Mon Sep 17 00:00:00 2001 From: hu55a1n1 Date: Wed, 28 Feb 2024 15:29:26 -0800 Subject: [PATCH] mtcs-intent crate --- Cargo.lock | 149 +++++++++++++++++++++++++------ enclaves/quartz/src/server.rs | 2 + utils/mtcs-intent/.gitignore | 3 + utils/mtcs-intent/Cargo.toml | 17 ++++ utils/mtcs-intent/src/main.rs | 160 ++++++++++++++++++++++++++++++++++ 5 files changed, 304 insertions(+), 27 deletions(-) create mode 100644 utils/mtcs-intent/.gitignore create mode 100644 utils/mtcs-intent/Cargo.toml create mode 100644 utils/mtcs-intent/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index ed621a9..8c6c2ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,7 +157,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -168,7 +168,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -473,7 +473,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -853,7 +853,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -864,7 +864,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -948,7 +948,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -979,6 +979,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve 0.13.8", "rfc6979 0.4.0", + "serdect", "signature 2.2.0", "spki 0.7.3", ] @@ -994,6 +995,7 @@ dependencies = [ "hkdf", "libsecp256k1", "once_cell", + "openssl", "parking_lot", "rand_core 0.6.4", "sha2 0.10.8", @@ -1101,6 +1103,7 @@ dependencies = [ "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", + "serdect", "subtle", "zeroize", ] @@ -1188,6 +1191,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1259,7 +1277,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -1659,6 +1677,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "once_cell", + "serdect", "sha2 0.10.8", "signature 2.2.0", ] @@ -1777,9 +1796,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "matchers" @@ -1852,6 +1871,21 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "mtcs-intent" +version = "0.1.0" +dependencies = [ + "clap", + "cosmwasm-std", + "ecies", + "hex", + "k256 0.13.3", + "rand", + "serde", + "serde_json", + "sha2 0.10.8", +] + [[package]] name = "multimap" version = "0.8.3" @@ -1975,12 +2009,50 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.4.2", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "overload" version = "0.1.1" @@ -2100,7 +2172,7 @@ checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -2146,6 +2218,12 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "polyval" version = "0.6.1" @@ -2177,7 +2255,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -2226,7 +2304,7 @@ dependencies = [ "prost 0.12.3", "prost-types 0.12.3", "regex", - "syn 2.0.51", + "syn 2.0.52", "tempfile", "which", ] @@ -2254,7 +2332,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -2278,7 +2356,7 @@ dependencies = [ [[package]] name = "quartz-cw" version = "0.1.0" -source = "git+ssh://git@github.com/informalsystems/bisenzone-cw-mvp.git?branch=hu55a1n1/11-use-quartz#0e877198416e3c2fb85777c177bcbabb3ca80b69" +source = "git+ssh://git@github.com/informalsystems/bisenzone-cw-mvp.git?branch=hu55a1n1/11-use-quartz#8f6ff80cce2160d9f0d1f7ce20c010f17c0fa88e" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -2349,7 +2427,7 @@ dependencies = [ [[package]] name = "quartz-tee-ra" version = "0.1.0" -source = "git+ssh://git@github.com/informalsystems/bisenzone-cw-mvp.git?branch=hu55a1n1/11-use-quartz#0e877198416e3c2fb85777c177bcbabb3ca80b69" +source = "git+ssh://git@github.com/informalsystems/bisenzone-cw-mvp.git?branch=hu55a1n1/11-use-quartz#8f6ff80cce2160d9f0d1f7ce20c010f17c0fa88e" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -2743,6 +2821,7 @@ dependencies = [ "der 0.7.8", "generic-array", "pkcs8 0.10.2", + "serdect", "subtle", "zeroize", ] @@ -2821,7 +2900,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -2854,7 +2933,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -2894,7 +2973,17 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", ] [[package]] @@ -3078,9 +3167,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.51" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -3414,7 +3503,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3553,7 +3642,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3669,7 +3758,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3723,7 +3812,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3863,6 +3952,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -3915,7 +4010,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", "wasm-bindgen-shared", ] @@ -3949,7 +4044,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4172,5 +4267,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] diff --git a/enclaves/quartz/src/server.rs b/enclaves/quartz/src/server.rs index 56266d4..0dda79f 100644 --- a/enclaves/quartz/src/server.rs +++ b/enclaves/quartz/src/server.rs @@ -66,6 +66,7 @@ where &self, _request: Request, ) -> TonicResult> { + // FIXME(hu55a1n1) - disallow calling more than once let mut nonce = self.nonce.lock().unwrap(); *nonce = rand::thread_rng().gen::(); @@ -84,6 +85,7 @@ where &self, _request: Request, ) -> TonicResult> { + // FIXME(hu55a1n1) - disallow calling more than once let nonce = self.nonce.lock().unwrap(); let sk = SigningKey::random(&mut rand::thread_rng()); let pk = sk.verifying_key(); diff --git a/utils/mtcs-intent/.gitignore b/utils/mtcs-intent/.gitignore new file mode 100644 index 0000000..d8c9f3f --- /dev/null +++ b/utils/mtcs-intent/.gitignore @@ -0,0 +1,3 @@ +*.pk +*.sk + diff --git a/utils/mtcs-intent/Cargo.toml b/utils/mtcs-intent/Cargo.toml new file mode 100644 index 0000000..3f89a52 --- /dev/null +++ b/utils/mtcs-intent/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "mtcs-intent" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "4.0.32", features = ["derive"] } +cosmwasm-std = "1.4.0" +ecies = "0.2.6" +hex = "0.4.3" +k256 = { version = "0.13.2", default-features = false, features = ["ecdsa", "alloc", "serde"] } +rand = "0.8.5" +serde = { version = "1.0.197", features = ["derive"] } +serde_json = "1.0.114" +sha2 = "0.10.8" diff --git a/utils/mtcs-intent/src/main.rs b/utils/mtcs-intent/src/main.rs new file mode 100644 index 0000000..f8b5d25 --- /dev/null +++ b/utils/mtcs-intent/src/main.rs @@ -0,0 +1,160 @@ +#![forbid(unsafe_code)] +#![warn( + clippy::checked_conversions, + clippy::panic, + clippy::panic_in_result_fn, + clippy::unwrap_used, + trivial_casts, + trivial_numeric_casts, + rust_2018_idioms, + unused_lifetimes, + unused_import_braces, + unused_qualifications +)] + +use std::{ + error::Error, + fs::{read_to_string, File}, + io::Write, + path::PathBuf, +}; + +use clap::{Parser, Subcommand}; +use cosmwasm_std::HexBinary; +use ecies::encrypt; +use k256::ecdsa::{SigningKey, VerifyingKey}; +use rand::Rng; +use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; + +#[derive(Debug, Parser)] +#[command(author, version, about, long_about = None)] +struct Cli { + #[command(subcommand)] + pub command: Command, +} + +#[derive(Debug, Subcommand)] +#[allow(clippy::large_enum_variant)] +enum Command { + KeyGen { + #[clap(long, default_value = "user.pk")] + pk_file: PathBuf, + #[clap(long, default_value = "user.sk")] + sk_file: PathBuf, + }, + EncryptObligation { + #[clap(long, value_parser = parse_obligation_json)] + obligation: Obligation, + #[clap(long, default_value = "epoch.pk")] + pk_file: PathBuf, + }, +} + +fn parse_obligation_json(s: &str) -> Result { + let raw_obligation: RawObligation = serde_json::from_str(s).map_err(|e| e.to_string())?; + raw_obligation.try_into() +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +struct RawObligation { + debtor: HexBinary, + creditor: HexBinary, + amount: u64, + #[serde(default)] + salt: HexBinary, +} + +#[derive(Clone, Debug)] +struct Obligation { + debtor: VerifyingKey, + creditor: VerifyingKey, + amount: u64, + salt: [u8; 64], +} + +impl TryFrom for Obligation { + type Error = String; + + fn try_from(raw_obligation: RawObligation) -> Result { + let mut salt = [0u8; 64]; + rand::thread_rng().fill(&mut salt[..]); + + Ok(Self { + debtor: VerifyingKey::from_sec1_bytes(raw_obligation.debtor.as_slice()) + .map_err(|e| e.to_string())?, + creditor: VerifyingKey::from_sec1_bytes(raw_obligation.debtor.as_slice()) + .map_err(|e| e.to_string())?, + amount: raw_obligation.amount, + salt, + }) + } +} + +impl From for RawObligation { + fn from(obligation: Obligation) -> Self { + Self { + debtor: obligation.debtor.to_sec1_bytes().into_vec().into(), + creditor: obligation.creditor.to_sec1_bytes().into_vec().into(), + amount: obligation.amount, + salt: obligation.salt.into(), + } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +struct EncryptedObligation { + ciphertext: HexBinary, + digest: HexBinary, +} + +fn main() -> Result<(), Box> { + let args = Cli::parse(); + + match args.command { + Command::KeyGen { pk_file, sk_file } => { + let sk = SigningKey::random(&mut rand::thread_rng()); + let pk = sk.verifying_key(); + + let mut sk_file = File::create(sk_file)?; + let sk = hex::encode(sk.to_bytes()); + sk_file.write_all(sk.as_bytes())?; + + let mut pk_file = File::create(pk_file)?; + let pk = hex::encode(pk.to_sec1_bytes()); + pk_file.write_all(pk.as_bytes())?; + } + Command::EncryptObligation { + obligation, + pk_file, + } => { + let epoch_pk = { + let pk_str = read_to_string(pk_file)?; + hex::decode(pk_str)? + }; + let obligation_ser = serde_json::to_string(&RawObligation::from(obligation)) + .expect("infallible serializer"); + + let ciphertext = + encrypt(&epoch_pk, obligation_ser.as_bytes()).map_err(|e| e.to_string())?; + + let digest: [u8; 32] = { + let mut hasher = Sha256::new(); + hasher.update(obligation_ser); + hasher.finalize().into() + }; + + let obligation_enc = EncryptedObligation { + ciphertext: ciphertext.into(), + digest: digest.into(), + }; + + println!( + "{}", + serde_json::to_string(&obligation_enc).expect("infallible serializer") + ); + } + } + + Ok(()) +}