Created
December 26, 2021 18:57
-
-
Save Pet3ris/5d0f3c094a9ec99aff54025a790aa0a7 to your computer and use it in GitHub Desktop.
Bitwise packing & unpacking in cairo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%lang starknet | |
%builtins pedersen range_check bitwise | |
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, HashBuiltin | |
from starkware.cairo.common.bitwise import bitwise_and | |
from starkware.cairo.common.math import assert_nn_le | |
const WORD = 2 ** 16 | |
const MASK = WORD - 1 | |
const MASK2 = MASK * WORD | |
@view | |
func pack2{range_check_ptr}(x : felt, y : felt) -> (res : felt): | |
assert_nn_le(x, WORD) # Could be removed as an optimization | |
assert_nn_le(y, WORD) # Could be removed as an optimization | |
return (x * WORD + y) | |
end | |
@view | |
func unpack1{bitwise_ptr : BitwiseBuiltin*}(packed : felt) -> (res : felt): | |
let (masked) = bitwise_and(packed, MASK2) | |
let res = masked / WORD | |
return (res=res) | |
end | |
@view | |
func unpack2{bitwise_ptr : BitwiseBuiltin*}(packed : felt) -> (res : felt): | |
let (res) = bitwise_and(packed, MASK) | |
return (res=res) | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import pytest | |
from starkware.starknet.testing.starknet import Starknet | |
CONTRACT_FILE = os.path.join(os.path.dirname(__file__), "packing.cairo") | |
@pytest.mark.asyncio | |
async def test_bitwise_packing(): | |
starknet = await Starknet.empty() | |
contract = await starknet.deploy( | |
source=CONTRACT_FILE, | |
) | |
a = 2 ** 13 + 1 | |
b = 7 | |
(packed,) = (await contract.pack2(a, b).call()).result | |
assert (await contract.unpack1(packed).call()).result == (a,) | |
assert (await contract.unpack2(packed).call()).result == (b,) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment