Forráskód Böngészése

zkas: Add a field definition on top of the circuit file.

Currently unused, but will probably be expanded to define proofs over
different fields.
parazyd 3 éve
szülő
commit
6a024ab801

+ 1 - 0
contrib/zk.lang

@@ -24,6 +24,7 @@
   <definitions>
     <context id="keywords" style-ref="keyword">
       <keyword>k</keyword>
+      <keyword>field</keyword>
       <keyword>constant</keyword>
       <keyword>witness</keyword>
       <keyword>circuit</keyword>

+ 1 - 1
contrib/zk.lua

@@ -20,7 +20,7 @@ local number = token(l.NUMBER, l.integer)
 
 -- Keywords.
 local keyword = token(l.KEYWORD, word_match{
-  'k', 'constant', 'witness', 'circuit',
+  'k', "field", 'constant', 'witness', 'circuit',
 })
 
 -- Constants.

+ 1 - 0
contrib/zk.vim

@@ -9,6 +9,7 @@ endif
 
 syn keyword zkasKeyword 
     \ k
+    \ field
     \ constant
     \ witness
     \ circuit

+ 1 - 0
example/simple.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "Simple" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
proof/arithmetic.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "Arith" {}
 

+ 1 - 0
proof/burn.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "Burn" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
proof/encrypt.zk

@@ -6,6 +6,7 @@
 # This is basically the el gamal scheme in ZK
 
 k = 13;
+field = "pallas";
 
 constant "Encrypt" {}
 

+ 1 - 0
proof/inclusion_proof.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "InclusionProof" {
 }

