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§
Sourcetype Commitment: Digest
type Commitment: Digest
A commitment attesting to the shards of data.
Sourcetype Shard: Clone + Debug + Eq + Codec<Cfg = CodecConfig> + Send + Sync + 'static
type Shard: Clone + Debug + Eq + Codec<Cfg = CodecConfig> + Send + Sync + 'static
A shard of data, to be received by a participant.
Sourcetype CheckedShard: Clone + Send + Sync
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.
Required Methods§
Sourcefn encode(
config: &Config,
data: impl Buf,
strategy: &impl Strategy,
) -> Result<(Self::Commitment, Vec<Self::Shard>), Self::Error>
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.
Sourcefn check(
config: &Config,
commitment: &Self::Commitment,
index: u16,
shard: &Self::Shard,
) -> Result<Self::CheckedShard, Self::Error>
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.
Sourcefn decode<'a>(
config: &Config,
commitment: &Self::Commitment,
shards: impl Iterator<Item = &'a Self::CheckedShard>,
strategy: &impl Strategy,
) -> Result<Vec<u8>, 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>
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>
impl<H: Hasher> Scheme for ReedSolomon<H>
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.
impl<P: PhasedScheme> Scheme for PhasedAsScheme<P>
commonware_stability_BETA nor commonware_stability_GAMMA nor commonware_stability_DELTA nor commonware_stability_EPSILON nor commonware_stability_RESERVED.