Bläddra i källkod

not small order

narodnik 5 år sedan
förälder
incheckning
945789c182
3 ändrade filer med 73 tillägg och 15 borttagningar
  1. 60 15
      proofs/mint2.psm
  2. 1 0
      scripts/vm.py
  3. 12 0
      src/vm.rs

+ 60 - 15
proofs/mint2.psm

@@ -2,6 +2,9 @@ constant edwards_d 0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d63
 constant one 0x0000000000000000000000000000000000000000000000000000000000000001
 constant one 0x0000000000000000000000000000000000000000000000000000000000000001
 
 
 {% macro square(x2, x) %}
 {% macro square(x2, x) %}
+    ########################################################
+    # square({{x2}}, {{x}})
+    ########################################################
     private {{x2}}
     private {{x2}}
     set {{x2}} {{x}}
     set {{x2}} {{x}}
     mul {{x2}} {{x}}
     mul {{x2}} {{x}}
@@ -13,6 +16,9 @@ constant one 0x0000000000000000000000000000000000000000000000000000000000000001
 {% endmacro %}
 {% endmacro %}
 
 
 {% macro jubjub_witness(p, u, v) %}
 {% macro jubjub_witness(p, u, v) %}
+    ########################################################
+    # jubjub_witness({{p}}, {{u}}, {{v}})
+    ########################################################
     # -u^2 + v^2 = 1 + du^2v^2
     # -u^2 + v^2 = 1 + du^2v^2
     {{ square(p + "_u2", u) }}
     {{ square(p + "_u2", u) }}
     {{ square(p + "_v2", v) }}
     {{ square(p + "_v2", v) }}
@@ -29,6 +35,10 @@ constant one 0x0000000000000000000000000000000000000000000000000000000000000001
 {% endmacro %}
 {% endmacro %}
 
 
 {% macro jubjub_double(p, u, v) %}
 {% macro jubjub_double(p, u, v) %}
+    ########################################################
+    # jubjub_double({{p}}, {{u}}, {{v}})
+    ########################################################
+
     # Compute T = (u + v) * (v - EDWARDS_A*u)
     # Compute T = (u + v) * (v - EDWARDS_A*u)
     #           = (u + v) * (u + v)
     #           = (u + v) * (u + v)
     private {{p}}_t
     private {{p}}_t
@@ -100,24 +110,59 @@ constant one 0x0000000000000000000000000000000000000000000000000000000000000001
     enforce
     enforce
 {% endmacro %}
 {% endmacro %}
 
 
+{% macro assert_not_small_order(p, u, v) %}
+    ########################################################
+    # assert_not_small_order({{p}}, {{u}}, {{v}})
+    ########################################################
+
+    # First doubling
+    {{ jubjub_double(p + "1", u, v) }}
+    # Second doubling
+    {{ jubjub_double(p + "2", p + "1_u", p + "1_v") }}
+    # Third doubling
+    {{ jubjub_double(p + "3", p + "2_u", p + "2_v") }}
+
+    # (0, -1) is a small order point, but won't ever appear here
+    # because cofactor is 2^3, and we performed three doublings.
+    # (0, 1) is the neutral element, so checking if u is nonzero
+    # is sufficient to prevent small order points here.
+
+    # Check u != 0
+
+    # Constrain a * inv = 1, which is only valid
+    # iff a has a multiplicative inverse, untrue
+    # for zero.
+    private {{p}}_u3_inv
+    set {{p}}_u3_inv {{p}}3_u
+    invert {{p}}_u3_inv
+
+    lc0_add {{p}}3_u
+    lc1_add {{p}}_u3_inv
+    lc2_add_one
+    enforce
+{% endmacro %}
+
 contract mint_contract
 contract mint_contract
     param public_u
     param public_u
     param public_v
     param public_v
     {{ jubjub_witness("public", "public_u", "public_v") }}
     {{ jubjub_witness("public", "public_u", "public_v") }}
-    {{ jubjub_double("pub_dbl", "public_u", "public_v") }}
-
-    # Use this code for testing point doubling
-    #public dbl_u
-    #set dbl_u pub_dbl_u
-    #lc0_add dbl_u
-    #lc1_add_one
-    #lc2_add pub_dbl_u
-    #enforce
-    #public dbl_v
-    #set dbl_v pub_dbl_v
-    #lc0_add dbl_v
-    #lc1_add_one
-    #lc2_add pub_dbl_v
-    #enforce
+    {{ assert_not_small_order("not_small", "public_u", "public_v") }}
+    {#
+        {{ jubjub_double("pub_dbl", "public_u", "public_v") }}
+
+        # Use this code for testing point doubling
+        #public dbl_u
+        #set dbl_u pub_dbl_u
+        #lc0_add dbl_u
+        #lc1_add_one
+        #lc2_add pub_dbl_u
+        #enforce
+        #public dbl_v
+        #set dbl_v pub_dbl_v
+        #lc0_add dbl_v
+        #lc1_add_one
+        #lc2_add pub_dbl_v
+        #enforce
+    #}
 end
 end
 
 

+ 1 - 0
scripts/vm.py

@@ -16,6 +16,7 @@ op_commands = {
     "divide": 2,
     "divide": 2,
     "double": 1,
     "double": 1,
     "square": 1,
     "square": 1,
+    "invert": 1,
     "unpack_bits": 3,
     "unpack_bits": 3,
     "load": 2,
     "load": 2,
     "local": 1,
     "local": 1,

+ 12 - 0
src/vm.rs

@@ -39,6 +39,7 @@ pub enum CryptoOperation {
     Divide(VariableRef, VariableRef),
     Divide(VariableRef, VariableRef),
     Double(VariableRef),
     Double(VariableRef),
     Square(VariableRef),
     Square(VariableRef),
+    Invert(VariableRef),
     UnpackBits(VariableRef, VariableRef, VariableRef),
     UnpackBits(VariableRef, VariableRef, VariableRef),
     Local,
     Local,
 }
 }
@@ -176,6 +177,17 @@ impl ZKVirtualMachine {
                     };
                     };
                     *self_ = self_.square();
                     *self_ = self_.square();
                 }
                 }
+                CryptoOperation::Invert(self_) => {
+                    let self_ = match self_ {
+                        VariableRef::Aux(index) => &mut self.aux[*index],
+                        VariableRef::Local(index) => &mut local_stack[*index],
+                    };
+                    if self_.is_zero() {
+                        return Err(ZKVMError::DivisionByZero);
+                    } else {
+                        *self_ = self_.invert().unwrap();
+                    }
+                }
                 CryptoOperation::UnpackBits(value, start, end) => {
                 CryptoOperation::UnpackBits(value, start, end) => {
                     let value = match value {
                     let value = match value {
                         VariableRef::Aux(index) => self.aux[*index].clone(),
                         VariableRef::Aux(index) => self.aux[*index].clone(),