PD-294 — Aligner le format Merkle proof sur RFC 9162 (inclusion proof)¶
1. Contexte¶
ProbatioVault produit des preuves d'inclusion Merkle dans le cadre de son enveloppe probatoire (ProofEnvelope). Le format actuel de la sous-structure merkle_proof est fonctionnel mais ne suit aucun standard reconnu. RFC 9162 (Certificate Transparency v2, section 2.1.3) definit un format d'inclusion proof largement adopte dans l'ecosysteme de transparence cryptographique.
L'objectif est d'aligner la structure de merkle_proof sur le modele RFC 9162 tout en conservant l'enveloppe ProbatioVault custom (tsa_token, hsm_signature, blockchain_anchor, event_metadata).
Positionnement : RFC 9162-inspired inclusion proof structure ; le schema de hachage reste specifique ProbatioVault (SHA3-256). Aucune revendication de conformite Certificate Transparency complete.
2. Besoin fonctionnel¶
En tant que verificateur de preuves ProbatioVault (auditeur, SDK client, service tiers), je veux recevoir une preuve d'inclusion Merkle dont la structure suit les conventions RFC 9162, afin de pouvoir verifier la preuve avec un algorithme standard (section 2.1.3.2 RFC 9162) et beneficier d'une interoperabilite accrue avec les outils de l'ecosysteme de transparence.
3. Format actuel (v1)¶
DTO MerkleProofResultAvailable¶
{
status: 'available',
eventHash: string, // hash de l'evenement (leaf)
merkleRoot: string, // racine SHA hex 64 chars
merklePath: string[], // siblings bottom-to-top
treeId: string, // UUID de l'arbre
treeSize: number, // nombre de feuilles
leafIndex: number, // position 0-based
hashAlgorithm: 'SHA-256', // ATTENTION: incohérence — le code declare SHA-256
hashAlgorithmVersion: '1.0'
}
Export ProofArtifactDto¶
{
merkle_proof: string[], // siblings
merkle_root: string, // SHA hex 64 chars
merkle_index: number // position 0-based
}
Persistance merkle_leaves¶
| Colonne | Type | Description |
|---|---|---|
leaf_hash | VARCHAR(64) | hash hex de la feuille |
leaf_index | INTEGER | position 0-based |
inclusion_proof | JSONB | string[] siblings |
Incohérence identifiee : le DTO declare hashAlgorithm: 'SHA-256' alors que l'ecosysteme ProbatioVault utilise SHA3-256 (journal append-only, HKDF, integrite documentaire). Cette incohérence doit etre corrigee dans PD-294.
4. Format cible (v2, RFC 9162-inspired)¶
Sous-structure merkle_proof dans ProofEnvelope¶
{
proof_version: 2,
leaf_index: number, // position 0-based (RFC 9162 §2.1.3.2)
tree_size: number, // nombre total de feuilles (RFC 9162 §2.1.3.2)
inclusion_path: string[], // siblings bottom-to-top (RFC 9162 "inclusion_path")
merkle_root: string, // root hash hex
hash_algorithm: 'sha3-256', // explicite, ProbatioVault-specifique
event_hash: string // hash de la feuille (entree verifiee)
}
Mapping v1 -> v2¶
| v1 | v2 | Transformation |
|---|---|---|
merklePath | inclusion_path | Renommage (alignement RFC 9162) |
merkleRoot | merkle_root | snake_case |
leafIndex | leaf_index | snake_case |
treeSize | tree_size | snake_case |
eventHash | event_hash | snake_case |
hashAlgorithm: 'SHA-256' | hash_algorithm: 'sha3-256' | Correction + renommage |
| — | proof_version: 2 | Nouveau champ discriminant |
treeId | — | Supprime de la sous-structure (detail interne) |
hashAlgorithmVersion | — | Absorbe par hash_algorithm |
Algorithme de verification (RFC 9162 §2.1.3.2)¶
Le format v2 permet la verification standard :
- Verifier
leaf_index < tree_size - Initialiser
fn = leaf_index,sn = tree_size - 1,r = event_hash - Pour chaque
pdansinclusion_path: - Si
LSB(fn)est set oufn == sn:r = HASH(0x01 || p || r) - Sinon :
r = HASH(0x01 || r || p) - Right-shift
fnetsn - Verifier
sn == 0etr == merkle_root
Ou HASH = SHA3-256 (divergence assumee vs CT classique qui utilise SHA-256).
5. Strategie de migration¶
Principe : dual-read / single-write¶
- Lecture : supporter v1 (legacy) ET v2 (nouveau format)
- Ecriture : emettre uniquement v2
- Pas de migration retroactive des preuves persistees (valeur probatoire)
Discriminant¶
Le champ proof_version (absent en v1, valeur 2 en v2) permet au code de lecture de determiner le format et d'appliquer l'adaptateur adequat.
Adaptateur de lecture¶
Pour les preuves legacy (v1), l'API peut normaliser a la volee en v2 sans reecriture en base :
v1.merklePath -> v2.inclusion_path
v1.merkleRoot -> v2.merkle_root
v1.leafIndex -> v2.leaf_index
v1.treeSize -> v2.tree_size
v1.eventHash -> v2.event_hash
proof_version -> 1 (infere)
hash_algorithm -> 'sha3-256' (corrige)
6. Perimetre et exclusions¶
Dans le scope PD-294¶
- Definition du format cible v2 (sous-structure
merkle_proof) - Regles de mapping v1 -> v2
- Strategie de migration dual-read / single-write
- Correction de l'incohérence
hashAlgorithm: 'SHA-256'->hash_algorithm: 'sha3-256' - Criteres d'acceptation transverses de compatibilite
- Ajout de
proof_versioncomme discriminant
Hors scope¶
- Implementation de
getMerkleProof()etverifyMerkleProof(): PD-56 - Consistency proofs (RFC 9162 §2.1.4) : story separee si besoin futur
- Migration retroactive des preuves existantes : exclue par arbitrage PO
- Modification du schema de hachage : SHA3-256 conserve (pas de migration vers SHA-256)
- Enveloppe ProofEnvelope : reste custom ProbatioVault, non impactee structurellement
7. Stories impactees¶
| Story | Module | Impact PD-294 |
|---|---|---|
| PD-54 (Done) | Construction arbre Merkle | Aucun (produit le root, pas le proof format) |
| PD-55 (Done) | Worker ancrage blockchain | Aucun (consomme le root hash) |
| PD-56 (en cours) | Generation Merkle proof | DIRECT — getMerkleProof() doit suivre v2 |
| PD-237 (Done) | Persistance Merkle | Verifier compatibilite merkle_leaves avec v2 |
| PD-245 (Done) | Format preuve multi-chain | Compatible (blockchain_anchor reste dans l'enveloppe PV) |
| PD-282 (Done) | ProofEnvelope HSM/eIDAS | merkle_proof devient sous-objet v2 standardise |
8. Invariants¶
| ID | Invariant | Justification |
|---|---|---|
| INV-294-01 | Le format v2 DOIT contenir leaf_index, tree_size, inclusion_path, merkle_root, hash_algorithm, event_hash, proof_version | Alignement RFC 9162 §2.1.3 |
| INV-294-02 | hash_algorithm DOIT valoir 'sha3-256' (pas 'SHA-256') | Correction incohérence + alignement ecosysteme PV |
| INV-294-03 | Les preuves v1 existantes NE DOIVENT PAS etre reecrites en base | Valeur probatoire des preuves persistees |
| INV-294-04 | L'API DOIT normaliser les preuves v1 en format v2 a la volee en lecture | Compatibilite backward transparente |
| INV-294-05 | proof_version absent = v1 implicite ; proof_version: 2 = v2 explicite | Discriminant non-breaking |
| INV-294-06 | L'algorithme de verification §2.1.3.2 DOIT etre applicable sur le format v2 | Interoperabilite avec outils standard (modulo hash) |
| INV-294-07 | treeId NE DOIT PAS apparaitre dans la sous-structure v2 exposee | Detail d'implementation interne, pas dans le proof |
| INV-294-08 | Toute preuve v2 emise DOIT etre verifiable par l'algorithme RFC 9162 §2.1.3.2 adapte SHA3-256 | Non-regression fonctionnelle |
9. Risques et arbitrages¶
| Risque | Mitigation |
|---|---|
| Incohérence SHA-256 vs SHA3-256 dans le code existant | PD-294 corrige le DTO ; verifier que le hash reel est bien SHA3-256 dans la construction d'arbre (PD-54) |
| Breaking change API pour consommateurs existants | Versionning via proof_version ; v1 reste lisible ; transition progressive |
| PD-56 en cours — risque de conflit | PD-294 definit le contrat avant que PD-56 implemente ; coordination explicite |
| Preuves v1 non-migrees cohabitent indefiniment | Acceptable : le discriminant proof_version assure la cohabitation ; pas de date d'obsolescence imposee |
10. References¶
- RFC 9162 — Certificate Transparency v2 (sections 2.1.3, 2.1.3.1, 2.1.3.2, 4.12)
- PD-54 — Construction arbre Merkle
- PD-55 — Worker ancrage blockchain
- PD-56 — Generation Merkle proof (IMPACT DIRECT)
- PD-237 — Persistance Merkle
- PD-282 — ProofEnvelope HSM/eIDAS
- Learning PD-55 : "Gate 3 blockchain/crypto necessite 3 iterations si formalisme RFC manquant dans les specs initiales"
- Learning PD-264 : "Atomicite multi-composant — clarifier synchrone vs asynchrone des la spec"