From f3ecce8045580833a055dfeb89335698ee861b9b Mon Sep 17 00:00:00 2001 From: Edgar Luque Date: Mon, 26 Aug 2024 12:48:47 +0200 Subject: [PATCH] bitwise --- src/vm/uint128.rs | 23 ++++++++++++++++++++++- src/vm/uint32.rs | 23 ++++++++++++++++++++++- src/vm/uint64.rs | 23 ++++++++++++++++++++++- src/vm/uint8.rs | 42 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 106 insertions(+), 5 deletions(-) diff --git a/src/vm/uint128.rs b/src/vm/uint128.rs index dcaa6c9..08e9956 100644 --- a/src/vm/uint128.rs +++ b/src/vm/uint128.rs @@ -28,7 +28,7 @@ pub fn eval( Uint128Concrete::FromFelt252(info) => eval_from_felt(registry, info, args), Uint128Concrete::IsZero(info) => eval_is_zero(registry, info, args), Uint128Concrete::Divmod(_) => todo!(), - Uint128Concrete::Bitwise(_) => todo!(), + Uint128Concrete::Bitwise(info) => eval_bitwise(registry, info, args), Uint128Concrete::GuaranteeMul(_) => todo!(), Uint128Concrete::MulGuaranteeVerify(_) => todo!(), Uint128Concrete::ByteReverse(_) => todo!(), @@ -85,6 +85,27 @@ pub fn eval_is_zero( } } +pub fn eval_bitwise( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [bitwise @ Value::Unit, Value::U128(lhs), Value::U128(rhs)]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + let and = lhs & rhs; + let or = lhs | rhs; + let xor = lhs ^ rhs; + + EvalAction::NormalBranch( + 0, + smallvec![bitwise, Value::U128(and), Value::U128(or), Value::U128(xor)], + ) +} + pub fn eval_const( _registry: &ProgramRegistry, info: &IntConstConcreteLibfunc, diff --git a/src/vm/uint32.rs b/src/vm/uint32.rs index b229310..b1daf1d 100644 --- a/src/vm/uint32.rs +++ b/src/vm/uint32.rs @@ -29,7 +29,7 @@ pub fn eval( Uint32Concrete::IsZero(info) => eval_is_zero(registry, info, args), Uint32Concrete::Divmod(info) => eval_divmod(registry, info, args), Uint32Concrete::WideMul(info) => eval_widemul(registry, info, args), - Uint32Concrete::Bitwise(_) => todo!(), + Uint32Concrete::Bitwise(info) => eval_bitwise(registry, info, args), } } @@ -104,6 +104,27 @@ pub fn eval_equal( EvalAction::NormalBranch((lhs == rhs) as usize, smallvec![]) } +pub fn eval_bitwise( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [bitwise @ Value::Unit, Value::U32(lhs), Value::U32(rhs)]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + let and = lhs & rhs; + let or = lhs | rhs; + let xor = lhs ^ rhs; + + EvalAction::NormalBranch( + 0, + smallvec![bitwise, Value::U32(and), Value::U32(or), Value::U32(xor)], + ) +} + pub fn eval_is_zero( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, diff --git a/src/vm/uint64.rs b/src/vm/uint64.rs index 9760b0d..224dcba 100644 --- a/src/vm/uint64.rs +++ b/src/vm/uint64.rs @@ -29,7 +29,7 @@ pub fn eval( Uint64Concrete::IsZero(info) => eval_is_zero(registry, info, args), Uint64Concrete::Divmod(info) => eval_divmod(registry, info, args), Uint64Concrete::WideMul(info) => eval_widemul(registry, info, args), - Uint64Concrete::Bitwise(_) => todo!(), + Uint64Concrete::Bitwise(info) => eval_bitwise(registry, info, args), } } @@ -104,6 +104,27 @@ pub fn eval_equal( EvalAction::NormalBranch((lhs == rhs) as usize, smallvec![]) } +pub fn eval_bitwise( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [bitwise @ Value::Unit, Value::U64(lhs), Value::U64(rhs)]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + let and = lhs & rhs; + let or = lhs | rhs; + let xor = lhs ^ rhs; + + EvalAction::NormalBranch( + 0, + smallvec![bitwise, Value::U64(and), Value::U64(or), Value::U64(xor)], + ) +} + pub fn eval_is_zero( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, diff --git a/src/vm/uint8.rs b/src/vm/uint8.rs index ef839ab..24d18ee 100644 --- a/src/vm/uint8.rs +++ b/src/vm/uint8.rs @@ -27,12 +27,29 @@ pub fn eval( Uint8Concrete::ToFelt252(info) => eval_to_felt252(registry, info, args), Uint8Concrete::FromFelt252(info) => eval_from_felt(registry, info, args), Uint8Concrete::IsZero(info) => eval_is_zero(registry, info, args), - Uint8Concrete::Divmod(_) => todo!(), + Uint8Concrete::Divmod(info) => eval_divmod(registry, info, args), Uint8Concrete::WideMul(info) => eval_widemul(registry, info, args), - Uint8Concrete::Bitwise(_) => todo!(), + Uint8Concrete::Bitwise(info) => eval_bitwise(registry, info, args), } } +pub fn eval_divmod( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [range_check @ Value::Unit, Value::U8(x), Value::U8(y)]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + let val = Value::U8(x / y); + let rem = Value::U8(x % y); + + EvalAction::NormalBranch(0, smallvec![range_check, val, rem]) +} + pub fn eval_to_felt252( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, @@ -99,6 +116,27 @@ pub fn eval_equal( EvalAction::NormalBranch((lhs == rhs) as usize, smallvec![]) } +pub fn eval_bitwise( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + args: Vec, +) -> EvalAction { + let [bitwise @ Value::Unit, Value::U8(lhs), Value::U8(rhs)]: [Value; 3] = + args.try_into().unwrap() + else { + panic!() + }; + + let and = lhs & rhs; + let or = lhs | rhs; + let xor = lhs ^ rhs; + + EvalAction::NormalBranch( + 0, + smallvec![bitwise, Value::U8(and), Value::U8(or), Value::U8(xor)], + ) +} + pub fn eval_is_zero( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc,