Skip to content

Commit

Permalink
Bigint pack div mod test
Browse files Browse the repository at this point in the history
  • Loading branch information
mmsc2 committed Sep 28, 2023
1 parent e6f8acc commit 7522950
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 2 deletions.
56 changes: 56 additions & 0 deletions pkg/hints/bigint_hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,59 @@ func SafeDivBigint(vm *VirtualMachine, execScopes *ExecutionScopes, idsData IdsM

return nil
}

func calculateX(vm *VirtualMachine, idsData IdsManager) (big.Int, error) {
x_bigint5, err := LimbsFromVarName(5, "x", idsData, vm)
if err != nil {
return big.Int{}, err
}
// pack only takes the first three limbs
x0 := x_bigint5[0]
x1 := x_bigint5[1]
x2 := x_bigint5[2]
var limbs = []lambdaworks.Felt{x0, x1, x2}

x_lower := BigInt3{Limbs: limbs}
x_lower_bigint := x_lower.Pack86()

d3 := x_bigint5[3].ToSigned()
d4 := x_bigint5[4].ToSigned()

base := BASE()
d3.Mul(d3, base.Exp(&base, big.NewInt(3), nil))
d4.Mul(d4, base.Exp(&base, big.NewInt(4), nil))

x_lower_bigint.Add(&x_lower_bigint, d3)
x_lower_bigint.Add(&x_lower_bigint, d4)

return x_lower_bigint, nil
}

func bigintPackDivMod(vm *VirtualMachine, execScopes *ExecutionScopes, idsData IdsManager) error {

pUnpack, err := BigInt3FromVarName("P", idsData, vm)
if err != nil {
return err
}
p := pUnpack.Pack86()

x, err := calculateX(vm, idsData)
if err != nil {
return err
}

yUnpacked, err := BigInt3FromVarName("y", idsData, vm)
if err != nil {
return err
}
y := yUnpacked.Pack86()

res, _ := new(big.Int).DivMod(&x, &y, &p)
execScopes.AssignOrUpdateVariable("res", *res)
execScopes.AssignOrUpdateVariable("value", *res)
execScopes.AssignOrUpdateVariable("x", x)
execScopes.AssignOrUpdateVariable("y", y)
execScopes.AssignOrUpdateVariable("p", p)

return nil
}
114 changes: 114 additions & 0 deletions pkg/hints/bigint_hint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
. "github.com/lambdaclass/cairo-vm.go/pkg/types"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm"
"github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
)

Expand Down Expand Up @@ -134,5 +135,118 @@ func TestSafeDivBigInt(t *testing.T) {
if expectedVal.Cmp(&value) != 0 {
t.Errorf("incorrect value expected: %s, got: %s", expectedVal.Text(10), value.Text(10))
}

// check memory
addr := memory.NewRelocatable(1, 0)
val, _ := vm.Segments.Memory.GetFelt(addr)

if val != lambdaworks.FeltFromUint(1) {
t.Errorf("incorrect value fetched from memory")
}
}
}

func TestBigintPackDivModHint(t *testing.T) {
vm := NewVirtualMachine()

vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()
vm.Segments.AddSegment()

vm.RunContext.Fp = NewRelocatable(1, 0)
idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"x": {
NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x38a23ca66202c8c2a72277")),
NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x6730e765376ff17ea8385")),
NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(0)),
NewMaybeRelocatableFelt(lambdaworks.FeltFromUint(0)),
},
"y": {
NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x20a4b46d3c5e24cda81f22")),
NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x967bf895824330d4273d0")),
NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x541e10c21560da25ada4c")),
},
"P": {
NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x8a03bbfd25e8cd0364141")),
NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0x3ffffffffffaeabb739abd")),
NewMaybeRelocatableFelt(lambdaworks.FeltFromHex("0xfffffffffffffffffffff")),
},
},
vm,
)

execScopes := NewExecutionScopes()

hintProcessor := CairoVmHintProcessor{}
hintData := any(HintData{
Ids: idsManager,
Code: BIGINT_PACK_DIV_MOD,
})

err := hintProcessor.ExecuteHint(vm, &hintData, nil, execScopes)

