From 04d9552861dbc9b8c680ec45b539a7152f739a43 Mon Sep 17 00:00:00 2001 From: Sh0g0-1758 Date: Thu, 15 Aug 2024 15:53:18 +0530 Subject: [PATCH 1/8] Wrote Impl --- pkg/hintrunner/core/hint.go | 217 ++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) diff --git a/pkg/hintrunner/core/hint.go b/pkg/hintrunner/core/hint.go index a738570e..b6a4e0ee 100644 --- a/pkg/hintrunner/core/hint.go +++ b/pkg/hintrunner/core/hint.go @@ -417,6 +417,223 @@ func (hint DivMod) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerContext) e return nil } +type U256InvModN struct { + b0 hinter.ResOperander + b1 hinter.ResOperander + n0 hinter.ResOperander + n1 hinter.ResOperander + g0_or_no_inv hinter.CellRefer + g1_option hinter.CellRefer + s_or_r0 hinter.CellRefer + s_or_r1 hinter.CellRefer + t_or_k0 hinter.CellRefer + t_or_k1 hinter.CellRefer +} + +func (hint U256InvModN) String() string { + return "U256InvModN" +} + +func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerContext) error { + pow_2_128 := new(big.Int).Lsh(big.NewInt(1), 128) + + b0, err := hint.b0.Resolve(vm) + if err != nil { + return fmt.Errorf("resolve b0 operand %s: %v", hint.b0, err) + } + b1, err := hint.b1.Resolve(vm) + if err != nil { + return fmt.Errorf("resolve b1 operand %s: %v", hint.b1, err) + } + n0, err := hint.n0.Resolve(vm) + if err != nil { + return fmt.Errorf("resolve n0 operand %s: %v", hint.n0, err) + } + n1, err := hint.n1.Resolve(vm) + if err != nil { + return fmt.Errorf("resolve n1 operand %s: %v", hint.n1, err) + } + + g0OrNoInvAddr, err := hint.g0_or_no_inv.Get(vm) + if err != nil { + return fmt.Errorf("get g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) + } + g1OptionAddr, err := hint.g1_option.Get(vm) + if err != nil { + return fmt.Errorf("get g1_option address %s: %w", g1OptionAddr, err) + } + sOrR0Addr, err := hint.s_or_r0.Get(vm) + if err != nil { + return fmt.Errorf("get s_or_r0 address %s: %w", sOrR0Addr, err) + } + sOrR1Addr, err := hint.s_or_r1.Get(vm) + if err != nil { + return fmt.Errorf("get s_or_r1 address %s: %w", sOrR1Addr, err) + } + tOrK0Addr, err := hint.t_or_k0.Get(vm) + if err != nil { + return fmt.Errorf("get t_or_k0 address %s: %w", tOrK0Addr, err) + } + tOrK1Addr, err := hint.t_or_k1.Get(vm) + if err != nil { + return fmt.Errorf("get t_or_k1 address %s: %w", tOrK1Addr, err) + } + + b0Felt, err := b0.FieldElement() + if err != nil { + return err + } + b1Felt, err := b1.FieldElement() + if err != nil { + return err + } + n0Felt, err := n0.FieldElement() + if err != nil { + return err + } + n1Felt, err := n1.FieldElement() + if err != nil { + return err + } + var b0BigInt big.Int + b0Felt.BigInt(&b0BigInt) + var b1BigInt big.Int + b1Felt.BigInt(&b1BigInt) + var n0BigInt big.Int + n0Felt.BigInt(&n0BigInt) + var n1BigInt big.Int + n1Felt.BigInt(&n1BigInt) + b := new(big.Int).Lsh(&b1BigInt, 128) + b.Add(b, &b0BigInt) + n := new(big.Int).Lsh(&n1BigInt, 128) + n.Add(n, &n0BigInt) + var x big.Int + var y big.Int + var g big.Int + g.GCD(&x, &y, n, b) + if n.Cmp(big.NewInt(1)) == 0 { + mv := mem.MemoryValueFromFieldElement(b0Felt) + err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) + if err != nil { + return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) + } + mv = mem.MemoryValueFromFieldElement(b1Felt) + err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) + if err != nil { + return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) + } + mv = mem.MemoryValueFromFieldElement(&utils.FeltOne) + err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) + if err != nil { + return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) + } + mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) + err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) + if err != nil { + return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) + } + mv = mem.MemoryValueFromFieldElement(&utils.FeltOne) + err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) + if err != nil { + return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) + } + mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) + err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) + if err != nil { + return fmt.Errorf("write to g1_option address %s: %w", g1OptionAddr, err) + } + } else if g.Cmp(big.NewInt(1)) != 0 { + if new(big.Int).Rem(&g, big.NewInt(2)) == big.NewInt(0) { + g = *big.NewInt(2) + } + limb1 := new(big.Int).Div(new(big.Int).Div(b, &g), pow_2_128) + limb0 := new(big.Int).Rem(new(big.Int).Div(b, &g), pow_2_128) + mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) + if err != nil { + return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) + } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) + if err != nil { + return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) + } + limb1 = new(big.Int).Div(new(big.Int).Div(n, &g), pow_2_128) + limb0 = new(big.Int).Rem(new(big.Int).Div(n, &g), pow_2_128) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) + if err != nil { + return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) + } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) + if err != nil { + return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) + } + limb1 = new(big.Int).Div(&g, pow_2_128) + limb0 = new(big.Int).Rem(&g, pow_2_128) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) + if err != nil { + return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) + } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) + if err != nil { + return fmt.Errorf("write to g1_option address %s: %w", g1OptionAddr, err) + } + } else { + y.Rem(&y, n) + if y.Cmp(big.NewInt(0)) < 0 { + y.Add(&y, n) + } + k := new(big.Int).Mul(&y, b) + k.Sub(k, big.NewInt(1)) + k.Div(k, n) + limb1 := new(big.Int).Div(&y, pow_2_128) + limb0 := new(big.Int).Rem(&y, pow_2_128) + mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) + if err != nil { + return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) + } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) + if err != nil { + return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) + } + limb1 = new(big.Int).Div(k, pow_2_128) + limb0 = new(big.Int).Rem(k, pow_2_128) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) + if err != nil { + return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) + } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) + if err != nil { + return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) + } + mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) + err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) + if err != nil { + return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) + } + mv = mem.MemoryValueFromFieldElement(&utils.FeltOne) + err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) + if err != nil { + return fmt.Errorf("write to g1_option address %s: %w", g1OptionAddr, err) + } + } + + // mv := mem.MemoryValueFromFieldElement(&resFelt) + // err = vm.Memory.WriteToAddress(&dstAddr, &mv) + // if err != nil { + // return fmt.Errorf("write to dst address %s: %w", dstAddr, err) + // } + return nil +} + type Uint256DivMod struct { dividend0 hinter.ResOperander dividend1 hinter.ResOperander From d677816830023498b96bcbcde18d7a203ea4cf99 Mon Sep 17 00:00:00 2001 From: Sh0g0-1758 Date: Thu, 15 Aug 2024 15:54:15 +0530 Subject: [PATCH 2/8] nit --- pkg/hintrunner/core/hint.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pkg/hintrunner/core/hint.go b/pkg/hintrunner/core/hint.go index b6a4e0ee..c387067e 100644 --- a/pkg/hintrunner/core/hint.go +++ b/pkg/hintrunner/core/hint.go @@ -626,11 +626,6 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte } } - // mv := mem.MemoryValueFromFieldElement(&resFelt) - // err = vm.Memory.WriteToAddress(&dstAddr, &mv) - // if err != nil { - // return fmt.Errorf("write to dst address %s: %w", dstAddr, err) - // } return nil } From 7d14eeef2f26df79f493cae4cde004d9fde76261 Mon Sep 17 00:00:00 2001 From: Sh0g0-1758 Date: Thu, 15 Aug 2024 16:06:15 +0530 Subject: [PATCH 3/8] fmt --- pkg/hintrunner/core/hint.go | 42 ++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/pkg/hintrunner/core/hint.go b/pkg/hintrunner/core/hint.go index c387067e..54922986 100644 --- a/pkg/hintrunner/core/hint.go +++ b/pkg/hintrunner/core/hint.go @@ -441,14 +441,17 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte if err != nil { return fmt.Errorf("resolve b0 operand %s: %v", hint.b0, err) } + b1, err := hint.b1.Resolve(vm) if err != nil { return fmt.Errorf("resolve b1 operand %s: %v", hint.b1, err) } + n0, err := hint.n0.Resolve(vm) if err != nil { return fmt.Errorf("resolve n0 operand %s: %v", hint.n0, err) } + n1, err := hint.n1.Resolve(vm) if err != nil { return fmt.Errorf("resolve n1 operand %s: %v", hint.n1, err) @@ -458,22 +461,27 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte if err != nil { return fmt.Errorf("get g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) } + g1OptionAddr, err := hint.g1_option.Get(vm) if err != nil { return fmt.Errorf("get g1_option address %s: %w", g1OptionAddr, err) } + sOrR0Addr, err := hint.s_or_r0.Get(vm) if err != nil { return fmt.Errorf("get s_or_r0 address %s: %w", sOrR0Addr, err) } + sOrR1Addr, err := hint.s_or_r1.Get(vm) if err != nil { return fmt.Errorf("get s_or_r1 address %s: %w", sOrR1Addr, err) } + tOrK0Addr, err := hint.t_or_k0.Get(vm) if err != nil { return fmt.Errorf("get t_or_k0 address %s: %w", tOrK0Addr, err) } + tOrK1Addr, err := hint.t_or_k1.Get(vm) if err != nil { return fmt.Errorf("get t_or_k1 address %s: %w", tOrK1Addr, err) @@ -495,48 +503,62 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte if err != nil { return err } + var b0BigInt big.Int b0Felt.BigInt(&b0BigInt) + var b1BigInt big.Int b1Felt.BigInt(&b1BigInt) + var n0BigInt big.Int n0Felt.BigInt(&n0BigInt) + var n1BigInt big.Int n1Felt.BigInt(&n1BigInt) + b := new(big.Int).Lsh(&b1BigInt, 128) b.Add(b, &b0BigInt) + n := new(big.Int).Lsh(&n1BigInt, 128) n.Add(n, &n0BigInt) + var x big.Int var y big.Int var g big.Int + g.GCD(&x, &y, n, b) + if n.Cmp(big.NewInt(1)) == 0 { mv := mem.MemoryValueFromFieldElement(b0Felt) err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) if err != nil { return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) } + mv = mem.MemoryValueFromFieldElement(b1Felt) err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) if err != nil { return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) } + mv = mem.MemoryValueFromFieldElement(&utils.FeltOne) err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) if err != nil { return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) } + mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) if err != nil { return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) } + mv = mem.MemoryValueFromFieldElement(&utils.FeltOne) err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) if err != nil { return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) } + mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) if err != nil { @@ -546,37 +568,46 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte if new(big.Int).Rem(&g, big.NewInt(2)) == big.NewInt(0) { g = *big.NewInt(2) } + limb1 := new(big.Int).Div(new(big.Int).Div(b, &g), pow_2_128) limb0 := new(big.Int).Rem(new(big.Int).Div(b, &g), pow_2_128) + mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) if err != nil { return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) if err != nil { return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) } + limb1 = new(big.Int).Div(new(big.Int).Div(n, &g), pow_2_128) limb0 = new(big.Int).Rem(new(big.Int).Div(n, &g), pow_2_128) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) if err != nil { return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) if err != nil { return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) } + limb1 = new(big.Int).Div(&g, pow_2_128) limb0 = new(big.Int).Rem(&g, pow_2_128) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) if err != nil { return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) if err != nil { @@ -587,39 +618,48 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte if y.Cmp(big.NewInt(0)) < 0 { y.Add(&y, n) } + k := new(big.Int).Mul(&y, b) k.Sub(k, big.NewInt(1)) k.Div(k, n) + limb1 := new(big.Int).Div(&y, pow_2_128) limb0 := new(big.Int).Rem(&y, pow_2_128) + mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) if err != nil { return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) if err != nil { return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) } + limb1 = new(big.Int).Div(k, pow_2_128) limb0 = new(big.Int).Rem(k, pow_2_128) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) if err != nil { return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) } + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) if err != nil { return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) } + mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) if err != nil { return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) } - mv = mem.MemoryValueFromFieldElement(&utils.FeltOne) + + mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) if err != nil { return fmt.Errorf("write to g1_option address %s: %w", g1OptionAddr, err) From 6b3fce0bf26334925c7a4628ef6361b941452954 Mon Sep 17 00:00:00 2001 From: Sh0g0-1758 Date: Thu, 15 Aug 2024 16:07:31 +0530 Subject: [PATCH 4/8] removed bug --- pkg/hintrunner/core/hint.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pkg/hintrunner/core/hint.go b/pkg/hintrunner/core/hint.go index 54922986..757f2dcb 100644 --- a/pkg/hintrunner/core/hint.go +++ b/pkg/hintrunner/core/hint.go @@ -658,12 +658,6 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte if err != nil { return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) } - - mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) - err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) - if err != nil { - return fmt.Errorf("write to g1_option address %s: %w", g1OptionAddr, err) - } } return nil From b61e0bc2efb119d826b9d932c767433294d885c4 Mon Sep 17 00:00:00 2001 From: Sh0g0-1758 Date: Thu, 15 Aug 2024 16:18:49 +0530 Subject: [PATCH 5/8] Added hint support for starkent --- pkg/hintrunner/core/hint.go | 130 +++++++++++++++++------------------ pkg/parsers/starknet/hint.go | 16 +++++ 2 files changed, 81 insertions(+), 65 deletions(-) diff --git a/pkg/hintrunner/core/hint.go b/pkg/hintrunner/core/hint.go index 757f2dcb..7d6e1e8e 100644 --- a/pkg/hintrunner/core/hint.go +++ b/pkg/hintrunner/core/hint.go @@ -418,16 +418,16 @@ func (hint DivMod) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerContext) e } type U256InvModN struct { - b0 hinter.ResOperander - b1 hinter.ResOperander - n0 hinter.ResOperander - n1 hinter.ResOperander - g0_or_no_inv hinter.CellRefer - g1_option hinter.CellRefer - s_or_r0 hinter.CellRefer - s_or_r1 hinter.CellRefer - t_or_k0 hinter.CellRefer - t_or_k1 hinter.CellRefer + B0 hinter.ResOperander + B1 hinter.ResOperander + N0 hinter.ResOperander + N1 hinter.ResOperander + G0OrNoInv hinter.CellRefer + G1Option hinter.CellRefer + SOrR0 hinter.CellRefer + SOrR1 hinter.CellRefer + TOrK0 hinter.CellRefer + TOrK1 hinter.CellRefer } func (hint U256InvModN) String() string { @@ -437,90 +437,90 @@ func (hint U256InvModN) String() string { func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerContext) error { pow_2_128 := new(big.Int).Lsh(big.NewInt(1), 128) - b0, err := hint.b0.Resolve(vm) + B0, err := hint.B0.Resolve(vm) if err != nil { - return fmt.Errorf("resolve b0 operand %s: %v", hint.b0, err) + return fmt.Errorf("resolve B0 operand %s: %v", hint.B0, err) } - b1, err := hint.b1.Resolve(vm) + B1, err := hint.B1.Resolve(vm) if err != nil { - return fmt.Errorf("resolve b1 operand %s: %v", hint.b1, err) + return fmt.Errorf("resolve B1 operand %s: %v", hint.B1, err) } - n0, err := hint.n0.Resolve(vm) + N0, err := hint.N0.Resolve(vm) if err != nil { - return fmt.Errorf("resolve n0 operand %s: %v", hint.n0, err) + return fmt.Errorf("resolve N0 operand %s: %v", hint.N0, err) } - n1, err := hint.n1.Resolve(vm) + N1, err := hint.N1.Resolve(vm) if err != nil { - return fmt.Errorf("resolve n1 operand %s: %v", hint.n1, err) + return fmt.Errorf("resolve N1 operand %s: %v", hint.N1, err) } - g0OrNoInvAddr, err := hint.g0_or_no_inv.Get(vm) + g0OrNoInvAddr, err := hint.G0OrNoInv.Get(vm) if err != nil { - return fmt.Errorf("get g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) + return fmt.Errorf("get G0OrNoInv address %s: %w", g0OrNoInvAddr, err) } - g1OptionAddr, err := hint.g1_option.Get(vm) + g1OptionAddr, err := hint.G1Option.Get(vm) if err != nil { - return fmt.Errorf("get g1_option address %s: %w", g1OptionAddr, err) + return fmt.Errorf("get G1Option address %s: %w", g1OptionAddr, err) } - sOrR0Addr, err := hint.s_or_r0.Get(vm) + sOrR0Addr, err := hint.SOrR0.Get(vm) if err != nil { - return fmt.Errorf("get s_or_r0 address %s: %w", sOrR0Addr, err) + return fmt.Errorf("get SOrR0 address %s: %w", sOrR0Addr, err) } - sOrR1Addr, err := hint.s_or_r1.Get(vm) + sOrR1Addr, err := hint.SOrR1.Get(vm) if err != nil { - return fmt.Errorf("get s_or_r1 address %s: %w", sOrR1Addr, err) + return fmt.Errorf("get SOrR1 address %s: %w", sOrR1Addr, err) } - tOrK0Addr, err := hint.t_or_k0.Get(vm) + tOrK0Addr, err := hint.TOrK0.Get(vm) if err != nil { - return fmt.Errorf("get t_or_k0 address %s: %w", tOrK0Addr, err) + return fmt.Errorf("get TOrK0 address %s: %w", tOrK0Addr, err) } - tOrK1Addr, err := hint.t_or_k1.Get(vm) + tOrK1Addr, err := hint.TOrK1.Get(vm) if err != nil { - return fmt.Errorf("get t_or_k1 address %s: %w", tOrK1Addr, err) + return fmt.Errorf("get TOrK1 address %s: %w", tOrK1Addr, err) } - b0Felt, err := b0.FieldElement() + B0Felt, err := B0.FieldElement() if err != nil { return err } - b1Felt, err := b1.FieldElement() + B1Felt, err := B1.FieldElement() if err != nil { return err } - n0Felt, err := n0.FieldElement() + N0Felt, err := N0.FieldElement() if err != nil { return err } - n1Felt, err := n1.FieldElement() + N1Felt, err := N1.FieldElement() if err != nil { return err } - var b0BigInt big.Int - b0Felt.BigInt(&b0BigInt) + var B0BigInt big.Int + B0Felt.BigInt(&B0BigInt) - var b1BigInt big.Int - b1Felt.BigInt(&b1BigInt) + var B1BigInt big.Int + B1Felt.BigInt(&B1BigInt) - var n0BigInt big.Int - n0Felt.BigInt(&n0BigInt) + var N0BigInt big.Int + N0Felt.BigInt(&N0BigInt) - var n1BigInt big.Int - n1Felt.BigInt(&n1BigInt) + var N1BigInt big.Int + N1Felt.BigInt(&N1BigInt) - b := new(big.Int).Lsh(&b1BigInt, 128) - b.Add(b, &b0BigInt) + b := new(big.Int).Lsh(&B1BigInt, 128) + b.Add(b, &B0BigInt) - n := new(big.Int).Lsh(&n1BigInt, 128) - n.Add(n, &n0BigInt) + n := new(big.Int).Lsh(&N1BigInt, 128) + n.Add(n, &N0BigInt) var x big.Int var y big.Int @@ -529,40 +529,40 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte g.GCD(&x, &y, n, b) if n.Cmp(big.NewInt(1)) == 0 { - mv := mem.MemoryValueFromFieldElement(b0Felt) + mv := mem.MemoryValueFromFieldElement(B0Felt) err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) if err != nil { - return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) + return fmt.Errorf("write to SOrR0 address %s: %w", sOrR0Addr, err) } - mv = mem.MemoryValueFromFieldElement(b1Felt) + mv = mem.MemoryValueFromFieldElement(B1Felt) err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) if err != nil { - return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) + return fmt.Errorf("write to SOrR1 address %s: %w", sOrR1Addr, err) } mv = mem.MemoryValueFromFieldElement(&utils.FeltOne) err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) if err != nil { - return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) + return fmt.Errorf("write to TOrK0 address %s: %w", tOrK0Addr, err) } mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) if err != nil { - return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) + return fmt.Errorf("write to TOrK1 address %s: %w", tOrK1Addr, err) } mv = mem.MemoryValueFromFieldElement(&utils.FeltOne) err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) if err != nil { - return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) + return fmt.Errorf("write to G0OrNoInv address %s: %w", g0OrNoInvAddr, err) } mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) if err != nil { - return fmt.Errorf("write to g1_option address %s: %w", g1OptionAddr, err) + return fmt.Errorf("write to G1Option address %s: %w", g1OptionAddr, err) } } else if g.Cmp(big.NewInt(1)) != 0 { if new(big.Int).Rem(&g, big.NewInt(2)) == big.NewInt(0) { @@ -575,13 +575,13 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) if err != nil { - return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) + return fmt.Errorf("write to SOrR0 address %s: %w", sOrR0Addr, err) } mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) if err != nil { - return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) + return fmt.Errorf("write to SOrR1 address %s: %w", sOrR1Addr, err) } limb1 = new(big.Int).Div(new(big.Int).Div(n, &g), pow_2_128) @@ -590,13 +590,13 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) if err != nil { - return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) + return fmt.Errorf("write to TOrK0 address %s: %w", tOrK0Addr, err) } mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) if err != nil { - return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) + return fmt.Errorf("write to TOrK1 address %s: %w", tOrK1Addr, err) } limb1 = new(big.Int).Div(&g, pow_2_128) @@ -605,13 +605,13 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) if err != nil { - return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) + return fmt.Errorf("write to G0OrNoInv address %s: %w", g0OrNoInvAddr, err) } mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) if err != nil { - return fmt.Errorf("write to g1_option address %s: %w", g1OptionAddr, err) + return fmt.Errorf("write to G1Option address %s: %w", g1OptionAddr, err) } } else { y.Rem(&y, n) @@ -629,13 +629,13 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) if err != nil { - return fmt.Errorf("write to s_or_r0 address %s: %w", sOrR0Addr, err) + return fmt.Errorf("write to SOrR0 address %s: %w", sOrR0Addr, err) } mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) if err != nil { - return fmt.Errorf("write to s_or_r1 address %s: %w", sOrR1Addr, err) + return fmt.Errorf("write to SOrR1 address %s: %w", sOrR1Addr, err) } limb1 = new(big.Int).Div(k, pow_2_128) @@ -644,19 +644,19 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) if err != nil { - return fmt.Errorf("write to t_or_k0 address %s: %w", tOrK0Addr, err) + return fmt.Errorf("write to TOrK0 address %s: %w", tOrK0Addr, err) } mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) if err != nil { - return fmt.Errorf("write to t_or_k1 address %s: %w", tOrK1Addr, err) + return fmt.Errorf("write to TOrK1 address %s: %w", tOrK1Addr, err) } mv = mem.MemoryValueFromFieldElement(&utils.FeltZero) err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) if err != nil { - return fmt.Errorf("write to g0_or_no_inv address %s: %w", g0OrNoInvAddr, err) + return fmt.Errorf("write to G0OrNoInv address %s: %w", g0OrNoInvAddr, err) } } diff --git a/pkg/parsers/starknet/hint.go b/pkg/parsers/starknet/hint.go index 0db74ff3..428a22d7 100644 --- a/pkg/parsers/starknet/hint.go +++ b/pkg/parsers/starknet/hint.go @@ -23,6 +23,7 @@ const ( TestLessThanOrEqualAddressName HintName = "TestLessThanOrEqualAddress" WideMul128Name HintName = "WideMul128" DivModName HintName = "DivMod" + U256InvModName HintName = "U256InvMod" Uint256DivModName HintName = "Uint256DivMod" Uint512DivModByUint256Name HintName = "Uint512DivModByUint256" SquareRootName HintName = "SquareRoot" @@ -106,6 +107,19 @@ type DivMod struct { Remainder CellRef `json:"remainder" validate:"required"` } +type U256InvMod struct { + B0 ResOperand `json:"b0" validate:"required"` + B1 ResOperand `json:"b1" validate:"required"` + N0 ResOperand `json:"n0" validate:"required"` + N1 ResOperand `json:"n1" validate:"required"` + G0OrNoInv CellRef `json:"g0_or_no_inv" validate:"required"` + G1Option CellRef `json:"g1_option" validate:"required"` + SOrR0 CellRef `json:"s_or_r0" validate:"required"` + SOrR1 CellRef `json:"s_or_r1" validate:"required"` + TOrK0 CellRef `json:"t_or_k0" validate:"required"` + TOrK1 CellRef `json:"t_or_k1" validate:"required"` +} + type Uint256DivMod struct { Dividend0 ResOperand `json:"dividend0" validate:"required"` Dividend1 ResOperand `json:"dividend1" validate:"required"` @@ -478,6 +492,8 @@ func (h *Hint) UnmarshalJSON(data []byte) error { args = &WideMul128{} case DivModName: args = &DivMod{} + case U256InvModName: + args = &U256InvMod{} case Uint256DivModName: args = &Uint256DivMod{} case Uint512DivModByUint256Name: From 174f98d515015e03c715ab85edccd85688fd0f33 Mon Sep 17 00:00:00 2001 From: Sh0g0-1758 Date: Thu, 15 Aug 2024 16:43:41 +0530 Subject: [PATCH 6/8] Refactored Implementation --- pkg/hintrunner/core/hint.go | 53 ++++++++++-------------------- pkg/hintrunner/utils/math_utils.go | 4 +-- 2 files changed, 19 insertions(+), 38 deletions(-) diff --git a/pkg/hintrunner/core/hint.go b/pkg/hintrunner/core/hint.go index 7d6e1e8e..86d96a34 100644 --- a/pkg/hintrunner/core/hint.go +++ b/pkg/hintrunner/core/hint.go @@ -435,8 +435,6 @@ func (hint U256InvModN) String() string { } func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerContext) error { - pow_2_128 := new(big.Int).Lsh(big.NewInt(1), 128) - B0, err := hint.B0.Resolve(vm) if err != nil { return fmt.Errorf("resolve B0 operand %s: %v", hint.B0, err) @@ -522,11 +520,9 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte n := new(big.Int).Lsh(&N1BigInt, 128) n.Add(n, &N0BigInt) - var x big.Int - var y big.Int - var g big.Int - - g.GCD(&x, &y, n, b) + _, r, g := u.Igcdex(n, b) + mask := new(big.Int).Lsh(big.NewInt(1), 128) + mask.Sub(mask, big.NewInt(1)) if n.Cmp(big.NewInt(1)) == 0 { mv := mem.MemoryValueFromFieldElement(B0Felt) @@ -569,85 +565,70 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte g = *big.NewInt(2) } - limb1 := new(big.Int).Div(new(big.Int).Div(b, &g), pow_2_128) - limb0 := new(big.Int).Rem(new(big.Int).Div(b, &g), pow_2_128) + s := new(big.Int).Div(b, &g) + t := new(big.Int).Div(n, &g) - mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).And(s, mask))) err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) if err != nil { return fmt.Errorf("write to SOrR0 address %s: %w", sOrR0Addr, err) } - mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).Rsh(s, 128))) err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) if err != nil { return fmt.Errorf("write to SOrR1 address %s: %w", sOrR1Addr, err) } - limb1 = new(big.Int).Div(new(big.Int).Div(n, &g), pow_2_128) - limb0 = new(big.Int).Rem(new(big.Int).Div(n, &g), pow_2_128) - - mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).And(t, mask))) err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) if err != nil { return fmt.Errorf("write to TOrK0 address %s: %w", tOrK0Addr, err) } - mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).Rsh(t, 128))) err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) if err != nil { return fmt.Errorf("write to TOrK1 address %s: %w", tOrK1Addr, err) } - limb1 = new(big.Int).Div(&g, pow_2_128) - limb0 = new(big.Int).Rem(&g, pow_2_128) - - mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).And(&g, mask))) err = vm.Memory.WriteToAddress(&g0OrNoInvAddr, &mv) if err != nil { return fmt.Errorf("write to G0OrNoInv address %s: %w", g0OrNoInvAddr, err) } - mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).Rsh(&g, 128))) err = vm.Memory.WriteToAddress(&g1OptionAddr, &mv) if err != nil { return fmt.Errorf("write to G1Option address %s: %w", g1OptionAddr, err) } } else { - y.Rem(&y, n) - if y.Cmp(big.NewInt(0)) < 0 { - y.Add(&y, n) - } + r.Rem(&r, n) - k := new(big.Int).Mul(&y, b) + k := new(big.Int).Mul(&r, b) k.Sub(k, big.NewInt(1)) k.Div(k, n) - limb1 := new(big.Int).Div(&y, pow_2_128) - limb0 := new(big.Int).Rem(&y, pow_2_128) - - mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + mv := mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).And(&r, mask))) err = vm.Memory.WriteToAddress(&sOrR0Addr, &mv) if err != nil { return fmt.Errorf("write to SOrR0 address %s: %w", sOrR0Addr, err) } - mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).Rsh(&r, 128))) err = vm.Memory.WriteToAddress(&sOrR1Addr, &mv) if err != nil { return fmt.Errorf("write to SOrR1 address %s: %w", sOrR1Addr, err) } - limb1 = new(big.Int).Div(k, pow_2_128) - limb0 = new(big.Int).Rem(k, pow_2_128) - - mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb0)) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).And(k, mask))) err = vm.Memory.WriteToAddress(&tOrK0Addr, &mv) if err != nil { return fmt.Errorf("write to TOrK0 address %s: %w", tOrK0Addr, err) } - mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(limb1)) + mv = mem.MemoryValueFromFieldElement(new(f.Element).SetBigInt(new(big.Int).Rsh(k, 128))) err = vm.Memory.WriteToAddress(&tOrK1Addr, &mv) if err != nil { return fmt.Errorf("write to TOrK1 address %s: %w", tOrK1Addr, err) diff --git a/pkg/hintrunner/utils/math_utils.go b/pkg/hintrunner/utils/math_utils.go index f3b111ea..7f274f81 100644 --- a/pkg/hintrunner/utils/math_utils.go +++ b/pkg/hintrunner/utils/math_utils.go @@ -55,7 +55,7 @@ func AsIntBig(value *big.Int) big.Int { func Divmod(n, m, p *big.Int) (big.Int, error) { // https://github.com/starkware-libs/cairo-lang/blob/efa9648f57568aad8f8a13fbf027d2de7c63c2c0/src/starkware/python/math_utils.py#L26 - a, _, c := igcdex(m, p) + a, _, c := Igcdex(m, p) if c.Cmp(big.NewInt(1)) != 0 { return *big.NewInt(0), errors.New("no solution exists (gcd(m, p) != 1)") } @@ -65,7 +65,7 @@ func Divmod(n, m, p *big.Int) (big.Int, error) { return *res, nil } -func igcdex(a, b *big.Int) (big.Int, big.Int, big.Int) { +func Igcdex(a, b *big.Int) (big.Int, big.Int, big.Int) { // https://github.com/sympy/sympy/blob/d91b8ad6d36a59a879cc70e5f4b379da5fdd46ce/sympy/core/intfunc.py#L362 if a.Cmp(big.NewInt(0)) == 0 && b.Cmp(big.NewInt(0)) == 0 { From 245cbff080ea69166fe6e3dc7c4ec3eba4fb65b9 Mon Sep 17 00:00:00 2001 From: Sh0g0-1758 Date: Thu, 15 Aug 2024 18:58:28 +0530 Subject: [PATCH 7/8] Added tests --- pkg/hintrunner/core/hint.go | 2 +- pkg/hintrunner/core/hint_test.go | 268 ++++++++++++++++++++++++ pkg/hintrunner/utils/math_utils_test.go | 2 +- 3 files changed, 270 insertions(+), 2 deletions(-) diff --git a/pkg/hintrunner/core/hint.go b/pkg/hintrunner/core/hint.go index 86d96a34..1ffd102b 100644 --- a/pkg/hintrunner/core/hint.go +++ b/pkg/hintrunner/core/hint.go @@ -561,7 +561,7 @@ func (hint U256InvModN) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerConte return fmt.Errorf("write to G1Option address %s: %w", g1OptionAddr, err) } } else if g.Cmp(big.NewInt(1)) != 0 { - if new(big.Int).Rem(&g, big.NewInt(2)) == big.NewInt(0) { + if new(big.Int).Rem(&g, big.NewInt(2)).Cmp(big.NewInt(0)) == 0 { g = *big.NewInt(2) } diff --git a/pkg/hintrunner/core/hint_test.go b/pkg/hintrunner/core/hint_test.go index 0fce1b0e..bf34907c 100644 --- a/pkg/hintrunner/core/hint_test.go +++ b/pkg/hintrunner/core/hint_test.go @@ -455,6 +455,274 @@ func TestDivModDivisionByZeroError(t *testing.T) { require.ErrorContains(t, err, "cannot be divided by zero, rhs: 0") } +func TestU256InvModN(t *testing.T) { + t.Run("test u256InvModN (n == 1)", func(t *testing.T) { + vm := VM.DefaultVirtualMachine() + vm.Context.Ap = 0 + vm.Context.Fp = 0 + + var G0OrNoInv hinter.ApCellRef = 1 + var G1Option hinter.ApCellRef = 2 + var SOrR0 hinter.ApCellRef = 3 + var SOrR1 hinter.ApCellRef = 4 + var TOrK0 hinter.ApCellRef = 5 + var TOrK1 hinter.ApCellRef = 6 + + B0Felt := f.NewElement(0) + B1Felt := f.NewElement(1) + + N0Felt := f.NewElement(1) + N1Felt := f.NewElement(0) + + hint := U256InvModN{ + B0: hinter.Immediate(B0Felt), + B1: hinter.Immediate(B1Felt), + N0: hinter.Immediate(N0Felt), + N1: hinter.Immediate(N1Felt), + G0OrNoInv: G0OrNoInv, + G1Option: G1Option, + SOrR0: SOrR0, + SOrR1: SOrR1, + TOrK0: TOrK0, + TOrK1: TOrK1, + } + + err := hint.Execute(vm, nil) + require.Nil(t, err) + + G0OrNoInvVal := &f.Element{} + _, err = G0OrNoInvVal.SetString("1") + require.Nil(t, err) + + require.Equal( + t, + mem.MemoryValueFromFieldElement(G0OrNoInvVal), + utils.ReadFrom(vm, VM.ExecutionSegment, 1), + ) + + G1OptionVal := &f.Element{} + G1OptionVal.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(G1OptionVal), + utils.ReadFrom(vm, VM.ExecutionSegment, 2), + ) + + SOrR0Val := &f.Element{} + SOrR0Val.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(SOrR0Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 3), + ) + + SOrR1Val := &f.Element{} + _, err = SOrR1Val.SetString("1") + require.Nil(t, err) + + require.Equal( + t, + mem.MemoryValueFromFieldElement(SOrR1Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 4), + ) + + TOrK0Val := &f.Element{} + _, err = TOrK0Val.SetString("1") + require.Nil(t, err) + + require.Equal( + t, + mem.MemoryValueFromFieldElement(TOrK0Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 5), + ) + + TOrK1Val := &f.Element{} + TOrK1Val.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(TOrK1Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 6), + ) + }) + + t.Run("test u256InvModN (g != 1)", func(t *testing.T) { + vm := VM.DefaultVirtualMachine() + vm.Context.Ap = 0 + vm.Context.Fp = 0 + + var G0OrNoInv hinter.ApCellRef = 1 + var G1Option hinter.ApCellRef = 2 + var SOrR0 hinter.ApCellRef = 3 + var SOrR1 hinter.ApCellRef = 4 + var TOrK0 hinter.ApCellRef = 5 + var TOrK1 hinter.ApCellRef = 6 + + B0Felt := f.NewElement(2004) + B1Felt := f.NewElement(0) + + N0Felt := f.NewElement(100) + N1Felt := f.NewElement(0) + + hint := U256InvModN{ + B0: hinter.Immediate(B0Felt), + B1: hinter.Immediate(B1Felt), + N0: hinter.Immediate(N0Felt), + N1: hinter.Immediate(N1Felt), + G0OrNoInv: G0OrNoInv, + G1Option: G1Option, + SOrR0: SOrR0, + SOrR1: SOrR1, + TOrK0: TOrK0, + TOrK1: TOrK1, + } + + err := hint.Execute(vm, nil) + require.Nil(t, err) + + G0OrNoInvVal := &f.Element{} + _, err = G0OrNoInvVal.SetString("2") + require.Nil(t, err) + + require.Equal( + t, + mem.MemoryValueFromFieldElement(G0OrNoInvVal), + utils.ReadFrom(vm, VM.ExecutionSegment, 1), + ) + + G1OptionVal := &f.Element{} + G1OptionVal.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(G1OptionVal), + utils.ReadFrom(vm, VM.ExecutionSegment, 2), + ) + + SOrR0Val := &f.Element{} + _, err = SOrR0Val.SetString("1002") + require.Nil(t, err) + + require.Equal( + t, + mem.MemoryValueFromFieldElement(SOrR0Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 3), + ) + + SOrR1Val := &f.Element{} + SOrR1Val.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(SOrR1Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 4), + ) + + TOrK0Val := &f.Element{} + _, err = TOrK0Val.SetString("50") + require.Nil(t, err) + + require.Equal( + t, + mem.MemoryValueFromFieldElement(TOrK0Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 5), + ) + + TOrK1Val := &f.Element{} + TOrK1Val.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(TOrK1Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 6), + ) + }) + + t.Run("test u256InvModN (n != 1 and g == 1)", func(t *testing.T) { + vm := VM.DefaultVirtualMachine() + vm.Context.Ap = 0 + vm.Context.Fp = 0 + + var G0OrNoInv hinter.ApCellRef = 1 + var G1Option hinter.ApCellRef = 2 + var SOrR0 hinter.ApCellRef = 3 + var SOrR1 hinter.ApCellRef = 4 + var TOrK0 hinter.ApCellRef = 5 + var TOrK1 hinter.ApCellRef = 6 + + B0Felt := f.NewElement(3) + B1Felt := f.NewElement(0) + + N0Felt := f.NewElement(2) + N1Felt := f.NewElement(0) + + hint := U256InvModN{ + B0: hinter.Immediate(B0Felt), + B1: hinter.Immediate(B1Felt), + N0: hinter.Immediate(N0Felt), + N1: hinter.Immediate(N1Felt), + G0OrNoInv: G0OrNoInv, + G1Option: G1Option, + SOrR0: SOrR0, + SOrR1: SOrR1, + TOrK0: TOrK0, + TOrK1: TOrK1, + } + + err := hint.Execute(vm, nil) + require.Nil(t, err) + + G0OrNoInvVal := &f.Element{} + G0OrNoInvVal.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(G0OrNoInvVal), + utils.ReadFrom(vm, VM.ExecutionSegment, 1), + ) + + SOrR0Val := &f.Element{} + _, err = SOrR0Val.SetString("1") + require.Nil(t, err) + + require.Equal( + t, + mem.MemoryValueFromFieldElement(SOrR0Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 3), + ) + + SOrR1Val := &f.Element{} + SOrR1Val.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(SOrR1Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 4), + ) + + TOrK0Val := &f.Element{} + _, err = TOrK0Val.SetString("1") + require.Nil(t, err) + + require.Equal( + t, + mem.MemoryValueFromFieldElement(TOrK0Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 5), + ) + + TOrK1Val := &f.Element{} + TOrK1Val.SetZero() + + require.Equal( + t, + mem.MemoryValueFromFieldElement(TOrK1Val), + utils.ReadFrom(vm, VM.ExecutionSegment, 6), + ) + }) +} + func TestUint256DivMod(t *testing.T) { t.Run("test uint256DivMod", func(t *testing.T) { vm := VM.DefaultVirtualMachine() diff --git a/pkg/hintrunner/utils/math_utils_test.go b/pkg/hintrunner/utils/math_utils_test.go index 8ad73cac..3c1a0a60 100644 --- a/pkg/hintrunner/utils/math_utils_test.go +++ b/pkg/hintrunner/utils/math_utils_test.go @@ -98,7 +98,7 @@ func TestIgcdex(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - actualX, actualY, actualG := igcdex(tt.a, tt.b) + actualX, actualY, actualG := Igcdex(tt.a, tt.b) if actualX.Cmp(tt.expectedX) != 0 { t.Errorf("got x: %v, want: %v", actualX, tt.expectedX) From db48970959ba6edd626e08720c6699758fe6e26d Mon Sep 17 00:00:00 2001 From: Sh0g0-1758 Date: Wed, 21 Aug 2024 21:13:27 +0530 Subject: [PATCH 8/8] nit --- pkg/hintrunner/core/hint_test.go | 33 +++++++++++--------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/pkg/hintrunner/core/hint_test.go b/pkg/hintrunner/core/hint_test.go index 23c5fe56..82bf52ff 100644 --- a/pkg/hintrunner/core/hint_test.go +++ b/pkg/hintrunner/core/hint_test.go @@ -491,8 +491,7 @@ func TestU256InvModN(t *testing.T) { require.Nil(t, err) G0OrNoInvVal := &f.Element{} - _, err = G0OrNoInvVal.SetString("1") - require.Nil(t, err) + G0OrNoInvVal.SetInt64(1) require.Equal( t, @@ -519,8 +518,7 @@ func TestU256InvModN(t *testing.T) { ) SOrR1Val := &f.Element{} - _, err = SOrR1Val.SetString("1") - require.Nil(t, err) + SOrR1Val.SetInt64(1) require.Equal( t, @@ -529,8 +527,7 @@ func TestU256InvModN(t *testing.T) { ) TOrK0Val := &f.Element{} - _, err = TOrK0Val.SetString("1") - require.Nil(t, err) + TOrK0Val.SetInt64(1) require.Equal( t, @@ -583,8 +580,7 @@ func TestU256InvModN(t *testing.T) { require.Nil(t, err) G0OrNoInvVal := &f.Element{} - _, err = G0OrNoInvVal.SetString("2") - require.Nil(t, err) + G0OrNoInvVal.SetInt64(2) require.Equal( t, @@ -602,8 +598,7 @@ func TestU256InvModN(t *testing.T) { ) SOrR0Val := &f.Element{} - _, err = SOrR0Val.SetString("1002") - require.Nil(t, err) + SOrR0Val.SetInt64(1002) require.Equal( t, @@ -621,8 +616,7 @@ func TestU256InvModN(t *testing.T) { ) TOrK0Val := &f.Element{} - _, err = TOrK0Val.SetString("50") - require.Nil(t, err) + TOrK0Val.SetInt64(50) require.Equal( t, @@ -684,8 +678,7 @@ func TestU256InvModN(t *testing.T) { ) SOrR0Val := &f.Element{} - _, err = SOrR0Val.SetString("1") - require.Nil(t, err) + SOrR0Val.SetInt64(1) require.Equal( t, @@ -703,8 +696,7 @@ func TestU256InvModN(t *testing.T) { ) TOrK0Val := &f.Element{} - _, err = TOrK0Val.SetString("1") - require.Nil(t, err) + TOrK0Val.SetInt64(1) require.Equal( t, @@ -755,8 +747,7 @@ func TestUint256DivMod(t *testing.T) { require.Nil(t, err) quotient0Val := &f.Element{} - _, err = quotient0Val.SetString("10") - require.Nil(t, err) + quotient0Val.SetInt64(10) require.Equal( t, @@ -775,8 +766,7 @@ func TestUint256DivMod(t *testing.T) { ) remainder0Val := &f.Element{} - _, err = remainder0Val.SetString("59") - require.Nil(t, err) + remainder0Val.SetInt64(59) require.Equal( t, @@ -785,8 +775,7 @@ func TestUint256DivMod(t *testing.T) { ) remainder1Val := &f.Element{} - _, err = remainder1Val.SetString("2") - require.Nil(t, err) + remainder1Val.SetInt64(2) require.Equal( t,