Skip to content

Commit

Permalink
Improve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
LogvinovLeon committed May 24, 2024
1 parent d7eb9a3 commit 2afbd25
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 62 deletions.
7 changes: 1 addition & 6 deletions ethereum/circuits/lib/src/misc/arrays.nr
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,7 @@ pub(crate) fn memcpy_up_to_length<TItem, SRC_LEN, DEST_LEN>(dest: &mut [TItem; D
}
}

/// Fills destination array with content of source array starting from the starting position.
///
/// # Arguments
/// * `dest` - Destination array
/// * `src` - Source array
/// * `offset` - Offset in source array
// Fills destination array with content of source array starting from the starting position.
pub(crate) fn memcpy<TItem, SRC_LEN, DEST_LEN>(dest: &mut [TItem; DEST_LEN], src: [TItem; SRC_LEN], offset: u64) {
memcpy_up_to_length(dest, src, offset, DEST_LEN);
}
Expand Down
17 changes: 2 additions & 15 deletions ethereum/circuits/lib/src/misc/bytes.nr
Original file line number Diff line number Diff line change
Expand Up @@ -71,32 +71,19 @@ pub fn shift_right_by_one<N>(arr: &mut [u8; N]) {
}
}

/// Left-shift for byte arrays
/// Returns an appropriately shifted byte array.
///
/// # Arguments
/// * `input` - Byte array
/// * `n` - Amount to left-shift elements by
///
/// # Quirks
/// The empty slots are set to 0.
// Left-shift the byte array
pub(crate) fn left_byte_shift<N>(input: [u8; N], n: u64) -> [u8; N] {
let mut out = [0; N];

for i in 0..N {
// Restrict indices to be shifted, i.e. ∀i: i+n < N, out[i] ← input[i+n].
let index_ind = (((i + n) as u32) < (N as u32)) as u64;
out[i] = (index_ind as u8) * input[index_ind * (i + n)];
}

out
}

