Skip to content

Commit

Permalink
Implement UnsafeKeccak
Browse files Browse the repository at this point in the history
  • Loading branch information
fmoletta committed Sep 19, 2023
1 parent 60d7b72 commit d7a7693
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkg/hints/keccak_hint_codes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package hints

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')"
69 changes: 69 additions & 0 deletions pkg/hints/keccak_hints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package hints

import (
. "github.com/lambdaclass/cairo-vm.go/pkg/hints/hint_utils"
. "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/pkg/errors"
"golang.org/x/crypto/sha3"
)

func unsafeKeccak(ids IdsManager, vm *VirtualMachine, scopes ExecutionScopes) error {
// Fetch ids variable
lengthFelt, err := ids.GetFelt("length", vm)
if err != nil {
return err
}
length, err := lengthFelt.ToU64()
if err != nil {
return err
}
data, err := ids.GetRelocatable("data", vm)
if err != nil {
return err
}
// Check __keccak_max_size if available
keccakMaxSizeAny, err := scopes.Get("__keccak_max_size")
if err == nil {
keccakMaxSize, ok := keccakMaxSizeAny.(uint64)
if ok {
if length > keccakMaxSize {
return errors.Errorf("unsafe_keccak() can only be used with length<=%d. Got: length=%d", keccakMaxSize, length)
}
}
}
keccakInput := make([]byte, 0)
for byteIdx, wordIdx := 0, 0; byteIdx < int(length); byteIdx, wordIdx = byteIdx+16, wordIdx+1 {
wordAddr := data.AddUint(uint(wordIdx))
word, err := vm.Segments.Memory.GetFelt(wordAddr)
if err != nil {
return err
}
nBytes := int(length) - byteIdx
if nBytes > 16 {
nBytes = 16
}

if int(word.Bits()) > 8*nBytes {
return errors.Errorf("Invalid word size: %s", word.ToHexString())
}

start := 32 - nBytes
keccakInput = append(keccakInput, word.ToBeBytes()[start:]...)

}

hasher := sha3.New256()
resBytes := hasher.Sum(keccakInput)

high := FeltFromBeBytes((*[32]byte)(resBytes[:16]))
low := FeltFromBeBytes((*[32]byte)(resBytes[16:32]))

err = ids.Insert("high", NewMaybeRelocatableFelt(high), vm)
if err != nil {
return err
}
return ids.Insert("low", NewMaybeRelocatableFelt(low), vm)
}

0 comments on commit d7a7693

Please sign in to comment.