11//! Transcript commitments.
22
3- use std:: { collections :: HashSet , fmt} ;
3+ use std:: fmt;
44
55use rangeset:: iter:: { FromRangeIterator , IntoRangeIterator } ;
66use serde:: { Deserialize , Serialize } ;
@@ -68,6 +68,8 @@ impl TranscriptCommitConfig {
6868 }
6969
7070 /// Returns an iterator over the hash commitment indices.
71+ ///
72+ /// Commitments are returned in the order they were added to the builder.
7173 pub fn iter_hash ( & self ) -> impl Iterator < Item = ( & ( Direction , RangeSet < usize > ) , & HashAlgId ) > {
7274 self . commits . iter ( ) . map ( |( idx, kind) | match kind {
7375 TranscriptCommitmentKind :: Hash { alg } => ( idx, alg) ,
@@ -90,7 +92,7 @@ impl TranscriptCommitConfig {
9092pub struct TranscriptCommitConfigBuilder < ' a > {
9193 transcript : & ' a Transcript ,
9294 default_kind : TranscriptCommitmentKind ,
93- commits : HashSet < ( ( Direction , RangeSet < usize > ) , TranscriptCommitmentKind ) > ,
95+ commits : Vec < ( ( Direction , RangeSet < usize > ) , TranscriptCommitmentKind ) > ,
9496}
9597
9698impl < ' a > TranscriptCommitConfigBuilder < ' a > {
@@ -101,7 +103,7 @@ impl<'a> TranscriptCommitConfigBuilder<'a> {
101103 default_kind : TranscriptCommitmentKind :: Hash {
102104 alg : HashAlgId :: BLAKE3 ,
103105 } ,
104- commits : HashSet :: default ( ) ,
106+ commits : Vec :: default ( ) ,
105107 }
106108 }
107109
@@ -145,7 +147,10 @@ impl<'a> TranscriptCommitConfigBuilder<'a> {
145147 ) ) ;
146148 }
147149
148- self . commits . insert ( ( ( direction, idx) , kind) ) ;
150+ let commit = ( ( direction, idx) , kind) ;
151+ if !self . commits . contains ( & commit) {
152+ self . commits . push ( commit) ;
153+ }
149154
150155 Ok ( self )
151156 }
@@ -203,7 +208,7 @@ impl<'a> TranscriptCommitConfigBuilder<'a> {
203208 /// Builds the configuration.
204209 pub fn build ( self ) -> Result < TranscriptCommitConfig , TranscriptCommitConfigBuilderError > {
205210 Ok ( TranscriptCommitConfig {
206- commits : Vec :: from_iter ( self . commits ) ,
211+ commits : self . commits ,
207212 } )
208213 }
209214}
@@ -279,4 +284,34 @@ mod tests {
279284 assert ! ( builder. commit_sent( & ( 10 ..15 ) ) . is_err( ) ) ;
280285 assert ! ( builder. commit_recv( & ( 10 ..15 ) ) . is_err( ) ) ;
281286 }
287+
288+ #[ test]
289+ fn test_commitment_order_matches_insertion_order ( ) {
290+ let transcript = Transcript :: new ( [ 0 ; 12 ] , [ 0 ; 12 ] ) ;
291+ let mut builder = TranscriptCommitConfigBuilder :: new ( & transcript) ;
292+
293+ builder. commit_recv ( & ( 8 ..10 ) ) . unwrap ( ) ;
294+ builder. commit_sent ( & ( 1 ..3 ) ) . unwrap ( ) ;
295+ builder. commit_recv ( & ( 4 ..6 ) ) . unwrap ( ) ;
296+ builder. commit_recv ( & ( 8 ..10 ) ) . unwrap ( ) ;
297+
298+ let config = builder. build ( ) . unwrap ( ) ;
299+ let commits = config
300+ . iter_hash ( )
301+ . map ( |( ( direction, idx) , alg) | ( * direction, idx. clone ( ) , * alg) )
302+ . collect :: < Vec < _ > > ( ) ;
303+
304+ assert_eq ! (
305+ commits,
306+ vec![
307+ (
308+ Direction :: Received ,
309+ RangeSet :: from( 8 ..10 ) ,
310+ HashAlgId :: BLAKE3
311+ ) ,
312+ ( Direction :: Sent , RangeSet :: from( 1 ..3 ) , HashAlgId :: BLAKE3 ) ,
313+ ( Direction :: Received , RangeSet :: from( 4 ..6 ) , HashAlgId :: BLAKE3 ) ,
314+ ]
315+ ) ;
316+ }
282317}
0 commit comments