Просмотр исходного кода

spec: add money coin, current day, pedersen commits

zero 2 лет назад
Родитель
Сommit
f357f1778b

+ 7 - 5
doc/src/SUMMARY.md

@@ -79,11 +79,13 @@
 - [Concepts](spec/concepts.md)
 - [Cryptographic Schemes](spec/crypto-schemes.md)
 - [Contracts]()
-  - [DAO](spec/contracts/dao/dao.md)
-    - [Concepts](spec/contracts/dao/concepts.md)
-    - [Model](spec/contracts/dao/model.md)
-    - [Contract](spec/contracts/dao/contract.md)
-  - [Money](spec/contracts/money.md)
+  - [DAO](spec/contract/dao/dao.md)
+    - [Concepts](spec/contract/dao/concepts.md)
+    - [Model](spec/contract/dao/model.md)
+    - [Scheme](spec/contract/dao/scheme.md)
+  - [Money]()
+    - [Model](spec/contract/money/model.md)
+    - [Scheme](spec/contract/money/scheme.md)
 
 # P2P API Tutorial
 

+ 16 - 7
doc/src/spec/concepts.md

@@ -33,7 +33,7 @@ environment with limited access to the host.
 ## Contract Sections
 
 Contract operation is defined by *sections*. Each contract section is only
-allowed to call certain host functions.
+allowed to call certain [host functions](#host-functions).
 
 **Example:** `exec()` may call `db_get()` but not `db_set()`, while `update()`
 cannot call `db_get()`, but may call `db_set()`.
@@ -42,6 +42,21 @@ cannot call `db_get()`, but may call `db_set()`.
 {{#include ../../../src/runtime/vm_runtime.rs:contract-section}}
 ```
 
+For a list of permissions given to host functions, see the section [Host Functions](#host-functions).
+
+## Contract Function IDs
+
+Let $𝔽ₚ$ be defined as in the section [Pallas and Vesta](crypto-schemes.md#pallas-and-vesta).
+
+Functions can be specified using a tuple $\t{FuncId} := (𝔽ₚ, 𝔹)$.
+
+## Host Functions
+
+Host functions give access to the executing node context external to the local
+WASM scope.
+
+The current list of functions are:
+
 | Host function     | Permission                     | Description                         |
 |-------------------|--------------------------------|-------------------------------------|
 | `db_init`         | Deploy                         | Create a new database               |
@@ -55,9 +70,3 @@ cannot call `db_get()`, but may call `db_set()`.
 | `set_return_data` | Exec, Metadata                 | Used for returning data to the host |
 | `get_slot`        | Deploy, Exec, Metadata         | Get the current slot                |
 
-## Function IDs
-
-Let $𝔽ₚ$ be defined as in the section [Pallas and Vesta](crypto-schemes.md#pallas-and-vesta).
-
-Functions can be specified using a tuple $\t{FuncId} := (𝔽ₚ, 𝔹)$.
-

+ 0 - 0
doc/src/spec/contracts/dao/concepts.md → doc/src/spec/contract/dao/concepts.md


+ 1 - 1
doc/src/spec/contracts/dao/dao.md → doc/src/spec/contract/dao/dao.md

@@ -9,5 +9,5 @@ threshold they are finalized, then the proposal can be executed.
 
 - [Concepts](concepts.md)
 - [Model](model.md)
-- [Contract](contract.md)
+- [Scheme](scheme.md)
 

+ 18 - 2
doc/src/spec/contracts/dao/model.md → doc/src/spec/contract/dao/model.md

@@ -26,7 +26,7 @@ $$ \begin{aligned}
   \t{Params}_\t{DAO}.Q &∈ ℕ₆₄ \\
   \t{Params}_\t{DAO}.A^\% &∈ ℕ₆₄ × ℕ₆₄ \\
   \t{Params}_\t{DAO}.τ &∈ 𝔽ₚ \\
-  \t{Params}_\t{DAO}.PK &∈ ℙₚ
+  \t{Params}_\t{DAO}.\t{PK} &∈ ℙₚ
 \end{aligned} $$
 where the approval ratio $\t{Approval}^\% = (q, d)$ defines the equivalence
 class $[\frac{q}{d}]$ of fractions defined by $q₁d₂ = q₂d₁ ⟺  [\frac{q₁}{d₁}] \~ [\frac{q₂}{d₂}]$.
@@ -36,7 +36,7 @@ class $[\frac{q}{d}]$ of fractions defined by $q₁d₂ = q₂d₁ ⟺  [\frac{q
 ```
 
 $$ \t{Bulla}_\t{DAO} : \t{Params}_\t{DAO} × 𝔽ₚ → 𝔽ₚ $$
-$$ \t{Bulla}_\t{DAO}(p, b_\t{DAO}) = \t{Bulla}(ℕ₆₄2𝔽ₚ(p.L), ℕ₆₄2𝔽ₚ(p.Q), ℕ₆₄2𝔽ₚ(p.A^\%), p.τ, \mathcal{X}(p.PK), \mathcal{Y}(p.PK), b_\t{DAO}) $$
+$$ \t{Bulla}_\t{DAO}(p, b_\t{DAO}) = \t{Bulla}(ℕ₆₄2𝔽ₚ(p.L), ℕ₆₄2𝔽ₚ(p.Q), ℕ₆₄2𝔽ₚ(p.A^\%), p.τ, \mathcal{X}(p.\t{PK}), \mathcal{Y}(p.\t{PK}), b_\t{DAO}) $$
 
 ## Proposals
 
@@ -89,3 +89,19 @@ Let $P$ be a proposal bulla as in the section [Proposal](#proposal).
 
 Define $\t{Nullifier}_\t{Vote} : 𝔽ₚ × 𝔽ₚ × 𝔽ₚ → 𝔽ₚ$ as follows:
 $$ \t{Nullifier}_\t{Vote}(\mathcal{C}.s, C, P) = \t{PoseidonHash}(\mathcal{C}.s, C, P) $$
+
+## Current Day
+
+Time limits on proposals are expressed in terms of days. Since proofs cannot
+guarantee which block they get into, we therefore must modulo the block height
+a certain number which we use in the proofs.
+
+```rust
+{{#include ../../../../../src/contract/dao/src/lib.rs:dao-slot_to_day}}
+```
+
+which can be used like this
+```rust
+{{#include ../../../../../src/contract/dao/src/entrypoint/propose.rs:dao-slot_to_day-example-usage}}
+```
+

+ 6 - 6
doc/src/spec/contracts/dao/contract.md → doc/src/spec/contract/dao/scheme.md

@@ -6,16 +6,14 @@ Let $\t{PoseidonHash}$ be defined as in the section [PoseidonHash Function](../.
 
 Let $𝔽ₚ, ℙₚ, \t{DerivePubKey}$ be defined as in the section [Pallas and Vesta](../../crypto-schemes.md#pallas-and-vesta).
 
+Let $\t{PedersenCommit}$ be defined as in the section [Homomorphic Pedersen Commitments](../../crypto-schemes.md#homomorphic-pedersen-commitments).
+
 Let $\t{Params}_\t{DAO}, \t{Bulla}_\t{DAO}, \t{Params}_\t{Proposal}, \t{Bulla}_\t{Proposal}$ be defined as in [DAO Model](model.md).
 
 TODO: add merkle section to crypto-schemes with merklepos, merklepath,
 MerkleRoot
 
-TODO: add pedersencommit
-
-TODO: need params coin
-
-TODO: document current day = $𝔽ₚ$ CurrentDay
+TODO: rename slot to block_height
 
 ## Mint
 
@@ -88,7 +86,9 @@ $$ \begin{aligned}
 
 ### Contract Statement
 
-Let $t₀ = \t{CurrentDay} ∈ 𝔽ₚ$ be the current day.
+Let $t₀ = \t{CurrentDay} ∈ 𝔽ₚ$ be the current day as defined in [Current Day](model.md#current-day).
+
+Let $\t{Params}_\t{Coin}$ be defined as in [Coin](../money/model.md#coin).
 
 **Valid DAO bulla merkle root**   check that $R_\t{DAO}$ is a previously
 seen merkle root in the DAO contract merkle roots DB.

+ 41 - 0
doc/src/spec/contract/money/model.md

@@ -0,0 +1,41 @@
+# Model
+
+Let $\t{Bulla}$ be defined as in the section [Bulla Commitments](../../crypto-schemes.md#bulla-commitments).
+
+Let $ℙₚ, 𝔽ₚ$ be defined as in the section [Pallas and Vesta](../../crypto-schemes.md#pallas-and-vesta).
+
+## Coin
+
+The coin contains the main parameters that define the `Money::transfer()` operation:
+
+* The public key $\t{PK}$ serves a dual role.
+  1. Protects receiver privacy from the sender since the corresponding secret
+     key is used in the nullifier.
+  2. Authorizes the creation of the nullifier by the receiver.
+* The core parameters are the value $v$ and the token ID $τ$.
+* The serial $ζ$ is randomly selected, and guarantees uniqueness of the coin
+  which is used in the nullifier. This simultaneously acts as the coin's random
+  blinding factor.
+* To enable protocol owned liquidity, we define the spend hook $\t{SH}$
+  which adds a constraint that when the coin is spent, it must be called by
+  the contract specified. The user data $\t{UD}$ can then be used by the parent
+  contract to store additional parameters in the coin. If the parameter length
+  exceeds the size of $𝔽ₚ$ then a commit can be used here instead.
+
+Define the coin params
+$$ \begin{aligned}
+  \t{Params}_\t{Coin}.\t{PK} &∈ ℙₚ \\
+  \t{Params}_\t{Coin}.v &∈ ℕ₆₄ \\
+  \t{Params}_\t{Coin}.τ &∈ 𝔽ₚ \\
+  \t{Params}_\t{Coin}.ζ &∈ 𝔽ₚ \\
+  \t{Params}_\t{Coin}.\t{SH} &∈ 𝔽ₚ \\
+  \t{Params}_\t{Coin}.\t{UD} &∈ 𝔽ₚ \\
+\end{aligned} $$
+
+```rust
+{{#include ../../../../../src/contract/money/src/model.rs:coin-attributes}}
+```
+
+$$ \t{Coin} : \t{Params}_\t{Coin} → 𝔽ₚ $$
+$$ \t{Coin}(p) = \t{Bulla}(\mathcal{X}(p.\t{PK}), \mathcal{Y}(p.\t{PK}), ℕ₆₄2𝔽ₚ(p.v), p.τ, p.ζ, p.\t{SH}, p.\t{UD}) $$
+

+ 9 - 8
doc/src/spec/contracts/money.md → doc/src/spec/contract/money/scheme.md

@@ -6,11 +6,12 @@ PoS consensus tokens.
 
 The functions/entrypoints provided by this smart contract are:
 ```rust
-{{#include ../../../../src/contract/money/src/lib.rs:money-function}}
+{{#include ../../../../../src/contract/money/src/lib.rs:money-function}}
 ```
 
 ## `MoneyFunction::TransferV1`
 
+Let $\t{PoseidonHash}$ be defined as in the section [PoseidonHash Function](../../crypto-schemes.md#poseidonhash-function).
 
 ### ZK proofs
 
@@ -40,10 +41,10 @@ on the network.
 
 **Circuit:**
 
-$$ C = \text{Poseidon}(P || v || t || s || h || u) $$
+$$ C = \text{PoseidonHash}(P, v, t, s, h, u) $$
 $$ \text{RangeCheck}(64, v) $$
 $$ V = vG + v_{\text{blind}}H $$
-$$ T = \text{Poseidon}(t || t_{\text{blind}}) $$
+$$ T = \text{PoseidonHash}(t, t_{\text{blind}}) $$
 
 $G$ and $H$ are constant well-known generators that are in the codebase
 as `VALUE_COMMIT_VALUE` and `VALUE_COMMIT_RANDOM`:
@@ -86,14 +87,14 @@ on the network.
 
 **Circuit:**
 
-$$ N = \text{Poseidon}(x || s) $$
+$$ N = \text{PoseidonHash}(x, s) $$
 $$ V = vG + v_{\text{blind}}H $$
-$$ T = \text{Poseidon}(t || t_{\text{blind}}) $$
+$$ T = \text{PoseidonHash}(t, t_{\text{blind}}) $$
 $$ P = xK $$
-$$ C = \text{Poseidon}(P || v || t || s || h || u) $$
+$$ C = \text{PoseidonHash}(P, v, t, s, h, u) $$
 $$ C' = \text{ZeroCond}(v, C) $$
 $$ R = \text{MerkleRoot}(l, p, C') $$
-$$ U = \text{Poseidon}(u, u_{\text{blind}}) $$
+$$ U = \text{PoseidonHash}(u, u_{\text{blind}}) $$
 $$ Z = zK $$
 
 $G$ and $H$ are the same generators used in `Mint_V1`, $K$ is the
@@ -143,7 +144,7 @@ number of inputs that were created with `Burn_V1` and a number of
 outputs created with `Mint_V1`.
 
 ```rust
-{{#include ../../../../src/contract/money/src/model.rs:money-params}}
+{{#include ../../../../../src/contract/money/src/model.rs:money-params}}
 ```
 
 This gets encoded into the `Transaction` format and the transaction is

+ 24 - 0
doc/src/spec/crypto-schemes.md

@@ -97,9 +97,33 @@ Define the function
 $$ \t{DerivePubKey} : 𝔽ₚ → ℙₚ $$
 $$ \t{DerivePubKey}(x) = \t{Lift}ᵥ(x) G_N $$
 
+## Group Hash
+
+Let $\t{GroupHash} : 𝔹^* × 𝔹^* → ℙₚ$ be the hash to curve function
+defined in [ZCash Protocol Spec, section 5.4.9.8](https://zips.z.cash/protocol/protocol.pdf#concretegrouphashpallasandvesta).
+The first input element acts as the domain separator to distinguish
+uses of the group hash for different purposes, while the second input is
+the actual message.
+
 ## BLAKE2b Hash Function
 
 BLAKE2 is defined by [ANWW2013](https://blake2.net/#sp).
 Define the BLAKE2b variant as
 $$ \t{BLAKE2b}: 𝔹^* → 𝔹⁶⁴ $$
 
+## Homomorphic Pedersen Commitments
+
+Let $\t{GroupHash}$ be defined as in [Group Hash](#group-hash).
+
+Let $\t{Lift}ᵥ$ be defined as in [Pubkey Derivation](#pubkey-derivation).
+
+When instantiating value commitments, we require the homomorphic property.
+
+Define:
+$$ G_V = \t{GroupHash}(\textbf{"z.cash:Orchard-cv"}, \textbf{"v"}) $$
+$$ G_B = \t{GroupHash}(\textbf{"z.cash:Orchard-cv"}, \textbf{"r"}) $$
+$$ \t{PedersenCommit} : 𝔽ₚ × 𝔽ᵥ → ℙₚ $$
+$$ \t{PedersenCommit}(v, b) = \t{Lift}ᵥ(v) G_V + b G_B $$
+
+This scheme is a computationally binding and perfectly hiding commitment scheme.
+

+ 2 - 0
src/contract/dao/src/entrypoint/propose.rs

@@ -83,7 +83,9 @@ pub(crate) fn dao_propose_get_metadata(
         ));
     }
 
+    // ANCHOR: dao-slot_to_day-example-usage
     let current_day = slot_to_day(get_verifying_slot());
+    // ANCHOR_END: dao-slot_to_day-example-usage
 
     let total_funds_coords = total_funds_commit.to_affine().coordinates().unwrap();
     zk_public_inputs.push((

+ 2 - 0
src/contract/dao/src/lib.rs

@@ -90,6 +90,7 @@ pub const DAO_CONTRACT_ZKAS_DAO_AUTH_MONEY_TRANSFER_NS: &str = "DaoAuthMoneyTran
 pub const DAO_CONTRACT_ZKAS_DAO_AUTH_MONEY_TRANSFER_ENC_COIN_NS: &str =
     "DaoAuthMoneyTransferEncCoin";
 
+// ANCHOR: dao-slot_to_day
 const SLOT_TIME: u64 = 90;
 const SECS_IN_DAY: u64 = 24 * 60 * 60;
 
@@ -98,3 +99,4 @@ pub fn slot_to_day(slot: u64) -> u64 {
     let timestamp_secs = slot * SLOT_TIME;
     timestamp_secs / SECS_IN_DAY
 }
+// ANCHOR_END: dao-slot_to_day

+ 2 - 0
src/contract/money/src/model.rs

@@ -62,6 +62,7 @@ darkfi_sdk::fp_to_bs58!(Coin);
 darkfi_sdk::ty_from_fp!(Coin);
 
 #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
+// ANCHOR: coin-attributes
 pub struct CoinAttributes {
     pub public_key: PublicKey,
     pub value: u64,
@@ -71,6 +72,7 @@ pub struct CoinAttributes {
     pub spend_hook: pallas::Base,
     pub user_data: pallas::Base,
 }
+// ANCHOR_END: coin-attributes
 
 impl CoinAttributes {
     pub fn to_coin(&self) -> Coin {