commonware_cryptography/reed_solomon/
mod.rs1pub use self::{
20 decoder_result::{DecoderResult, Originals, Recoveries, RecoveryDecoderResult},
21 encoder_result::{EncoderResult, Recovery},
22 engine::SHARD_CHUNK_BYTES,
23 wrappers::{Decoder, Encoder},
24};
25use thiserror::Error;
26
27#[cfg(test)]
28#[macro_use]
29mod test_util;
30
31mod decoder_result;
32mod encoder_result;
33mod wrappers;
34
35pub mod algorithm {
36 #![doc = include_str!("algorithm.md")]
37}
38pub mod engine;
39pub mod rate;
40
41#[derive(Clone, Copy, Debug, Error, PartialEq)]
43pub enum Error {
44 #[error("different shard size: expected {shard_bytes} bytes, got {got} bytes")]
46 DifferentShardSize {
47 shard_bytes: usize,
49 got: usize,
51 },
52
53 #[error("duplicate original shard index: {index}")]
55 DuplicateOriginalShardIndex {
56 index: usize,
58 },
59
60 #[error("duplicate recovery shard index: {index}")]
62 DuplicateRecoveryShardIndex {
63 index: usize,
65 },
66
67 #[error("invalid original shard index: {index} >= original_count {original_count}")]
70 InvalidOriginalShardIndex {
71 original_count: usize,
73 index: usize,
75 },
76
77 #[error("invalid recovery shard index: {index} >= recovery_count {recovery_count}")]
80 InvalidRecoveryShardIndex {
81 recovery_count: usize,
83 index: usize,
85 },
86
87 #[error("invalid shard size: {shard_bytes} bytes (must non-zero and multiple of 2)")]
89 InvalidShardSize {
90 shard_bytes: usize,
92 },
93
94 #[error(
99 "not enough shards: {original_received_count} original + {recovery_received_count} recovery < {original_count} original_count"
100 )]
101 NotEnoughShards {
102 original_count: usize,
104 original_received_count: usize,
106 recovery_received_count: usize,
108 },
109
110 #[error(
112 "too few original shards: got {original_received_count} shards while original_count is {original_count}"
113 )]
114 TooFewOriginalShards {
115 original_count: usize,
117 original_received_count: usize,
119 },
120
121 #[error("too many original shards: got more than original_count ({original_count}) shards")]
123 TooManyOriginalShards {
124 original_count: usize,
126 },
127
128 #[error(
130 "unsupported shard count: {original_count} original shards with {recovery_count} recovery shards"
131 )]
132 UnsupportedShardCount {
133 original_count: usize,
135 recovery_count: usize,
137 },
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143 use crate::reed_solomon::{engine::DefaultEngine, rate::DefaultRate};
144
145 #[test]
146 fn roundtrip() {
147 let original = test_util::generate_original(2, 1024, 123);
148
149 let mut encoder = Encoder::new(2, 3, 1024).unwrap();
150 for shard in &original {
151 encoder.add_original_shard(shard).unwrap();
152 }
153 let encoding = encoder.encode().unwrap();
154 let recovery: Vec<_> = encoding.recovery_iter().map(<[u8]>::to_vec).collect();
155
156 test_util::assert_hash(&recovery, test_util::LOW_2_3);
157
158 let mut decoder = Decoder::new(2, 3, 1024).unwrap();
159 decoder.add_recovery_shard(0, &recovery[0]).unwrap();
160 decoder.add_recovery_shard(1, &recovery[1]).unwrap();
161 let decoding = decoder.decode().unwrap().unwrap();
162 let mut restored = decoding.original_iter();
163
164 assert_eq!(restored.next(), Some((0, original[0].as_slice())));
165 assert_eq!(restored.next(), Some((1, original[1].as_slice())));
166 assert_eq!(restored.next(), None);
167 }
168
169 #[test]
170 fn test_send() {
171 fn assert_send<T: Send>() {}
172 assert_send::<Encoder>();
173 assert_send::<Decoder>();
174 assert_send::<DefaultEngine>();
175 assert_send::<DefaultRate<DefaultEngine>>();
176 assert_send::<DecoderResult<'_>>();
177 assert_send::<RecoveryDecoderResult<'_>>();
178 assert_send::<EncoderResult<'_>>();
179 assert_send::<Error>();
180 }
181
182 #[test]
183 fn test_sync() {
184 fn assert_sync<T: Sync>() {}
185 assert_sync::<Encoder>();
186 assert_sync::<Decoder>();
187 assert_sync::<DefaultEngine>();
188 assert_sync::<DefaultRate<DefaultEngine>>();
189 assert_sync::<DecoderResult<'_>>();
190 assert_sync::<RecoveryDecoderResult<'_>>();
191 assert_sync::<EncoderResult<'_>>();
192 assert_sync::<Error>();
193 }
194}