• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

input-output-hk / catalyst-libs / 16597827432

29 Jul 2025 01:40PM UTC coverage: 63.556% (-0.6%) from 64.185%
16597827432

push

github

web-flow
chore(rust/hermes-ipfs): bump rust-ipfs for hermes-ipfs (#422)

* bump rust-ipfs

* bump catalyst-ci

* bump catalyst-ci

* sync-cfg

* upd to rust 1.88

* spelling

* fix lints

* revert clippy fix

* Revert "upd to rust 1.88"

This reverts commit 52a726ec5.

* Revert rust fmt related changes

* Remove the `match_on_vec_items` lint which has been removed in Rust 1.88

* Fix lints

* Revert accidental change

* Revert "Revert accidental change"

This reverts commit 5e9d637d6.

---------

Co-authored-by: Steven Johnson <stevenj@users.noreply.github.com>
Co-authored-by: rafal-ch <rafal.chabowski@iohk.io>

14 of 47 new or added lines in 20 files covered. (29.79%)

62 existing lines in 29 files now uncovered.

9649 of 15182 relevant lines covered (63.56%)

2584.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.81
/rust/catalyst-voting/src/crypto/zk_unit_vector/decoding.rs
1
//! ZK Unit Vector objects decoding implementation
2

3
use std::io::Read;
4

5
use anyhow::anyhow;
6

7
use super::{Announcement, Ciphertext, GroupElement, ResponseRandomness, Scalar, UnitVectorProof};
8
use crate::utils::read_array;
9

10
impl UnitVectorProof {
11
    /// Get an underlying vector length.
12
    ///
13
    /// **Note** each vector field has the same length.
14
    #[must_use]
15
    pub fn size(&self) -> usize {
256✔
16
        self.0.len()
256✔
17
    }
256✔
18

19
    /// Decode `UnitVectorProof` from bytes.
20
    ///
21
    /// # Errors
22
    ///   - Cannot decode announcement value.
23
    ///   - Cannot decode ciphertext value.
24
    ///   - Cannot decode response randomness value.
25
    ///   - Cannot decode scalar value.
26
    pub fn from_bytes<R: Read>(reader: &mut R, len: usize) -> anyhow::Result<Self> {
256✔
27
        let ann = (0..len)
256✔
28
            .map(|i| {
530✔
29
                let bytes = read_array(reader)?;
530✔
30
                Announcement::from_bytes(&bytes).map_err(|e| {
530✔
31
                    anyhow!(
×
32
                        "Cannot decode announcement at {i}, \
×
33
                        error: {e}."
×
34
                    )
UNCOV
35
                })
×
36
            })
530✔
37
            .collect::<anyhow::Result<_>>()?;
256✔
38
        let dl = (0..len)
256✔
39
            .map(|i| {
530✔
40
                let bytes = read_array(reader)?;
530✔
41
                Ciphertext::from_bytes(&bytes).map_err(|e| {
530✔
42
                    anyhow!(
×
43
                        "Cannot decode ciphertext at {i}, \
×
44
                        error: {e}."
×
45
                    )
UNCOV
46
                })
×
47
            })
530✔
48
            .collect::<anyhow::Result<_>>()?;
256✔
49
        let rr = (0..len)
256✔
50
            .map(|i| {
530✔
51
                let bytes = read_array(reader)?;
530✔
52
                ResponseRandomness::from_bytes(&bytes).map_err(|e| {
530✔
53
                    anyhow!(
×
54
                        "Cannot decode response randomness at {i}, \
×
55
                        error: {e}."
×
56
                    )
UNCOV
57
                })
×
58
            })
530✔
59
            .collect::<anyhow::Result<_>>()?;
256✔
60

61
        let bytes = read_array(reader)?;
256✔
62
        let scalar =
256✔
63
            Scalar::from_bytes(bytes).map_err(|_| anyhow!("Cannot decode scalar field."))?;
256✔
64
        Ok(Self(ann, dl, rr, scalar))
256✔
65
    }
256✔
66

67
    /// Get a deserialized bytes size
68
    #[must_use]
69
    fn bytes_size(&self) -> usize {
512✔
70
        Scalar::BYTES_SIZE
512✔
71
            + self.0.len() * Announcement::BYTES_SIZE
512✔
72
            + self.0.len() * Ciphertext::BYTES_SIZE
512✔
73
            + self.0.len() * ResponseRandomness::BYTES_SIZE
512✔
74
    }
512✔
75

76
    /// Encode `EncryptedVote` tos bytes.
77
    #[must_use]
78
    pub fn to_bytes(&self) -> Vec<u8> {
256✔
79
        let mut res = Vec::with_capacity(self.bytes_size());
256✔
80
        self.0
256✔
81
            .iter()
256✔
82
            .for_each(|c| res.extend_from_slice(&c.to_bytes()));
530✔
83
        self.1
256✔
84
            .iter()
256✔
85
            .for_each(|c| res.extend_from_slice(&c.to_bytes()));
530✔
86
        self.2
256✔
87
            .iter()
256✔
88
            .for_each(|c| res.extend_from_slice(&c.to_bytes()));
530✔
89
        res.extend_from_slice(&self.3.to_bytes());
256✔
90
        res
256✔
91
    }
256✔
92
}
93

94
impl Announcement {
95
    /// `Announcement` bytes size
96
    pub const BYTES_SIZE: usize = GroupElement::BYTES_SIZE * 3;
97

98
    /// Decode `Announcement` from bytes.
99
    ///
100
    /// # Errors
101
    ///   - `AnnouncementDecodingError`
102
    #[allow(clippy::unwrap_used)]
103
    pub fn from_bytes(bytes: &[u8; Self::BYTES_SIZE]) -> anyhow::Result<Self> {
786✔
104
        let i = GroupElement::from_bytes(bytes[0..32].try_into().unwrap())
786✔
105
            .map_err(|_| anyhow!("Cannot decode `i` group element field."))?;
786✔
106
        let b = GroupElement::from_bytes(bytes[32..64].try_into().unwrap())
786✔
107
            .map_err(|_| anyhow!("Cannot decode `b` group element field."))?;
786✔
108
        let a = GroupElement::from_bytes(bytes[64..96].try_into().unwrap())
786✔
109
            .map_err(|_| anyhow!("Cannot decode `a` group element field."))?;
786✔
110
        Ok(Self { i, b, a })
786✔
111
    }
786✔
112

113
    /// Encode `Announcement` tos bytes.
114
    #[must_use]
115
    pub fn to_bytes(&self) -> [u8; Self::BYTES_SIZE] {
786✔
116
        let mut res = [0; 96];
786✔
117
        res[0..32].copy_from_slice(&self.i.to_bytes());
786✔
118
        res[32..64].copy_from_slice(&self.b.to_bytes());
786✔
119
        res[64..96].copy_from_slice(&self.a.to_bytes());
786✔
120
        res
786✔
121
    }
786✔
122
}
123

124
impl ResponseRandomness {
125
    /// `ResponseRandomness` bytes size
126
    pub const BYTES_SIZE: usize = Scalar::BYTES_SIZE * 3;
127

128
    /// Decode `ResponseRandomness` from bytes.
129
    ///
130
    /// # Errors
131
    ///   - Cannot decode scalar field.
132
    #[allow(clippy::unwrap_used)]
133
    pub fn from_bytes(bytes: &[u8; Self::BYTES_SIZE]) -> anyhow::Result<Self> {
786✔
134
        let z = Scalar::from_bytes(bytes[0..32].try_into().unwrap())
786✔
135
            .map_err(|_| anyhow!("Cannot decode `z` scalar field."))?;
786✔
136
        let w = Scalar::from_bytes(bytes[32..64].try_into().unwrap())
786✔
137
            .map_err(|_| anyhow!("Cannot decode `w` scalar field."))?;
786✔
138
        let v = Scalar::from_bytes(bytes[64..96].try_into().unwrap())
786✔
139
            .map_err(|_| anyhow!("Cannot decode `v` scalar field."))?;
786✔
140
        Ok(Self { z, w, v })
786✔
141
    }
786✔
142

143
    /// Encode `ResponseRandomness` tos bytes.
144
    #[must_use]
145
    pub fn to_bytes(&self) -> [u8; Self::BYTES_SIZE] {
786✔
146
        let mut res = [0; 96];
786✔
147
        res[0..32].copy_from_slice(&self.z.to_bytes());
786✔
148
        res[32..64].copy_from_slice(&self.w.to_bytes());
786✔
149
        res[64..96].copy_from_slice(&self.v.to_bytes());
786✔
150
        res
786✔
151
    }
786✔
152
}
153

154
#[cfg(test)]
155
mod tests {
156
    use test_strategy::proptest;
157

158
    use super::*;
159

160
    #[proptest]
161
    fn proof_to_bytes_from_bytes_test(
162
        #[strategy(0..5usize)] _size: usize, #[any(#_size)] p1: UnitVectorProof,
163
    ) {
164
        let bytes = p1.to_bytes();
165
        assert_eq!(bytes.len(), p1.bytes_size());
166
        let p2 = UnitVectorProof::from_bytes(&mut bytes.as_slice(), p1.size()).unwrap();
167
        assert_eq!(p1, p2);
168
    }
169

170
    #[proptest]
171
    fn announcement_to_bytes_from_bytes_test(a1: Announcement) {
172
        let bytes = a1.to_bytes();
173
        let a2 = Announcement::from_bytes(&bytes).unwrap();
174
        assert_eq!(a1, a2);
175
    }
176

177
    #[proptest]
178
    fn response_randomness_to_bytes_from_bytes_test(r1: ResponseRandomness) {
179
        let bytes = r1.to_bytes();
180
        let r2 = ResponseRandomness::from_bytes(&bytes).unwrap();
181
        assert_eq!(r1, r2);
182
    }
183
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc