From 1429c01799dd99078e8261b4c625e2f82fe38af8 Mon Sep 17 00:00:00 2001 From: Milton Date: Wed, 27 Sep 2023 11:10:05 -0300 Subject: [PATCH 1/8] Safe Div hint --- pkg/hints/hint_codes/ec_op_hints.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index fabd0531..55f2ec85 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -27,3 +27,5 @@ y0 = pack(ids.pt0.y, PRIME) value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"` const FAST_EC_ADD_ASSIGN_NEW_Y = "value = new_y = (slope * (x0 - new_x) - y0) % SECP_P" + +const BIGINT_SAFE_DIV = "k = safe_div(res * y - x, p)\nvalue = k if k > 0 else 0 - k\nids.flag = 1 if k > 0 else 0" \ No newline at end of file From 0aaf96e9179baf340e766b2e051782b4ea4d485f Mon Sep 17 00:00:00 2001 From: Milton Date: Wed, 27 Sep 2023 12:53:18 -0300 Subject: [PATCH 2/8] Div safe test --- pkg/hints/bigint_hint.go | 83 +++++++++++++++++++++++++++-- pkg/hints/bigint_hint_test.go | 64 ++++++++++++++++++++++ pkg/hints/hint_codes/ec_op_hints.go | 2 +- pkg/hints/hint_processor.go | 2 + 4 files changed, 147 insertions(+), 4 deletions(-) diff --git a/pkg/hints/bigint_hint.go b/pkg/hints/bigint_hint.go index a13fc098..b8271847 100644 --- a/pkg/hints/bigint_hint.go +++ b/pkg/hints/bigint_hint.go @@ -2,11 +2,13 @@ package hints import ( "errors" + "fmt" "math/big" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" . "github.com/lambdaclass/cairo-vm.go/pkg/types" + . "github.com/lambdaclass/cairo-vm.go/pkg/utils" . "github.com/lambdaclass/cairo-vm.go/pkg/vm" "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) @@ -20,8 +22,8 @@ Implements hint: %} */ -func NondetBigInt3(virtual_machine VirtualMachine, execScopes ExecutionScopes, idsData IdsManager) error { - resRelloc, err := idsData.GetAddr("res", &virtual_machine) +func NondetBigInt3(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsManager) error { + resRelloc, err := idsData.GetAddr("res", &vm) if err != nil { return err } @@ -47,10 +49,85 @@ func NondetBigInt3(virtual_machine VirtualMachine, execScopes ExecutionScopes, i arg = append(arg, *m) } - _, loadErr := virtual_machine.Segments.LoadData(resRelloc, &arg) + _, loadErr := vm.Segments.LoadData(resRelloc, &arg) if loadErr != nil { return loadErr } return nil } + +/// Implements hint: +/// ```python +/// k = safe_div(res * y - x, p) +/// value = k if k > 0 else 0 - k +/// ids.flag = 1 if k > 0 else 0 +/// ``` + +func SafeDivBigint(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsManager) error { + resUncast, err := execScopes.Get("res") + if err != nil { + return err + } + res, ok := resUncast.(big.Int) + if !ok { + return errors.New("Could not cast res value in SafeDivBigint") + } + + yUncast, err := execScopes.Get("y") + if err != nil { + return err + } + y, ok := yUncast.(big.Int) + if !ok { + return errors.New("Could not cast y value in SafeDivBigint") + } + + xUncast, err := execScopes.Get("x") + if err != nil { + return err + } + x, ok := xUncast.(big.Int) + if !ok { + return errors.New("Could not cast x value in SafeDivBigint") + } + + pUncast, err := execScopes.Get("p") + if err != nil { + return err + } + p, ok := pUncast.(big.Int) + if !ok { + return errors.New("Could not cast p value in SafeDivBigint") + } + + param_x := new(big.Int).Mul(&res, &y) + param_x.Sub(param_x, &x) + + fmt.Println("param x: ",param_x) + k, err := SafeDivBig(param_x, &p) + fmt.Println("k", k) + if err != nil { + return err + } + + var value big.Int + var flag lambdaworks.Felt + + // check if k is positive + if k.Cmp(big.NewInt(0)) == 1 { + value = *k + flag = lambdaworks.FeltFromUint(1) + } else { + value = *new(big.Int).Neg(k) + flag = lambdaworks.FeltFromUint(0) + } + + execScopes.AssignOrUpdateVariable("k", k) + execScopes.AssignOrUpdateVariable("value", value) + + val := memory.NewMaybeRelocatableFelt(flag) + idsData.Insert("flag", val, &vm) + + return nil +} diff --git a/pkg/hints/bigint_hint_test.go b/pkg/hints/bigint_hint_test.go index 27bc55b4..68e66598 100644 --- a/pkg/hints/bigint_hint_test.go +++ b/pkg/hints/bigint_hint_test.go @@ -73,3 +73,67 @@ func TestNonDetBigInt3Ok(t *testing.T) { } } } + +func TestSafeDivBigInt(t *testing.T) { + vm := NewVirtualMachine() + + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + execScopes := NewExecutionScopes() + + res, _ := new(big.Int).SetString("109567829260688255124154626727441144629993228404337546799996747905569082729709", 10) + x, _ := new(big.Int).SetString("91414600319290532004473480113251693728834511388719905794310982800988866814583", 10) + y, _ := new(big.Int).SetString("38047400353360331012910998489219098987968251547384484838080352663220422975266", 10) + p, _ := new(big.Int).SetString("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10) + + execScopes.AssignOrUpdateVariable("res", *res) + execScopes.AssignOrUpdateVariable("x", *x) + execScopes.AssignOrUpdateVariable("y", *y) + execScopes.AssignOrUpdateVariable("p", *p) + + vm.RunContext.Fp = NewRelocatable(1, 0) + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "flag": {nil}, + }, + vm, + ) + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: BIGINT_SAFE_DIV, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, execScopes) + + if err != nil { + t.Errorf("Safe Big int div hint test failed with error: %s", err) + } else { + expectedK, _ := new(big.Int).SetString("36002209591245282109880156842267569109802494162594623391338581162816748840003", 10) + expectedVal, _ := new(big.Int).SetString("36002209591245282109880156842267569109802494162594623391338581162816748840003", 10) + + kUncast, err := execScopes.Get("k") + if err != nil { + t.Errorf("%s", err) + } + k, _ := kUncast.(big.Int) + + valUncast, err := execScopes.Get("value") + if err != nil { + t.Errorf("%s", err) + } + + value, _ := valUncast.(big.Int) + + if expectedK.Cmp(&k) != 0 { + t.Errorf("incorrect K value expected: %s, got: %s", expectedK.Text(10), k.Text(10)) + } + + if expectedVal.Cmp(&value) != 0 { + t.Errorf("incorrect value expected: %s, got: %s", expectedVal.Text(10), value.Text(10)) + } + } +} diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index d63868b1..9d32edf3 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -31,4 +31,4 @@ value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"` const FAST_EC_ADD_ASSIGN_NEW_Y = "value = new_y = (slope * (x0 - new_x) - y0) % SECP_P" -const BIGINT_SAFE_DIV = "k = safe_div(res * y - x, p)\nvalue = k if k > 0 else 0 - k\nids.flag = 1 if k > 0 else 0" \ No newline at end of file +const BIGINT_SAFE_DIV = "k = safe_div(res * y - x, p)\nvalue = k if k > 0 else 0 - k\nids.flag = 1 if k > 0 else 0" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 6ed7562f..828e03e6 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -186,6 +186,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return fastEcAddAssignNewX(data.Ids, vm, execScopes, "pt0", "pt1", SECP_P()) case FAST_EC_ADD_ASSIGN_NEW_Y: return fastEcAddAssignNewY(execScopes) + case BIGINT_SAFE_DIV: + return SafeDivBigint(*vm, *execScopes, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } From e6f8acc1817fd59d5a5f4bff4073e92e1c142c3a Mon Sep 17 00:00:00 2001 From: Milton Date: Thu, 28 Sep 2023 10:38:03 -0300 Subject: [PATCH 3/8] Fix broken test --- pkg/hints/bigint_hint.go | 9 +++------ pkg/hints/bigint_hint_test.go | 1 - pkg/hints/hint_processor.go | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pkg/hints/bigint_hint.go b/pkg/hints/bigint_hint.go index b8271847..2ab76460 100644 --- a/pkg/hints/bigint_hint.go +++ b/pkg/hints/bigint_hint.go @@ -2,7 +2,6 @@ package hints import ( "errors" - "fmt" "math/big" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" @@ -64,7 +63,7 @@ func NondetBigInt3(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsMan /// ids.flag = 1 if k > 0 else 0 /// ``` -func SafeDivBigint(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsManager) error { +func SafeDivBigint(vm *VirtualMachine, execScopes *ExecutionScopes, idsData IdsManager) error { resUncast, err := execScopes.Get("res") if err != nil { return err @@ -104,9 +103,7 @@ func SafeDivBigint(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsMan param_x := new(big.Int).Mul(&res, &y) param_x.Sub(param_x, &x) - fmt.Println("param x: ",param_x) k, err := SafeDivBig(param_x, &p) - fmt.Println("k", k) if err != nil { return err } @@ -123,11 +120,11 @@ func SafeDivBigint(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsMan flag = lambdaworks.FeltFromUint(0) } - execScopes.AssignOrUpdateVariable("k", k) + execScopes.AssignOrUpdateVariable("k", *k) execScopes.AssignOrUpdateVariable("value", value) val := memory.NewMaybeRelocatableFelt(flag) - idsData.Insert("flag", val, &vm) + idsData.Insert("flag", val, vm) return nil } diff --git a/pkg/hints/bigint_hint_test.go b/pkg/hints/bigint_hint_test.go index 68e66598..a3bf7441 100644 --- a/pkg/hints/bigint_hint_test.go +++ b/pkg/hints/bigint_hint_test.go @@ -125,7 +125,6 @@ func TestSafeDivBigInt(t *testing.T) { if err != nil { t.Errorf("%s", err) } - value, _ := valUncast.(big.Int) if expectedK.Cmp(&k) != 0 { diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 828e03e6..d547bb2d 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -187,7 +187,7 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, case FAST_EC_ADD_ASSIGN_NEW_Y: return fastEcAddAssignNewY(execScopes) case BIGINT_SAFE_DIV: - return SafeDivBigint(*vm, *execScopes, data.Ids) + return SafeDivBigint(vm, execScopes, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } From 75229505985f8c2f67eb83a2c53895390886f75b Mon Sep 17 00:00:00 2001 From: Milton Date: Thu, 28 Sep 2023 14:36:24 -0300 Subject: [PATCH 4/8] Bigint pack div mod test --- pkg/hints/bigint_hint.go | 56 +++++++++++++ pkg/hints/bigint_hint_test.go | 114 +++++++++++++++++++++++++++ pkg/hints/ec_hint_test.go | 1 - pkg/hints/hint_codes/ec_op_hints.go | 1 + pkg/hints/hint_processor.go | 2 + pkg/hints/hint_utils/bigint_utils.go | 2 +- pkg/hints/hint_utils/secp_utils.go | 5 ++ 7 files changed, 179 insertions(+), 2 deletions(-) diff --git a/pkg/hints/bigint_hint.go b/pkg/hints/bigint_hint.go index 2ab76460..dd5ea75c 100644 --- a/pkg/hints/bigint_hint.go +++ b/pkg/hints/bigint_hint.go @@ -128,3 +128,59 @@ func SafeDivBigint(vm *VirtualMachine, execScopes *ExecutionScopes, idsData IdsM return nil } + +func calculateX(vm *VirtualMachine, idsData IdsManager) (big.Int, error) { + x_bigint5, err := LimbsFromVarName(5, "x", idsData, vm) + if err != nil { + return big.Int{}, err + } + // pack only takes the first three limbs + x0 := x_bigint5[0] + x1 := x_bigint5[1] + x2 := x_bigint5[2] + var limbs = []lambdaworks.Felt{x0, x1, x2} + + x_lower := BigInt3{Limbs: limbs} + x_lower_bigint := x_lower.Pack86() + + d3 := x_bigint5[3].ToSigned() + d4 := x_bigint5[4].ToSigned() + + base := BASE() + d3.Mul(d3, base.Exp(&base, big.NewInt(3), nil)) + d4.Mul(d4, base.Exp(&base, big.NewInt(4), nil)) + + x_lower_bigint.Add(&x_lower_bigint, d3) + x_lower_bigint.Add(&x_lower_bigint, d4) + + return x_lower_bigint, nil +} + +func bigintPackDivMod(vm *VirtualMachine, execScopes *ExecutionScopes, idsData IdsManager) error { + + pUnpack, err := BigInt3FromVarName("P", idsData, vm) + if err != nil { + return err + } + p := pUnpack.Pack86() + + x, err := calculateX(vm, idsData) + if err != nil { + return err + } + + yUnpacked, err := BigInt3FromVarName("y", idsData, vm) + if err != nil { + return err + } + y := yUnpacked.Pack86() + + res, _ := new(big.Int).DivMod(&x, &y, &p) + execScopes.AssignOrUpdateVariable("res", *res) + execScopes.AssignOrUpdateVariable("value", *res) + execScopes.AssignOrUpdateVariable("x", x) + execScopes.AssignOrUpdateVariable("y", y) + execScopes.AssignOrUpdateVariable("p", p) + + return nil +} diff --git a/pkg/hints/bigint_hint_test.go b/pkg/hints/bigint_hint_test.go index a3bf7441..543e1bc5 100644 --- a/pkg/hints/bigint_hint_test.go +++ b/pkg/hints/bigint_hint_test.go @@ -10,6 +10,7 @@ import ( "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" . "github.com/lambdaclass/cairo-vm.go/pkg/types" . "github.com/lambdaclass/cairo-vm.go/pkg/vm" + "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) @@ -134,5 +135,118 @@ func TestSafeDivBigInt(t *testing.T) { if expectedVal.Cmp(&value) != 0 { t.Errorf("incorrect value expected: %s, got: %s", expectedVal.Text(10), value.Text(10)) } + + // check memory + addr := memory.NewRelocatable(1, 0) + val, _ := vm.Segments.Memory.GetFelt(addr) + + if val != lambdaworks.FeltFromUint(1) { + t.Errorf("incorrect value fetched from memory") + } + } +} + +func TestBigintPackDivModHint(t *testing.T) { + vm := NewVirtualMachine() + + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + vm.RunContext.Fp = NewRelocatable(1, 0) + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "x": { + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x38a23ca66202c8c2a72277")), + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x6730e765376ff17ea8385")), + NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(0)), + NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(0)), + }, + "y": { + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x20a4b46d3c5e24cda81f22")), + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x967bf895824330d4273d0")), + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x541e10c21560da25ada4c")), + }, + "P": { + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x8a03bbfd25e8cd0364141")), + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x3ffffffffffaeabb739abd")), + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0xfffffffffffffffffffff")), + }, + }, + vm, + ) + + execScopes := NewExecutionScopes() + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: BIGINT_PACK_DIV_MOD, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, execScopes) + + if err != nil { + t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err) + } else { + expected, _ := new(big.Int).SetString("109567829260688255124154626727441144629993228404337546799996747905569082729709", 10) + yExpected, _ := new(big.Int).SetString("38047400353360331012910998489219098987968251547384484838080352663220422975266", 10) + xExpected, _ := new(big.Int).SetString("91414600319290532004473480113251693728834511388719905794310982800988866814583", 10) + pExpected, _ := new(big.Int).SetString("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10) + + // fetch values + resu, err := execScopes.Get("res") + if err != nil { + t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err) + } + res := resu.(big.Int) + + valu, err := execScopes.Get("value") + if err != nil { + t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err) + } + value := valu.(big.Int) + + yu, err := execScopes.Get("y") + if err != nil { + t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err) + } + y := yu.(big.Int) + + xu, err := execScopes.Get("x") + if err != nil { + t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err) + } + x := xu.(big.Int) + + pu, err := execScopes.Get("p") + if err != nil { + t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err) + } + p := pu.(big.Int) + + if res.Cmp(expected) != 0 { + t.Errorf("incorrect res expected: %s, got: %s", expected.Text(10), expected.Text(10)) + } + if value.Cmp(expected) != 0 { + t.Errorf("incorrect value expected: %s, got: %s", value.Text(10), expected.Text(10)) + } + if y.Cmp(yExpected) != 0 { + t.Errorf("incorrect y expected: %s, got: %s", yExpected.Text(10), y.Text(10)) + } + if x.Cmp(xExpected) != 0 { + t.Errorf("incorrect x expected: %s, got: %s", xExpected.Text(10), x.Text(10)) + } + if p.Cmp(pExpected) != 0 { + t.Errorf("incorrect p expected: %s, got: %s", pExpected.Text(10), p.Text(10)) + } } } diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 3cf08a82..01d88e3f 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -246,7 +246,6 @@ func TestRunComputeSlopeV2Ok(t *testing.T) { idsManager := SetupIdsForTest( map[string][]*MaybeRelocatable{ "point0": { - NewMaybeRelocatableFelt(FeltFromUint64(512)), NewMaybeRelocatableFelt(FeltFromUint64(2412)), NewMaybeRelocatableFelt(FeltFromUint64(133)), diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index 9d32edf3..4bb14700 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -32,3 +32,4 @@ value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"` const FAST_EC_ADD_ASSIGN_NEW_Y = "value = new_y = (slope * (x0 - new_x) - y0) % SECP_P" const BIGINT_SAFE_DIV = "k = safe_div(res * y - x, p)\nvalue = k if k > 0 else 0 - k\nids.flag = 1 if k > 0 else 0" +const BIGINT_PACK_DIV_MOD = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nfrom starkware.cairo.common.math_utils import as_int\nfrom starkware.python.math_utils import div_mod, safe_div\n\np = pack(ids.P, PRIME)\nx = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4\ny = pack(ids.y, PRIME)\n\nvalue = res = div_mod(x, y, p)" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index d547bb2d..134911e1 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -188,6 +188,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return fastEcAddAssignNewY(execScopes) case BIGINT_SAFE_DIV: return SafeDivBigint(vm, execScopes, data.Ids) + case BIGINT_PACK_DIV_MOD: + return bigintPackDivMod(vm, execScopes, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index 9a900443..916f0181 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -14,7 +14,7 @@ import ( // This file contains an implementation of each behaviour at the limbs level, and the wrappers for each specific type // Generic methods for all types -func limbsFromVarName(nLimbs int, name string, ids IdsManager, vm *VirtualMachine) ([]Felt, error) { +func LimbsFromVarName(nLimbs int, name string, ids IdsManager, vm *VirtualMachine) ([]Felt, error) { baseAddr, err := ids.GetAddr(name, vm) if err != nil { return nil, err diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go index a125823a..291b0907 100644 --- a/pkg/hints/hint_utils/secp_utils.go +++ b/pkg/hints/hint_utils/secp_utils.go @@ -5,6 +5,11 @@ import ( "math/big" ) +func BASE() big.Int { + base, _ := new(big.Int).SetString("77371252455336267181195264", 10) + return *base +} + func SECP_P() big.Int { secpP, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) return *secpP From 465cb1512a1214f844beb7cef7d5ff193b65094e Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 29 Sep 2023 08:27:56 -0300 Subject: [PATCH 5/8] Fix bigint pack div mod test --- pkg/hints/bigint_hint.go | 8 +++++++- pkg/hints/bigint_hint_test.go | 12 ++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pkg/hints/bigint_hint.go b/pkg/hints/bigint_hint.go index dd5ea75c..b1d04a6f 100644 --- a/pkg/hints/bigint_hint.go +++ b/pkg/hints/bigint_hint.go @@ -2,10 +2,12 @@ package hints import ( "errors" + "fmt" "math/big" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" + "github.com/lambdaclass/cairo-vm.go/pkg/math_utils" . "github.com/lambdaclass/cairo-vm.go/pkg/types" . "github.com/lambdaclass/cairo-vm.go/pkg/utils" . "github.com/lambdaclass/cairo-vm.go/pkg/vm" @@ -138,6 +140,7 @@ func calculateX(vm *VirtualMachine, idsData IdsManager) (big.Int, error) { x0 := x_bigint5[0] x1 := x_bigint5[1] x2 := x_bigint5[2] + var limbs = []lambdaworks.Felt{x0, x1, x2} x_lower := BigInt3{Limbs: limbs} @@ -173,9 +176,12 @@ func bigintPackDivMod(vm *VirtualMachine, execScopes *ExecutionScopes, idsData I if err != nil { return err } + x1 := x y := yUnpacked.Pack86() - res, _ := new(big.Int).DivMod(&x, &y, &p) + res, _ := math_utils.DivMod(&x1, &y, &p) + fmt.Println("x", x.Text(10)) + execScopes.AssignOrUpdateVariable("res", *res) execScopes.AssignOrUpdateVariable("value", *res) execScopes.AssignOrUpdateVariable("x", x) diff --git a/pkg/hints/bigint_hint_test.go b/pkg/hints/bigint_hint_test.go index 543e1bc5..b9c15184 100644 --- a/pkg/hints/bigint_hint_test.go +++ b/pkg/hints/bigint_hint_test.go @@ -1,6 +1,7 @@ package hints_test import ( + "fmt" "math/big" "testing" @@ -167,6 +168,7 @@ func TestBigintPackDivModHint(t *testing.T) { "x": { NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x38a23ca66202c8c2a72277")), NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x6730e765376ff17ea8385")), + NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0xca1ad489ab60ea581e6c1")), NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(0)), NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(0)), }, @@ -233,11 +235,17 @@ func TestBigintPackDivModHint(t *testing.T) { } p := pu.(big.Int) + fmt.Println("") + fmt.Println("") + fmt.Println("") + fmt.Println("") + fmt.Println("") + fmt.Println("") if res.Cmp(expected) != 0 { - t.Errorf("incorrect res expected: %s, got: %s", expected.Text(10), expected.Text(10)) + t.Errorf("incorrect res expected: %s, got: %s", expected.Text(10), res.Text(10)) } if value.Cmp(expected) != 0 { - t.Errorf("incorrect value expected: %s, got: %s", value.Text(10), expected.Text(10)) + t.Errorf("incorrect value expected: %s, got: %s", expected.Text(10), value.Text(10)) } if y.Cmp(yExpected) != 0 { t.Errorf("incorrect y expected: %s, got: %s", yExpected.Text(10), y.Text(10)) From d34b0f25055b1323cd208a57fa7745103ca6d328 Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 29 Sep 2023 08:33:14 -0300 Subject: [PATCH 6/8] Delete debug info --- pkg/hints/bigint_hint.go | 4 +--- pkg/hints/bigint_hint_test.go | 7 ------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/pkg/hints/bigint_hint.go b/pkg/hints/bigint_hint.go index b1d04a6f..d29a5817 100644 --- a/pkg/hints/bigint_hint.go +++ b/pkg/hints/bigint_hint.go @@ -2,7 +2,6 @@ package hints import ( "errors" - "fmt" "math/big" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" @@ -171,16 +170,15 @@ func bigintPackDivMod(vm *VirtualMachine, execScopes *ExecutionScopes, idsData I if err != nil { return err } + x1 := x yUnpacked, err := BigInt3FromVarName("y", idsData, vm) if err != nil { return err } - x1 := x y := yUnpacked.Pack86() res, _ := math_utils.DivMod(&x1, &y, &p) - fmt.Println("x", x.Text(10)) execScopes.AssignOrUpdateVariable("res", *res) execScopes.AssignOrUpdateVariable("value", *res) diff --git a/pkg/hints/bigint_hint_test.go b/pkg/hints/bigint_hint_test.go index b9c15184..00be7132 100644 --- a/pkg/hints/bigint_hint_test.go +++ b/pkg/hints/bigint_hint_test.go @@ -1,7 +1,6 @@ package hints_test import ( - "fmt" "math/big" "testing" @@ -235,12 +234,6 @@ func TestBigintPackDivModHint(t *testing.T) { } p := pu.(big.Int) - fmt.Println("") - fmt.Println("") - fmt.Println("") - fmt.Println("") - fmt.Println("") - fmt.Println("") if res.Cmp(expected) != 0 { t.Errorf("incorrect res expected: %s, got: %s", expected.Text(10), res.Text(10)) } From f76eeaac299081de458636ba51fe085fa0325ba1 Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 29 Sep 2023 11:47:53 -0300 Subject: [PATCH 7/8] Assert le felt v 0 6 hint --- pkg/hints/hint_codes/math_hint_codes.go | 2 ++ pkg/hints/hint_processor.go | 2 ++ pkg/hints/math_hints.go | 33 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/pkg/hints/hint_codes/math_hint_codes.go b/pkg/hints/hint_codes/math_hint_codes.go index de6083ff..b0db9236 100644 --- a/pkg/hints/hint_codes/math_hint_codes.go +++ b/pkg/hints/hint_codes/math_hint_codes.go @@ -42,3 +42,5 @@ const SPLIT_FELT = "from starkware.cairo.common.math_utils import assert_integer const SPLIT_INT = "memory[ids.output] = res = (int(ids.value) % PRIME) % ids.base\nassert res < ids.bound, f'split_int(): Limb {res} is out of range.'" const SPLIT_INT_ASSERT_RANGE = "assert ids.value == 0, 'split_int(): value is out of range.'" + +const ASSERT_LE_FELT_V_0_6 = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\nassert (ids.a % PRIME) <= (ids.b % PRIME), \\\n f'a = {ids.a % PRIME} is not less than or equal to b = {ids.b % PRIME}.'" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 134911e1..50b56775 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -190,6 +190,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return SafeDivBigint(vm, execScopes, data.Ids) case BIGINT_PACK_DIV_MOD: return bigintPackDivMod(vm, execScopes, data.Ids) + case ASSERT_LE_FELT_V_0_6: + return assertLeFeltV06(vm, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/math_hints.go b/pkg/hints/math_hints.go index 03b239c3..5e1ce350 100644 --- a/pkg/hints/math_hints.go +++ b/pkg/hints/math_hints.go @@ -1,6 +1,7 @@ package hints import ( + "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/builtins" @@ -10,6 +11,7 @@ import ( . "github.com/lambdaclass/cairo-vm.go/pkg/math_utils" . "github.com/lambdaclass/cairo-vm.go/pkg/types" . "github.com/lambdaclass/cairo-vm.go/pkg/vm" + "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" "github.com/pkg/errors" ) @@ -605,3 +607,34 @@ func splitIntAssertRange(ids IdsManager, vm *VirtualMachine) error { return nil } + +func assertLeFeltV06(vm *VirtualMachine, ids IdsManager) error { + a, err := ids.GetFelt("a", vm) + if err != nil { + return err + } + + b, err := ids.GetFelt("b", vm) + if err != nil { + return err + } + if a.Cmp(b) == 1 { + err := fmt.Sprintf("Assertion failed, %s, is not less or equal to %s", a.ToHexString(), b.ToHexString()) + return errors.New(err) + } + + bound, err := vm.GetRangeCheckBound() + if err != nil { + return err + } + + acmp := a.Cmp(bound) + bcmp := b.Sub(a).Cmp(bound) + + // Todo: check if using only & is enough (rust uses && between bools) + small_inputs := lambdaworks.FeltFromUint(uint(acmp & bcmp)) + + ids.Insert("small_inputs", memory.NewMaybeRelocatableFelt(small_inputs), vm) + + return nil +} From 6a0b68cb7f20f396cce8d844602b37e2860f4c09 Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 29 Sep 2023 12:01:29 -0300 Subject: [PATCH 8/8] Assert le felt v 0 8 hint and tests --- pkg/hints/hint_codes/math_hint_codes.go | 2 + pkg/hints/hint_processor.go | 2 + pkg/hints/math_hints.go | 18 +++++++++ pkg/hints/math_hints_test.go | 54 +++++++++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/pkg/hints/hint_codes/math_hint_codes.go b/pkg/hints/hint_codes/math_hint_codes.go index b0db9236..7c517534 100644 --- a/pkg/hints/hint_codes/math_hint_codes.go +++ b/pkg/hints/hint_codes/math_hint_codes.go @@ -44,3 +44,5 @@ const SPLIT_INT = "memory[ids.output] = res = (int(ids.value) % PRIME) % ids.bas const SPLIT_INT_ASSERT_RANGE = "assert ids.value == 0, 'split_int(): value is out of range.'" const ASSERT_LE_FELT_V_0_6 = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\nassert (ids.a % PRIME) <= (ids.b % PRIME), \\\n f'a = {ids.a % PRIME} is not less than or equal to b = {ids.b % PRIME}.'" + +const ASSERT_LE_FELT_V_0_8 = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert_integer(ids.b)\na = ids.a % PRIME\nb = ids.b % PRIME\nassert a <= b, f'a = {a} is not less than or equal to b = {b}.'\n\nids.small_inputs = int(\n a < range_check_builtin.bound and (b - a) < range_check_builtin.bound)" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 50b56775..49fc8158 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -192,6 +192,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return bigintPackDivMod(vm, execScopes, data.Ids) case ASSERT_LE_FELT_V_0_6: return assertLeFeltV06(vm, data.Ids) + case ASSERT_LE_FELT_V_0_8: + return assertLeFeltV08(vm, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/math_hints.go b/pkg/hints/math_hints.go index 5e1ce350..c0ed9577 100644 --- a/pkg/hints/math_hints.go +++ b/pkg/hints/math_hints.go @@ -623,6 +623,24 @@ func assertLeFeltV06(vm *VirtualMachine, ids IdsManager) error { return errors.New(err) } + return nil +} + +func assertLeFeltV08(vm *VirtualMachine, ids IdsManager) error { + a, err := ids.GetFelt("a", vm) + if err != nil { + return err + } + + b, err := ids.GetFelt("b", vm) + if err != nil { + return err + } + if a.Cmp(b) == 1 { + err := fmt.Sprintf("Assertion failed, %s, is not less or equal to %s", a.ToHexString(), b.ToHexString()) + return errors.New(err) + } + bound, err := vm.GetRangeCheckBound() if err != nil { return err diff --git a/pkg/hints/math_hints_test.go b/pkg/hints/math_hints_test.go index 296dfb8e..97706d16 100644 --- a/pkg/hints/math_hints_test.go +++ b/pkg/hints/math_hints_test.go @@ -1138,3 +1138,57 @@ func TestSplitIntAssertRangeHintOutOfRangeError(t *testing.T) { t.Errorf("SPLIT_INT_ASSERT_RANGE hint should have failed") } } + +func TestAssertLeFeltV06AssertionFail(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + vm.RunContext.Fp = memory.NewRelocatable(1, 2) + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "a": {NewMaybeRelocatableFelt(FeltFromDecString("17"))}, + "b": {NewMaybeRelocatableFelt(FeltFromDecString("7"))}, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: ASSERT_LE_FELT_V_0_6, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil) + + if err == nil { + t.Errorf("ASSERT_LE_FELT_V_0_6 hint should have failed") + } + +} + +func TestAssertLeFeltV08AssertionFail(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + vm.RunContext.Fp = memory.NewRelocatable(1, 2) + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "a": {NewMaybeRelocatableFelt(FeltFromDecString("17"))}, + "b": {NewMaybeRelocatableFelt(FeltFromDecString("7"))}, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: ASSERT_LE_FELT_V_0_8, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil) + + if err == nil { + t.Errorf("ASSERT_LE_FELT_V_0_6 hint should have failed") + } + +}