Skip to content

Commit

Permalink
remove fields Uncast and trait MayBeUncast
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-ferdinand committed Jun 8, 2023
1 parent 6301cad commit 27461b1
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 245 deletions.
238 changes: 89 additions & 149 deletions triton-vm/src/proof_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ type AuthenticationStructure<Digest> = Vec<PartialAuthenticationPath<Digest>>;
#[derive(Debug, Clone, PartialEq, Eq, BFieldCodec)]
pub struct FriResponse(pub Vec<(PartialAuthenticationPath<Digest>, XFieldElement)>);

pub trait MayBeUncast {
fn uncast(&self) -> Vec<BFieldElement>;
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProofItem {
CompressedAuthenticationPaths(AuthenticationStructure<Digest>),
Expand All @@ -35,228 +31,172 @@ pub enum ProofItem {
RevealedCombinationElements(Vec<XFieldElement>),
FriCodeword(Vec<XFieldElement>),
FriResponse(FriResponse),
Uncast(Vec<BFieldElement>),
}

impl MayBeUncast for ProofItem {
fn uncast(&self) -> Vec<BFieldElement> {
if let Self::Uncast(vector) = self {
let vector_len = BFieldElement::new(vector.len() as u64);
vec![vec![vector_len], vector.to_owned()].concat()
} else {
self.encode()
}
impl ProofItem {
/// The unique identifier for this item type.
pub const fn discriminant(&self) -> BFieldElement {
use ProofItem::*;
let discriminant: u64 = match self {
CompressedAuthenticationPaths(_) => 0,
MasterBaseTableRows(_) => 1,
MasterExtTableRows(_) => 2,
OutOfDomainBaseRow(_) => 3,
OutOfDomainExtRow(_) => 4,
MerkleRoot(_) => 5,
AuthenticationPath(_) => 6,
RevealedCombinationElements(_) => 7,
FriCodeword(_) => 8,
FriResponse(_) => 9,
};
BFieldElement::new(discriminant)
}
}

impl ProofItem
where
AuthenticationStructure<Digest>: BFieldCodec,
Vec<Vec<BFieldElement>>: BFieldCodec,
Vec<Vec<XFieldElement>>: BFieldCodec,
Digest: BFieldCodec,
Vec<BFieldElement>: BFieldCodec,
Vec<XFieldElement>: BFieldCodec,
Vec<Digest>: BFieldCodec,
BFieldElement: BFieldCodec,
XFieldElement: BFieldCodec,
FriResponse: BFieldCodec,
{
pub fn as_compressed_authentication_paths(&self) -> Result<AuthenticationStructure<Digest>> {
match self {
Self::CompressedAuthenticationPaths(caps) => Ok(caps.to_owned()),
Self::Uncast(str) => match AuthenticationStructure::<Digest>::decode(str) {
Ok(boxed_auth_struct) => Ok(*boxed_auth_struct),
Err(e) => bail!(ProofStreamError::new(&format!(
"cast to authentication structure failed: {e}"
))),
},
other => bail!(ProofStreamError::new(&format!(
"expected compressed authentication paths, but got something else: {other:?}",
"expected compressed authentication paths, but got {other:?}",
))),
}
}

pub fn as_master_base_table_rows(&self) -> Result<Vec<Vec<BFieldElement>>> {
match self {
Self::MasterBaseTableRows(bss) => Ok(bss.to_owned()),
Self::Uncast(str) => match Vec::<Vec<BFieldElement>>::decode(str) {
Ok(base_element_vectors) => Ok(*base_element_vectors),
Err(_) => bail!(ProofStreamError::new("cast to base element vectors failed",)),
},
_ => bail!(ProofStreamError::new(
"expected master base table rows, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected master base table rows, but got something {other:?}",
))),
}
}

pub fn as_master_ext_table_rows(&self) -> Result<Vec<Vec<XFieldElement>>> {
match self {
Self::MasterExtTableRows(xss) => Ok(xss.to_owned()),
Self::Uncast(str) => match Vec::<Vec<XFieldElement>>::decode(str) {
Ok(ext_element_vectors) => Ok(*ext_element_vectors),
Err(_) => bail!(ProofStreamError::new(
"cast to extension field element vectors failed",
)),
},
_ => bail!(ProofStreamError::new(
"expected master extension table rows, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected master extension table rows, but got {other:?}",
))),
}
}

pub fn as_out_of_domain_base_row(&self) -> Result<Vec<XFieldElement>> {
match self {
Self::OutOfDomainBaseRow(xs) => Ok(xs.to_owned()),
Self::Uncast(str) => match Vec::<XFieldElement>::decode(str) {
Ok(xs) => {
if xs.len() != NUM_BASE_COLUMNS {
bail!(ProofStreamError::new(
"cast to out of domain base row failed"
));
}
Ok(*xs)
}
Err(_) => bail!(ProofStreamError::new(
"cast to out of domain base row failed"
)),
},
_ => bail!(ProofStreamError::new(
"expected out of domain base row, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected out of domain base row, but got {other:?}",
))),
}
}

pub fn as_out_of_domain_ext_row(&self) -> Result<Vec<XFieldElement>> {
match self {
Self::OutOfDomainExtRow(xs) => Ok(xs.to_owned()),
Self::Uncast(str) => match Vec::<XFieldElement>::decode(str) {
Ok(xs) => {
if xs.len() != NUM_EXT_COLUMNS {
bail!(ProofStreamError::new(
"cast to out of domain extension row failed"
));
}
Ok(*xs)
}
Err(_) => bail!(ProofStreamError::new(
"cast to out of domain extension row failed"
)),
},
_ => bail!(ProofStreamError::new(
"expected out of domain extension row, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected out of domain extension row, but got {other:?}",
))),
}
}

pub fn as_merkle_root(&self) -> Result<Digest> {
match self {
Self::MerkleRoot(bs) => Ok(*bs),
Self::Uncast(str) => match Digest::decode(str) {
Ok(merkle_root) => Ok(*merkle_root),
Err(_) => bail!(ProofStreamError::new("cast to Merkle root failed",)),
},
_ => bail!(ProofStreamError::new(
"expected merkle root, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected merkle root, but got {other:?}",
))),
}
}

