commonware_coding/
no_coding.rs

1use crate::Config;
2use commonware_codec::{EncodeSize, RangeCfg, Read, Write};
3use commonware_cryptography::Hasher;
4use commonware_parallel::Strategy;
5use std::marker::PhantomData;
6use thiserror::Error;
7
8#[derive(Error, Debug)]
9pub enum Error {
10    #[error("data does not match commitment")]
11    BadData,
12}
13
14/// A trivial scheme which performs no coding at all.
15///
16/// Instead, each shard contains all of the data.
17///
18/// The commitment is simply a hash of that data. This struct is generic
19/// over the choice of [commonware_cryptography::Hasher].
20#[derive(Clone, Copy)]
21pub struct NoCoding<H> {
22    _marker: PhantomData<H>,
23}
24
25impl<H> std::fmt::Debug for NoCoding<H> {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        f.debug_struct("NoCoding").finish()
28    }
29}
30
31#[derive(Clone, PartialEq, Eq)]
32#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
33pub struct Shard(Vec<u8>);
34
35impl EncodeSize for Shard {
36    fn encode_size(&self) -> usize {
37        self.0.encode_size()
38    }
39}
40
41impl Write for Shard {
42    fn write(&self, buf: &mut impl bytes::BufMut) {
43        self.0.write(buf)
44    }
45}
46
47impl Read for Shard {
48    type Cfg = crate::CodecConfig;
49
50    fn read_cfg(
51        buf: &mut impl bytes::Buf,
52        cfg: &Self::Cfg,
53    ) -> Result<Self, commonware_codec::Error> {
54        Vec::read_cfg(buf, &(RangeCfg::new(0..=cfg.maximum_shard_size), ())).map(Self)
55    }
56}
57
58#[derive(Clone, PartialEq, Eq)]
59#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
60pub struct ReShard(());
61
62impl EncodeSize for ReShard {
63    fn encode_size(&self) -> usize {
64        0
65    }
66}
67
68impl Write for ReShard {
69    fn write(&self, _buf: &mut impl bytes::BufMut) {}
70}
71
72impl Read for ReShard {
73    type Cfg = crate::CodecConfig;
74
75    fn read_cfg(
76        _buf: &mut impl bytes::Buf,
77        _cfg: &Self::Cfg,
78    ) -> Result<Self, commonware_codec::Error> {
79        Ok(Self(()))
80    }
81}
82
83impl<H: Hasher> crate::Scheme for NoCoding<H> {
84    type Commitment = H::Digest;
85
86    type Shard = Shard;
87
88    type ReShard = ReShard;
89
90    type CheckedShard = ();
91
92    type CheckingData = Vec<u8>;
93
94    type Error = Error;
95
96    fn encode(
97        config: &crate::Config,
98        mut data: impl bytes::Buf,
99        _strategy: &impl Strategy,
100    ) -> Result<(Self::Commitment, Vec<Self::Shard>), Self::Error> {
101        let data: Vec<u8> = data.copy_to_bytes(data.remaining()).to_vec();
102        let commitment = H::new().update(&data).finalize();
103        let shards = (0..config.total_shards())
104            .map(|_| Shard(data.clone()))
105            .collect();
106        Ok((commitment, shards))
107    }
108
109    fn reshard(
110        _config: &Config,
111        commitment: &Self::Commitment,
112        _index: u16,
113        shard: Self::Shard,
114    ) -> Result<(Self::CheckingData, Self::CheckedShard, Self::ReShard), Self::Error> {
115        let my_commitment = H::new().update(shard.0.as_slice()).finalize();
116        if &my_commitment != commitment {
117            return Err(Error::BadData);
118        }
119        Ok((shard.0, (), ReShard(())))
120    }
121
122    fn check(
123        _config: &Config,
124        _commitment: &Self::Commitment,
125        _checking_data: &Self::CheckingData,
126        _index: u16,
127        _reshard: Self::ReShard,
128    ) -> Result<Self::CheckedShard, Self::Error> {
129        Ok(())
130    }
131
132    fn decode(
133        _config: &Config,
134        _commitment: &Self::Commitment,
135        checking_data: Self::CheckingData,
136        _shards: &[Self::CheckedShard],
137        _strategy: &impl Strategy,
138    ) -> Result<Vec<u8>, Self::Error> {
139        Ok(checking_data)
140    }
141}
142
143impl<H: Hasher> crate::ValidatingScheme for NoCoding<H> {}
144
145#[cfg(all(test, feature = "arbitrary"))]
146mod conformance {
147    use super::*;
148    use commonware_codec::conformance::CodecConformance;
149
150    commonware_conformance::conformance_tests! {
151        CodecConformance<Shard>,
152        CodecConformance<ReShard>
153    }
154}