Skip to content

Commit 2467add

Browse files
More encoding/decoding
1 parent 6cfd573 commit 2467add

File tree

2 files changed

+166
-12
lines changed

2 files changed

+166
-12
lines changed

rust/catalyst-contest/src/encrypted_choices.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl Decode<'_, ()> for EncryptedChoices {
4040
let version = u64::decode(d, ctx)?;
4141
if version != 0 {
4242
return Err(minicbor::decode::Error::message(format!(
43-
"Unexpected encrypted choices array value: {version}, expected 0"
43+
"Unexpected encrypted choices version value: {version}, expected 0"
4444
)));
4545
}
4646

@@ -73,7 +73,7 @@ impl Decode<'_, ()> for EncryptedBlock {
7373
d: &mut Decoder<'_>,
7474
ctx: &mut (),
7575
) -> Result<Self, minicbor::decode::Error> {
76-
<[u8; ENCRYPTED_BLOCK_ARRAY_LEN as usize]>::decode(d, ctx).map(EncryptedBlock)
76+
<[u8; ENCRYPTED_BLOCK_ARRAY_LEN as usize]>::decode(d, ctx).map(Self)
7777
}
7878
}
7979

Lines changed: 164 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,154 @@
11
//! A universal encrypted row proof.
22
3+
use cbork_utils::decode_helper::decode_array_len;
34
use minicbor::{Decode, Decoder, Encode, Encoder, encode::Write};
45

6+
use crate::ElgamalRistretto255Choice;
7+
8+
const SCALAR_PROOF_LEN: u64 = 32;
9+
510
/// A universal encrypted row proof.
611
///
712
/// The CDDL schema:
813
/// ```cddl
914
/// row-proof = [0, zkproof-elgamal-ristretto255-unit-vector-with-single-selection ]
1015
///
1116
/// zkproof-elgamal-ristretto255-unit-vector-with-single-selection = [ +zkproof-elgamal-ristretto255-unit-vector-with-single-selection-item, zkproof-ed25519-scalar ]
17+
/// ```
18+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
19+
pub struct RowProof {
20+
/// A list of a single selection proofs.
21+
pub selections: Vec<SingleSelectionProof>,
22+
/// An individual Ed25519 scalar used in ZK proofs.
23+
pub scalar: ProofScalar,
24+
}
25+
26+
/// A proof that the row is a unit vector with a single selection.
1227
///
28+
/// The CDDL schema:
29+
/// ```cddl
1330
/// zkproof-elgamal-ristretto255-unit-vector-with-single-selection-item = ( zkproof-elgamal-announcement, ~elgamal-ristretto255-encrypted-choice, zkproof-ed25519-r-response )
31+
/// ```
32+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
33+
pub struct SingleSelectionProof {
34+
/// A ZK proof announcement values for Elgamal.
35+
pub announcement: ProofAnnouncement,
36+
/// An elgamal encrypted ciphertext.
37+
pub choice: ElgamalRistretto255Choice,
38+
/// A ZK proof response values for Ed25519.
39+
pub response: ProofResponse,
40+
}
41+
42+
/// An individual Ed25519 scalar used in ZK proofs.
1443
///
44+
/// The CDDL schema:
45+
/// ```cddl
46+
/// zkproof-ed25519-scalar = bytes .size 32
47+
/// ```
48+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
49+
pub struct ProofScalar(pub [u8; SCALAR_PROOF_LEN as usize]);
50+
51+
/// A ZK proof announcement values for Elgamal.
52+
///
53+
/// The CDDL schema:
54+
/// ```cddl
1555
/// zkproof-elgamal-announcement = ( zkproof-elgamal-group-element, zkproof-elgamal-group-element, zkproof-elgamal-group-element )
1656
///
1757
/// zkproof-elgamal-group-element = bytes .size 32
58+
/// ```
59+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
60+
pub struct ProofAnnouncement {}
61+
62+
/// A ZK proof response values for Ed25519.
1863
///
19-
/// zkproof-ed25519-r-response = ( zkproof-ed25519-scalar, zkproof-ed25519-scalar, zkproof-ed25519-scalar )
64+
/// The CDDL schema:
2065
///
21-
/// zkproof-ed25519-scalar = bytes .size 32
66+
/// ```cddl
67+
/// zkproof-ed25519-r-response = ( zkproof-ed25519-scalar, zkproof-ed25519-scalar, zkproof-ed25519-scalar )
2268
/// ```
2369
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
24-
pub struct RowProof {
25-
/// A list of a single selection proofs.
26-
pub selections: Vec<()>,
27-
/// An individual Ed25519 scalar used in ZK proofs.
28-
pub scalar: (),
29-
}
70+
pub struct ProofResponse {}
3071

