11//! A universal encrypted row proof.
22
3+ use cbork_utils:: decode_helper:: decode_array_len;
34use 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
3172impl 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) ]
53182mod 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