Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 9 additions & 34 deletions src/_string_tools/slice_packed_field.nr
Original file line number Diff line number Diff line change
Expand Up @@ -594,37 +594,11 @@ fn divmod_31(numerator: u16) -> (u16, u16) {
(quotient, remainder)
}

/**
* @brief converts a 16 bit value into 16 fake bools (Field elements that are 0 or 1)
**/
unconstrained fn decompose(val: Field) -> [Field; 16] {
let mut r: [Field; 16] = [0; 16];

let mut it = val as u32;
for i in 0..16 {
r[i] = (it & 1) as Field;
it >>= 1;
}
r
}

// 5 gates?
pub fn get_last_limb_path<let OutputFields: u32>(last_limb_index: Field) -> [Field; OutputFields] {
pub fn get_last_limb_path<let OutputFields: u32>(last_limb_index: Field) -> [u1; OutputFields] {
// TODO we offset by 1 explain why (0 byte length produces 0 - 1 which = invalid array index. we just add 1 and increase array length by 1 to compensate)
let path = LAST_LIMB_PATH[cast_num_to_u32(last_limb_index + 1)]; // 2
// Safety: check the comments below
let path_valid_bits = unsafe { decompose(path) };
let mut path_valid_sum: Field = 0;
let mut path_valid_output: [Field; OutputFields] = [0; OutputFields];
for i in 0..OutputFields {
// we check that the path valid bits are binary
assert(path_valid_bits[i] * path_valid_bits[i] - path_valid_bits[i] == 0);
path_valid_sum += (path_valid_bits[i] * (1 << i as u8) as Field);
path_valid_output[i] = path_valid_bits[i];
}
// we check that the path valid bits sum to the path
assert(path_valid_sum == path);
path_valid_output
path.to_le_bits::<OutputFields>()
}

/**
Expand Down Expand Up @@ -728,13 +702,13 @@ pub fn slice_fields<let InputFields: u32, let OutputFields: u32>(
// 1, 70.5
let index_of_output_limb: Field = (num_bytes_div_31 as Field - num_bytes_mod_31_is_0 as Field);
// 5, 75.5
let path_valid_output: [Field; OutputFields] = get_last_limb_path(index_of_output_limb);
let path_valid_output: [u1; OutputFields] = get_last_limb_path(index_of_output_limb);

// 2, 77.5
let tail_shift = BYTE_SHIFT[cast_num_to_u32(num_unused_bytes_in_start_limb)];

// 51, 128.5
let mut result = [0; OutputFields];
let mut result: [Field; OutputFields] = [0; OutputFields];
let mut previous = tail;
for i in 0..(OutputFields - 1) {
// 0
Expand All @@ -748,9 +722,9 @@ pub fn slice_fields<let InputFields: u32, let OutputFields: u32>(
// 1, 48
let combined = previous * tail_shift + head;
// 1, 49
result[i] = combined * slice_valid;
result[i] = combined * (slice_valid as Field);
// 2, 51
previous = (tail - previous) * slice_valid + previous;
previous = (tail - previous) * (slice_valid as Field) + previous;
}

// 2, 130.5
Expand Down Expand Up @@ -787,9 +761,10 @@ pub fn slice_fields<let InputFields: u32, let OutputFields: u32>(
std::as_witness(last_limb);

let mut path: [Field; OutputFields] = [0; OutputFields];
path[0] = (1 - path_valid_output[0]);
path[0] = (1 - path_valid_output[0] as Field);
for i in 1..OutputFields {
path[i] = path_valid_output[i] * -path_valid_output[i - 1] + path_valid_output[i - 1];
path[i] = path_valid_output[i - 1] as Field
- path_valid_output[i] as Field * path_valid_output[i - 1] as Field;
}

for i in 0..OutputFields {
Expand Down
Loading