Skip to content

Instantly share code, notes, and snippets.

@swapnilraj
Created June 1, 2022 17:25
Show Gist options
  • Save swapnilraj/a978e95995fd4638f485ac2b74c6f6ec to your computer and use it in GitHub Desktop.
Save swapnilraj/a978e95995fd4638f485ac2b74c6f6ec to your computer and use it in GitHub Desktop.
%lang starknet
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.cairo_keccak.keccak import keccak_uint256s, finalize_keccak, keccak_uint256s_bigend
rom starkware.cairo.common.math import split_felt
from starkware.cairo.common.math_cmp import is_le_felt
from starkware.cairo.common.uint256 import Uint256, uint256_shl, uint256_add
func felt_to_uint256{range_check_ptr}(x) -> (x_ : Uint256):
let split = split_felt(x)
return (Uint256(low=split.low, high=split.high))
end
@external
func warp_keccak{range_check_ptr, bitwise_ptr : BitwiseBuiltin*}(input_len: felt, input: felt*) ->
(output: Uint256):
alloc_locals
let (packed_len, packed_bytes: Uint256*) = pack_bytes(input_len, input)
let (local keccak_ptr_start) = alloc()
let keccak_ptr = keccak_ptr_start
let (res) = keccak_uint256s{keccak_ptr=keccak_ptr}(n_elements=packed_len,
elements=packed_bytes)
finalize_keccak(keccak_ptr_start=keccak_ptr_start, keccak_ptr_end=keccak_ptr)
return (res)
end
@external
func pack_bytes{range_check_ptr}(input_len: felt, input: felt*) ->
(packed_bytes_len: felt, packed_bytes: Uint256*):
alloc_locals
let (bytes_buffer : Uint256*) = alloc()
let (index) = pack_bytes_inner(0, bytes_buffer, input_len, input)
return (index + 1, bytes_buffer)
end
func min{range_check_ptr}(a: felt, b: felt) -> (res: felt):
alloc_locals
let (a_less_b) = is_le_felt(a, b):
if a_less_b == 1:
return (a)
else
return (b)
else
end
func pack_bytes_inner{range_check_ptr}(index: felt, bytes_buffer: Uint256*, input_len: felt, input: felt*) ->
(index: felt):
alloc_locals
let (chunk_size) = min(input_len, 32)
let (chunk_unaligned) = is_le_felt(input_len, 32)
if chunk_unaligned == 1:
# let (padding_high_bit) = felt_to_uint256(((32 - input_len) * 8 ) - 1)
# let (padding) = uint256_shl(Uint256(low=1, high=0), padding_high_bit)
# let (padding, _) = uint256_add(padding, Uint256(1,0))
let (packed_byte: Uint256) = pack_bytes_in_uint256(0, chunk_size, input, Uint256(0,0))
assert bytes_buffer[index] = packed_byte
return (index)
else:
let (packed_byte: Uint256) = pack_bytes_in_uint256(0, chunk_size, input, Uint256(0,0))
assert bytes_buffer[index] = packed_byte
return pack_bytes_inner(0, bytes_buffer, input_len - 32, input + 32)
end
end
func pack_bytes_in_uint256{range_check_ptr}(byte_index: felt, input_len: felt, input: felt*, byte_buffer: Uint256) -> (packed_byte: Uint256):
alloc_locals
if byte_index == input_len:
return (byte_buffer)
end
let (byte) = felt_to_uint256(input[byte_index])
let (shift_offset : Uint256) = felt_to_uint256(248 - (8 * byte_index))
let (shifted_val : Uint256) = uint256_shl(byte, shift_offset)
let (byte_buffer, _) = uint256_add(byte_buffer, shifted_val)
return pack_bytes_in_uint256(byte_index + 1, input_len, input, byte_buffer)
end
import os
import pytest
from starkware.starknet.testing.starknet import Starknet
# The path to the contract source code.
CONTRACT_FILE = os.path.join(
os.path.dirname(__file__), "test.cairo")
@pytest.mark.asyncio
async def test_address():
starknet = await Starknet.empty()
# Deploy the contract.
contract = await starknet.deploy(
source=CONTRACT_FILE, cairo_path=[]
)
res = await contract.warp_keccak([0xff, 0xff]).invoke()
print(res)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment