From 977ba29fcdddd64516182b34c7dd9abcccc1101a Mon Sep 17 00:00:00 2001 From: Milton Date: Thu, 14 Sep 2023 15:37:32 -0300 Subject: [PATCH 01/86] Add ec hints --- pkg/hints/ec_hint.go | 92 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 pkg/hints/ec_hint.go diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go new file mode 100644 index 00000000..33a6c162 --- /dev/null +++ b/pkg/hints/ec_hint.go @@ -0,0 +1,92 @@ +package hints + +import ( + "errors" + "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/vm" + "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" +) + +type BigInt3 struct { + limbs []lambdaworks.Felt +} + +type EcPoint struct { + X BigInt3 + Y BigInt3 +} + +func (val *BigInt3) Pack86() big.Int { + sum := big.NewInt(0) + for i := 0; i < 3; i++ { + felt := val.limbs[i] + signed := felt.ToSigned() + shifed := new(big.Int).Lsh(signed, uint(i*86)) + sum.Add(sum, shifed) + } + return *sum +} + +func FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMachine) (BigInt3, error) { + limbs := make([]lambdaworks.Felt, 0) + for i := 0; i < 3; i++ { + felt, err := virtual_machine.Segments.Memory.GetFelt(addr.AddUint(uint(i))) + if err == nil { + limbs = append(limbs, felt) + } else { + return BigInt3{}, errors.New("Identifier has no member") + } + } + return BigInt3{limbs: limbs}, nil +} + +func FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { + point_addr, err := ids_data.GetAddr(name, &virtual_machine) + if err != nil { + return EcPoint{}, err + } + + x, err := FromBaseAddr(point_addr, virtual_machine) + if err != nil { + return EcPoint{}, err + } + + y, err := FromBaseAddr(point_addr.AddUint(3), virtual_machine) + if err != nil { + return EcPoint{}, err + } + + return EcPoint{X: x, Y: y}, nil +} + +/* +Implements main logic for `EC_NEGATE` and `EC_NEGATE_EMBEDDED_SECP` hints +*/ +func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, secp_p big.Int) error { + point, err := ids_data.GetRelocatable("point", &virtual_machine) + if err != nil { + return err + } + + point_y, err := point.AddInt(3) + if err != nil { + return err + } + + y_bigint3, err := FromBaseAddr(point_y, virtual_machine) + if err != nil { + return err + } + + y := y_bigint3.Pack86() + value := new(big.Int).Neg(&y) + value.Mod(value, &secp_p) + + exec_scopes.AssignOrUpdateVariable("value", value) + exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) + return nil +} From 70a9db2e91ebcf550f2aef0bc071d141d5baf557 Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 15 Sep 2023 14:23:23 -0300 Subject: [PATCH 02/86] Implement hints --- pkg/hints/ec_hint.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 33a6c162..57a35074 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -90,3 +90,28 @@ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionSco exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) return nil } + +func EcNegateImportSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { + secp_p, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) + return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) +} + +/* +Implements hint: +%{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + SECP_P = 2**255-19 + + y = pack(ids.point.y, PRIME) % SECP_P + # The modulo operation in python always returns a nonnegative number. + value = (-y) % SECP_P +%} +*/ + +func EcNegateEmbeddedSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { + secp_p := big.NewInt(1) + secp_p.Lsh(secp_p, 256) + secp_p.Sub(secp_p, big.NewInt(19)) + + return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) +} From 864b7b87c9d30dfab2337c92d3595052ff31c201 Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 15 Sep 2023 15:13:26 -0300 Subject: [PATCH 03/86] Add the hints to the processor --- pkg/hints/ec_hint.go | 4 ++-- pkg/hints/hint_codes/ec_op_hints.go | 4 ++++ pkg/hints/{ => hint_codes}/math_hint_codes.go | 2 +- pkg/hints/{ => hint_codes}/memcpy_hint_codes.go | 2 +- pkg/hints/hint_processor.go | 5 +++++ pkg/hints/math_hints_test.go | 1 + pkg/hints/memcpy_hints_test.go | 1 + 7 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 pkg/hints/hint_codes/ec_op_hints.go rename pkg/hints/{ => hint_codes}/math_hint_codes.go (98%) rename pkg/hints/{ => hint_codes}/memcpy_hint_codes.go (82%) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 57a35074..95e89096 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -91,7 +91,7 @@ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionSco return nil } -func EcNegateImportSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { +func ec_negate_import_secp_p(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { secp_p, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) } @@ -108,7 +108,7 @@ Implements hint: %} */ -func EcNegateEmbeddedSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { +func ec_negate_embedded_secp_p(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { secp_p := big.NewInt(1) secp_p.Lsh(secp_p, 256) secp_p.Sub(secp_p, big.NewInt(19)) diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go new file mode 100644 index 00000000..c2092a7f --- /dev/null +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -0,0 +1,4 @@ +package hint_codes + +const EC_NEGATE = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P" +const EC_NEGATE_EMBEDDED_SECP = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nSECP_P = 2**255-19\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P" diff --git a/pkg/hints/math_hint_codes.go b/pkg/hints/hint_codes/math_hint_codes.go similarity index 98% rename from pkg/hints/math_hint_codes.go rename to pkg/hints/hint_codes/math_hint_codes.go index 4eead668..0bf0f36e 100644 --- a/pkg/hints/math_hint_codes.go +++ b/pkg/hints/hint_codes/math_hint_codes.go @@ -1,4 +1,4 @@ -package hints +package hint_codes const ASSERT_NN = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.a)\nassert 0 <= ids.a % PRIME < range_check_builtin.bound, f'a = {ids.a} is out of range.'" diff --git a/pkg/hints/memcpy_hint_codes.go b/pkg/hints/hint_codes/memcpy_hint_codes.go similarity index 82% rename from pkg/hints/memcpy_hint_codes.go rename to pkg/hints/hint_codes/memcpy_hint_codes.go index 71e356c5..68efc0de 100644 --- a/pkg/hints/memcpy_hint_codes.go +++ b/pkg/hints/hint_codes/memcpy_hint_codes.go @@ -1,4 +1,4 @@ -package hints +package hint_codes const ADD_SEGMENT = "memory[ap] = segments.add()" const VM_EXIT_SCOPE = "vm_exit_scope()" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index e12c7194..acbe5175 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -3,6 +3,7 @@ package hints import ( "strings" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" . "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/parser" @@ -51,6 +52,10 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return vm_exit_scope(execScopes) case ASSERT_NOT_EQUAL: return assert_not_equal(data.Ids, vm) + case EC_NEGATE: + return ec_negate_import_secp_p(*vm, *execScopes, data.Ids) + case EC_NEGATE_EMBEDDED_SECP: + return ec_negate_embedded_secp_p(*vm, *execScopes, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/math_hints_test.go b/pkg/hints/math_hints_test.go index efd08f43..3c76bcac 100644 --- a/pkg/hints/math_hints_test.go +++ b/pkg/hints/math_hints_test.go @@ -4,6 +4,7 @@ import ( "testing" . "github.com/lambdaclass/cairo-vm.go/pkg/hints" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" . "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/vm" diff --git a/pkg/hints/memcpy_hints_test.go b/pkg/hints/memcpy_hints_test.go index 758b0717..19c0cde7 100644 --- a/pkg/hints/memcpy_hints_test.go +++ b/pkg/hints/memcpy_hints_test.go @@ -4,6 +4,7 @@ import ( "testing" . "github.com/lambdaclass/cairo-vm.go/pkg/hints" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" . "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" From 7df419225f828f5876869fe6191d71edac02ad5c Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 15 Sep 2023 16:48:03 -0300 Subject: [PATCH 04/86] Test pack86 function --- pkg/hints/ec_hint.go | 6 +++--- pkg/hints/ec_hint_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 pkg/hints/ec_hint_test.go diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 95e89096..8cd5cdfc 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -12,7 +12,7 @@ import ( ) type BigInt3 struct { - limbs []lambdaworks.Felt + Limbs []lambdaworks.Felt } type EcPoint struct { @@ -23,7 +23,7 @@ type EcPoint struct { func (val *BigInt3) Pack86() big.Int { sum := big.NewInt(0) for i := 0; i < 3; i++ { - felt := val.limbs[i] + felt := val.Limbs[i] signed := felt.ToSigned() shifed := new(big.Int).Lsh(signed, uint(i*86)) sum.Add(sum, shifed) @@ -41,7 +41,7 @@ func FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMachine) (B return BigInt3{}, errors.New("Identifier has no member") } } - return BigInt3{limbs: limbs}, nil + return BigInt3{Limbs: limbs}, nil } func FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go new file mode 100644 index 00000000..76afdce6 --- /dev/null +++ b/pkg/hints/ec_hint_test.go @@ -0,0 +1,31 @@ +package hints_test + +import ( + "math/big" + "testing" + + "github.com/lambdaclass/cairo-vm.go/pkg/hints" + "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" +) + +func TestBigInt3Pack86(t *testing.T) { + limbs1 := []lambdaworks.Felt{lambdaworks.FeltFromUint64(10), lambdaworks.FeltFromUint64(10), lambdaworks.FeltFromUint64(10)} + bigint := hints.BigInt3{Limbs: limbs1} + pack1 := bigint.Pack86() + + expected, _ := new(big.Int).SetString("59863107065073783529622931521771477038469668772249610", 10) + + if pack1.Cmp(expected) != 0 { + t.Errorf("Different pack from expected") + } + + limbs2 := []lambdaworks.Felt{lambdaworks.FeltFromDecString("773712524553362"), lambdaworks.FeltFromDecString("57408430697461422066401280"), lambdaworks.FeltFromDecString("1292469707114105")} + bigint2 := hints.BigInt3{Limbs: limbs2} + pack2 := bigint2.Pack86() + + expected2, _ := new(big.Int).SetString("7737125245533626718119526477371252455336267181195264773712524553362", 10) + + if pack2.Cmp(expected2) != 0 { + t.Errorf("Different pack from expected2") + } +} \ No newline at end of file From 1a663098db49b3056da639ff229a45364ea282b8 Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 15 Sep 2023 18:46:32 -0300 Subject: [PATCH 05/86] Test hint --- pkg/hints/ec_hint.go | 3 ++ pkg/hints/ec_hint_test.go | 74 ++++++++++++++++++++++++++++++++++--- pkg/hints/hint_processor.go | 4 ++ 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 8cd5cdfc..16240678 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -2,6 +2,7 @@ package hints import ( "errors" + "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" @@ -67,6 +68,7 @@ func FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_u Implements main logic for `EC_NEGATE` and `EC_NEGATE_EMBEDDED_SECP` hints */ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, secp_p big.Int) error { + fmt.Println("inside negate") point, err := ids_data.GetRelocatable("point", &virtual_machine) if err != nil { return err @@ -92,6 +94,7 @@ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionSco } func ec_negate_import_secp_p(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { + fmt.Println("ec negate sec") secp_p, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) } diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 76afdce6..1b2a5186 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -4,13 +4,18 @@ import ( "math/big" "testing" - "github.com/lambdaclass/cairo-vm.go/pkg/hints" - "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" + . "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/vm" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" + ) func TestBigInt3Pack86(t *testing.T) { - limbs1 := []lambdaworks.Felt{lambdaworks.FeltFromUint64(10), lambdaworks.FeltFromUint64(10), lambdaworks.FeltFromUint64(10)} - bigint := hints.BigInt3{Limbs: limbs1} + limbs1 := []Felt{FeltFromUint64(10), FeltFromUint64(10), FeltFromUint64(10)} + bigint := BigInt3{Limbs: limbs1} pack1 := bigint.Pack86() expected, _ := new(big.Int).SetString("59863107065073783529622931521771477038469668772249610", 10) @@ -19,8 +24,8 @@ func TestBigInt3Pack86(t *testing.T) { t.Errorf("Different pack from expected") } - limbs2 := []lambdaworks.Felt{lambdaworks.FeltFromDecString("773712524553362"), lambdaworks.FeltFromDecString("57408430697461422066401280"), lambdaworks.FeltFromDecString("1292469707114105")} - bigint2 := hints.BigInt3{Limbs: limbs2} + limbs2 := []Felt{FeltFromDecString("773712524553362"), FeltFromDecString("57408430697461422066401280"), FeltFromDecString("1292469707114105")} + bigint2 := BigInt3{Limbs: limbs2} pack2 := bigint2.Pack86() expected2, _ := new(big.Int).SetString("7737125245533626718119526477371252455336267181195264773712524553362", 10) @@ -28,4 +33,61 @@ func TestBigInt3Pack86(t *testing.T) { if pack2.Cmp(expected2) != 0 { t.Errorf("Different pack from expected2") } +} + + + +// fn run_ec_negate_ok() { +// let hint_code = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P"; +// let mut vm = vm_with_range_check!(); + +// vm.segments = segments![((1, 3), 2645i32), ((1, 4), 454i32), ((1, 5), 206i32)]; +// //Initialize fp +// vm.run_context.fp = 1; +// //Create hint_data +// let ids_data = ids_data!["point"]; +// let mut exec_scopes = ExecutionScopes::new(); +// //Execute the hint +// assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); +// //Check 'value' is defined in the vm scope +// assert_matches!( +// exec_scopes.get::("value"), +// Ok(x) if x == bigint_str!( +// "115792089237316195423569751828682367333329274433232027476421668138471189901786" +// ) +// ); +// } + +func TestRunEcNegateOk(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.Memory.Insert(NewRelocatable(1,3), NewMaybeRelocatableFelt(FeltFromUint64(2645))) + vm.Segments.Memory.Insert(NewRelocatable(1,4), NewMaybeRelocatableFelt(FeltFromUint64(454))) + vm.Segments.Memory.Insert(NewRelocatable(1,5), NewMaybeRelocatableFelt(FeltFromUint64(206))) + + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "point": {NewMaybeRelocatableFelt(FeltFromDecString("-1"))}, + "ec_negative": {nil}, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: EC_NEGATE, + }) + err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil) + if err != nil { + t.Errorf("Ec Negative hint test failed with error %s", err) + } + // Check ids.is_positive + value, err := idsManager.GetFelt("value", vm) + expected := FeltFromDecString("115792089237316195423569751828682367333329274433232027476421668138471189901786") + + if err != nil || value != expected { + t.Errorf("Ec Negative hint test incorrect value for ids.value") + } } \ No newline at end of file diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index acbe5175..e7a0eb3f 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -1,6 +1,7 @@ package hints import ( + "fmt" "strings" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" @@ -53,6 +54,9 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, case ASSERT_NOT_EQUAL: return assert_not_equal(data.Ids, vm) case EC_NEGATE: + fmt.Println("match case") + fmt.Println("vm: ", vm) + fmt.Println("escopes", execScopes) return ec_negate_import_secp_p(*vm, *execScopes, data.Ids) case EC_NEGATE_EMBEDDED_SECP: return ec_negate_embedded_secp_p(*vm, *execScopes, data.Ids) From 91ffa57fe1782cb1d88e64d9e2e77b69ea635d5b Mon Sep 17 00:00:00 2001 From: Milton Date: Mon, 18 Sep 2023 11:17:48 -0300 Subject: [PATCH 06/86] Delete debug info, Test ec negative op --- pkg/hints/ec_hint.go | 3 --- pkg/hints/ec_hint_test.go | 34 +++++++++++++++++----------------- pkg/hints/hint_processor.go | 4 ---- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 16240678..8cd5cdfc 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -2,7 +2,6 @@ package hints import ( "errors" - "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" @@ -68,7 +67,6 @@ func FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_u Implements main logic for `EC_NEGATE` and `EC_NEGATE_EMBEDDED_SECP` hints */ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, secp_p big.Int) error { - fmt.Println("inside negate") point, err := ids_data.GetRelocatable("point", &virtual_machine) if err != nil { return err @@ -94,7 +92,6 @@ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionSco } func ec_negate_import_secp_p(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { - fmt.Println("ec negate sec") secp_p, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) } diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 1b2a5186..cbb22037 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -8,9 +8,9 @@ import ( . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" . "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/vm" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" - ) func TestBigInt3Pack86(t *testing.T) { @@ -35,8 +35,6 @@ func TestBigInt3Pack86(t *testing.T) { } } - - // fn run_ec_negate_ok() { // let hint_code = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P"; // let mut vm = vm_with_range_check!(); @@ -62,14 +60,13 @@ func TestRunEcNegateOk(t *testing.T) { vm := NewVirtualMachine() vm.Segments.AddSegment() vm.Segments.AddSegment() - vm.Segments.Memory.Insert(NewRelocatable(1,3), NewMaybeRelocatableFelt(FeltFromUint64(2645))) - vm.Segments.Memory.Insert(NewRelocatable(1,4), NewMaybeRelocatableFelt(FeltFromUint64(454))) - vm.Segments.Memory.Insert(NewRelocatable(1,5), NewMaybeRelocatableFelt(FeltFromUint64(206))) - + vm.Segments.Memory.Insert(NewRelocatable(1, 3), NewMaybeRelocatableFelt(FeltFromUint64(2645))) + vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(454))) + vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(206))) idsManager := SetupIdsForTest( map[string][]*MaybeRelocatable{ - "point": {NewMaybeRelocatableFelt(FeltFromDecString("-1"))}, + "point": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 0))}, "ec_negative": {nil}, }, vm, @@ -79,15 +76,18 @@ func TestRunEcNegateOk(t *testing.T) { Ids: idsManager, Code: EC_NEGATE, }) - err := hintProcessor.ExecuteHint(vm, &hintData, nil, nil) + exec_scopes := types.NewExecutionScopes() + err := hintProcessor.ExecuteHint(vm, &hintData, nil, exec_scopes) if err != nil { t.Errorf("Ec Negative hint test failed with error %s", err) + } else { + // Check ids.is_positive + value, err := exec_scopes.Get("value") + val := value.(*big.Int) + expected, _ := new(big.Int).SetString("115792089237316195423569751828682367333329274433232027476421668138471189901786", 10) + + if err != nil || expected.Cmp(val) != 0 { + t.Errorf("Ec Negative hint test incorrect value for exec_scopes.value") + } } - // Check ids.is_positive - value, err := idsManager.GetFelt("value", vm) - expected := FeltFromDecString("115792089237316195423569751828682367333329274433232027476421668138471189901786") - - if err != nil || value != expected { - t.Errorf("Ec Negative hint test incorrect value for ids.value") - } -} \ No newline at end of file +} diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index e7a0eb3f..acbe5175 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -1,7 +1,6 @@ package hints import ( - "fmt" "strings" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" @@ -54,9 +53,6 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, case ASSERT_NOT_EQUAL: return assert_not_equal(data.Ids, vm) case EC_NEGATE: - fmt.Println("match case") - fmt.Println("vm: ", vm) - fmt.Println("escopes", execScopes) return ec_negate_import_secp_p(*vm, *execScopes, data.Ids) case EC_NEGATE_EMBEDDED_SECP: return ec_negate_embedded_secp_p(*vm, *execScopes, data.Ids) From 7bf190976a7591ffe1c7552be20e2f8cd8ca1472 Mon Sep 17 00:00:00 2001 From: Milton Date: Mon, 18 Sep 2023 13:04:36 -0300 Subject: [PATCH 07/86] Second hint test --- pkg/hints/ec_hint.go | 4 +- pkg/hints/ec_hint_test.go | 85 +++++++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 22 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 8cd5cdfc..065f9050 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -2,6 +2,7 @@ package hints import ( "errors" + "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" @@ -68,6 +69,7 @@ Implements main logic for `EC_NEGATE` and `EC_NEGATE_EMBEDDED_SECP` hints */ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, secp_p big.Int) error { point, err := ids_data.GetRelocatable("point", &virtual_machine) + fmt.Println("point ", point) if err != nil { return err } @@ -109,9 +111,9 @@ Implements hint: */ func ec_negate_embedded_secp_p(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { + fmt.Println("inside hint") secp_p := big.NewInt(1) secp_p.Lsh(secp_p, 256) secp_p.Sub(secp_p, big.NewInt(19)) - return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) } diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index cbb22037..cbf25a45 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -1,6 +1,7 @@ package hints_test import ( + "fmt" "math/big" "testing" @@ -35,27 +36,6 @@ func TestBigInt3Pack86(t *testing.T) { } } -// fn run_ec_negate_ok() { -// let hint_code = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P"; -// let mut vm = vm_with_range_check!(); - -// vm.segments = segments![((1, 3), 2645i32), ((1, 4), 454i32), ((1, 5), 206i32)]; -// //Initialize fp -// vm.run_context.fp = 1; -// //Create hint_data -// let ids_data = ids_data!["point"]; -// let mut exec_scopes = ExecutionScopes::new(); -// //Execute the hint -// assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); -// //Check 'value' is defined in the vm scope -// assert_matches!( -// exec_scopes.get::("value"), -// Ok(x) if x == bigint_str!( -// "115792089237316195423569751828682367333329274433232027476421668138471189901786" -// ) -// ); -// } - func TestRunEcNegateOk(t *testing.T) { vm := NewVirtualMachine() vm.Segments.AddSegment() @@ -71,6 +51,9 @@ func TestRunEcNegateOk(t *testing.T) { }, vm, ) + + point, _ := idsManager.Get("point", vm) + fmt.Println("Ids manager: ", point) hintProcessor := CairoVmHintProcessor{} hintData := any(HintData{ Ids: idsManager, @@ -91,3 +74,63 @@ func TestRunEcNegateOk(t *testing.T) { } } } + +func TestRunEcEmbeddedSecpOk(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.Memory.Insert(NewRelocatable(1, 3), NewMaybeRelocatableFelt(FeltFromUint64(2645))) + vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(454))) + vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(206))) + + y2 := big.NewInt(206) + y2.Lsh(y2, 86*2) + + y1 := big.NewInt(454) + y1.Lsh(y1, 86) + + y0 := big.NewInt(2645) + + y := new(big.Int) + y.Add(y, y2) + y.Add(y, y1) + y.Add(y, y0) + + //vm.RunContext.Fp = NewRelocatable(1,0) + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "point": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 0))}, + "ec_negative": {nil}, + }, + vm, + ) + + point, _ := idsManager.Get("point", vm) + fmt.Println("Ids manager: ", point) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: EC_NEGATE_EMBEDDED_SECP, + }) + exec_scopes := types.NewExecutionScopes() + err := hintProcessor.ExecuteHint(vm, &hintData, nil, exec_scopes) + if err != nil { + t.Errorf("Ec Negative Embedded Sec hint test failed with error %s", err) + } else { + // Check ids.is_positive + value, err := exec_scopes.Get("value") + val := value.(*big.Int) + + // expected value + minus_y := big.NewInt(1) + minus_y.Lsh(minus_y, 255) + minus_y.Sub(minus_y, big.NewInt(19)) + minus_y.Sub(minus_y, y) + + if err != nil || minus_y.Cmp(val) != 0 { + t.Errorf("Ec Negative hint test incorrect value for exec_scopes.value") + } + } + +} From a08c642fc3d7e5eb7bbd902009bb199d99adf1a2 Mon Sep 17 00:00:00 2001 From: Milton Date: Mon, 18 Sep 2023 13:51:26 -0300 Subject: [PATCH 08/86] Test embedded hint --- pkg/hints/ec_hint.go | 2 +- pkg/hints/ec_hint_test.go | 116 +++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 60 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index d81f19f1..270822cd 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -112,7 +112,7 @@ Implements hint: func ec_negate_embedded_secp_p(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { secp_p := big.NewInt(1) - secp_p.Lsh(secp_p, 256) + secp_p.Lsh(secp_p, 255) secp_p.Sub(secp_p, big.NewInt(19)) return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) } diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 656275e1..bed5fbe3 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -75,62 +75,60 @@ func TestRunEcNegateOk(t *testing.T) { } } -// func TestRunEcEmbeddedSecpOk(t *testing.T) { -// vm := NewVirtualMachine() -// vm.Segments.AddSegment() -// vm.Segments.AddSegment() -// vm.Segments.Memory.Insert(NewRelocatable(1, 3), NewMaybeRelocatableFelt(FeltFromUint64(2645))) -// vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(454))) -// vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(206))) - -// y2 := big.NewInt(206) -// y2.Lsh(y2, 86*2) - -// y1 := big.NewInt(454) -// y1.Lsh(y1, 86) - -// y0 := big.NewInt(2645) - -// y := new(big.Int) -// y.Add(y, y2) -// y.Add(y, y1) -// y.Add(y, y0) - -// //vm.RunContext.Fp = NewRelocatable(1,0) - -// idsManager := SetupIdsForTest( -// map[string][]*MaybeRelocatable{ -// "point": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 0))}, -// "ec_negative": {nil}, -// }, -// vm, -// ) - -// point, _ := idsManager.Get("point", vm) -// fmt.Println("Ids manager: ", point) -// hintProcessor := CairoVmHintProcessor{} -// hintData := any(HintData{ -// Ids: idsManager, -// Code: EC_NEGATE_EMBEDDED_SECP, -// }) -// exec_scopes := types.NewExecutionScopes() -// err := hintProcessor.ExecuteHint(vm, &hintData, nil, exec_scopes) -// if err != nil { -// t.Errorf("Ec Negative Embedded Sec hint test failed with error %s", err) -// } else { -// // Check ids.is_positive -// value, err := exec_scopes.Get("value") -// val := value.(*big.Int) - -// // expected value -// minus_y := big.NewInt(1) -// minus_y.Lsh(minus_y, 255) -// minus_y.Sub(minus_y, big.NewInt(19)) -// minus_y.Sub(minus_y, y) - -// if err != nil || minus_y.Cmp(val) != 0 { -// t.Errorf("Ec Negative hint test incorrect value for exec_scopes.value") -// } -// } - -// } +func TestRunEcEmbeddedSecpOk(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.Memory.Insert(NewRelocatable(1, 3), NewMaybeRelocatableFelt(FeltFromUint64(2645))) + vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(454))) + vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(206))) + + y2 := big.NewInt(206) + y2.Lsh(y2, 86*2) + + y1 := big.NewInt(454) + y1.Lsh(y1, 86) + + y0 := big.NewInt(2645) + + y := new(big.Int) + y.Add(y, y2) + y.Add(y, y1) + y.Add(y, y0) + + vm.RunContext.Fp = NewRelocatable(1, 1) + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "point": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 0))}, + "ec_negative": {nil}, + }, + vm, + ) + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: EC_NEGATE_EMBEDDED_SECP, + }) + exec_scopes := types.NewExecutionScopes() + err := hintProcessor.ExecuteHint(vm, &hintData, nil, exec_scopes) + if err != nil { + t.Errorf("Ec Negative Embedded Sec hint test failed with error %s", err) + } else { + // Check ids.is_positive + value, err := exec_scopes.Get("value") + val := value.(*big.Int) + + // expected value + minus_y := big.NewInt(1) + minus_y.Lsh(minus_y, 255) + minus_y.Sub(minus_y, big.NewInt(19)) + minus_y.Sub(minus_y, y) + + if err != nil || minus_y.Cmp(val) != 0 { + t.Errorf("Ec Negative hint test incorrect value for exec_scopes.value") + } + } + +} From 6c6eed9613848d3d047e8b131a998e2e20717c93 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 07:48:03 -0300 Subject: [PATCH 09/86] Change to Camel case --- pkg/hints/ec_hint.go | 22 ++++++++++------------ pkg/hints/hint_processor.go | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 270822cd..8c83ff07 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -2,7 +2,6 @@ package hints import ( "errors" - "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" @@ -32,7 +31,7 @@ func (val *BigInt3) Pack86() big.Int { return *sum } -func FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMachine) (BigInt3, error) { +func BigInt3FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMachine) (BigInt3, error) { limbs := make([]lambdaworks.Felt, 0) for i := 0; i < 3; i++ { felt, err := virtual_machine.Segments.Memory.GetFelt(addr.AddUint(uint(i))) @@ -45,18 +44,18 @@ func FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMachine) (B return BigInt3{Limbs: limbs}, nil } -func FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { +func BigInt3FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { point_addr, err := ids_data.GetAddr(name, &virtual_machine) if err != nil { return EcPoint{}, err } - x, err := FromBaseAddr(point_addr, virtual_machine) + x, err := BigInt3FromBaseAddr(point_addr, virtual_machine) if err != nil { return EcPoint{}, err } - y, err := FromBaseAddr(point_addr.AddUint(3), virtual_machine) + y, err := BigInt3FromBaseAddr(point_addr.AddUint(3), virtual_machine) if err != nil { return EcPoint{}, err } @@ -67,9 +66,8 @@ func FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_u /* Implements main logic for `EC_NEGATE` and `EC_NEGATE_EMBEDDED_SECP` hints */ -func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, secp_p big.Int) error { +func ecNegate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, secp_p big.Int) error { point, err := ids_data.GetRelocatable("point", &virtual_machine) - fmt.Println("point ", point) if err != nil { return err } @@ -79,7 +77,7 @@ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionSco return err } - y_bigint3, err := FromBaseAddr(point_y, virtual_machine) + y_bigint3, err := BigInt3FromBaseAddr(point_y, virtual_machine) if err != nil { return err } @@ -93,9 +91,9 @@ func ec_negate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionSco return nil } -func ec_negate_import_secp_p(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { +func ecNegateImportSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { secp_p, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) - return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) + return ecNegate(virtual_machine, exec_scopes, ids_data, *secp_p) } /* @@ -110,9 +108,9 @@ Implements hint: %} */ -func ec_negate_embedded_secp_p(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { +func ecNegateEmbeddedSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { secp_p := big.NewInt(1) secp_p.Lsh(secp_p, 255) secp_p.Sub(secp_p, big.NewInt(19)) - return ec_negate(virtual_machine, exec_scopes, ids_data, *secp_p) + return ecNegate(virtual_machine, exec_scopes, ids_data, *secp_p) } diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index dbd1c2ed..ccc26810 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -63,9 +63,9 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, case ASSERT_NOT_EQUAL: return assert_not_equal(data.Ids, vm) case EC_NEGATE: - return ec_negate_import_secp_p(*vm, *execScopes, data.Ids) + return ecNegateImportSecpP(*vm, *execScopes, data.Ids) case EC_NEGATE_EMBEDDED_SECP: - return ec_negate_embedded_secp_p(*vm, *execScopes, data.Ids) + return ecNegateEmbeddedSecpP(*vm, *execScopes, data.Ids) case POW: return pow(data.Ids, vm) case SQRT: From ec9345c31f711995264a1257fb165ce4da796f30 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 10:24:58 -0300 Subject: [PATCH 10/86] Implement slope hints --- pkg/hints/ec_hint.go | 95 +++++++++++++++++++++++++++++ pkg/hints/hint_codes/ec_op_hints.go | 2 + pkg/hints/hint_processor.go | 4 ++ pkg/hints/hint_utils/secp_utils.go | 13 ++++ 4 files changed, 114 insertions(+) create mode 100644 pkg/hints/hint_utils/secp_utils.go diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 8c83ff07..ec4e1c96 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -4,6 +4,7 @@ import ( "errors" "math/big" + "github.com/lambdaclass/cairo-vm.go/pkg/builtins" "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" @@ -114,3 +115,97 @@ func ecNegateEmbeddedSecpP(virtual_machine vm.VirtualMachine, exec_scopes types. secp_p.Sub(secp_p, big.NewInt(19)) return ecNegate(virtual_machine, exec_scopes, ids_data, *secp_p) } + +/* +Implements hint: + + %{ + from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack + from starkware.python.math_utils import ec_double_slope + + # Compute the slope. + x = pack(ids.point.x, PRIME) + y = pack(ids.point.y, PRIME) + value = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P) + +%} +*/ +func computeDoublingSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point_alias string, secp_p big.Int, alpha big.Int) error { + exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) + + point, err := BigInt3FromVarName(point_alias, virtual_machine, ids_data) + if err != nil { + return err + } + + x := point.X.Pack86() + y := point.Y.Pack86() + double_point := builtins.DoublePointB{X: x, Y: y} + + value, err := builtins.EcDoubleSlope(double_point, alpha, secp_p) + if err != nil { + return err + } + + exec_scopes.AssignOrUpdateVariable("value", value) + exec_scopes.AssignOrUpdateVariable("slope", value) + + return nil +} + +/* +Implements hint: +%{ + from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack + from starkware.python.math_utils import line_slope + + # Compute the slope. + x0 = pack(ids.point0.x, PRIME) + y0 = pack(ids.point0.y, PRIME) + x1 = pack(ids.point1.x, PRIME) + y1 = pack(ids.point1.y, PRIME) + value = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P) +%} +*/ + +func computeSlopeAndAssingSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point0_alias string, point1_alias string, secp_p big.Int) error { + exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) + return computeSlope(virtual_machine, exec_scopes, ids_data, point0_alias, point1_alias) +} + +func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point0_alias string, point1_alias string) error { + point0, err := BigInt3FromVarName(point0_alias, virtual_machine, ids_data) + if err != nil { + return err + } + point1, err := BigInt3FromVarName(point1_alias, virtual_machine, ids_data) + if err != nil { + return err + } + + secp_p, err := exec_scopes.Get("SECP_P") + if err != nil { + return err + } + secp := secp_p.(big.Int) + + // build partial sum + x0 := point0.X.Pack86() + y0 := point0.Y.Pack86() + point_a := builtins.PartialSumB{X: x0, Y: y0} + + // build double point + x1 := point1.X.Pack86() + y1 := point1.Y.Pack86() + point_b := builtins.DoublePointB{X: x1, Y: y1} + + value, err := builtins.LineSlope(point_a, point_b, secp) + if err != nil { + return err + } + + exec_scopes.AssignOrUpdateVariable("value", value) + exec_scopes.AssignOrUpdateVariable("slope", value) + + return nil +} diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index c2092a7f..254720c5 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -2,3 +2,5 @@ package hint_codes const EC_NEGATE = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P" const EC_NEGATE_EMBEDDED_SECP = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nSECP_P = 2**255-19\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P" +const EC_DOUBLE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P)" +const COMPUTE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import line_slope\n\n# Compute the slope.\nx0 = pack(ids.point0.x, PRIME)\ny0 = pack(ids.point0.y, PRIME)\nx1 = pack(ids.point1.x, PRIME)\ny1 = pack(ids.point1.y, PRIME)\nvalue = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index ccc26810..a15cd939 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -74,6 +74,10 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return memcpy_enter_scope(data.Ids, vm, execScopes) case VM_ENTER_SCOPE: return vm_enter_scope(execScopes) + case COMPUTE_SLOPE_V1: + return computeSlopeAndAssingSecpP(*vm, *execScopes, data.Ids, "point0", "point1", SECP_P()) + case EC_DOUBLE_SLOPE_V1: + return computeDoublingSlope(*vm, *execScopes, data.Ids, "point", SECP_P(), ALPHA()) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go new file mode 100644 index 00000000..f531944c --- /dev/null +++ b/pkg/hints/hint_utils/secp_utils.go @@ -0,0 +1,13 @@ +package hint_utils + +import "math/big" + +func SECP_P() big.Int { + secp_p, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) + return *secp_p +} + +func ALPHA() big.Int { + alpha := big.NewInt(0) + return *alpha +} From ff7fb500c8dcf3f1a393200b1816141ac58412c4 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 10:26:38 -0300 Subject: [PATCH 11/86] Fix format --- pkg/hints/hint_codes/ec_op_hints.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index 7feaf789..254720c5 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -4,4 +4,3 @@ const EC_NEGATE = "from starkware.cairo.common.cairo_secp.secp_utils import SECP const EC_NEGATE_EMBEDDED_SECP = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nSECP_P = 2**255-19\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P" const EC_DOUBLE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P)" const COMPUTE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import line_slope\n\n# Compute the slope.\nx0 = pack(ids.point0.x, PRIME)\ny0 = pack(ids.point0.y, PRIME)\nx1 = pack(ids.point1.x, PRIME)\ny1 = pack(ids.point1.y, PRIME)\nvalue = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)" - From 4e9afc502a967645bca70e1572c057e4d0ef28d5 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 10:27:28 -0300 Subject: [PATCH 12/86] Delete github conflict string --- pkg/hints/ec_hint.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index c967060d..5668fbaf 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -4,10 +4,7 @@ import ( "errors" "math/big" -<<<<<<< HEAD "github.com/lambdaclass/cairo-vm.go/pkg/builtins" -======= ->>>>>>> main "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" From cc53b652fc6c0fdc56953f63db6cdb1cf123f5c4 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 11:45:32 -0300 Subject: [PATCH 13/86] Tests hints --- pkg/hints/ec_hint.go | 7 ++- pkg/hints/ec_hint_test.go | 102 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 5668fbaf..08747f37 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -2,6 +2,7 @@ package hints import ( "errors" + "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/builtins" @@ -46,7 +47,10 @@ func BigInt3FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMach } func BigInt3FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { + fmt.Println(name) + fmt.Println("ids data", ids_data) point_addr, err := ids_data.GetAddr(name, &virtual_machine) + fmt.Println(point_addr) if err != nil { return EcPoint{}, err } @@ -133,10 +137,12 @@ Implements hint: func computeDoublingSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point_alias string, secp_p big.Int, alpha big.Int) error { exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) + fmt.Println(ids_data) point, err := BigInt3FromVarName(point_alias, virtual_machine, ids_data) if err != nil { return err } + fmt.Println("after point") x := point.X.Pack86() y := point.Y.Pack86() @@ -209,4 +215,3 @@ func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.Execution return nil } - diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index bed5fbe3..db15ef15 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -132,3 +132,105 @@ func TestRunEcEmbeddedSecpOk(t *testing.T) { } } + +// func TestComputeDoublingSlopeOk(t *testing.T) { +// vm := NewVirtualMachine() +// vm.Segments.AddSegment() +// vm.Segments.AddSegment() +// vm.Segments.Memory.Insert(NewRelocatable(1, 0), NewMaybeRelocatableFelt(FeltFromUint64(614323))) +// vm.Segments.Memory.Insert(NewRelocatable(1, 1), NewMaybeRelocatableFelt(FeltFromUint64(5456867))) +// vm.Segments.Memory.Insert(NewRelocatable(1, 2), NewMaybeRelocatableFelt(FeltFromUint64(101208))) +// vm.Segments.Memory.Insert(NewRelocatable(1, 3), NewMaybeRelocatableFelt(FeltFromUint64(773712524))) +// vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(77371252))) +// vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(5298795))) + +// vm.RunContext.Fp = NewRelocatable(1, 1) + +// idsManager := SetupIdsForTest( +// map[string][]*MaybeRelocatable{ +// "point": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 0))}, +// }, +// vm, +// ) + +// hintProcessor := CairoVmHintProcessor{} +// hintData := any(HintData{ +// Ids: idsManager, +// Code: EC_DOUBLE_SLOPE_V1, +// }) + +// exec_scopes := types.NewExecutionScopes() +// err := hintProcessor.ExecuteHint(vm, &hintData, nil, exec_scopes) +// if err != nil { +// t.Errorf("EC_DOUBLE_SLOPE_V1 hint test failed with error %s", err) +// } else { +// value, _ := exec_scopes.Get("value") +// val := value.(big.Int) + +// slope_res, _ := exec_scopes.Get("slope") +// slope := slope_res.(big.Int) + +// // expected values +// expected_val, _ := new(big.Int).SetString("40442433062102151071094722250325492738932110061897694430475034100717288403728", 10) + +// expected_slope, _ := new(big.Int).SetString("40442433062102151071094722250325492738932110061897694430475034100717288403728", 10) + +// if expected_val.Cmp(&val) != 0 || expected_slope.Cmp(&slope) != 0 { +// t.Errorf("EC_DOUBLE_SLOPE_V1 hint test incorrect value for exec_scopes.value or exec_scopes.slope") +// } +// } +// } + +func TestRunComputeSlopeOk(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.Memory.Insert(NewRelocatable(1, 0), NewMaybeRelocatableFelt(FeltFromUint64(134))) + vm.Segments.Memory.Insert(NewRelocatable(1, 1), NewMaybeRelocatableFelt(FeltFromUint64(5123))) + vm.Segments.Memory.Insert(NewRelocatable(1, 2), NewMaybeRelocatableFelt(FeltFromUint64(140))) + vm.Segments.Memory.Insert(NewRelocatable(1, 3), NewMaybeRelocatableFelt(FeltFromUint64(1232))) + vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(4652))) + vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(720))) + vm.Segments.Memory.Insert(NewRelocatable(1, 6), NewMaybeRelocatableFelt(FeltFromUint64(156))) + vm.Segments.Memory.Insert(NewRelocatable(1, 7), NewMaybeRelocatableFelt(FeltFromUint64(6545))) + vm.Segments.Memory.Insert(NewRelocatable(1, 8), NewMaybeRelocatableFelt(FeltFromUint64(100010))) + vm.Segments.Memory.Insert(NewRelocatable(1, 9), NewMaybeRelocatableFelt(FeltFromUint64(1123))) + vm.Segments.Memory.Insert(NewRelocatable(1, 10), NewMaybeRelocatableFelt(FeltFromUint64(1325))) + vm.Segments.Memory.Insert(NewRelocatable(1, 11), NewMaybeRelocatableFelt(FeltFromUint64(910))) + + vm.RunContext.Fp = NewRelocatable(1, 14) + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "point0": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 0))}, + "point1": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 6))}, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: COMPUTE_SLOPE_V1, + }) + + exec_scopes := types.NewExecutionScopes() + err := hintProcessor.ExecuteHint(vm, &hintData, nil, exec_scopes) + if err != nil { + t.Errorf("EC_DOUBLE_SLOPE_V1 hint test failed with error %s", err) + } else { + value, _ := exec_scopes.Get("value") + val := value.(big.Int) + + slope_res, _ := exec_scopes.Get("slope") + slope := slope_res.(big.Int) + + // expected values + expected_val, _ := new(big.Int).SetString("41419765295989780131385135514529906223027172305400087935755859001910844026631", 10) + + expected_slope, _ := new(big.Int).SetString("41419765295989780131385135514529906223027172305400087935755859001910844026631", 10) + + if expected_val.Cmp(&val) != 0 || expected_slope.Cmp(&slope) != 0 { + t.Errorf("EC_DOUBLE_SLOPE_V1 hint test incorrect value for exec_scopes.value or exec_scopes.slope") + } + } +} From a0d269bdc574e8e7931a15868eff246e4045bf95 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 12:49:39 -0300 Subject: [PATCH 14/86] Tests hints slopes --- pkg/hints/ec_hint.go | 4 -- pkg/hints/ec_hint_test.go | 126 ++++++++++++++++++++------------------ 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 08747f37..4cc18ea9 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -47,10 +47,7 @@ func BigInt3FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMach } func BigInt3FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { - fmt.Println(name) - fmt.Println("ids data", ids_data) point_addr, err := ids_data.GetAddr(name, &virtual_machine) - fmt.Println(point_addr) if err != nil { return EcPoint{}, err } @@ -137,7 +134,6 @@ Implements hint: func computeDoublingSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point_alias string, secp_p big.Int, alpha big.Int) error { exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) - fmt.Println(ids_data) point, err := BigInt3FromVarName(point_alias, virtual_machine, ids_data) if err != nil { return err diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index db15ef15..70090666 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -133,80 +133,84 @@ func TestRunEcEmbeddedSecpOk(t *testing.T) { } -// func TestComputeDoublingSlopeOk(t *testing.T) { -// vm := NewVirtualMachine() -// vm.Segments.AddSegment() -// vm.Segments.AddSegment() -// vm.Segments.Memory.Insert(NewRelocatable(1, 0), NewMaybeRelocatableFelt(FeltFromUint64(614323))) -// vm.Segments.Memory.Insert(NewRelocatable(1, 1), NewMaybeRelocatableFelt(FeltFromUint64(5456867))) -// vm.Segments.Memory.Insert(NewRelocatable(1, 2), NewMaybeRelocatableFelt(FeltFromUint64(101208))) -// vm.Segments.Memory.Insert(NewRelocatable(1, 3), NewMaybeRelocatableFelt(FeltFromUint64(773712524))) -// vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(77371252))) -// vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(5298795))) - -// vm.RunContext.Fp = NewRelocatable(1, 1) - -// idsManager := SetupIdsForTest( -// map[string][]*MaybeRelocatable{ -// "point": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 0))}, -// }, -// vm, -// ) - -// hintProcessor := CairoVmHintProcessor{} -// hintData := any(HintData{ -// Ids: idsManager, -// Code: EC_DOUBLE_SLOPE_V1, -// }) - -// exec_scopes := types.NewExecutionScopes() -// err := hintProcessor.ExecuteHint(vm, &hintData, nil, exec_scopes) -// if err != nil { -// t.Errorf("EC_DOUBLE_SLOPE_V1 hint test failed with error %s", err) -// } else { -// value, _ := exec_scopes.Get("value") -// val := value.(big.Int) - -// slope_res, _ := exec_scopes.Get("slope") -// slope := slope_res.(big.Int) - -// // expected values -// expected_val, _ := new(big.Int).SetString("40442433062102151071094722250325492738932110061897694430475034100717288403728", 10) - -// expected_slope, _ := new(big.Int).SetString("40442433062102151071094722250325492738932110061897694430475034100717288403728", 10) - -// if expected_val.Cmp(&val) != 0 || expected_slope.Cmp(&slope) != 0 { -// t.Errorf("EC_DOUBLE_SLOPE_V1 hint test incorrect value for exec_scopes.value or exec_scopes.slope") -// } -// } -// } +func TestComputeDoublingSlopeOk(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + vm.RunContext.Fp = NewRelocatable(1, 1) + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "point": { + NewMaybeRelocatableFelt(FeltFromUint64(614323)), + NewMaybeRelocatableFelt(FeltFromUint64(5456867)), + NewMaybeRelocatableFelt(FeltFromUint64(101208)), + NewMaybeRelocatableFelt(FeltFromUint64(773712524)), + NewMaybeRelocatableFelt(FeltFromUint64(77371252)), + NewMaybeRelocatableFelt(FeltFromUint64(5298795)), + }, + }, + vm, + ) + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: EC_DOUBLE_SLOPE_V1, + }) + + exec_scopes := types.NewExecutionScopes() + err := hintProcessor.ExecuteHint(vm, &hintData, nil, exec_scopes) + if err != nil { + t.Errorf("EC_DOUBLE_SLOPE_V1 hint test failed with error %s", err) + } else { + value, _ := exec_scopes.Get("value") + val := value.(big.Int) + + slope_res, _ := exec_scopes.Get("slope") + slope := slope_res.(big.Int) + + // expected values + expected_val, _ := new(big.Int).SetString("40442433062102151071094722250325492738932110061897694430475034100717288403728", 10) + + expected_slope, _ := new(big.Int).SetString("40442433062102151071094722250325492738932110061897694430475034100717288403728", 10) + + if expected_val.Cmp(&val) != 0 || expected_slope.Cmp(&slope) != 0 { + t.Errorf("EC_DOUBLE_SLOPE_V1 hint test incorrect value for exec_scopes.value or exec_scopes.slope") + } + } +} func TestRunComputeSlopeOk(t *testing.T) { vm := NewVirtualMachine() vm.Segments.AddSegment() vm.Segments.AddSegment() - vm.Segments.Memory.Insert(NewRelocatable(1, 0), NewMaybeRelocatableFelt(FeltFromUint64(134))) - vm.Segments.Memory.Insert(NewRelocatable(1, 1), NewMaybeRelocatableFelt(FeltFromUint64(5123))) - vm.Segments.Memory.Insert(NewRelocatable(1, 2), NewMaybeRelocatableFelt(FeltFromUint64(140))) - vm.Segments.Memory.Insert(NewRelocatable(1, 3), NewMaybeRelocatableFelt(FeltFromUint64(1232))) - vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(4652))) - vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(720))) - vm.Segments.Memory.Insert(NewRelocatable(1, 6), NewMaybeRelocatableFelt(FeltFromUint64(156))) - vm.Segments.Memory.Insert(NewRelocatable(1, 7), NewMaybeRelocatableFelt(FeltFromUint64(6545))) - vm.Segments.Memory.Insert(NewRelocatable(1, 8), NewMaybeRelocatableFelt(FeltFromUint64(100010))) - vm.Segments.Memory.Insert(NewRelocatable(1, 9), NewMaybeRelocatableFelt(FeltFromUint64(1123))) - vm.Segments.Memory.Insert(NewRelocatable(1, 10), NewMaybeRelocatableFelt(FeltFromUint64(1325))) - vm.Segments.Memory.Insert(NewRelocatable(1, 11), NewMaybeRelocatableFelt(FeltFromUint64(910))) vm.RunContext.Fp = NewRelocatable(1, 14) idsManager := SetupIdsForTest( map[string][]*MaybeRelocatable{ - "point0": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 0))}, - "point1": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 6))}, + "point0": { + NewMaybeRelocatableFelt(FeltFromUint64(134)), + NewMaybeRelocatableFelt(FeltFromUint64(5123)), + NewMaybeRelocatableFelt(FeltFromUint64(140)), + NewMaybeRelocatableFelt(FeltFromUint64(1232)), + NewMaybeRelocatableFelt(FeltFromUint64(4652)), + NewMaybeRelocatableFelt(FeltFromUint64(720)), + }, + "point1": { + NewMaybeRelocatableFelt(FeltFromUint64(156)), + NewMaybeRelocatableFelt(FeltFromUint64(6545)), + NewMaybeRelocatableFelt(FeltFromUint64(100010)), + NewMaybeRelocatableFelt(FeltFromUint64(1123)), + NewMaybeRelocatableFelt(FeltFromUint64(1325)), + NewMaybeRelocatableFelt(FeltFromUint64(910)), + }, }, vm, ) + hintProcessor := CairoVmHintProcessor{} hintData := any(HintData{ Ids: idsManager, From a27b814fee20bd0ac56b7e15ae28bba12f1717d7 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 12:52:40 -0300 Subject: [PATCH 15/86] Rename misleading name function --- pkg/hints/ec_hint.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 4cc18ea9..d0bc80a4 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -46,7 +46,7 @@ func BigInt3FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMach return BigInt3{Limbs: limbs}, nil } -func BigInt3FromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { +func EcFromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { point_addr, err := ids_data.GetAddr(name, &virtual_machine) if err != nil { return EcPoint{}, err @@ -134,7 +134,7 @@ Implements hint: func computeDoublingSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point_alias string, secp_p big.Int, alpha big.Int) error { exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) - point, err := BigInt3FromVarName(point_alias, virtual_machine, ids_data) + point, err := EcFromVarName(point_alias, virtual_machine, ids_data) if err != nil { return err } @@ -176,11 +176,11 @@ func computeSlopeAndAssingSecpP(virtual_machine vm.VirtualMachine, exec_scopes t } func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point0_alias string, point1_alias string) error { - point0, err := BigInt3FromVarName(point0_alias, virtual_machine, ids_data) + point0, err := EcFromVarName(point0_alias, virtual_machine, ids_data) if err != nil { return err } - point1, err := BigInt3FromVarName(point1_alias, virtual_machine, ids_data) + point1, err := EcFromVarName(point1_alias, virtual_machine, ids_data) if err != nil { return err } From 9e3950249ae8ae73ebf8180a19f9595bc54d99e5 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 16:25:30 -0300 Subject: [PATCH 16/86] Fix function name --- pkg/hints/ec_hint.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index d0bc80a4..d114f900 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -46,7 +46,7 @@ func BigInt3FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMach return BigInt3{Limbs: limbs}, nil } -func EcFromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { +func EcPointFromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { point_addr, err := ids_data.GetAddr(name, &virtual_machine) if err != nil { return EcPoint{}, err From 0fdad83680d7d7db6a7a97508a6aa1c6a1b6ee95 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 17:58:34 -0300 Subject: [PATCH 17/86] Fix error in function call --- pkg/hints/ec_hint.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index d114f900..4f291a32 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -134,7 +134,7 @@ Implements hint: func computeDoublingSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point_alias string, secp_p big.Int, alpha big.Int) error { exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) - point, err := EcFromVarName(point_alias, virtual_machine, ids_data) + point, err := EcPointFromVarName(point_alias, virtual_machine, ids_data) if err != nil { return err } @@ -176,11 +176,11 @@ func computeSlopeAndAssingSecpP(virtual_machine vm.VirtualMachine, exec_scopes t } func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point0_alias string, point1_alias string) error { - point0, err := EcFromVarName(point0_alias, virtual_machine, ids_data) + point0, err := EcPointFromVarName(point0_alias, virtual_machine, ids_data) if err != nil { return err } - point1, err := EcFromVarName(point1_alias, virtual_machine, ids_data) + point1, err := EcPointFromVarName(point1_alias, virtual_machine, ids_data) if err != nil { return err } From 78dd5d026797e3020448c6e2f63bd8ec87474c50 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 18:28:04 -0300 Subject: [PATCH 18/86] Delete debug info --- pkg/hints/ec_hint.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 4f291a32..5df3d00c 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -138,7 +138,6 @@ func computeDoublingSlope(virtual_machine vm.VirtualMachine, exec_scopes types.E if err != nil { return err } - fmt.Println("after point") x := point.X.Pack86() y := point.Y.Pack86() From facfb8a23c74756459f7fe0b8be3c203c0a07222 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 19 Sep 2023 18:29:59 -0300 Subject: [PATCH 19/86] Delete unused import --- pkg/hints/ec_hint.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 5df3d00c..821fa266 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -2,7 +2,6 @@ package hints import ( "errors" - "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/builtins" From 76c8b8bfd1dccaa1a22a691bda8df8baabbe137f Mon Sep 17 00:00:00 2001 From: Milton Date: Wed, 20 Sep 2023 12:29:52 -0300 Subject: [PATCH 20/86] Secp hints --- pkg/hints/ec_hint.go | 35 ++++++++++++++++++++++------- pkg/hints/hint_codes/secp_p_hint.go | 4 ++++ pkg/hints/hint_processor.go | 4 ++++ pkg/hints/hint_utils/secp_utils.go | 10 +++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 pkg/hints/hint_codes/secp_p_hint.go diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 821fa266..67750661 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -5,7 +5,7 @@ import ( "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/builtins" - "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" + . "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/vm" @@ -45,7 +45,7 @@ func BigInt3FromBaseAddr(addr memory.Relocatable, virtual_machine vm.VirtualMach return BigInt3{Limbs: limbs}, nil } -func EcPointFromVarName(name string, virtual_machine vm.VirtualMachine, ids_data hint_utils.IdsManager) (EcPoint, error) { +func EcPointFromVarName(name string, virtual_machine vm.VirtualMachine, ids_data IdsManager) (EcPoint, error) { point_addr, err := ids_data.GetAddr(name, &virtual_machine) if err != nil { return EcPoint{}, err @@ -67,7 +67,7 @@ func EcPointFromVarName(name string, virtual_machine vm.VirtualMachine, ids_data /* Implements main logic for `EC_NEGATE` and `EC_NEGATE_EMBEDDED_SECP` hints */ -func ecNegate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, secp_p big.Int) error { +func ecNegate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager, secp_p big.Int) error { point, err := ids_data.GetRelocatable("point", &virtual_machine) if err != nil { return err @@ -92,7 +92,7 @@ func ecNegate(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScop return nil } -func ecNegateImportSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { +func ecNegateImportSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager) error { secp_p, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) return ecNegate(virtual_machine, exec_scopes, ids_data, *secp_p) } @@ -109,7 +109,7 @@ Implements hint: %} */ -func ecNegateEmbeddedSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager) error { +func ecNegateEmbeddedSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager) error { secp_p := big.NewInt(1) secp_p.Lsh(secp_p, 255) secp_p.Sub(secp_p, big.NewInt(19)) @@ -130,7 +130,7 @@ Implements hint: %} */ -func computeDoublingSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point_alias string, secp_p big.Int, alpha big.Int) error { +func computeDoublingSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager, point_alias string, secp_p big.Int, alpha big.Int) error { exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) point, err := EcPointFromVarName(point_alias, virtual_machine, ids_data) @@ -168,12 +168,12 @@ Implements hint: %} */ -func computeSlopeAndAssingSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point0_alias string, point1_alias string, secp_p big.Int) error { +func computeSlopeAndAssingSecpP(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager, point0_alias string, point1_alias string, secp_p big.Int) error { exec_scopes.AssignOrUpdateVariable("SECP_P", secp_p) return computeSlope(virtual_machine, exec_scopes, ids_data, point0_alias, point1_alias) } -func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data hint_utils.IdsManager, point0_alias string, point1_alias string) error { +func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager, point0_alias string, point1_alias string) error { point0, err := EcPointFromVarName(point0_alias, virtual_machine, ids_data) if err != nil { return err @@ -209,3 +209,22 @@ func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.Execution return nil } + +/* +Implements hint: +%{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA %} +*/ + +func importSecp256r1Alpha(exec_scopes types.ExecutionScopes) error { + exec_scopes.AssignOrUpdateVariable("ALPHA", SECP256R1_ALPHA()) + return nil +} + +/* +Implements hint: +%{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N %} +*/ +func importSECP256R1N(exec_scopes types.ExecutionScopes) error { + exec_scopes.AssignOrUpdateVariable("N", SECP256R1_N()) + return nil +} diff --git a/pkg/hints/hint_codes/secp_p_hint.go b/pkg/hints/hint_codes/secp_p_hint.go new file mode 100644 index 00000000..39f10898 --- /dev/null +++ b/pkg/hints/hint_codes/secp_p_hint.go @@ -0,0 +1,4 @@ +package hint_codes + +const IMPORT_SECP256R1_ALPHA = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA" +const IMPORT_SECP256R1_N = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index ee4ecf22..9079a2f3 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -128,6 +128,10 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return Assert250Bit(data.Ids, vm, constants) case SPLIT_FELT: return SplitFelt(data.Ids, vm, constants) + case IMPORT_SECP256R1_ALPHA: + return importSecp256r1Alpha(*execScopes) + case IMPORT_SECP256R1_N: + return importSECP256R1N(*execScopes) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go index f531944c..5c105a6e 100644 --- a/pkg/hints/hint_utils/secp_utils.go +++ b/pkg/hints/hint_utils/secp_utils.go @@ -11,3 +11,13 @@ func ALPHA() big.Int { alpha := big.NewInt(0) return *alpha } + +func SECP256R1_ALPHA() big.Int { + secp_p_alpha, _ := new(big.Int).SetString("115792089210356248762697446949407573530086143415290314195533631308867097853948", 10) + return *secp_p_alpha +} + +func SECP256R1_N() big.Int { + secp256, _ := new(big.Int).SetString("115792089210356248762697446949407573529996955224135760342422259061068512044369", 10) + return *secp256 +} From 41c5e0055fada50960c3a14292daa5840e1984b0 Mon Sep 17 00:00:00 2001 From: Milton Date: Wed, 20 Sep 2023 12:44:05 -0300 Subject: [PATCH 21/86] Secpr21 --- pkg/hints/ec_hint.go | 12 ++++++++++++ pkg/hints/hint_codes/secp_p_hint.go | 1 + pkg/hints/hint_utils/secp_utils.go | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 67750661..6efaf482 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -228,3 +228,15 @@ func importSECP256R1N(exec_scopes types.ExecutionScopes) error { exec_scopes.AssignOrUpdateVariable("N", SECP256R1_N()) return nil } + +/* +Implements hint: +%{ +from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P +%} +*/ + +func importSECP256R1P(exec_scopes types.ExecutionScopes) error { + exec_scopes.AssignOrUpdateVariable("SECP_P", SECP256R1_P()) + return nil +} diff --git a/pkg/hints/hint_codes/secp_p_hint.go b/pkg/hints/hint_codes/secp_p_hint.go index 39f10898..b383099a 100644 --- a/pkg/hints/hint_codes/secp_p_hint.go +++ b/pkg/hints/hint_codes/secp_p_hint.go @@ -2,3 +2,4 @@ package hint_codes const IMPORT_SECP256R1_ALPHA = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA" const IMPORT_SECP256R1_N = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N" +const IMPORT_SECP256R1_P = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P" diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go index 5c105a6e..640c1aeb 100644 --- a/pkg/hints/hint_utils/secp_utils.go +++ b/pkg/hints/hint_utils/secp_utils.go @@ -21,3 +21,8 @@ func SECP256R1_N() big.Int { secp256, _ := new(big.Int).SetString("115792089210356248762697446949407573529996955224135760342422259061068512044369", 10) return *secp256 } + +func SECP256R1_P() big.Int { + secp256r1, _ := new(big.Int).SetString("115792089210356248762697446949407573530086143415290314195533631308867097853951", 10) + return *secp256r1 +} From ed75168b3c50783e235fef158b7a7042bac42feb Mon Sep 17 00:00:00 2001 From: Milton Date: Wed, 20 Sep 2023 12:44:51 -0300 Subject: [PATCH 22/86] Add it to the hint processor --- pkg/hints/hint_processor.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index cc4cd3fb..675fd482 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -136,6 +136,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return importSecp256r1Alpha(*execScopes) case IMPORT_SECP256R1_N: return importSECP256R1N(*execScopes) + case IMPORT_SECP256R1_P: + return importSECP256R1P(*execScopes) default: return errors.Errorf("Unknown Hint: %s", data.Code) } From e868fa09f3d8a7847aeda148a1befd784c8e3824 Mon Sep 17 00:00:00 2001 From: Milton Date: Wed, 20 Sep 2023 14:43:04 -0300 Subject: [PATCH 23/86] Hints secp --- cairo_programs/ec_double_slope.cairo | 212 +++++++++++++++++++++++++++ pkg/hints/ec_hint.go | 45 ++++++ pkg/hints/ec_hint_test.go | 10 ++ pkg/hints/hint_codes/ec_op_hints.go | 1 + pkg/hints/hint_processor.go | 2 + 5 files changed, 270 insertions(+) create mode 100644 cairo_programs/ec_double_slope.cairo diff --git a/cairo_programs/ec_double_slope.cairo b/cairo_programs/ec_double_slope.cairo new file mode 100644 index 00000000..10177482 --- /dev/null +++ b/cairo_programs/ec_double_slope.cairo @@ -0,0 +1,212 @@ +%builtins range_check + +// Source: https://github.com/rdubois-crypto/efficient-secp256r1/blob/4b74807c5e91f1ed4cb00a1c973be05c63986e61/src/secp256r1/ec.cairo +from starkware.cairo.common.cairo_secp.bigint import BigInt3, UnreducedBigInt3, nondet_bigint3 +from starkware.cairo.common.cairo_secp.ec import EcPoint + +// src.secp256r1.constants +// SECP_REM is defined by the equation: +// secp256r1_prime = 2 ** 256 - SECP_REM. +const SECP_REM = 2 ** 224 - 2 ** 192 - 2 ** 96 + 1; + +const BASE = 2 ** 86; + +// A = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc +const A0 = 0x3ffffffffffffffffffffc; +const A1 = 0x3ff; +const A2 = 0xffffffff0000000100000; + +// Constants for unreduced_mul/sqr +const s2 = (-(2 ** 76)) - 2 ** 12; +const s1 = (-(2 ** 66)) + 4; +const s0 = 2 ** 56; + +const r2 = 2 ** 54 - 2 ** 22; +const r1 = -(2 ** 12); +const r0 = 4; + +// src.secp256r1.field +// Adapt from starkware.cairo.common.math's assert_250_bit +func assert_165_bit{range_check_ptr}(value) { + const UPPER_BOUND = 2 ** 165; + const SHIFT = 2 ** 128; + const HIGH_BOUND = UPPER_BOUND / SHIFT; + + let low = [range_check_ptr]; + let high = [range_check_ptr + 1]; + + %{ + from starkware.cairo.common.math_utils import as_int + + # Correctness check. + value = as_int(ids.value, PRIME) % PRIME + assert value < ids.UPPER_BOUND, f'{value} is outside of the range [0, 2**250).' + + # Calculation for the assertion. + ids.high, ids.low = divmod(ids.value, ids.SHIFT) + %} + + assert [range_check_ptr + 2] = HIGH_BOUND - 1 - high; + + assert value = high * SHIFT + low; + + let range_check_ptr = range_check_ptr + 3; + return (); +} + +// src.secp256r1.field +// Computes the multiplication of two big integers, given in BigInt3 representation, modulo the +// secp256r1 prime. +// +// Arguments: +// x, y - the two BigInt3 to operate on. +// +// Returns: +// x * y in an UnreducedBigInt3 representation (the returned limbs may be above 3 * BASE). +// +// This means that if unreduced_mul is called on the result of nondet_bigint3, or the difference +// between two such results, we have: +// Soundness guarantee: the limbs are in the range (). +// Completeness guarantee: the limbs are in the range (). +func unreduced_mul(a: BigInt3, b: BigInt3) -> (res_low: UnreducedBigInt3) { + tempvar twice_d2 = a.d2 * b.d2; + tempvar d1d2 = a.d2 * b.d1 + a.d1 * b.d2; + return ( + UnreducedBigInt3( + d0=a.d0 * b.d0 + s0 * twice_d2 + r0 * d1d2, + d1=a.d1 * b.d0 + a.d0 * b.d1 + s1 * twice_d2 + r1 * d1d2, + d2=a.d2 * b.d0 + a.d1 * b.d1 + a.d0 * b.d2 + s2 * twice_d2 + r2 * d1d2, + ), + ); +} + +// src.secp256r1.field +// Computes the square of a big integer, given in BigInt3 representation, modulo the +// secp256r1 prime. +// +// Has the same guarantees as in unreduced_mul(a, a). +func unreduced_sqr(a: BigInt3) -> (res_low: UnreducedBigInt3) { + tempvar twice_d2 = a.d2 * a.d2; + tempvar twice_d1d2 = a.d2 * a.d1 + a.d1 * a.d2; + tempvar d1d0 = a.d1 * a.d0; + return ( + UnreducedBigInt3( + d0=a.d0 * a.d0 + s0 * twice_d2 + r0 * twice_d1d2, + d1=d1d0 + d1d0 + s1 * twice_d2 + r1 * twice_d1d2, + d2=a.d2 * a.d0 + a.d1 * a.d1 + a.d0 * a.d2 + s2 * twice_d2 + r2 * twice_d1d2, + ), + ); +} + +// src.secp256r1.field +// Verifies that the given unreduced value is equal to zero modulo the secp256r1 prime. +// +// Completeness assumption: val's limbs are in the range (-2**210.99, 2**210.99). +// Soundness assumption: val's limbs are in the range (-2**250, 2**250). +func verify_zero{range_check_ptr}(val: UnreducedBigInt3) { + alloc_locals; + local q; + // local q_sign; + let q_sign = 1; + // original: + // %{ from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1_P as SECP_P %} + // %{ + // from starkware.cairo.common.cairo_secp.secp_utils import pack + + // q, r = divmod(pack(ids.val, PRIME), SECP_P) + // assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." + // if q >= 0: + // ids.q = q % PRIME + // ids.q_sign = 1 + // else: + // ids.q = (0-q) % PRIME + // ids.q_sign = -1 % PRIME + // %} + %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P %} + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + + q, r = divmod(pack(ids.val, PRIME), SECP_P) + assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." + ids.q = q % PRIME + %} + // assert_250_bit(q); // 256K steps + // assert_le_felt(q, 2**165); // 275K steps + assert_165_bit(q); + assert q_sign * (val.d2 + val.d1 / BASE + val.d0 / BASE ** 2) = q * ( + (BASE / 4) - SECP_REM / BASE ** 2 + ); + // Multiply by BASE**2 both sides: + // (q_sign) * val = q * (BASE**3 / 4 - SECP_REM) + // = q * (2**256 - SECP_REM) = q * secp256r1_prime = 0 mod secp256r1_prime + return (); +} + +// Computes the slope of the elliptic curve at a given point. +// The slope is used to compute point + point. +// +// Arguments: +// point - the point to operate on. +// +// Returns: +// slope - the slope of the curve at point, in BigInt3 representation. +// +// Assumption: point != 0. +func compute_doubling_slope{range_check_ptr}(point: EcPoint) -> (slope: BigInt3) { + // Note that y cannot be zero: assume that it is, then point = -point, so 2 * point = 0, which + // contradicts the fact that the size of the curve is odd. + // originals: + // %{ from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1_P as SECP_P %} + // %{ from starkware.cairo.common.cairo_secp.secp_utils import SECP256R1_ALPHA as ALPHA %} + %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P %} + %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA %} + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.python.math_utils import ec_double_slope + + # Compute the slope. + x = pack(ids.point.x, PRIME) + y = pack(ids.point.y, PRIME) + value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P) + %} + let (slope: BigInt3) = nondet_bigint3(); + + let (x_sqr: UnreducedBigInt3) = unreduced_sqr(point.x); + let (slope_y: UnreducedBigInt3) = unreduced_mul(slope, point.y); + verify_zero( + UnreducedBigInt3( + d0=3 * x_sqr.d0 + A0 - 2 * slope_y.d0, + d1=3 * x_sqr.d1 + A1 - 2 * slope_y.d1, + d2=3 * x_sqr.d2 + A2 - 2 * slope_y.d2, + ), + ); + + return (slope=slope); +} + +func test_doubling_slope{range_check_ptr}() { + let point = EcPoint(BigInt3(614323, 5456867, 101208), BigInt3(773712524, 77371252, 5298795)); + + let (slope) = compute_doubling_slope(point); + + assert slope = BigInt3( + 64081873649130491683833713, 34843994309543177837008178, 16548672716077616016846383 + ); + + let point = EcPoint( + BigInt3(51215, 36848548548458, 634734734), BigInt3(26362, 263724839599, 901297012) + ); + + let (slope) = compute_doubling_slope(point); + + assert slope = BigInt3( + 71848883893335852660776740, 75644451964360469099209675, 547087410329256463669633 + ); + + return (); +} + +func main{range_check_ptr}() { + test_doubling_slope(); + return (); +} diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 6efaf482..e030cd93 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -240,3 +240,48 @@ func importSECP256R1P(exec_scopes types.ExecutionScopes) error { exec_scopes.AssignOrUpdateVariable("SECP_P", SECP256R1_P()) return nil } + +/* +Implements hint: + + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.python.math_utils import ec_double_slope + + # Compute the slope. + x = pack(ids.point.x, PRIME) + y = pack(ids.point.y, PRIME) + value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P) + +%} +*/ +func computeDoublingSlopeExternalConsts(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager) error { + // ids.point + point, err := EcPointFromVarName("point", virtual_machine, ids_data) + if err != nil { + return err + } + + secp_p_uncast, err := exec_scopes.Get("SECP_P") + if err != nil { + return err + } + secp_p := secp_p_uncast.(big.Int) + + alpha_uncast, err := exec_scopes.Get("ALPHA") + if err != nil { + return nil + } + + alpha := alpha_uncast.(big.Int) + double_point_b := builtins.DoublePointB{X: point.X.Pack86(), Y: point.Y.Pack86()} + + value, err := builtins.EcDoubleSlope(double_point_b, alpha, secp_p) + if err != nil { + return err + } + + exec_scopes.AssignOrUpdateVariable("value", value) + exec_scopes.AssignOrUpdateVariable("slope", value) + return nil +} diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 05cb78e4..8da541f9 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_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/cairo_run" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) @@ -234,3 +235,12 @@ func TestRunComputeSlopeOk(t *testing.T) { } } } + +func TestIntegrationEcDoubleSlope(t *testing.T) { + t.Helper() + cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false} + _, err := cairo_run.CairoRun("../../cairo_programs/ec_double_slope.json", cairoRunConfig) + if err != nil { + t.Errorf("TestIntegrationEcSlope failed with error:\n %v", err) + } +} diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index 254720c5..b22361cc 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -4,3 +4,4 @@ const EC_NEGATE = "from starkware.cairo.common.cairo_secp.secp_utils import SECP const EC_NEGATE_EMBEDDED_SECP = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nSECP_P = 2**255-19\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P" const EC_DOUBLE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P)" const COMPUTE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import line_slope\n\n# Compute the slope.\nx0 = pack(ids.point0.x, PRIME)\ny0 = pack(ids.point0.y, PRIME)\nx1 = pack(ids.point1.x, PRIME)\ny1 = pack(ids.point1.y, PRIME)\nvalue = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)" +const EC_DOUBLE_SLOPE_EXTERNAL_CONSTS = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P)" \ No newline at end of file diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 675fd482..1f09f67a 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -138,6 +138,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return importSECP256R1N(*execScopes) case IMPORT_SECP256R1_P: return importSECP256R1P(*execScopes) + case EC_DOUBLE_SLOPE_EXTERNAL_CONSTS: + return computeDoublingSlopeExternalConsts(*vm, *execScopes, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } From efad459638c6b75487dc91be8440f859956df423 Mon Sep 17 00:00:00 2001 From: Milton Date: Wed, 20 Sep 2023 16:28:21 -0300 Subject: [PATCH 24/86] bigint3 nondet --- pkg/hints/hint_codes/ec_op_hints.go | 3 +- pkg/hints/hint_processor.go | 2 ++ pkg/hints/hint_utils/bigint_utils.go | 46 ++++++++++++++++++++++++++++ pkg/hints/hint_utils/secp_utils.go | 24 ++++++++++++++- 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 pkg/hints/hint_utils/bigint_utils.go diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index b22361cc..98fce988 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -4,4 +4,5 @@ const EC_NEGATE = "from starkware.cairo.common.cairo_secp.secp_utils import SECP const EC_NEGATE_EMBEDDED_SECP = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nSECP_P = 2**255-19\n\ny = pack(ids.point.y, PRIME) % SECP_P\n# The modulo operation in python always returns a nonnegative number.\nvalue = (-y) % SECP_P" const EC_DOUBLE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P)" const COMPUTE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import line_slope\n\n# Compute the slope.\nx0 = pack(ids.point0.x, PRIME)\ny0 = pack(ids.point0.y, PRIME)\nx1 = pack(ids.point1.x, PRIME)\ny1 = pack(ids.point1.y, PRIME)\nvalue = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)" -const EC_DOUBLE_SLOPE_EXTERNAL_CONSTS = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P)" \ No newline at end of file +const EC_DOUBLE_SLOPE_EXTERNAL_CONSTS = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P)" +const NONDET_BIGINT3_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import split\n\nsegments.write_arg(ids.res.address_, split(value))" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index eb2a1898..6dea9ad4 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -142,6 +142,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return importSECP256R1P(*execScopes) case EC_DOUBLE_SLOPE_EXTERNAL_CONSTS: return computeDoublingSlopeExternalConsts(*vm, *execScopes, data.Ids) + case NONDET_BIGINT3_V1: + return NondetBigInt3(*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 new file mode 100644 index 00000000..802606b6 --- /dev/null +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -0,0 +1,46 @@ +package hint_utils + +import ( + "math/big" + + "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" +) + +/* +Implements hint: +%{ + from starkware.cairo.common.cairo_secp.secp_utils import split + + segments.write_arg(ids.res.address_, split(value)) +%} +*/ + +func NondetBigInt3(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager) error { + res_relloc, err := ids_data.GetRelocatable("res", &virtual_machine) + if err != nil { + return err + } + + value_uncast, err := exec_scopes.Get("value") + if err != nil { + return err + } + value := value_uncast.(big.Int) + + bigint3_split, err := Bigint3Split(value) + if err != nil { + return err + } + arg := make([]memory.MaybeRelocatable, 0) + + for i := 0; i < 3; i++ { + m := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(&bigint3_split[i])) + arg = append(arg, *m) + } + + virtual_machine.Segments.LoadData(res_relloc, &arg) + return nil +} diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go index 640c1aeb..3d050b1d 100644 --- a/pkg/hints/hint_utils/secp_utils.go +++ b/pkg/hints/hint_utils/secp_utils.go @@ -1,6 +1,9 @@ package hint_utils -import "math/big" +import ( + "errors" + "math/big" +) func SECP_P() big.Int { secp_p, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10) @@ -26,3 +29,22 @@ func SECP256R1_P() big.Int { secp256r1, _ := new(big.Int).SetString("115792089210356248762697446949407573530086143415290314195533631308867097853951", 10) return *secp256r1 } + +func BASE_MINUS_ONE() *big.Int { + res, _ := new(big.Int).SetString("77371252455336267181195263", 10) + return res +} + +func Bigint3Split(integer big.Int) ([]big.Int, error) { + canonical_repr := make([]big.Int, 3) + num := integer + for i := 0; i < 3; i++ { + canonical_repr[i] = *new(big.Int).And(&num, BASE_MINUS_ONE()) + num.Rsh(&num, 86) + } + if num.Cmp(big.NewInt(0)) != 0 { + return nil, errors.New("HintError SecpSplitOutOfRange") + } + + return canonical_repr, nil +} From c09d92147963868686bc231553a18ee8760d4694 Mon Sep 17 00:00:00 2001 From: Milton Date: Wed, 20 Sep 2023 17:51:10 -0300 Subject: [PATCH 25/86] Zero verify --- pkg/hints/hint_codes/secp_p_hint.go | 1 + pkg/hints/hint_utils/field_utils.go | 39 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 pkg/hints/hint_utils/field_utils.go diff --git a/pkg/hints/hint_codes/secp_p_hint.go b/pkg/hints/hint_codes/secp_p_hint.go index b383099a..2d6dac14 100644 --- a/pkg/hints/hint_codes/secp_p_hint.go +++ b/pkg/hints/hint_codes/secp_p_hint.go @@ -3,3 +3,4 @@ package hint_codes const IMPORT_SECP256R1_ALPHA = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA" const IMPORT_SECP256R1_N = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N" const IMPORT_SECP256R1_P = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P" +const VERIFY_ZERO_EXTERNAL_SECP = "from starkware.cairo.common.cairo_secp.secp_utils import pack\n\nq, r = divmod(pack(ids.val, PRIME), SECP_P)\nassert r == 0, f\"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}.\"\nids.q = q % PRIME" diff --git a/pkg/hints/hint_utils/field_utils.go b/pkg/hints/hint_utils/field_utils.go new file mode 100644 index 00000000..450da9dc --- /dev/null +++ b/pkg/hints/hint_utils/field_utils.go @@ -0,0 +1,39 @@ +package hint_utils + +import ( + "math/big" + + "github.com/lambdaclass/cairo-vm.go/pkg/hints" + "github.com/lambdaclass/cairo-vm.go/pkg/types" + "github.com/lambdaclass/cairo-vm.go/pkg/vm" +) + +/* +Implements hint: +%{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + + q, r = divmod(pack(ids.val, PRIME), SECP_P) + assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." + ids.q = q % PRIME +%} +*/ + +func verifyZeroWithExternalConst(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager) error { + secp_p_uncast, err := exec_scopes.Get("SECP_P") + if err != nil { + return err + } + secp_p := secp_p_uncast.(big.Int) + addr, err := ids_data.GetRelocatable("val", &virtual_machine) + if err != nil { + return err + } + + val, err := hints.BigInt3FromBaseAddr(addr, virtual_machine) + if err != nil { + return err + } + + return nil +} From 50994ada0b9454770fb90d7c03fdde4673ff6c6c Mon Sep 17 00:00:00 2001 From: Milton Date: Thu, 21 Sep 2023 08:30:24 -0300 Subject: [PATCH 26/86] Merge main --- pkg/hints/ec_hint.go | 6 ++---- pkg/hints/{hint_utils => }/field_utils.go | 7 ++++--- 2 files changed, 6 insertions(+), 7 deletions(-) rename pkg/hints/{hint_utils => }/field_utils.go (85%) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index e030cd93..5f722cfb 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -210,6 +210,7 @@ func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.Execution return nil } + /* Implements hint: %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA %} @@ -243,16 +244,13 @@ func importSECP256R1P(exec_scopes types.ExecutionScopes) error { /* Implements hint: - %{ from starkware.cairo.common.cairo_secp.secp_utils import pack from starkware.python.math_utils import ec_double_slope - # Compute the slope. x = pack(ids.point.x, PRIME) y = pack(ids.point.y, PRIME) value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P) - %} */ func computeDoublingSlopeExternalConsts(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager) error { @@ -284,4 +282,4 @@ func computeDoublingSlopeExternalConsts(virtual_machine vm.VirtualMachine, exec_ exec_scopes.AssignOrUpdateVariable("value", value) exec_scopes.AssignOrUpdateVariable("slope", value) return nil -} +} \ No newline at end of file diff --git a/pkg/hints/hint_utils/field_utils.go b/pkg/hints/field_utils.go similarity index 85% rename from pkg/hints/hint_utils/field_utils.go rename to pkg/hints/field_utils.go index 450da9dc..041d2c60 100644 --- a/pkg/hints/hint_utils/field_utils.go +++ b/pkg/hints/field_utils.go @@ -1,9 +1,10 @@ -package hint_utils +package hints import ( "math/big" - "github.com/lambdaclass/cairo-vm.go/pkg/hints" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" + "github.com/lambdaclass/cairo-vm.go/pkg/types" "github.com/lambdaclass/cairo-vm.go/pkg/vm" ) @@ -30,7 +31,7 @@ func verifyZeroWithExternalConst(virtual_machine vm.VirtualMachine, exec_scopes return err } - val, err := hints.BigInt3FromBaseAddr(addr, virtual_machine) + val, err := BigInt3FromBaseAddr(addr, virtual_machine) if err != nil { return err } From 2d44427eb48f39e89d78f9f974c1cbf9d2162ba2 Mon Sep 17 00:00:00 2001 From: Milton Date: Thu, 21 Sep 2023 11:37:32 -0300 Subject: [PATCH 27/86] Add hint to hint processor --- pkg/hints/ec_hint.go | 5 +++-- pkg/hints/field_utils.go | 26 +++++++++++++++++++------- pkg/hints/hint_codes/ec_op_hints.go | 2 +- pkg/hints/hint_processor.go | 2 ++ 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 5f722cfb..41a9f457 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -210,7 +210,6 @@ func computeSlope(virtual_machine vm.VirtualMachine, exec_scopes types.Execution return nil } - /* Implements hint: %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA %} @@ -244,6 +243,7 @@ func importSECP256R1P(exec_scopes types.ExecutionScopes) error { /* Implements hint: + %{ from starkware.cairo.common.cairo_secp.secp_utils import pack from starkware.python.math_utils import ec_double_slope @@ -251,6 +251,7 @@ Implements hint: x = pack(ids.point.x, PRIME) y = pack(ids.point.y, PRIME) value = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P) + %} */ func computeDoublingSlopeExternalConsts(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager) error { @@ -282,4 +283,4 @@ func computeDoublingSlopeExternalConsts(virtual_machine vm.VirtualMachine, exec_ exec_scopes.AssignOrUpdateVariable("value", value) exec_scopes.AssignOrUpdateVariable("slope", value) return nil -} \ No newline at end of file +} diff --git a/pkg/hints/field_utils.go b/pkg/hints/field_utils.go index 041d2c60..e53c8fb7 100644 --- a/pkg/hints/field_utils.go +++ b/pkg/hints/field_utils.go @@ -1,12 +1,15 @@ package hints import ( + "errors" "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/vm/memory" - "github.com/lambdaclass/cairo-vm.go/pkg/types" - "github.com/lambdaclass/cairo-vm.go/pkg/vm" + . "github.com/lambdaclass/cairo-vm.go/pkg/types" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm" ) /* @@ -20,21 +23,30 @@ Implements hint: %} */ -func verifyZeroWithExternalConst(virtual_machine vm.VirtualMachine, exec_scopes types.ExecutionScopes, ids_data IdsManager) error { - secp_p_uncast, err := exec_scopes.Get("SECP_P") +func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsManager) error { + secpPuncast, err := execScopes.Get("SECP_P") if err != nil { return err } - secp_p := secp_p_uncast.(big.Int) - addr, err := ids_data.GetRelocatable("val", &virtual_machine) + SecpP := secpPuncast.(big.Int) + addr, err := idsData.GetRelocatable("val", &vm) if err != nil { return err } - val, err := BigInt3FromBaseAddr(addr, virtual_machine) + val, err := BigInt3FromBaseAddr(addr, vm) if err != nil { return err } + v := val.Pack86() + q, r := v.DivMod(&v, &SecpP, new(big.Int)) + + if r.Cmp(big.NewInt(0)) != 0 { + return errors.New("verify remainder is not zero: Invalid input") + } + + quotient := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(q)) + idsData.Insert("q", quotient, &vm) return nil } diff --git a/pkg/hints/hint_codes/ec_op_hints.go b/pkg/hints/hint_codes/ec_op_hints.go index 98fce988..efbf4a55 100644 --- a/pkg/hints/hint_codes/ec_op_hints.go +++ b/pkg/hints/hint_codes/ec_op_hints.go @@ -5,4 +5,4 @@ const EC_NEGATE_EMBEDDED_SECP = "from starkware.cairo.common.cairo_secp.secp_uti const EC_DOUBLE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=0, p=SECP_P)" const COMPUTE_SLOPE_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack\nfrom starkware.python.math_utils import line_slope\n\n# Compute the slope.\nx0 = pack(ids.point0.x, PRIME)\ny0 = pack(ids.point0.y, PRIME)\nx1 = pack(ids.point1.x, PRIME)\ny1 = pack(ids.point1.y, PRIME)\nvalue = slope = line_slope(point1=(x0, y0), point2=(x1, y1), p=SECP_P)" const EC_DOUBLE_SLOPE_EXTERNAL_CONSTS = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nfrom starkware.python.math_utils import ec_double_slope\n\n# Compute the slope.\nx = pack(ids.point.x, PRIME)\ny = pack(ids.point.y, PRIME)\nvalue = slope = ec_double_slope(point=(x, y), alpha=ALPHA, p=SECP_P)" -const NONDET_BIGINT3_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import split\n\nsegments.write_arg(ids.res.address_, split(value))" +const NONDET_BIGINT3_V1 = "from starkware.cairo.common.cairo_secp.secp_utils import split\n\nsegments.write_arg(ids.res.address_, split(value))" \ No newline at end of file diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index e8f0e672..b89f43b6 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -152,6 +152,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return splitInt(data.Ids, vm) case SPLIT_INT_ASSERT_RANGE: return splitIntAssertRange(data.Ids, vm) + case VERIFY_ZERO_EXTERNAL_SECP: + return verifyZeroWithExternalConst(*vm, *execScopes, data.Ids) default: return errors.Errorf("Unknown Hint: %s", data.Code) } From 7720f4295a7794a294ad02569a81e63054dd4359 Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 22 Sep 2023 10:39:43 -0300 Subject: [PATCH 28/86] Debug info --- pkg/hints/ec_hint.go | 4 ++++ pkg/hints/field_utils.go | 12 ++++++++---- pkg/hints/hint_utils/bigint_utils.go | 6 ++++++ pkg/hints/hint_utils/ids_manager.go | 7 +------ pkg/hints/hint_utils/secp_utils.go | 4 ++++ 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 96b08804..e342de90 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -2,6 +2,7 @@ package hints import ( "errors" + "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/builtins" @@ -37,6 +38,7 @@ func BigInt3FromBaseAddr(addr memory.Relocatable, vm VirtualMachine) (BigInt3, e for i := 0; i < 3; i++ { felt, err := vm.Segments.Memory.GetFelt(addr.AddUint(uint(i))) if err == nil { + fmt.Println("value from memory: from address ", felt.ToBigInt().Text(10), addr.AddUint(uint(i))) limbs = append(limbs, felt) } else { return BigInt3{}, errors.New("Identifier has no member") @@ -257,6 +259,7 @@ Implements hint: */ func computeDoublingSlopeExternalConsts(vm VirtualMachine, execScopes ExecutionScopes, ids_data IdsManager) error { // ids.point + fmt.Println("compute doubling slope extenral ") point, err := EcPointFromVarName("point", vm, ids_data) if err != nil { return err @@ -277,6 +280,7 @@ func computeDoublingSlopeExternalConsts(vm VirtualMachine, execScopes ExecutionS double_point_b := builtins.DoublePointB{X: point.X.Pack86(), Y: point.Y.Pack86()} value, err := builtins.EcDoubleSlope(double_point_b, alpha, secp_p) + fmt.Println("value of ec double slope", value.Text(10)) if err != nil { return err } diff --git a/pkg/hints/field_utils.go b/pkg/hints/field_utils.go index e53c8fb7..f541e549 100644 --- a/pkg/hints/field_utils.go +++ b/pkg/hints/field_utils.go @@ -2,6 +2,7 @@ package hints import ( "errors" + "fmt" "math/big" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" @@ -28,20 +29,23 @@ func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, if err != nil { return err } - SecpP := secpPuncast.(big.Int) - addr, err := idsData.GetRelocatable("val", &vm) + secpP := secpPuncast.(big.Int) + fmt.Println("secp: ", secpP.Text(10)) + addr, err := idsData.GetAddr("val", &vm) if err != nil { return err } + fmt.Println("addr ", addr) val, err := BigInt3FromBaseAddr(addr, vm) if err != nil { return err } v := val.Pack86() - q, r := v.DivMod(&v, &SecpP, new(big.Int)) - + fmt.Println("val in zero with external: ", v.Text(10)) + q, r := v.DivMod(&v, &secpP, new(big.Int)) + //fmt.Println(r) if r.Cmp(big.NewInt(0)) != 0 { return errors.New("verify remainder is not zero: Invalid input") } diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index 0a2dd820..75a0ef43 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -1,6 +1,7 @@ package hint_utils import ( + "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" @@ -24,11 +25,14 @@ func NondetBigInt3(virtual_machine vm.VirtualMachine, exec_scopes types.Executio return err } + fmt.Println("res alloc: ", res_relloc) + value_uncast, err := exec_scopes.Get("value") if err != nil { return err } value := value_uncast.(big.Int) + fmt.Println("value in nond int: \n", value.Text(10)) bigint3_split, err := Bigint3Split(value) if err != nil { @@ -36,8 +40,10 @@ func NondetBigInt3(virtual_machine vm.VirtualMachine, exec_scopes types.Executio } arg := make([]memory.MaybeRelocatable, 0) + fmt.Println("args: ") for i := 0; i < 3; i++ { m := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(&bigint3_split[i])) + fmt.Println(bigint3_split[i].Text(10)) arg = append(arg, *m) } diff --git a/pkg/hints/hint_utils/ids_manager.go b/pkg/hints/hint_utils/ids_manager.go index d7c19c8b..138bfba7 100644 --- a/pkg/hints/hint_utils/ids_manager.go +++ b/pkg/hints/hint_utils/ids_manager.go @@ -93,7 +93,6 @@ func (ids *IdsManager) GetRelocatable(name string, vm *VirtualMachine) (Relocata // Returns the value of an identifier as a MaybeRelocatable func (ids *IdsManager) Get(name string, vm *VirtualMachine) (*MaybeRelocatable, error) { - fmt.Println("name ", name) reference, ok := ids.References[name] if ok { val, ok := getValueFromReference(&reference, ids.HintApTracking, vm) @@ -129,6 +128,7 @@ func (ids *IdsManager) GetAddr(name string, vm *VirtualMachine) (Relocatable, er ids_lives := ids.GetStructField("cat", 0, vm) or ids_lives := ids.Get("cat", vm) ids_paws := ids.GetStructField("cat", 1, vm) */ + func (ids *IdsManager) GetStructField(name string, field_off uint, vm *VirtualMachine) (*MaybeRelocatable, error) { reference, ok := ids.References[name] if ok { @@ -234,15 +234,10 @@ func getValueFromReference(reference *HintReference, apTracking parser.ApTrackin if reference.Offset1.ValueType == Immediate { return NewMaybeRelocatableFelt(reference.Offset1.Immediate), true } - fmt.Println("after first if ") addr, ok := getAddressFromReference(reference, apTracking, vm) - fmt.Println("after fetching address ok? ", ok) - fmt.Println("addr", addr) if ok { if reference.Dereference { - fmt.Println("enter dereference with: ", reference.Dereference) val, err := vm.Segments.Memory.Get(addr) - fmt.Println("err?: ", err) if err == nil { return val, true } diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go index bb7e9a41..e5295323 100644 --- a/pkg/hints/hint_utils/secp_utils.go +++ b/pkg/hints/hint_utils/secp_utils.go @@ -2,6 +2,7 @@ package hint_utils import ( "errors" + "fmt" "math/big" ) @@ -38,8 +39,11 @@ func BASE_MINUS_ONE() *big.Int { func Bigint3Split(integer big.Int) ([]big.Int, error) { canonicalRepr := make([]big.Int, 3) num := integer + fmt.Println("canonical repr: ") + for i := 0; i < 3; i++ { canonicalRepr[i] = *new(big.Int).And(&num, BASE_MINUS_ONE()) + fmt.Println(canonicalRepr[i].Text(10)) num.Rsh(&num, 86) } if num.Cmp(big.NewInt(0)) != 0 { From 5ce7e744ff3cdcfac6fe71c23078359903b7dd89 Mon Sep 17 00:00:00 2001 From: Milton Date: Fri, 22 Sep 2023 11:28:22 -0300 Subject: [PATCH 29/86] Prints --- pkg/hints/field_utils.go | 2 +- pkg/hints/hint_utils/bigint_utils.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/hints/field_utils.go b/pkg/hints/field_utils.go index 985df186..cc9a3966 100644 --- a/pkg/hints/field_utils.go +++ b/pkg/hints/field_utils.go @@ -45,7 +45,7 @@ func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, v := val.Pack86() fmt.Println("val in zero with external: ", v.Text(10)) q, r := v.DivMod(&v, &secpP, new(big.Int)) - //fmt.Println(r) + fmt.Println(r) if r.Cmp(big.NewInt(0)) != 0 { return errors.New("verify remainder is not zero: Invalid input") } diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index ccceab12..dc3fb6d7 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -70,6 +70,7 @@ func limbsFromBaseAddress(nLimbs int, name string, addr Relocatable, vm *Virtual limbs := make([]Felt, 0) for i := 0; i < nLimbs; i++ { felt, err := vm.Segments.Memory.GetFelt(addr.AddUint(uint(i))) + fmt.Println("value in memory: ", felt.ToBigInt().Text(10), addr.AddUint(uint(i))) if err == nil { limbs = append(limbs, felt) } else { From 3969b1b07b317be7a5ef8afd4d70308bd75369e6 Mon Sep 17 00:00:00 2001 From: Milton Date: Mon, 25 Sep 2023 09:44:06 -0300 Subject: [PATCH 30/86] Test verify with unit test --- pkg/hints/ec_hint_test.go | 17 ++++---- pkg/hints/field_utils.go | 1 + pkg/hints/field_utils_test.go | 61 ++++++++++++++++++++++++++++ pkg/hints/hint_utils/bigint_utils.go | 2 + 4 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 pkg/hints/field_utils_test.go diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 2d5d5dde..0b08bcd2 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -10,7 +10,6 @@ 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/cairo_run" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) @@ -236,11 +235,11 @@ func TestRunComputeSlopeOk(t *testing.T) { } } -func TestIntegrationEcDoubleSlope(t *testing.T) { - t.Helper() - cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false} - _, err := cairo_run.CairoRun("../../cairo_programs/ec_double_slope.json", cairoRunConfig) - if err != nil { - t.Errorf("TestIntegrationEcSlope failed with error:\n %v", err) - } -} +// func TestIntegrationEcDoubleSlope(t *testing.T) { +// t.Helper() +// cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false} +// _, err := cairo_run.CairoRun("../../cairo_programs/ec_double_slope.json", cairoRunConfig) +// if err != nil { +// t.Errorf("TestIntegrationEcSlope failed with error:\n %v", err) +// } +// } diff --git a/pkg/hints/field_utils.go b/pkg/hints/field_utils.go index cc9a3966..e6b0a59a 100644 --- a/pkg/hints/field_utils.go +++ b/pkg/hints/field_utils.go @@ -25,6 +25,7 @@ Implements hint: */ func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsManager) error { + fmt.Println("inside verify") secpPuncast, err := execScopes.Get("SECP_P") if err != nil { return err diff --git a/pkg/hints/field_utils_test.go b/pkg/hints/field_utils_test.go new file mode 100644 index 00000000..f5b5855f --- /dev/null +++ b/pkg/hints/field_utils_test.go @@ -0,0 +1,61 @@ +package hints_test + +import ( + "fmt" + "math/big" + "testing" + + . "github.com/lambdaclass/cairo-vm.go/pkg/hints" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" + . "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/vm" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" +) + +func TestVerifyZeroWithExternalConst(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(55))) + vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(0))) + vm.Segments.Memory.Insert(NewRelocatable(1, 6), NewMaybeRelocatableFelt(FeltFromUint64(0))) + + vm.RunContext.Pc = NewRelocatable(0, 0) + vm.RunContext.Ap = NewRelocatable(1, 9) + vm.RunContext.Fp = NewRelocatable(1, 9) + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "val": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 4))}, + "q": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 9))}, + }, + vm, + ) + + newScepP := big.NewInt(55) + execScopes := NewExecutionScopes() + + execScopes.AssignOrUpdateVariable("SECP_P", *newScepP) + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: VERIFY_ZERO_EXTERNAL_SECP, + }) + err := hintProcessor.ExecuteHint(vm, &hintData, nil, execScopes) + if err != nil { + t.Errorf("verifyZeroWithExternalConst hint test failed with error: %s", err) + } else { + valueInMemory, err := vm.Segments.Memory.GetFelt(NewRelocatable(1, 9)) + fmt.Println("fetching from memory") + if err != nil { + t.Errorf("could not fetch value with error: %s", err) + } + if valueInMemory != FeltFromUint64(1) { + t.Errorf("value in memory is not the expected") + } + } +} diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index dc3fb6d7..6ae9507c 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -67,6 +67,7 @@ func limbsFromVarName(nLimbs int, name string, ids IdsManager, vm *VirtualMachin } func limbsFromBaseAddress(nLimbs int, name string, addr Relocatable, vm *VirtualMachine) ([]Felt, error) { + fmt.Println(name) limbs := make([]Felt, 0) for i := 0; i < nLimbs; i++ { felt, err := vm.Segments.Memory.GetFelt(addr.AddUint(uint(i))) @@ -74,6 +75,7 @@ func limbsFromBaseAddress(nLimbs int, name string, addr Relocatable, vm *Virtual if err == nil { limbs = append(limbs, felt) } else { + fmt.Println("error name: ", name) return nil, errors.Errorf("Identifier %s has no member d%d", name, i) } } From 942c204712babe7db5551e3b0dd22e924cb07b2f Mon Sep 17 00:00:00 2001 From: Milton Date: Mon, 25 Sep 2023 11:00:03 -0300 Subject: [PATCH 31/86] Debug unit test --- pkg/hints/field_utils.go | 3 ++- pkg/hints/field_utils_test.go | 5 ++++- pkg/hints/hint_utils/bigint_utils.go | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkg/hints/field_utils.go b/pkg/hints/field_utils.go index e6b0a59a..ca99ef83 100644 --- a/pkg/hints/field_utils.go +++ b/pkg/hints/field_utils.go @@ -33,6 +33,7 @@ func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, secpP := secpPuncast.(big.Int) fmt.Println("secp: ", secpP.Text(10)) addr, err := idsData.GetAddr("val", &vm) + fmt.Println("addr or err:", addr, err) if err != nil { return err } @@ -46,7 +47,7 @@ func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, v := val.Pack86() fmt.Println("val in zero with external: ", v.Text(10)) q, r := v.DivMod(&v, &secpP, new(big.Int)) - fmt.Println(r) + fmt.Println("r: ", r) if r.Cmp(big.NewInt(0)) != 0 { return errors.New("verify remainder is not zero: Invalid input") } diff --git a/pkg/hints/field_utils_test.go b/pkg/hints/field_utils_test.go index f5b5855f..7ff20ecb 100644 --- a/pkg/hints/field_utils_test.go +++ b/pkg/hints/field_utils_test.go @@ -25,7 +25,7 @@ func TestVerifyZeroWithExternalConst(t *testing.T) { vm.RunContext.Pc = NewRelocatable(0, 0) vm.RunContext.Ap = NewRelocatable(1, 9) - vm.RunContext.Fp = NewRelocatable(1, 9) + vm.RunContext.Fp = NewRelocatable(1, 4) idsManager := SetupIdsForTest( map[string][]*MaybeRelocatable{ @@ -35,10 +35,13 @@ func TestVerifyZeroWithExternalConst(t *testing.T) { vm, ) + fmt.Println("ids manager: ", idsManager) + newScepP := big.NewInt(55) execScopes := NewExecutionScopes() execScopes.AssignOrUpdateVariable("SECP_P", *newScepP) + fmt.Println("after exec") hintProcessor := CairoVmHintProcessor{} hintData := any(HintData{ diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index 6ae9507c..c408e517 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -67,7 +67,7 @@ func limbsFromVarName(nLimbs int, name string, ids IdsManager, vm *VirtualMachin } func limbsFromBaseAddress(nLimbs int, name string, addr Relocatable, vm *VirtualMachine) ([]Felt, error) { - fmt.Println(name) + fmt.Println("addr in libms base addr: ", addr) limbs := make([]Felt, 0) for i := 0; i < nLimbs; i++ { felt, err := vm.Segments.Memory.GetFelt(addr.AddUint(uint(i))) From ee521d09f4fbdd23ae5f056e0b7e9670f3e300fa Mon Sep 17 00:00:00 2001 From: Milton Date: Mon, 25 Sep 2023 12:12:11 -0300 Subject: [PATCH 32/86] Test verify zero with debug --- pkg/hints/field_utils_test.go | 15 ++++++--------- pkg/hints/hint_utils/ids_manager.go | 1 + 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/pkg/hints/field_utils_test.go b/pkg/hints/field_utils_test.go index 7ff20ecb..a1c866f5 100644 --- a/pkg/hints/field_utils_test.go +++ b/pkg/hints/field_utils_test.go @@ -8,6 +8,7 @@ import ( . "github.com/lambdaclass/cairo-vm.go/pkg/hints" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" . "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/lambdaworks" . "github.com/lambdaclass/cairo-vm.go/pkg/types" . "github.com/lambdaclass/cairo-vm.go/pkg/vm" @@ -19,18 +20,14 @@ func TestVerifyZeroWithExternalConst(t *testing.T) { vm.Segments.AddSegment() vm.Segments.AddSegment() - vm.Segments.Memory.Insert(NewRelocatable(1, 4), NewMaybeRelocatableFelt(FeltFromUint64(55))) - vm.Segments.Memory.Insert(NewRelocatable(1, 5), NewMaybeRelocatableFelt(FeltFromUint64(0))) - vm.Segments.Memory.Insert(NewRelocatable(1, 6), NewMaybeRelocatableFelt(FeltFromUint64(0))) - vm.RunContext.Pc = NewRelocatable(0, 0) vm.RunContext.Ap = NewRelocatable(1, 9) - vm.RunContext.Fp = NewRelocatable(1, 4) + vm.RunContext.Fp = NewRelocatable(1, 9) idsManager := SetupIdsForTest( map[string][]*MaybeRelocatable{ - "val": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 4))}, - "q": {NewMaybeRelocatableRelocatable(NewRelocatable(1, 9))}, + "val": {NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(55)), NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(0)), NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(0))}, + "q": {NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(1))}, }, vm, ) @@ -52,8 +49,8 @@ func TestVerifyZeroWithExternalConst(t *testing.T) { if err != nil { t.Errorf("verifyZeroWithExternalConst hint test failed with error: %s", err) } else { - valueInMemory, err := vm.Segments.Memory.GetFelt(NewRelocatable(1, 9)) - fmt.Println("fetching from memory") + valueInMemory, err := vm.Segments.Memory.GetFelt(NewRelocatable(1, 12)) + fmt.Println("fetching from memory:", valueInMemory) if err != nil { t.Errorf("could not fetch value with error: %s", err) } diff --git a/pkg/hints/hint_utils/ids_manager.go b/pkg/hints/hint_utils/ids_manager.go index 138bfba7..700f42a4 100644 --- a/pkg/hints/hint_utils/ids_manager.go +++ b/pkg/hints/hint_utils/ids_manager.go @@ -59,6 +59,7 @@ func (ids *IdsManager) GetConst(name string, constants *map[string]lambdaworks.F func (ids *IdsManager) Insert(name string, value *MaybeRelocatable, vm *VirtualMachine) error { addr, err := ids.GetAddr(name, vm) + fmt.Println("insert in addres", addr) if err != nil { return err } From 621a61619d74d730970d04c75c6eee794031d7cb Mon Sep 17 00:00:00 2001 From: Milton Date: Mon, 25 Sep 2023 13:23:44 -0300 Subject: [PATCH 33/86] Non det big 3 test --- pkg/hints/hint_utils/bigint_utils_test.go | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 pkg/hints/hint_utils/bigint_utils_test.go diff --git a/pkg/hints/hint_utils/bigint_utils_test.go b/pkg/hints/hint_utils/bigint_utils_test.go new file mode 100644 index 00000000..10f50a95 --- /dev/null +++ b/pkg/hints/hint_utils/bigint_utils_test.go @@ -0,0 +1,28 @@ +package hint_utils_test + +import ( + "math/big" + "testing" + + . "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" +) + + +func TestNonDetBigInt3Ok(t *testing.T) { + vm := NewVirtualMachine() + + vm.Segments.AddSegment() + vm.Segments.AddSegment() + vm.Segments.AddSegment() + + vm.RunContext.Pc = NewRelocatable(0, 0) + vm.RunContext.Ap = NewRelocatable(1, 6) + vm.RunContext.Fp = NewRelocatable(1, 6) + + value, _ := new(big.Int).SetString("7737125245533626718119526477371252455336267181195264773712524553362", 10) + execScopes := NewExecutionScopes() + + execScopes.AssignOrUpdateVariable("value", *value) +} \ No newline at end of file From 6d2cc54a4398829e206ca9d38b5efea22f853ff9 Mon Sep 17 00:00:00 2001 From: Milton Date: Mon, 25 Sep 2023 17:01:47 -0300 Subject: [PATCH 34/86] Modify test to use ids manager --- pkg/hints/field_utils_test.go | 9 +--- pkg/hints/hint_utils/bigint_utils_test.go | 51 ++++++++++++++++++++++- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/pkg/hints/field_utils_test.go b/pkg/hints/field_utils_test.go index a1c866f5..534f8eff 100644 --- a/pkg/hints/field_utils_test.go +++ b/pkg/hints/field_utils_test.go @@ -1,7 +1,6 @@ package hints_test import ( - "fmt" "math/big" "testing" @@ -27,18 +26,15 @@ func TestVerifyZeroWithExternalConst(t *testing.T) { idsManager := SetupIdsForTest( map[string][]*MaybeRelocatable{ "val": {NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(55)), NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(0)), NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(0))}, - "q": {NewMaybeRelocatableFelt(lambdaworks.FeltFromUint64(1))}, + "q": {nil}, }, vm, ) - fmt.Println("ids manager: ", idsManager) - newScepP := big.NewInt(55) execScopes := NewExecutionScopes() execScopes.AssignOrUpdateVariable("SECP_P", *newScepP) - fmt.Println("after exec") hintProcessor := CairoVmHintProcessor{} hintData := any(HintData{ @@ -49,8 +45,7 @@ func TestVerifyZeroWithExternalConst(t *testing.T) { if err != nil { t.Errorf("verifyZeroWithExternalConst hint test failed with error: %s", err) } else { - valueInMemory, err := vm.Segments.Memory.GetFelt(NewRelocatable(1, 12)) - fmt.Println("fetching from memory:", valueInMemory) + valueInMemory, err := idsManager.GetFelt("q", vm) if err != nil { t.Errorf("could not fetch value with error: %s", err) } diff --git a/pkg/hints/hint_utils/bigint_utils_test.go b/pkg/hints/hint_utils/bigint_utils_test.go index 10f50a95..9d0e734f 100644 --- a/pkg/hints/hint_utils/bigint_utils_test.go +++ b/pkg/hints/hint_utils/bigint_utils_test.go @@ -4,12 +4,15 @@ import ( "math/big" "testing" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" + . "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/vm" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) - func TestNonDetBigInt3Ok(t *testing.T) { vm := NewVirtualMachine() @@ -25,4 +28,48 @@ func TestNonDetBigInt3Ok(t *testing.T) { execScopes := NewExecutionScopes() execScopes.AssignOrUpdateVariable("value", *value) -} \ No newline at end of file + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "res": {nil}, + }, + vm, + ) + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: NONDET_BIGINT3_V1, + }) + err := hintProcessor.ExecuteHint(vm, &hintData, nil, execScopes) + if err != nil { + t.Errorf("Non Det Big Int 3 hint test failed with error: %s", err) + } else { + valueInStruct0, err := idsManager.GetStructFieldFelt("res", 0, vm) + expected0 := lambdaworks.FeltFromUint(773712524553362) + if err != nil { + t.Errorf("error fetching from ids manager : %s", err) + } + if valueInStruct0 != expected0 { + t.Errorf(" Incorrect field value %s, expected %s", valueInStruct0.ToHexString(), expected0.ToHexString()) + } + + valueInStruct1, err := idsManager.GetStructFieldFelt("res", 1, vm) + expected1 := lambdaworks.FeltFromDecString("57408430697461422066401280") + if err != nil { + t.Errorf("error fetching from ids manager : %s", err) + } + if valueInStruct1 != expected1 { + t.Errorf(" Incorrect field value %s, expected %s", valueInStruct1.ToHexString(), expected1.ToHexString()) + } + + valueInStruct2, err := idsManager.GetStructFieldFelt("res", 2, vm) + expected2 := lambdaworks.FeltFromDecString("1292469707114105") + if err != nil { + t.Errorf("error fetching from ids manager : %s", err) + } + if valueInStruct2 != expected2 { + t.Errorf(" Incorrect field value %s, expected %s", valueInStruct2.ToHexString(), expected2.ToHexString()) + } + } +} From cef26c00e0e94a75eedf1846a9e0d6f607acd778 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 25 Sep 2023 18:16:24 -0300 Subject: [PATCH 35/86] Add hint codes --- pkg/hints/hint_codes/signature_hint_codes.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 pkg/hints/hint_codes/signature_hint_codes.go diff --git a/pkg/hints/hint_codes/signature_hint_codes.go b/pkg/hints/hint_codes/signature_hint_codes.go new file mode 100644 index 00000000..ce65dfe6 --- /dev/null +++ b/pkg/hints/hint_codes/signature_hint_codes.go @@ -0,0 +1,15 @@ +package hint_codes + +const DIV_MOD_N_PACKED_DIVMOD_V1 = `from starkware.cairo.common.cairo_secp.secp_utils import N, pack +from starkware.python.math_utils import div_mod, safe_div + +a = pack(ids.a, PRIME) +b = pack(ids.b, PRIME) +value = res = div_mod(a, b, N)` + +const DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N = `from starkware.cairo.common.cairo_secp.secp_utils import pack +from starkware.python.math_utils import div_mod, safe_div + +a = pack(ids.a, PRIME) +b = pack(ids.b, PRIME) +value = res = div_mod(a, b, N)` From ca18c74fd9acbb40502697b464a7777e99ebac72 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 25 Sep 2023 18:37:12 -0300 Subject: [PATCH 36/86] Implement base hint --- pkg/hints/hint_utils/bigint_utils.go | 9 +++++++ pkg/hints/signature_hints.go | 35 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 pkg/hints/signature_hints.go diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index acbed672..1bb61730 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -93,3 +93,12 @@ func BigInt3FromBaseAddr(addr Relocatable, name string, vm *VirtualMachine) (Big limbs, err := limbsFromBaseAddress(3, name, addr, vm) return BigInt3{Limbs: limbs}, err } + +// Uint384 + +type Uint384 = BigInt3 + +func Uint384FromVarName(name string, ids IdsManager, vm *VirtualMachine) (Uint384, error) { + limbs, err := limbsFromVarName(3, name, ids, vm) + return Uint384{Limbs: limbs}, err +} diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go new file mode 100644 index 00000000..f6f4351f --- /dev/null +++ b/pkg/hints/signature_hints.go @@ -0,0 +1,35 @@ +package hints + +import ( + "math/big" + + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" + . "github.com/lambdaclass/cairo-vm.go/pkg/types" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm" + "github.com/pkg/errors" +) + +func divModNPacked(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, n *big.Int) error { + a, err := Uint384FromVarName("a", ids, vm) + if err != nil { + return err + } + b, err := Uint384FromVarName("b", ids, vm) + if err != nil { + return err + } + packedA := a.Pack86() + packedB := b.Pack86() + + if packedB.Cmp(big.NewInt(0)) == 0 { + return errors.New("Attempted to divide by zero") + } + val := new(big.Int).Mod(new(big.Int).Div(&packedA, &packedB), n) + + scopes.AssignOrUpdateVariable("a", packedA) + scopes.AssignOrUpdateVariable("b", packedB) + scopes.AssignOrUpdateVariable("val", val) + scopes.AssignOrUpdateVariable("res", val) + + return nil +} From ea13432ab4cdd2625df841cecf8ecc7747767d67 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 25 Sep 2023 18:42:20 -0300 Subject: [PATCH 37/86] Add hints --- pkg/hints/signature_hints.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index f6f4351f..05cd5595 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -33,3 +33,21 @@ func divModNPacked(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, return nil } + +func divModNPackedDivMod(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { + n, _ := new(big.Int).SetString("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10) + scopes.AssignOrUpdateVariable("N", n) + return divModNPacked(ids, vm, scopes, n) +} + +func divModNPackedDivModExternalN(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { + nAny, err := scopes.Get("N") + if err != nil { + return err + } + n, ok := nAny.(*big.Int) + if !ok { + return errors.New("N not in scope") + } + return divModNPacked(ids, vm, scopes, n) +} From dd910fac87a9ad8d3ab18ce66ad42a8d3dcfbbed Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 25 Sep 2023 18:49:05 -0300 Subject: [PATCH 38/86] Add hints to ExecuteHint --- pkg/hints/hint_processor.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 8718a624..e8c53010 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -148,6 +148,10 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return splitInt(data.Ids, vm) case SPLIT_INT_ASSERT_RANGE: return splitIntAssertRange(data.Ids, vm) + case DIV_MOD_N_PACKED_DIVMOD_V1: + return divModNPackedDivMod(data.Ids, vm, execScopes) + case DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N: + return divModNPackedDivModExternalN(data.Ids, vm, execScopes) default: return errors.Errorf("Unknown Hint: %s", data.Code) } From 552715d8ebb47aab6b4087761e3cd06760c2e433 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 26 Sep 2023 08:29:15 -0300 Subject: [PATCH 39/86] debug info --- pkg/hints/hint_utils/bigint_utils.go | 5 ++++- pkg/hints/hint_utils/bigint_utils_test.go | 6 +++--- pkg/hints/hint_utils/ids_manager.go | 2 ++ pkg/vm/memory/segments.go | 3 +++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index c408e517..0c7440cb 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -46,10 +46,13 @@ func NondetBigInt3(virtual_machine VirtualMachine, exec_scopes ExecutionScopes, fmt.Println("args: ") for i := 0; i < 3; i++ { m := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(&bigint3_split[i])) - fmt.Println(bigint3_split[i].Text(10)) arg = append(arg, *m) } + for j := 0; j<3 ; j++{ + fmt.Println(arg[j]) + } + virtual_machine.Segments.LoadData(res_relloc, &arg) return nil } diff --git a/pkg/hints/hint_utils/bigint_utils_test.go b/pkg/hints/hint_utils/bigint_utils_test.go index 9d0e734f..f98a6147 100644 --- a/pkg/hints/hint_utils/bigint_utils_test.go +++ b/pkg/hints/hint_utils/bigint_utils_test.go @@ -51,7 +51,7 @@ func TestNonDetBigInt3Ok(t *testing.T) { t.Errorf("error fetching from ids manager : %s", err) } if valueInStruct0 != expected0 { - t.Errorf(" Incorrect field value %s, expected %s", valueInStruct0.ToHexString(), expected0.ToHexString()) + t.Errorf(" Incorrect field value %s, expected %s", valueInStruct0.ToBigInt().Text(10), expected0.ToBigInt().Text(10)) } valueInStruct1, err := idsManager.GetStructFieldFelt("res", 1, vm) @@ -60,7 +60,7 @@ func TestNonDetBigInt3Ok(t *testing.T) { t.Errorf("error fetching from ids manager : %s", err) } if valueInStruct1 != expected1 { - t.Errorf(" Incorrect field value %s, expected %s", valueInStruct1.ToHexString(), expected1.ToHexString()) + t.Errorf(" Incorrect field value %s, expected %s", valueInStruct1.ToBigInt().Text(10), expected1.ToBigInt().Text(10)) } valueInStruct2, err := idsManager.GetStructFieldFelt("res", 2, vm) @@ -69,7 +69,7 @@ func TestNonDetBigInt3Ok(t *testing.T) { t.Errorf("error fetching from ids manager : %s", err) } if valueInStruct2 != expected2 { - t.Errorf(" Incorrect field value %s, expected %s", valueInStruct2.ToHexString(), expected2.ToHexString()) + t.Errorf(" Incorrect field value %s, expected %s", valueInStruct2.ToBigInt().Text(10), expected2.ToBigInt().Text(10)) } } } diff --git a/pkg/hints/hint_utils/ids_manager.go b/pkg/hints/hint_utils/ids_manager.go index 700f42a4..8677c2be 100644 --- a/pkg/hints/hint_utils/ids_manager.go +++ b/pkg/hints/hint_utils/ids_manager.go @@ -252,9 +252,11 @@ func getValueFromReference(reference *HintReference, apTracking parser.ApTrackin func getStructFieldFromReference(reference *HintReference, field_off uint, apTracking parser.ApTrackingData, vm *VirtualMachine) (*MaybeRelocatable, bool) { addr, ok := getAddressFromReference(reference, apTracking, vm) + fmt.Println("addr", addr.AddUint(field_off)) if ok { if reference.Dereference { val, err := vm.Segments.Memory.Get(addr.AddUint(field_off)) + fmt.Println("value fetched", val) if err == nil { return val, true } diff --git a/pkg/vm/memory/segments.go b/pkg/vm/memory/segments.go index 732ee0b7..8e669fd3 100644 --- a/pkg/vm/memory/segments.go +++ b/pkg/vm/memory/segments.go @@ -1,6 +1,8 @@ package memory import ( + "fmt" + "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" ) @@ -97,6 +99,7 @@ func (s *MemorySegmentManager) RelocateMemory(relocationTable *[]uint) (map[uint // If any insertion fails, returns (0,0) and the memory insertion error func (m *MemorySegmentManager) LoadData(ptr Relocatable, data *[]MaybeRelocatable) (Relocatable, error) { for _, val := range *data { + fmt.Println("value being inserted: at possition", val, ptr) err := m.Memory.Insert(ptr, &val) if err != nil { return Relocatable{0, 0}, err From af1afcb06d86e1a005289e3454592e3c0f8d6987 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 26 Sep 2023 12:06:31 -0300 Subject: [PATCH 40/86] Fix broken test --- pkg/hints/ec_hint.go | 3 --- pkg/hints/ec_hint_test.go | 17 +++++++++-------- pkg/hints/field_utils.go | 8 +------- pkg/hints/hint_utils/bigint_utils.go | 15 +++------------ pkg/hints/hint_utils/bigint_utils_test.go | 2 +- pkg/hints/hint_utils/ids_manager.go | 10 ++++------ pkg/hints/hint_utils/secp_utils.go | 5 ++--- pkg/lambdaworks/lambdaworks.go | 7 +++---- pkg/vm/memory/segments.go | 4 +--- pkg/vm/vm_core.go | 2 ++ 10 files changed, 26 insertions(+), 47 deletions(-) diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index 43d847c0..ee974108 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -1,7 +1,6 @@ package hints import ( - "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/builtins" @@ -230,7 +229,6 @@ Implements hint: */ func computeDoublingSlopeExternalConsts(vm VirtualMachine, execScopes ExecutionScopes, ids_data IdsManager) error { // ids.point - fmt.Println("compute doubling slope extenral ") point, err := EcPointFromVarName("point", &vm, ids_data) if err != nil { return err @@ -251,7 +249,6 @@ func computeDoublingSlopeExternalConsts(vm VirtualMachine, execScopes ExecutionS double_point_b := builtins.DoublePointB{X: point.X.Pack86(), Y: point.Y.Pack86()} value, err := builtins.EcDoubleSlope(double_point_b, alpha, secp_p) - fmt.Println("value of ec double slope", value.Text(10)) if err != nil { return err } diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 0b08bcd2..2d5d5dde 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_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/cairo_run" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) @@ -235,11 +236,11 @@ func TestRunComputeSlopeOk(t *testing.T) { } } -// func TestIntegrationEcDoubleSlope(t *testing.T) { -// t.Helper() -// cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false} -// _, err := cairo_run.CairoRun("../../cairo_programs/ec_double_slope.json", cairoRunConfig) -// if err != nil { -// t.Errorf("TestIntegrationEcSlope failed with error:\n %v", err) -// } -// } +func TestIntegrationEcDoubleSlope(t *testing.T) { + t.Helper() + cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false} + _, err := cairo_run.CairoRun("../../cairo_programs/ec_double_slope.json", cairoRunConfig) + if err != nil { + t.Errorf("TestIntegrationEcSlope failed with error:\n %v", err) + } +} diff --git a/pkg/hints/field_utils.go b/pkg/hints/field_utils.go index ca99ef83..11caef6e 100644 --- a/pkg/hints/field_utils.go +++ b/pkg/hints/field_utils.go @@ -2,7 +2,6 @@ package hints import ( "errors" - "fmt" "math/big" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" @@ -25,29 +24,24 @@ Implements hint: */ func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, idsData IdsManager) error { - fmt.Println("inside verify") secpPuncast, err := execScopes.Get("SECP_P") if err != nil { return err } secpP := secpPuncast.(big.Int) - fmt.Println("secp: ", secpP.Text(10)) addr, err := idsData.GetAddr("val", &vm) - fmt.Println("addr or err:", addr, err) if err != nil { return err } - fmt.Println("addr ", addr) val, err := BigInt3FromBaseAddr(addr, "val", &vm) if err != nil { return err } v := val.Pack86() - fmt.Println("val in zero with external: ", v.Text(10)) q, r := v.DivMod(&v, &secpP, new(big.Int)) - fmt.Println("r: ", r) + if r.Cmp(big.NewInt(0)) != 0 { return errors.New("verify remainder is not zero: Invalid input") } diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index 0c7440cb..737a85e8 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -1,7 +1,6 @@ package hint_utils import ( - "fmt" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" @@ -28,14 +27,11 @@ func NondetBigInt3(virtual_machine VirtualMachine, exec_scopes ExecutionScopes, return err } - fmt.Println("res alloc: ", res_relloc) - value_uncast, err := exec_scopes.Get("value") if err != nil { return err } value := value_uncast.(big.Int) - fmt.Println("value in nond int: \n", value.Text(10)) bigint3_split, err := Bigint3Split(value) if err != nil { @@ -43,16 +39,11 @@ func NondetBigInt3(virtual_machine VirtualMachine, exec_scopes ExecutionScopes, } arg := make([]memory.MaybeRelocatable, 0) - fmt.Println("args: ") for i := 0; i < 3; i++ { m := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(&bigint3_split[i])) arg = append(arg, *m) } - for j := 0; j<3 ; j++{ - fmt.Println(arg[j]) - } - virtual_machine.Segments.LoadData(res_relloc, &arg) return nil } @@ -70,15 +61,15 @@ func limbsFromVarName(nLimbs int, name string, ids IdsManager, vm *VirtualMachin } func limbsFromBaseAddress(nLimbs int, name string, addr Relocatable, vm *VirtualMachine) ([]Felt, error) { - fmt.Println("addr in libms base addr: ", addr) + //fmt.Println("addr in libms base addr: ", addr) limbs := make([]Felt, 0) for i := 0; i < nLimbs; i++ { felt, err := vm.Segments.Memory.GetFelt(addr.AddUint(uint(i))) - fmt.Println("value in memory: ", felt.ToBigInt().Text(10), addr.AddUint(uint(i))) + //fmt.Println("value in memory: ", felt.ToBigInt().Text(10), addr.AddUint(uint(i))) if err == nil { limbs = append(limbs, felt) } else { - fmt.Println("error name: ", name) + //fmt.Println("error name: ", name) return nil, errors.Errorf("Identifier %s has no member d%d", name, i) } } diff --git a/pkg/hints/hint_utils/bigint_utils_test.go b/pkg/hints/hint_utils/bigint_utils_test.go index f98a6147..478117fd 100644 --- a/pkg/hints/hint_utils/bigint_utils_test.go +++ b/pkg/hints/hint_utils/bigint_utils_test.go @@ -46,7 +46,7 @@ func TestNonDetBigInt3Ok(t *testing.T) { t.Errorf("Non Det Big Int 3 hint test failed with error: %s", err) } else { valueInStruct0, err := idsManager.GetStructFieldFelt("res", 0, vm) - expected0 := lambdaworks.FeltFromUint(773712524553362) + expected0 := lambdaworks.FeltFromDecString("773712524553362") if err != nil { t.Errorf("error fetching from ids manager : %s", err) } diff --git a/pkg/hints/hint_utils/ids_manager.go b/pkg/hints/hint_utils/ids_manager.go index 8677c2be..a3c899bd 100644 --- a/pkg/hints/hint_utils/ids_manager.go +++ b/pkg/hints/hint_utils/ids_manager.go @@ -1,8 +1,6 @@ package hint_utils import ( - "fmt" - "github.com/pkg/errors" "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" @@ -59,7 +57,7 @@ func (ids *IdsManager) GetConst(name string, constants *map[string]lambdaworks.F func (ids *IdsManager) Insert(name string, value *MaybeRelocatable, vm *VirtualMachine) error { addr, err := ids.GetAddr(name, vm) - fmt.Println("insert in addres", addr) + //fmt.Println("insert in addres", addr) if err != nil { return err } @@ -243,7 +241,7 @@ func getValueFromReference(reference *HintReference, apTracking parser.ApTrackin return val, true } } else { - fmt.Println("enter else case") + //fmt.Println("enter else case") return NewMaybeRelocatableRelocatable(addr), true } } @@ -252,11 +250,11 @@ func getValueFromReference(reference *HintReference, apTracking parser.ApTrackin func getStructFieldFromReference(reference *HintReference, field_off uint, apTracking parser.ApTrackingData, vm *VirtualMachine) (*MaybeRelocatable, bool) { addr, ok := getAddressFromReference(reference, apTracking, vm) - fmt.Println("addr", addr.AddUint(field_off)) + //fmt.Println("addr", addr.AddUint(field_off)) if ok { if reference.Dereference { val, err := vm.Segments.Memory.Get(addr.AddUint(field_off)) - fmt.Println("value fetched", val) + //fmt.Println("value fetched", val) if err == nil { return val, true } diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go index e5295323..4c29ea9b 100644 --- a/pkg/hints/hint_utils/secp_utils.go +++ b/pkg/hints/hint_utils/secp_utils.go @@ -2,7 +2,6 @@ package hint_utils import ( "errors" - "fmt" "math/big" ) @@ -39,11 +38,11 @@ func BASE_MINUS_ONE() *big.Int { func Bigint3Split(integer big.Int) ([]big.Int, error) { canonicalRepr := make([]big.Int, 3) num := integer - fmt.Println("canonical repr: ") + //fmt.Println("canonical repr: ") for i := 0; i < 3; i++ { canonicalRepr[i] = *new(big.Int).And(&num, BASE_MINUS_ONE()) - fmt.Println(canonicalRepr[i].Text(10)) + //fmt.Println(canonicalRepr[i].Text(10)) num.Rsh(&num, 86) } if num.Cmp(big.NewInt(0)) != 0 { diff --git a/pkg/lambdaworks/lambdaworks.go b/pkg/lambdaworks/lambdaworks.go index 59f3a477..c2ef874c 100644 --- a/pkg/lambdaworks/lambdaworks.go +++ b/pkg/lambdaworks/lambdaworks.go @@ -309,10 +309,9 @@ func FeltFromBigInt(n *big.Int) Felt { if n.Cmp(prime) != -1 { n = new(big.Int).Mod(n, prime) } - bytes := n.Bytes() - var bytes32 [32]byte - copy(bytes32[:], bytes) - return FeltFromLeBytes(&bytes32) + + value := n.Text(10) + return FeltFromDecString(value) } const CAIRO_PRIME_HEX = "0x800000000000011000000000000000000000000000000000000000000000001" diff --git a/pkg/vm/memory/segments.go b/pkg/vm/memory/segments.go index 8e669fd3..21029d3a 100644 --- a/pkg/vm/memory/segments.go +++ b/pkg/vm/memory/segments.go @@ -1,8 +1,6 @@ package memory import ( - "fmt" - "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" ) @@ -99,7 +97,7 @@ func (s *MemorySegmentManager) RelocateMemory(relocationTable *[]uint) (map[uint // If any insertion fails, returns (0,0) and the memory insertion error func (m *MemorySegmentManager) LoadData(ptr Relocatable, data *[]MaybeRelocatable) (Relocatable, error) { for _, val := range *data { - fmt.Println("value being inserted: at possition", val, ptr) + //fmt.Println("value being inserted: at possition", val, ptr) err := m.Memory.Insert(ptr, &val) if err != nil { return Relocatable{0, 0}, err diff --git a/pkg/vm/vm_core.go b/pkg/vm/vm_core.go index 7f5aec40..cb02b175 100644 --- a/pkg/vm/vm_core.go +++ b/pkg/vm/vm_core.go @@ -247,6 +247,8 @@ func (vm *VirtualMachine) OpcodeAssertions(instruction Instruction, operands Ope return &VirtualMachineError{"UnconstrainedResAssertEq"} } if !operands.Res.IsEqual(&operands.Dst) { + fmt.Println("operands Res: ", operands.Res) + fmt.Println("Operands des: ", operands.Dst) return &VirtualMachineError{"DiffAssertValues"} } case Call: From 69d015ec2d37e93694a2023b510a0b91548a7691 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 26 Sep 2023 12:17:14 -0300 Subject: [PATCH 41/86] Move integration test to cairo_run_test.go --- pkg/hints/bigint_hint.go | 56 ++++++++++++++++++++++ pkg/hints/{hint_utils => }/bigint_utils.go | 43 ++--------------- pkg/hints/ec_hint.go | 20 +++++--- pkg/hints/ec_hint_test.go | 10 ---- pkg/hints/field_utils.go | 6 ++- pkg/hints/hint_utils/ids_manager.go | 1 - pkg/vm/cairo_run/cairo_run_test.go | 4 ++ 7 files changed, 82 insertions(+), 58 deletions(-) create mode 100644 pkg/hints/bigint_hint.go rename pkg/hints/{hint_utils => }/bigint_utils.go (72%) diff --git a/pkg/hints/bigint_hint.go b/pkg/hints/bigint_hint.go new file mode 100644 index 00000000..1cc58f07 --- /dev/null +++ b/pkg/hints/bigint_hint.go @@ -0,0 +1,56 @@ +package hints + +import ( + "errors" + "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/vm" + "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" +) + +/* +Implements hint: +%{ + from starkware.cairo.common.cairo_secp.secp_utils import split + + segments.write_arg(ids.res.address_, split(value)) +%} +*/ + +func NondetBigInt3(virtual_machine VirtualMachine, execScopes ExecutionScopes, idsData IdsManager) error { + resRelloc, err := idsData.GetAddr("res", &virtual_machine) + if err != nil { + return err + } + + valueUncast, err := execScopes.Get("value") + if err != nil { + return err + } + value, ok := valueUncast.(big.Int) + if !ok { + return errors.New("Could not cast value into big int") + } + + bigint3Split, err := Bigint3Split(value) + if err != nil { + return err + } + + arg := make([]memory.MaybeRelocatable, 0) + + for i := 0; i < 3; i++ { + m := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(&bigint3Split[i])) + arg = append(arg, *m) + } + + _, load_err := virtual_machine.Segments.LoadData(resRelloc, &arg) + if load_err != nil { + return load_err + } + + return nil +} diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/bigint_utils.go similarity index 72% rename from pkg/hints/hint_utils/bigint_utils.go rename to pkg/hints/bigint_utils.go index 4f1e537d..9e651933 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/bigint_utils.go @@ -1,53 +1,16 @@ -package hint_utils +package hints import ( "math/big" - "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" + . "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/vm" - "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" + "github.com/pkg/errors" ) -/* -Implements hint: -%{ - from starkware.cairo.common.cairo_secp.secp_utils import split - - segments.write_arg(ids.res.address_, split(value)) -%} -*/ - -func NondetBigInt3(virtual_machine VirtualMachine, exec_scopes ExecutionScopes, ids_data IdsManager) error { - res_relloc, err := ids_data.GetAddr("res", &virtual_machine) - if err != nil { - return err - } - - value_uncast, err := exec_scopes.Get("value") - if err != nil { - return err - } - value := value_uncast.(big.Int) - - bigint3_split, err := Bigint3Split(value) - if err != nil { - return err - } - arg := make([]memory.MaybeRelocatable, 0) - - for i := 0; i < 3; i++ { - m := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(&bigint3_split[i])) - arg = append(arg, *m) - } - - virtual_machine.Segments.LoadData(res_relloc, &arg) - return nil -} - // In cairo, various structs are used to represent big integers, all of them have numbered fields of Felt type (d0, d1,...) and share the same behaviours // This file contains an implementation of each behaviour at the limbs level, and the wrappers for each specific type diff --git a/pkg/hints/ec_hint.go b/pkg/hints/ec_hint.go index ee974108..62b70e2a 100644 --- a/pkg/hints/ec_hint.go +++ b/pkg/hints/ec_hint.go @@ -1,6 +1,7 @@ package hints import ( + "errors" "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/builtins" @@ -234,21 +235,28 @@ func computeDoublingSlopeExternalConsts(vm VirtualMachine, execScopes ExecutionS return err } - secp_p_uncast, err := execScopes.Get("SECP_P") + secpPuncast, err := execScopes.Get("SECP_P") if err != nil { return err } - secp_p := secp_p_uncast.(big.Int) + secpP, ok := secpPuncast.(big.Int) + if !ok { + return errors.New("Could not cast secp into big int") + } - alpha_uncast, err := execScopes.Get("ALPHA") + alphaUncast, err := execScopes.Get("ALPHA") if err != nil { return nil } - alpha := alpha_uncast.(big.Int) - double_point_b := builtins.DoublePointB{X: point.X.Pack86(), Y: point.Y.Pack86()} + alpha, ok := alphaUncast.(big.Int) + if !ok { + return errors.New("Could not cast alpha into big int") + } + + doublePoint_b := builtins.DoublePointB{X: point.X.Pack86(), Y: point.Y.Pack86()} - value, err := builtins.EcDoubleSlope(double_point_b, alpha, secp_p) + value, err := builtins.EcDoubleSlope(doublePoint_b, alpha, secpP) if err != nil { return err } diff --git a/pkg/hints/ec_hint_test.go b/pkg/hints/ec_hint_test.go index 2d5d5dde..4e5e0fbc 100644 --- a/pkg/hints/ec_hint_test.go +++ b/pkg/hints/ec_hint_test.go @@ -10,7 +10,6 @@ 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/cairo_run" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) @@ -235,12 +234,3 @@ func TestRunComputeSlopeOk(t *testing.T) { } } } - -func TestIntegrationEcDoubleSlope(t *testing.T) { - t.Helper() - cairoRunConfig := cairo_run.CairoRunConfig{DisableTracePadding: false, Layout: "all_cairo", ProofMode: false} - _, err := cairo_run.CairoRun("../../cairo_programs/ec_double_slope.json", cairoRunConfig) - if err != nil { - t.Errorf("TestIntegrationEcSlope failed with error:\n %v", err) - } -} diff --git a/pkg/hints/field_utils.go b/pkg/hints/field_utils.go index 11caef6e..96e72ceb 100644 --- a/pkg/hints/field_utils.go +++ b/pkg/hints/field_utils.go @@ -28,7 +28,11 @@ func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, if err != nil { return err } - secpP := secpPuncast.(big.Int) + secpP, ok := secpPuncast.(big.Int) + if !ok { + return errors.New("Could not cast secpP into big int") + } + addr, err := idsData.GetAddr("val", &vm) if err != nil { return err diff --git a/pkg/hints/hint_utils/ids_manager.go b/pkg/hints/hint_utils/ids_manager.go index ec50f7e0..ef2550b5 100644 --- a/pkg/hints/hint_utils/ids_manager.go +++ b/pkg/hints/hint_utils/ids_manager.go @@ -126,7 +126,6 @@ func (ids *IdsManager) GetAddr(name string, vm *VirtualMachine) (Relocatable, er ids_lives := ids.GetStructField("cat", 0, vm) or ids_lives := ids.Get("cat", vm) ids_paws := ids.GetStructField("cat", 1, vm) */ - func (ids *IdsManager) GetStructField(name string, field_off uint, vm *VirtualMachine) (*MaybeRelocatable, error) { reference, ok := ids.References[name] if ok { diff --git a/pkg/vm/cairo_run/cairo_run_test.go b/pkg/vm/cairo_run/cairo_run_test.go index 34ad51dd..a11cc8bc 100644 --- a/pkg/vm/cairo_run/cairo_run_test.go +++ b/pkg/vm/cairo_run/cairo_run_test.go @@ -320,3 +320,7 @@ func TestSplitIntHint(t *testing.T) { func TestSplitIntHintProofMode(t *testing.T) { testProgramProof("split_int", t) } + +func TestIntegrationEcDoubleSlope(t *testing.T) { + testProgram("ec_double_slope", t) +} From b5f44e202ef360fd69cf69aa59f970843203546a Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 26 Sep 2023 12:20:32 -0300 Subject: [PATCH 42/86] Move file from hints_utils and rename --- .../{hint_utils/bigint_utils_test.go => bigint_hint_test.go} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename pkg/hints/{hint_utils/bigint_utils_test.go => bigint_hint_test.go} (99%) diff --git a/pkg/hints/hint_utils/bigint_utils_test.go b/pkg/hints/bigint_hint_test.go similarity index 99% rename from pkg/hints/hint_utils/bigint_utils_test.go rename to pkg/hints/bigint_hint_test.go index 478117fd..27bc55b4 100644 --- a/pkg/hints/hint_utils/bigint_utils_test.go +++ b/pkg/hints/bigint_hint_test.go @@ -1,4 +1,4 @@ -package hint_utils_test +package hints_test import ( "math/big" From 6cfabdf09f033d526c06a2b3363b491ad41cdaff Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 26 Sep 2023 12:39:45 -0300 Subject: [PATCH 43/86] Delete debug --- pkg/hints/hint_utils/bigint_utils.go | 3 --- pkg/hints/hint_utils/ids_manager.go | 4 ---- pkg/hints/hint_utils/secp_utils.go | 2 -- pkg/vm/memory/segments.go | 1 - pkg/vm/vm_core.go | 2 -- 5 files changed, 12 deletions(-) diff --git a/pkg/hints/hint_utils/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go index 737a85e8..4f1e537d 100644 --- a/pkg/hints/hint_utils/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -61,15 +61,12 @@ func limbsFromVarName(nLimbs int, name string, ids IdsManager, vm *VirtualMachin } func limbsFromBaseAddress(nLimbs int, name string, addr Relocatable, vm *VirtualMachine) ([]Felt, error) { - //fmt.Println("addr in libms base addr: ", addr) limbs := make([]Felt, 0) for i := 0; i < nLimbs; i++ { felt, err := vm.Segments.Memory.GetFelt(addr.AddUint(uint(i))) - //fmt.Println("value in memory: ", felt.ToBigInt().Text(10), addr.AddUint(uint(i))) if err == nil { limbs = append(limbs, felt) } else { - //fmt.Println("error name: ", name) return nil, errors.Errorf("Identifier %s has no member d%d", name, i) } } diff --git a/pkg/hints/hint_utils/ids_manager.go b/pkg/hints/hint_utils/ids_manager.go index a3c899bd..ec50f7e0 100644 --- a/pkg/hints/hint_utils/ids_manager.go +++ b/pkg/hints/hint_utils/ids_manager.go @@ -57,7 +57,6 @@ func (ids *IdsManager) GetConst(name string, constants *map[string]lambdaworks.F func (ids *IdsManager) Insert(name string, value *MaybeRelocatable, vm *VirtualMachine) error { addr, err := ids.GetAddr(name, vm) - //fmt.Println("insert in addres", addr) if err != nil { return err } @@ -241,7 +240,6 @@ func getValueFromReference(reference *HintReference, apTracking parser.ApTrackin return val, true } } else { - //fmt.Println("enter else case") return NewMaybeRelocatableRelocatable(addr), true } } @@ -250,11 +248,9 @@ func getValueFromReference(reference *HintReference, apTracking parser.ApTrackin func getStructFieldFromReference(reference *HintReference, field_off uint, apTracking parser.ApTrackingData, vm *VirtualMachine) (*MaybeRelocatable, bool) { addr, ok := getAddressFromReference(reference, apTracking, vm) - //fmt.Println("addr", addr.AddUint(field_off)) if ok { if reference.Dereference { val, err := vm.Segments.Memory.Get(addr.AddUint(field_off)) - //fmt.Println("value fetched", val) if err == nil { return val, true } diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go index 4c29ea9b..3ceaa4bf 100644 --- a/pkg/hints/hint_utils/secp_utils.go +++ b/pkg/hints/hint_utils/secp_utils.go @@ -38,11 +38,9 @@ func BASE_MINUS_ONE() *big.Int { func Bigint3Split(integer big.Int) ([]big.Int, error) { canonicalRepr := make([]big.Int, 3) num := integer - //fmt.Println("canonical repr: ") for i := 0; i < 3; i++ { canonicalRepr[i] = *new(big.Int).And(&num, BASE_MINUS_ONE()) - //fmt.Println(canonicalRepr[i].Text(10)) num.Rsh(&num, 86) } if num.Cmp(big.NewInt(0)) != 0 { diff --git a/pkg/vm/memory/segments.go b/pkg/vm/memory/segments.go index 21029d3a..732ee0b7 100644 --- a/pkg/vm/memory/segments.go +++ b/pkg/vm/memory/segments.go @@ -97,7 +97,6 @@ func (s *MemorySegmentManager) RelocateMemory(relocationTable *[]uint) (map[uint // If any insertion fails, returns (0,0) and the memory insertion error func (m *MemorySegmentManager) LoadData(ptr Relocatable, data *[]MaybeRelocatable) (Relocatable, error) { for _, val := range *data { - //fmt.Println("value being inserted: at possition", val, ptr) err := m.Memory.Insert(ptr, &val) if err != nil { return Relocatable{0, 0}, err diff --git a/pkg/vm/vm_core.go b/pkg/vm/vm_core.go index cb02b175..7f5aec40 100644 --- a/pkg/vm/vm_core.go +++ b/pkg/vm/vm_core.go @@ -247,8 +247,6 @@ func (vm *VirtualMachine) OpcodeAssertions(instruction Instruction, operands Ope return &VirtualMachineError{"UnconstrainedResAssertEq"} } if !operands.Res.IsEqual(&operands.Dst) { - fmt.Println("operands Res: ", operands.Res) - fmt.Println("Operands des: ", operands.Dst) return &VirtualMachineError{"DiffAssertValues"} } case Call: From 6527b7243000bc88e7923193d91ac45a34bbcf4f Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 26 Sep 2023 12:47:51 -0300 Subject: [PATCH 44/86] Return error of IdsData.Insert --- pkg/hints/field_utils.go | 3 +-- pkg/hints/{ => hint_utils}/bigint_utils.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) rename pkg/hints/{ => hint_utils}/bigint_utils.go (97%) diff --git a/pkg/hints/field_utils.go b/pkg/hints/field_utils.go index 96e72ceb..bb81d791 100644 --- a/pkg/hints/field_utils.go +++ b/pkg/hints/field_utils.go @@ -51,6 +51,5 @@ func verifyZeroWithExternalConst(vm VirtualMachine, execScopes ExecutionScopes, } quotient := memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(q)) - idsData.Insert("q", quotient, &vm) - return nil + return idsData.Insert("q", quotient, &vm) } diff --git a/pkg/hints/bigint_utils.go b/pkg/hints/hint_utils/bigint_utils.go similarity index 97% rename from pkg/hints/bigint_utils.go rename to pkg/hints/hint_utils/bigint_utils.go index 9e651933..c6d68c8c 100644 --- a/pkg/hints/bigint_utils.go +++ b/pkg/hints/hint_utils/bigint_utils.go @@ -1,9 +1,8 @@ -package hints +package hint_utils import ( "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/vm" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" From 2bcf01575f0f9c21fa8e85ee8681f0543b4d0734 Mon Sep 17 00:00:00 2001 From: Milton Date: Tue, 26 Sep 2023 12:49:46 -0300 Subject: [PATCH 45/86] Change to camel case --- pkg/hints/bigint_hint.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/hints/bigint_hint.go b/pkg/hints/bigint_hint.go index 1cc58f07..a13fc098 100644 --- a/pkg/hints/bigint_hint.go +++ b/pkg/hints/bigint_hint.go @@ -47,9 +47,9 @@ func NondetBigInt3(virtual_machine VirtualMachine, execScopes ExecutionScopes, i arg = append(arg, *m) } - _, load_err := virtual_machine.Segments.LoadData(resRelloc, &arg) - if load_err != nil { - return load_err + _, loadErr := virtual_machine.Segments.LoadData(resRelloc, &arg) + if loadErr != nil { + return loadErr } return nil From b542a09e6f135e9cc6011c87c62507cd344d4aee Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 13:59:02 -0300 Subject: [PATCH 46/86] Add unit test --- pkg/hints/signature_hints_test.go | 56 +++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 pkg/hints/signature_hints_test.go diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go new file mode 100644 index 00000000..9596412e --- /dev/null +++ b/pkg/hints/signature_hints_test.go @@ -0,0 +1,56 @@ +package hints_test + +import ( + "math/big" + "testing" + + . "github.com/lambdaclass/cairo-vm.go/pkg/hints" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" + . "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/vm" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" +) + +func TestDivModNPackedDivMod(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "a": { + NewMaybeRelocatableFelt(FeltFromUint64(10)), + NewMaybeRelocatableFelt(FeltFromUint64(0)), + NewMaybeRelocatableFelt(FeltFromUint64(0)), + }, + "b": { + NewMaybeRelocatableFelt(FeltFromUint64(2)), + NewMaybeRelocatableFelt(FeltFromUint64(0)), + NewMaybeRelocatableFelt(FeltFromUint64(0)), + }, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: DIV_MOD_N_PACKED_DIVMOD_V1, + }) + scopes := NewExecutionScopes() + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("DIV_MOD_N_PACKED_DIVMOD_V1 hint test failed with error %s", err) + } + // Check result in scope + expectedRes := big.NewInt(5) + + res, err := scopes.Get("res") + if err != nil || res.(*big.Int).Cmp(expectedRes) != 0 { + t.Error("Wrong/No scope value res") + } + + val, err := scopes.Get("val") + if err != nil || val.(*big.Int).Cmp(expectedRes) != 0 { + t.Error("Wrong/No scope value val") + } +} From 8cd64b6a6f690fcbdc6617be5bf956658bfc24af Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 14:01:35 -0300 Subject: [PATCH 47/86] Add unit test --- pkg/hints/signature_hints_test.go | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go index 9596412e..2e25e605 100644 --- a/pkg/hints/signature_hints_test.go +++ b/pkg/hints/signature_hints_test.go @@ -54,3 +54,46 @@ func TestDivModNPackedDivMod(t *testing.T) { t.Error("Wrong/No scope value val") } } + +func TestDivModNPackedDivModExternalN(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "a": { + NewMaybeRelocatableFelt(FeltFromUint64(20)), + NewMaybeRelocatableFelt(FeltFromUint64(0)), + NewMaybeRelocatableFelt(FeltFromUint64(0)), + }, + "b": { + NewMaybeRelocatableFelt(FeltFromUint64(2)), + NewMaybeRelocatableFelt(FeltFromUint64(0)), + NewMaybeRelocatableFelt(FeltFromUint64(0)), + }, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N, + }) + scopes := NewExecutionScopes() + scopes.AssignOrUpdateVariable("N", big.NewInt(7)) + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N hint test failed with error %s", err) + } + // Check result in scope + expectedRes := big.NewInt(3) + + res, err := scopes.Get("res") + if err != nil || res.(*big.Int).Cmp(expectedRes) != 0 { + t.Error("Wrong/No scope value res") + } + + val, err := scopes.Get("val") + if err != nil || val.(*big.Int).Cmp(expectedRes) != 0 { + t.Error("Wrong/No scope value val") + } +} From f3d9dbed8dd53c2321d83fb8346f522b137d033c Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 14:13:25 -0300 Subject: [PATCH 48/86] Add hint codes --- pkg/hints/hint_codes/signature_hint_codes.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/hints/hint_codes/signature_hint_codes.go b/pkg/hints/hint_codes/signature_hint_codes.go index ce65dfe6..40d11b91 100644 --- a/pkg/hints/hint_codes/signature_hint_codes.go +++ b/pkg/hints/hint_codes/signature_hint_codes.go @@ -13,3 +13,7 @@ from starkware.python.math_utils import div_mod, safe_div a = pack(ids.a, PRIME) b = pack(ids.b, PRIME) value = res = div_mod(a, b, N)` + +const DIV_MOD_N_SAFE_DIV = "value = k = safe_div(res * b - a, N)" + +const DIV_MOD_N_SAFE_DIV_PLUS_ONE = "value = k_plus_one = safe_div(res * b - a, N) + 1" From 91f81888bd969a20836bf898e1f23d513983a651 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 14:43:00 -0300 Subject: [PATCH 49/86] Implement hint --- pkg/hints/signature_hints.go | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index 05cd5595..a2cd8d24 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -5,6 +5,7 @@ import ( . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_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" "github.com/pkg/errors" ) @@ -51,3 +52,53 @@ func divModNPackedDivModExternalN(ids IdsManager, vm *VirtualMachine, scopes *Ex } return divModNPacked(ids, vm, scopes, n) } + +func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAlias string, toAdd int64) error { + // Fetch scope variables + aAny, err := scopes.Get(aAlias) + if err != nil { + return err + } + a, ok := aAny.(*big.Int) + if !ok { + return errors.Errorf("%s not in scope", aAlias) + } + + bAny, err := scopes.Get(bAlias) + if err != nil { + return err + } + b, ok := bAny.(*big.Int) + if !ok { + return errors.Errorf("%s not in scope", bAlias) + } + + resAny, err := scopes.Get("res") + if err != nil { + return err + } + res, ok := resAny.(*big.Int) + if !ok { + return errors.New("res not in scope") + } + + nAny, err := scopes.Get("N") + if err != nil { + return err + } + n, ok := nAny.(*big.Int) + if !ok { + return errors.New("N not in scope") + } + // Hint logic + value, err := utils.SafeDivBig(new(big.Int).Mul(res, new(big.Int).Sub(a, b)), n) + if err != nil { + return err + } + if toAdd != 0 { + value = new(big.Int).Add(value, big.NewInt(toAdd)) + } + // Update scope + scopes.AssignOrUpdateVariable("value", value) + return nil +} From 29efa2dcf69fa3da7aebc1978fc7dc6dc7642278 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 14:53:53 -0300 Subject: [PATCH 50/86] Add SafeDivBig --- pkg/utils/math_utils.go | 13 ++++++++++ pkg/utils/math_utils_test.go | 46 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 pkg/utils/math_utils_test.go diff --git a/pkg/utils/math_utils.go b/pkg/utils/math_utils.go index 54000f2d..b1054f70 100644 --- a/pkg/utils/math_utils.go +++ b/pkg/utils/math_utils.go @@ -2,6 +2,7 @@ package utils import ( "math" + "math/big" "github.com/pkg/errors" ) @@ -50,3 +51,15 @@ func DivCeil(x uint, y uint) uint { } return q } + +// Performs integer division between x and y; fails if x is not divisible by y. +func SafeDivBig(x *big.Int, y *big.Int) (*big.Int, error) { + if y.Cmp(big.NewInt(0)) == 0 { + return &big.Int{}, errors.New("SafeDiv: Attempted to divide by zero") + } + q, r := x.DivMod(x, y, new(big.Int)) + if r.Cmp(big.NewInt(0)) != 0 { + return &big.Int{}, errors.Errorf("SafeDiv: %s is not divisible by %s", x.Text(10), y.Text(10)) + } + return q, nil +} diff --git a/pkg/utils/math_utils_test.go b/pkg/utils/math_utils_test.go new file mode 100644 index 00000000..e3b2a152 --- /dev/null +++ b/pkg/utils/math_utils_test.go @@ -0,0 +1,46 @@ +package utils_test + +import ( + "math/big" + "testing" + + . "github.com/lambdaclass/cairo-vm.go/pkg/utils" +) + +func TestSafeDivBigOkSmallNumbers(t *testing.T) { + a := big.NewInt(10) + b := big.NewInt(5) + expected := big.NewInt(2) + val, err := SafeDivBig(a, b) + if err != nil || val.Cmp(expected) != 0 { + t.Error("Wrong value returned by SafeDivBig") + } +} + +func TestSafeDivBigOkBigNumbers(t *testing.T) { + a, _ := new(big.Int).SetString("1354671610274991796869769298862800192014", 10) + b, _ := new(big.Int).SetString("37853847583", 10) + expected, _ := new(big.Int).SetString("35786893453952854863476753458", 10) + val, err := SafeDivBig(a, b) + if err != nil || val.Cmp(expected) != 0 { + t.Error("Wrong value returned by SafeDivBig") + } +} + +func TestSafeDivBigErrNotDivisible(t *testing.T) { + a := big.NewInt(10) + b := big.NewInt(7) + _, err := SafeDivBig(a, b) + if err == nil { + t.Error("SafeDivBig should have failed") + } +} + +func TestSafeDivBigErrZeroDivison(t *testing.T) { + a := big.NewInt(10) + b := big.NewInt(0) + _, err := SafeDivBig(a, b) + if err == nil { + t.Error("SafeDivBig should have failed") + } +} From d0cc45e78b7d8b276c0e0ea60f0970881d7743be Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 15:08:49 -0300 Subject: [PATCH 51/86] Add generic way to fetch scope variables --- pkg/types/exec_scope_test.go | 18 ++++++++++++++++++ pkg/types/exec_scopes.go | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/pkg/types/exec_scope_test.go b/pkg/types/exec_scope_test.go index 119f266d..6eb1d97e 100644 --- a/pkg/types/exec_scope_test.go +++ b/pkg/types/exec_scope_test.go @@ -258,3 +258,21 @@ func TestErrExitMainScope(t *testing.T) { t.Errorf("TestErrExitMainScope should fail with error: %s and fails with: %s", types.ErrCannotExitMainScop, err) } } + +func TestFetchScopeVar(t *testing.T) { + scope := make(map[string]interface{}) + scope["k"] = lambdaworks.FeltOne() + + scopes := types.NewExecutionScopes() + scopes.EnterScope(scope) + + result, err := types.FetchScopeVar[lambdaworks.Felt]("k", scopes) + if err != nil { + t.Errorf("TestGetLocalVariables failed with error: %s", err) + + } + expected := lambdaworks.FeltOne() + if expected != result { + t.Errorf("TestGetLocalVariables failed, expected: %s, got: %s", expected.ToSignedFeltString(), result.ToSignedFeltString()) + } +} diff --git a/pkg/types/exec_scopes.go b/pkg/types/exec_scopes.go index 357a1cec..085f8e05 100644 --- a/pkg/types/exec_scopes.go +++ b/pkg/types/exec_scopes.go @@ -82,3 +82,20 @@ func (es *ExecutionScopes) Get(varName string) (interface{}, error) { } return val, nil } + +// Generic version of ExecutionScopes.Get which also handles casting +func FetchScopeVar[T interface{}](varName string, scopes *ExecutionScopes) (T, error) { + locals, err := scopes.GetLocalVariables() + if err != nil { + return *new(T), err + } + valAny, prs := locals[varName] + if !prs { + return *new(T), ErrVariableNotInScope(varName) + } + val, ok := valAny.(T) + if !ok { + return *new(T), ErrVariableNotInScope(varName) + } + return val, nil +} From 0655cfe88e807d714ec38002b6d4013355371876 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 15:10:19 -0300 Subject: [PATCH 52/86] Add generic fetch --- pkg/hints/signature_hints.go | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index a2cd8d24..b75aeabe 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -55,41 +55,26 @@ func divModNPackedDivModExternalN(ids IdsManager, vm *VirtualMachine, scopes *Ex func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAlias string, toAdd int64) error { // Fetch scope variables - aAny, err := scopes.Get(aAlias) + a, err := FetchScopeVar[*big.Int](aAlias, scopes) if err != nil { return err } - a, ok := aAny.(*big.Int) - if !ok { - return errors.Errorf("%s not in scope", aAlias) - } - bAny, err := scopes.Get(bAlias) + b, err := FetchScopeVar[*big.Int](bAlias, scopes) if err != nil { return err } - b, ok := bAny.(*big.Int) - if !ok { - return errors.Errorf("%s not in scope", bAlias) - } - resAny, err := scopes.Get("res") + res, err := FetchScopeVar[*big.Int]("res", scopes) if err != nil { return err } - res, ok := resAny.(*big.Int) - if !ok { - return errors.New("res not in scope") - } - nAny, err := scopes.Get("N") + n, err := FetchScopeVar[*big.Int]("N", scopes) if err != nil { return err } - n, ok := nAny.(*big.Int) - if !ok { - return errors.New("N not in scope") - } + // Hint logic value, err := utils.SafeDivBig(new(big.Int).Mul(res, new(big.Int).Sub(a, b)), n) if err != nil { From ca654b444f9860c708549f7cafa92964b5b7d0d6 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 15:08:49 -0300 Subject: [PATCH 53/86] Add generic way to fetch scope variables --- pkg/types/exec_scope_test.go | 18 ++++++++++++++++++ pkg/types/exec_scopes.go | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/pkg/types/exec_scope_test.go b/pkg/types/exec_scope_test.go index 119f266d..6eb1d97e 100644 --- a/pkg/types/exec_scope_test.go +++ b/pkg/types/exec_scope_test.go @@ -258,3 +258,21 @@ func TestErrExitMainScope(t *testing.T) { t.Errorf("TestErrExitMainScope should fail with error: %s and fails with: %s", types.ErrCannotExitMainScop, err) } } + +func TestFetchScopeVar(t *testing.T) { + scope := make(map[string]interface{}) + scope["k"] = lambdaworks.FeltOne() + + scopes := types.NewExecutionScopes() + scopes.EnterScope(scope) + + result, err := types.FetchScopeVar[lambdaworks.Felt]("k", scopes) + if err != nil { + t.Errorf("TestGetLocalVariables failed with error: %s", err) + + } + expected := lambdaworks.FeltOne() + if expected != result { + t.Errorf("TestGetLocalVariables failed, expected: %s, got: %s", expected.ToSignedFeltString(), result.ToSignedFeltString()) + } +} diff --git a/pkg/types/exec_scopes.go b/pkg/types/exec_scopes.go index 357a1cec..085f8e05 100644 --- a/pkg/types/exec_scopes.go +++ b/pkg/types/exec_scopes.go @@ -82,3 +82,20 @@ func (es *ExecutionScopes) Get(varName string) (interface{}, error) { } return val, nil } + +// Generic version of ExecutionScopes.Get which also handles casting +func FetchScopeVar[T interface{}](varName string, scopes *ExecutionScopes) (T, error) { + locals, err := scopes.GetLocalVariables() + if err != nil { + return *new(T), err + } + valAny, prs := locals[varName] + if !prs { + return *new(T), ErrVariableNotInScope(varName) + } + val, ok := valAny.(T) + if !ok { + return *new(T), ErrVariableNotInScope(varName) + } + return val, nil +} From 08ebcd61bcec03560c42c1ec73c9050b14b5e116 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 15:18:41 -0300 Subject: [PATCH 54/86] Use more specific error --- pkg/types/exec_scopes.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/types/exec_scopes.go b/pkg/types/exec_scopes.go index 085f8e05..bb372f40 100644 --- a/pkg/types/exec_scopes.go +++ b/pkg/types/exec_scopes.go @@ -18,6 +18,10 @@ func ErrVariableNotInScope(varName string) error { return ExecutionScopesError(errors.Errorf("Variable %s not in scope", varName)) } +func ErrVariableHasWrongType(varName string) error { + return ExecutionScopesError(errors.Errorf("Scope variable %s has wrong type", varName)) +} + func NewExecutionScopes() *ExecutionScopes { data := make([]map[string]interface{}, 1) data[0] = make(map[string]interface{}) @@ -95,7 +99,7 @@ func FetchScopeVar[T interface{}](varName string, scopes *ExecutionScopes) (T, e } val, ok := valAny.(T) if !ok { - return *new(T), ErrVariableNotInScope(varName) + return *new(T), ErrVariableHasWrongType(varName) } return val, nil } From a6e4d4a7774d5ddf4cd58b5fa8c20b23e3ee16ba Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 15:45:59 -0300 Subject: [PATCH 55/86] Add hints to ExecuteHint --- pkg/hints/hint_processor.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index e8c53010..854ff657 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -152,6 +152,10 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return divModNPackedDivMod(data.Ids, vm, execScopes) case DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N: return divModNPackedDivModExternalN(data.Ids, vm, execScopes) + case DIV_MOD_N_SAFE_DIV: + return divModNSafeDiv(data.Ids, execScopes, "a", "b", 0) + case DIV_MOD_N_SAFE_DIV_PLUS_ONE: + return divModNSafeDiv(data.Ids, execScopes, "a", "b", 1) default: return errors.Errorf("Unknown Hint: %s", data.Code) } From c85e6500c2a4127147f3d39665b076f8521533db Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 15:52:40 -0300 Subject: [PATCH 56/86] Add extra hint --- pkg/hints/hint_codes/signature_hint_codes.go | 2 ++ pkg/hints/hint_processor.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pkg/hints/hint_codes/signature_hint_codes.go b/pkg/hints/hint_codes/signature_hint_codes.go index 40d11b91..37b37051 100644 --- a/pkg/hints/hint_codes/signature_hint_codes.go +++ b/pkg/hints/hint_codes/signature_hint_codes.go @@ -17,3 +17,5 @@ value = res = div_mod(a, b, N)` const DIV_MOD_N_SAFE_DIV = "value = k = safe_div(res * b - a, N)" const DIV_MOD_N_SAFE_DIV_PLUS_ONE = "value = k_plus_one = safe_div(res * b - a, N) + 1" + +const XS_SAFE_DIV = "value = k = safe_div(res * s - x, N)" diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 854ff657..72fa8214 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -152,6 +152,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return divModNPackedDivMod(data.Ids, vm, execScopes) case DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N: return divModNPackedDivModExternalN(data.Ids, vm, execScopes) + case XS_SAFE_DIV: + return divModNSafeDiv(data.Ids, execScopes, "x", "s", 0) case DIV_MOD_N_SAFE_DIV: return divModNSafeDiv(data.Ids, execScopes, "a", "b", 0) case DIV_MOD_N_SAFE_DIV_PLUS_ONE: From 2e948d878946fd05855e7ffd22cb4ac26a0a6806 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 16:12:03 -0300 Subject: [PATCH 57/86] Fix logic, add unit test --- pkg/hints/signature_hints.go | 2 +- pkg/hints/signature_hints_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index b75aeabe..8b356127 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -76,7 +76,7 @@ func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAli } // Hint logic - value, err := utils.SafeDivBig(new(big.Int).Mul(res, new(big.Int).Sub(a, b)), n) + value, err := utils.SafeDivBig(new(big.Int).Sub(new(big.Int).Mul(res, b), a), n) if err != nil { return err } diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go index 2e25e605..63bfa3b6 100644 --- a/pkg/hints/signature_hints_test.go +++ b/pkg/hints/signature_hints_test.go @@ -97,3 +97,34 @@ func TestDivModNPackedDivModExternalN(t *testing.T) { t.Error("Wrong/No scope value val") } } + +func TestDivModSafeDivOk(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{}, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: DIV_MOD_N_SAFE_DIV, + }) + scopes := NewExecutionScopes() + scopes.AssignOrUpdateVariable("N", big.NewInt(5)) + scopes.AssignOrUpdateVariable("a", big.NewInt(10)) + scopes.AssignOrUpdateVariable("b", big.NewInt(30)) + scopes.AssignOrUpdateVariable("res", big.NewInt(2)) + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("DIV_MOD_N_SAFE_DIV hint test failed with error %s", err) + } + // Check result in scope + expectedValue := big.NewInt(10) // (2 * 30 - 10) / 5 = 10 + + value, err := scopes.Get("value") + println(value.(*big.Int).Text(10)) + if err != nil || value.(*big.Int).Cmp(expectedValue) != 0 { + t.Error("Wrong/No scope variable value") + } +} From 97c9cc7fa5e83a94cc8ceb76412ecdf902b8aa67 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 16:14:37 -0300 Subject: [PATCH 58/86] Add unit test --- pkg/hints/signature_hints_test.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go index 63bfa3b6..e1b8951c 100644 --- a/pkg/hints/signature_hints_test.go +++ b/pkg/hints/signature_hints_test.go @@ -128,3 +128,34 @@ func TestDivModSafeDivOk(t *testing.T) { t.Error("Wrong/No scope variable value") } } + +func TestDivModSafeDivPlusOneOk(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{}, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: DIV_MOD_N_SAFE_DIV_PLUS_ONE, + }) + scopes := NewExecutionScopes() + scopes.AssignOrUpdateVariable("N", big.NewInt(5)) + scopes.AssignOrUpdateVariable("a", big.NewInt(10)) + scopes.AssignOrUpdateVariable("b", big.NewInt(30)) + scopes.AssignOrUpdateVariable("res", big.NewInt(2)) + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("DIV_MOD_N_SAFE_DIV_PLUS_ONE hint test failed with error %s", err) + } + // Check result in scope + expectedValue := big.NewInt(11) // (2 * 30 - 10) / 5 + 1 = 11 + + value, err := scopes.Get("value") + println(value.(*big.Int).Text(10)) + if err != nil || value.(*big.Int).Cmp(expectedValue) != 0 { + t.Error("Wrong/No scope variable value") + } +} From 66c38a6a896cb6bc474864829a4c33f6261d82d6 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 16:15:52 -0300 Subject: [PATCH 59/86] use boolean flag instead or arg --- pkg/hints/hint_processor.go | 6 +++--- pkg/hints/signature_hints.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 72fa8214..124f02f8 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -153,11 +153,11 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, case DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N: return divModNPackedDivModExternalN(data.Ids, vm, execScopes) case XS_SAFE_DIV: - return divModNSafeDiv(data.Ids, execScopes, "x", "s", 0) + return divModNSafeDiv(data.Ids, execScopes, "x", "s", false) case DIV_MOD_N_SAFE_DIV: - return divModNSafeDiv(data.Ids, execScopes, "a", "b", 0) + return divModNSafeDiv(data.Ids, execScopes, "a", "b", false) case DIV_MOD_N_SAFE_DIV_PLUS_ONE: - return divModNSafeDiv(data.Ids, execScopes, "a", "b", 1) + return divModNSafeDiv(data.Ids, execScopes, "a", "b", true) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index 8b356127..c9f9393c 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -53,7 +53,7 @@ func divModNPackedDivModExternalN(ids IdsManager, vm *VirtualMachine, scopes *Ex return divModNPacked(ids, vm, scopes, n) } -func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAlias string, toAdd int64) error { +func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAlias string, addOne bool) error { // Fetch scope variables a, err := FetchScopeVar[*big.Int](aAlias, scopes) if err != nil { @@ -80,8 +80,8 @@ func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAli if err != nil { return err } - if toAdd != 0 { - value = new(big.Int).Add(value, big.NewInt(toAdd)) + if addOne { + value = new(big.Int).Add(value, big.NewInt(1)) } // Update scope scopes.AssignOrUpdateVariable("value", value) From f6c402d6af041f1c9fac57c5817e12d689bfd51a Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Tue, 26 Sep 2023 16:54:42 -0300 Subject: [PATCH 60/86] Fix scope var name --- pkg/hints/signature_hints.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index 05cd5595..5ec04fe5 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -28,7 +28,7 @@ func divModNPacked(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, scopes.AssignOrUpdateVariable("a", packedA) scopes.AssignOrUpdateVariable("b", packedB) - scopes.AssignOrUpdateVariable("val", val) + scopes.AssignOrUpdateVariable("value", val) scopes.AssignOrUpdateVariable("res", val) return nil From 97a67f811b4dc585e492a06e5ea05f1d731cbc2c Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Tue, 26 Sep 2023 16:55:13 -0300 Subject: [PATCH 61/86] Fix scope var name in tests --- pkg/hints/signature_hints_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go index 2e25e605..f77a5308 100644 --- a/pkg/hints/signature_hints_test.go +++ b/pkg/hints/signature_hints_test.go @@ -49,7 +49,7 @@ func TestDivModNPackedDivMod(t *testing.T) { t.Error("Wrong/No scope value res") } - val, err := scopes.Get("val") + val, err := scopes.Get("value") if err != nil || val.(*big.Int).Cmp(expectedRes) != 0 { t.Error("Wrong/No scope value val") } @@ -92,7 +92,7 @@ func TestDivModNPackedDivModExternalN(t *testing.T) { t.Error("Wrong/No scope value res") } - val, err := scopes.Get("val") + val, err := scopes.Get("value") if err != nil || val.(*big.Int).Cmp(expectedRes) != 0 { t.Error("Wrong/No scope value val") } From 69993be48a9a8fea8d241450463e4dd240091056 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 17:00:38 -0300 Subject: [PATCH 62/86] Make FetchScopeVar work despite references --- pkg/types/exec_scope_test.go | 19 +++++++++++++++++++ pkg/types/exec_scopes.go | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/pkg/types/exec_scope_test.go b/pkg/types/exec_scope_test.go index 6eb1d97e..4b513a49 100644 --- a/pkg/types/exec_scope_test.go +++ b/pkg/types/exec_scope_test.go @@ -276,3 +276,22 @@ func TestFetchScopeVar(t *testing.T) { t.Errorf("TestGetLocalVariables failed, expected: %s, got: %s", expected.ToSignedFeltString(), result.ToSignedFeltString()) } } + +func TestFetchScopeVarReference(t *testing.T) { + scope := make(map[string]interface{}) + k := lambdaworks.FeltOne() + scope["k"] = &k + + scopes := types.NewExecutionScopes() + scopes.EnterScope(scope) + + result, err := types.FetchScopeVar[lambdaworks.Felt]("k", scopes) + if err != nil { + t.Errorf("TestGetLocalVariables failed with error: %s", err) + + } + expected := lambdaworks.FeltOne() + if expected != result { + t.Errorf("TestGetLocalVariables failed, expected: %s, got: %s", expected.ToSignedFeltString(), result.ToSignedFeltString()) + } +} diff --git a/pkg/types/exec_scopes.go b/pkg/types/exec_scopes.go index bb372f40..14c205f7 100644 --- a/pkg/types/exec_scopes.go +++ b/pkg/types/exec_scopes.go @@ -88,6 +88,7 @@ func (es *ExecutionScopes) Get(varName string) (interface{}, error) { } // Generic version of ExecutionScopes.Get which also handles casting +// Also works if the scope variable has type *T instead of T func FetchScopeVar[T interface{}](varName string, scopes *ExecutionScopes) (T, error) { locals, err := scopes.GetLocalVariables() if err != nil { @@ -99,6 +100,10 @@ func FetchScopeVar[T interface{}](varName string, scopes *ExecutionScopes) (T, e } val, ok := valAny.(T) if !ok { + val, ok := valAny.(*T) + if ok { + return *val, nil + } return *new(T), ErrVariableHasWrongType(varName) } return val, nil From 2739694aea8fc7d0f04a932456d277093d67df95 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 17:07:23 -0300 Subject: [PATCH 63/86] Revert "Make FetchScopeVar work despite references" This reverts commit 69993be48a9a8fea8d241450463e4dd240091056. --- pkg/types/exec_scope_test.go | 19 ------------------- pkg/types/exec_scopes.go | 5 ----- 2 files changed, 24 deletions(-) diff --git a/pkg/types/exec_scope_test.go b/pkg/types/exec_scope_test.go index 4b513a49..6eb1d97e 100644 --- a/pkg/types/exec_scope_test.go +++ b/pkg/types/exec_scope_test.go @@ -276,22 +276,3 @@ func TestFetchScopeVar(t *testing.T) { t.Errorf("TestGetLocalVariables failed, expected: %s, got: %s", expected.ToSignedFeltString(), result.ToSignedFeltString()) } } - -func TestFetchScopeVarReference(t *testing.T) { - scope := make(map[string]interface{}) - k := lambdaworks.FeltOne() - scope["k"] = &k - - scopes := types.NewExecutionScopes() - scopes.EnterScope(scope) - - result, err := types.FetchScopeVar[lambdaworks.Felt]("k", scopes) - if err != nil { - t.Errorf("TestGetLocalVariables failed with error: %s", err) - - } - expected := lambdaworks.FeltOne() - if expected != result { - t.Errorf("TestGetLocalVariables failed, expected: %s, got: %s", expected.ToSignedFeltString(), result.ToSignedFeltString()) - } -} diff --git a/pkg/types/exec_scopes.go b/pkg/types/exec_scopes.go index 14c205f7..bb372f40 100644 --- a/pkg/types/exec_scopes.go +++ b/pkg/types/exec_scopes.go @@ -88,7 +88,6 @@ func (es *ExecutionScopes) Get(varName string) (interface{}, error) { } // Generic version of ExecutionScopes.Get which also handles casting -// Also works if the scope variable has type *T instead of T func FetchScopeVar[T interface{}](varName string, scopes *ExecutionScopes) (T, error) { locals, err := scopes.GetLocalVariables() if err != nil { @@ -100,10 +99,6 @@ func FetchScopeVar[T interface{}](varName string, scopes *ExecutionScopes) (T, e } val, ok := valAny.(T) if !ok { - val, ok := valAny.(*T) - if ok { - return *val, nil - } return *new(T), ErrVariableHasWrongType(varName) } return val, nil From 9116e1b07a0e2c5c8fdf46157f03a6873814b212 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 17:10:57 -0300 Subject: [PATCH 64/86] Handle scope variables as big.Int instead of *big.Int --- pkg/hints/signature_hints.go | 26 +++++++--------- pkg/hints/signature_hints_test.go | 50 +++++++++++++++++------------- pkg/vm/cairo_run/cairo_run_test.go | 4 +++ 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index 7e14b59b..13c587c4 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -29,54 +29,50 @@ func divModNPacked(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, scopes.AssignOrUpdateVariable("a", packedA) scopes.AssignOrUpdateVariable("b", packedB) - scopes.AssignOrUpdateVariable("value", val) - scopes.AssignOrUpdateVariable("res", val) + scopes.AssignOrUpdateVariable("value", *val) + scopes.AssignOrUpdateVariable("res", *val) return nil } func divModNPackedDivMod(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { n, _ := new(big.Int).SetString("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10) - scopes.AssignOrUpdateVariable("N", n) + scopes.AssignOrUpdateVariable("N", *n) return divModNPacked(ids, vm, scopes, n) } func divModNPackedDivModExternalN(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { - nAny, err := scopes.Get("N") + n, err := FetchScopeVar[big.Int]("N", scopes) if err != nil { return err } - n, ok := nAny.(*big.Int) - if !ok { - return errors.New("N not in scope") - } - return divModNPacked(ids, vm, scopes, n) + return divModNPacked(ids, vm, scopes, &n) } func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAlias string, addOne bool) error { // Fetch scope variables - a, err := FetchScopeVar[*big.Int](aAlias, scopes) + a, err := FetchScopeVar[big.Int](aAlias, scopes) if err != nil { return err } - b, err := FetchScopeVar[*big.Int](bAlias, scopes) + b, err := FetchScopeVar[big.Int](bAlias, scopes) if err != nil { return err } - res, err := FetchScopeVar[*big.Int]("res", scopes) + res, err := FetchScopeVar[big.Int]("res", scopes) if err != nil { return err } - n, err := FetchScopeVar[*big.Int]("N", scopes) + n, err := FetchScopeVar[big.Int]("N", scopes) if err != nil { return err } // Hint logic - value, err := utils.SafeDivBig(new(big.Int).Sub(new(big.Int).Mul(res, b), a), n) + value, err := utils.SafeDivBig(new(big.Int).Sub(new(big.Int).Mul(&res, &b), &a), &n) if err != nil { return err } @@ -84,6 +80,6 @@ func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAli value = new(big.Int).Add(value, big.NewInt(1)) } // Update scope - scopes.AssignOrUpdateVariable("value", value) + scopes.AssignOrUpdateVariable("value", *value) return nil } diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go index d244c174..59b92733 100644 --- a/pkg/hints/signature_hints_test.go +++ b/pkg/hints/signature_hints_test.go @@ -44,13 +44,18 @@ func TestDivModNPackedDivMod(t *testing.T) { // Check result in scope expectedRes := big.NewInt(5) - res, err := scopes.Get("res") - if err != nil || res.(*big.Int).Cmp(expectedRes) != 0 { + res, err := FetchScopeVar[big.Int]("res", scopes) + if err != nil || res.Cmp(expectedRes) != 0 { t.Error("Wrong/No scope value res") } +<<<<<<< Updated upstream val, err := scopes.Get("value") if err != nil || val.(*big.Int).Cmp(expectedRes) != 0 { +======= + val, err := FetchScopeVar[big.Int]("val", scopes) + if err != nil || val.Cmp(expectedRes) != 0 { +>>>>>>> Stashed changes t.Error("Wrong/No scope value val") } } @@ -79,7 +84,7 @@ func TestDivModNPackedDivModExternalN(t *testing.T) { Code: DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N, }) scopes := NewExecutionScopes() - scopes.AssignOrUpdateVariable("N", big.NewInt(7)) + scopes.AssignOrUpdateVariable("N", *big.NewInt(7)) err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) if err != nil { t.Errorf("DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N hint test failed with error %s", err) @@ -87,13 +92,18 @@ func TestDivModNPackedDivModExternalN(t *testing.T) { // Check result in scope expectedRes := big.NewInt(3) - res, err := scopes.Get("res") - if err != nil || res.(*big.Int).Cmp(expectedRes) != 0 { + res, err := FetchScopeVar[big.Int]("res", scopes) + if err != nil || res.Cmp(expectedRes) != 0 { t.Error("Wrong/No scope value res") } +<<<<<<< Updated upstream val, err := scopes.Get("value") if err != nil || val.(*big.Int).Cmp(expectedRes) != 0 { +======= + val, err := FetchScopeVar[big.Int]("val", scopes) + if err != nil || val.Cmp(expectedRes) != 0 { +>>>>>>> Stashed changes t.Error("Wrong/No scope value val") } } @@ -111,10 +121,10 @@ func TestDivModSafeDivOk(t *testing.T) { Code: DIV_MOD_N_SAFE_DIV, }) scopes := NewExecutionScopes() - scopes.AssignOrUpdateVariable("N", big.NewInt(5)) - scopes.AssignOrUpdateVariable("a", big.NewInt(10)) - scopes.AssignOrUpdateVariable("b", big.NewInt(30)) - scopes.AssignOrUpdateVariable("res", big.NewInt(2)) + scopes.AssignOrUpdateVariable("N", *big.NewInt(5)) + scopes.AssignOrUpdateVariable("a", *big.NewInt(10)) + scopes.AssignOrUpdateVariable("b", *big.NewInt(30)) + scopes.AssignOrUpdateVariable("res", *big.NewInt(2)) err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) if err != nil { t.Errorf("DIV_MOD_N_SAFE_DIV hint test failed with error %s", err) @@ -122,10 +132,9 @@ func TestDivModSafeDivOk(t *testing.T) { // Check result in scope expectedValue := big.NewInt(10) // (2 * 30 - 10) / 5 = 10 - value, err := scopes.Get("value") - println(value.(*big.Int).Text(10)) - if err != nil || value.(*big.Int).Cmp(expectedValue) != 0 { - t.Error("Wrong/No scope variable value") + val, err := FetchScopeVar[big.Int]("value", scopes) + if err != nil || val.Cmp(expectedValue) != 0 { + t.Error("Wrong/No scope value val") } } @@ -142,10 +151,10 @@ func TestDivModSafeDivPlusOneOk(t *testing.T) { Code: DIV_MOD_N_SAFE_DIV_PLUS_ONE, }) scopes := NewExecutionScopes() - scopes.AssignOrUpdateVariable("N", big.NewInt(5)) - scopes.AssignOrUpdateVariable("a", big.NewInt(10)) - scopes.AssignOrUpdateVariable("b", big.NewInt(30)) - scopes.AssignOrUpdateVariable("res", big.NewInt(2)) + scopes.AssignOrUpdateVariable("N", *big.NewInt(5)) + scopes.AssignOrUpdateVariable("a", *big.NewInt(10)) + scopes.AssignOrUpdateVariable("b", *big.NewInt(30)) + scopes.AssignOrUpdateVariable("res", *big.NewInt(2)) err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) if err != nil { t.Errorf("DIV_MOD_N_SAFE_DIV_PLUS_ONE hint test failed with error %s", err) @@ -153,9 +162,8 @@ func TestDivModSafeDivPlusOneOk(t *testing.T) { // Check result in scope expectedValue := big.NewInt(11) // (2 * 30 - 10) / 5 + 1 = 11 - value, err := scopes.Get("value") - println(value.(*big.Int).Text(10)) - if err != nil || value.(*big.Int).Cmp(expectedValue) != 0 { - t.Error("Wrong/No scope variable value") + val, err := FetchScopeVar[big.Int]("value", scopes) + if err != nil || val.Cmp(expectedValue) != 0 { + t.Error("Wrong/No scope value val") } } diff --git a/pkg/vm/cairo_run/cairo_run_test.go b/pkg/vm/cairo_run/cairo_run_test.go index 34ad51dd..82b4e8dc 100644 --- a/pkg/vm/cairo_run/cairo_run_test.go +++ b/pkg/vm/cairo_run/cairo_run_test.go @@ -320,3 +320,7 @@ func TestSplitIntHint(t *testing.T) { func TestSplitIntHintProofMode(t *testing.T) { testProgramProof("split_int", t) } + +func TestDivModN(t *testing.T) { + testProgram("div_mod_n", t) +} From 62b9ed2271ea27b54c80e0f2bf8d8c3f96036ea2 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 17:44:50 -0300 Subject: [PATCH 65/86] Fix merge cnflicts --- pkg/hints/signature_hints_test.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go index 59b92733..1d3ec9ca 100644 --- a/pkg/hints/signature_hints_test.go +++ b/pkg/hints/signature_hints_test.go @@ -49,13 +49,8 @@ func TestDivModNPackedDivMod(t *testing.T) { t.Error("Wrong/No scope value res") } -<<<<<<< Updated upstream - val, err := scopes.Get("value") - if err != nil || val.(*big.Int).Cmp(expectedRes) != 0 { -======= val, err := FetchScopeVar[big.Int]("val", scopes) if err != nil || val.Cmp(expectedRes) != 0 { ->>>>>>> Stashed changes t.Error("Wrong/No scope value val") } } @@ -97,13 +92,8 @@ func TestDivModNPackedDivModExternalN(t *testing.T) { t.Error("Wrong/No scope value res") } -<<<<<<< Updated upstream - val, err := scopes.Get("value") - if err != nil || val.(*big.Int).Cmp(expectedRes) != 0 { -======= val, err := FetchScopeVar[big.Int]("val", scopes) if err != nil || val.Cmp(expectedRes) != 0 { ->>>>>>> Stashed changes t.Error("Wrong/No scope value val") } } From ccd58058230ccea52882bbefa4dba727b55090da Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 17:48:02 -0300 Subject: [PATCH 66/86] Fix tests --- pkg/hints/signature_hints_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go index 1d3ec9ca..4c3de522 100644 --- a/pkg/hints/signature_hints_test.go +++ b/pkg/hints/signature_hints_test.go @@ -49,9 +49,9 @@ func TestDivModNPackedDivMod(t *testing.T) { t.Error("Wrong/No scope value res") } - val, err := FetchScopeVar[big.Int]("val", scopes) + val, err := FetchScopeVar[big.Int]("value", scopes) if err != nil || val.Cmp(expectedRes) != 0 { - t.Error("Wrong/No scope value val") + t.Error("Wrong/No scope var value") } } @@ -92,9 +92,9 @@ func TestDivModNPackedDivModExternalN(t *testing.T) { t.Error("Wrong/No scope value res") } - val, err := FetchScopeVar[big.Int]("val", scopes) + val, err := FetchScopeVar[big.Int]("value", scopes) if err != nil || val.Cmp(expectedRes) != 0 { - t.Error("Wrong/No scope value val") + t.Error("Wrong/No scope var value") } } From e0573c140db4ada43baa252273fe005afc75520d Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 17:50:08 -0300 Subject: [PATCH 67/86] Implement Igcdex + add tests --- pkg/utils/math_utils.go | 30 +++++++++++++++++++++++++++ pkg/utils/math_utils_test.go | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/pkg/utils/math_utils.go b/pkg/utils/math_utils.go index b1054f70..832c8f31 100644 --- a/pkg/utils/math_utils.go +++ b/pkg/utils/math_utils.go @@ -63,3 +63,33 @@ func SafeDivBig(x *big.Int, y *big.Int) (*big.Int, error) { } return q, nil } + +func Igcdex(a *big.Int, b *big.Int) (*big.Int, *big.Int, *big.Int) { + zero := big.NewInt(0) + one := big.NewInt(1) + switch true { + case a.Cmp(zero) == 0 && b.Cmp(zero) == 0: + return zero, one, zero + case a.Cmp(zero) == 0: + return zero, big.NewInt(int64(a.Sign())), new(big.Int).Abs(b) + case b.Cmp(zero) == 0: + return big.NewInt(int64(a.Sign())), zero, new(big.Int).Abs(a) + default: + xSign := big.NewInt(int64(a.Sign())) + ySign := big.NewInt(int64(b.Sign())) + a = new(big.Int).Abs(a) + b = new(big.Int).Abs(b) + x, y, r, s := big.NewInt(1), big.NewInt(0), big.NewInt(0), big.NewInt(1) + for b.Cmp(zero) != 0 { + q, c := new(big.Int).DivMod(a, b, new(big.Int)) + x = new(big.Int).Sub(x, new(big.Int).Mul(q, r)) + y = new(big.Int).Sub(y, new(big.Int).Mul(q, s)) + + a, b, r, s, x, y = b, c, x, y, r, s + } + + return new(big.Int).Mul(x, xSign), new(big.Int).Mul(y, ySign), a + + } + +} diff --git a/pkg/utils/math_utils_test.go b/pkg/utils/math_utils_test.go index e3b2a152..95a86a45 100644 --- a/pkg/utils/math_utils_test.go +++ b/pkg/utils/math_utils_test.go @@ -44,3 +44,43 @@ func TestSafeDivBigErrZeroDivison(t *testing.T) { t.Error("SafeDivBig should have failed") } } + +func TestIgcdex11(t *testing.T) { + a := big.NewInt(1) + b := big.NewInt(1) + expectedX, expectedY, expectedZ := big.NewInt(0), big.NewInt(1), big.NewInt(1) + x, y, z := Igcdex(a, b) + if x.Cmp(expectedX) != 0 || y.Cmp(expectedY) != 0 || z.Cmp(expectedZ) != 0 { + t.Error("Wrong values returned by Igcdex") + } +} + +func TestIgcdex00(t *testing.T) { + a := big.NewInt(0) + b := big.NewInt(0) + expectedX, expectedY, expectedZ := big.NewInt(0), big.NewInt(1), big.NewInt(0) + x, y, z := Igcdex(a, b) + if x.Cmp(expectedX) != 0 || y.Cmp(expectedY) != 0 || z.Cmp(expectedZ) != 0 { + t.Error("Wrong values returned by Igcdex") + } +} + +func TestIgcdex10(t *testing.T) { + a := big.NewInt(1) + b := big.NewInt(0) + expectedX, expectedY, expectedZ := big.NewInt(1), big.NewInt(0), big.NewInt(1) + x, y, z := Igcdex(a, b) + if x.Cmp(expectedX) != 0 || y.Cmp(expectedY) != 0 || z.Cmp(expectedZ) != 0 { + t.Error("Wrong values returned by Igcdex") + } +} + +func TestIgcdex46(t *testing.T) { + a := big.NewInt(4) + b := big.NewInt(6) + expectedX, expectedY, expectedZ := big.NewInt(-1), big.NewInt(1), big.NewInt(2) + x, y, z := Igcdex(a, b) + if x.Cmp(expectedX) != 0 || y.Cmp(expectedY) != 0 || z.Cmp(expectedZ) != 0 { + t.Error("Wrong values returned by Igcdex") + } +} From 04df1044ccec79b127add1647c7bf99e781a6119 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 17:57:20 -0300 Subject: [PATCH 68/86] Implement DivMod --- pkg/utils/math_utils.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/utils/math_utils.go b/pkg/utils/math_utils.go index 832c8f31..4626f55f 100644 --- a/pkg/utils/math_utils.go +++ b/pkg/utils/math_utils.go @@ -64,6 +64,15 @@ func SafeDivBig(x *big.Int, y *big.Int) (*big.Int, error) { return q, nil } +// Finds a nonnegative integer x < p such that (m * x) % p == n. +func DivMod(n *big.Int, m *big.Int, p *big.Int) (*big.Int, error) { + a, _, c := Igcdex(m, p) + if c.Cmp(big.NewInt(1)) != 0 { + return nil, errors.Errorf("Operation failed: divmod(%s, %s, %s), igcdex(%s, %s) != 1 ", n.Text(10), m.Text(10), p.Text(10), m.Text(10), p.Text(10)) + } + return new(big.Int).Mod(new(big.Int).Mul(n, a), p), nil +} + func Igcdex(a *big.Int, b *big.Int) (*big.Int, *big.Int, *big.Int) { zero := big.NewInt(0) one := big.NewInt(1) From 7bd7edc7e226d30869de93bb4ef74fbd4f8c8849 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 18:03:01 -0300 Subject: [PATCH 69/86] Use DivMod instead of Div + Mod --- pkg/hints/signature_hints.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index 13c587c4..8311de7d 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -25,7 +25,10 @@ func divModNPacked(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, if packedB.Cmp(big.NewInt(0)) == 0 { return errors.New("Attempted to divide by zero") } - val := new(big.Int).Mod(new(big.Int).Div(&packedA, &packedB), n) + val, err := utils.DivMod(&packedA, &packedB, n) + if err != nil { + return err + } scopes.AssignOrUpdateVariable("a", packedA) scopes.AssignOrUpdateVariable("b", packedB) From b1c81af1c1c1aa0a63e066ba7e52891406351d32 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 18:25:50 -0300 Subject: [PATCH 70/86] Dont modify the original value in bigint3_split function --- pkg/hints/hint_utils/secp_utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/hints/hint_utils/secp_utils.go b/pkg/hints/hint_utils/secp_utils.go index 3ceaa4bf..325caec5 100644 --- a/pkg/hints/hint_utils/secp_utils.go +++ b/pkg/hints/hint_utils/secp_utils.go @@ -41,7 +41,7 @@ func Bigint3Split(integer big.Int) ([]big.Int, error) { for i := 0; i < 3; i++ { canonicalRepr[i] = *new(big.Int).And(&num, BASE_MINUS_ONE()) - num.Rsh(&num, 86) + num = *new(big.Int).Rsh(&num, 86) } if num.Cmp(big.NewInt(0)) != 0 { return nil, errors.New("HintError SecpSplitOutOfRange") From 2fbc48d193ff64a5af56916c09020865090837c7 Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 18:33:12 -0300 Subject: [PATCH 71/86] Push test file --- cairo_programs/div_mod_n.cairo | 129 +++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 cairo_programs/div_mod_n.cairo diff --git a/cairo_programs/div_mod_n.cairo b/cairo_programs/div_mod_n.cairo new file mode 100644 index 00000000..4dbe3c82 --- /dev/null +++ b/cairo_programs/div_mod_n.cairo @@ -0,0 +1,129 @@ +%builtins range_check + +from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3, BASE, bigint_mul +from starkware.cairo.common.cairo_secp.constants import BETA, N0, N1, N2 + +// Source: https://github.com/myBraavos/efficient-secp256r1/blob/73cca4d53730cb8b2dcf34e36c7b8f34b96b3230/src/secp256r1/signature.cairo + +// Computes a * b^(-1) modulo the size of the elliptic curve (N). +// +// Prover assumptions: +// * All the limbs of a are in the range (-2 ** 210.99, 2 ** 210.99). +// * All the limbs of b are in the range (-2 ** 124.99, 2 ** 124.99). +// * b is in the range [0, 2 ** 256). +// +// Soundness assumptions: +// * The limbs of a are in the range (-2 ** 249, 2 ** 249). +// * The limbs of b are in the range (-2 ** 159.83, 2 ** 159.83). +func div_mod_n{range_check_ptr}(a: BigInt3, b: BigInt3) -> (res: BigInt3) { + %{ + from starkware.cairo.common.cairo_secp.secp_utils import N, pack + from starkware.python.math_utils import div_mod, safe_div + + a = pack(ids.a, PRIME) + b = pack(ids.b, PRIME) + value = res = div_mod(a, b, N) + %} + let (res) = nondet_bigint3(); + + %{ value = k_plus_one = safe_div(res * b - a, N) + 1 %} + let (k_plus_one) = nondet_bigint3(); + let k = BigInt3(d0=k_plus_one.d0 - 1, d1=k_plus_one.d1, d2=k_plus_one.d2); + + let (res_b) = bigint_mul(res, b); + let n = BigInt3(N0, N1, N2); + let (k_n) = bigint_mul(k, n); + + // We should now have res_b = k_n + a. Since the numbers are in unreduced form, + // we should handle the carry. + + tempvar carry1 = (res_b.d0 - k_n.d0 - a.d0) / BASE; + assert [range_check_ptr + 0] = carry1 + 2 ** 127; + + tempvar carry2 = (res_b.d1 - k_n.d1 - a.d1 + carry1) / BASE; + assert [range_check_ptr + 1] = carry2 + 2 ** 127; + + tempvar carry3 = (res_b.d2 - k_n.d2 - a.d2 + carry2) / BASE; + assert [range_check_ptr + 2] = carry3 + 2 ** 127; + + tempvar carry4 = (res_b.d3 - k_n.d3 + carry3) / BASE; + assert [range_check_ptr + 3] = carry4 + 2 ** 127; + + assert res_b.d4 - k_n.d4 + carry4 = 0; + + let range_check_ptr = range_check_ptr + 4; + + return (res=res); +} + +func div_mod_n_alt{range_check_ptr}(a: BigInt3, b: BigInt3) -> (res: BigInt3) { + // just used to import N + %{ + from starkware.cairo.common.cairo_secp.secp_utils import N, pack + from starkware.python.math_utils import div_mod, safe_div + + a = pack(ids.a, PRIME) + b = pack(ids.b, PRIME) + value = res = div_mod(a, b, N) + %} + + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.python.math_utils import div_mod, safe_div + + a = pack(ids.a, PRIME) + b = pack(ids.b, PRIME) + value = res = div_mod(a, b, N) + %} + let (res) = nondet_bigint3(); + + %{ value = k_plus_one = safe_div(res * b - a, N) + 1 %} + let (k_plus_one) = nondet_bigint3(); + let k = BigInt3(d0=k_plus_one.d0 - 1, d1=k_plus_one.d1, d2=k_plus_one.d2); + + let (res_b) = bigint_mul(res, b); + let n = BigInt3(N0, N1, N2); + let (k_n) = bigint_mul(k, n); + + tempvar carry1 = (res_b.d0 - k_n.d0 - a.d0) / BASE; + assert [range_check_ptr + 0] = carry1 + 2 ** 127; + + tempvar carry2 = (res_b.d1 - k_n.d1 - a.d1 + carry1) / BASE; + assert [range_check_ptr + 1] = carry2 + 2 ** 127; + + tempvar carry3 = (res_b.d2 - k_n.d2 - a.d2 + carry2) / BASE; + assert [range_check_ptr + 2] = carry3 + 2 ** 127; + + tempvar carry4 = (res_b.d3 - k_n.d3 + carry3) / BASE; + assert [range_check_ptr + 3] = carry4 + 2 ** 127; + + assert res_b.d4 - k_n.d4 + carry4 = 0; + + let range_check_ptr = range_check_ptr + 4; + + return (res=res); +} + +func test_div_mod_n{range_check_ptr: felt}() { + let a: BigInt3 = BigInt3(100, 99, 98); + let b: BigInt3 = BigInt3(10, 9, 8); + + let (res) = div_mod_n(a, b); + + assert res = BigInt3( + 3413472211745629263979533, 17305268010345238170172332, 11991751872105858217578135 + ); + + // test alternative hint + let (res_alt) = div_mod_n_alt(a, b); + + assert res_alt = res; + + return (); +} + +func main{range_check_ptr: felt}() { + test_div_mod_n(); + + return (); +} From 468e1764a81ad3fc871442fb5ce9d4a8626f9e8d Mon Sep 17 00:00:00 2001 From: Federica Date: Tue, 26 Sep 2023 18:35:03 -0300 Subject: [PATCH 72/86] Remove redundant check --- pkg/hints/signature_hints.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index 8311de7d..37b57f7f 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -7,7 +7,6 @@ import ( . "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/pkg/errors" ) func divModNPacked(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, n *big.Int) error { @@ -22,9 +21,6 @@ func divModNPacked(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, packedA := a.Pack86() packedB := b.Pack86() - if packedB.Cmp(big.NewInt(0)) == 0 { - return errors.New("Attempted to divide by zero") - } val, err := utils.DivMod(&packedA, &packedB, n) if err != nil { return err From 4921ef6a87cd01e862a41b5fafbda618bf9e6b4d Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 29 Sep 2023 11:36:44 -0300 Subject: [PATCH 73/86] Implement Reduce_V1 hint --- pkg/hints/hint_codes/secp_p_hint_codes.go | 13 +++++++++++++ pkg/hints/hint_processor.go | 2 ++ pkg/hints/secp_p_hints.go | 21 +++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 pkg/hints/hint_codes/secp_p_hint_codes.go create mode 100644 pkg/hints/secp_p_hints.go diff --git a/pkg/hints/hint_codes/secp_p_hint_codes.go b/pkg/hints/hint_codes/secp_p_hint_codes.go new file mode 100644 index 00000000..b548bbb3 --- /dev/null +++ b/pkg/hints/hint_codes/secp_p_hint_codes.go @@ -0,0 +1,13 @@ +package hint_codes + +const IMPORT_SECP256R1_ALPHA = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_ALPHA as ALPHA" + +const IMPORT_SECP256R1_N = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_N as N" + +const IMPORT_SECP256R1_P = "from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P" + +const VERIFY_ZERO_EXTERNAL_SECP = "from starkware.cairo.common.cairo_secp.secp_utils import pack\n\nq, r = divmod(pack(ids.val, PRIME), SECP_P)\nassert r == 0, f\"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}.\"\nids.q = q % PRIME" + +const REDUCE_V1 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack + +value = pack(ids.x, PRIME) % SECP_P` diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 0779a591..fda86e58 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -196,6 +196,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 REDUCE_V1: + return reduceV1(data.Ids, vm, execScopes) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/secp_p_hints.go b/pkg/hints/secp_p_hints.go new file mode 100644 index 00000000..002296ed --- /dev/null +++ b/pkg/hints/secp_p_hints.go @@ -0,0 +1,21 @@ +package hints + +import ( + "math/big" + + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" + . "github.com/lambdaclass/cairo-vm.go/pkg/types" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm" +) + +func reduceV1(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { + secpP := SECP_P() + scopes.AssignOrUpdateVariable("SECP_P", secpP) + value, err := Uint384FromVarName("x", ids, vm) + if err != nil { + return err + } + packedValue := value.Pack86() + scopes.AssignOrUpdateVariable("value", *new(big.Int).Mod(&packedValue, &secpP)) + return nil +} From ee2b36c8211eb74ff06bb01d3885876073fc697e Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 29 Sep 2023 11:40:03 -0300 Subject: [PATCH 74/86] Fix file names --- .../{secp_p_hint_codes.go => secp_hint_codes.go} | 0 pkg/hints/{secp_p_hints.go => secp_hints.go} | 0 pkg/hints/secp_hints_test.go | 15 +++++++++++++++ 3 files changed, 15 insertions(+) rename pkg/hints/hint_codes/{secp_p_hint_codes.go => secp_hint_codes.go} (100%) rename pkg/hints/{secp_p_hints.go => secp_hints.go} (100%) create mode 100644 pkg/hints/secp_hints_test.go diff --git a/pkg/hints/hint_codes/secp_p_hint_codes.go b/pkg/hints/hint_codes/secp_hint_codes.go similarity index 100% rename from pkg/hints/hint_codes/secp_p_hint_codes.go rename to pkg/hints/hint_codes/secp_hint_codes.go diff --git a/pkg/hints/secp_p_hints.go b/pkg/hints/secp_hints.go similarity index 100% rename from pkg/hints/secp_p_hints.go rename to pkg/hints/secp_hints.go diff --git a/pkg/hints/secp_hints_test.go b/pkg/hints/secp_hints_test.go new file mode 100644 index 00000000..994f4a3f --- /dev/null +++ b/pkg/hints/secp_hints_test.go @@ -0,0 +1,15 @@ +package hints_test + +import ( + "testing" + + . "github.com/lambdaclass/cairo-vm.go/pkg/hints" + . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" + . "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/vm" + . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" +) + +func TestReduceV1(t *testing.T) {} From 94b046c7354f8d8a08a0a2a3f537308e4d6bbabc Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 29 Sep 2023 11:48:26 -0300 Subject: [PATCH 75/86] Add unit test --- pkg/hints/secp_hints_test.go | 42 +++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/pkg/hints/secp_hints_test.go b/pkg/hints/secp_hints_test.go index 994f4a3f..03a2b2e4 100644 --- a/pkg/hints/secp_hints_test.go +++ b/pkg/hints/secp_hints_test.go @@ -1,6 +1,7 @@ package hints_test import ( + "math/big" "testing" . "github.com/lambdaclass/cairo-vm.go/pkg/hints" @@ -12,4 +13,43 @@ import ( . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" ) -func TestReduceV1(t *testing.T) {} +func TestReduceV1(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "x": { + NewMaybeRelocatableFelt(FeltFromDecString("6")), + NewMaybeRelocatableFelt(FeltFromDecString("6")), + NewMaybeRelocatableFelt(FeltFromDecString("6")), + }, + }, + vm, + ) + scopes := NewExecutionScopes() + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: REDUCE_V1, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("REDUCE_V1 hint failed with error %s", err) + } + // Checked scope variables + // SECP_P + secpP, err := FetchScopeVar[big.Int]("SECP_P", scopes) + expectedSecpP := SECP_P() + if err != nil || secpP.Cmp(&expectedSecpP) != 0 { + t.Errorf("Wrong/No scope var SECP_P") + } + + value, err := FetchScopeVar[big.Int]("value", scopes) + valueUnpacked := Uint384{Limbs: []Felt{FeltFromUint(6), FeltFromUint(6), FeltFromUint(6)}} + expectedvalue := valueUnpacked.Pack86() + if err != nil || value.Cmp(&expectedvalue) != 0 { + t.Errorf("Wrong/No scope var value") + } +} From e725a5753ef4f564f17bec17d04c6818c86138ac Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 29 Sep 2023 11:56:09 -0300 Subject: [PATCH 76/86] Add testing util CheckScopeVar` --- pkg/hints/hint_utils/testing_utils.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/hints/hint_utils/testing_utils.go b/pkg/hints/hint_utils/testing_utils.go index 46403f07..a52ddb0d 100644 --- a/pkg/hints/hint_utils/testing_utils.go +++ b/pkg/hints/hint_utils/testing_utils.go @@ -1,8 +1,12 @@ package hint_utils import ( + "reflect" + "testing" + "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" "github.com/lambdaclass/cairo-vm.go/pkg/parser" + "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" ) @@ -56,3 +60,13 @@ func SetupConstantsForTest(new_constants map[string]lambdaworks.Felt, ids *IdsMa } return constants } + +func CheckScopeVar[T any](name string, expectedVal T, scopes *types.ExecutionScopes, t *testing.T) { + val, err := types.FetchScopeVar[T](name, scopes) + if err != nil { + t.Error(err.Error()) + } + if !reflect.DeepEqual(val, expectedVal) { + t.Errorf("Wrong scope var %s.\n Expected: %v, got: %v", name, expectedVal, val) + } +} From 9f392d8f26a9506801a0f1cad0b76b33ee47f23f Mon Sep 17 00:00:00 2001 From: Federica Date: Fri, 29 Sep 2023 11:56:20 -0300 Subject: [PATCH 77/86] Refactor test --- pkg/hints/secp_hints_test.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/pkg/hints/secp_hints_test.go b/pkg/hints/secp_hints_test.go index 03a2b2e4..656f152a 100644 --- a/pkg/hints/secp_hints_test.go +++ b/pkg/hints/secp_hints_test.go @@ -39,17 +39,8 @@ func TestReduceV1(t *testing.T) { t.Errorf("REDUCE_V1 hint failed with error %s", err) } // Checked scope variables - // SECP_P - secpP, err := FetchScopeVar[big.Int]("SECP_P", scopes) - expectedSecpP := SECP_P() - if err != nil || secpP.Cmp(&expectedSecpP) != 0 { - t.Errorf("Wrong/No scope var SECP_P") - } + CheckScopeVar[big.Int]("SECP_P", SECP_P(), scopes, t) - value, err := FetchScopeVar[big.Int]("value", scopes) valueUnpacked := Uint384{Limbs: []Felt{FeltFromUint(6), FeltFromUint(6), FeltFromUint(6)}} - expectedvalue := valueUnpacked.Pack86() - if err != nil || value.Cmp(&expectedvalue) != 0 { - t.Errorf("Wrong/No scope var value") - } + CheckScopeVar[big.Int]("value", valueUnpacked.Pack86(), scopes, t) } From 53fcdb54da53fbdd5aee4a9f54031e368bbee10a Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 10:38:08 -0300 Subject: [PATCH 78/86] Merge math_utils/utils & utils/math_utils --- pkg/builtins/ec_op.go | 5 +- pkg/hints/math_hints.go | 2 +- pkg/math_utils/utils.go | 27 -------- pkg/math_utils/utils_test.go | 129 ----------------------------------- pkg/utils/math_utils.go | 7 ++ pkg/utils/math_utils_test.go | 121 ++++++++++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 160 deletions(-) delete mode 100644 pkg/math_utils/utils.go delete mode 100644 pkg/math_utils/utils_test.go diff --git a/pkg/builtins/ec_op.go b/pkg/builtins/ec_op.go index 0e973a0a..9053c25c 100644 --- a/pkg/builtins/ec_op.go +++ b/pkg/builtins/ec_op.go @@ -5,7 +5,6 @@ import ( "math/big" "github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks" - "github.com/lambdaclass/cairo-vm.go/pkg/math_utils" "github.com/lambdaclass/cairo-vm.go/pkg/utils" "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" "github.com/pkg/errors" @@ -263,7 +262,7 @@ func LineSlope(point_a PartialSumB, point_b DoublePointB, prime big.Int) (big.In n := new(big.Int).Sub(&point_a.Y, &point_b.Y) m := new(big.Int).Sub(&point_a.X, &point_b.X) - z, err := math_utils.DivMod(n, m, &prime) + z, err := utils.DivMod(n, m, &prime) if err != nil { return big.Int{}, err } @@ -299,7 +298,7 @@ func EcDoubleSlope(point DoublePointB, alpha big.Int, prime big.Int) (big.Int, e n.Add(n, &alpha) m := new(big.Int).Mul(&point.Y, big.NewInt(2)) - z, err := math_utils.DivMod(n, m, &prime) + z, err := utils.DivMod(n, m, &prime) if err != nil { return big.Int{}, err diff --git a/pkg/hints/math_hints.go b/pkg/hints/math_hints.go index 03b239c3..a577131d 100644 --- a/pkg/hints/math_hints.go +++ b/pkg/hints/math_hints.go @@ -7,8 +7,8 @@ import ( . "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/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" . "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" "github.com/pkg/errors" diff --git a/pkg/math_utils/utils.go b/pkg/math_utils/utils.go deleted file mode 100644 index 282ba4a3..00000000 --- a/pkg/math_utils/utils.go +++ /dev/null @@ -1,27 +0,0 @@ -package math_utils - -import ( - "github.com/pkg/errors" - "math/big" -) - -// Finds a nonnegative integer x < p such that (m * x) % p == n. -func DivMod(n *big.Int, m *big.Int, p *big.Int) (*big.Int, error) { - a := new(big.Int) - gcd := new(big.Int) - gcd.GCD(a, nil, m, p) - - if gcd.Cmp(big.NewInt(1)) != 0 { - return nil, errors.Errorf("gcd(%s, %s) != 1", m, p) - } - - return n.Mul(n, a).Mod(n, p), nil -} - -func ISqrt(x *big.Int) (*big.Int, error) { - if x.Sign() == -1 { - return nil, errors.Errorf("Expected x: %s to be non-negative", x) - } - res := new(big.Int) - return res.Sqrt(x), nil -} diff --git a/pkg/math_utils/utils_test.go b/pkg/math_utils/utils_test.go deleted file mode 100644 index c4eee853..00000000 --- a/pkg/math_utils/utils_test.go +++ /dev/null @@ -1,129 +0,0 @@ -package math_utils_test - -import ( - "math/big" - "testing" - - . "github.com/lambdaclass/cairo-vm.go/pkg/math_utils" -) - -func TestDivModOk(t *testing.T) { - a := new(big.Int) - b := new(big.Int) - prime := new(big.Int) - expected := new(big.Int) - - a.SetString("11260647941622813594563746375280766662237311019551239924981511729608487775604310196863705127454617186486639011517352066501847110680463498585797912894788", 10) - b.SetString("4020711254448367604954374443741161860304516084891705811279711044808359405970", 10) - prime.SetString("800000000000011000000000000000000000000000000000000000000000001", 16) - expected.SetString("2904750555256547440469454488220756360634457312540595732507835416669695939476", 10) - - num, err := DivMod(a, b, prime) - if err != nil { - t.Errorf("DivMod failed with error: %s", err) - } - if num.Cmp(expected) != 0 { - t.Errorf("Expected result: %s to be equal to %s", num, expected) - } -} - -func TestDivModMZeroFail(t *testing.T) { - a := new(big.Int) - b := new(big.Int) - prime := new(big.Int) - - a.SetString("11260647941622813594563746375280766662237311019551239924981511729608487775604310196863705127454617186486639011517352066501847110680463498585797912894788", 10) - prime.SetString("800000000000011000000000000000000000000000000000000000000000001", 16) - - _, err := DivMod(a, b, prime) - if err == nil { - t.Errorf("DivMod expected to failed with gcd != 1") - } -} - -func TestDivModMEqPFail(t *testing.T) { - a := new(big.Int) - b := new(big.Int) - prime := new(big.Int) - - a.SetString("11260647941622813594563746375280766662237311019551239924981511729608487775604310196863705127454617186486639011517352066501847110680463498585797912894788", 10) - b.SetString("800000000000011000000000000000000000000000000000000000000000001", 16) - prime.SetString("800000000000011000000000000000000000000000000000000000000000001", 16) - - _, err := DivMod(a, b, prime) - if err == nil { - t.Errorf("DivMod expected to failed with gcd != 1") - } -} - -func TestIsSqrtOk(t *testing.T) { - x := new(big.Int) - y := new(big.Int) - x.SetString("4573659632505831259480", 10) - y.Mul(x, x) - - sqr_y, err := ISqrt(y) - if err != nil { - t.Errorf("ISqrt failed with error: %s", err) - } - if x.Cmp(sqr_y) != 0 { - t.Errorf("Failed to get square root of x^2, x: %s", x) - } -} - -func TestCalculateIsqrtA(t *testing.T) { - x := new(big.Int) - x.SetString("81", 10) - sqrt, err := ISqrt(x) - if err != nil { - t.Error("ISqrt failed") - } - - expected := new(big.Int) - expected.SetString("9", 10) - - if sqrt.Cmp(expected) != 0 { - t.Errorf("ISqrt failed, expected %d, got %d", expected, sqrt) - } -} - -func TestCalculateIsqrtB(t *testing.T) { - x := new(big.Int) - x.SetString("4573659632505831259480", 10) - square := new(big.Int) - square = square.Mul(x, x) - - sqrt, err := ISqrt(square) - if err != nil { - t.Error("ISqrt failed") - } - - if sqrt.Cmp(x) != 0 { - t.Errorf("ISqrt failed, expected %d, got %d", x, sqrt) - } -} - -func TestCalculateIsqrtC(t *testing.T) { - x := new(big.Int) - x.SetString("3618502788666131213697322783095070105623107215331596699973092056135872020481", 10) - square := new(big.Int) - square = square.Mul(x, x) - - sqrt, err := ISqrt(square) - if err != nil { - t.Error("ISqrt failed") - } - - if sqrt.Cmp(x) != 0 { - t.Errorf("ISqrt failed, expected %d, got %d", x, sqrt) - } -} - -func TestIsSqrtFail(t *testing.T) { - x := big.NewInt(-1) - - _, err := ISqrt(x) - if err == nil { - t.Errorf("expected ISqrt to fail") - } -} diff --git a/pkg/utils/math_utils.go b/pkg/utils/math_utils.go index 4626f55f..7f011a6c 100644 --- a/pkg/utils/math_utils.go +++ b/pkg/utils/math_utils.go @@ -100,5 +100,12 @@ func Igcdex(a *big.Int, b *big.Int) (*big.Int, *big.Int, *big.Int) { return new(big.Int).Mul(x, xSign), new(big.Int).Mul(y, ySign), a } +} +func ISqrt(x *big.Int) (*big.Int, error) { + if x.Sign() == -1 { + return nil, errors.Errorf("Expected x: %s to be non-negative", x) + } + res := new(big.Int) + return res.Sqrt(x), nil } diff --git a/pkg/utils/math_utils_test.go b/pkg/utils/math_utils_test.go index 95a86a45..3b308322 100644 --- a/pkg/utils/math_utils_test.go +++ b/pkg/utils/math_utils_test.go @@ -84,3 +84,124 @@ func TestIgcdex46(t *testing.T) { t.Error("Wrong values returned by Igcdex") } } + +func TestDivModOk(t *testing.T) { + a := new(big.Int) + b := new(big.Int) + prime := new(big.Int) + expected := new(big.Int) + + a.SetString("11260647941622813594563746375280766662237311019551239924981511729608487775604310196863705127454617186486639011517352066501847110680463498585797912894788", 10) + b.SetString("4020711254448367604954374443741161860304516084891705811279711044808359405970", 10) + prime.SetString("800000000000011000000000000000000000000000000000000000000000001", 16) + expected.SetString("2904750555256547440469454488220756360634457312540595732507835416669695939476", 10) + + num, err := DivMod(a, b, prime) + if err != nil { + t.Errorf("DivMod failed with error: %s", err) + } + if num.Cmp(expected) != 0 { + t.Errorf("Expected result: %s to be equal to %s", num, expected) + } +} + +func TestDivModMZeroFail(t *testing.T) { + a := new(big.Int) + b := new(big.Int) + prime := new(big.Int) + + a.SetString("11260647941622813594563746375280766662237311019551239924981511729608487775604310196863705127454617186486639011517352066501847110680463498585797912894788", 10) + prime.SetString("800000000000011000000000000000000000000000000000000000000000001", 16) + + _, err := DivMod(a, b, prime) + if err == nil { + t.Errorf("DivMod expected to failed with gcd != 1") + } +} + +func TestDivModMEqPFail(t *testing.T) { + a := new(big.Int) + b := new(big.Int) + prime := new(big.Int) + + a.SetString("11260647941622813594563746375280766662237311019551239924981511729608487775604310196863705127454617186486639011517352066501847110680463498585797912894788", 10) + b.SetString("800000000000011000000000000000000000000000000000000000000000001", 16) + prime.SetString("800000000000011000000000000000000000000000000000000000000000001", 16) + + _, err := DivMod(a, b, prime) + if err == nil { + t.Errorf("DivMod expected to failed with gcd != 1") + } +} + +func TestIsSqrtOk(t *testing.T) { + x := new(big.Int) + y := new(big.Int) + x.SetString("4573659632505831259480", 10) + y.Mul(x, x) + + sqr_y, err := ISqrt(y) + if err != nil { + t.Errorf("ISqrt failed with error: %s", err) + } + if x.Cmp(sqr_y) != 0 { + t.Errorf("Failed to get square root of x^2, x: %s", x) + } +} + +func TestCalculateIsqrtA(t *testing.T) { + x := new(big.Int) + x.SetString("81", 10) + sqrt, err := ISqrt(x) + if err != nil { + t.Error("ISqrt failed") + } + + expected := new(big.Int) + expected.SetString("9", 10) + + if sqrt.Cmp(expected) != 0 { + t.Errorf("ISqrt failed, expected %d, got %d", expected, sqrt) + } +} + +func TestCalculateIsqrtB(t *testing.T) { + x := new(big.Int) + x.SetString("4573659632505831259480", 10) + square := new(big.Int) + square = square.Mul(x, x) + + sqrt, err := ISqrt(square) + if err != nil { + t.Error("ISqrt failed") + } + + if sqrt.Cmp(x) != 0 { + t.Errorf("ISqrt failed, expected %d, got %d", x, sqrt) + } +} + +func TestCalculateIsqrtC(t *testing.T) { + x := new(big.Int) + x.SetString("3618502788666131213697322783095070105623107215331596699973092056135872020481", 10) + square := new(big.Int) + square = square.Mul(x, x) + + sqrt, err := ISqrt(square) + if err != nil { + t.Error("ISqrt failed") + } + + if sqrt.Cmp(x) != 0 { + t.Errorf("ISqrt failed, expected %d, got %d", x, sqrt) + } +} + +func TestIsSqrtFail(t *testing.T) { + x := big.NewInt(-1) + + _, err := ISqrt(x) + if err == nil { + t.Errorf("expected ISqrt to fail") + } +} From 53e547f59c261c1e578253fd5b6cdb828c10ff98 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 14:11:27 -0300 Subject: [PATCH 79/86] Restore gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4ff14c33..cbf63bd4 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,6 @@ go.work # python env cairo-vm-env -env # generated trace files cairo_programs/*.trace From da8fc0a415e6a5b524f5f219573372d70a0a88b2 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 15:24:47 -0300 Subject: [PATCH 80/86] Add hint + tests --- pkg/hints/hint_codes/secp_hint_codes.go | 5 ++++ pkg/hints/hint_processor.go | 2 ++ pkg/hints/secp_hints.go | 12 ++++++++++ pkg/hints/secp_hints_test.go | 32 +++++++++++++++++++++++++ pkg/vm/cairo_run/cairo_run_test.go | 4 ++++ 5 files changed, 55 insertions(+) diff --git a/pkg/hints/hint_codes/secp_hint_codes.go b/pkg/hints/hint_codes/secp_hint_codes.go index b548bbb3..7a1cf698 100644 --- a/pkg/hints/hint_codes/secp_hint_codes.go +++ b/pkg/hints/hint_codes/secp_hint_codes.go @@ -11,3 +11,8 @@ const VERIFY_ZERO_EXTERNAL_SECP = "from starkware.cairo.common.cairo_secp.secp_u const REDUCE_V1 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack value = pack(ids.x, PRIME) % SECP_P` + +const REDUCE_ED25519 = `from starkware.cairo.common.cairo_secp.secp_utils import pack +SECP_P=2**255-19 + +value = pack(ids.x, PRIME) % SECP_P` diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index d0925294..fa32ee83 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -210,6 +210,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return fastEcAddAssignNewY(execScopes) case REDUCE_V1: return reduceV1(data.Ids, vm, execScopes) + case REDUCE_ED25519: + return reduceED25519(data.Ids, vm, execScopes) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/secp_hints.go b/pkg/hints/secp_hints.go index 002296ed..4967e350 100644 --- a/pkg/hints/secp_hints.go +++ b/pkg/hints/secp_hints.go @@ -19,3 +19,15 @@ func reduceV1(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error scopes.AssignOrUpdateVariable("value", *new(big.Int).Mod(&packedValue, &secpP)) return nil } + +func reduceED25519(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { + secpP := SECP_P_V2() + scopes.AssignOrUpdateVariable("SECP_P", secpP) + value, err := Uint384FromVarName("x", ids, vm) + if err != nil { + return err + } + packedValue := value.Pack86() + scopes.AssignOrUpdateVariable("value", *new(big.Int).Mod(&packedValue, &secpP)) + return nil +} diff --git a/pkg/hints/secp_hints_test.go b/pkg/hints/secp_hints_test.go index 656f152a..077a3d10 100644 --- a/pkg/hints/secp_hints_test.go +++ b/pkg/hints/secp_hints_test.go @@ -44,3 +44,35 @@ func TestReduceV1(t *testing.T) { valueUnpacked := Uint384{Limbs: []Felt{FeltFromUint(6), FeltFromUint(6), FeltFromUint(6)}} CheckScopeVar[big.Int]("value", valueUnpacked.Pack86(), scopes, t) } + +func TestReduceED(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "x": { + NewMaybeRelocatableFelt(FeltFromDecString("6")), + NewMaybeRelocatableFelt(FeltFromDecString("6")), + NewMaybeRelocatableFelt(FeltFromDecString("6")), + }, + }, + vm, + ) + scopes := NewExecutionScopes() + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: REDUCE_ED25519, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("REDUCE_ED25519 hint failed with error %s", err) + } + // Checked scope variables + CheckScopeVar[big.Int]("SECP_P", SECP_P_V2(), scopes, t) + + valueUnpacked := Uint384{Limbs: []Felt{FeltFromUint(6), FeltFromUint(6), FeltFromUint(6)}} + CheckScopeVar[big.Int]("value", valueUnpacked.Pack86(), scopes, t) +} diff --git a/pkg/vm/cairo_run/cairo_run_test.go b/pkg/vm/cairo_run/cairo_run_test.go index f0685afb..e320cb3a 100644 --- a/pkg/vm/cairo_run/cairo_run_test.go +++ b/pkg/vm/cairo_run/cairo_run_test.go @@ -352,3 +352,7 @@ func TestCairoKeccak(t *testing.T) { func TestKeccakAddUint256(t *testing.T) { testProgram("keccak_add_uint256", t) } + +func TestReduce(t *testing.T) { + testProgram("reduce", t) +} From 6b91a52843a8ee22fa5242e0428d3b685f00595b Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 15:25:09 -0300 Subject: [PATCH 81/86] Add test file --- cairo_programs/reduce.cairo | 127 ++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 cairo_programs/reduce.cairo diff --git a/cairo_programs/reduce.cairo b/cairo_programs/reduce.cairo new file mode 100644 index 00000000..a4651d10 --- /dev/null +++ b/cairo_programs/reduce.cairo @@ -0,0 +1,127 @@ +%builtins range_check + +from starkware.cairo.common.cairo_secp.bigint import BigInt3, UnreducedBigInt3, nondet_bigint3 + +const BASE = 2 ** 86; +const SECP_REM = 19; + +func verify_zero{range_check_ptr}(val: UnreducedBigInt3) { + let q = [ap]; + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + SECP_P = 2**255-19 + to_assert = pack(ids.val, PRIME) + q, r = divmod(pack(ids.val, PRIME), SECP_P) + assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." + ids.q = q % PRIME + %} + let q_biased = [ap + 1]; + q_biased = q + 2 ** 127, ap++; + [range_check_ptr] = q_biased, ap++; + // This implies that q is in the range [-2**127, 2**127). + + tempvar r1 = (val.d0 + q * SECP_REM) / BASE; + assert [range_check_ptr + 1] = r1 + 2 ** 127; + // This implies that r1 is in the range [-2**127, 2**127). + // Therefore, r1 * BASE is in the range [-2**213, 2**213). + // By the soundness assumption, val.d0 is in the range (-2**250, 2**250). + // This implies that r1 * BASE = val.d0 + q * SECP_REM (as integers). + + tempvar r2 = (val.d1 + r1) / BASE; + assert [range_check_ptr + 2] = r2 + 2 ** 127; + // Similarly, this implies that r2 * BASE = val.d1 + r1 (as integers). + // Therefore, r2 * BASE**2 = val.d1 * BASE + r1 * BASE. + + assert val.d2 = q * (BASE / 8) - r2; + // Similarly, this implies that q * BASE / 4 = val.d2 + r2 (as integers). + // Therefore, + // q * BASE**3 / 4 = val.d2 * BASE**2 + r2 * BASE ** 2 = + // val.d2 * BASE**2 + val.d1 * BASE + r1 * BASE = + // val.d2 * BASE**2 + val.d1 * BASE + val.d0 + q * SECP_REM = + // val + q * SECP_REM. + // Hence, val = q * (BASE**3 / 4 - SECP_REM) = q * (2**256 - SECP_REM) = q * secp256k1_prime. + + let range_check_ptr = range_check_ptr + 3; + return (); +} + +// Receives an unreduced number, and returns a number that is equal to the original number mod +// Ed25519 prime and in reduced form (meaning every limb is in the range [0, BASE)). +// +// Completeness assumption: x's limbs are in the range (-2**210.99, 2**210.99). +// Soundness assumption: x's limbs are in the range (-2**249.99, 2**249.99). +func reduce_ed25519{range_check_ptr}(x: UnreducedBigInt3) -> (reduced_x: BigInt3) { + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + SECP_P=2**255-19 + + value = pack(ids.x, PRIME) % SECP_P + %} + let (reduced_x: BigInt3) = nondet_bigint3(); + + verify_zero( + UnreducedBigInt3(d0=x.d0 - reduced_x.d0, d1=x.d1 - reduced_x.d1, d2=x.d2 - reduced_x.d2) + ); + return (reduced_x=reduced_x); +} + +func test_reduce_ed25519{range_check_ptr}() { + let x = UnreducedBigInt3(0, 0, 0); + let (res) = reduce_ed25519(x); + assert res = BigInt3(0, 0, 0); + + let x = UnreducedBigInt3( + 1113660525233188137217661511617697775365785011829423399545361443, + 1243997169368861650657124871657865626433458458266748922940703512, + 1484456708474143440067316914074363277495967516029110959982060577, + ); + let (res) = reduce_ed25519(x); + assert res = BigInt3( + 42193159084937489098474581, 19864776835133205750023223, 916662843592479469328893 + ); + + return (); +} + +func reduce_v2{range_check_ptr}(x: UnreducedBigInt3) -> (reduced_x: BigInt3) { + let orig_x = x; + %{ from starkware.cairo.common.cairo_secp.secp256r1_utils import SECP256R1_P as SECP_P %} + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + value = pack(ids.x, PRIME) % SECP_P + %} + let (reduced_x: BigInt3) = nondet_bigint3(); + + verify_zero( + UnreducedBigInt3( + d0=orig_x.d0 - reduced_x.d0, + d1=orig_x.d1 - reduced_x.d1, + d2=orig_x.d2 - reduced_x.d2 + ) + ); + return (reduced_x=reduced_x); +} + +func main{range_check_ptr}() { + test_reduce_ed25519(); + + // reduce_v2 tests + let x = UnreducedBigInt3(0, 0, 0); + let (reduce_v2_a) = reduce_v2(x); + assert reduce_v2_a = BigInt3( + 0, 0, 0 + ); + + let y = UnreducedBigInt3(12354, 745634534, 81298789312879123); + let (reduce_v2_b) = reduce_v2(y); + assert reduce_v2_b = BigInt3( + 12354, 745634534, 81298789312879123 + ); + + let z = UnreducedBigInt3(12354812987893128791212331231233, 7453123123123123312634534, 8129224990312325879); + let (reduce_v2_c) = reduce_v2(z); + assert reduce_v2_c = BigInt3( + 16653320122975184709085185, 7453123123123123312794216, 8129224990312325879 + ); + return (); +} \ No newline at end of file From 307207c0dc760db1aa78a678f421cf93ec37bf44 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 15:37:46 -0300 Subject: [PATCH 82/86] Add REDUCE_V2 hint --- pkg/hints/hint_codes/secp_hint_codes.go | 3 +++ pkg/hints/hint_processor.go | 2 ++ pkg/hints/secp_hints.go | 14 +++++++++++ pkg/hints/secp_hints_test.go | 31 +++++++++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/pkg/hints/hint_codes/secp_hint_codes.go b/pkg/hints/hint_codes/secp_hint_codes.go index 7a1cf698..8db5f0a7 100644 --- a/pkg/hints/hint_codes/secp_hint_codes.go +++ b/pkg/hints/hint_codes/secp_hint_codes.go @@ -12,6 +12,9 @@ const REDUCE_V1 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP value = pack(ids.x, PRIME) % SECP_P` +const REDUCE_V2 = `from starkware.cairo.common.cairo_secp.secp_utils import pack +value = pack(ids.x, PRIME) % SECP_P` + const REDUCE_ED25519 = `from starkware.cairo.common.cairo_secp.secp_utils import pack SECP_P=2**255-19 diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index fa32ee83..7e07413d 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -210,6 +210,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return fastEcAddAssignNewY(execScopes) case REDUCE_V1: return reduceV1(data.Ids, vm, execScopes) + case REDUCE_V2: + return reduceV2(data.Ids, vm, execScopes) case REDUCE_ED25519: return reduceED25519(data.Ids, vm, execScopes) default: diff --git a/pkg/hints/secp_hints.go b/pkg/hints/secp_hints.go index 4967e350..51a75ed5 100644 --- a/pkg/hints/secp_hints.go +++ b/pkg/hints/secp_hints.go @@ -20,6 +20,20 @@ func reduceV1(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error return nil } +func reduceV2(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { + secpP, err := FetchScopeVar[big.Int]("SECP_P", scopes) + if err != nil { + return err + } + value, err := Uint384FromVarName("x", ids, vm) + if err != nil { + return err + } + packedValue := value.Pack86() + scopes.AssignOrUpdateVariable("value", *new(big.Int).Mod(&packedValue, &secpP)) + return nil +} + func reduceED25519(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { secpP := SECP_P_V2() scopes.AssignOrUpdateVariable("SECP_P", secpP) diff --git a/pkg/hints/secp_hints_test.go b/pkg/hints/secp_hints_test.go index 077a3d10..38f421cf 100644 --- a/pkg/hints/secp_hints_test.go +++ b/pkg/hints/secp_hints_test.go @@ -45,6 +45,37 @@ func TestReduceV1(t *testing.T) { CheckScopeVar[big.Int]("value", valueUnpacked.Pack86(), scopes, t) } +func TestReduceV2(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "x": { + NewMaybeRelocatableFelt(FeltFromDecString("6")), + NewMaybeRelocatableFelt(FeltFromDecString("6")), + NewMaybeRelocatableFelt(FeltFromDecString("6")), + }, + }, + vm, + ) + scopes := NewExecutionScopes() + scopes.AssignOrUpdateVariable("SECP_P", SECP_P()) + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: REDUCE_V2, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("REDUCE_V2 hint failed with error %s", err) + } + + valueUnpacked := Uint384{Limbs: []Felt{FeltFromUint(6), FeltFromUint(6), FeltFromUint(6)}} + CheckScopeVar[big.Int]("value", valueUnpacked.Pack86(), scopes, t) +} + func TestReduceED(t *testing.T) { vm := NewVirtualMachine() vm.Segments.AddSegment() From 37b3302d4b7f5f2cfde5f5fab619c9221ecc01aa Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 15:52:55 -0300 Subject: [PATCH 83/86] Implement verify_zero hints --- pkg/hints/hint_codes/secp_hint_codes.go | 18 ++++++++++++++++++ pkg/hints/hint_processor.go | 5 +++++ pkg/hints/secp_hints.go | 17 +++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/pkg/hints/hint_codes/secp_hint_codes.go b/pkg/hints/hint_codes/secp_hint_codes.go index 8db5f0a7..2698a95a 100644 --- a/pkg/hints/hint_codes/secp_hint_codes.go +++ b/pkg/hints/hint_codes/secp_hint_codes.go @@ -19,3 +19,21 @@ const REDUCE_ED25519 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P=2**255-19 value = pack(ids.x, PRIME) % SECP_P` + +const VERIFY_ZERO_V1 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack + +q, r = divmod(pack(ids.val, PRIME), SECP_P) +assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." +ids.q = q % PRIME` + +const VERIFY_ZERO_V2 = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P +q, r = divmod(pack(ids.val, PRIME), SECP_P) +assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." +ids.q = q % PRIME` + +const VERIFY_ZERO_V3 = `from starkware.cairo.common.cairo_secp.secp_utils import pack +SECP_P = 2**255-19 +to_assert = pack(ids.val, PRIME) +q, r = divmod(pack(ids.val, PRIME), SECP_P) +assert r == 0, f"verify_zero: Invalid input {ids.val.d0, ids.val.d1, ids.val.d2}." +ids.q = q % PRIME` diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 7e07413d..6e4c3ec5 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -4,6 +4,7 @@ import ( "strings" . "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_codes" + "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils" . "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/parser" @@ -214,6 +215,10 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return reduceV2(data.Ids, vm, execScopes) case REDUCE_ED25519: return reduceED25519(data.Ids, vm, execScopes) + case VERIFY_ZERO_V1, VERIFY_ZERO_V2: + return verifyZero(data.Ids, vm, execScopes, hint_utils.SECP_P()) + case VERIFY_ZERO_V3: + return verifyZero(data.Ids, vm, execScopes, hint_utils.SECP_P_V2()) default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/secp_hints.go b/pkg/hints/secp_hints.go index 51a75ed5..7f2fba87 100644 --- a/pkg/hints/secp_hints.go +++ b/pkg/hints/secp_hints.go @@ -4,8 +4,11 @@ import ( "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/vm" + "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory" + "github.com/pkg/errors" ) func reduceV1(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) error { @@ -45,3 +48,17 @@ func reduceED25519(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes) scopes.AssignOrUpdateVariable("value", *new(big.Int).Mod(&packedValue, &secpP)) return nil } + +func verifyZero(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, secpP big.Int) error { + scopes.AssignOrUpdateVariable("SECP_P", secpP) + valUnpacked, err := Uint384FromVarName("val", ids, vm) + if err != nil { + return err + } + val := valUnpacked.Pack86() + q, r := new(big.Int).DivMod(&val, &secpP, new(big.Int)) + if r.Cmp(big.NewInt(0)) != 0 { + return errors.Errorf("verify_zero: Invalid input %s", val.Text(10)) + } + return ids.Insert("q", memory.NewMaybeRelocatableFelt(lambdaworks.FeltFromBigInt(q)), vm) +} From 36b75e77f640ed303247b916cc91bc84babdb2e7 Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 16:04:35 -0300 Subject: [PATCH 84/86] Add verify_zero hints --- pkg/hints/secp_hints_test.go | 108 +++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/pkg/hints/secp_hints_test.go b/pkg/hints/secp_hints_test.go index 38f421cf..a1556d04 100644 --- a/pkg/hints/secp_hints_test.go +++ b/pkg/hints/secp_hints_test.go @@ -107,3 +107,111 @@ func TestReduceED(t *testing.T) { valueUnpacked := Uint384{Limbs: []Felt{FeltFromUint(6), FeltFromUint(6), FeltFromUint(6)}} CheckScopeVar[big.Int]("value", valueUnpacked.Pack86(), scopes, t) } + +func TestVerifyZeroV1(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "val": { + NewMaybeRelocatableFelt(FeltFromDecString("0")), + NewMaybeRelocatableFelt(FeltFromDecString("0")), + NewMaybeRelocatableFelt(FeltFromDecString("0")), + }, + "q": {nil, nil, nil}, + }, + vm, + ) + scopes := NewExecutionScopes() + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: VERIFY_ZERO_V1, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("VERIFY_ZERO_V1 hint failed with error %s", err) + } + // Check scope variables + CheckScopeVar[big.Int]("SECP_P", SECP_P(), scopes, t) + // Check ids variables + expectedQ := FeltZero() + idsQ, err := idsManager.GetFelt("q", vm) + if err != nil || expectedQ.Cmp(idsQ) != 0 { + t.Error("Wrong/No ids.q") + } +} + +func TestVerifyZeroV2(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "val": { + NewMaybeRelocatableFelt(FeltFromDecString("0")), + NewMaybeRelocatableFelt(FeltFromDecString("0")), + NewMaybeRelocatableFelt(FeltFromDecString("0")), + }, + "q": {nil, nil, nil}, + }, + vm, + ) + scopes := NewExecutionScopes() + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: VERIFY_ZERO_V2, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("VERIFY_ZERO_V2 hint failed with error %s", err) + } + // Check scope variables + CheckScopeVar[big.Int]("SECP_P", SECP_P(), scopes, t) + // Check ids variables + expectedQ := FeltZero() + idsQ, err := idsManager.GetFelt("q", vm) + if err != nil || expectedQ.Cmp(idsQ) != 0 { + t.Error("Wrong/No ids.q") + } +} + +func TestVerifyZeroV3(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "val": { + NewMaybeRelocatableFelt(FeltFromDecString("0")), + NewMaybeRelocatableFelt(FeltFromDecString("0")), + NewMaybeRelocatableFelt(FeltFromDecString("0")), + }, + "q": {nil, nil, nil}, + }, + vm, + ) + scopes := NewExecutionScopes() + + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: VERIFY_ZERO_V3, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, scopes) + if err != nil { + t.Errorf("VERIFY_ZERO_V3 hint failed with error %s", err) + } + // Check scope variables + CheckScopeVar[big.Int]("SECP_P", SECP_P_V2(), scopes, t) + // Check ids variables + expectedQ := FeltZero() + idsQ, err := idsManager.GetFelt("q", vm) + if err != nil || expectedQ.Cmp(idsQ) != 0 { + t.Error("Wrong/No ids.q") + } +} From 754d3f1375d17d677c1ce62f704568937b01bf7e Mon Sep 17 00:00:00 2001 From: Federica Date: Mon, 2 Oct 2023 16:08:51 -0300 Subject: [PATCH 85/86] Fix fmt --- cairo_programs/reduce.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cairo_programs/reduce.cairo b/cairo_programs/reduce.cairo index a4651d10..486e8b22 100644 --- a/cairo_programs/reduce.cairo +++ b/cairo_programs/reduce.cairo @@ -124,4 +124,4 @@ func main{range_check_ptr}() { 16653320122975184709085185, 7453123123123123312794216, 8129224990312325879 ); return (); -} \ No newline at end of file +} From e109087741aa5e4910c40bb2af8869b2ebf1a95e Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Thu, 5 Oct 2023 23:30:00 +0300 Subject: [PATCH 86/86] Implement `GET_POINT_FROM_X` hint (#298) * Add hint code * Implement hint * Add unit test * Fix test value * Fix hint logic * Add unit test * Add integration test * fmt * Fix * Bump cairo-vm version --- Makefile | 2 +- cairo_programs/signature.cairo | 24 +++++++ pkg/hints/hint_codes/signature_hint_codes.go | 12 ++++ pkg/hints/hint_processor.go | 2 + pkg/hints/signature_hints.go | 31 ++++++++ pkg/hints/signature_hints_test.go | 76 ++++++++++++++++++++ pkg/utils/math_utils.go | 5 ++ pkg/vm/cairo_run/cairo_run_test.go | 4 ++ 8 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 cairo_programs/signature.cairo diff --git a/Makefile b/Makefile index 9954a52f..467040f7 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CAIRO_VM_CLI:=cairo-vm/target/release/cairo-vm-cli $(CAIRO_VM_CLI): - git clone --depth 1 -b v0.8.5 https://github.com/lambdaclass/cairo-vm + git clone --depth 1 -b v0.8.7 https://github.com/lambdaclass/cairo-vm cd cairo-vm; cargo b --release --bin cairo-vm-cli # Create proof mode programs. diff --git a/cairo_programs/signature.cairo b/cairo_programs/signature.cairo new file mode 100644 index 00000000..b6f4a0d4 --- /dev/null +++ b/cairo_programs/signature.cairo @@ -0,0 +1,24 @@ +%builtins range_check + +from starkware.cairo.common.cairo_secp.signature import div_mod_n, get_point_from_x +from starkware.cairo.common.cairo_secp.bigint import BigInt3 + +func main{range_check_ptr: felt}() { + let a: BigInt3 = BigInt3(100, 99, 98); + let b: BigInt3 = BigInt3(10, 9, 8); + let (res) = div_mod_n(a, b); + assert res.d0 = 3413472211745629263979533; + assert res.d1 = 17305268010345238170172332; + assert res.d2 = 11991751872105858217578135; + + let x: BigInt3 = BigInt3(100, 99, 98); + let v: felt = 10; + let (point) = get_point_from_x(x, v); + assert point.x.d0 = 100; + assert point.x.d1 = 99; + assert point.x.d2 = 98; + assert point.y.d0 = 50471654703173585387369794; + assert point.y.d1 = 68898944762041070370364387; + assert point.y.d2 = 16932612780945290933872774; + return (); +} diff --git a/pkg/hints/hint_codes/signature_hint_codes.go b/pkg/hints/hint_codes/signature_hint_codes.go index 37b37051..b1e4e189 100644 --- a/pkg/hints/hint_codes/signature_hint_codes.go +++ b/pkg/hints/hint_codes/signature_hint_codes.go @@ -19,3 +19,15 @@ const DIV_MOD_N_SAFE_DIV = "value = k = safe_div(res * b - a, N)" const DIV_MOD_N_SAFE_DIV_PLUS_ONE = "value = k_plus_one = safe_div(res * b - a, N) + 1" const XS_SAFE_DIV = "value = k = safe_div(res * s - x, N)" + +const GET_POINT_FROM_X = `from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack + +x_cube_int = pack(ids.x_cube, PRIME) % SECP_P +y_square_int = (x_cube_int + ids.BETA) % SECP_P +y = pow(y_square_int, (SECP_P + 1) // 4, SECP_P) + +# We need to decide whether to take y or SECP_P - y. +if ids.v % 2 == y % 2: + value = y +else: + value = (-y) % SECP_P` diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 6e4c3ec5..04043ff9 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -199,6 +199,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return divModNSafeDiv(data.Ids, execScopes, "a", "b", false) case DIV_MOD_N_SAFE_DIV_PLUS_ONE: return divModNSafeDiv(data.Ids, execScopes, "a", "b", true) + case GET_POINT_FROM_X: + return getPointFromX(data.Ids, vm, execScopes, constants) case VERIFY_ZERO_EXTERNAL_SECP: return verifyZeroWithExternalConst(*vm, *execScopes, data.Ids) case FAST_EC_ADD_ASSIGN_NEW_X: diff --git a/pkg/hints/signature_hints.go b/pkg/hints/signature_hints.go index 37b57f7f..60340204 100644 --- a/pkg/hints/signature_hints.go +++ b/pkg/hints/signature_hints.go @@ -4,6 +4,7 @@ import ( "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" @@ -82,3 +83,33 @@ func divModNSafeDiv(ids IdsManager, scopes *ExecutionScopes, aAlias string, bAli scopes.AssignOrUpdateVariable("value", *value) return nil } + +func getPointFromX(ids IdsManager, vm *VirtualMachine, scopes *ExecutionScopes, constants *map[string]Felt) error { + // Handle scope & ids variables + secpP := SECP_P() + scopes.AssignOrUpdateVariable("SECP_P", secpP) + betaFelt, err := ids.GetConst("BETA", constants) + if err != nil { + return err + } + beta := new(big.Int).Mod(betaFelt.ToBigInt(), &secpP) + xCubeIntUnpacked, err := Uint384FromVarName("x_cube", ids, vm) + if err != nil { + return err + } + xCube := xCubeIntUnpacked.Pack86() + vFelt, err := ids.GetFelt("v", vm) + v := vFelt.ToBigInt() + if err != nil { + return err + } + // Hint logic + yCube := new(big.Int).Mod(new(big.Int).Add(&xCube, beta), &secpP) + // y = (yCube ** ((SECP_P + 1) << 2)) % SECP_P + y := new(big.Int).Exp(yCube, new(big.Int).Rsh(new(big.Int).Add(&secpP, big.NewInt(1)), 2), &secpP) + if utils.IsEven(v) != utils.IsEven(y) { + y = new(big.Int).Sub(&secpP, y) + } + scopes.AssignOrUpdateVariable("value", *y) + return nil +} diff --git a/pkg/hints/signature_hints_test.go b/pkg/hints/signature_hints_test.go index 4c3de522..23c648e4 100644 --- a/pkg/hints/signature_hints_test.go +++ b/pkg/hints/signature_hints_test.go @@ -157,3 +157,79 @@ func TestDivModSafeDivPlusOneOk(t *testing.T) { t.Error("Wrong/No scope value val") } } + +func TestGetPointFromXOk(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "v": { + NewMaybeRelocatableFelt(FeltFromUint(18)), + }, + "x_cube": { + NewMaybeRelocatableFelt(FeltFromUint64(2147483647)), + NewMaybeRelocatableFelt(FeltFromUint64(2147483647)), + NewMaybeRelocatableFelt(FeltFromUint64(2147483647)), + }, + }, + vm, + ) + constants := SetupConstantsForTest(map[string]Felt{ + "BETA": FeltFromUint(7), + }, &idsManager) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: GET_POINT_FROM_X, + }) + scopes := NewExecutionScopes() + err := hintProcessor.ExecuteHint(vm, &hintData, &constants, scopes) + if err != nil { + t.Errorf("GET_POINT_FROM_X hint test failed with error %s", err) + } + // Check result in scope + expectedValue, _ := new(big.Int).SetString("21517397797248348844406833268402983856262903417026833897388175962266357959124", 10) + + value, err := FetchScopeVar[big.Int]("value", scopes) + if err != nil || value.Cmp(expectedValue) != 0 { + t.Errorf("Wrong/No scope var value.\n Expected %v, got: %v", expectedValue, &value) + } +} + +func TestGetPointFromXNegativeY(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "v": { + NewMaybeRelocatableFelt(FeltOne()), + }, + "x_cube": { + NewMaybeRelocatableFelt(FeltFromUint64(2147483647)), + NewMaybeRelocatableFelt(FeltFromUint64(2147483647)), + NewMaybeRelocatableFelt(FeltFromUint64(2147483647)), + }, + }, + vm, + ) + constants := SetupConstantsForTest(map[string]Felt{ + "BETA": FeltFromUint(7), + }, &idsManager) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: GET_POINT_FROM_X, + }) + scopes := NewExecutionScopes() + err := hintProcessor.ExecuteHint(vm, &hintData, &constants, scopes) + if err != nil { + t.Errorf("GET_POINT_FROM_X hint test failed with error %s", err) + } + // Check result in scope + expectedValue, _ := new(big.Int).SetString("94274691440067846579164151740284923997007081248613730142069408045642476712539", 10) + + value, err := FetchScopeVar[big.Int]("value", scopes) + if err != nil || value.Cmp(expectedValue) != 0 { + t.Errorf("Wrong/No scope var value.\n Expected %v, got: %v", expectedValue, &value) + } +} diff --git a/pkg/utils/math_utils.go b/pkg/utils/math_utils.go index 7f011a6c..54ce207e 100644 --- a/pkg/utils/math_utils.go +++ b/pkg/utils/math_utils.go @@ -102,6 +102,11 @@ func Igcdex(a *big.Int, b *big.Int) (*big.Int, *big.Int, *big.Int) { } } +func IsEven(n *big.Int) bool { + res := new(big.Int).And(n, big.NewInt(1)) + return res.Cmp(big.NewInt(0)) != 0 +} + func ISqrt(x *big.Int) (*big.Int, error) { if x.Sign() == -1 { return nil, errors.Errorf("Expected x: %s to be non-negative", x) diff --git a/pkg/vm/cairo_run/cairo_run_test.go b/pkg/vm/cairo_run/cairo_run_test.go index e320cb3a..e123789c 100644 --- a/pkg/vm/cairo_run/cairo_run_test.go +++ b/pkg/vm/cairo_run/cairo_run_test.go @@ -333,6 +333,10 @@ func TestDivModN(t *testing.T) { testProgram("div_mod_n", t) } +func TestSignature(t *testing.T) { + testProgram("signature", t) +} + func TestEcDoubleAssign(t *testing.T) { testProgram("ec_double_assign", t) }