decoder.rs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2023 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 darkfi_serial::{deserialize_partial, VarInt};
  19. use super::{compiler::MAGIC_BYTES, types::StackType, LitType, Opcode, VarType};
  20. use crate::{Error::ZkasDecoderError as ZkasErr, Result};
  21. /// A ZkBinary decoded from compiled zkas code.
  22. /// This is used by the zkvm.
  23. #[derive(Clone, Debug)]
  24. pub struct ZkBinary {
  25. pub namespace: String,
  26. pub constants: Vec<(VarType, String)>,
  27. pub literals: Vec<(LitType, String)>,
  28. pub witnesses: Vec<VarType>,
  29. pub opcodes: Vec<(Opcode, Vec<(StackType, usize)>)>,
  30. }
  31. // https://stackoverflow.com/questions/35901547/how-can-i-find-a-subsequence-in-a-u8-slice
  32. fn find_subslice(haystack: &[u8], needle: &[u8]) -> Option<usize> {
  33. haystack.windows(needle.len()).position(|window| window == needle)
  34. }
  35. impl ZkBinary {
  36. pub fn decode(bytes: &[u8]) -> Result<Self> {
  37. let magic_bytes = &bytes[0..4];
  38. if magic_bytes != MAGIC_BYTES {
  39. return Err(ZkasErr("Magic bytes are incorrect.".to_string()))
  40. }
  41. let _binary_version = &bytes[4];
  42. // After the binary version, we're supposed to have the contract namespace
  43. let (namespace, _) = deserialize_partial(&bytes[5..])?;
  44. let constants_offset = match find_subslice(bytes, b".constant") {
  45. Some(v) => v,
  46. None => return Err(ZkasErr("Could not find .constant section".to_string())),
  47. };
  48. let literals_offset = match find_subslice(bytes, b".literal") {
  49. Some(v) => v,
  50. None => return Err(ZkasErr("Could not find .literal section".to_string())),
  51. };
  52. let contract_offset = match find_subslice(bytes, b".contract") {
  53. Some(v) => v,
  54. None => return Err(ZkasErr("Could not find .contract section".to_string())),
  55. };
  56. let circuit_offset = match find_subslice(bytes, b".circuit") {
  57. Some(v) => v,
  58. None => return Err(ZkasErr("Could not find .circuit section".to_string())),
  59. };
  60. let debug_offset = match find_subslice(bytes, b".debug") {
  61. Some(v) => v,
  62. None => bytes.len(),
  63. };
  64. if constants_offset > literals_offset {
  65. return Err(ZkasErr(".literal section appeared before .constant".to_string()))
  66. }
  67. if literals_offset > contract_offset {
  68. return Err(ZkasErr(".contract section appeared before .literal".to_string()))
  69. }
  70. if contract_offset > circuit_offset {
  71. return Err(ZkasErr(".circuit section appeared before .contract".to_string()))
  72. }
  73. if circuit_offset > debug_offset {
  74. return Err(ZkasErr(".debug section appeared before .circuit or EOF".to_string()))
  75. }
  76. let constants_section = &bytes[constants_offset + b".constant".len()..literals_offset];
  77. let literals_section = &bytes[literals_offset + b".literal".len()..contract_offset];
  78. let contract_section = &bytes[contract_offset + b".contract".len()..circuit_offset];
  79. let circuit_section = &bytes[circuit_offset + b".circuit".len()..debug_offset];
  80. let constants = ZkBinary::parse_constants(constants_section)?;
  81. let literals = ZkBinary::parse_literals(literals_section)?;
  82. let witnesses = ZkBinary::parse_contract(contract_section)?;
  83. let opcodes = ZkBinary::parse_circuit(circuit_section)?;
  84. // TODO: Debug info
  85. Ok(Self { namespace, constants, literals, witnesses, opcodes })
  86. }
  87. fn parse_constants(bytes: &[u8]) -> Result<Vec<(VarType, String)>> {
  88. let mut constants = vec![];
  89. let mut iter_offset = 0;
  90. while iter_offset < bytes.len() {
  91. let c_type = match VarType::from_repr(bytes[iter_offset]) {
  92. Some(v) => v,
  93. None => {
  94. return Err(ZkasErr(format!(
  95. "Could not decode constant VarType from {}",
  96. bytes[iter_offset],
  97. )))
  98. }
  99. };
  100. iter_offset += 1;
  101. let (name, offset) = deserialize_partial::<String>(&bytes[iter_offset..])?;
  102. iter_offset += offset;
  103. constants.push((c_type, name));
  104. }
  105. Ok(constants)
  106. }
  107. fn parse_literals(bytes: &[u8]) -> Result<Vec<(LitType, String)>> {
  108. let mut literals = vec![];
  109. let mut iter_offset = 0;
  110. while iter_offset < bytes.len() {
  111. let l_type = match LitType::from_repr(bytes[iter_offset]) {
  112. Some(v) => v,
  113. None => {
  114. return Err(ZkasErr(format!(
  115. "Could not decode literal LitType from {}",
  116. bytes[iter_offset],
  117. )))
  118. }
  119. };
  120. iter_offset += 1;
  121. let (name, offset) = deserialize_partial::<String>(&bytes[iter_offset..])?;
  122. iter_offset += offset;
  123. literals.push((l_type, name));
  124. }
  125. Ok(literals)
  126. }
  127. fn parse_contract(bytes: &[u8]) -> Result<Vec<VarType>> {
  128. let mut witnesses = vec![];
  129. let mut iter_offset = 0;
  130. while iter_offset < bytes.len() {
  131. let w_type = match VarType::from_repr(bytes[iter_offset]) {
  132. Some(v) => v,
  133. None => {
  134. return Err(ZkasErr(format!(
  135. "Could not decode witness VarType from {}",
  136. bytes[iter_offset],
  137. )))
  138. }
  139. };
  140. iter_offset += 1;
  141. witnesses.push(w_type);
  142. }
  143. Ok(witnesses)
  144. }
  145. #[allow(clippy::type_complexity)]
  146. fn parse_circuit(bytes: &[u8]) -> Result<Vec<(Opcode, Vec<(StackType, usize)>)>> {
  147. let mut opcodes = vec![];
  148. let mut iter_offset = 0;
  149. while iter_offset < bytes.len() {
  150. let opcode = match Opcode::from_repr(bytes[iter_offset]) {
  151. Some(v) => v,
  152. None => {
  153. return Err(ZkasErr(format!(
  154. "Could not decode Opcode from {}",
  155. bytes[iter_offset]
  156. )))
  157. }
  158. };
  159. iter_offset += 1;
  160. let (arg_num, offset) = deserialize_partial::<VarInt>(&bytes[iter_offset..])?;
  161. iter_offset += offset;
  162. let mut args = vec![];
  163. for _ in 0..arg_num.0 {
  164. let stack_type = bytes[iter_offset];
  165. iter_offset += 1;
  166. let (stack_index, offset) = deserialize_partial::<VarInt>(&bytes[iter_offset..])?;
  167. iter_offset += offset;
  168. let stack_type = match StackType::from_repr(stack_type) {
  169. Some(v) => v,
  170. None => {
  171. return Err(ZkasErr(format!(
  172. "Could not decode StackType from {}",
  173. stack_type
  174. )))
  175. }
  176. };
  177. args.push((stack_type, stack_index.0 as usize)); // FIXME, why?
  178. }
  179. opcodes.push((opcode, args));
  180. }
  181. Ok(opcodes)
  182. }
  183. }