diff --git a/pkg/hints/hint_codes/keccak_hint_codes.go b/pkg/hints/hint_codes/keccak_hint_codes.go index 2db053ca..c9cc1ea1 100644 --- a/pkg/hints/hint_codes/keccak_hint_codes.go +++ b/pkg/hints/hint_codes/keccak_hint_codes.go @@ -1,3 +1,5 @@ package hint_codes const UNSAFE_KECCAK = "from eth_hash.auto import keccak\n\ndata, length = ids.data, ids.length\n\nif '__keccak_max_size' in globals():\n assert length <= __keccak_max_size, \\\n f'unsafe_keccak() can only be used with length<={__keccak_max_size}. ' \\\n f'Got: length={length}.'\n\nkeccak_input = bytearray()\nfor word_i, byte_i in enumerate(range(0, length, 16)):\n word = memory[data + word_i]\n n_bytes = min(16, length - byte_i)\n assert 0 <= word < 2 ** (8 * n_bytes)\n keccak_input += word.to_bytes(n_bytes, 'big')\n\nhashed = keccak(keccak_input)\nids.high = int.from_bytes(hashed[:16], 'big')\nids.low = int.from_bytes(hashed[16:32], 'big')" + +const UNSAFE_KECCAK_FINALIZE = "from eth_hash.auto import keccak\nkeccak_input = bytearray()\nn_elms = ids.keccak_state.end_ptr - ids.keccak_state.start_ptr\nfor word in memory.get_range(ids.keccak_state.start_ptr, n_elms):\n keccak_input += word.to_bytes(16, 'big')\nhashed = keccak(keccak_input)\nids.high = int.from_bytes(hashed[:16], 'big')\nids.low = int.from_bytes(hashed[16:32], 'big')" diff --git a/pkg/hints/hint_utils/ids_manager.go b/pkg/hints/hint_utils/ids_manager.go index f883ac5c..fadacfeb 100644 --- a/pkg/hints/hint_utils/ids_manager.go +++ b/pkg/hints/hint_utils/ids_manager.go @@ -162,6 +162,35 @@ func (ids *IdsManager) GetStructFieldFelt(name string, field_off uint, vm *Virtu return lambdaworks.Felt{}, ErrUnknownIdentifier(name) } +/* + Returns the value of an ids' field (given that the identifier is a sruct) as a Relocatable + For example: + + struct shelter { + cats cat* + dogs dog* + } + + to access each struct field, cats will be field 0 and dogs will be field 1, so to access them we can use: + ids_cats := ids.GetStructFieldFelt("shelter", 0, vm) or ids_cats := ids.Get("shelter", vm) + ids_dogs := ids.GetStructFieldFelt("shelter", 1, vm) +*/ +func (ids *IdsManager) GetStructFieldRelocatable(name string, field_off uint, vm *VirtualMachine) (Relocatable, error) { + reference, ok := ids.References[name] + if ok { + val, ok := getStructFieldFromReference(&reference, field_off, ids.HintApTracking, vm) + if ok { + rel, is_rel := val.GetRelocatable() + if !is_rel { + return Relocatable{}, errors.Errorf("Identifier %s is not a Relocatable", name) + } + return rel, nil + } + } + + return Relocatable{}, ErrUnknownIdentifier(name) +} + /* Inserts value into an ids' field (given that the identifier is a sruct) For example: diff --git a/pkg/hints/keccak_hints.go b/pkg/hints/keccak_hints.go index 615e5d06..1ec95b77 100644 --- a/pkg/hints/keccak_hints.go +++ b/pkg/hints/keccak_hints.go @@ -71,3 +71,19 @@ func unsafeKeccak(ids IdsManager, vm *VirtualMachine, scopes ExecutionScopes) er } return ids.Insert("low", NewMaybeRelocatableFelt(low), vm) } + +func unsafeKeccakFinalize(ids IdsManager, vm *VirtualMachine, scopes ExecutionScopes) error { + // Fetch ids variables + startPtr, err := ids.GetStructFieldRelocatable("keccak_state", 0, vm) + if err != nil { + return err + } + endPtr, err := ids.GetStructFieldRelocatable("keccak_state", 1, vm) + if err != nil { + return err + } + n_elems, err := endPtr.Sub(startPtr) + if err != nil { + return err + } +}