pub fn as_authentication_path(&self) -> Result<Vec<Digest>> {
match self {
Self::AuthenticationPath(bss) => Ok(bss.to_owned()),
Self::Uncast(str) => match Vec::<Digest>::decode(str) {
Ok(authentication_path) => Ok(*authentication_path),
Err(_) => bail!(ProofStreamError::new("cast to authentication path failed",)),
},
_ => bail!(ProofStreamError::new(
"expected authentication path, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected authentication path, but got {other:?}",
))),
}
}

pub fn as_revealed_combination_elements(&self) -> Result<Vec<XFieldElement>> {
match self {
Self::RevealedCombinationElements(xs) => Ok(xs.to_owned()),
Self::Uncast(str) => match Vec::<XFieldElement>::decode(str) {
Ok(revealed_combination_elements) => Ok(*revealed_combination_elements),
Err(_) => bail!(ProofStreamError::new(
"cast to revealed combination elements failed",
)),
},
_ => bail!(ProofStreamError::new(
"expected revealed combination elements, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected revealed combination elements, but got {other:?}",
))),
}
}

pub fn as_fri_codeword(&self) -> Result<Vec<XFieldElement>> {
match self {
Self::FriCodeword(xs) => Ok(xs.to_owned()),
Self::Uncast(str) => match Vec::<XFieldElement>::decode(str) {
Ok(fri_codeword) => Ok(*fri_codeword),
Err(_) => bail!(ProofStreamError::new("cast to FRI codeword failed",)),
},
_ => bail!(ProofStreamError::new(
"expected FRI codeword, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected FRI codeword, but got {other:?}",
))),
}
}

pub fn as_fri_response(&self) -> Result<FriResponse> {
match self {
Self::FriResponse(fri_proof) => Ok(fri_proof.to_owned()),
Self::Uncast(str) => match FriResponse::decode(str) {
Ok(fri_proof) => Ok(*fri_proof),
Err(_) => bail!(ProofStreamError::new("cast to FRI proof failed",)),
},
_ => bail!(ProofStreamError::new(
"expected FRI proof, but got something else",
)),
other => bail!(ProofStreamError::new(&format!(
"expected FRI proof, but got {other:?}"
),)),
}
}
}

