Skip to main content

Scheme

Trait Scheme 

Source
pub trait Scheme:
    Debug
    + Clone
    + Send
    + Sync
    + 'static {
    type Commitment: Digest;
    type Shard: Clone + Debug + Eq + Codec<Cfg = CodecConfig> + Send + Sync + 'static;
    type CheckedShard: Clone + Send + Sync;
    type Error: Debug + Send;

    // Required methods
    fn encode(
        config: &Config,
        data: impl Buf,
        strategy: &impl Strategy,
    ) -> Result<(Self::Commitment, Vec<Self::Shard>), Self::Error>;
    fn check(
        config: &Config,
        commitment: &Self::Commitment,
        index: u16,
        shard: &Self::Shard,
    ) -> Result<Self::CheckedShard, Self::Error>;
    fn decode<'a>(
        config: &Config,
        commitment: &Self::Commitment,
        shards: impl Iterator<Item = &'a Self::CheckedShard>,
        strategy: &impl Strategy,
    ) -> Result<Vec<u8>, Self::Error>;
}
Expand description

A scheme for encoding data into pieces, and recovering the data from those pieces.

§Example

use commonware_coding::{Config, ReedSolomon, Scheme as _};
use commonware_cryptography::Sha256;
use commonware_parallel::Sequential;
use commonware_utils::NZU16;

const STRATEGY: Sequential = Sequential;

type RS = ReedSolomon<Sha256>;

let config = Config {
    minimum_shards: NZU16!(2),
    extra_shards: NZU16!(1),
};
let data = b"Hello!";
// Turn the data into shards, and a commitment to those shards.
let (commitment, shards) =
     RS::encode(&config, data.as_slice(), &STRATEGY).unwrap();

// Each participant checks their shard against the commitment.
let checked_shards: Vec<_> = shards
        .iter()
        .enumerate()
        .map(|(i, shard)| {
            RS::check(&config, &commitment, i as u16, shard).unwrap()
        })
        .collect();

// Decode from any minimum_shards-sized subset.
let data2 = RS::decode(&config, &commitment, checked_shards[..2].iter(), &STRATEGY).unwrap();
assert_eq!(&data[..], &data2[..]);

// Decoding works with different shards, with a guarantee to get the same result.
let data3 = RS::decode(&config, &commitment, checked_shards[1..].iter(), &STRATEGY).unwrap();
assert_eq!(&data[..], &data3[..]);

§Guarantees

Here are additional properties that implementors of this trait need to consider, and that users of this trait can rely on.

§Check Agreement

Scheme::check should agree across honest parties, even for malicious encoders.

It should not be possible for parties A and B to both call check successfully on their own shards, but then have either of them fail when calling check on the other’s shard.

In other words, if an honest party considers their shard to be correctly formed, then other honest parties which have also successfully checked their own shards will agree with that shard being correct.

A violation of this property would be, for example, if a malicious payload could convince two parties that they both have valid shards, but then checking each other’s shards reports issues with those shards.

§Unique Commitments

Scheme::encode MUST be deterministic.

For a given Config and data, the only Scheme::Commitment which should pass Scheme::decode MUST be that produced by Scheme::encode.

In other words, a data has a unique valid commitment associated with it.

Required Associated Types§

Source

type Commitment: Digest

A commitment attesting to the shards of data.

Source

type Shard: Clone + Debug + Eq + Codec<Cfg = CodecConfig> + Send + Sync + 'static

A shard of data, to be received by a participant.

Source

type CheckedShard: Clone + Send + Sync

A shard that has been checked for inclusion in the commitment.

This allows excluding invalid shards from the function signature of Self::decode.

Source

type Error: Debug + Send

The type of errors that can occur during encoding, checking, and decoding.

Required Methods§

Source

fn encode( config: &Config, data: impl Buf, strategy: &impl Strategy, ) -> Result<(Self::Commitment, Vec<Self::Shard>), Self::Error>

Encode a piece of data, returning a commitment, along with shards, and proofs.

Each shard and proof is intended for exactly one participant. The number of shards returned should equal config.minimum_shards + config.extra_shards.

Source

fn check( config: &Config, commitment: &Self::Commitment, index: u16, shard: &Self::Shard, ) -> Result<Self::CheckedShard, Self::Error>

Check the integrity of a shard, producing a checked shard.

This takes in an index, to make sure that the shard you’re checking is associated with the participant you expect it to be.

Source

fn decode<'a>( config: &Config, commitment: &Self::Commitment, shards: impl Iterator<Item = &'a Self::CheckedShard>, strategy: &impl Strategy, ) -> Result<Vec<u8>, Self::Error>

Decode the data from shards received from other participants.

The data must be decodeable with as few as config.minimum_shards, including your own shard.

Calls to this function with the same commitment, but with different shards, or shards in a different order should also result in the same output data, or in failure. In other words, when using the decoding function in a broader system, you get a guarantee that every participant decoding will see the same final data, even if they receive different shards, or receive them in a different order.

§Commitment Binding

Implementations must reject shards that were checked against a different commitment than the one passed to decode. Mixing checked shards from separate encode calls (and thus different commitments) must return an error.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<H: Hasher> Scheme for ReedSolomon<H>

Source§

type Commitment = <H as Hasher>::Digest

Source§

type Shard = Chunk<<H as Hasher>::Digest>

Source§

type CheckedShard = CheckedChunk<<H as Hasher>::Digest>

Source§

type Error = Error

Source§

impl<P: PhasedScheme> Scheme for PhasedAsScheme<P>

Available on neither commonware_stability_BETA nor commonware_stability_GAMMA nor commonware_stability_DELTA nor commonware_stability_EPSILON nor commonware_stability_RESERVED.