Browse Source

zkas: Add more opcodes and rework a few functions.

Luther Blissett 4 years ago
parent
commit
6dfafe7f2f
2 changed files with 115 additions and 75 deletions
  1. 87 48
      src/zkas/opcode.rs
  2. 28 27
      src/zkas/types.rs

+ 87 - 48
src/zkas/opcode.rs

@@ -1,20 +1,23 @@
-use super::types::Type;
+use super::VarType;
 
 
-/// Opcodes supported by the VM
+/// Opcodes supported by the zkas VM
 #[derive(Copy, Clone, Debug)]
 #[derive(Copy, Clone, Debug)]
 #[repr(u8)]
 #[repr(u8)]
 pub enum Opcode {
 pub enum Opcode {
+    /// Intermediate opcode for the compiler, should never appear in the result
+    Noop = 0x00,
+
     /// Elliptic curve addition
     /// Elliptic curve addition
-    EcAdd = 0x00,
+    EcAdd = 0x01,
 
 
-    /// Elliptic curve multiplication
-    EcMul = 0x01,
+    // Elliptic curve multiplication
+    EcMul = 0x02,
 
 
     /// Elliptic curve multiplication with a Base field element
     /// Elliptic curve multiplication with a Base field element
-    EcMulBase = 0x02,
+    EcMulBase = 0x03,
 
 
-    /// Elliptic curve multiplication with a u64 wrapped in a Scalar element
-    EcMulShort = 0x03,
+    /// Elliptic curve multiplication with a Base field element of 64bit width
+    EcMulShort = 0x04,
 
 
     /// Get the x coordinate of an elliptic curve point
     /// Get the x coordinate of an elliptic curve point
     EcGetX = 0x08,
     EcGetX = 0x08,
@@ -22,11 +25,11 @@ pub enum Opcode {
     /// Get the y coordinate of an elliptic curve point
     /// Get the y coordinate of an elliptic curve point
     EcGetY = 0x09,
     EcGetY = 0x09,
 
 
-    /// Poseidon hash of N elements
+    /// Poseidon hash of N Base field elements
     PoseidonHash = 0x10,
     PoseidonHash = 0x10,
 
 
-    /// Calculate merkle root  given a position, Merkle path, and an element
-    CalculateMerkleRoot = 0x20,
+    /// Calculate Merkle root, given a position, Merkle path, and an element
+    MerkleRoot = 0x20,
 
 
     /// Base field element addition
     /// Base field element addition
     BaseAdd = 0x30,
     BaseAdd = 0x30,
@@ -37,52 +40,88 @@ pub enum Opcode {
     /// Base field element subtraction
     /// Base field element subtraction
     BaseSub = 0x32,
     BaseSub = 0x32,
 
 
+    /// Witness an unsigned integer into a Base field element
+    WitnessBase = 0x40,
+
+    /// Range check a Base field element, given bit-width (up to 253)
+    RangeCheck = 0x50,
+
+    /// Compare two Base field elements and see if a is less than b
+    LessThan = 0x51,
+
     /// Constrain a Base field element to a circuit's public input
     /// Constrain a Base field element to a circuit's public input
     ConstrainInstance = 0xf0,
     ConstrainInstance = 0xf0,
 
 
-    /// Intermediate opcode for the compiler, should never appear in the result
-    Noop = 0xff,
+    /// Debug a variable's value in the ZK circuit table.
+    DebugPrint = 0xff,
 }
 }
 
 
 impl Opcode {
 impl Opcode {
-    /// Return a tuple of vectors of types that are accepted by a specific opcode
-    /// `r.0` is the return type(s) and `r.1` is the argument type(s).
-    pub fn arg_types(&self) -> (Vec<Type>, Vec<Type>) {
-        match self {
-            // (return_type, opcode_arg_types)
-            Opcode::EcAdd => (vec![Type::EcPoint], vec![Type::EcPoint, Type::EcPoint]),
-            Opcode::EcMul => (vec![Type::EcPoint], vec![Type::Scalar, Type::EcFixedPoint]),
-            Opcode::EcMulBase => (vec![Type::EcPoint], vec![Type::Base, Type::EcFixedPointBase]),
-            Opcode::EcMulShort => (vec![Type::EcPoint], vec![Type::Base, Type::EcFixedPointShort]),
-            Opcode::EcGetX => (vec![Type::Base], vec![Type::EcPoint]),
-            Opcode::EcGetY => (vec![Type::Base], vec![Type::EcPoint]),
-            Opcode::PoseidonHash => (vec![Type::Base], vec![Type::BaseArray]),
-            Opcode::CalculateMerkleRoot => {
-                (vec![Type::Base], vec![Type::Uint32, Type::MerklePath, Type::Base])
-            }
-            Opcode::BaseAdd => (vec![Type::Base], vec![Type::Base, Type::Base]),
-            Opcode::BaseMul => (vec![Type::Base], vec![Type::Base, Type::Base]),
-            Opcode::BaseSub => (vec![Type::Base], vec![Type::Base, Type::Base]),
-            Opcode::ConstrainInstance => (vec![], vec![Type::Base]),
-            Opcode::Noop => (vec![], vec![]),
+    pub fn from_name(n: &str) -> Option<Self> {
+        match n {
+            "ec_add" => Some(Self::EcAdd),
+            "ec_mul" => Some(Self::EcMul),
+            "ec_mul_base" => Some(Self::EcMulBase),
+            "ec_mul_short" => Some(Self::EcMulShort),
+            "ec_get_x" => Some(Self::EcGetX),
+            "ec_get_y" => Some(Self::EcGetY),
+            "poseidon_hash" => Some(Self::PoseidonHash),
+            "merkle_root" => Some(Self::MerkleRoot),
+            "base_add" => Some(Self::BaseAdd),
+            "base_mul" => Some(Self::BaseMul),
+            "base_sub" => Some(Self::BaseSub),
+            "witness_base" => Some(Self::WitnessBase),
+            "range_check" => Some(Self::RangeCheck),
+            "less_than" => Some(Self::LessThan),
+            "constrain_instance" => Some(Self::ConstrainInstance),
+            "debug" => Some(Self::DebugPrint),
+            _ => None,
         }
         }
     }
     }
 
 
-    pub fn from_repr(b: u8) -> Self {
-        match b {
-            0x00 => Self::EcAdd,
-            0x01 => Self::EcMul,
-            0x02 => Self::EcMulBase,
-            0x03 => Self::EcMulShort,
-            0x08 => Self::EcGetX,
-            0x09 => Self::EcGetY,
-            0x10 => Self::PoseidonHash,
-            0x20 => Self::CalculateMerkleRoot,
-            0x30 => Self::BaseAdd,
-            0x31 => Self::BaseMul,
-            0x32 => Self::BaseSub,
-            0xf0 => Self::ConstrainInstance,
-            _ => unimplemented!(),
+    /// Return a tuple of vectors of types that are accepted by a specific opcode.
+    /// `r.0` is the return type(s), and `r.1` is the argument type(s).
+    pub fn arg_types(&self) -> (Vec<VarType>, Vec<VarType>) {
+        match self {
+            Opcode::Noop => (vec![], vec![]),
+
+            Opcode::EcAdd => (vec![VarType::EcPoint], vec![VarType::EcPoint, VarType::EcPoint]),
+
+            Opcode::EcMul => (vec![VarType::EcPoint], vec![VarType::Scalar, VarType::EcFixedPoint]),
+
+            Opcode::EcMulBase => {
+                (vec![VarType::EcPoint], vec![VarType::Base, VarType::EcFixedPointBase])
+            }
+
+            Opcode::EcMulShort => {
+                (vec![VarType::EcPoint], vec![VarType::Base, VarType::EcFixedPointShort])
+            }
+
+            Opcode::EcGetX => (vec![VarType::Base], vec![VarType::EcPoint]),
+
+            Opcode::EcGetY => (vec![VarType::Base], vec![VarType::EcPoint]),
+
+            Opcode::PoseidonHash => (vec![VarType::Base], vec![VarType::BaseArray]),
+
+            Opcode::MerkleRoot => {
+                (vec![VarType::Base], vec![VarType::Uint32, VarType::MerklePath, VarType::Base])
+            }
+
+            Opcode::BaseAdd => (vec![VarType::Base], vec![VarType::Base]),
+
+            Opcode::BaseMul => (vec![VarType::Base], vec![VarType::Base]),
+
+            Opcode::BaseSub => (vec![VarType::Base], vec![VarType::Base]),
+
+            Opcode::WitnessBase => (vec![VarType::Base], vec![VarType::Uint64]),
+
+            Opcode::RangeCheck => (vec![], vec![VarType::Uint64, VarType::Base]),
+
+            Opcode::LessThan => (vec![], vec![VarType::Base, VarType::Base]),
+
+            Opcode::ConstrainInstance => (vec![], vec![VarType::Base]),
+
+            Opcode::DebugPrint => (vec![], vec![]),
         }
         }
     }
     }
 }
 }

+ 28 - 27
src/zkas/types.rs

@@ -1,32 +1,35 @@
-/// Types supported by the VM
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+/// Varable types supported by the zkas VM
+#[derive(Copy, Clone, PartialEq, Debug)]
 #[repr(u8)]
 #[repr(u8)]
-pub enum Type {
+pub enum VarType {
+    /// Dummy intermediate type
+    Dummy = 0x00,
+
     /// Elliptic curve point
     /// Elliptic curve point
-    EcPoint = 0x00,
+    EcPoint = 0x01,
 
 
     /// Elliptic curve fixed point (a constant)
     /// Elliptic curve fixed point (a constant)
-    EcFixedPoint = 0x01,
+    EcFixedPoint = 0x02,
 
 
     /// Elliptic curve fixed point short
     /// Elliptic curve fixed point short
-    EcFixedPointShort = 0x02,
+    EcFixedPointShort = 0x03,
 
 
     /// Elliptic curve fixed point in base field
     /// Elliptic curve fixed point in base field
-    EcFixedPointBase = 0x03,
+    EcFixedPointBase = 0x04,
 
 
     /// Base field element
     /// Base field element
     Base = 0x10,
     Base = 0x10,
 
 
-    /// Array of Base field elements
+    /// Base field element array
     BaseArray = 0x11,
     BaseArray = 0x11,
 
 
     /// Scalar field element
     /// Scalar field element
     Scalar = 0x12,
     Scalar = 0x12,
 
 
-    /// Array of Scalar field elements
+    /// Scalar field element array
     ScalarArray = 0x13,
     ScalarArray = 0x13,
 
 
-    /// A Merkle path
+    /// A Merkle tree path
     MerklePath = 0x20,
     MerklePath = 0x20,
 
 
     /// Unsigned 32-bit integer
     /// Unsigned 32-bit integer
@@ -34,26 +37,24 @@ pub enum Type {
 
 
     /// Unsigned 64-bit integer
     /// Unsigned 64-bit integer
     Uint64 = 0x31,
     Uint64 = 0x31,
+}
 
 
-    /// Intermediate type, should never appear in the result
-    Dummy = 0xff,
+/// Literal types supported by the zkas VM
+#[derive(Copy, Clone, PartialEq, Debug)]
+#[repr(u8)]
+pub enum LitType {
+    /// Dummy intermediate type
+    Dummy = 0x00,
+
+    /// Unsigned 64-bit integer
+    Uint64 = 0x01,
 }
 }
 
 
-impl Type {
-    pub fn from_repr(b: u8) -> Self {
-        match b {
-            0x00 => Self::EcPoint,
-            0x01 => Self::EcFixedPoint,
-            0x02 => Self::EcFixedPointShort,
-            0x03 => Self::EcFixedPointBase,
-            0x10 => Self::Base,
-            0x11 => Self::BaseArray,
-            0x12 => Self::Scalar,
-            0x13 => Self::ScalarArray,
-            0x20 => Self::MerklePath,
-            0x30 => Self::Uint32,
-            0x31 => Self::Uint64,
-            _ => unimplemented!(),
+impl LitType {
+    pub fn to_vartype(&self) -> VarType {
+        match self {
+            Self::Dummy => VarType::Dummy,
+            Self::Uint64 => VarType::Uint64,
         }
         }
     }
     }
 }
 }