# Merkle Tree Certificates
`synta.mtc` implements the ASN.1 types from `draft-ietf-plants-merkle-tree-certs`.
All classes are immutable (frozen) and constructed via `from_der` static methods.
```python
import synta.mtc as mtc
```
Name fields such as `issuer_der` and `subject_der` are raw DER-encoded `Name` SEQUENCES;
pass them to `synta.parse_name_attrs()` to decode the DN attributes.
## ProofNode
A single node in a Merkle inclusion proof path.
```python
class ProofNode:
@staticmethod
def from_der(data: bytes) -> ProofNode: ...
is_left: bool # True if this is the left sibling in the path
hash: bytes # raw hash bytes at this proof node
```
## Subtree
A hash subtree covering leaf range `[start, end)`.
```python
class Subtree:
@staticmethod
def from_der(data: bytes) -> Subtree: ...
start: int # start leaf index (inclusive)
end: int # end leaf index (exclusive)
value: bytes # aggregated hash bytes for [start, end)
```
## SubtreeProof
Left and right subtree lists for log compaction.
```python
class SubtreeProof:
@staticmethod
def from_der(data: bytes) -> SubtreeProof: ...
left_subtrees: list[Subtree] | None
right_subtrees: list[Subtree] | None
```
## InclusionProof
Merkle inclusion proof for a log entry.
```python
class InclusionProof:
@staticmethod
def from_der(data: bytes) -> InclusionProof: ...
log_entry_index: int # leaf position of the certified entry
tree_size: int # total leaves at proof time
inclusion_path: list[ProofNode] # ordered sibling hashes
```
## LogID
Identifies a transparency log by its hash algorithm and public key.
```python
class LogID:
@staticmethod
def from_der(data: bytes) -> LogID: ...
hash_algorithm_oid: str # hash algorithm OID (dot-notation)
public_key_der: bytes # DER-encoded SubjectPublicKeyInfo
```
## CosignerID
Identifies a cosigner (witness) by the issuer and serial number of their certificate.
```python
class CosignerID:
@staticmethod
def from_der(data: bytes) -> CosignerID: ...
issuer_der: bytes # DER-encoded issuer Name SEQUENCE
serial_number: int # certificate serial number
```
## Checkpoint
A signed Merkle tree head from a transparency log.
```python
class Checkpoint:
@staticmethod
def from_der(data: bytes) -> Checkpoint: ...
log_id: LogID
tree_size: int
tree_minimum_index: int | None # optional lower leaf bound
root_value: bytes # Merkle root hash bytes
timestamp: str # GeneralizedTime string
```
## SubtreeSignature
A cosigner's signature over a subtree and checkpoint.
```python
class SubtreeSignature:
@staticmethod
def from_der(data: bytes) -> SubtreeSignature: ...
cosigner: CosignerID # cosigner identity
subtree: Subtree # subtree being signed
checkpoint: Checkpoint # checkpoint signed alongside the subtree
signature_algorithm_oid: str # dotted-decimal OID
signature: bytes # raw signature bytes
```
## TbsCertificateLogEntry
The to-be-signed body of a Merkle Tree Certificate log entry.
```python
class TbsCertificateLogEntry:
@staticmethod
def from_der(data: bytes) -> TbsCertificateLogEntry: ...
issuer_der: bytes # raw Name DER
validity_not_before: str # GeneralizedTime string
validity_not_after: str # GeneralizedTime string
subject_der: bytes # raw Name DER
subject_public_key_algorithm_oid: str # algorithm OID (dot-notation)
subject_public_key_hash: bytes # hash of the SubjectPublicKeyInfo
issuer_unique_id: bytes | None
subject_unique_id: bytes | None
extensions_der: bytes | None # raw SEQUENCE OF Extension DER
```
## MerkleTreeCertEntry
Top-level CHOICE wrapper for a Merkle Tree Certificate log entry.
```python
class MerkleTreeCertEntry:
@staticmethod
def from_der(data: bytes) -> MerkleTreeCertEntry: ...
variant: str # "NullEntry" or "TbsCertEntry"
tbs_cert_entry: TbsCertificateLogEntry | None
# tbs_cert_entry is set when variant == "TbsCertEntry", else None.
```
## LandmarkID
Identifies a landmark log: a `LogID` plus the tree size at issuance.
```python
class LandmarkID:
@staticmethod
def from_der(data: bytes) -> LandmarkID: ...
log_id: LogID # identifies the landmark log
tree_size: int # tree size at issuance
```
## StandaloneCertificate
A full standalone Merkle Tree Certificate.
```python
class StandaloneCertificate:
@staticmethod
def from_der(data: bytes) -> StandaloneCertificate: ...
tbs_certificate_der: bytes # DER-encoded TBSCertificate
inclusion_proof: InclusionProof
subtree_proof: SubtreeProof
subtree_signatures: list[SubtreeSignature]
signature_algorithm_oid: str # dotted-decimal OID
signature: bytes
```
## LandmarkCertificate
A Merkle Tree Landmark Certificate.
```python
class LandmarkCertificate:
@staticmethod
def from_der(data: bytes) -> LandmarkCertificate: ...
tbs_certificate_der: bytes # DER-encoded TBSCertificate
inclusion_proof: InclusionProof
landmark_id: LandmarkID
signature_algorithm_oid: str
signature: bytes
```
## Usage
```python
import synta
import synta.mtc as mtc
# Parse a Merkle Tree Certificate log entry
entry = mtc.MerkleTreeCertEntry.from_der(data)
if entry.variant == "TbsCertEntry":
tbs = entry.tbs_cert_entry
issuer = synta.parse_name_attrs(tbs.issuer_der)
subject = synta.parse_name_attrs(tbs.subject_der)
print(f"issuer: {issuer}")
print(f"subject: {subject}")
print(f"not before: {tbs.validity_not_before}")
# Parse a StandaloneCertificate
sc = mtc.StandaloneCertificate.from_der(data)
print(f"leaf index: {sc.inclusion_proof.log_entry_index}")
print(f"tree size: {sc.inclusion_proof.tree_size}")
print(f"cosignatures: {len(sc.subtree_signatures)}")
```