if err != nil {
t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err)
} else {
expected, _ := new(big.Int).SetString("109567829260688255124154626727441144629993228404337546799996747905569082729709", 10)
yExpected, _ := new(big.Int).SetString("38047400353360331012910998489219098987968251547384484838080352663220422975266", 10)
xExpected, _ := new(big.Int).SetString("91414600319290532004473480113251693728834511388719905794310982800988866814583", 10)
pExpected, _ := new(big.Int).SetString("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10)

// fetch values
resu, err := execScopes.Get("res")
if err != nil {
t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err)
}
res := resu.(big.Int)

valu, err := execScopes.Get("value")
if err != nil {
t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err)
}
value := valu.(big.Int)

yu, err := execScopes.Get("y")
if err != nil {
t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err)
}
y := yu.(big.Int)

xu, err := execScopes.Get("x")
if err != nil {
t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err)
}
x := xu.(big.Int)

pu, err := execScopes.Get("p")
if err != nil {
t.Errorf("BIGINT_PACK_DIV_MOD test failed with error: %s", err)
}
p := pu.(big.Int)

if res.Cmp(expected) != 0 {
t.Errorf("incorrect res expected: %s, got: %s", expected.Text(10), expected.Text(10))
}
if value.Cmp(expected) != 0 {
t.Errorf("incorrect value expected: %s, got: %s", value.Text(10), expected.Text(10))
}
if y.Cmp(yExpected) != 0 {
t.Errorf("incorrect y expected: %s, got: %s", yExpected.Text(10), y.Text(10))
}
if x.Cmp(xExpected) != 0 {
t.Errorf("incorrect x expected: %s, got: %s", xExpected.Text(10), x.Text(10))
}
if p.Cmp(pExpected) != 0 {
t.Errorf("incorrect p expected: %s, got: %s", pExpected.Text(10), p.Text(10))
}
}
}
1 change: 0 additions & 1 deletion pkg/hints/ec_hint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ func TestRunComputeSlopeV2Ok(t *testing.T) {
idsManager := SetupIdsForTest(
map[string][]*MaybeRelocatable{
"point0": {

NewMaybeRelocatableFelt(FeltFromUint64(512)),
NewMaybeRelocatableFelt(FeltFromUint64(2412)),
NewMaybeRelocatableFelt(FeltFromUint64(133)),
Expand Down
1 change: 1 addition & 0 deletions pkg/hints/hint_codes/ec_op_hints.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P"`
const FAST_EC_ADD_ASSIGN_NEW_Y = "value = new_y = (slope * (x0 - new_x) - y0) % SECP_P"

const BIGINT_SAFE_DIV = "k = safe_div(res * y - x, p)\nvalue = k if k > 0 else 0 - k\nids.flag = 1 if k > 0 else 0"
const BIGINT_PACK_DIV_MOD = "from starkware.cairo.common.cairo_secp.secp_utils import pack\nfrom starkware.cairo.common.math_utils import as_int\nfrom starkware.python.math_utils import div_mod, safe_div\n\np = pack(ids.P, PRIME)\nx = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4\ny = pack(ids.y, PRIME)\n\nvalue = res = div_mod(x, y, p)"
2 changes: 2 additions & 0 deletions pkg/hints/hint_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any,
return fastEcAddAssignNewY(execScopes)
case BIGINT_SAFE_DIV:
return SafeDivBigint(vm, execScopes, data.Ids)
case BIGINT_PACK_DIV_MOD:
return bigintPackDivMod(vm, execScopes, data.Ids)
default:
return errors.Errorf("Unknown Hint: %s", data.Code)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/hints/hint_utils/bigint_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
// This file contains an implementation of each behaviour at the limbs level, and the wrappers for each specific type

// Generic methods for all types
func limbsFromVarName(nLimbs int, name string, ids IdsManager, vm *VirtualMachine) ([]Felt, error) {
func LimbsFromVarName(nLimbs int, name string, ids IdsManager, vm *VirtualMachine) ([]Felt, error) {
baseAddr, err := ids.GetAddr(name, vm)
if err != nil {
return nil, err
Expand Down
5 changes: 5 additions & 0 deletions pkg/hints/hint_utils/secp_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import (
"math/big"
)

func BASE() big.Int {
base, _ := new(big.Int).SetString("77371252455336267181195264", 10)
return *base
}

func SECP_P() big.Int {
secpP, _ := new(big.Int).SetString("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10)
return *secpP
Expand Down

0 comments on commit 7522950

Please sign in to comment.