impl BFieldCodec for ProofItem {
/// Turn the given string of BFieldElements into a ProofItem. The first element denotes the
/// length of the encoding; make sure it is correct!
/// Turn the given string of BFieldElements into a ProofItem. The first element indicates the
/// field type, and the rest of the elements are the data for the item.
fn decode(str: &[BFieldElement]) -> Result<Box<Self>> {
let Some(len) = str.get(0) else {
bail!(ProofStreamError::new("empty buffer"))
};
if len.value() + 1 != str.len() as u64 {
bail!(ProofStreamError::new("length mismatch"))
if str.is_empty() {
bail!(ProofStreamError::new("empty buffer"));
}

let raw_item = Self::Uncast(str[1..].to_vec());
Ok(Box::new(raw_item))
let discriminant = str[0].value();
let str = &str[1..];
let item = match discriminant {
0 => Self::CompressedAuthenticationPaths(*AuthenticationStructure::decode(str)?),
1 => Self::MasterBaseTableRows(*Vec::<Vec<BFieldElement>>::decode(str)?),
2 => Self::MasterExtTableRows(*Vec::<Vec<XFieldElement>>::decode(str)?),
3 => Self::OutOfDomainBaseRow(*Vec::<XFieldElement>::decode(str)?),
4 => Self::OutOfDomainExtRow(*Vec::<XFieldElement>::decode(str)?),
5 => Self::MerkleRoot(*Digest::decode(str)?),
6 => Self::AuthenticationPath(*Vec::<Digest>::decode(str)?),
7 => Self::RevealedCombinationElements(*Vec::<XFieldElement>::decode(str)?),
8 => Self::FriCodeword(*Vec::<XFieldElement>::decode(str)?),
9 => Self::FriResponse(*FriResponse::decode(str)?),
i => bail!(ProofStreamError::new(&format!(
"Unknown discriminant {i} for ProofItem."
))),
};
Ok(Box::new(item))
}

/// Encode the ProofItem as a string of BFieldElements, with the first element denoting the
/// length of the rest.
fn encode(&self) -> Vec<BFieldElement> {
let mut tail = match self {
ProofItem::CompressedAuthenticationPaths(something) => something.encode(),
ProofItem::MasterBaseTableRows(something) => something.encode(),
ProofItem::MasterExtTableRows(something) => something.encode(),
ProofItem::OutOfDomainBaseRow(row) => {
debug_assert_eq!(NUM_BASE_COLUMNS, row.len());
row.encode()
}
ProofItem::OutOfDomainExtRow(row) => {
debug_assert_eq!(NUM_EXT_COLUMNS, row.len());
row.encode()
}
ProofItem::MerkleRoot(something) => something.encode(),
ProofItem::AuthenticationPath(something) => something.encode(),
ProofItem::RevealedCombinationElements(something) => something.encode(),
ProofItem::FriCodeword(something) => something.encode(),
ProofItem::FriResponse(something) => something.encode(),
ProofItem::Uncast(something) => something.encode(),
use ProofItem::*;

#[cfg(debug_assertions)]
match self {
OutOfDomainBaseRow(row) => assert_eq!(NUM_BASE_COLUMNS, row.len()),
OutOfDomainExtRow(row) => assert_eq!(NUM_EXT_COLUMNS, row.len()),
_ => (),
}

let discriminant = vec![self.discriminant()];
let encoding = match self {
CompressedAuthenticationPaths(something) => something.encode(),
MasterBaseTableRows(something) => something.encode(),
MasterExtTableRows(something) => something.encode(),
OutOfDomainBaseRow(row) => row.encode(),
OutOfDomainExtRow(row) => row.encode(),
MerkleRoot(something) => something.encode(),
AuthenticationPath(something) => something.encode(),
RevealedCombinationElements(something) => something.encode(),
FriCodeword(something) => something.encode(),
FriResponse(something) => something.encode(),
};
let head = BFieldElement::new(tail.len() as u64);
tail.insert(0, head);
tail
[discriminant, encoding].concat()
}

fn static_length() -> Option<usize> {
Expand Down
Loading

0 comments on commit 27461b1

Please sign in to comment.