3172
impl Decode<'_, ()> for RowProof {
3273
fn decode(
3374
d: &mut Decoder<'_>,
3475
ctx: &mut (),
3576
) -> Result<Self, minicbor::decode::Error> {
77+
let len = decode_array_len(d, "row proof")?;
78+
if len != 2 {
79+
return Err(minicbor::decode::Error::message(format!(
80+
"Unexpected row proof array length {len}, expected 2"
81+
)));
82+
}
83+
let version = u64::decode(d, ctx)?;
84+
if version != 0 {
85+
return Err(minicbor::decode::Error::message(format!(
86+
"Unexpected row proof version value: {version}, expected 0"
87+
)));
88+
}
89+
90+
let len = decode_array_len(d, "row proof single selection")?;
91+
if len < 2 {
92+
return Err(minicbor::decode::Error::message(format!(
93+
"Unexpected row proof single selection array length {len}, expected ata least 2"
94+
)));
95+
}
96+
97+
let mut selections = Vec::with_capacity(len as usize - 1);
98+
for _ in 0..len - 1 {
99+
selections.push(SingleSelectionProof::decode(d, ctx)?);
100+
}
101+
102+
let scalar = ProofScalar::decode(d, ctx)?;
103+
104+
Ok(Self { selections, scalar })
105+
}
106+
}
107+
108+
impl Encode<()> for RowProof {
109+
fn encode<W: Write>(
110+
&self,
111+
e: &mut Encoder<W>,
112+
ctx: &mut (),
113+
) -> Result<(), minicbor::encode::Error<W::Error>> {
114+
e.array(2)?;
115+
0.encode(e, ctx)?;
116+
117+
e.array(self.selections.len() as u64 + 1)?;
118+
for selection in &self.selections {
119+
selection.encode(e, ctx)?;
120+
}
121+
self.scalar.encode(e, ctx)
122+
}
123+
}
124+
125+
impl Decode<'_, ()> for SingleSelectionProof {
126+
fn decode(
127+
d: &mut Decoder<'_>,
128+
ctx: &mut (),
129+
) -> Result<Self, minicbor::decode::Error> {
130+
let len = decode_array_len(d, "row proof")?;
131+
if len != 3 {
132+
return Err(minicbor::decode::Error::message(format!(
133+
"Unexpected row proof array length {len}, expected 3"
134+
)));
135+
}
136+
137+
let announcement
138+
139+
/*
140+
pub announcement: ProofAnnouncement,
141+
/// An elgamal encrypted ciphertext.
142+
pub choice: ElgamalRistretto255Choice,
143+
/// A ZK proof response values for Ed25519.
144+
pub response: ProofResponse,
145+
*/
36146
// TODO: FIXME:
37147
todo!()
38148
}
39149
}
40150

41-
impl Encode<()> for RowProof {
151+
impl Encode<()> for SingleSelectionProof {
42152
fn encode<W: Write>(
43153
&self,
44154
e: &mut Encoder<W>,
@@ -49,12 +159,31 @@ impl Encode<()> for RowProof {
49159
}
50160
}
51161

162+
impl Decode<'_, ()> for ProofScalar {
163+
fn decode(
164+
d: &mut Decoder<'_>,
165+
ctx: &mut (),
166+
) -> Result<Self, minicbor::decode::Error> {
167+
<[u8; SCALAR_PROOF_LEN as usize]>::decode(d, ctx).map(Self)
168+
}
169+
}
170+
171+
impl Encode<()> for ProofScalar {
172+
fn encode<W: Write>(
173+
&self,
174+
e: &mut Encoder<W>,
175+
ctx: &mut (),
176+
) -> Result<(), minicbor::encode::Error<W::Error>> {
177+
self.0.encode(e, ctx)
178+
}
179+
}
180+
52181
#[cfg(test)]
53182
mod tests {
54183
use super::*;
55184

56185
#[test]
57-
fn roundtrip() {
186+
fn row_proof_roundtrip() {
58187
let original = RowProof {};
59188
let mut buffer = Vec::new();
60189
original
@@ -63,4 +192,29 @@ mod tests {
63192
let decoded = RowProof::decode(&mut Decoder::new(&buffer), &mut ()).unwrap();
64193
assert_eq!(original, decoded);
65194
}
195+
196+
#[test]
197+
fn single_selection_proof_roundtrip() {
198+
let original = SingleSelectionProof {};
199+
let mut buffer = Vec::new();
200+
original
201+
.encode(&mut Encoder::new(&mut buffer), &mut ())
202+
.unwrap();
203+
let decoded = SingleSelectionProof::decode(&mut Decoder::new(&buffer), &mut ()).unwrap();
204+
assert_eq!(original, decoded);
205+
}
206+
207+
#[test]
208+
fn proof_scalar_roundtrip() {
209+
let original = ProofScalar([
210+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
211+
24, 25, 26, 27, 28, 29, 30, 31,
212+
]);
213+
let mut buffer = Vec::new();
214+
original
215+
.encode(&mut Encoder::new(&mut buffer), &mut ())
216+
.unwrap();
217+
let decoded = ProofScalar::decode(&mut Decoder::new(&buffer), &mut ()).unwrap();
218+
assert_eq!(original, decoded);
219+
}
66220
}

0 commit comments

Comments
 (0)