| // Copyright 2026 Google LLC | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| // | |
| edition = "2024"; | |
| package credentio; | |
| import "cbor/tags.proto"; | |
| // A BMFF-based hash assertion. See | |
| // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_bmff_based_hash. | |
| message BmffBasedHashAssertion { | |
| // Excludes certain boxes from the hash. | |
| repeated BmffRange exclusions = 1 | |
| [(cbor.tags) = { is_required: true, disallow_empty: true }]; | |
| // A string identifying the cryptographic hash algorithm. | |
| string alg = 2; | |
| bytes hash = 3; | |
| repeated BmffMerkle merkles = 4 [(cbor.tags) = { name: "merkle" }]; | |
| // A human-readable description of what this hash covers. | |
| string name = 5; | |
| } | |
| message BmffRange { | |
| // Location of box(es) of the hash starting from the root node as an xpath | |
| // formatted string of version https://www.w3.org/TR/xpath-10/ with highly | |
| // constrained syntax. | |
| string xpath = 1 [(cbor.tags) = { is_required: true }]; | |
| // Length of a leafmost box of the hash. | |
| int64 length = 2; | |
| // The data in the leafmost box. | |
| repeated BmffData data = 3; | |
| // Only subsets of the data in the leafmost box. | |
| repeated BmffSubset subsets = 4 [(cbor.tags) = { name: "subset" }]; | |
| int64 version = 5; | |
| bytes flags = 6; | |
| // Whether flags must be an exact match. | |
| bool exact = 7; | |
| } | |
| message BmffData { | |
| int64 offset = 1 [(cbor.tags) = { is_required: true }]; | |
| bytes value = 2 [(cbor.tags) = { is_required: true }]; | |
| } | |
| message BmffSubset { | |
| int64 offset = 1 [(cbor.tags) = { is_required: true }]; | |
| int64 length = 2 [(cbor.tags) = { is_required: true }]; | |
| } | |
| message BmffMerkle { | |
| // Unique id that differentiates across files to determine which Merkle | |
| // tree should be used to validate a given 'mdat' box. | |
| int64 unique_id = 1 [(cbor.tags) = { is_required: true, name: "uniqueId" }]; | |
| // Local id used to differentiate across multiple 'mdat' boxes within a single | |
| // file to determine which Merkle tree should be used to validate that 'mdat' | |
| // box. | |
| int64 local_id = 2 [(cbor.tags) = { is_required: true, name: "localId" }]; | |
| // Number of leaf nodes in the Merkle tree. | |
| int64 count = 3 [(cbor.tags) = { is_required: true }]; | |
| // A string identifying the cryptographic hash algorithm | |
| string alg = 4; | |
| // The hash of the entire initialization segment file for fragmented assets | |
| // like MP4. | |
| bytes init_hash = 5 [(cbor.tags) = { name: "initHash" }]; | |
| // Representing a single row of the Merkle tree. | |
| repeated bytes hashes = 6 | |
| [(cbor.tags) = { is_required: true, disallow_empty: true }]; | |
| // The following two fields are used to determine the block size of the | |
| // Merkle tree and are only used for non-fragmented assets. Only one of them | |
| // can be set. FixedBlockSize breaks the input string into fixed-size blocks, | |
| // while VariableBlockSizes uses a list of block sizes to determine the block | |
| // size of each block. | |
| int64 fixed_block_size = 7 | |
| [(cbor.tags) = { name: "fixedBlockSize", type: TYPE_UINT }]; | |
| repeated int64 variable_block_sizes = 8 | |
| [(cbor.tags) = { name: "variableBlockSizes" }]; | |
| } | |
| // Auxiliary data for a Merkle map. See | |
| // https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html#_box_containing_the_merkle_auxiliary. | |
| message BmffMerkleMap { | |
| // Unique ID used in combination with the local ID to identify the BMFFMerkle | |
| // map. | |
| int64 unique_id = 1 [(cbor.tags) = { is_required: true, name: "uniqueId" }]; | |
| int64 local_id = 2 [(cbor.tags) = { is_required: true, name: "localId" }]; | |
| // The zero-based index of this leaf in the leaf row of the Merkle map. | |
| int64 location = 3 [(cbor.tags) = { is_required: true }]; | |
| // A series of hashes that are sequentially hashed against the leaf data hash | |
| // via merkle proof to generate the final hash to be compared against the | |
| // corresponding hash in the Merkle map. | |
| repeated bytes hashes = 4 [(cbor.tags) = { disallow_empty: true }]; | |
| } |