decoder.rs 6.8 KB

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