From c5d6830903a8093f37390424d2b85622ef41d906 Mon Sep 17 00:00:00 2001 From: lunar-mining Date: Fri, 10 Sep 2021 14:53:37 +0200 Subject: [PATCH 01/10] added asset_id param to deposit/withdraw/transfer --- src/client/client.rs | 9 +++++++-- src/rpc/adapters/client_adapter.rs | 28 ++++++++++++++++------------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/client/client.rs b/src/client/client.rs index 110a11fec..5b7b9b008 100644 --- a/src/client/client.rs +++ b/src/client/client.rs @@ -124,7 +124,12 @@ impl Client { Ok(()) } - pub async fn transfer(self: &mut Self, pub_key: String, amount: f64) -> Result<()> { + pub async fn transfer( + self: &mut Self, + asset_id: u64, + pub_key: String, + amount: f64, + ) -> Result<()> { let address = bs58::decode(pub_key.clone()) .into_vec() .map_err(|_| ClientFailed::UnvalidAddress(pub_key.clone()))?; @@ -136,7 +141,7 @@ impl Client { return Err(ClientFailed::UnvalidAmount(amount as u64).into()); } - self.send(address.clone(), amount.clone() as u64, 1, false) + self.send(address.clone(), amount.clone() as u64, asset_id, false) .await?; Ok(()) diff --git a/src/rpc/adapters/client_adapter.rs b/src/rpc/adapters/client_adapter.rs index d6baef891..4643cdd56 100644 --- a/src/rpc/adapters/client_adapter.rs +++ b/src/rpc/adapters/client_adapter.rs @@ -31,15 +31,15 @@ pub trait RpcClient { /// transfer #[rpc(name = "transfer")] - fn transfer(&self, pub_key: String, amount: f64) -> BoxFuture>; + fn transfer(&self, asset_id: u64, pub_key: String, amount: f64) -> BoxFuture>; /// withdraw #[rpc(name = "withdraw")] - fn withdraw(&self, pub_key: String, amount: f64) -> BoxFuture>; + fn withdraw(&self, asset_id: u64, pub_key: String, amount: f64) -> BoxFuture>; /// deposit #[rpc(name = "deposit")] - fn deposit(&self) -> BoxFuture>; + fn deposit(&self, asset_id: u64) -> BoxFuture>; } pub struct RpcClientAdapter { @@ -75,13 +75,14 @@ impl RpcClientAdapter { async fn transfer_process( client: Arc>, + asset_id: u64, address: String, amount: f64, ) -> Result { client .lock() .await - .transfer(address.clone(), amount) + .transfer(asset_id, address.clone(), amount) .await?; Ok(format!("transfered {} DRK to {}", amount, address)) @@ -90,13 +91,14 @@ impl RpcClientAdapter { async fn withdraw_process( client: Arc>, cashier_client: Arc>, + asset_id: u64, address: String, amount: f64, ) -> Result { let drk_public = cashier_client .lock() .await - .withdraw(1, address) + .withdraw(asset_id, address) .await .map_err(|err| ClientFailed::from(err))?; @@ -106,7 +108,7 @@ impl RpcClientAdapter { client .lock() .await - .transfer(drk_addr.clone(), amount) + .transfer(asset_id, drk_addr.clone(), amount) .await?; return Ok(format!( @@ -121,12 +123,13 @@ impl RpcClientAdapter { async fn deposit_process( client: Arc>, cashier_client: Arc>, + asset_id: u64, ) -> Result { let deposit_addr = client.lock().await.state.wallet.get_public_keys()?[0]; let coin_public = cashier_client .lock() .await - .get_address(1, deposit_addr) + .get_address(asset_id, deposit_addr) .await .map_err(|err| ClientFailed::from(err))?; @@ -159,24 +162,25 @@ impl RpcClient for RpcClientAdapter { Self::key_gen_process(self.client.clone()).boxed() } - fn transfer(&self, pub_key: String, amount: f64) -> BoxFuture> { + fn transfer(&self, asset_id: u64, pub_key: String, amount: f64) -> BoxFuture> { debug!(target: "RPC USER ADAPTER", "transfer() [START]"); - Self::transfer_process(self.client.clone(), pub_key, amount).boxed() + Self::transfer_process(self.client.clone(), asset_id, pub_key, amount).boxed() } - fn withdraw(&self, pub_key: String, amount: f64) -> BoxFuture> { + fn withdraw(&self, asset_id: u64, pub_key: String, amount: f64) -> BoxFuture> { debug!(target: "RPC USER ADAPTER", "withdraw() [START]"); Self::withdraw_process( self.client.clone(), self.cashier_client.clone(), + asset_id, pub_key, amount, ) .boxed() } - fn deposit(&self) -> BoxFuture> { + fn deposit(&self, asset_id: u64) -> BoxFuture> { debug!(target: "RPC USER ADAPTER", "deposit() [START]"); - Self::deposit_process(self.client.clone(), self.cashier_client.clone()).boxed() + Self::deposit_process(self.client.clone(), self.cashier_client.clone(), asset_id).boxed() } } From 62292e28573bd7cb633756c9621967bfbf2bd1e3 Mon Sep 17 00:00:00 2001 From: lunar-mining Date: Fri, 10 Sep 2021 15:07:54 +0200 Subject: [PATCH 02/10] added 'asset' to cli and made help messages multichain --- src/cli/drk_cli.rs | 56 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/cli/drk_cli.rs b/src/cli/drk_cli.rs index 650a50b7b..c3986ed77 100644 --- a/src/cli/drk_cli.rs +++ b/src/cli/drk_cli.rs @@ -16,6 +16,7 @@ fn amount_f64(v: String) -> std::result::Result<(), String> { #[derive(Deserialize, Debug)] pub struct TransferParams { + pub asset: String, pub pub_key: String, pub amount: f64, } @@ -23,6 +24,7 @@ pub struct TransferParams { impl TransferParams { pub fn new() -> Self { Self { + asset: String::new(), pub_key: String::new(), amount: 0.0, } @@ -43,6 +45,7 @@ impl Deposit { #[derive(Deserialize, Debug)] pub struct WithdrawParams { + pub asset: String, pub pub_key: String, pub amount: f64, } @@ -50,6 +53,7 @@ pub struct WithdrawParams { impl WithdrawParams { pub fn new() -> Self { Self { + asset: String::new(), pub_key: String::new(), amount: 0.0, } @@ -131,12 +135,20 @@ impl DrkCli { ) .subcommand( App::new("transfer") - .about("Transfer DBTC between users") + .about("Transfer dark assets between users") + .arg( + Arg::with_name("asset") + .value_name("ASSET_TYPE") + .takes_value(true) + .index(1) + .help("Desired asset type") + .required(true), + ) .arg( Arg::with_name("address") .value_name("RECEIVE_ADDRESS") .takes_value(true) - .index(1) + .index(2) .help("Address of recipient") .required(true), ) @@ -144,21 +156,40 @@ impl DrkCli { Arg::with_name("amount") .value_name("AMOUNT") .takes_value(true) - .index(2) + .index(3) .validator(amount_f64) - .help("Amount to send, in DBTC") + .help("Amount to send") + .required(true), + ), + ) + .subcommand( + App::new("deposit") + .about("Deposit clear assets for dark assets") + .arg( + Arg::with_name("asset") + .value_name("ASSET_TYPE") + .takes_value(true) + .index(1) + .help("Desired asset type") .required(true), ), ) - .subcommand(App::new("deposit").about("Deposit BTC for dBTC")) .subcommand( App::new("withdraw") - .about("Withdraw BTC for dBTC") + .about("Withdraw dark assets for clear assets") + .arg( + Arg::with_name("asset") + .value_name("ASSET_TYPE") + .takes_value(true) + .index(1) + .help("Desired asset type") + .required(true), + ) .arg( Arg::with_name("address") .value_name("RECEIVE_ADDRESS") .takes_value(true) - .index(1) + .index(2) .help("Address of recipient") .required(true), ) @@ -166,13 +197,12 @@ impl DrkCli { Arg::with_name("amount") .value_name("AMOUNT") .takes_value(true) - .index(2) + .index(3) .validator(amount_f64) - .help("Amount to send, in BTC") + .help("Amount to send") .required(true), ), ) - .subcommand(App::new("deposit").about("Deposit BTC for dBTC")) .get_matches(); let verbose = app.is_present("verbose"); @@ -199,6 +229,9 @@ impl DrkCli { match app.subcommand_matches("transfer") { Some(transfer_sub) => { let mut trn = TransferParams::new(); + if let Some(asset) = transfer_sub.value_of("asset") { + trn.asset = asset.to_string(); + } if let Some(address) = transfer_sub.value_of("address") { trn.pub_key = address.to_string(); } @@ -214,6 +247,9 @@ impl DrkCli { match app.subcommand_matches("withdraw") { Some(withdraw_sub) => { let mut wdraw = WithdrawParams::new(); + if let Some(asset) = withdraw_sub.value_of("asset") { + wdraw.asset = asset.to_string(); + } if let Some(address) = withdraw_sub.value_of("address") { wdraw.pub_key = address.to_string(); } From 1e96c744cc33e9dde77d71caf82f15719fe6ecb5 Mon Sep 17 00:00:00 2001 From: lunar-mining Date: Sat, 11 Sep 2021 08:58:50 +0200 Subject: [PATCH 03/10] made Asset type to handle drk cli inputs --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/cli/drk_cli.rs | 46 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1737d9f62..93300edee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3885,9 +3885,9 @@ checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" [[package]] name = "sha2" -version = "0.9.6" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", diff --git a/Cargo.toml b/Cargo.toml index b726b401f..96ae76f56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ zcash_proofs = "0.5.0" #bench-utils = { git = "https://github.com/scipr-lab/zexe", features = ["print-trace"]} rand = "0.7.3" rand_core = "0.5.1" -sha2 = "0.9.1" +sha2 = "0.9.8" rand_xorshift = "0.2" blake2s_simd = "0.5" blake2b_simd = "0.5.11" diff --git a/src/cli/drk_cli.rs b/src/cli/drk_cli.rs index c3986ed77..f68e9f345 100644 --- a/src/cli/drk_cli.rs +++ b/src/cli/drk_cli.rs @@ -1,9 +1,11 @@ //use super::cli_config::DrkCliConfig; use crate::Result; +use blake2b_simd::Params; use clap::{App, Arg}; use serde::Deserialize; +use crate::serial; use std::path::PathBuf; fn amount_f64(v: String) -> std::result::Result<(), String> { @@ -16,7 +18,7 @@ fn amount_f64(v: String) -> std::result::Result<(), String> { #[derive(Deserialize, Debug)] pub struct TransferParams { - pub asset: String, + pub asset: Asset, pub pub_key: String, pub amount: f64, } @@ -24,7 +26,7 @@ pub struct TransferParams { impl TransferParams { pub fn new() -> Self { Self { - asset: String::new(), + asset: Asset::new(), pub_key: String::new(), amount: 0.0, } @@ -32,20 +34,20 @@ impl TransferParams { } pub struct Deposit { - pub asset: String, + pub asset: Asset, } impl Deposit { pub fn new() -> Self { Self { - asset: String::new(), + asset: Asset::new(), } } } #[derive(Deserialize, Debug)] pub struct WithdrawParams { - pub asset: String, + pub asset: Asset, pub pub_key: String, pub amount: f64, } @@ -53,13 +55,36 @@ pub struct WithdrawParams { impl WithdrawParams { pub fn new() -> Self { Self { - asset: String::new(), + asset: Asset::new(), pub_key: String::new(), amount: 0.0, } } } +#[derive(Deserialize, Debug)] +pub struct Asset { + pub ticker: String, + pub id: Vec, +} + +impl Asset { + pub fn new() -> Self { + Self { + ticker: String::new(), + id: Vec::new(), + } + } + pub fn id_hash(&self, ticker: &String) -> Result> { + let mut hasher = Params::new().hash_length(64).to_state(); + hasher.update(ticker.as_bytes()); + let result = hasher.finalize(); + let scalar = jubjub::Fr::from_bytes_wide(result.as_array()); + let id = serial::serialize(&scalar); + Ok(id) + } +} + pub struct DrkCli { pub verbose: bool, pub wallet: bool, @@ -218,7 +243,8 @@ impl DrkCli { Some(deposit_sub) => { let mut dep = Deposit::new(); if let Some(asset) = deposit_sub.value_of("asset") { - dep.asset = asset.to_string(); + dep.asset.ticker = asset.to_string(); + dep.asset.id = dep.asset.id_hash(&dep.asset.ticker)?; } deposit = Some(dep); } @@ -230,7 +256,8 @@ impl DrkCli { Some(transfer_sub) => { let mut trn = TransferParams::new(); if let Some(asset) = transfer_sub.value_of("asset") { - trn.asset = asset.to_string(); + trn.asset.ticker = asset.to_string(); + trn.asset.id = trn.asset.id_hash(&trn.asset.ticker)?; } if let Some(address) = transfer_sub.value_of("address") { trn.pub_key = address.to_string(); @@ -248,7 +275,8 @@ impl DrkCli { Some(withdraw_sub) => { let mut wdraw = WithdrawParams::new(); if let Some(asset) = withdraw_sub.value_of("asset") { - wdraw.asset = asset.to_string(); + wdraw.asset.ticker = asset.to_string(); + wdraw.asset.id = wdraw.asset.id_hash(&wdraw.asset.ticker)?; } if let Some(address) = withdraw_sub.value_of("address") { wdraw.pub_key = address.to_string(); From 1f80182fd872a57f31402260573d9ebbc8f9c614 Mon Sep 17 00:00:00 2001 From: narodnik Date: Sat, 11 Sep 2021 09:20:34 +0200 Subject: [PATCH 04/10] add description for what how the vanishing polynomial is calculated as X^N - 1 --- doc/vanishing-poly.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 doc/vanishing-poly.md diff --git a/doc/vanishing-poly.md b/doc/vanishing-poly.md new file mode 100644 index 000000000..51b65e3ce --- /dev/null +++ b/doc/vanishing-poly.md @@ -0,0 +1,10 @@ +We have a vanishing polynomial $Z(X) = X^N - 1$. Implicitly we are proving that + +$$X^N = 1$$ + +What are the solutions to this polynomial? Well the answer is $\omega$ which is any root of $1$. + +Therefore the solution to the formula $X^N - 1$ will be all the values of $X^N = 1$ or + +$$X^N - 1 = (\omega - 1)(\omega^2 - 1)\cdots(\omega^{N - 1} - 1)$$ + From 5233a8efd97fac01f0127b353c45a86f4d6d88de Mon Sep 17 00:00:00 2001 From: narodnik Date: Sat, 11 Sep 2021 11:13:10 +0200 Subject: [PATCH 05/10] add example of fft (fast fourier transform) --- scripts/halo/fft.sage | 62 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 scripts/halo/fft.sage diff --git a/scripts/halo/fft.sage b/scripts/halo/fft.sage new file mode 100644 index 000000000..4cb517974 --- /dev/null +++ b/scripts/halo/fft.sage @@ -0,0 +1,62 @@ +q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 +K = GF(q) +P. = K[] + +def get_omega(): + generator = K(5) + assert (q - 1) % 2^32 == 0 + # Root of unity + t = (q - 1) / 2^32 + omega = generator**t + + assert omega != 1 + assert omega^(2^16) != 1 + assert omega^(2^31) != 1 + assert omega^(2^32) == 1 + + return omega + +# Order of this element is 2^32 +omega = get_omega() +k = 3 +n = 2^k +omega = omega^(2^32 / n) +assert omega^n == 1 + +f = 6*X^7 + 7*X^5 + 3*X^2 + X + +def fft(F): + print(f"fft({F})") + # On the first invocation: + #assert len(F) == n + N = len(F) + if N == 1: + print(" returning 1") + return F + + omega_prime = omega^(n/N) + assert omega_prime^(n - 1) != 1 + assert omega_prime^N == 1 + # Split into even and odd powers of X + F_e = [a for a in F[::2]] + print(" Evens:", F_e) + F_o = [a for a in F[1::2]] + print(" Odds:", F_o) + + y_e, y_o = fft(F_e), fft(F_o) + print(f"y_e = {y_e}, y_o = {y_o}") + y = [0] * N + for j in range(N / 2): + y[j] = y_e[j] + omega_prime^j * y_o[j] + y[j + N / 2] = y_e[j] - omega_prime^j * y_o[j] + print(f" returning y = {y}") + return y + +print("f =", f) +evals = fft(list(f)) +print("evals =", evals) +print("{omega^i : i in {0, 1, ..., n - 1}} =", [omega^i for i in range(n)]) +evals2 = [f(omega^i) for i in range(n)] +print("{f(omega^i) for all omega^i} =", evals2) +assert evals == evals2 + From 546cd0dfabd0f0a2b1e28447cc48462b4e3f638f Mon Sep 17 00:00:00 2001 From: narodnik Date: Sat, 11 Sep 2021 11:14:04 +0200 Subject: [PATCH 06/10] todo.md: mark fft todo item as complete --- todo.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/todo.md b/todo.md index 275ee072b..aa5efa2b9 100644 --- a/todo.md +++ b/todo.md @@ -53,11 +53,11 @@ Open research questions. ## light-clients - [ ] Fast efficient batch DH technique. Currently all new transactions need to be scanned. There should be a means of efficiently batching this test for light clients initially syncing against a server. -- [ ] Anonymouse fetch using an Oblivious-Transfer protocol. Light clients potentially leak info to servers based on the data they request, but with an OT protocol they do not reveal exactly what they are requesting. +- [ ] Anonymous fetch using an Oblivious-Transfer protocol. Light clients potentially leak info to servers based on the data they request, but with an OT protocol they do not reveal exactly what they are requesting. ## cryptography -- [ ] FFT for polynomial multiplication +- [x] FFT for polynomial multiplication - [ ] finish bulletproofs impl ## blockchain From 5d99b5817e19e011e4511f7d3a4661f76a89d358 Mon Sep 17 00:00:00 2001 From: narodnik Date: Sat, 11 Sep 2021 11:16:44 +0200 Subject: [PATCH 07/10] fft.sage: add link to cp algorithms --- scripts/halo/fft.sage | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/halo/fft.sage b/scripts/halo/fft.sage index 4cb517974..803b58e2d 100644 --- a/scripts/halo/fft.sage +++ b/scripts/halo/fft.sage @@ -1,3 +1,5 @@ +# See also https://cp-algorithms.com/algebra/fft.html + q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 K = GF(q) P. = K[] From c3f0424e7a061feb0701a3600c038cc522a37683 Mon Sep 17 00:00:00 2001 From: narodnik Date: Sat, 11 Sep 2021 12:50:12 +0200 Subject: [PATCH 08/10] todo: halo2 lookup --- todo.md | 1 + 1 file changed, 1 insertion(+) diff --git a/todo.md b/todo.md index aa5efa2b9..fb4075dc2 100644 --- a/todo.md +++ b/todo.md @@ -59,6 +59,7 @@ Open research questions. - [x] FFT for polynomial multiplication - [ ] finish bulletproofs impl +- [ ] halo2 lookup ## blockchain From 71ae901729defd47133e737e9bf3d1e855bbe956 Mon Sep 17 00:00:00 2001 From: narodnik Date: Sat, 11 Sep 2021 13:34:24 +0200 Subject: [PATCH 09/10] add comment about delta --- scripts/halo/halo2.sage | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/halo/halo2.sage b/scripts/halo/halo2.sage index 6552468fb..f22bf5757 100644 --- a/scripts/halo/halo2.sage +++ b/scripts/halo/halo2.sage @@ -13,6 +13,12 @@ assert int(t) % 2 != 0 delta = generator^(2^32) assert delta^t == 1 +# The size of the multiplicative group is phi(q) = q - 1 +# And inside this group are 2 distinct subgroups of size t and 2^s. +# delta is the generator for the size t subgroup, and omega for the 2^s one. +# Taking powers of these generators and multiplying them will produce +# unique cosets that divide the entire group for q. + def get_omega(): generator = K(5) assert (q - 1) % 2^32 == 0 From 97cb5d5b5e38b543b3f6e73acd7e450c1b731df8 Mon Sep 17 00:00:00 2001 From: narodnik Date: Sat, 11 Sep 2021 19:04:30 +0200 Subject: [PATCH 10/10] todo: groth permutation paper --- todo.md | 1 + 1 file changed, 1 insertion(+) diff --git a/todo.md b/todo.md index fb4075dc2..ef408cd75 100644 --- a/todo.md +++ b/todo.md @@ -60,6 +60,7 @@ Open research questions. - [x] FFT for polynomial multiplication - [ ] finish bulletproofs impl - [ ] halo2 lookup +- [ ] read groth permutation paper ## blockchain