@@ -27,6 +27,8 @@ pub struct ArchiveSizeProof {
27
27
pub layer_size_tree_root : Hash ,
28
28
/// Integrity proofs to prevent tampering
29
29
pub integrity_proofs : IntegrityProofs ,
30
+ /// Publisher's public key (included by proof generator, verified by verifier)
31
+ pub publisher_public_key : Option < String > ,
30
32
}
31
33
32
34
/// Integrity proofs to verify archive structure
@@ -59,6 +61,9 @@ pub struct CompressedSizeProof {
59
61
pub proof_path_length : u8 , // 1 byte: Number of proof elements
60
62
pub proof_path : Vec < ProofElement > , // Variable: Merkle proof path
61
63
64
+ // Publisher verification (32 bytes)
65
+ pub publisher_public_key : [ u8 ; 32 ] , // 32 bytes: Publisher's public key
66
+
62
67
// Integrity verification (96 bytes)
63
68
pub header_hash : [ u8 ; 32 ] , // 32 bytes: Archive header hash
64
69
pub index_hash : [ u8 ; 32 ] , // 32 bytes: Layer index hash
@@ -147,6 +152,7 @@ impl ArchiveSizeProof {
147
152
layer_sizes,
148
153
layer_size_tree_root : layer_size_tree. root ( ) ,
149
154
integrity_proofs,
155
+ publisher_public_key : None , // Will be set by CLI command
150
156
} )
151
157
}
152
158
@@ -229,6 +235,16 @@ impl CompressedSizeProof {
229
235
}
230
236
] ;
231
237
238
+ // Convert publisher public key from hex string to bytes
239
+ let mut publisher_key_bytes = [ 0u8 ; 32 ] ;
240
+ if let Some ( ref pubkey_hex) = proof. publisher_public_key {
241
+ if let Ok ( pubkey_bytes) = hex:: decode ( pubkey_hex) {
242
+ if pubkey_bytes. len ( ) == 32 {
243
+ publisher_key_bytes. copy_from_slice ( & pubkey_bytes) ;
244
+ }
245
+ }
246
+ }
247
+
232
248
Ok ( Self {
233
249
version : 1 ,
234
250
store_id : * proof. store_id . as_bytes ( ) ,
@@ -238,6 +254,7 @@ impl CompressedSizeProof {
238
254
merkle_tree_root : * proof. layer_size_tree_root . as_bytes ( ) ,
239
255
proof_path_length : proof_path. len ( ) as u8 ,
240
256
proof_path,
257
+ publisher_public_key : publisher_key_bytes,
241
258
header_hash : * proof. integrity_proofs . archive_header_hash . as_bytes ( ) ,
242
259
index_hash : * proof. integrity_proofs . layer_index_hash . as_bytes ( ) ,
243
260
first_layer_hash : * proof. integrity_proofs . first_layer_content_hash . as_bytes ( ) ,
@@ -265,7 +282,10 @@ impl CompressedSizeProof {
265
282
buffer. push ( element. position ) ;
266
283
}
267
284
268
- // 4. Integrity proofs (96 bytes)
285
+ // 4. Publisher public key (32 bytes)
286
+ buffer. extend_from_slice ( & self . publisher_public_key ) ;
287
+
288
+ // 5. Integrity proofs (96 bytes)
269
289
buffer. extend_from_slice ( & self . header_hash ) ;
270
290
buffer. extend_from_slice ( & self . index_hash ) ;
271
291
buffer. extend_from_slice ( & self . first_layer_hash ) ;
@@ -284,7 +304,7 @@ impl CompressedSizeProof {
284
304
let buffer = zstd:: decode_all ( & compressed[ ..] )
285
305
. map_err ( |e| DigstoreError :: internal ( format ! ( "Decompression failed: {}" , e) ) ) ?;
286
306
287
- if buffer. len ( ) < 110 {
307
+ if buffer. len ( ) < 142 { // 110 + 32 for publisher public key
288
308
return Err ( DigstoreError :: internal ( "Proof too short" ) ) ;
289
309
}
290
310
@@ -324,7 +344,16 @@ impl CompressedSizeProof {
324
344
offset += 33 ;
325
345
}
326
346
327
- // 5. Parse integrity proofs
347
+ // 5. Parse publisher public key (32 bytes)
348
+ if offset + 32 > buffer. len ( ) {
349
+ return Err ( DigstoreError :: internal ( "Publisher public key extends beyond buffer" ) ) ;
350
+ }
351
+
352
+ let mut publisher_public_key = [ 0u8 ; 32 ] ;
353
+ publisher_public_key. copy_from_slice ( & buffer[ offset..offset + 32 ] ) ;
354
+ offset += 32 ;
355
+
356
+ // 6. Parse integrity proofs (96 bytes)
328
357
if offset + 96 > buffer. len ( ) {
329
358
return Err ( DigstoreError :: internal ( "Integrity proofs extend beyond buffer" ) ) ;
330
359
}
@@ -345,6 +374,7 @@ impl CompressedSizeProof {
345
374
merkle_tree_root,
346
375
proof_path_length,
347
376
proof_path,
377
+ publisher_public_key,
348
378
header_hash,
349
379
index_hash,
350
380
first_layer_hash,
@@ -356,6 +386,13 @@ impl CompressedSizeProof {
356
386
// For simplified verification, create minimal layer sizes that sum to total
357
387
let layer_sizes = vec ! [ self . total_size / 2 , self . total_size - ( self . total_size / 2 ) ] ; // Split into 2 layers
358
388
389
+ // Convert publisher public key back to hex string
390
+ let publisher_public_key = if self . publisher_public_key != [ 0u8 ; 32 ] {
391
+ Some ( hex:: encode ( & self . publisher_public_key ) )
392
+ } else {
393
+ None
394
+ } ;
395
+
359
396
Ok ( ArchiveSizeProof {
360
397
store_id : Hash :: from_bytes ( self . store_id ) ,
361
398
root_hash : Hash :: from_bytes ( self . root_hash ) ,
@@ -370,6 +407,7 @@ impl CompressedSizeProof {
370
407
first_layer_content_hash : Hash :: from_bytes ( self . first_layer_hash ) ,
371
408
last_layer_content_hash : Hash :: from_bytes ( self . first_layer_hash ) , // Simplified
372
409
} ,
410
+ publisher_public_key,
373
411
} )
374
412
}
375
413
}
0 commit comments