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

ergoplatform / sigma-rust / 12044238637

27 Nov 2024 05:19AM UTC coverage: 78.34%. First build
12044238637

Pull #782

github

web-flow
Merge 244d652da into 61a345ebc
Pull Request #782: No_std support

112 of 218 new or added lines in 55 files covered. (51.38%)

10952 of 13980 relevant lines covered (78.34%)

3.0 hits per line

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

79.41
/ergotree-ir/src/sigma_protocol/sigma_boolean/cor.rs
1
//! OR conjunction for sigma proposition
2
use core::convert::TryInto;
3

4
use alloc::vec::Vec;
5

6
use super::SigmaBoolean;
7
use super::SigmaConjectureItems;
8
use crate::has_opcode::HasStaticOpCode;
9
use crate::serialization::op_code::OpCode;
10
use crate::serialization::sigma_byte_reader::SigmaByteRead;
11
use crate::serialization::sigma_byte_writer::SigmaByteWrite;
12
use crate::serialization::{SigmaParsingError, SigmaSerializable, SigmaSerializeResult};
13
use crate::sigma_protocol::sigma_boolean::SigmaConjecture;
14

15
/// OR conjunction for sigma proposition
16
#[derive(PartialEq, Eq, Debug, Clone)]
17
pub struct Cor {
18
    /// Items of the conjunctions
19
    pub items: SigmaConjectureItems<SigmaBoolean>,
20
}
21

22
impl HasStaticOpCode for Cor {
23
    const OP_CODE: OpCode = OpCode::OR;
24
}
25

26
impl Cor {
27
    /// Connects the given sigma propositions into COR proposition performing
28
    /// partial evaluation when some of them are trivial propositioins.
29
    pub fn normalized(items: SigmaConjectureItems<SigmaBoolean>) -> SigmaBoolean {
5✔
30
        assert!(!items.is_empty());
10✔
31
        let mut res = Vec::new();
5✔
32
        for it in items {
27✔
33
            match it {
8✔
34
                SigmaBoolean::TrivialProp(true) => return it,
1✔
35
                SigmaBoolean::TrivialProp(false) => (),
36
                _ => res.push(it),
12✔
37
            }
38
        }
39
        if res.is_empty() {
6✔
40
            false.into()
2✔
41
        } else if res.len() == 1 {
18✔
42
            #[allow(clippy::unwrap_used)]
43
            res.first().unwrap().clone()
6✔
44
        } else {
45
            #[allow(clippy::unwrap_used)]
46
            SigmaBoolean::SigmaConjecture(SigmaConjecture::Cor(Cor {
6✔
47
                // should be 2 or more so unwrap is safe here
48
                items: res.try_into().unwrap(),
6✔
49
            }))
50
        }
51
    }
52
}
53

54
impl core::fmt::Display for Cor {
NEW
55
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
×
56
        f.write_str("(")?;
×
57
        for (i, item) in self.items.iter().enumerate() {
×
58
            if i > 0 {
×
59
                f.write_str(" || ")?;
×
60
            }
61
            item.fmt(f)?;
×
62
        }
63
        f.write_str(")")
×
64
    }
65
}
66

67
impl SigmaSerializable for Cor {
68
    fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
5✔
69
        w.put_u16(self.items.len() as u16)?;
5✔
70
        self.items.iter().try_for_each(|i| i.sigma_serialize(w))
15✔
71
    }
72

73
    fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
7✔
74
        let items_count = r.get_u16()?;
14✔
75
        let mut items = Vec::with_capacity(items_count as usize);
7✔
76
        for _ in 0..items_count {
21✔
77
            items.push(SigmaBoolean::sigma_parse(r)?);
14✔
78
        }
79
        Ok(Cor {
7✔
80
            items: items.try_into()?,
14✔
81
        })
82
    }
83
}
84

85
#[cfg(feature = "arbitrary")]
86
#[allow(clippy::unwrap_used)]
87
mod arbitrary {
88
    use super::*;
89
    use proptest::collection::vec;
90
    use proptest::prelude::*;
91

92
    impl Arbitrary for Cor {
93
        type Parameters = ();
94
        type Strategy = BoxedStrategy<Self>;
95

96
        fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
1✔
97
            vec(any::<SigmaBoolean>(), 2..=4)
1✔
98
                .prop_map(|items| Cor {
2✔
99
                    items: items.try_into().unwrap(),
1✔
100
                })
101
                .boxed()
102
        }
103
    }
104
}
105

106
#[allow(clippy::panic)]
107
#[allow(clippy::unwrap_used)]
108
#[allow(clippy::panic)]
109
#[cfg(test)]
110
#[cfg(feature = "arbitrary")]
111
mod tests {
112
    use super::*;
113
    use crate::serialization::sigma_serialize_roundtrip;
114
    use crate::sigma_protocol::sigma_boolean::ProveDlog;
115

116
    use alloc::vec;
117
    use core::convert::TryInto;
118
    use proptest::prelude::*;
119
    use sigma_test_util::force_any_val;
120

121
    #[test]
122
    fn trivial_true() {
123
        let cor = Cor::normalized(vec![true.into(), false.into()].try_into().unwrap());
124
        assert!(matches!(cor, SigmaBoolean::TrivialProp(true)));
125
    }
126

127
    #[test]
128
    fn trivial_false() {
129
        let cor = Cor::normalized(vec![false.into(), false.into()].try_into().unwrap());
130
        assert!(matches!(cor, SigmaBoolean::TrivialProp(false)));
131
    }
132

133
    #[test]
134
    fn pk_triv_true() {
135
        let pk = force_any_val::<ProveDlog>();
136
        let cor = Cor::normalized(vec![pk.into(), true.into()].try_into().unwrap());
137
        assert!(matches!(cor, SigmaBoolean::TrivialProp(true)));
138
    }
139

140
    #[test]
141
    fn pk_triv_false() {
142
        let pk = force_any_val::<ProveDlog>();
143
        let cor = Cor::normalized(vec![pk.clone().into(), false.into()].try_into().unwrap());
144
        let res: ProveDlog = cor.try_into().unwrap();
145
        assert_eq!(res, pk);
146
    }
147

148
    #[test]
149
    fn pk_pk() {
150
        let pk1 = force_any_val::<ProveDlog>();
151
        let pk2 = force_any_val::<ProveDlog>();
152
        let pks: SigmaConjectureItems<SigmaBoolean> =
153
            vec![pk1.into(), pk2.into()].try_into().unwrap();
154
        let cor = Cor::normalized(pks.clone());
155
        assert!(matches!(
156
            cor,
157
            SigmaBoolean::SigmaConjecture(SigmaConjecture::Cor(Cor {items})) if items == pks
158
        ));
159
    }
160

161
    proptest! {
162

163
        #[test]
164
        fn sigma_proposition_ser_roundtrip(
165
            v in any_with::<Cor>(())) {
166
                prop_assert_eq![sigma_serialize_roundtrip(&v), v]
167
        }
168
    }
169
}
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

© 2025 Coveralls, Inc