Skip to content

Commit

Permalink
SplitOutput0
Browse files Browse the repository at this point in the history
  • Loading branch information
TAdev0 committed Jul 1, 2024
1 parent 6d939e4 commit 2c3dd51
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions pkg/hintrunner/zero/hintcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ ids.multiplicities = segments.gen_arg([len(positions_dict[k]) for k in output])`
blockPermutationCode string = "from starkware.cairo.common.keccak_utils.keccak_utils import keccak_func\n_keccak_state_size_felts = int(ids.KECCAK_STATE_SIZE_FELTS)\nassert 0 <= _keccak_state_size_felts < 100\noutput_values = keccak_func(memory.get_range(\nids.keccak_ptr - _keccak_state_size_felts, _keccak_state_size_felts))\nsegments.write_arg(ids.keccak_ptr, output_values)"
compareBytesInWordCode string = "memory[ap] = to_felt_or_relocatable(ids.n_bytes < ids.BYTES_IN_WORD)"
compareKeccakFullRateInBytesCode string = "memory[ap] = to_felt_or_relocatable(ids.n_bytes >= ids.KECCAK_FULL_RATE_IN_BYTES)"
splitOutput0Code string = "ids.output0_low = ids.output0 & ((1 << 128) - 1)\nids.output0_high = ids.output0 >> 128"

// ------ Dictionaries hints related code ------
dictNewCode string = "if '__dict_manager' not in globals():\n from starkware.cairo.common.dict import DictManager\n __dict_manager = DictManager()\n\nmemory[ap] = __dict_manager.new_dict(segments, initial_dict)\ndel initial_dict"
Expand Down
2 changes: 2 additions & 0 deletions pkg/hintrunner/zero/zerohint.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint, hintPC uint64
return createBlockPermutationHinter(resolver)
case compareBytesInWordCode:
return createCompareBytesInWordNondetHinter(resolver)
case splitOutput0Code:
return createSplitOutput0Hinter(resolver)
// Usort hints
case usortEnterScopeCode:
return createUsortEnterScopeHinter()
Expand Down
75 changes: 75 additions & 0 deletions pkg/hintrunner/zero/zerohint_keccak.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,3 +572,78 @@ func createCompareBytesInWordNondetHinter(resolver hintReferenceResolver) (hinte

return newCompareBytesInWordHint(nBytes), nil
}

// SplitOutput0 hint splits `output0` into `output0_low` (16 bytes) and `output0_high` (9 bytes)
//
// `newSplitOutput0Hint` takes 3 operanders as arguments
// - `output0_low` is the variable that will store the low part of `output0`
// - `output0_high` is the variable that will store the high part of `output0`
// - `output0` is the value to split
func newSplitOutput0Hint(output0Low, output0High, output0 hinter.ResOperander) hinter.Hinter {
return &GenericZeroHinter{
Name: "SplitOutput0",
Op: func(vm *VM.VirtualMachine, _ *hinter.HintRunnerContext) error {
//> ids.output0_low = ids.output0 & ((1 << 128) - 1)
//> ids.output0_high = ids.output0 >> 128

output0LowAddr, err := output0Low.GetAddress(vm)
if err != nil {
return err
}

output0HighAddr, err := output0High.GetAddress(vm)
if err != nil {
return err
}

output0, err := hinter.ResolveAsFelt(vm, output0)
if err != nil {
return err
}

output0Uint := uint256.Int(output0.Bits())

var output0Low uint256.Int
mask := new(uint256.Int).Lsh(uint256.NewInt(1), 128)
mask.Sub(mask, uint256.NewInt(1))
output0Low.And(&output0Uint, mask)
output0LowBytes := output0Low.Bytes()
output0LowFelt := fp.Element{}
output0LowFelt.SetBytes(output0LowBytes)
output0LowMv := memory.MemoryValueFromFieldElement(&output0LowFelt)

var output0High uint256.Int
output0High.Rsh(&output0Uint, 128)
output0HighBytes := output0High.Bytes()
output0HighFelt := fp.Element{}
output0HighFelt.SetBytes(output0HighBytes)
output0HighMv := memory.MemoryValueFromFieldElement(&output0HighFelt)

err = vm.Memory.WriteToAddress(&output0LowAddr, &output0LowMv)
if err != nil {
return err
}

return vm.Memory.WriteToAddress(&output0HighAddr, &output0HighMv)
},
}
}

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

output0High, err := resolver.GetResOperander("output0_high")
if err != nil {
return nil, err
}

output0, err := resolver.GetResOperander("output0")
if err != nil {
return nil, err
}

return newSplitOutput0Hint(output0Low, output0High, output0), nil
}

0 comments on commit 2c3dd51

Please sign in to comment.