Skip to content

Commit

Permalink
no limbs
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Jan 8, 2025
1 parent afe1706 commit ca3ec19
Showing 1 changed file with 18 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use dep::protocol_types::{constants::POW64, traits::{Deserialize, Serialize}};
use dep::protocol_types::traits::{Deserialize, Serialize};
use std::cmp::min;

mod test;
Expand Down Expand Up @@ -127,38 +127,28 @@ impl<let INITIAL_DELAY: u32> ScheduledDelayChange<INITIAL_DELAY> {

impl<let INITIAL_DELAY: u32> Serialize<1> for ScheduledDelayChange<INITIAL_DELAY> {
fn serialize(self) -> [Field; 1] {
// We represent the values in two u64 limbs and then we pack them into a single Field.
// Low limb: [ pre_inner: u32 | post_inner: u32 ]
// High limb: [ empty | pre_is_some: u8 | post_is_some: u8 | block_of_change: u32 ]
let lo = ((self.pre.unwrap_unchecked() as u64) * (1 << 32))
+ (self.post.unwrap_unchecked() as u64);

let hi = (self.pre.is_some() as u64) * (1 << 33)
+ (self.post.is_some() as u64 * (1 << 32))
+ self.block_of_change as u64;

let packed = lo as Field + (hi as Field) * POW64;

[packed]
// Pack all values directly into a single Field:
// [pre_inner: 32 bits | post_inner: 32 bits | block_of_change: 32 bits | post_is_some: 1 bit | pre_is_some: 1 bit]
let packed = U128::from_integer(self.pre.unwrap_unchecked())
+ (U128::from_integer(self.post.unwrap_unchecked()) << 32)
+ (U128::from_integer(self.block_of_change) << 64)
+ (U128::from_integer(self.post.is_some()) << 96)
+ (U128::from_integer(self.pre.is_some()) << 97);

[packed.to_integer()]
}
}

impl<let INITIAL_DELAY: u32> Deserialize<1> for ScheduledDelayChange<INITIAL_DELAY> {
fn deserialize(input: [Field; 1]) -> Self {
let packed = input[0];

// We unpack the limbs from the Field.
let lo = packed as u64;
let hi = ((packed - lo as Field) / POW64) as u64;

// We use division and modulo to clear the bits that correspond to other values when unpacking.
let pre_is_some = (hi / (1 << 33)) as bool;
let pre_inner = (lo / (1 << 32)) as u32;

let post_is_some = ((hi / (1 << 32)) % (1 << 1)) as bool;
let post_inner = (lo % (1 << 32)) as u32;

let block_of_change = (hi % (1 << 32)) as u32;
let packed = U128::from_field(input[0]);

// We unpack the values from the Field
let pre_inner = packed.to_integer() as u32;
let post_inner = (packed >> 32).to_integer() as u32;
let block_of_change = (packed >> 64).to_integer() as u32;
let post_is_some = (packed >> 96).to_integer() & 1 == 1;
let pre_is_some = (packed >> 97).to_integer() & 1 == 1;

Self {
pre: if pre_is_some {
Expand Down

0 comments on commit ca3ec19

Please sign in to comment.