Skip to content

Instantly share code, notes, and snippets.

@Pet3ris
Created December 26, 2021 18:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pet3ris/5d0f3c094a9ec99aff54025a790aa0a7 to your computer and use it in GitHub Desktop.
Save Pet3ris/5d0f3c094a9ec99aff54025a790aa0a7 to your computer and use it in GitHub Desktop.
Bitwise packing & unpacking in cairo
%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
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