+ 1 - 0
proof/lead.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "Lead" {
          EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
proof/mint.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "Mint" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
proof/opcodes.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "Opcodes" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
proof/set_v1.zk

@@ -6,6 +6,7 @@
 
 # 2 ** k is the maximum nubmer of rows in the circuit.
 k = 11;
+field = "pallas";
 
 # Section to declare constants used in the circuit.
 # "Set_V1" is the namepsace of circuit. 

+ 1 - 0
proof/tx.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "tx" {
          EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
proof/voting.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "Vote" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
script/research/rln/signal.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "RlnSignal" {}
 

+ 1 - 0
script/research/rln/slash.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "RlnSlash" {}
 

+ 1 - 0
src/contract/consensus/proof/consensus_burn_v1.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "ConsensusBurn_V1" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
src/contract/consensus/proof/consensus_mint_v1.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "ConsensusMint_V1" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
src/contract/consensus/proof/consensus_proposal_v1.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "ConsensusProposal_V1" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
src/contract/dao/proof/dao-exec.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "DaoExec" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
src/contract/dao/proof/dao-mint.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "DaoMint" {
 	EcFixedPoint VALUE_COMMIT_RANDOM,

+ 1 - 0
src/contract/dao/proof/dao-propose-burn.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "DaoProposeInput" {
 	EcFixedPointBase NULLIFIER_K,

+ 1 - 0
src/contract/dao/proof/dao-propose-main.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "DaoProposeMain" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 1 - 0
src/contract/dao/proof/dao-vote-burn.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "DaoVoteInput" {
 	EcFixedPointBase NULLIFIER_K,

+ 1 - 0
src/contract/dao/proof/dao-vote-main.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "DaoVoteMain" {
 	EcFixedPoint VALUE_COMMIT_RANDOM,

+ 1 - 0
src/contract/deployooor/proof/derive_contract_id.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "DeriveContractID" {
 	EcFixedPointBase NULLIFIER_K,

+ 1 - 0
src/contract/money/proof/burn_v1.zk

@@ -1,5 +1,6 @@
 # The k parameter defining the number of rows used in our circuit (2^k)
 k = 13;
+field = "pallas";
 
 # The constants we define for our circuit
 constant "Burn_V1" {

+ 1 - 0
src/contract/money/proof/mint_v1.zk

@@ -1,5 +1,6 @@
 # The k parameter defining the number of rows used in our circuit (2^k)
 k = 13;
+field = "pallas";
 
 # The constants we define for our circuit
 constant "Mint_V1" {

+ 1 - 0
src/contract/money/proof/token_freeze_v1.zk

@@ -1,4 +1,5 @@
 k = 13;
+field = "pallas";
 
 constant "TokenFreeze_V1" {
 	EcFixedPointBase NULLIFIER_K,

+ 1 - 1
src/contract/money/proof/token_mint_v1.zk

@@ -1,6 +1,6 @@
 # Circuit used to mint arbitrary coins given a mint authority secret.
-
 k = 13;
+field = "pallas";
 
 constant "TokenMint_V1" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,

+ 3 - 0
src/zkas/constants.rs

@@ -21,3 +21,6 @@ pub const MAX_K: u32 = 16;
 
 /// Maximum allowed namespace length in bytes
 pub const MAX_NS_LEN: usize = 32;
+
+/// Allowed fields for proofs
+pub const ALLOWED_FIELDS: [&str; 1] = ["pallas"];

+ 46 - 5
src/zkas/parser.rs

@@ -22,7 +22,7 @@ use itertools::Itertools;
 
 use super::{
     ast::{Arg, Constant, Literal, Statement, StatementType, Variable, Witness},
-    constants::{MAX_K, MAX_NS_LEN},
+    constants::{ALLOWED_FIELDS, MAX_K, MAX_NS_LEN},
     error::ErrorEmitter,
     lexer::{Token, TokenType},
     LitType, Opcode, VarType,
@@ -30,7 +30,7 @@ use super::{
 
 /// zkas language builtin keywords.
 /// These can not be used anywhere except where they are expected.
-const KEYWORDS: [&str; 4] = ["k", "constant", "witness", "circuit"];
+const KEYWORDS: [&str; 5] = ["k", "field", "constant", "witness", "circuit"];
 
 /// Forbidden namespaces
 const NOPE_NS: [&str; 4] = [".constant", ".literal", ".witness", ".circuit"];
@@ -145,16 +145,57 @@ impl Parser {
             number.token_type != TokenType::Number ||
             semicolon.token_type != TokenType::Semicolon
         {
-            self.error.abort("Source file does not start with k=n;", 0, 0);
+            self.error.abort("Source file does not start with k=n;", k.line, k.column);
         }
 
         if k.token != "k" {
-            self.error.abort("Source file does not start with k=n;", 0, 0);
+            self.error.abort("Source file does not start with k=n;", k.line, k.column);
         }
 
         let declared_k = number.token.parse().unwrap();
         if declared_k > MAX_K {
-            self.error.abort(&format!("k param is too high, max allowed is {}", MAX_K), 0, 0);
+            self.error.abort(
+                &format!("k param is too high, max allowed is {}", MAX_K),
+                number.line,
+                number.column,
+            );
+        }
+
+        // Then we declare the field we're working in.
+        let Some((field, equal, field_name, semicolon)) = iter.next_tuple() else {
+            self.error.abort("Source file does not declare field after k", k.line, k.column);
+            unreachable!();
+        };
+
+        if field.token_type != TokenType::Symbol ||
+            equal.token_type != TokenType::Assign ||
+            field_name.token_type != TokenType::String ||
+            semicolon.token_type != TokenType::Semicolon
+        {
+            self.error.abort(
+                "Source file does not declare field after k",
+                field.line,
+                field.column,
+            );
+        }
+
+        if field.token != "field" {
+            self.error.abort(
+                "Source file does not declare field after k",
+                field.line,
+                field.column,
+            );
+        }
+
+        if !ALLOWED_FIELDS.contains(&field_name.token.as_str()) {
+            self.error.abort(
+                &format!(
+                    "Declared field \"{}\" is not supported. Use any of: {:?}",
+                    field_name.token, ALLOWED_FIELDS
+                ),
+                field_name.line,
+                field_name.column,
+            );
         }
 
         while let Some(t) = iter.next() {