mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-10 07:07:57 -05:00
refactor(core): replace Idx with RangeSet (#988)
* refactor(core): replace Idx with RangeSet * clippy
This commit is contained in:
16
crates/core/src/display.rs
Normal file
16
crates/core/src/display.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use rangeset::RangeSet;
|
||||
|
||||
pub(crate) struct FmtRangeSet<'a>(pub &'a RangeSet<usize>);
|
||||
|
||||
impl<'a> std::fmt::Display for FmtRangeSet<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("{")?;
|
||||
for range in self.0.iter_ranges() {
|
||||
write!(f, "{}..{}", range.start, range.end)?;
|
||||
if range.end < self.0.end().unwrap_or(0) {
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
}
|
||||
f.write_str("}")
|
||||
}
|
||||
}
|
||||
@@ -11,15 +11,17 @@ pub mod hash;
|
||||
pub mod merkle;
|
||||
pub mod transcript;
|
||||
pub mod webpki;
|
||||
pub use rangeset;
|
||||
pub(crate) mod display;
|
||||
|
||||
use rangeset::ToRangeSet;
|
||||
use rangeset::{RangeSet, ToRangeSet, UnionMut};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
connection::{HandshakeData, ServerName},
|
||||
transcript::{
|
||||
Direction, Idx, PartialTranscript, Transcript, TranscriptCommitConfig,
|
||||
TranscriptCommitRequest, TranscriptCommitment, TranscriptSecret,
|
||||
Direction, PartialTranscript, Transcript, TranscriptCommitConfig, TranscriptCommitRequest,
|
||||
TranscriptCommitment, TranscriptSecret,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -58,8 +60,8 @@ impl ProveConfig {
|
||||
pub struct ProveConfigBuilder<'a> {
|
||||
transcript: &'a Transcript,
|
||||
server_identity: bool,
|
||||
reveal_sent: Idx,
|
||||
reveal_recv: Idx,
|
||||
reveal_sent: RangeSet<usize>,
|
||||
reveal_recv: RangeSet<usize>,
|
||||
transcript_commit: Option<TranscriptCommitConfig>,
|
||||
}
|
||||
|
||||
@@ -69,8 +71,8 @@ impl<'a> ProveConfigBuilder<'a> {
|
||||
Self {
|
||||
transcript,
|
||||
server_identity: false,
|
||||
reveal_sent: Idx::default(),
|
||||
reveal_recv: Idx::default(),
|
||||
reveal_sent: RangeSet::default(),
|
||||
reveal_recv: RangeSet::default(),
|
||||
transcript_commit: None,
|
||||
}
|
||||
}
|
||||
@@ -93,13 +95,13 @@ impl<'a> ProveConfigBuilder<'a> {
|
||||
direction: Direction,
|
||||
ranges: &dyn ToRangeSet<usize>,
|
||||
) -> Result<&mut Self, ProveConfigBuilderError> {
|
||||
let idx = Idx::new(ranges.to_range_set());
|
||||
let idx = ranges.to_range_set();
|
||||
|
||||
if idx.end() > self.transcript.len_of_direction(direction) {
|
||||
if idx.end().unwrap_or(0) > self.transcript.len_of_direction(direction) {
|
||||
return Err(ProveConfigBuilderError(
|
||||
ProveConfigBuilderErrorRepr::IndexOutOfBounds {
|
||||
direction,
|
||||
actual: idx.end(),
|
||||
actual: idx.end().unwrap_or(0),
|
||||
len: self.transcript.len_of_direction(direction),
|
||||
},
|
||||
));
|
||||
|
||||
@@ -26,7 +26,7 @@ mod tls;
|
||||
|
||||
use std::{fmt, ops::Range};
|
||||
|
||||
use rangeset::{Difference, IndexRanges, RangeSet, Subset, ToRangeSet, Union, UnionMut};
|
||||
use rangeset::{Difference, IndexRanges, RangeSet, Union};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::connection::TranscriptLength;
|
||||
@@ -96,18 +96,18 @@ impl Transcript {
|
||||
|
||||
/// Returns the subsequence of the transcript with the provided index,
|
||||
/// returning `None` if the index is out of bounds.
|
||||
pub fn get(&self, direction: Direction, idx: &Idx) -> Option<Subsequence> {
|
||||
pub fn get(&self, direction: Direction, idx: &RangeSet<usize>) -> Option<Subsequence> {
|
||||
let data = match direction {
|
||||
Direction::Sent => &self.sent,
|
||||
Direction::Received => &self.received,
|
||||
};
|
||||
|
||||
if idx.end() > data.len() {
|
||||
if idx.end().unwrap_or(0) > data.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(
|
||||
Subsequence::new(idx.clone(), data.index_ranges(&idx.0))
|
||||
Subsequence::new(idx.clone(), data.index_ranges(idx))
|
||||
.expect("data is same length as index"),
|
||||
)
|
||||
}
|
||||
@@ -122,7 +122,11 @@ impl Transcript {
|
||||
///
|
||||
/// * `sent_idx` - The indices of the sent data to include.
|
||||
/// * `recv_idx` - The indices of the received data to include.
|
||||
pub fn to_partial(&self, sent_idx: Idx, recv_idx: Idx) -> PartialTranscript {
|
||||
pub fn to_partial(
|
||||
&self,
|
||||
sent_idx: RangeSet<usize>,
|
||||
recv_idx: RangeSet<usize>,
|
||||
) -> PartialTranscript {
|
||||
let mut sent = vec![0; self.sent.len()];
|
||||
let mut received = vec![0; self.received.len()];
|
||||
|
||||
@@ -157,9 +161,9 @@ pub struct PartialTranscript {
|
||||
/// Data received by the Prover from the Server.
|
||||
received: Vec<u8>,
|
||||
/// Index of `sent` which have been authenticated.
|
||||
sent_authed_idx: Idx,
|
||||
sent_authed_idx: RangeSet<usize>,
|
||||
/// Index of `received` which have been authenticated.
|
||||
received_authed_idx: Idx,
|
||||
received_authed_idx: RangeSet<usize>,
|
||||
}
|
||||
|
||||
/// `PartialTranscript` in a compressed form.
|
||||
@@ -171,9 +175,9 @@ pub struct CompressedPartialTranscript {
|
||||
/// Received data which has been authenticated.
|
||||
received_authed: Vec<u8>,
|
||||
/// Index of `sent_authed`.
|
||||
sent_idx: Idx,
|
||||
sent_idx: RangeSet<usize>,
|
||||
/// Index of `received_authed`.
|
||||
recv_idx: Idx,
|
||||
recv_idx: RangeSet<usize>,
|
||||
/// Total bytelength of sent data in the original partial transcript.
|
||||
sent_total: usize,
|
||||
/// Total bytelength of received data in the original partial transcript.
|
||||
@@ -185,10 +189,10 @@ impl From<PartialTranscript> for CompressedPartialTranscript {
|
||||
Self {
|
||||
sent_authed: uncompressed
|
||||
.sent
|
||||
.index_ranges(&uncompressed.sent_authed_idx.0),
|
||||
.index_ranges(&uncompressed.sent_authed_idx),
|
||||
received_authed: uncompressed
|
||||
.received
|
||||
.index_ranges(&uncompressed.received_authed_idx.0),
|
||||
.index_ranges(&uncompressed.received_authed_idx),
|
||||
sent_idx: uncompressed.sent_authed_idx,
|
||||
recv_idx: uncompressed.received_authed_idx,
|
||||
sent_total: uncompressed.sent.len(),
|
||||
@@ -238,8 +242,8 @@ impl PartialTranscript {
|
||||
Self {
|
||||
sent: vec![0; sent_len],
|
||||
received: vec![0; received_len],
|
||||
sent_authed_idx: Idx::default(),
|
||||
received_authed_idx: Idx::default(),
|
||||
sent_authed_idx: RangeSet::default(),
|
||||
received_authed_idx: RangeSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,10 +264,10 @@ impl PartialTranscript {
|
||||
}
|
||||
|
||||
/// Returns whether the index is in bounds of the transcript.
|
||||
pub fn contains(&self, direction: Direction, idx: &Idx) -> bool {
|
||||
pub fn contains(&self, direction: Direction, idx: &RangeSet<usize>) -> bool {
|
||||
match direction {
|
||||
Direction::Sent => idx.end() <= self.sent.len(),
|
||||
Direction::Received => idx.end() <= self.received.len(),
|
||||
Direction::Sent => idx.end().unwrap_or(0) <= self.sent.len(),
|
||||
Direction::Received => idx.end().unwrap_or(0) <= self.received.len(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,23 +294,23 @@ impl PartialTranscript {
|
||||
}
|
||||
|
||||
/// Returns the index of sent data which have been authenticated.
|
||||
pub fn sent_authed(&self) -> &Idx {
|
||||
pub fn sent_authed(&self) -> &RangeSet<usize> {
|
||||
&self.sent_authed_idx
|
||||
}
|
||||
|
||||
/// Returns the index of received data which have been authenticated.
|
||||
pub fn received_authed(&self) -> &Idx {
|
||||
pub fn received_authed(&self) -> &RangeSet<usize> {
|
||||
&self.received_authed_idx
|
||||
}
|
||||
|
||||
/// Returns the index of sent data which haven't been authenticated.
|
||||
pub fn sent_unauthed(&self) -> Idx {
|
||||
Idx(RangeSet::from(0..self.sent.len()).difference(&self.sent_authed_idx.0))
|
||||
pub fn sent_unauthed(&self) -> RangeSet<usize> {
|
||||
(0..self.sent.len()).difference(&self.sent_authed_idx)
|
||||
}
|
||||
|
||||
/// Returns the index of received data which haven't been authenticated.
|
||||
pub fn received_unauthed(&self) -> Idx {
|
||||
Idx(RangeSet::from(0..self.received.len()).difference(&self.received_authed_idx.0))
|
||||
pub fn received_unauthed(&self) -> RangeSet<usize> {
|
||||
(0..self.received.len()).difference(&self.received_authed_idx)
|
||||
}
|
||||
|
||||
/// Returns an iterator over the authenticated data in the transcript.
|
||||
@@ -316,7 +320,7 @@ impl PartialTranscript {
|
||||
Direction::Received => (&self.received, &self.received_authed_idx),
|
||||
};
|
||||
|
||||
authed.0.iter().map(|i| data[i])
|
||||
authed.iter().map(|i| data[i])
|
||||
}
|
||||
|
||||
/// Unions the authenticated data of this transcript with another.
|
||||
@@ -338,8 +342,7 @@ impl PartialTranscript {
|
||||
|
||||
for range in other
|
||||
.sent_authed_idx
|
||||
.0
|
||||
.difference(&self.sent_authed_idx.0)
|
||||
.difference(&self.sent_authed_idx)
|
||||
.iter_ranges()
|
||||
{
|
||||
self.sent[range.clone()].copy_from_slice(&other.sent[range]);
|
||||
@@ -347,8 +350,7 @@ impl PartialTranscript {
|
||||
|
||||
for range in other
|
||||
.received_authed_idx
|
||||
.0
|
||||
.difference(&self.received_authed_idx.0)
|
||||
.difference(&self.received_authed_idx)
|
||||
.iter_ranges()
|
||||
{
|
||||
self.received[range.clone()].copy_from_slice(&other.received[range]);
|
||||
@@ -400,12 +402,12 @@ impl PartialTranscript {
|
||||
pub fn set_unauthed_range(&mut self, value: u8, direction: Direction, range: Range<usize>) {
|
||||
match direction {
|
||||
Direction::Sent => {
|
||||
for range in range.difference(&self.sent_authed_idx.0).iter_ranges() {
|
||||
for range in range.difference(&self.sent_authed_idx).iter_ranges() {
|
||||
self.sent[range].fill(value);
|
||||
}
|
||||
}
|
||||
Direction::Received => {
|
||||
for range in range.difference(&self.received_authed_idx.0).iter_ranges() {
|
||||
for range in range.difference(&self.received_authed_idx).iter_ranges() {
|
||||
self.received[range].fill(value);
|
||||
}
|
||||
}
|
||||
@@ -434,130 +436,19 @@ impl fmt::Display for Direction {
|
||||
}
|
||||
}
|
||||
|
||||
/// Transcript index.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Idx(RangeSet<usize>);
|
||||
|
||||
impl Idx {
|
||||
/// Creates a new index builder.
|
||||
pub fn builder() -> IdxBuilder {
|
||||
IdxBuilder::default()
|
||||
}
|
||||
|
||||
/// Creates an empty index.
|
||||
pub fn empty() -> Self {
|
||||
Self(RangeSet::default())
|
||||
}
|
||||
|
||||
/// Creates a new transcript index.
|
||||
pub fn new(ranges: impl Into<RangeSet<usize>>) -> Self {
|
||||
Self(ranges.into())
|
||||
}
|
||||
|
||||
/// Returns the start of the index.
|
||||
pub fn start(&self) -> usize {
|
||||
self.0.min().unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Returns the end of the index, non-inclusive.
|
||||
pub fn end(&self) -> usize {
|
||||
self.0.end().unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Returns an iterator over the values in the index.
|
||||
pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
/// Returns an iterator over the ranges of the index.
|
||||
pub fn iter_ranges(&self) -> impl Iterator<Item = Range<usize>> + '_ {
|
||||
self.0.iter_ranges()
|
||||
}
|
||||
|
||||
/// Returns the number of values in the index.
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
/// Returns whether the index is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the number of disjoint ranges in the index.
|
||||
pub fn count(&self) -> usize {
|
||||
self.0.len_ranges()
|
||||
}
|
||||
|
||||
pub(crate) fn as_range_set(&self) -> &RangeSet<usize> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Returns the union of this index with another.
|
||||
pub(crate) fn union(&self, other: &Idx) -> Idx {
|
||||
Idx(self.0.union(&other.0))
|
||||
}
|
||||
|
||||
/// Unions this index with another.
|
||||
pub(crate) fn union_mut(&mut self, other: &Idx) {
|
||||
self.0.union_mut(&other.0);
|
||||
}
|
||||
|
||||
/// Returns the difference between `self` and `other`.
|
||||
pub(crate) fn difference(&self, other: &Idx) -> Idx {
|
||||
Idx(self.0.difference(&other.0))
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is a subset of `other`.
|
||||
pub(crate) fn is_subset(&self, other: &Idx) -> bool {
|
||||
self.0.is_subset(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Idx {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("Idx([")?;
|
||||
let count = self.0.len_ranges();
|
||||
for (i, range) in self.0.iter_ranges().enumerate() {
|
||||
write!(f, "{}..{}", range.start, range.end)?;
|
||||
if i < count - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
f.write_str("])")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder for [`Idx`].
|
||||
#[derive(Debug, Default)]
|
||||
pub struct IdxBuilder(RangeSet<usize>);
|
||||
|
||||
impl IdxBuilder {
|
||||
/// Unions ranges.
|
||||
pub fn union(self, ranges: &dyn ToRangeSet<usize>) -> Self {
|
||||
IdxBuilder(self.0.union(&ranges.to_range_set()))
|
||||
}
|
||||
|
||||
/// Builds the index.
|
||||
pub fn build(self) -> Idx {
|
||||
Idx(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Transcript subsequence.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(try_from = "validation::SubsequenceUnchecked")]
|
||||
pub struct Subsequence {
|
||||
/// Index of the subsequence.
|
||||
idx: Idx,
|
||||
idx: RangeSet<usize>,
|
||||
/// Data of the subsequence.
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Subsequence {
|
||||
/// Creates a new subsequence.
|
||||
pub fn new(idx: Idx, data: Vec<u8>) -> Result<Self, InvalidSubsequence> {
|
||||
pub fn new(idx: RangeSet<usize>, data: Vec<u8>) -> Result<Self, InvalidSubsequence> {
|
||||
if idx.len() != data.len() {
|
||||
return Err(InvalidSubsequence(
|
||||
"index length does not match data length",
|
||||
@@ -568,7 +459,7 @@ impl Subsequence {
|
||||
}
|
||||
|
||||
/// Returns the index of the subsequence.
|
||||
pub fn index(&self) -> &Idx {
|
||||
pub fn index(&self) -> &RangeSet<usize> {
|
||||
&self.idx
|
||||
}
|
||||
|
||||
@@ -584,7 +475,7 @@ impl Subsequence {
|
||||
}
|
||||
|
||||
/// Returns the inner parts of the subsequence.
|
||||
pub fn into_parts(self) -> (Idx, Vec<u8>) {
|
||||
pub fn into_parts(self) -> (RangeSet<usize>, Vec<u8>) {
|
||||
(self.idx, self.data)
|
||||
}
|
||||
|
||||
@@ -612,7 +503,7 @@ mod validation {
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub(super) struct SubsequenceUnchecked {
|
||||
idx: Idx,
|
||||
idx: RangeSet<usize>,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
@@ -634,8 +525,8 @@ mod validation {
|
||||
pub(super) struct CompressedPartialTranscriptUnchecked {
|
||||
sent_authed: Vec<u8>,
|
||||
received_authed: Vec<u8>,
|
||||
sent_idx: Idx,
|
||||
recv_idx: Idx,
|
||||
sent_idx: RangeSet<usize>,
|
||||
recv_idx: RangeSet<usize>,
|
||||
sent_total: usize,
|
||||
recv_total: usize,
|
||||
}
|
||||
@@ -652,8 +543,8 @@ mod validation {
|
||||
));
|
||||
}
|
||||
|
||||
if unchecked.sent_idx.end() > unchecked.sent_total
|
||||
|| unchecked.recv_idx.end() > unchecked.recv_total
|
||||
if unchecked.sent_idx.end().unwrap_or(0) > unchecked.sent_total
|
||||
|| unchecked.recv_idx.end().unwrap_or(0) > unchecked.recv_total
|
||||
{
|
||||
return Err(InvalidCompressedPartialTranscript(
|
||||
"ranges are not in bounds of the data",
|
||||
@@ -682,8 +573,8 @@ mod validation {
|
||||
CompressedPartialTranscriptUnchecked {
|
||||
received_authed: vec![1, 2, 3, 11, 12, 13],
|
||||
sent_authed: vec![4, 5, 6, 14, 15, 16],
|
||||
recv_idx: Idx(RangeSet::new(&[1..4, 11..14])),
|
||||
sent_idx: Idx(RangeSet::new(&[4..7, 14..17])),
|
||||
recv_idx: RangeSet::from([1..4, 11..14]),
|
||||
sent_idx: RangeSet::from([4..7, 14..17]),
|
||||
sent_total: 20,
|
||||
recv_total: 20,
|
||||
}
|
||||
@@ -722,7 +613,6 @@ mod validation {
|
||||
// Change the total to be less than the last range's end bound.
|
||||
let end = partial_transcript
|
||||
.sent_idx
|
||||
.0
|
||||
.iter_ranges()
|
||||
.next_back()
|
||||
.unwrap()
|
||||
@@ -754,31 +644,25 @@ mod tests {
|
||||
|
||||
#[fixture]
|
||||
fn partial_transcript() -> PartialTranscript {
|
||||
transcript().to_partial(
|
||||
Idx::new(RangeSet::new(&[1..4, 6..9])),
|
||||
Idx::new(RangeSet::new(&[2..5, 7..10])),
|
||||
)
|
||||
transcript().to_partial(RangeSet::from([1..4, 6..9]), RangeSet::from([2..5, 7..10]))
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_transcript_get_subsequence(transcript: Transcript) {
|
||||
let subseq = transcript
|
||||
.get(Direction::Received, &Idx(RangeSet::from([0..4, 7..10])))
|
||||
.get(Direction::Received, &RangeSet::from([0..4, 7..10]))
|
||||
.unwrap();
|
||||
assert_eq!(subseq.data, vec![0, 1, 2, 3, 7, 8, 9]);
|
||||
|
||||
let subseq = transcript
|
||||
.get(Direction::Sent, &Idx(RangeSet::from([0..4, 9..12])))
|
||||
.get(Direction::Sent, &RangeSet::from([0..4, 9..12]))
|
||||
.unwrap();
|
||||
assert_eq!(subseq.data, vec![0, 1, 2, 3, 9, 10, 11]);
|
||||
|
||||
let subseq = transcript.get(
|
||||
Direction::Received,
|
||||
&Idx(RangeSet::from([0..4, 7..10, 11..13])),
|
||||
);
|
||||
let subseq = transcript.get(Direction::Received, &RangeSet::from([0..4, 7..10, 11..13]));
|
||||
assert_eq!(subseq, None);
|
||||
|
||||
let subseq = transcript.get(Direction::Sent, &Idx(RangeSet::from([0..4, 7..10, 11..13])));
|
||||
let subseq = transcript.get(Direction::Sent, &RangeSet::from([0..4, 7..10, 11..13]));
|
||||
assert_eq!(subseq, None);
|
||||
}
|
||||
|
||||
@@ -791,7 +675,7 @@ mod tests {
|
||||
|
||||
#[rstest]
|
||||
fn test_transcript_to_partial_success(transcript: Transcript) {
|
||||
let partial = transcript.to_partial(Idx::new(0..2), Idx::new(3..7));
|
||||
let partial = transcript.to_partial(RangeSet::from(0..2), RangeSet::from(3..7));
|
||||
assert_eq!(partial.sent_unsafe(), [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
assert_eq!(
|
||||
partial.received_unsafe(),
|
||||
@@ -802,29 +686,30 @@ mod tests {
|
||||
#[rstest]
|
||||
#[should_panic]
|
||||
fn test_transcript_to_partial_failure(transcript: Transcript) {
|
||||
let _ = transcript.to_partial(Idx::new(0..14), Idx::new(3..7));
|
||||
let _ = transcript.to_partial(RangeSet::from(0..14), RangeSet::from(3..7));
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_partial_transcript_contains(transcript: Transcript) {
|
||||
let partial = transcript.to_partial(Idx::new(0..2), Idx::new(3..7));
|
||||
assert!(partial.contains(Direction::Sent, &Idx::new([0..5, 7..10])));
|
||||
assert!(!partial.contains(Direction::Received, &Idx::new([4..6, 7..13])))
|
||||
let partial = transcript.to_partial(RangeSet::from(0..2), RangeSet::from(3..7));
|
||||
assert!(partial.contains(Direction::Sent, &RangeSet::from([0..5, 7..10])));
|
||||
assert!(!partial.contains(Direction::Received, &RangeSet::from([4..6, 7..13])))
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_partial_transcript_unauthed(transcript: Transcript) {
|
||||
let partial = transcript.to_partial(Idx::new(0..2), Idx::new(3..7));
|
||||
assert_eq!(partial.sent_unauthed(), Idx::new(2..12));
|
||||
assert_eq!(partial.received_unauthed(), Idx::new([0..3, 7..12]));
|
||||
let partial = transcript.to_partial(RangeSet::from(0..2), RangeSet::from(3..7));
|
||||
assert_eq!(partial.sent_unauthed(), RangeSet::from(2..12));
|
||||
assert_eq!(partial.received_unauthed(), RangeSet::from([0..3, 7..12]));
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_partial_transcript_union_success(transcript: Transcript) {
|
||||
// Non overlapping ranges.
|
||||
let mut simple_partial = transcript.to_partial(Idx::new(0..2), Idx::new(3..7));
|
||||
let mut simple_partial = transcript.to_partial(RangeSet::from(0..2), RangeSet::from(3..7));
|
||||
|
||||
let other_simple_partial = transcript.to_partial(Idx::new(3..5), Idx::new(1..2));
|
||||
let other_simple_partial =
|
||||
transcript.to_partial(RangeSet::from(3..5), RangeSet::from(1..2));
|
||||
|
||||
simple_partial.union_transcript(&other_simple_partial);
|
||||
|
||||
@@ -836,12 +721,16 @@ mod tests {
|
||||
simple_partial.received_unsafe(),
|
||||
[0, 1, 0, 3, 4, 5, 6, 0, 0, 0, 0, 0]
|
||||
);
|
||||
assert_eq!(simple_partial.sent_authed(), &Idx::new([0..2, 3..5]));
|
||||
assert_eq!(simple_partial.received_authed(), &Idx::new([1..2, 3..7]));
|
||||
assert_eq!(simple_partial.sent_authed(), &RangeSet::from([0..2, 3..5]));
|
||||
assert_eq!(
|
||||
simple_partial.received_authed(),
|
||||
&RangeSet::from([1..2, 3..7])
|
||||
);
|
||||
|
||||
// Overwrite with another partial transcript.
|
||||
|
||||
let another_simple_partial = transcript.to_partial(Idx::new(1..4), Idx::new(6..9));
|
||||
let another_simple_partial =
|
||||
transcript.to_partial(RangeSet::from(1..4), RangeSet::from(6..9));
|
||||
|
||||
simple_partial.union_transcript(&another_simple_partial);
|
||||
|
||||
@@ -853,13 +742,17 @@ mod tests {
|
||||
simple_partial.received_unsafe(),
|
||||
[0, 1, 0, 3, 4, 5, 6, 7, 8, 0, 0, 0]
|
||||
);
|
||||
assert_eq!(simple_partial.sent_authed(), &Idx::new(0..5));
|
||||
assert_eq!(simple_partial.received_authed(), &Idx::new([1..2, 3..9]));
|
||||
assert_eq!(simple_partial.sent_authed(), &RangeSet::from(0..5));
|
||||
assert_eq!(
|
||||
simple_partial.received_authed(),
|
||||
&RangeSet::from([1..2, 3..9])
|
||||
);
|
||||
|
||||
// Overlapping ranges.
|
||||
let mut overlap_partial = transcript.to_partial(Idx::new(4..6), Idx::new(3..7));
|
||||
let mut overlap_partial = transcript.to_partial(RangeSet::from(4..6), RangeSet::from(3..7));
|
||||
|
||||
let other_overlap_partial = transcript.to_partial(Idx::new(3..5), Idx::new(5..9));
|
||||
let other_overlap_partial =
|
||||
transcript.to_partial(RangeSet::from(3..5), RangeSet::from(5..9));
|
||||
|
||||
overlap_partial.union_transcript(&other_overlap_partial);
|
||||
|
||||
@@ -871,13 +764,16 @@ mod tests {
|
||||
overlap_partial.received_unsafe(),
|
||||
[0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 0]
|
||||
);
|
||||
assert_eq!(overlap_partial.sent_authed(), &Idx::new([3..5, 4..6]));
|
||||
assert_eq!(overlap_partial.received_authed(), &Idx::new([3..7, 5..9]));
|
||||
assert_eq!(overlap_partial.sent_authed(), &RangeSet::from([3..5, 4..6]));
|
||||
assert_eq!(
|
||||
overlap_partial.received_authed(),
|
||||
&RangeSet::from([3..7, 5..9])
|
||||
);
|
||||
|
||||
// Equal ranges.
|
||||
let mut equal_partial = transcript.to_partial(Idx::new(4..6), Idx::new(3..7));
|
||||
let mut equal_partial = transcript.to_partial(RangeSet::from(4..6), RangeSet::from(3..7));
|
||||
|
||||
let other_equal_partial = transcript.to_partial(Idx::new(4..6), Idx::new(3..7));
|
||||
let other_equal_partial = transcript.to_partial(RangeSet::from(4..6), RangeSet::from(3..7));
|
||||
|
||||
equal_partial.union_transcript(&other_equal_partial);
|
||||
|
||||
@@ -889,13 +785,15 @@ mod tests {
|
||||
equal_partial.received_unsafe(),
|
||||
[0, 0, 0, 3, 4, 5, 6, 0, 0, 0, 0, 0]
|
||||
);
|
||||
assert_eq!(equal_partial.sent_authed(), &Idx::new(4..6));
|
||||
assert_eq!(equal_partial.received_authed(), &Idx::new(3..7));
|
||||
assert_eq!(equal_partial.sent_authed(), &RangeSet::from(4..6));
|
||||
assert_eq!(equal_partial.received_authed(), &RangeSet::from(3..7));
|
||||
|
||||
// Subset ranges.
|
||||
let mut subset_partial = transcript.to_partial(Idx::new(4..10), Idx::new(3..11));
|
||||
let mut subset_partial =
|
||||
transcript.to_partial(RangeSet::from(4..10), RangeSet::from(3..11));
|
||||
|
||||
let other_subset_partial = transcript.to_partial(Idx::new(6..9), Idx::new(5..6));
|
||||
let other_subset_partial =
|
||||
transcript.to_partial(RangeSet::from(6..9), RangeSet::from(5..6));
|
||||
|
||||
subset_partial.union_transcript(&other_subset_partial);
|
||||
|
||||
@@ -907,30 +805,32 @@ mod tests {
|
||||
subset_partial.received_unsafe(),
|
||||
[0, 0, 0, 3, 4, 5, 6, 7, 8, 9, 10, 0]
|
||||
);
|
||||
assert_eq!(subset_partial.sent_authed(), &Idx::new(4..10));
|
||||
assert_eq!(subset_partial.received_authed(), &Idx::new(3..11));
|
||||
assert_eq!(subset_partial.sent_authed(), &RangeSet::from(4..10));
|
||||
assert_eq!(subset_partial.received_authed(), &RangeSet::from(3..11));
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[should_panic]
|
||||
fn test_partial_transcript_union_failure(transcript: Transcript) {
|
||||
let mut partial = transcript.to_partial(Idx::new(4..10), Idx::new(3..11));
|
||||
let mut partial = transcript.to_partial(RangeSet::from(4..10), RangeSet::from(3..11));
|
||||
|
||||
let other_transcript = Transcript::new(
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
||||
);
|
||||
|
||||
let other_partial = other_transcript.to_partial(Idx::new(6..9), Idx::new(5..6));
|
||||
let other_partial = other_transcript.to_partial(RangeSet::from(6..9), RangeSet::from(5..6));
|
||||
|
||||
partial.union_transcript(&other_partial);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_partial_transcript_union_subseq_success(transcript: Transcript) {
|
||||
let mut partial = transcript.to_partial(Idx::new(4..10), Idx::new(3..11));
|
||||
let sent_seq = Subsequence::new(Idx::new([0..3, 5..7]), [0, 1, 2, 5, 6].into()).unwrap();
|
||||
let recv_seq = Subsequence::new(Idx::new([0..4, 5..7]), [0, 1, 2, 3, 5, 6].into()).unwrap();
|
||||
let mut partial = transcript.to_partial(RangeSet::from(4..10), RangeSet::from(3..11));
|
||||
let sent_seq =
|
||||
Subsequence::new(RangeSet::from([0..3, 5..7]), [0, 1, 2, 5, 6].into()).unwrap();
|
||||
let recv_seq =
|
||||
Subsequence::new(RangeSet::from([0..4, 5..7]), [0, 1, 2, 3, 5, 6].into()).unwrap();
|
||||
|
||||
partial.union_subsequence(Direction::Sent, &sent_seq);
|
||||
partial.union_subsequence(Direction::Received, &recv_seq);
|
||||
@@ -940,30 +840,31 @@ mod tests {
|
||||
partial.received_unsafe(),
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0]
|
||||
);
|
||||
assert_eq!(partial.sent_authed(), &Idx::new([0..3, 4..10]));
|
||||
assert_eq!(partial.received_authed(), &Idx::new(0..11));
|
||||
assert_eq!(partial.sent_authed(), &RangeSet::from([0..3, 4..10]));
|
||||
assert_eq!(partial.received_authed(), &RangeSet::from(0..11));
|
||||
|
||||
// Overwrite with another subseq.
|
||||
let other_sent_seq = Subsequence::new(Idx::new(0..3), [3, 2, 1].into()).unwrap();
|
||||
let other_sent_seq = Subsequence::new(RangeSet::from(0..3), [3, 2, 1].into()).unwrap();
|
||||
|
||||
partial.union_subsequence(Direction::Sent, &other_sent_seq);
|
||||
assert_eq!(partial.sent_unsafe(), [3, 2, 1, 0, 4, 5, 6, 7, 8, 9, 0, 0]);
|
||||
assert_eq!(partial.sent_authed(), &Idx::new([0..3, 4..10]));
|
||||
assert_eq!(partial.sent_authed(), &RangeSet::from([0..3, 4..10]));
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[should_panic]
|
||||
fn test_partial_transcript_union_subseq_failure(transcript: Transcript) {
|
||||
let mut partial = transcript.to_partial(Idx::new(4..10), Idx::new(3..11));
|
||||
let mut partial = transcript.to_partial(RangeSet::from(4..10), RangeSet::from(3..11));
|
||||
|
||||
let sent_seq = Subsequence::new(Idx::new([0..3, 13..15]), [0, 1, 2, 5, 6].into()).unwrap();
|
||||
let sent_seq =
|
||||
Subsequence::new(RangeSet::from([0..3, 13..15]), [0, 1, 2, 5, 6].into()).unwrap();
|
||||
|
||||
partial.union_subsequence(Direction::Sent, &sent_seq);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_partial_transcript_set_unauthed_range(transcript: Transcript) {
|
||||
let mut partial = transcript.to_partial(Idx::new(4..10), Idx::new(3..7));
|
||||
let mut partial = transcript.to_partial(RangeSet::from(4..10), RangeSet::from(3..7));
|
||||
|
||||
partial.set_unauthed_range(7, Direction::Sent, 2..5);
|
||||
partial.set_unauthed_range(5, Direction::Sent, 0..2);
|
||||
@@ -980,13 +881,13 @@ mod tests {
|
||||
#[rstest]
|
||||
#[should_panic]
|
||||
fn test_subsequence_new_invalid_len() {
|
||||
let _ = Subsequence::new(Idx::new([0..3, 5..8]), [0, 1, 2, 5, 6].into()).unwrap();
|
||||
let _ = Subsequence::new(RangeSet::from([0..3, 5..8]), [0, 1, 2, 5, 6].into()).unwrap();
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[should_panic]
|
||||
fn test_subsequence_copy_to_invalid_len() {
|
||||
let seq = Subsequence::new(Idx::new([0..3, 5..7]), [0, 1, 2, 5, 6].into()).unwrap();
|
||||
let seq = Subsequence::new(RangeSet::from([0..3, 5..7]), [0, 1, 2, 5, 6].into()).unwrap();
|
||||
|
||||
let mut data: [u8; 3] = [0, 1, 2];
|
||||
seq.copy_to(&mut data);
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
transcript::{
|
||||
encoding::{EncodingCommitment, EncodingTree},
|
||||
hash::{PlaintextHash, PlaintextHashSecret},
|
||||
Direction, Idx, Transcript,
|
||||
Direction, RangeSet, Transcript,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -71,7 +71,7 @@ pub struct TranscriptCommitConfig {
|
||||
encoding_hash_alg: HashAlgId,
|
||||
has_encoding: bool,
|
||||
has_hash: bool,
|
||||
commits: Vec<((Direction, Idx), TranscriptCommitmentKind)>,
|
||||
commits: Vec<((Direction, RangeSet<usize>), TranscriptCommitmentKind)>,
|
||||
}
|
||||
|
||||
impl TranscriptCommitConfig {
|
||||
@@ -96,7 +96,7 @@ impl TranscriptCommitConfig {
|
||||
}
|
||||
|
||||
/// Returns an iterator over the encoding commitment indices.
|
||||
pub fn iter_encoding(&self) -> impl Iterator<Item = &(Direction, Idx)> {
|
||||
pub fn iter_encoding(&self) -> impl Iterator<Item = &(Direction, RangeSet<usize>)> {
|
||||
self.commits.iter().filter_map(|(idx, kind)| match kind {
|
||||
TranscriptCommitmentKind::Encoding => Some(idx),
|
||||
_ => None,
|
||||
@@ -104,7 +104,7 @@ impl TranscriptCommitConfig {
|
||||
}
|
||||
|
||||
/// Returns an iterator over the hash commitment indices.
|
||||
pub fn iter_hash(&self) -> impl Iterator<Item = (&(Direction, Idx), &HashAlgId)> {
|
||||
pub fn iter_hash(&self) -> impl Iterator<Item = (&(Direction, RangeSet<usize>), &HashAlgId)> {
|
||||
self.commits.iter().filter_map(|(idx, kind)| match kind {
|
||||
TranscriptCommitmentKind::Hash { alg } => Some((idx, alg)),
|
||||
_ => None,
|
||||
@@ -134,7 +134,7 @@ pub struct TranscriptCommitConfigBuilder<'a> {
|
||||
has_encoding: bool,
|
||||
has_hash: bool,
|
||||
default_kind: TranscriptCommitmentKind,
|
||||
commits: HashSet<((Direction, Idx), TranscriptCommitmentKind)>,
|
||||
commits: HashSet<((Direction, RangeSet<usize>), TranscriptCommitmentKind)>,
|
||||
}
|
||||
|
||||
impl<'a> TranscriptCommitConfigBuilder<'a> {
|
||||
@@ -175,15 +175,15 @@ impl<'a> TranscriptCommitConfigBuilder<'a> {
|
||||
direction: Direction,
|
||||
kind: TranscriptCommitmentKind,
|
||||
) -> Result<&mut Self, TranscriptCommitConfigBuilderError> {
|
||||
let idx = Idx::new(ranges.to_range_set());
|
||||
let idx = ranges.to_range_set();
|
||||
|
||||
if idx.end() > self.transcript.len_of_direction(direction) {
|
||||
if idx.end().unwrap_or(0) > self.transcript.len_of_direction(direction) {
|
||||
return Err(TranscriptCommitConfigBuilderError::new(
|
||||
ErrorKind::Index,
|
||||
format!(
|
||||
"range is out of bounds of the transcript ({}): {} > {}",
|
||||
direction,
|
||||
idx.end(),
|
||||
idx.end().unwrap_or(0),
|
||||
self.transcript.len_of_direction(direction)
|
||||
),
|
||||
));
|
||||
@@ -290,7 +290,7 @@ impl fmt::Display for TranscriptCommitConfigBuilderError {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TranscriptCommitRequest {
|
||||
encoding: bool,
|
||||
hash: Vec<(Direction, Idx, HashAlgId)>,
|
||||
hash: Vec<(Direction, RangeSet<usize>, HashAlgId)>,
|
||||
}
|
||||
|
||||
impl TranscriptCommitRequest {
|
||||
@@ -305,7 +305,7 @@ impl TranscriptCommitRequest {
|
||||
}
|
||||
|
||||
/// Returns an iterator over the hash commitments.
|
||||
pub fn iter_hash(&self) -> impl Iterator<Item = &(Direction, Idx, HashAlgId)> {
|
||||
pub fn iter_hash(&self) -> impl Iterator<Item = &(Direction, RangeSet<usize>, HashAlgId)> {
|
||||
self.hash.iter()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
transcript::{
|
||||
commit::MAX_TOTAL_COMMITTED_DATA,
|
||||
encoding::{new_encoder, Encoder, EncodingCommitment},
|
||||
Direction, Idx,
|
||||
Direction,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::{
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub(super) struct Opening {
|
||||
pub(super) direction: Direction,
|
||||
pub(super) idx: Idx,
|
||||
pub(super) idx: RangeSet<usize>,
|
||||
pub(super) blinder: Blinder,
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ impl EncodingProof {
|
||||
commitment: &EncodingCommitment,
|
||||
sent: &[u8],
|
||||
recv: &[u8],
|
||||
) -> Result<(Idx, Idx), EncodingProofError> {
|
||||
) -> Result<(RangeSet<usize>, RangeSet<usize>), EncodingProofError> {
|
||||
let hasher = provider.get(&commitment.root.alg)?;
|
||||
|
||||
let encoder = new_encoder(&commitment.secret);
|
||||
@@ -89,13 +89,13 @@ impl EncodingProof {
|
||||
};
|
||||
|
||||
// Make sure the ranges are within the bounds of the transcript.
|
||||
if idx.end() > data.len() {
|
||||
if idx.end().unwrap_or(0) > data.len() {
|
||||
return Err(EncodingProofError::new(
|
||||
ErrorKind::Proof,
|
||||
format!(
|
||||
"index out of bounds of the transcript ({}): {} > {}",
|
||||
direction,
|
||||
idx.end(),
|
||||
idx.end().unwrap_or(0),
|
||||
data.len()
|
||||
),
|
||||
));
|
||||
@@ -111,7 +111,7 @@ impl EncodingProof {
|
||||
// present in the merkle tree.
|
||||
leaves.push((*id, hasher.hash(&expected_leaf)));
|
||||
|
||||
auth.union_mut(idx.as_range_set());
|
||||
auth.union_mut(idx);
|
||||
}
|
||||
|
||||
// Verify that the expected hashes are present in the merkle tree.
|
||||
@@ -121,7 +121,7 @@ impl EncodingProof {
|
||||
// data is authentic.
|
||||
inclusion_proof.verify(hasher, &commitment.root, leaves)?;
|
||||
|
||||
Ok((Idx(auth_sent), Idx(auth_recv)))
|
||||
Ok((auth_sent, auth_recv))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ mod test {
|
||||
hash::Blake3,
|
||||
transcript::{
|
||||
encoding::{EncoderSecret, EncodingTree},
|
||||
Idx, Transcript,
|
||||
Transcript,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -249,8 +249,8 @@ mod test {
|
||||
fn new_encoding_fixture(secret: EncoderSecret) -> EncodingFixture {
|
||||
let transcript = Transcript::new(POST_JSON, OK_JSON);
|
||||
|
||||
let idx_0 = (Direction::Sent, Idx::new(0..POST_JSON.len()));
|
||||
let idx_1 = (Direction::Received, Idx::new(0..OK_JSON.len()));
|
||||
let idx_0 = (Direction::Sent, RangeSet::from(0..POST_JSON.len()));
|
||||
let idx_1 = (Direction::Received, RangeSet::from(0..OK_JSON.len()));
|
||||
|
||||
let provider = encoding_provider(transcript.sent(), transcript.received());
|
||||
let tree = EncodingTree::new(&Blake3::default(), [&idx_0, &idx_1], &provider).unwrap();
|
||||
@@ -317,7 +317,7 @@ mod test {
|
||||
|
||||
let Opening { idx, .. } = proof.openings.values_mut().next().unwrap();
|
||||
|
||||
*idx = Idx::new([0..3, 13..15]);
|
||||
*idx = RangeSet::from([0..3, 13..15]);
|
||||
|
||||
let err = proof
|
||||
.verify_with_provider(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use bimap::BiMap;
|
||||
use rangeset::{RangeSet, UnionMut};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
@@ -11,7 +12,7 @@ use crate::{
|
||||
proof::{EncodingProof, Opening},
|
||||
EncodingProvider,
|
||||
},
|
||||
Direction, Idx,
|
||||
Direction,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -22,7 +23,7 @@ pub enum EncodingTreeError {
|
||||
#[error("index is out of bounds of the transcript")]
|
||||
OutOfBounds {
|
||||
/// The index.
|
||||
index: Idx,
|
||||
index: RangeSet<usize>,
|
||||
/// The transcript length.
|
||||
transcript_length: usize,
|
||||
},
|
||||
@@ -30,13 +31,13 @@ pub enum EncodingTreeError {
|
||||
#[error("encoding provider is missing an encoding for an index")]
|
||||
MissingEncoding {
|
||||
/// The index which is missing.
|
||||
index: Idx,
|
||||
index: RangeSet<usize>,
|
||||
},
|
||||
/// Index is missing from the tree.
|
||||
#[error("index is missing from the tree")]
|
||||
MissingLeaf {
|
||||
/// The index which is missing.
|
||||
index: Idx,
|
||||
index: RangeSet<usize>,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -49,11 +50,11 @@ pub struct EncodingTree {
|
||||
blinders: Vec<Blinder>,
|
||||
/// Mapping between the index of a leaf and the transcript index it
|
||||
/// corresponds to.
|
||||
idxs: BiMap<usize, (Direction, Idx)>,
|
||||
idxs: BiMap<usize, (Direction, RangeSet<usize>)>,
|
||||
/// Union of all transcript indices in the sent direction.
|
||||
sent_idx: Idx,
|
||||
sent_idx: RangeSet<usize>,
|
||||
/// Union of all transcript indices in the received direction.
|
||||
received_idx: Idx,
|
||||
received_idx: RangeSet<usize>,
|
||||
}
|
||||
|
||||
opaque_debug::implement!(EncodingTree);
|
||||
@@ -68,15 +69,15 @@ impl EncodingTree {
|
||||
/// * `provider` - The encoding provider.
|
||||
pub fn new<'idx>(
|
||||
hasher: &dyn HashAlgorithm,
|
||||
idxs: impl IntoIterator<Item = &'idx (Direction, Idx)>,
|
||||
idxs: impl IntoIterator<Item = &'idx (Direction, RangeSet<usize>)>,
|
||||
provider: &dyn EncodingProvider,
|
||||
) -> Result<Self, EncodingTreeError> {
|
||||
let mut this = Self {
|
||||
tree: MerkleTree::new(hasher.id()),
|
||||
blinders: Vec::new(),
|
||||
idxs: BiMap::new(),
|
||||
sent_idx: Idx::empty(),
|
||||
received_idx: Idx::empty(),
|
||||
sent_idx: RangeSet::default(),
|
||||
received_idx: RangeSet::default(),
|
||||
};
|
||||
|
||||
let mut leaves = Vec::new();
|
||||
@@ -138,7 +139,7 @@ impl EncodingTree {
|
||||
/// * `idxs` - The transcript indices to prove.
|
||||
pub fn proof<'idx>(
|
||||
&self,
|
||||
idxs: impl Iterator<Item = &'idx (Direction, Idx)>,
|
||||
idxs: impl Iterator<Item = &'idx (Direction, RangeSet<usize>)>,
|
||||
) -> Result<EncodingProof, EncodingTreeError> {
|
||||
let mut openings = HashMap::new();
|
||||
for dir_idx in idxs {
|
||||
@@ -171,11 +172,11 @@ impl EncodingTree {
|
||||
}
|
||||
|
||||
/// Returns whether the tree contains the given transcript index.
|
||||
pub fn contains(&self, idx: &(Direction, Idx)) -> bool {
|
||||
pub fn contains(&self, idx: &(Direction, RangeSet<usize>)) -> bool {
|
||||
self.idxs.contains_right(idx)
|
||||
}
|
||||
|
||||
pub(crate) fn idx(&self, direction: Direction) -> &Idx {
|
||||
pub(crate) fn idx(&self, direction: Direction) -> &RangeSet<usize> {
|
||||
match direction {
|
||||
Direction::Sent => &self.sent_idx,
|
||||
Direction::Received => &self.received_idx,
|
||||
@@ -183,7 +184,7 @@ impl EncodingTree {
|
||||
}
|
||||
|
||||
/// Returns the committed transcript indices.
|
||||
pub(crate) fn transcript_indices(&self) -> impl Iterator<Item = &(Direction, Idx)> {
|
||||
pub(crate) fn transcript_indices(&self) -> impl Iterator<Item = &(Direction, RangeSet<usize>)> {
|
||||
self.idxs.right_values()
|
||||
}
|
||||
}
|
||||
@@ -200,7 +201,7 @@ mod tests {
|
||||
|
||||
fn new_tree<'seq>(
|
||||
transcript: &Transcript,
|
||||
idxs: impl Iterator<Item = &'seq (Direction, Idx)>,
|
||||
idxs: impl Iterator<Item = &'seq (Direction, RangeSet<usize>)>,
|
||||
) -> Result<EncodingTree, EncodingTreeError> {
|
||||
let provider = encoding_provider(transcript.sent(), transcript.received());
|
||||
|
||||
@@ -211,8 +212,8 @@ mod tests {
|
||||
fn test_encoding_tree() {
|
||||
let transcript = Transcript::new(POST_JSON, OK_JSON);
|
||||
|
||||
let idx_0 = (Direction::Sent, Idx::new(0..POST_JSON.len()));
|
||||
let idx_1 = (Direction::Received, Idx::new(0..OK_JSON.len()));
|
||||
let idx_0 = (Direction::Sent, RangeSet::from(0..POST_JSON.len()));
|
||||
let idx_1 = (Direction::Received, RangeSet::from(0..OK_JSON.len()));
|
||||
|
||||
let tree = new_tree(&transcript, [&idx_0, &idx_1].into_iter()).unwrap();
|
||||
|
||||
@@ -243,10 +244,10 @@ mod tests {
|
||||
fn test_encoding_tree_multiple_ranges() {
|
||||
let transcript = Transcript::new(POST_JSON, OK_JSON);
|
||||
|
||||
let idx_0 = (Direction::Sent, Idx::new(0..1));
|
||||
let idx_1 = (Direction::Sent, Idx::new(1..POST_JSON.len()));
|
||||
let idx_2 = (Direction::Received, Idx::new(0..1));
|
||||
let idx_3 = (Direction::Received, Idx::new(1..OK_JSON.len()));
|
||||
let idx_0 = (Direction::Sent, RangeSet::from(0..1));
|
||||
let idx_1 = (Direction::Sent, RangeSet::from(1..POST_JSON.len()));
|
||||
let idx_2 = (Direction::Received, RangeSet::from(0..1));
|
||||
let idx_3 = (Direction::Received, RangeSet::from(1..OK_JSON.len()));
|
||||
|
||||
let tree = new_tree(&transcript, [&idx_0, &idx_1, &idx_2, &idx_3].into_iter()).unwrap();
|
||||
|
||||
@@ -273,11 +274,11 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut expected_auth_sent = Idx::default();
|
||||
let mut expected_auth_sent = RangeSet::default();
|
||||
expected_auth_sent.union_mut(&idx_0.1);
|
||||
expected_auth_sent.union_mut(&idx_1.1);
|
||||
|
||||
let mut expected_auth_recv = Idx::default();
|
||||
let mut expected_auth_recv = RangeSet::default();
|
||||
expected_auth_recv.union_mut(&idx_2.1);
|
||||
expected_auth_recv.union_mut(&idx_3.1);
|
||||
|
||||
@@ -289,9 +290,9 @@ mod tests {
|
||||
fn test_encoding_tree_proof_missing_leaf() {
|
||||
let transcript = Transcript::new(POST_JSON, OK_JSON);
|
||||
|
||||
let idx_0 = (Direction::Sent, Idx::new(0..POST_JSON.len()));
|
||||
let idx_1 = (Direction::Received, Idx::new(0..4));
|
||||
let idx_2 = (Direction::Received, Idx::new(4..OK_JSON.len()));
|
||||
let idx_0 = (Direction::Sent, RangeSet::from(0..POST_JSON.len()));
|
||||
let idx_1 = (Direction::Received, RangeSet::from(0..4));
|
||||
let idx_2 = (Direction::Received, RangeSet::from(4..OK_JSON.len()));
|
||||
|
||||
let tree = new_tree(&transcript, [&idx_0, &idx_1].into_iter()).unwrap();
|
||||
|
||||
@@ -305,8 +306,8 @@ mod tests {
|
||||
fn test_encoding_tree_out_of_bounds() {
|
||||
let transcript = Transcript::new(POST_JSON, OK_JSON);
|
||||
|
||||
let idx_0 = (Direction::Sent, Idx::new(0..POST_JSON.len() + 1));
|
||||
let idx_1 = (Direction::Received, Idx::new(0..OK_JSON.len() + 1));
|
||||
let idx_0 = (Direction::Sent, RangeSet::from(0..POST_JSON.len() + 1));
|
||||
let idx_1 = (Direction::Received, RangeSet::from(0..OK_JSON.len() + 1));
|
||||
|
||||
let result = new_tree(&transcript, [&idx_0].into_iter()).unwrap_err();
|
||||
assert!(matches!(result, EncodingTreeError::MissingEncoding { .. }));
|
||||
@@ -321,7 +322,7 @@ mod tests {
|
||||
|
||||
let result = EncodingTree::new(
|
||||
&Blake3::default(),
|
||||
[(Direction::Sent, Idx::new(0..8))].iter(),
|
||||
[(Direction::Sent, RangeSet::from(0..8))].iter(),
|
||||
&provider,
|
||||
)
|
||||
.unwrap_err();
|
||||
|
||||
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
hash::{Blinder, HashAlgId, HashAlgorithm, TypedHash},
|
||||
transcript::{Direction, Idx},
|
||||
transcript::{Direction, RangeSet},
|
||||
};
|
||||
|
||||
/// Hashes plaintext with a blinder.
|
||||
@@ -23,7 +23,7 @@ pub struct PlaintextHash {
|
||||
/// Direction of the plaintext.
|
||||
pub direction: Direction,
|
||||
/// Index of plaintext.
|
||||
pub idx: Idx,
|
||||
pub idx: RangeSet<usize>,
|
||||
/// The hash of the data.
|
||||
pub hash: TypedHash,
|
||||
}
|
||||
@@ -34,7 +34,7 @@ pub struct PlaintextHashSecret {
|
||||
/// Direction of the plaintext.
|
||||
pub direction: Direction,
|
||||
/// Index of plaintext.
|
||||
pub idx: Idx,
|
||||
pub idx: RangeSet<usize>,
|
||||
/// The algorithm of the hash.
|
||||
pub alg: HashAlgId,
|
||||
/// Blinder for the hash.
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
//! Transcript proofs.
|
||||
|
||||
use rangeset::{Cover, ToRangeSet};
|
||||
use rangeset::{Cover, Difference, Subset, ToRangeSet, UnionMut};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{collections::HashSet, fmt};
|
||||
|
||||
use crate::{
|
||||
connection::TranscriptLength,
|
||||
display::FmtRangeSet,
|
||||
hash::{HashAlgId, HashProvider},
|
||||
transcript::{
|
||||
commit::{TranscriptCommitment, TranscriptCommitmentKind},
|
||||
encoding::{EncodingProof, EncodingProofError, EncodingTree},
|
||||
hash::{hash_plaintext, PlaintextHash, PlaintextHashSecret},
|
||||
Direction, Idx, PartialTranscript, Transcript, TranscriptSecret,
|
||||
Direction, PartialTranscript, RangeSet, Transcript, TranscriptSecret,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -77,8 +78,8 @@ impl TranscriptProof {
|
||||
));
|
||||
}
|
||||
|
||||
let mut total_auth_sent = Idx::default();
|
||||
let mut total_auth_recv = Idx::default();
|
||||
let mut total_auth_sent = RangeSet::default();
|
||||
let mut total_auth_recv = RangeSet::default();
|
||||
|
||||
// Verify encoding proof.
|
||||
if let Some(proof) = self.encoding_proof {
|
||||
@@ -120,7 +121,7 @@ impl TranscriptProof {
|
||||
Direction::Received => (self.transcript.received_unsafe(), &mut total_auth_recv),
|
||||
};
|
||||
|
||||
if idx.end() > plaintext.len() {
|
||||
if idx.end().unwrap_or(0) > plaintext.len() {
|
||||
return Err(TranscriptProofError::new(
|
||||
ErrorKind::Hash,
|
||||
"hash opening index is out of bounds",
|
||||
@@ -215,15 +216,15 @@ impl From<EncodingProofError> for TranscriptProofError {
|
||||
/// Union of ranges to reveal.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
struct QueryIdx {
|
||||
sent: Idx,
|
||||
recv: Idx,
|
||||
sent: RangeSet<usize>,
|
||||
recv: RangeSet<usize>,
|
||||
}
|
||||
|
||||
impl QueryIdx {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
sent: Idx::empty(),
|
||||
recv: Idx::empty(),
|
||||
sent: RangeSet::default(),
|
||||
recv: RangeSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +232,7 @@ impl QueryIdx {
|
||||
self.sent.is_empty() && self.recv.is_empty()
|
||||
}
|
||||
|
||||
fn union(&mut self, direction: &Direction, other: &Idx) {
|
||||
fn union(&mut self, direction: &Direction, other: &RangeSet<usize>) {
|
||||
match direction {
|
||||
Direction::Sent => self.sent.union_mut(other),
|
||||
Direction::Received => self.recv.union_mut(other),
|
||||
@@ -241,7 +242,12 @@ impl QueryIdx {
|
||||
|
||||
impl std::fmt::Display for QueryIdx {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "sent: {}, received: {}", self.sent, self.recv)
|
||||
write!(
|
||||
f,
|
||||
"sent: {}, received: {}",
|
||||
FmtRangeSet(&self.sent),
|
||||
FmtRangeSet(&self.recv)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,8 +259,8 @@ pub struct TranscriptProofBuilder<'a> {
|
||||
transcript: &'a Transcript,
|
||||
encoding_tree: Option<&'a EncodingTree>,
|
||||
hash_secrets: Vec<&'a PlaintextHashSecret>,
|
||||
committed_sent: Idx,
|
||||
committed_recv: Idx,
|
||||
committed_sent: RangeSet<usize>,
|
||||
committed_recv: RangeSet<usize>,
|
||||
query_idx: QueryIdx,
|
||||
}
|
||||
|
||||
@@ -264,8 +270,8 @@ impl<'a> TranscriptProofBuilder<'a> {
|
||||
transcript: &'a Transcript,
|
||||
secrets: impl IntoIterator<Item = &'a TranscriptSecret>,
|
||||
) -> Self {
|
||||
let mut committed_sent = Idx::empty();
|
||||
let mut committed_recv = Idx::empty();
|
||||
let mut committed_sent = RangeSet::default();
|
||||
let mut committed_recv = RangeSet::default();
|
||||
|
||||
let mut encoding_tree = None;
|
||||
let mut hash_secrets = Vec::new();
|
||||
@@ -323,15 +329,15 @@ impl<'a> TranscriptProofBuilder<'a> {
|
||||
ranges: &dyn ToRangeSet<usize>,
|
||||
direction: Direction,
|
||||
) -> Result<&mut Self, TranscriptProofBuilderError> {
|
||||
let idx = Idx::new(ranges.to_range_set());
|
||||
let idx = ranges.to_range_set();
|
||||
|
||||
if idx.end() > self.transcript.len_of_direction(direction) {
|
||||
if idx.end().unwrap_or(0) > self.transcript.len_of_direction(direction) {
|
||||
return Err(TranscriptProofBuilderError::new(
|
||||
BuilderErrorKind::Index,
|
||||
format!(
|
||||
"range is out of bounds of the transcript ({}): {} > {}",
|
||||
direction,
|
||||
idx.end(),
|
||||
idx.end().unwrap_or(0),
|
||||
self.transcript.len_of_direction(direction)
|
||||
),
|
||||
));
|
||||
@@ -348,7 +354,10 @@ impl<'a> TranscriptProofBuilder<'a> {
|
||||
let missing = idx.difference(committed);
|
||||
return Err(TranscriptProofBuilderError::new(
|
||||
BuilderErrorKind::MissingCommitment,
|
||||
format!("commitment is missing for ranges in {direction} transcript: {missing}"),
|
||||
format!(
|
||||
"commitment is missing for ranges in {direction} transcript: {}",
|
||||
FmtRangeSet(&missing)
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(self)
|
||||
@@ -403,25 +412,23 @@ impl<'a> TranscriptProofBuilder<'a> {
|
||||
continue;
|
||||
};
|
||||
|
||||
let (sent_dir_idxs, sent_uncovered) =
|
||||
uncovered_query_idx.sent.as_range_set().cover_by(
|
||||
encoding_tree
|
||||
.transcript_indices()
|
||||
.filter(|(dir, _)| *dir == Direction::Sent),
|
||||
|(_, idx)| &idx.0,
|
||||
);
|
||||
let (sent_dir_idxs, sent_uncovered) = uncovered_query_idx.sent.cover_by(
|
||||
encoding_tree
|
||||
.transcript_indices()
|
||||
.filter(|(dir, _)| *dir == Direction::Sent),
|
||||
|(_, idx)| idx,
|
||||
);
|
||||
// Uncovered ranges will be checked with ranges of the next
|
||||
// preferred commitment kind.
|
||||
uncovered_query_idx.sent = Idx(sent_uncovered);
|
||||
uncovered_query_idx.sent = sent_uncovered;
|
||||
|
||||
let (recv_dir_idxs, recv_uncovered) =
|
||||
uncovered_query_idx.recv.as_range_set().cover_by(
|
||||
encoding_tree
|
||||
.transcript_indices()
|
||||
.filter(|(dir, _)| *dir == Direction::Received),
|
||||
|(_, idx)| &idx.0,
|
||||
);
|
||||
uncovered_query_idx.recv = Idx(recv_uncovered);
|
||||
let (recv_dir_idxs, recv_uncovered) = uncovered_query_idx.recv.cover_by(
|
||||
encoding_tree
|
||||
.transcript_indices()
|
||||
.filter(|(dir, _)| *dir == Direction::Received),
|
||||
|(_, idx)| idx,
|
||||
);
|
||||
uncovered_query_idx.recv = recv_uncovered;
|
||||
|
||||
let dir_idxs = sent_dir_idxs
|
||||
.into_iter()
|
||||
@@ -439,25 +446,23 @@ impl<'a> TranscriptProofBuilder<'a> {
|
||||
}
|
||||
}
|
||||
TranscriptCommitmentKind::Hash { alg } => {
|
||||
let (sent_hashes, sent_uncovered) =
|
||||
uncovered_query_idx.sent.as_range_set().cover_by(
|
||||
self.hash_secrets.iter().filter(|hash| {
|
||||
hash.direction == Direction::Sent && &hash.alg == alg
|
||||
}),
|
||||
|hash| &hash.idx.0,
|
||||
);
|
||||
let (sent_hashes, sent_uncovered) = uncovered_query_idx.sent.cover_by(
|
||||
self.hash_secrets.iter().filter(|hash| {
|
||||
hash.direction == Direction::Sent && &hash.alg == alg
|
||||
}),
|
||||
|hash| &hash.idx,
|
||||
);
|
||||
// Uncovered ranges will be checked with ranges of the next
|
||||
// preferred commitment kind.
|
||||
uncovered_query_idx.sent = Idx(sent_uncovered);
|
||||
uncovered_query_idx.sent = sent_uncovered;
|
||||
|
||||
let (recv_hashes, recv_uncovered) =
|
||||
uncovered_query_idx.recv.as_range_set().cover_by(
|
||||
self.hash_secrets.iter().filter(|hash| {
|
||||
hash.direction == Direction::Received && &hash.alg == alg
|
||||
}),
|
||||
|hash| &hash.idx.0,
|
||||
);
|
||||
uncovered_query_idx.recv = Idx(recv_uncovered);
|
||||
let (recv_hashes, recv_uncovered) = uncovered_query_idx.recv.cover_by(
|
||||
self.hash_secrets.iter().filter(|hash| {
|
||||
hash.direction == Direction::Received && &hash.alg == alg
|
||||
}),
|
||||
|hash| &hash.idx,
|
||||
);
|
||||
uncovered_query_idx.recv = recv_uncovered;
|
||||
|
||||
transcript_proof.hash_secrets.extend(
|
||||
sent_hashes
|
||||
@@ -577,7 +582,7 @@ mod tests {
|
||||
#[rstest]
|
||||
fn test_verify_missing_encoding_commitment_root() {
|
||||
let transcript = Transcript::new(GET_WITH_HEADER, OK_JSON);
|
||||
let idxs = vec![(Direction::Received, Idx::new(0..transcript.len().1))];
|
||||
let idxs = vec![(Direction::Received, RangeSet::from(0..transcript.len().1))];
|
||||
let encoding_tree = EncodingTree::new(
|
||||
&Blake3::default(),
|
||||
&idxs,
|
||||
@@ -638,7 +643,7 @@ mod tests {
|
||||
let transcript = Transcript::new(GET_WITH_HEADER, OK_JSON);
|
||||
|
||||
let direction = Direction::Sent;
|
||||
let idx = Idx::new(0..10);
|
||||
let idx = RangeSet::from(0..10);
|
||||
let blinder: Blinder = rng.random();
|
||||
let alg = HashAlgId::SHA256;
|
||||
let hasher = provider.get(&alg).unwrap();
|
||||
@@ -684,7 +689,7 @@ mod tests {
|
||||
let transcript = Transcript::new(GET_WITH_HEADER, OK_JSON);
|
||||
|
||||
let direction = Direction::Sent;
|
||||
let idx = Idx::new(0..10);
|
||||
let idx = RangeSet::from(0..10);
|
||||
let blinder: Blinder = rng.random();
|
||||
let alg = HashAlgId::SHA256;
|
||||
let hasher = provider.get(&alg).unwrap();
|
||||
@@ -894,10 +899,10 @@ mod tests {
|
||||
match kind {
|
||||
BuilderErrorKind::Cover { uncovered, .. } => {
|
||||
if !uncovered_sent_rangeset.is_empty() {
|
||||
assert_eq!(uncovered.sent, Idx(uncovered_sent_rangeset));
|
||||
assert_eq!(uncovered.sent, uncovered_sent_rangeset);
|
||||
}
|
||||
if !uncovered_recv_rangeset.is_empty() {
|
||||
assert_eq!(uncovered.recv, Idx(uncovered_recv_rangeset));
|
||||
assert_eq!(uncovered.recv, uncovered_recv_rangeset);
|
||||
}
|
||||
}
|
||||
_ => panic!("unexpected error kind: {kind:?}"),
|
||||
|
||||
@@ -9,10 +9,11 @@ use mpz_memory_core::{
|
||||
binary::{Binary, U8},
|
||||
};
|
||||
use mpz_vm_core::{Vm, VmError, prelude::*};
|
||||
use rangeset::RangeSet;
|
||||
use tlsn_core::{
|
||||
hash::{Blinder, Hash, HashAlgId, TypedHash},
|
||||
transcript::{
|
||||
Direction, Idx,
|
||||
Direction,
|
||||
hash::{PlaintextHash, PlaintextHashSecret},
|
||||
},
|
||||
};
|
||||
@@ -26,7 +27,7 @@ pub(crate) struct HashCommitFuture {
|
||||
#[allow(clippy::type_complexity)]
|
||||
futs: Vec<(
|
||||
Direction,
|
||||
Idx,
|
||||
RangeSet<usize>,
|
||||
HashAlgId,
|
||||
DecodeFutureTyped<BitVec, Vec<u8>>,
|
||||
)>,
|
||||
@@ -60,7 +61,7 @@ impl HashCommitFuture {
|
||||
pub(crate) fn prove_hash(
|
||||
vm: &mut dyn Vm<Binary>,
|
||||
refs: &TranscriptRefs,
|
||||
idxs: impl IntoIterator<Item = (Direction, Idx, HashAlgId)>,
|
||||
idxs: impl IntoIterator<Item = (Direction, RangeSet<usize>, HashAlgId)>,
|
||||
) -> Result<(HashCommitFuture, Vec<PlaintextHashSecret>), HashCommitError> {
|
||||
let mut futs = Vec::new();
|
||||
let mut secrets = Vec::new();
|
||||
@@ -90,7 +91,7 @@ pub(crate) fn prove_hash(
|
||||
pub(crate) fn verify_hash(
|
||||
vm: &mut dyn Vm<Binary>,
|
||||
refs: &TranscriptRefs,
|
||||
idxs: impl IntoIterator<Item = (Direction, Idx, HashAlgId)>,
|
||||
idxs: impl IntoIterator<Item = (Direction, RangeSet<usize>, HashAlgId)>,
|
||||
) -> Result<HashCommitFuture, HashCommitError> {
|
||||
let mut futs = Vec::new();
|
||||
for (direction, idx, alg, hash_ref, blinder_ref) in
|
||||
@@ -112,8 +113,17 @@ fn hash_commit_inner(
|
||||
vm: &mut dyn Vm<Binary>,
|
||||
role: Role,
|
||||
refs: &TranscriptRefs,
|
||||
idxs: impl IntoIterator<Item = (Direction, Idx, HashAlgId)>,
|
||||
) -> Result<Vec<(Direction, Idx, HashAlgId, Array<U8, 32>, Vector<U8>)>, HashCommitError> {
|
||||
idxs: impl IntoIterator<Item = (Direction, RangeSet<usize>, HashAlgId)>,
|
||||
) -> Result<
|
||||
Vec<(
|
||||
Direction,
|
||||
RangeSet<usize>,
|
||||
HashAlgId,
|
||||
Array<U8, 32>,
|
||||
Vector<U8>,
|
||||
)>,
|
||||
HashCommitError,
|
||||
> {
|
||||
let mut output = Vec::new();
|
||||
let mut hashers = HashMap::new();
|
||||
for (direction, idx, alg) in idxs {
|
||||
|
||||
@@ -3,8 +3,8 @@ use mpz_memory_core::{
|
||||
binary::{Binary, U8},
|
||||
};
|
||||
use mpz_vm_core::{Vm, VmError};
|
||||
use rangeset::Intersection;
|
||||
use tlsn_core::transcript::{Direction, Idx, PartialTranscript};
|
||||
use rangeset::{Intersection, RangeSet};
|
||||
use tlsn_core::transcript::{Direction, PartialTranscript};
|
||||
|
||||
/// References to the application plaintext in the transcript.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
@@ -38,7 +38,11 @@ impl TranscriptRefs {
|
||||
|
||||
/// Returns VM references for the given direction and index, otherwise
|
||||
/// `None` if the index is out of bounds.
|
||||
pub(crate) fn get(&self, direction: Direction, idx: &Idx) -> Option<Vec<Vector<U8>>> {
|
||||
pub(crate) fn get(
|
||||
&self,
|
||||
direction: Direction,
|
||||
idx: &RangeSet<usize>,
|
||||
) -> Option<Vec<Vector<U8>>> {
|
||||
if idx.is_empty() {
|
||||
return Some(Vec::new());
|
||||
}
|
||||
@@ -83,8 +87,8 @@ impl TranscriptRefs {
|
||||
/// Decodes the transcript.
|
||||
pub(crate) fn decode_transcript(
|
||||
vm: &mut dyn Vm<Binary>,
|
||||
sent: &Idx,
|
||||
recv: &Idx,
|
||||
sent: &RangeSet<usize>,
|
||||
recv: &RangeSet<usize>,
|
||||
refs: &TranscriptRefs,
|
||||
) -> Result<(), VmError> {
|
||||
let sent_refs = refs.get(Direction::Sent, sent).expect("index is in bounds");
|
||||
@@ -149,7 +153,7 @@ mod tests {
|
||||
use mpz_memory_core::{FromRaw, Slice, Vector, binary::U8};
|
||||
use rangeset::RangeSet;
|
||||
use std::ops::Range;
|
||||
use tlsn_core::transcript::{Direction, Idx};
|
||||
use tlsn_core::transcript::Direction;
|
||||
|
||||
// TRANSCRIPT_REFS:
|
||||
//
|
||||
@@ -185,7 +189,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let vm_refs = transcript_refs
|
||||
.get(Direction::Sent, &idx_fixture())
|
||||
.get(Direction::Sent, &RangeSet::from(IDXS))
|
||||
.unwrap();
|
||||
|
||||
let expected_refs: Vec<Vector<U8>> = EXPECTED_REFS
|
||||
@@ -204,9 +208,4 @@ mod tests {
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
fn idx_fixture() -> Idx {
|
||||
let set = RangeSet::from(IDXS);
|
||||
Idx::builder().union(&set).build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,13 @@ use mpz_memory_core::{
|
||||
correlated::{Delta, Key, Mac},
|
||||
};
|
||||
use rand::Rng;
|
||||
use rangeset::RangeSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serio::{SinkExt, stream::IoStreamExt};
|
||||
use tlsn_core::{
|
||||
hash::HashAlgorithm,
|
||||
transcript::{
|
||||
Direction, Idx,
|
||||
Direction,
|
||||
encoding::{
|
||||
Encoder, EncoderSecret, EncodingCommitment, EncodingProvider, EncodingProviderError,
|
||||
EncodingTree, EncodingTreeError, new_encoder,
|
||||
@@ -117,7 +118,7 @@ pub(crate) async fn receive<'a>(
|
||||
hasher: &(dyn HashAlgorithm + Send + Sync),
|
||||
refs: &TranscriptRefs,
|
||||
f: impl Fn(Vector<U8>) -> &'a [Mac],
|
||||
idxs: impl IntoIterator<Item = &(Direction, Idx)>,
|
||||
idxs: impl IntoIterator<Item = &(Direction, RangeSet<usize>)>,
|
||||
) -> Result<(EncodingCommitment, EncodingTree), EncodingError> {
|
||||
// Set frame limit and add some extra bytes cushion room.
|
||||
let (sent, recv) = refs.len();
|
||||
|
||||
Reference in New Issue
Block a user