1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use alloc::vec::Vec;
use super::field::GF256;
#[cfg(feature = "fuzzing")]
use arbitrary::Arbitrary;
#[cfg(feature = "zeroize_memory")]
use zeroize::Zeroize;
#[derive(Clone)]
#[cfg_attr(feature = "fuzzing", derive(Arbitrary, Debug))]
#[cfg_attr(feature = "zeroize_memory", derive(Zeroize))]
#[cfg_attr(feature = "zeroize_memory", zeroize(drop))]
pub struct Share {
pub x: GF256,
pub y: Vec<GF256>,
}
impl From<&Share> for Vec<u8> {
fn from(s: &Share) -> Vec<u8> {
let mut bytes = Vec::with_capacity(s.y.len() + 1);
bytes.push(s.x.0);
bytes.extend(s.y.iter().map(|p| p.0));
bytes
}
}
impl core::convert::TryFrom<&[u8]> for Share {
type Error = &'static str;
fn try_from(s: &[u8]) -> Result<Share, Self::Error> {
if s.len() < 2 {
Err("A Share must be at least 2 bytes long")
} else {
let x = GF256(s[0]);
let y = s[1..].iter().map(|p| GF256(*p)).collect();
Ok(Share { x, y })
}
}
}
#[cfg(test)]
mod tests {
use super::{Share, GF256};
use alloc::{vec, vec::Vec};
use core::convert::TryFrom;
#[test]
fn vec_from_share_works() {
let share = Share {
x: GF256(1),
y: vec![GF256(2), GF256(3)],
};
let bytes = Vec::from(&share);
assert_eq!(bytes, vec![1, 2, 3]);
}
#[test]
fn share_from_u8_slice_works() {
let bytes = [1, 2, 3];
let share = Share::try_from(&bytes[..]).unwrap();
assert_eq!(share.x, GF256(1));
assert_eq!(share.y, vec![GF256(2), GF256(3)]);
}
}