Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NondetElementsOverTwo + NondetElementsOverTen( poseidon builtin related hints) #493

Merged
merged 8 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
%builtins poseidon
from starkware.cairo.common.cairo_builtins import PoseidonBuiltin
from starkware.cairo.common.poseidon_state import PoseidonBuiltinState
from starkware.cairo.common.builtin_poseidon.poseidon import (
poseidon_hash,
poseidon_hash_single,
poseidon_hash_many,
)
from starkware.cairo.common.alloc import alloc

func main{poseidon_ptr: PoseidonBuiltin*}() {
// Hash one
let (x) = poseidon_hash_single(
218676008889449692916464780911713710628115973574242889792891157041292792362
);
assert x = 2835120893146788752888137145656423078969524407843035783270702964188823073934;
// Hash two
let (y) = poseidon_hash(1253795, 18540013156130945068);
assert y = 37282360750367388068593128053386029947772104009544220786084510532118246655;
// Hash five
let felts: felt* = alloc();
assert felts[0] = 84175983715088675913672849362079546;
assert felts[1] = 9384720329467203286234076408512594689579283578028960384690;
assert felts[2] = 291883989128409324823849293040390493094093;
assert felts[3] = 5849589438543859348593485948598349584395839402940940290490324;
assert felts[4] = 1836254780028456372728992049476335424263474849;
let (z) = poseidon_hash_many(5, felts);
assert z = 47102513329160951064697157194713013753695317629154835326726810042406974264;
return ();
}
2 changes: 2 additions & 0 deletions pkg/hintrunner/zero/hintcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ const (
vmEnterScopeCode string = "vm_enter_scope()"
vmExitScopeCode string = "vm_exit_scope()"
findElementCode string = "array_ptr = ids.array_ptr\nelm_size = ids.elm_size\nassert isinstance(elm_size, int) and elm_size > 0, \\\n f'Invalid value for elm_size. Got: {elm_size}.'\nkey = ids.key\n\nif '__find_element_index' in globals():\n ids.index = __find_element_index\n found_key = memory[array_ptr + elm_size * __find_element_index]\n assert found_key == key, \\\n f'Invalid index found in __find_element_index. index: {__find_element_index}, ' \\\n f'expected key {key}, found key: {found_key}.'\n # Delete __find_element_index to make sure it's not used for the next calls.\n del __find_element_index\nelse:\n n_elms = ids.n_elms\n assert isinstance(n_elms, int) and n_elms >= 0, \\\n f'Invalid value for n_elms. Got: {n_elms}.'\n if '__find_element_max_size' in globals():\n assert n_elms <= __find_element_max_size, \\\n f'find_element() can only be used with n_elms<={__find_element_max_size}. ' \\\n f'Got: n_elms={n_elms}.'\n\n for i in range(n_elms):\n if memory[array_ptr + elm_size * i] == key:\n ids.index = i\n break\n else:\n raise ValueError(f'Key {key} was not found.')"
nondetElementsOverTWoCode string = "memory[ap] = to_felt_or_relocatable(ids.n >= 2)"
nondetElementsOverTenCode string = "memory[ap] = to_felt_or_relocatable(ids.n >= 10)"
setAddCode string = "assert ids.elm_size > 0\nassert ids.set_ptr <= ids.set_end_ptr\nelm_list = memory.get_range(ids.elm_ptr, ids.elm_size)\nfor i in range(0, ids.set_end_ptr - ids.set_ptr, ids.elm_size):\n if memory.get_range(ids.set_ptr + i, ids.elm_size) == elm_list:\n ids.index = i // ids.elm_size\n ids.is_elm_in_set = 1\n break\nelse:\n ids.is_elm_in_set = 0"
searchSortedLowerCode string = `array_ptr = ids.array_ptr
elm_size = ids.elm_size
Expand Down
4 changes: 4 additions & 0 deletions pkg/hintrunner/zero/zerohint.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint, hintPC uint64
return createTestAssignHinter(resolver)
case findElementCode:
return createFindElementHinter(resolver)
case nondetElementsOverTWoCode:
return createNondetElementsOverTWoHinter(resolver)
case nondetElementsOverTenCode:
return createNondetElementsOverTenHinter(resolver)
default:
return nil, fmt.Errorf("not identified hint")
}
Expand Down
84 changes: 84 additions & 0 deletions pkg/hintrunner/zero/zerohint_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -608,3 +608,87 @@ func createSearchSortedLowerHinter(resolver hintReferenceResolver) (hinter.Hinte

return newSearchSortedLowerHint(arrayPtr, elmSize, nElms, key, index), nil
}

// NondetElementsOverTWo hint compares the offset difference between two memory address and
// writes 1 or 0 at `ap` memory address, depending on whether the difference is greater or
// equal to 2 or not
//
// `newNondetElementsOverTWoHint` takes 2 operanders as arguments
// - `elementsEnd` represents the address in memory right after the last element of the array
// - `elements` represents the address in memory of the first element of the array
func newNondetElementsOverTWoHint(n hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "NondetElementsOverTWo",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
//> python hint in cairo file: "ids.elements_end - ids.elements >= 2"
//> python hint in whitelist: "memory[ap] = to_felt_or_relocatable(ids.elements_end - ids.elements >= 2)"
//> compiled file hint: "memory[ap] = to_felt_or_relocatable(ids.n >= 2)"

n, err := hinter.ResolveAsUint64(vm, n)
Sh0g0-1758 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}

apAddr := vm.Context.AddressAp()
var resultMv memory.MemoryValue
if n >= uint64(2) {
resultMv = memory.MemoryValueFromFieldElement(&utils.FeltOne)
} else {
resultMv = memory.MemoryValueFromFieldElement(&utils.FeltZero)
}

return vm.Memory.WriteToAddress(&apAddr, &resultMv)
},
}
}

func createNondetElementsOverTWoHinter(resolver hintReferenceResolver) (hinter.Hinter, error) {
n, err := resolver.GetResOperander("n")
if err != nil {
return nil, err
}

return newNondetElementsOverTWoHint(n), nil
}

// NondetElementsOverTen hint compares the offset difference between two memory address and
// writes 1 or 0 at `ap` memory address, depending on whether the difference is greater or
// esual to 10 or not
//
// `newNondetElementsOverTenHint` takes 2 operanders as arguments
// - `elementsEnd` represents the address in memory right after the last element of the array
// - `elements` represents the address in memory of the first element of the array
func newNondetElementsOverTenHint(n hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "NondetElementsOverTen",
Op: func(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
//> python hint in cairo file: "ids.elements_end - ids.elements >= 10"
//> python hint in whitelist: "memory[ap] = to_felt_or_relocatable(ids.elements_end - ids.elements >= 10)"
//> compiled file hint: "memory[ap] = to_felt_or_relocatable(ids.n >= 10)"

n, err := hinter.ResolveAsUint64(vm, n)
if err != nil {
return err
}

apAddr := vm.Context.AddressAp()
var resultMv memory.MemoryValue
if n >= uint64(10) {
resultMv = memory.MemoryValueFromFieldElement(&utils.FeltOne)
} else {
resultMv = memory.MemoryValueFromFieldElement(&utils.FeltZero)
}

return vm.Memory.WriteToAddress(&apAddr, &resultMv)
},
}
}

func createNondetElementsOverTenHinter(resolver hintReferenceResolver) (hinter.Hinter, error) {
n, err := resolver.GetResOperander("n")
if err != nil {
return nil, err
}

return newNondetElementsOverTenHint(n), nil
}
48 changes: 48 additions & 0 deletions pkg/hintrunner/zero/zerohint_others_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,5 +531,53 @@ func TestZeroHintOthers(t *testing.T) {
}),
},
},
"NondetElementsOverTwo": {
{
operanders: []*hintOperander{
{Name: "n", Kind: apRelative, Value: feltUint64(1)},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newNondetElementsOverTWoHint(
ctx.operanders["n"],
)
},
check: apValueEquals(feltUint64(0)),
},
{
operanders: []*hintOperander{
{Name: "n", Kind: apRelative, Value: feltUint64(2)},
Sh0g0-1758 marked this conversation as resolved.
Show resolved Hide resolved
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newNondetElementsOverTWoHint(
ctx.operanders["n"],
)
},
check: apValueEquals(feltUint64(1)),
},
},
"NondetElementsOverTen": {
{
operanders: []*hintOperander{
{Name: "n", Kind: apRelative, Value: feltUint64(9)},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newNondetElementsOverTenHint(
ctx.operanders["n"],
)
},
check: apValueEquals(feltUint64(0)),
},
{
operanders: []*hintOperander{
Sh0g0-1758 marked this conversation as resolved.
Show resolved Hide resolved
{Name: "n", Kind: apRelative, Value: feltUint64(10)},
},
makeHinter: func(ctx *hintTestContext) hinter.Hinter {
return newNondetElementsOverTenHint(
ctx.operanders["n"],
)
},
check: apValueEquals(feltUint64(1)),
},
},
})
}
Loading