فهرست منبع

Merge branch 'master' of github.com:darkrenaissance/darkfi

ghassmo 4 سال پیش
والد
کامیت
19e0e332dc
9فایلهای تغییر یافته به همراه183 افزوده شده و 32 حذف شده
  1. 2 2
      Cargo.lock
  2. 1 1
      Cargo.toml
  3. 10 0
      doc/vanishing-poly.md
  4. 64 0
      scripts/halo/fft.sage
  5. 6 0
      scripts/halo/halo2.sage
  6. 77 13
      src/cli/drk_cli.rs
  7. 3 3
      src/client/client.rs
  8. 16 11
      src/rpc/adapters/client_adapter.rs
  9. 4 2
      todo.md

+ 2 - 2
Cargo.lock

@@ -3888,9 +3888,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",

+ 1 - 1
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"

+ 10 - 0
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)$$
+

+ 64 - 0
scripts/halo/fft.sage

@@ -0,0 +1,64 @@
+# See also https://cp-algorithms.com/algebra/fft.html
+
+q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
+K = GF(q)
+P.<X> = 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
+

+ 6 - 0
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

+ 77 - 13
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,6 +18,7 @@ fn amount_f64(v: String) -> std::result::Result<(), String> {
 
 #[derive(Deserialize, Debug)]
 pub struct TransferParams {
+    pub asset: Asset,
     pub pub_key: String,
     pub amount: f64,
 }
@@ -23,6 +26,7 @@ pub struct TransferParams {
 impl TransferParams {
     pub fn new() -> Self {
         Self {
+            asset: Asset::new(),
             pub_key: String::new(),
             amount: 0.0,
         }
@@ -30,19 +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: Asset,
     pub pub_key: String,
     pub amount: f64,
 }
@@ -50,12 +55,36 @@ pub struct WithdrawParams {
 impl WithdrawParams {
     pub fn new() -> Self {
         Self {
+            asset: Asset::new(),
             pub_key: String::new(),
             amount: 0.0,
         }
     }
 }
 
+#[derive(Deserialize, Debug)]
+pub struct Asset {
+    pub ticker: String,
+    pub id: Vec<u8>,
+}
+
+impl Asset {
+    pub fn new() -> Self {
+        Self {
+            ticker: String::new(),
+            id: Vec::new(),
+        }
+    }
+    pub fn id_hash(&self, ticker: &String) -> Result<Vec<u8>> {
+        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,
@@ -131,12 +160,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 +181,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 +222,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");
@@ -188,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);
             }
@@ -199,6 +255,10 @@ 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.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();
                 }
@@ -214,6 +274,10 @@ 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.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();
                 }

+ 3 - 3
src/client/client.rs

@@ -9,8 +9,8 @@ use crate::crypto::{
 };
 use crate::rpc::adapters::{RpcClient, RpcClientAdapter};
 use crate::rpc::jsonserver;
-use crate::serial::Encodable;
 use crate::serial::Decodable;
+use crate::serial::Encodable;
 use crate::service::{CashierClient, GatewayClient, GatewaySlabsSubscriber};
 use crate::state::{state_transition, ProgramState, StateUpdate};
 use crate::wallet::{CashierDbPtr, WalletPtr};
@@ -126,15 +126,15 @@ impl Client {
 
     pub async fn transfer(
         self: &mut Self,
+        asset_id: u64,
         pub_key: jubjub::SubgroupPoint,
         amount: f64,
     ) -> Result<()> {
-
         if amount <= 0.0 {
             return Err(ClientFailed::UnvalidAmount(amount as u64).into());
         }
 
-        self.send(pub_key.clone(), amount.clone() as u64, 1, false)
+        self.send(pub_key.clone(), amount.clone() as u64, asset_id, false)
             .await?;
 
         Ok(())

+ 16 - 11
src/rpc/adapters/client_adapter.rs

@@ -31,15 +31,15 @@ pub trait RpcClient {
 
     /// transfer
     #[rpc(name = "transfer")]
-    fn transfer(&self, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>>;
+    fn transfer(&self, asset_id: u64, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>>;
 
     /// withdraw
     #[rpc(name = "withdraw")]
-    fn withdraw(&self, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>>;
+    fn withdraw(&self, asset_id: u64, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>>;
 
     /// deposit
     #[rpc(name = "deposit")]
-    fn deposit(&self) -> BoxFuture<Result<String>>;
+    fn deposit(&self, asset_id: u64) -> BoxFuture<Result<String>>;
 }
 
 pub struct RpcClientAdapter {
@@ -75,6 +75,7 @@ impl RpcClientAdapter {
 
     async fn transfer_process(
         client: Arc<Mutex<Client>>,
+        asset_id: u64,
         address: Vec<u8>,
         amount: f64,
     ) -> Result<String> {
@@ -89,7 +90,7 @@ impl RpcClientAdapter {
         client
             .lock()
             .await
-            .transfer(address.clone(), amount)
+            .transfer(asset_id, address.clone(), amount)
             .await?;
 
         Ok(format!("transfered {} DRK to {}", amount, address))
@@ -98,13 +99,14 @@ impl RpcClientAdapter {
     async fn withdraw_process(
         client: Arc<Mutex<Client>>,
         cashier_client: Arc<Mutex<CashierClient>>,
+        asset_id: u64,
         address: Vec<u8>,
         amount: f64,
     ) -> Result<String> {
         let drk_public = cashier_client
             .lock()
             .await
-            .withdraw(1, address)
+            .withdraw(asset_id, address)
             .await
             .map_err(|err| ClientFailed::from(err))?;
 
@@ -112,7 +114,7 @@ impl RpcClientAdapter {
             client
                 .lock()
                 .await
-                .transfer(drk_addr.clone(), amount)
+                .transfer(asset_id, drk_addr.clone(), amount)
                 .await?;
 
             return Ok(format!(
@@ -127,6 +129,7 @@ impl RpcClientAdapter {
     async fn deposit_process<T>(
         client: Arc<Mutex<Client>>,
         cashier_client: Arc<Mutex<CashierClient>>,
+        asset_id: u64,
     ) -> Result<String>
     where
         T: Decodable + ToString,
@@ -135,7 +138,7 @@ impl RpcClientAdapter {
         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))?;
 
@@ -169,28 +172,30 @@ impl RpcClient for RpcClientAdapter {
         Self::key_gen_process(self.client.clone()).boxed()
     }
 
-    fn transfer(&self, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>> {
+    fn transfer(&self, asset_id: u64, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>> {
         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: Vec<u8>, amount: f64) -> BoxFuture<Result<String>> {
+    fn withdraw(&self, asset_id: u64, pub_key: Vec<u8>, amount: f64) -> BoxFuture<Result<String>> {
         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<Result<String>> {
+    fn deposit(&self, asset_id: u64) -> BoxFuture<Result<String>> {
         debug!(target: "RPC USER ADAPTER", "deposit() [START]");
         #[cfg(feature = "default")]
         Self::deposit_process::<bitcoin::PublicKey>(
             self.client.clone(),
             self.cashier_client.clone(),
+            asset_id,
         )
         .boxed()
     }

+ 4 - 2
todo.md

@@ -54,12 +54,14 @@ 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
+- [ ] halo2 lookup
+- [ ] read groth permutation paper
 
 ## blockchain