diff --git a/core/src/mast/serialization/basic_block_data_decoder.rs b/core/src/mast/serialization/basic_block_data_decoder.rs index 75f2ab0bf4..b002b553f8 100644 --- a/core/src/mast/serialization/basic_block_data_decoder.rs +++ b/core/src/mast/serialization/basic_block_data_decoder.rs @@ -43,13 +43,13 @@ impl<'a> BasicBlockDataDecoder<'a> { // operation. let op_code = first_byte; - let maybe_operation = if op_code == Operation::Assert(0_u32).op_code() + let operation = if op_code == Operation::Assert(0_u32).op_code() || op_code == Operation::MpVerify(0_u32).op_code() { let value_le_bytes: [u8; 4] = self.data_reader.read_array()?; let value = u32::from_le_bytes(value_le_bytes); - Operation::with_opcode_and_data(op_code, OperationData::U32(value)) + Operation::with_opcode_and_data(op_code, OperationData::U32(value))? } else if op_code == Operation::U32assert2(ZERO).op_code() || op_code == Operation::Push(ZERO).op_code() { @@ -62,16 +62,12 @@ impl<'a> BasicBlockDataDecoder<'a> { )) })?; - Operation::with_opcode_and_data(op_code, OperationData::Felt(value_felt)) + Operation::with_opcode_and_data(op_code, OperationData::Felt(value_felt))? } else { // No operation data - Operation::with_opcode_and_data(op_code, OperationData::None) + Operation::with_opcode_and_data(op_code, OperationData::None)? }; - let operation = maybe_operation.ok_or_else(|| { - DeserializationError::InvalidValue(format!("invalid op code: {op_code}")) - })?; - operations.push(operation); } else { // decorator. diff --git a/core/src/operations/mod.rs b/core/src/operations/mod.rs index 8321db1c43..ab201933bd 100644 --- a/core/src/operations/mod.rs +++ b/core/src/operations/mod.rs @@ -1,10 +1,12 @@ use super::Felt; use core::fmt; mod decorators; +use alloc::string::ToString; pub use decorators::{ AdviceInjector, AssemblyOp, DebugOptions, Decorator, DecoratorIterator, DecoratorList, SignatureKind, }; +use winter_utils::DeserializationError; // OPERATIONS // ================================================================================================ @@ -449,123 +451,136 @@ pub enum OperationData { /// Constructors impl Operation { - // TODOP: document, and use `Result` instead? - pub fn with_opcode_and_data(opcode: u8, data: OperationData) -> Option { + // TODOP: document + pub fn with_opcode_and_data( + opcode: u8, + data: OperationData, + ) -> Result { match opcode { - 0b0000_0000 => Some(Self::Noop), - 0b0000_0001 => Some(Self::Eqz), - 0b0000_0010 => Some(Self::Neg), - 0b0000_0011 => Some(Self::Inv), - 0b0000_0100 => Some(Self::Incr), - 0b0000_0101 => Some(Self::Not), - 0b0000_0110 => Some(Self::FmpAdd), - 0b0000_0111 => Some(Self::MLoad), - 0b0000_1000 => Some(Self::Swap), - 0b0000_1001 => Some(Self::Caller), - 0b0000_1010 => Some(Self::MovUp2), - 0b0000_1011 => Some(Self::MovDn2), - 0b0000_1100 => Some(Self::MovUp3), - 0b0000_1101 => Some(Self::MovDn3), - 0b0000_1110 => Some(Self::AdvPopW), - 0b0000_1111 => Some(Self::Expacc), - - 0b0001_0000 => Some(Self::MovUp4), - 0b0001_0001 => Some(Self::MovDn4), - 0b0001_0010 => Some(Self::MovUp5), - 0b0001_0011 => Some(Self::MovDn5), - 0b0001_0100 => Some(Self::MovUp6), - 0b0001_0101 => Some(Self::MovDn6), - 0b0001_0110 => Some(Self::MovUp7), - 0b0001_0111 => Some(Self::MovDn7), - 0b0001_1000 => Some(Self::SwapW), - 0b0001_1001 => Some(Self::Ext2Mul), - 0b0001_1010 => Some(Self::MovUp8), - 0b0001_1011 => Some(Self::MovDn8), - 0b0001_1100 => Some(Self::SwapW2), - 0b0001_1101 => Some(Self::SwapW3), - 0b0001_1110 => Some(Self::SwapDW), + 0b0000_0000 => Ok(Self::Noop), + 0b0000_0001 => Ok(Self::Eqz), + 0b0000_0010 => Ok(Self::Neg), + 0b0000_0011 => Ok(Self::Inv), + 0b0000_0100 => Ok(Self::Incr), + 0b0000_0101 => Ok(Self::Not), + 0b0000_0110 => Ok(Self::FmpAdd), + 0b0000_0111 => Ok(Self::MLoad), + 0b0000_1000 => Ok(Self::Swap), + 0b0000_1001 => Ok(Self::Caller), + 0b0000_1010 => Ok(Self::MovUp2), + 0b0000_1011 => Ok(Self::MovDn2), + 0b0000_1100 => Ok(Self::MovUp3), + 0b0000_1101 => Ok(Self::MovDn3), + 0b0000_1110 => Ok(Self::AdvPopW), + 0b0000_1111 => Ok(Self::Expacc), + + 0b0001_0000 => Ok(Self::MovUp4), + 0b0001_0001 => Ok(Self::MovDn4), + 0b0001_0010 => Ok(Self::MovUp5), + 0b0001_0011 => Ok(Self::MovDn5), + 0b0001_0100 => Ok(Self::MovUp6), + 0b0001_0101 => Ok(Self::MovDn6), + 0b0001_0110 => Ok(Self::MovUp7), + 0b0001_0111 => Ok(Self::MovDn7), + 0b0001_1000 => Ok(Self::SwapW), + 0b0001_1001 => Ok(Self::Ext2Mul), + 0b0001_1010 => Ok(Self::MovUp8), + 0b0001_1011 => Ok(Self::MovDn8), + 0b0001_1100 => Ok(Self::SwapW2), + 0b0001_1101 => Ok(Self::SwapW3), + 0b0001_1110 => Ok(Self::SwapDW), // 0b0001_1111 => , 0b0010_0000 => match data { - OperationData::U32(value) => Some(Self::Assert(value)), - _ => None, + OperationData::U32(value) => Ok(Self::Assert(value)), + _ => Err(DeserializationError::InvalidValue( + "Invalid opcode data. 'Assert' opcode provided, hence expected to receive u32 data.".to_string() + )), }, - 0b0010_0001 => Some(Self::Eq), - 0b0010_0010 => Some(Self::Add), - 0b0010_0011 => Some(Self::Mul), - 0b0010_0100 => Some(Self::And), - 0b0010_0101 => Some(Self::Or), - 0b0010_0110 => Some(Self::U32and), - 0b0010_0111 => Some(Self::U32xor), - 0b0010_1000 => Some(Self::FriE2F4), - 0b0010_1001 => Some(Self::Drop), - 0b0010_1010 => Some(Self::CSwap), - 0b0010_1011 => Some(Self::CSwapW), - 0b0010_1100 => Some(Self::MLoadW), - 0b0010_1101 => Some(Self::MStore), - 0b0010_1110 => Some(Self::MStoreW), - 0b0010_1111 => Some(Self::FmpUpdate), - - 0b0011_0000 => Some(Self::Pad), - 0b0011_0001 => Some(Self::Dup0), - 0b0011_0010 => Some(Self::Dup1), - 0b0011_0011 => Some(Self::Dup2), - 0b0011_0100 => Some(Self::Dup3), - 0b0011_0101 => Some(Self::Dup4), - 0b0011_0110 => Some(Self::Dup5), - 0b0011_0111 => Some(Self::Dup6), - 0b0011_1000 => Some(Self::Dup7), - 0b0011_1001 => Some(Self::Dup9), - 0b0011_1010 => Some(Self::Dup11), - 0b0011_1011 => Some(Self::Dup13), - 0b0011_1100 => Some(Self::Dup15), - 0b0011_1101 => Some(Self::AdvPop), - 0b0011_1110 => Some(Self::SDepth), - 0b0011_1111 => Some(Self::Clk), - - 0b0100_0000 => Some(Self::U32add), - 0b0100_0010 => Some(Self::U32sub), - 0b0100_0100 => Some(Self::U32mul), - 0b0100_0110 => Some(Self::U32div), - 0b0100_1000 => Some(Self::U32split), + 0b0010_0001 => Ok(Self::Eq), + 0b0010_0010 => Ok(Self::Add), + 0b0010_0011 => Ok(Self::Mul), + 0b0010_0100 => Ok(Self::And), + 0b0010_0101 => Ok(Self::Or), + 0b0010_0110 => Ok(Self::U32and), + 0b0010_0111 => Ok(Self::U32xor), + 0b0010_1000 => Ok(Self::FriE2F4), + 0b0010_1001 => Ok(Self::Drop), + 0b0010_1010 => Ok(Self::CSwap), + 0b0010_1011 => Ok(Self::CSwapW), + 0b0010_1100 => Ok(Self::MLoadW), + 0b0010_1101 => Ok(Self::MStore), + 0b0010_1110 => Ok(Self::MStoreW), + 0b0010_1111 => Ok(Self::FmpUpdate), + + 0b0011_0000 => Ok(Self::Pad), + 0b0011_0001 => Ok(Self::Dup0), + 0b0011_0010 => Ok(Self::Dup1), + 0b0011_0011 => Ok(Self::Dup2), + 0b0011_0100 => Ok(Self::Dup3), + 0b0011_0101 => Ok(Self::Dup4), + 0b0011_0110 => Ok(Self::Dup5), + 0b0011_0111 => Ok(Self::Dup6), + 0b0011_1000 => Ok(Self::Dup7), + 0b0011_1001 => Ok(Self::Dup9), + 0b0011_1010 => Ok(Self::Dup11), + 0b0011_1011 => Ok(Self::Dup13), + 0b0011_1100 => Ok(Self::Dup15), + 0b0011_1101 => Ok(Self::AdvPop), + 0b0011_1110 => Ok(Self::SDepth), + 0b0011_1111 => Ok(Self::Clk), + + 0b0100_0000 => Ok(Self::U32add), + 0b0100_0010 => Ok(Self::U32sub), + 0b0100_0100 => Ok(Self::U32mul), + 0b0100_0110 => Ok(Self::U32div), + 0b0100_1000 => Ok(Self::U32split), 0b0100_1010 => match data { - OperationData::Felt(value) => Some(Self::U32assert2(value)), - _ => None, + OperationData::Felt(value) => Ok(Self::U32assert2(value)), + _ => Err(DeserializationError::InvalidValue( + "Invalid opcode data. 'U32assert2' opcode provided, hence expected to receive Felt data.".to_string() + )), }, - 0b0100_1100 => Some(Self::U32add3), - 0b0100_1110 => Some(Self::U32madd), + 0b0100_1100 => Ok(Self::U32add3), + 0b0100_1110 => Ok(Self::U32madd), - 0b0101_0000 => Some(Self::HPerm), + 0b0101_0000 => Ok(Self::HPerm), 0b0101_0001 => match data { - OperationData::U32(value) => Some(Self::MpVerify(value)), - _ => None, + OperationData::U32(value) => Ok(Self::MpVerify(value)), + _ => Err(DeserializationError::InvalidValue( + "Invalid opcode data. 'MpVerify' opcode provided, hence expected to receive u32 data.".to_string() + )), }, - 0b0101_0010 => Some(Self::Pipe), - 0b0101_0011 => Some(Self::MStream), - 0b0101_0100 => Some(Self::Split), - 0b0101_0101 => Some(Self::Loop), - 0b0101_0110 => Some(Self::Span), - 0b0101_0111 => Some(Self::Join), - 0b0101_1000 => Some(Self::Dyn), - 0b0101_1001 => Some(Self::RCombBase), + 0b0101_0010 => Ok(Self::Pipe), + 0b0101_0011 => Ok(Self::MStream), + 0b0101_0100 => Ok(Self::Split), + 0b0101_0101 => Ok(Self::Loop), + 0b0101_0110 => Ok(Self::Span), + 0b0101_0111 => Ok(Self::Join), + 0b0101_1000 => Ok(Self::Dyn), + 0b0101_1001 => Ok(Self::RCombBase), // 0b0101_1010 => , // 0b0101_1011 => , // 0b0101_1100 => , // 0b0101_1101 => , // 0b0101_1110 => , // 0b0101_1111 => , - 0b0110_0000 => Some(Self::MrUpdate), + 0b0110_0000 => Ok(Self::MrUpdate), 0b0110_0100 => match data { - OperationData::Felt(value) => Some(Self::Push(value)), - _ => None, + OperationData::Felt(value) => Ok(Self::Push(value)), + _ => Err(DeserializationError::InvalidValue( + "Invalid opcode data. 'Push' opcode provided, hence expected to receive Felt data.".to_string() + )), }, - 0b0110_1000 => Some(Self::SysCall), - 0b0110_1100 => Some(Self::Call), - 0b0111_0000 => Some(Self::End), - 0b0111_0100 => Some(Self::Repeat), - 0b0111_1000 => Some(Self::Respan), - 0b0111_1100 => Some(Self::Halt), - - _ => None, + 0b0110_1000 => Ok(Self::SysCall), + 0b0110_1100 => Ok(Self::Call), + 0b0111_0000 => Ok(Self::End), + 0b0111_0100 => Ok(Self::Repeat), + 0b0111_1000 => Ok(Self::Respan), + 0b0111_1100 => Ok(Self::Halt), + + _ => Err(DeserializationError::InvalidValue(format!( + "Invalid opcode {opcode}" + ))), } } }