vsss_rs_std/
share.rs

1/*
2    Copyright Michael Lodder. All Rights Reserved.
3    SPDX-License-Identifier: Apache-2.0
4*/
5
6use crate::*;
7use core::{
8    array::TryFromSliceError,
9    convert::TryFrom,
10    fmt::{self, Formatter},
11};
12use elliptic_curve::{ff::PrimeField, group::GroupEncoding};
13use serde::{
14    de::{self, SeqAccess, Unexpected, Visitor},
15    ser::SerializeSeq,
16    Deserialize, Deserializer, Serialize, Serializer,
17};
18use subtle::Choice;
19use zeroize::ZeroizeOnDrop;
20
21/// A Shamir simple secret share
22/// provides no integrity checking
23/// The first byte is the X-coordinate or identifier
24/// The remaining bytes are the Y-coordinate
25#[derive(Clone, Debug, Default, PartialEq, Eq, ZeroizeOnDrop)]
26pub struct Share(pub Vec<u8>);
27
28impl Serialize for Share {
29    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
30    where
31        S: Serializer,
32    {
33        if s.is_human_readable() {
34            hex::encode(&self.0).serialize(s)
35        } else {
36            let mut tupler = s.serialize_seq(Some(self.0.len()))?;
37            for b in &self.0 {
38                tupler.serialize_element(b)?;
39            }
40            tupler.end()
41        }
42    }
43}
44
45impl<'de> Deserialize<'de> for Share {
46    fn deserialize<D>(d: D) -> Result<Self, D::Error>
47    where
48        D: Deserializer<'de>,
49    {
50        struct ShareVisitor;
51
52        impl<'de> Visitor<'de> for ShareVisitor {
53            type Value = Share;
54
55            fn expecting(&self, f: &mut Formatter) -> fmt::Result {
56                write!(f, "a hex string or byte sequence")
57            }
58
59            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
60            where
61                E: de::Error,
62            {
63                let bytes = hex::decode(v)
64                    .map_err(|_e| de::Error::invalid_value(Unexpected::Str(v), &self))?;
65                Ok(Share(bytes))
66            }
67
68            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
69            where
70                A: SeqAccess<'de>,
71            {
72                let mut bytes = Vec::new();
73                while let Some(b) = seq.next_element()? {
74                    bytes.push(b);
75                }
76                Ok(Share(bytes))
77            }
78        }
79
80        if d.is_human_readable() {
81            d.deserialize_str(ShareVisitor)
82        } else {
83            d.deserialize_seq(ShareVisitor)
84        }
85    }
86}
87
88impl AsRef<[u8]> for Share {
89    fn as_ref(&self) -> &[u8] {
90        &self.0
91    }
92}
93
94impl TryFrom<&[u8]> for Share {
95    type Error = TryFromSliceError;
96
97    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
98        Ok(Self(bytes.to_vec()))
99    }
100}
101
102impl From<Share> for Vec<u8> {
103    fn from(share: Share) -> Self {
104        share.0.clone()
105    }
106}
107
108impl Share {
109    /// True if all value bytes are zero in constant time
110    pub fn is_zero(&self) -> Choice {
111        let mut v = 0i8;
112        for b in self.value() {
113            v |= *b as i8;
114        }
115        let v = ((v | -v) >> 7) + 1;
116        Choice::from(v as u8)
117    }
118
119    /// The identifier for this share
120    pub fn identifier(&self) -> u8 {
121        self.0[0]
122    }
123
124    /// The raw byte value of the share
125    pub fn value(&self) -> &[u8] {
126        &self.0[1..]
127    }
128
129    /// Convert this share into a group element
130    pub fn as_group_element<G: GroupEncoding>(&self) -> VsssResult<G> {
131        let mut repr = G::Repr::default();
132        repr.as_mut().copy_from_slice(self.value());
133        Option::<G>::from(G::from_bytes(&repr)).ok_or(Error::InvalidShareConversion)
134    }
135
136    /// Convert group element into a share
137    pub fn from_group_element<G: GroupEncoding>(identifier: u8, group: G) -> VsssResult<Self> {
138        if identifier == 0 {
139            Err(Error::InvalidShareConversion)
140        } else {
141            let repr = group.to_bytes();
142            let mut bytes = vec![identifier; repr.as_ref().len() + 1];
143            bytes[1..].copy_from_slice(repr.as_ref());
144            Ok(Self(bytes))
145        }
146    }
147
148    /// Convert this share into a prime field element
149    pub fn as_field_element<F: PrimeField>(&self) -> VsssResult<F> {
150        let mut repr = F::Repr::default();
151        repr.as_mut().copy_from_slice(self.value());
152        Option::<F>::from(F::from_repr(repr)).ok_or(Error::InvalidShareConversion)
153    }
154
155    /// Convert field element into a share
156    pub fn from_field_element<F: PrimeField>(identifier: u8, field: F) -> VsssResult<Self> {
157        if identifier == 0 {
158            Err(Error::InvalidShareConversion)
159        } else {
160            let repr = field.to_repr();
161            let mut bytes = vec![identifier; repr.as_ref().len() + 1];
162            bytes[1..].copy_from_slice(repr.as_ref());
163            Ok(Self(bytes))
164        }
165    }
166}