Skip to content

Commit 7de11cc

Browse files
ProofResponse, ProofAnnouncementElement, etc.
1 parent 9cad94c commit 7de11cc

File tree

3 files changed

+160
-25
lines changed

3 files changed

+160
-25
lines changed

rust/catalyst-contest/src/choices.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ impl Encode<()> for Choices {
101101
#[cfg(test)]
102102
mod tests {
103103
use super::*;
104-
use crate::row_proof::{ProofAnnouncement, ProofResponse, ProofScalar, SingleSelectionProof};
104+
use crate::row_proof::{
105+
ProofAnnouncement, ProofAnnouncementElement, ProofResponse, ProofScalar,
106+
SingleSelectionProof,
107+
};
105108

106109
#[test]
107110
fn clear_roundtrip() {
@@ -124,12 +127,20 @@ mod tests {
124127
choices: vec![],
125128
row_proof: Some(RowProof {
126129
selections: vec![SingleSelectionProof {
127-
announcement: ProofAnnouncement {},
130+
announcement: ProofAnnouncement(
131+
ProofAnnouncementElement(bytes),
132+
ProofAnnouncementElement(bytes),
133+
ProofAnnouncementElement(bytes),
134+
),
128135
choice: ElgamalRistretto255Choice {
129136
c1: bytes,
130137
c2: bytes,
131138
},
132-
response: ProofResponse {},
139+
response: ProofResponse(
140+
ProofScalar(bytes),
141+
ProofScalar(bytes),
142+
ProofScalar(bytes),
143+
),
133144
}],
134145
scalar: ProofScalar(bytes),
135146
}),

rust/catalyst-contest/src/contest_ballot.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,10 @@ mod tests {
114114
use crate::{
115115
EncryptedBlock, RowProof,
116116
elgamal_ristretto255_choice::ElgamalRistretto255Choice,
117-
row_proof::{ProofAnnouncement, ProofResponse, ProofScalar, SingleSelectionProof},
117+
row_proof::{
118+
ProofAnnouncement, ProofAnnouncementElement, ProofResponse, ProofScalar,
119+
SingleSelectionProof,
120+
},
118121
};
119122

120123
#[test]
@@ -140,12 +143,20 @@ mod tests {
140143
}],
141144
row_proof: Some(RowProof {
142145
selections: vec![SingleSelectionProof {
143-
announcement: ProofAnnouncement {},
146+
announcement: ProofAnnouncement(
147+
ProofAnnouncementElement(bytes),
148+
ProofAnnouncementElement(bytes),
149+
ProofAnnouncementElement(bytes),
150+
),
144151
choice: ElgamalRistretto255Choice {
145152
c1: bytes,
146153
c2: bytes,
147154
},
148-
response: ProofResponse {},
155+
response: ProofResponse(
156+
ProofScalar(bytes),
157+
ProofScalar(bytes),
158+
ProofScalar(bytes),
159+
),
149160
}],
150161
scalar: ProofScalar(bytes),
151162
}),

rust/catalyst-contest/src/row_proof.rs

Lines changed: 132 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,24 @@ use minicbor::{Decode, Decoder, Encode, Encoder, encode::Write};
55

66
use crate::ElgamalRistretto255Choice;
77

8+
/// A length of the underlying CBOR array of the `ProofScalar` type.
89
const SCALAR_PROOF_LEN: u64 = 32;
910

11+
/// A length of the underlying CBOR array of the `ProofAnnouncementElement` type.
12+
const PROOF_ANNOUNCEMENT_ELEMENT_LEN: u64 = 32;
13+
14+
/// A minimal length (number of elements) of the
15+
/// `zkproof-elgamal-ristretto255-unit-vector-with-single-selection` array.
16+
///
17+
///
18+
/// The number of elements consists of the following:
19+
/// - 7 (zkproof-elgamal-ristretto255-unit-vector-with-single-selection-item)
20+
/// - 3 (zkproof-elgamal-announcement = x3 zkproof-elgamal-group-element)
21+
/// - 1 (elgamal-ristretto255-encrypted-choice)
22+
/// - 3 (zkproof-ed25519-r-response = x3 zkproof-ed25519-scalar)
23+
/// - 1 (zkproof-ed25519-scalar)
24+
const MIN_SELECTION_LEN: u64 = 8;
25+
1026
/// A universal encrypted row proof.
1127
///
1228
/// The CDDL schema:
@@ -57,7 +73,20 @@ pub struct ProofScalar(pub [u8; SCALAR_PROOF_LEN as usize]);
5773
/// zkproof-elgamal-group-element = bytes .size 32
5874
/// ```
5975
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
60-
pub struct ProofAnnouncement {}
76+
pub struct ProofAnnouncement(
77+
pub ProofAnnouncementElement,
78+
pub ProofAnnouncementElement,
79+
pub ProofAnnouncementElement,
80+
);
81+
82+
/// An individual Elgamal group element used in ZK proofs.
83+
///
84+
/// The CDDL schema:
85+
/// ```cddl
86+
/// zkproof-elgamal-group-element = bytes .size 32
87+
/// ```
88+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
89+
pub struct ProofAnnouncementElement(pub [u8; PROOF_ANNOUNCEMENT_ELEMENT_LEN as usize]);
6190

6291
/// A ZK proof response values for Ed25519.
6392
///
@@ -67,7 +96,7 @@ pub struct ProofAnnouncement {}
6796
/// zkproof-ed25519-r-response = ( zkproof-ed25519-scalar, zkproof-ed25519-scalar, zkproof-ed25519-scalar )
6897
/// ```
6998
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
70-
pub struct ProofResponse {}
99+
pub struct ProofResponse(pub ProofScalar, pub ProofScalar, pub ProofScalar);
71100

72101
impl Decode<'_, ()> for RowProof {
73102
fn decode(
@@ -88,17 +117,16 @@ impl Decode<'_, ()> for RowProof {
88117
}
89118

90119
let len = decode_array_len(d, "row proof single selection")?;
91-
if len < 2 {
120+
if len < MIN_SELECTION_LEN || !len.is_multiple_of(MIN_SELECTION_LEN) {
92121
return Err(minicbor::decode::Error::message(format!(
93-
"Unexpected row proof single selection array length {len}, expected ata least 2"
122+
"Unexpected row proof single selection array length {len}, expected multiplier of {MIN_SELECTION_LEN}"
94123
)));
95124
}
96125

97126
let mut selections = Vec::with_capacity(len as usize - 1);
98-
for _ in 0..len - 1 {
127+
for _ in 0..len / MIN_SELECTION_LEN {
99128
selections.push(SingleSelectionProof::decode(d, ctx)?);
100129
}
101-
102130
let scalar = ProofScalar::decode(d, ctx)?;
103131

104132
Ok(Self { selections, scalar })
@@ -114,7 +142,7 @@ impl Encode<()> for RowProof {
114142
e.array(2)?;
115143
0.encode(e, ctx)?;
116144

117-
e.array(self.selections.len() as u64 + 1)?;
145+
e.array(MIN_SELECTION_LEN * self.selections.len() as u64 + 1)?;
118146
for selection in &self.selections {
119147
selection.encode(e, ctx)?;
120148
}
@@ -124,22 +152,30 @@ impl Encode<()> for RowProof {
124152

125153
impl Decode<'_, ()> for SingleSelectionProof {
126154
fn decode(
127-
_d: &mut Decoder<'_>,
128-
_ctx: &mut (),
155+
d: &mut Decoder<'_>,
156+
ctx: &mut (),
129157
) -> Result<Self, minicbor::decode::Error> {
130-
// TODO: FIXME:
131-
todo!()
158+
let announcement = ProofAnnouncement::decode(d, ctx)?;
159+
let choice = ElgamalRistretto255Choice::decode(d, ctx)?;
160+
let response = ProofResponse::decode(d, ctx)?;
161+
162+
Ok(Self {
163+
announcement,
164+
choice,
165+
response,
166+
})
132167
}
133168
}
134169

135170
impl Encode<()> for SingleSelectionProof {
136171
fn encode<W: Write>(
137172
&self,
138-
_e: &mut Encoder<W>,
139-
_ctx: &mut (),
173+
e: &mut Encoder<W>,
174+
ctx: &mut (),
140175
) -> Result<(), minicbor::encode::Error<W::Error>> {
141-
// TODO: FIXME:
142-
todo!()
176+
self.announcement.encode(e, ctx)?;
177+
self.choice.encode(e, ctx)?;
178+
self.response.encode(e, ctx)
143179
}
144180
}
145181

@@ -162,6 +198,75 @@ impl Encode<()> for ProofScalar {
162198
}
163199
}
164200

201+
impl Decode<'_, ()> for ProofAnnouncement {
202+
fn decode(
203+
d: &mut Decoder<'_>,
204+
ctx: &mut (),
205+
) -> Result<Self, minicbor::decode::Error> {
206+
Ok(Self(
207+
ProofAnnouncementElement::decode(d, ctx)?,
208+
ProofAnnouncementElement::decode(d, ctx)?,
209+
ProofAnnouncementElement::decode(d, ctx)?,
210+
))
211+
}
212+
}
213+
214+
impl Encode<()> for ProofAnnouncement {
215+
fn encode<W: Write>(
216+
&self,
217+
e: &mut Encoder<W>,
218+
ctx: &mut (),
219+
) -> Result<(), minicbor::encode::Error<W::Error>> {
220+
self.0.encode(e, ctx)?;
221+
self.1.encode(e, ctx)?;
222+
self.2.encode(e, ctx)
223+
}
224+
}
225+
226+
impl Decode<'_, ()> for ProofResponse {
227+
fn decode(
228+
d: &mut Decoder<'_>,
229+
ctx: &mut (),
230+
) -> Result<Self, minicbor::decode::Error> {
231+
Ok(Self(
232+
ProofScalar::decode(d, ctx)?,
233+
ProofScalar::decode(d, ctx)?,
234+
ProofScalar::decode(d, ctx)?,
235+
))
236+
}
237+
}
238+
239+
impl Encode<()> for ProofResponse {
240+
fn encode<W: Write>(
241+
&self,
242+
e: &mut Encoder<W>,
243+
ctx: &mut (),
244+
) -> Result<(), minicbor::encode::Error<W::Error>> {
245+
self.0.encode(e, ctx)?;
246+
self.1.encode(e, ctx)?;
247+
self.2.encode(e, ctx)
248+
}
249+
}
250+
251+
impl Decode<'_, ()> for ProofAnnouncementElement {
252+
fn decode(
253+
d: &mut Decoder<'_>,
254+
ctx: &mut (),
255+
) -> Result<Self, minicbor::decode::Error> {
256+
<[u8; PROOF_ANNOUNCEMENT_ELEMENT_LEN as usize]>::decode(d, ctx).map(Self)
257+
}
258+
}
259+
260+
impl Encode<()> for ProofAnnouncementElement {
261+
fn encode<W: Write>(
262+
&self,
263+
e: &mut Encoder<W>,
264+
ctx: &mut (),
265+
) -> Result<(), minicbor::encode::Error<W::Error>> {
266+
self.0.encode(e, ctx)
267+
}
268+
}
269+
165270
#[cfg(test)]
166271
mod tests {
167272
use super::*;
@@ -174,12 +279,16 @@ mod tests {
174279
];
175280
let original = RowProof {
176281
selections: vec![SingleSelectionProof {
177-
announcement: ProofAnnouncement {},
282+
announcement: ProofAnnouncement(
283+
ProofAnnouncementElement(bytes),
284+
ProofAnnouncementElement(bytes),
285+
ProofAnnouncementElement(bytes),
286+
),
178287
choice: ElgamalRistretto255Choice {
179288
c1: bytes,
180289
c2: bytes,
181290
},
182-
response: ProofResponse {},
291+
response: ProofResponse(ProofScalar(bytes), ProofScalar(bytes), ProofScalar(bytes)),
183292
}],
184293
scalar: ProofScalar(bytes),
185294
};
@@ -198,12 +307,16 @@ mod tests {
198307
25, 26, 27, 28, 29, 30, 31, 32,
199308
];
200309
let original = SingleSelectionProof {
201-
announcement: ProofAnnouncement {},
310+
announcement: ProofAnnouncement(
311+
ProofAnnouncementElement(bytes),
312+
ProofAnnouncementElement(bytes),
313+
ProofAnnouncementElement(bytes),
314+
),
202315
choice: ElgamalRistretto255Choice {
203316
c1: bytes,
204317
c2: bytes,
205318
},
206-
response: ProofResponse {},
319+
response: ProofResponse(ProofScalar(bytes), ProofScalar(bytes), ProofScalar(bytes)),
207320
};
208321
let mut buffer = Vec::new();
209322
original

0 commit comments

Comments
 (0)