opcode.rs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use super::VarType;
  19. /// Opcodes supported by the zkas VM
  20. #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
  21. #[repr(u8)]
  22. pub enum Opcode {
  23. /// Intermediate opcode for the compiler, should never appear in the result
  24. Noop = 0x00,
  25. /// Elliptic curve addition
  26. EcAdd = 0x01,
  27. /// Elliptic curve multiplication
  28. EcMul = 0x02,
  29. /// Elliptic curve multiplication with a Base field element
  30. EcMulBase = 0x03,
  31. /// Elliptic curve multiplication with a Base field element of 64bit width
  32. EcMulShort = 0x04,
  33. /// Variable Elliptic curve multiplication with a Base field element
  34. EcMulVarBase = 0x05,
  35. /// Get the x coordinate of an elliptic curve point
  36. EcGetX = 0x08,
  37. /// Get the y coordinate of an elliptic curve point
  38. EcGetY = 0x09,
  39. /// Poseidon hash of N Base field elements
  40. PoseidonHash = 0x10,
  41. /// Calculate Merkle root, given a position, Merkle path, and an element
  42. MerkleRoot = 0x20,
  43. /// Calculate sparse Merkle root, given the position, path and a member
  44. SparseMerkleRoot = 0x21,
  45. /// Base field element addition
  46. BaseAdd = 0x30,
  47. /// Base field element multiplication
  48. BaseMul = 0x31,
  49. /// Base field element subtraction
  50. BaseSub = 0x32,
  51. /// Witness an unsigned integer into a Base field element
  52. WitnessBase = 0x40,
  53. /// Range check a Base field element, given bit-width (up to 253)
  54. RangeCheck = 0x50,
  55. /// Strictly compare two Base field elements and see if a is less than b
  56. /// This enforces the sum of remaining bits to be zero.
  57. LessThanStrict = 0x51,
  58. /// Loosely two Base field elements and see if a is less than b
  59. /// This does not enforce the sum of remaining bits to be zero.
  60. LessThanLoose = 0x52,
  61. /// Check if a field element fits in a boolean (Either 0 or 1)
  62. BoolCheck = 0x53,
  63. /// Conditionally select between two base field elements given a boolean
  64. CondSelect = 0x60,
  65. /// Conditionally select between a and b (return a if a is zero, and b if a is nonzero)
  66. ZeroCondSelect = 0x61,
  67. /// Constrain equality of two Base field elements inside the circuit
  68. ConstrainEqualBase = 0xe0,
  69. /// Constrain equality of two EcPoint elements inside the circuit
  70. ConstrainEqualPoint = 0xe1,
  71. /// Constrain a Base field element to a circuit's public input
  72. ConstrainInstance = 0xf0,
  73. /// Debug a variable's value in the ZK circuit table.
  74. DebugPrint = 0xff,
  75. }
  76. impl Opcode {
  77. pub fn from_name(n: &str) -> Option<Self> {
  78. match n {
  79. "ec_add" => Some(Self::EcAdd),
  80. "ec_mul" => Some(Self::EcMul),
  81. "ec_mul_base" => Some(Self::EcMulBase),
  82. "ec_mul_short" => Some(Self::EcMulShort),
  83. "ec_mul_var_base" => Some(Self::EcMulVarBase),
  84. "ec_get_x" => Some(Self::EcGetX),
  85. "ec_get_y" => Some(Self::EcGetY),
  86. "poseidon_hash" => Some(Self::PoseidonHash),
  87. "merkle_root" => Some(Self::MerkleRoot),
  88. "sparse_merkle_root" => Some(Self::SparseMerkleRoot),
  89. "base_add" => Some(Self::BaseAdd),
  90. "base_mul" => Some(Self::BaseMul),
  91. "base_sub" => Some(Self::BaseSub),
  92. "witness_base" => Some(Self::WitnessBase),
  93. "range_check" => Some(Self::RangeCheck),
  94. "less_than_strict" => Some(Self::LessThanStrict),
  95. "less_than_loose" => Some(Self::LessThanLoose),
  96. "bool_check" => Some(Self::BoolCheck),
  97. "cond_select" => Some(Self::CondSelect),
  98. "zero_cond" => Some(Self::ZeroCondSelect),
  99. "constrain_equal_base" => Some(Self::ConstrainEqualBase),
  100. "constrain_equal_point" => Some(Self::ConstrainEqualPoint),
  101. "constrain_instance" => Some(Self::ConstrainInstance),
  102. "debug" => Some(Self::DebugPrint),
  103. _ => None,
  104. }
  105. }
  106. pub fn from_repr(b: u8) -> Option<Self> {
  107. match b {
  108. 0x01 => Some(Self::EcAdd),
  109. 0x02 => Some(Self::EcMul),
  110. 0x03 => Some(Self::EcMulBase),
  111. 0x04 => Some(Self::EcMulShort),
  112. 0x05 => Some(Self::EcMulVarBase),
  113. 0x08 => Some(Self::EcGetX),
  114. 0x09 => Some(Self::EcGetY),
  115. 0x10 => Some(Self::PoseidonHash),
  116. 0x20 => Some(Self::MerkleRoot),
  117. 0x21 => Some(Self::SparseMerkleRoot),
  118. 0x30 => Some(Self::BaseAdd),
  119. 0x31 => Some(Self::BaseMul),
  120. 0x32 => Some(Self::BaseSub),
  121. 0x40 => Some(Self::WitnessBase),
  122. 0x50 => Some(Self::RangeCheck),
  123. 0x51 => Some(Self::LessThanStrict),
  124. 0x52 => Some(Self::LessThanLoose),
  125. 0x53 => Some(Self::BoolCheck),
  126. 0x60 => Some(Self::CondSelect),
  127. 0x61 => Some(Self::ZeroCondSelect),
  128. 0xe0 => Some(Self::ConstrainEqualBase),
  129. 0xe1 => Some(Self::ConstrainEqualPoint),
  130. 0xf0 => Some(Self::ConstrainInstance),
  131. 0xff => Some(Self::DebugPrint),
  132. _ => None,
  133. }
  134. }
  135. pub fn name(&self) -> &str {
  136. match self {
  137. Self::Noop => "noop",
  138. Self::EcAdd => "ec_add",
  139. Self::EcMul => "ec_mul",
  140. Self::EcMulBase => "ec_mul_base",
  141. Self::EcMulShort => "ec_mul_short",
  142. Self::EcMulVarBase => "ec_mul_var_base",
  143. Self::EcGetX => "ec_get_x",
  144. Self::EcGetY => "ec_get_y",
  145. Self::PoseidonHash => "poseidon_hash",
  146. Self::MerkleRoot => "merkle_root",
  147. Self::SparseMerkleRoot => "sparse_merkle_root",
  148. Self::BaseAdd => "base_add",
  149. Self::BaseMul => "base_mul",
  150. Self::BaseSub => "base_sub",
  151. Self::WitnessBase => "witness_base",
  152. Self::RangeCheck => "range_check",
  153. Self::LessThanStrict => "less_than_strict",
  154. Self::LessThanLoose => "less_than_loose",
  155. Self::BoolCheck => "bool_check",
  156. Self::CondSelect => "cond_select",
  157. Self::ZeroCondSelect => "zero_cond",
  158. Self::ConstrainEqualBase => "constrain_equal_base",
  159. Self::ConstrainEqualPoint => "constrain_equal_point",
  160. Self::ConstrainInstance => "constrain_instance",
  161. Self::DebugPrint => "debug",
  162. }
  163. }
  164. /// Return a tuple of vectors of types that are accepted by a specific opcode.
  165. /// `r.0` is the return type(s), and `r.1` is the argument type(s).
  166. pub fn arg_types(&self) -> (Vec<VarType>, Vec<VarType>) {
  167. match self {
  168. Opcode::Noop => (vec![], vec![]),
  169. Opcode::EcAdd => (vec![VarType::EcPoint], vec![VarType::EcPoint, VarType::EcPoint]),
  170. Opcode::EcMul => (vec![VarType::EcPoint], vec![VarType::Scalar, VarType::EcFixedPoint]),
  171. Opcode::EcMulBase => {
  172. (vec![VarType::EcPoint], vec![VarType::Base, VarType::EcFixedPointBase])
  173. }
  174. Opcode::EcMulShort => {
  175. (vec![VarType::EcPoint], vec![VarType::Base, VarType::EcFixedPointShort])
  176. }
  177. Opcode::EcMulVarBase => {
  178. (vec![VarType::EcPoint], vec![VarType::Base, VarType::EcNiPoint])
  179. }
  180. Opcode::EcGetX => (vec![VarType::Base], vec![VarType::EcPoint]),
  181. Opcode::EcGetY => (vec![VarType::Base], vec![VarType::EcPoint]),
  182. Opcode::PoseidonHash => (vec![VarType::Base], vec![VarType::BaseArray]),
  183. Opcode::MerkleRoot => {
  184. (vec![VarType::Base], vec![VarType::Uint32, VarType::MerklePath, VarType::Base])
  185. }
  186. Opcode::SparseMerkleRoot => {
  187. (vec![VarType::Base], vec![VarType::Base, VarType::SparseMerklePath, VarType::Base])
  188. }
  189. Opcode::BaseAdd => (vec![VarType::Base], vec![VarType::Base, VarType::Base]),
  190. Opcode::BaseMul => (vec![VarType::Base], vec![VarType::Base, VarType::Base]),
  191. Opcode::BaseSub => (vec![VarType::Base], vec![VarType::Base, VarType::Base]),
  192. Opcode::WitnessBase => (vec![VarType::Base], vec![VarType::Uint64]),
  193. Opcode::RangeCheck => (vec![], vec![VarType::Uint64, VarType::Base]),
  194. Opcode::LessThanStrict => (vec![], vec![VarType::Base, VarType::Base]),
  195. Opcode::LessThanLoose => (vec![], vec![VarType::Base, VarType::Base]),
  196. Opcode::BoolCheck => (vec![], vec![VarType::Base]),
  197. Opcode::CondSelect => {
  198. (vec![VarType::Base], vec![VarType::Base, VarType::Base, VarType::Base])
  199. }
  200. Opcode::ZeroCondSelect => (vec![VarType::Base], vec![VarType::Base, VarType::Base]),
  201. Opcode::ConstrainEqualBase => (vec![], vec![VarType::Base, VarType::Base]),
  202. Opcode::ConstrainEqualPoint => (vec![], vec![VarType::EcPoint, VarType::EcPoint]),
  203. Opcode::ConstrainInstance => (vec![], vec![VarType::Base]),
  204. Opcode::DebugPrint => (vec![], vec![VarType::Any]),
  205. }
  206. }
  207. }