/// Function for expressing a big-endian byte array as a right-padded one.
/// Returns a right-padded byte array together with the actual byte length of the number.
///
/// # Arguments
/// * `in_value` - Byte array representing a number in big-endian form.
// Converts big-endian byte array to a right-padded one.
pub(crate) fn byte_value<N>(in_value: [u8; N]) -> BoundedVec<u8, N> {
let mut value_length = 0;

Expand Down
43 changes: 19 additions & 24 deletions ethereum/circuits/lib/src/rlp/decode.nr
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use dep::std::wrapping_sub;
use crate::rlp::types::{RlpList, RlpFragment, RlpHeader};
use crate::rlp::types::{RlpList, RlpFragment, RlpHeader, STRING, LIST};
use crate::misc::fragment::Fragment;

/// Max number of bytes required to represent length of a string or list
// Maximum number of bytes required to represent entity length.
// This means that this library can only decode RLP entities with a length of up to 2^16 bytes.
global MAX_LEN_IN_BYTES: u64 = 2;

/// RLP data type enum
global STRING: u64 = 0;
global LIST: u64 = 1;

pub fn extract_payload_len<N>(data: Fragment<N, u8>, lenlen: u64) -> u64 {
assert(lenlen <= MAX_LEN_IN_BYTES, "Length of length exceeds maximum");
assert(lenlen <= data.length, "Length of length exceeds input length");
Expand All @@ -31,25 +28,25 @@ pub fn decode_to_rlp_header<N>(data: Fragment<N, u8>) -> RlpHeader {

if (prefix < 0x80) { // single byte
RlpHeader { offset: 0, length: 1, data_type: STRING }
} else if (prefix < 0xb8) { // 0-55 byte string
} else if (prefix < 0xb8) { // [0, 55] byte string
let offset = 1;
let length = wrapping_sub(prefix, 0x80) as u64;
assert(offset + length <= N, "Decoded length of short string exceeds input length");

RlpHeader { offset, length, data_type: STRING }
} else if (prefix < 0xc0) { // >55-byte string
} else if (prefix < 0xc0) { // > 55 byte string
let offset = wrapping_sub(1 + prefix, 0xb7) as u64;
let length = extract_payload_len(data, wrapping_sub(prefix, 0xb7) as u64);
assert(offset + length <= N, "Decoded length of long string exceeds input length");

RlpHeader { offset, length, data_type: STRING }
} else if (prefix < 0xf8) { // 0-55 byte list
} else if (prefix < 0xf8) { // [0, 55] byte list
let offset = 1;
let length = wrapping_sub(prefix, 0xc0) as u64;
assert(offset + length <= N, "Decoded length of short list exceeds input length");

RlpHeader { offset, length, data_type: LIST }
} else { // >55-byte list
} else { // > 55 byte list
let offset = wrapping_sub(1 + prefix, 0xf7) as u64;
let length = extract_payload_len(data, wrapping_sub(prefix, 0xf7) as u64);
assert(offset + length <= N, "Decoded length of long list exceeds input length");
Expand All @@ -68,9 +65,7 @@ pub fn decode_string<N>(input: Fragment<N, u8>) -> RlpFragment {
RlpFragment { offset, length, data_type: STRING }
}

/// Returns an RLP list look-up table.
/// For string elements, the offset points to the payload, whereas the offset
/// of a list element points to the RLP header of that element.
// Strings are decoded and offsets point to the start of raw values, while list offsets point to the start of the RLP header.
pub fn decode_list<N, MAX_FIELDS>(data: Fragment<N, u8>) -> RlpList<MAX_FIELDS> {
let mut rlp_list: RlpList<MAX_FIELDS> = BoundedVec::new();

Expand All @@ -87,12 +82,15 @@ pub fn decode_list<N, MAX_FIELDS>(data: Fragment<N, u8>) -> RlpList<MAX_FIELDS>

let RlpHeader {offset: field_off, length: field_len, data_type: field_type} = decode_to_rlp_header(header);

let fragment = RlpFragment {
offset: current_offset + (1 - field_type) * field_off, // If the ith slot contains a list, include its RLP header.
length: field_len + field_type * field_off, // If the ith slot contains a list, include the length of its header.
data_type: field_type
};
rlp_list.push(fragment);
let mut offset = current_offset;
let mut length = field_len;
if (field_type == STRING) {
offset += field_off;
} else {
length += field_off;
}

rlp_list.push(RlpFragment { offset, length, data_type: field_type });

current_offset += field_off + field_len;
}
Expand All @@ -102,8 +100,7 @@ pub fn decode_list<N, MAX_FIELDS>(data: Fragment<N, u8>) -> RlpList<MAX_FIELDS>
rlp_list
}

/// RLP list decoder for lists of strings of length < 56 bytes.
/// Returns an RLP list look-up table.
// The version of decode_list that is cheaper to call, but only works for lists of small strings (<= 55 bytes).
pub fn decode_list_of_small_strings<N, NUM_FIELDS>(data: Fragment<N, u8>) -> RlpList<NUM_FIELDS> {
let mut rlp_list: RlpList<NUM_FIELDS> = BoundedVec::new();

Expand All @@ -119,9 +116,7 @@ pub fn decode_list_of_small_strings<N, NUM_FIELDS>(data: Fragment<N, u8>) -> Rlp
let first_byte = data.at(current_offset);

let (field_off, field_len) = get_small_string_offset_and_length(first_byte);

let fragment = RlpFragment { offset: current_offset + field_off, length: field_len, data_type: STRING };
rlp_list.push(fragment);
rlp_list.push(RlpFragment { offset: current_offset + field_off, length: field_len, data_type: STRING });

current_offset += field_off + field_len;
}
Expand Down
8 changes: 4 additions & 4 deletions ethereum/circuits/lib/src/rlp/decode_test.nr
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ mod extract_payload_len {
}

mod decode_string {
use crate::rlp::decode::{decode_string, STRING};
use crate::rlp::{decode::decode_string, types::STRING};
use crate::misc::{arrays::resize, fragment::Fragment};
use crate::rlp::types::RlpFragment;

Expand Down Expand Up @@ -90,7 +90,7 @@ mod decode_string {
}

mod decode_list {
use crate::rlp::{decode::{decode_list, RlpList, STRING}, types::RlpFragment};
use crate::rlp::{decode::{decode_list, RlpList}, types::{RlpFragment, STRING}};
use crate::misc::{bounded_vecs::bounded_vec_from_array, fragment::Fragment};

#[test]
Expand Down Expand Up @@ -134,7 +134,7 @@ mod decode_list {
}

mod decode_list_of_small_strings {
use crate::rlp::decode::{decode_list_of_small_strings, RlpList, RlpFragment, STRING};
use crate::rlp::{decode::{decode_list_of_small_strings, RlpList, RlpFragment}, types::STRING};
use crate::misc::{bounded_vecs::bounded_vec_from_array, fragment::Fragment};

#[test]
Expand Down Expand Up @@ -221,7 +221,7 @@ mod get_small_string_offset_and_length {
}

mod decode_to_rlp_header {
use crate::rlp::decode::{decode_to_rlp_header, RlpHeader, STRING, LIST};
use crate::rlp::{decode::{decode_to_rlp_header, RlpHeader}, types::{STRING, LIST}};
use crate::misc::{arrays::resize, fragment::Fragment};

#[test]
Expand Down
9 changes: 6 additions & 3 deletions ethereum/circuits/lib/src/rlp/types.nr
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use crate::misc::{arrays::sub_array_equals_up_to_length, fragment::Fragment};
use crate::rlp::decode::STRING;
use crate::misc::bytes::byte_value;
use dep::u2b::{u64_to_u8, u32_to_u8};
use crate::misc::types::{Bytes32, BYTES32_LENGTH, Address, ADDRESS_LENGTH};

// Enum for RLP data type
global STRING: u64 = 0;
global LIST: u64 = 1;

type RlpList<MAX_FIELDS> = BoundedVec<RlpFragment, MAX_FIELDS>;

struct RlpHeader {
offset: u64,
length: u64,
data_type: u64 // STRING or LIST
data_type: u64
}

impl Eq for RlpHeader {
Expand All @@ -21,7 +24,7 @@ impl Eq for RlpHeader {
struct RlpFragment {
offset: u64,
length: u64,
data_type: u64 // STRING or LIST
data_type: u64
}

impl RlpFragment {
Expand Down
20 changes: 10 additions & 10 deletions ethereum/circuits/lib/src/rlp/types_test.nr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod rlp_fragment {
mod assert_eq_bytes {
use crate::rlp::{decode::{STRING, LIST}, types::RlpFragment};
use crate::rlp::types::{STRING, LIST, RlpFragment};
use crate::misc::{arrays::alter_fragment, fragment::Fragment};

global bytes = Fragment::new_with_length(2, [0x12, 0x34, 0x00]);
Expand Down Expand Up @@ -42,7 +42,7 @@ mod rlp_fragment {
}

mod assert_eq_bounded_vec {
use crate::rlp::{decode::{STRING, LIST}, types::RlpFragment};
use crate::rlp::types::{STRING, LIST, RlpFragment};
use crate::misc::{arrays::alter_array, fragment::Fragment};

global bytes = [0x12, 0x34];
Expand Down Expand Up @@ -82,7 +82,7 @@ mod rlp_fragment {
}

mod assert_empty_string {
use crate::rlp::{decode::{STRING, LIST}, types::RlpFragment};
use crate::rlp::types::{STRING, LIST, RlpFragment};

global fragment = RlpFragment { offset: 0, length: 0, data_type: STRING };

Expand All @@ -109,7 +109,7 @@ mod rlp_fragment {
}

mod assert_eq_u1 {
use crate::rlp::{decode::STRING, types::RlpFragment};
use crate::rlp::types::{STRING, RlpFragment};
use crate::misc::fragment::Fragment;

global bit_value: u1 = 0x01;
Expand Down Expand Up @@ -142,7 +142,7 @@ mod rlp_fragment {
}

mod assert_eq_u8 {
use crate::rlp::{decode::STRING, types::RlpFragment};
use crate::rlp::types::{STRING, RlpFragment};
use crate::misc::fragment::Fragment;

global value = 0x10;
Expand All @@ -169,7 +169,7 @@ mod rlp_fragment {
}

mod assert_eq_u32 {
use crate::rlp::{decode::STRING, types::RlpFragment};
use crate::rlp::types::{STRING, RlpFragment};
use crate::misc::fragment::Fragment;

global value = 0x10000000;
Expand All @@ -194,7 +194,7 @@ mod rlp_fragment {
}

mod assert_eq_u64 {
use crate::rlp::{decode::STRING, types::RlpFragment};
use crate::rlp::types::{STRING, RlpFragment};
use crate::misc::fragment::Fragment;

global value = 0x1000000000000000;
Expand All @@ -219,7 +219,7 @@ mod rlp_fragment {
}

mod assert_eq_u128 {
use crate::rlp::{decode::STRING, types::RlpFragment};
use crate::rlp::types::{STRING, RlpFragment};
use crate::misc::fragment::Fragment;

global value = U128::from_integer(0x10000000000000000000000000000000);
Expand All @@ -244,7 +244,7 @@ mod rlp_fragment {
}

mod assert_eq_address {
use crate::rlp::{decode::STRING, types::RlpFragment};
use crate::rlp::types::{STRING, RlpFragment};
use crate::misc::types::Address;
use crate::misc::{arrays::alter_array, fragment::Fragment};
use crate::fixtures::mainnet::frontier::first::state_proof::state_proof as state_proof;
Expand Down Expand Up @@ -273,7 +273,7 @@ mod rlp_fragment {
}

mod assert_eq_bytes32 {
use crate::rlp::{decode::STRING, types::RlpFragment};
use crate::rlp::types::{STRING, RlpFragment};
use crate::misc::types::Bytes32;
use crate::misc::{arrays::alter_array, fragment::Fragment};
use crate::fixtures::mainnet::frontier::first::header::hash;
Expand Down

0 comments on commit 2afbd25

Please sign in to comment.