starkware-libs / cairo

Cairo is the first Turing-complete language for creating provable programs for general computation.
Apache License 2.0
1.6k stars 495 forks source link

feat: u64 Byte reverse #3589

Open feltroidprime opened 1 year ago

feltroidprime commented 1 year ago

Hello!

reverse endianness of u64 is useful in many cases when dealing with keccak

I wanted to implement it based off this https://github.com/starkware-libs/cairo-lang/blob/3a32740d0a743af6f4bfe227d1b5ecab0fc2884b/src/starkware/cairo/common/uint256.cairo#L464-L510

with 3 steps instead of 4

fn u64_byte_reverse(word: u64) -> u64 {
    let word: u128 = word.into();
    let word = (word & 0x00ff00ff00ff00ff00ff00ff00ff00ff) * (65535) + word;
    let word = (word & 0x00ffff0000ffff0000ffff0000ffff00) * (4294967295) + word;
    let word = (word & 0x0fffffffffffffff0000000000000000) * (18446744073709551615) + word;

    return (word / (72057594037927936)).try_into().unwrap();
}

the problem is that & is not implemented on felt252 and u128 isn't large enough and gives mul overflow

is it possible to add a u64_byte_reverse in the integer core lib ?

thanks!!

orizi commented 1 year ago

we should add these for additional types - but currently you can rather efficiently implement by:

fn u64_byte_reverse(word: u64) -> u64 {
    (u128_byte_reverse(word.into()) / 0x10000000000000000).try_into().unwrap()
}