@@ -180,39 +180,74 @@ func (c GenericCommitment) String() string {
180180type BatchedCommitment []byte
181181
182182// NewBatchedCommitment creates a new batched commitment from the given commitments
183- func NewBatchedCommitment (comms []CommitmentData ) BatchedCommitment {
184- // Calculate total size needed: 2 bytes length + encoded bytes for each commitment
185- totalSize := 0
183+ func NewBatchedCommitment (comms []CommitmentData ) (BatchedCommitment , error ) {
184+ if len (comms ) == 0 {
185+ return nil , ErrInvalidCommitment
186+ }
187+
188+ // Verify all commitments are of the same type
189+ subType := comms [0 ].CommitmentType ()
190+ for i , comm := range comms {
191+ if comm .CommitmentType () != subType {
192+ return nil , fmt .Errorf ("commitment at index %d has different type than first commitment" , i )
193+ }
194+ }
195+
196+ // Calculate total size needed: 1 byte for subcommitment type + (2 bytes length + raw data) for each commitment
197+ totalSize := 1 // subcommitment type byte
186198 for _ , comm := range comms {
187- encoded := comm .Encode ()
188- totalSize += 2 + len (encoded ) // 2 bytes for length
199+ rawData := comm .Encode ()[ 1 :] // Skip the type byte since we'll store it once at the start
200+ totalSize += 2 + len (rawData ) // 2 bytes for length + raw data
189201 }
190202
191203 result := make ([]byte , totalSize )
192- pos := 0
204+
205+ // Write the subcommitment type byte
206+ result [0 ] = byte (subType )
207+ pos := 1
193208
194209 for _ , comm := range comms {
195- encoded := comm .Encode ()
210+ rawData := comm .Encode ()[ 1 :] // Skip the type byte
196211 // Write length (2 bytes, big endian)
197- result [pos ] = byte (len (encoded ) >> 8 )
198- result [pos + 1 ] = byte (len (encoded ))
212+ result [pos ] = byte (len (rawData ) >> 8 )
213+ result [pos + 1 ] = byte (len (rawData ))
199214 pos += 2
200215
201- // Write encoded commitment (includes its type byte)
202- copy (result [pos :], encoded )
203- pos += len (encoded )
216+ // Write raw commitment data (without type byte)
217+ copy (result [pos :], rawData )
218+ pos += len (rawData )
204219 }
205220
206- return BatchedCommitment (result )
221+ return BatchedCommitment (result ), nil
207222}
208223
209224// DecodeBatchedCommitment validates and casts the commitment into a BatchedCommitment
210225func DecodeBatchedCommitment (commitment []byte ) (BatchedCommitment , error ) {
211226 if len (commitment ) == 0 {
212227 return nil , ErrInvalidCommitment
213228 }
214- // TODO: validate batched commitments
215- return commitment , nil
229+
230+ // Skip the subcommitment type byte when validating the structure
231+ reader := bytes .NewReader (commitment [1 :])
232+ for reader .Len () > 0 {
233+ // Read length (2 bytes)
234+ var length uint16
235+ if err := binary .Read (reader , binary .BigEndian , & length ); err != nil {
236+ return nil , ErrInvalidCommitment
237+ }
238+
239+ // Ensure we have enough bytes for this commitment
240+ if reader .Len () < int (length ) {
241+ return nil , ErrInvalidCommitment
242+ }
243+
244+ // Skip the commitment data
245+ if _ , err := reader .Seek (int64 (length ), io .SeekCurrent ); err != nil {
246+ return nil , ErrInvalidCommitment
247+ }
248+ }
249+
250+ return BatchedCommitment (commitment ), nil
216251}
217252
218253// CommitmentType returns the commitment type of BatchedCommitment
@@ -247,8 +282,14 @@ func (c BatchedCommitment) Verify(input []byte) error {
247282
248283// GetCommitments returns the individual commitments in the batch
249284func (c BatchedCommitment ) GetCommitments () ([]CommitmentData , error ) {
285+ if len (c ) < 1 {
286+ return nil , ErrInvalidCommitment
287+ }
288+
289+ // First byte is the subcommitment type
290+ subType := CommitmentType (c [0 ])
291+ reader := bytes .NewReader (c [1 :])
250292 var commitments []CommitmentData
251- reader := bytes .NewReader (c )
252293
253294 for reader .Len () > 0 {
254295 // Read length (2 bytes)
@@ -263,8 +304,11 @@ func (c BatchedCommitment) GetCommitments() ([]CommitmentData, error) {
263304 return nil , ErrInvalidCommitment
264305 }
265306
307+ // Reconstruct full commitment with type byte
308+ fullData := append ([]byte {byte (subType )}, data ... )
309+
266310 // Decode the commitment
267- comm , err := DecodeCommitmentData (data )
311+ comm , err := DecodeCommitmentData (fullData )
268312 if err != nil {
269313 return nil , err
270314 }
0 commit comments