Skip to content

Commit

Permalink
Fix division bug and make integration test pass
Browse files Browse the repository at this point in the history
  • Loading branch information
entropidelic committed Sep 19, 2023
1 parent c17e91e commit 967d072
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 66 deletions.
1 change: 1 addition & 0 deletions cairo_programs/signed_div_rem.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ from starkware.cairo.common.serialize import serialize_word
func signed_div_rem_man{range_check_ptr}(value, div, bound) -> (q: felt, r: felt) {
let r = [range_check_ptr];
let biased_q = [range_check_ptr + 1]; // == q + bound.

let range_check_ptr = range_check_ptr + 2;
%{
from starkware.cairo.common.math_utils import as_int, assert_integer
Expand Down
2 changes: 2 additions & 0 deletions pkg/hints/hint_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any,
return vm_enter_scope(execScopes)
case UNSIGNED_DIV_REM:
return unsignedDivRem(data.Ids, vm)
case SIGNED_DIV_REM:
return signedDivRem(data.Ids, vm)
default:
return errors.Errorf("Unknown Hint: %s", data.Code)
}
Expand Down
76 changes: 12 additions & 64 deletions pkg/hints/math_hints.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package hints

import (
"fmt"
"math/big"

"github.com/lambdaclass/cairo-vm.go/pkg/builtins"
Expand Down Expand Up @@ -253,77 +252,26 @@ func signedDivRem(ids IdsManager, vm *VirtualMachine) error {
if div.IsZero() || divGreater {
return errors.Errorf("div=%d is out of the valid range", div)
}

if bound.Cmp(rcBound.Shr(1)) == 1 {
return errors.Errorf("bound=%d is out of the valid range", bound)
}

sgnValue := value.ToSigned()
sgnBound := bound.ToBigInt()
intBound := bound.ToBigInt()
intDiv := div.ToBigInt()

q := new(big.Int).Div(sgnValue, intDiv)
r := new(big.Int).Rem(sgnValue, intDiv)
q, r := new(big.Int).DivMod(sgnValue, intDiv, new(big.Int))

if new(big.Int).Abs(intBound).Cmp(new(big.Int).Abs(q)) == -1 {
return errors.Errorf("%d / %d = %d is out of the range [-%d, %d]", sgnValue, div, q, bound, bound)
}

fmt.Println(sgnBound, q, r)
biasedQ := new(big.Int).Add(q, intBound)
biasedQFelt := lambdaworks.FeltFromBigInt(biasedQ)
rFelt := lambdaworks.FeltFromBigInt(r)

ids.Insert("r", NewMaybeRelocatableFelt(rFelt), vm)
ids.Insert("biased_q", NewMaybeRelocatableFelt(biasedQFelt), vm)

return nil
}

// pub fn signed_div_rem(
// vm: &mut VirtualMachine,
// ids_data: &HashMap<String, HintReference>,
// ap_tracking: &ApTracking,
// ) -> Result<(), HintError> {
// let div = get_integer_from_var_name("div", vm, ids_data, ap_tracking)?;
// let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
// let value = value.as_ref();
// let bound = get_integer_from_var_name("bound", vm, ids_data, ap_tracking)?;
// let builtin = vm.get_range_check_builtin()?;

// match &builtin._bound {
// Some(builtin_bound)
// if div.is_zero() || div.as_ref() > &div_prime_by_bound(builtin_bound.clone())? =>
// {
// return Err(HintError::OutOfValidRange(Box::new((
// div.into_owned(),
// builtin_bound.clone(),
// ))));
// }
// Some(builtin_bound) if bound.as_ref() > &(builtin_bound >> 1_u32) => {
// return Err(HintError::OutOfValidRange(Box::new((
// bound.into_owned(),
// builtin_bound >> 1_u32,
// ))));
// }
// None if div.is_zero() => {
// return Err(HintError::OutOfValidRange(Box::new((
// div.into_owned(),
// Felt252::zero() - Felt252::one(),
// ))));
// }
// _ => {}
// }

// let int_value = value.to_signed_felt();
// let int_div = div.to_bigint();
// let int_bound = bound.to_bigint();
// let (q, r) = int_value.div_mod_floor(&int_div);

// if int_bound.abs() < q.abs() {
// return Err(HintError::OutOfValidRange(Box::new((
// Felt252::new(q),
// bound.into_owned(),
// ))));
// }

// let biased_q = q + int_bound;
// insert_value_from_var_name("r", Felt252::new(r), vm, ids_data, ap_tracking)?;
// insert_value_from_var_name(
// "biased_q",
// Felt252::new(biased_q),
// vm,
// ids_data,
// ap_tracking,
// )
// }
2 changes: 1 addition & 1 deletion pkg/lambdaworks/lambdaworks.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func FeltFromUint64(value uint64) Felt {
return fromC(result)
}

func FeltFromBigInt(value big.Int) Felt {
func FeltFromBigInt(value *big.Int) Felt {
buff := make([]byte, 32)
bytes := value.FillBytes(buff)
return FeltFromBeBytes((*[32]byte)(bytes))
Expand Down
2 changes: 1 addition & 1 deletion pkg/lambdaworks/lambdaworks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func TestFromBigInt(t *testing.T) {
big := big.NewInt(15)

expectedFelt := lambdaworks.FeltFromDecString("15")
resFelt := lambdaworks.FeltFromBigInt(*big)
resFelt := lambdaworks.FeltFromBigInt(big)

if resFelt.Cmp(expectedFelt) != 0 {
t.Errorf("TestFromBigInt failed. Expected 15, got: %v", resFelt)
Expand Down
8 changes: 8 additions & 0 deletions pkg/vm/cairo_run/cairo_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,11 @@ func TestUnsignedDivRemHint(t *testing.T) {
t.Errorf("Program execution failed with error: %s", err)
}
}

func TestSignedDivRemHint(t *testing.T) {
cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false}
_, err := cairo_run.CairoRun("../../../cairo_programs/signed_div_rem.json", cairoRunConfig)
if err != nil {
t.Errorf("Program execution failed with error: %s", err)
}
}

0 comments on commit 967d072

Please sign in to comment.