RFC PV-PRE-001 : ProbatioVault Proxy Re-Encryption Protocol (Umbral)¶
Statut : Proposition interne Version : 1.3.0 Date : 2026-03-02 Auteur : ProbatioVault Engineering Verification formelle : TLA+ (TLC), Alloy (SAT), Z Notation, Prolog Changelog : v1.3 — PRE-16b binding crypto complet (algorithme + JCS + signature HSM), PRE-16c fail-closed binding, PRE-11 TTL en secondes reelles, PRE-19 wire format exact, PRE-20 stockage/transport KFrags, note ecarts spec/code
1. Introduction¶
1.1 Objectif¶
Ce document specifie le protocole PV PRE (Proxy Re-Encryption), base sur le schema Umbral (NuCypher), pour l'acces legal judiciaire aux documents chiffres dans ProbatioVault.
Le proxy peut re-chiffrer un ciphertext de la cle du proprietaire vers la cle du requerant legal, sans jamais pouvoir dechiffrer le contenu. Cette propriete zero-knowledge est un garde architectural : le modele ne contient aucune operation decrypt, et le code Prolog verifie l'absence de methode decrypt dans l'implementation. Au niveau cryptographique, les garanties de securite du schema Umbral (cf. NuCypher, "Umbral: A Threshold Proxy Re-Encryption Scheme") assurent l'impossibilite de dechiffrement par le proxy.
1.2 Portee¶
Ce protocole couvre :
- La generation de cles de re-chiffrement (ReKey) avec seuil (t, n)
- La double validation (DPO + legal) obligatoire avant re-chiffrement
- Le cycle de vie complet des ReKeys (ACTIVE -> terminal -> DESTROYED)
- La production de fragments cryptographiques (KFrag, CFrag, Capsule)
- Le binding cryptographique mandate-contexte
- La PKI (chaque cle publique liee a un certificat)
- L'anti-rejeu par nonce unique sur chaque re-encryption
- La destruction explicite (KFrags memoire + DB + cache)
- L'audit exhaustif de chaque operation
1.3 References normatives¶
| Reference | Titre | Usage |
|---|---|---|
| Umbral (NuCypher) | Proxy Re-Encryption using Elliptic Curves | Schema PRE de base |
| secp256k1 | SEC 2: Recommended Elliptic Curve Domain Parameters | Courbe elliptique (cle publique 33 bytes compressee) |
| RGPD Art. 17 | Droit a l'effacement | Destruction cryptographique |
| eIDAS | Regulation (EU) No 910/2014 | Certificats electroniques / PKI |
Note sur secp256k1 : Cette courbe est choisie pour la compatibilite avec l'ancrage blockchain Ethereum de ProbatioVault. Pour des usages purement PRE sans contrainte blockchain, Curve25519 offrirait de meilleures performances. Le choix de secp256k1 est un compromis interoperabilite/performance documente.
Note terminologique : Le seuil (t, n) utilise dans Umbral est un secret sharing polynomial (variante de Feldman/Pedersen VSS), pas le schema de Shamir classique. Shamir reconstruit un secret unique ; Umbral distribue une capacite de re-chiffrement sans jamais reconstituer la cle privee du proprietaire. La distinction est importante : dans Umbral, meme avec t KFrags, le proxy ne peut PAS dechiffrer — il ne fait que transformer le ciphertext.
1.4 Terminologie¶
| Terme | Definition |
|---|---|
| ReKey | Cle de re-chiffrement. Permet au proxy de transformer un ciphertext de owner vers recipient sans dechiffrer. |
| KFrag | Fragment de ReKey. Le proprietaire genere n KFrags ; t suffisent pour re-chiffrer (pas pour dechiffrer). |
| CFrag | Fragment de capsule re-chiffree. Produit par le proxy a partir d'un KFrag et du ciphertext original. |
| Capsule | Conteneur cryptographique encapsulant la cle symetrique du document original (~98 bytes : points E, V + preuve). |
| Mandat | Document legal (ordonnance judiciaire, requisition) autorisant l'acces. Lie a un certificat electronique et au contexte du ReKey (binding cryptographique). |
| Double validation | Approbation conjointe du DPO (data protection officer) et de l'autorite legale avant re-chiffrement. |
| Seuil (t, n) | Parametres du secret sharing polynomial Umbral : n KFrags generes, t suffisent pour re-chiffrer. Avec 1 <= t <= n <= 10. |
| TTL | Time-To-Live. Duree de validite d'un ReKey en secondes. |
| Nonce | Valeur unique par operation de re-encryption, garantissant l'anti-rejeu. |
2. Vue d'ensemble du protocole¶
2.1 Acteurs¶
+----------------+ +----------------+ +------------------+
| Proprietaire | | Proxy | | Requerant |
| (Owner) | | (ProbatioVault| | Legal |
| | | zero-knowledge) | (Magistrat, |
| pk_owner | | | | OPJ, DPO) |
| sk_owner | | NO sk_owner | | pk_recipient |
| cert_owner | | NO sk_recipient | sk_recipient |
+-------+--------+ +-------+--------+ +--------+---------+
| | |
| 1. GenerateReKey(t,n) | |
| [PKI: cert_owner valide] | |
|-------------------------->| |
| [n KFrags] | |
| | |
| | 2. DualValidate |
| | (DPO + Legal) |
| |<---------------------------|
| | [Mandat bound au ctx] |
| | [cert_recipient valide]|
| | |
| | 3. ReEncrypt(KFrag_i, |
| | nonce_i) |
| | (repete t fois, |
| | nonce unique/operation) |
| |-------------------------> |
| | [CFrag_1..CFrag_t] |
| | |
| | 4. Reconstruct |
| | (sk_recipient) |
| | Dechiffre le |
| | document |
2.2 Propriete zero-knowledge¶
EXIGENCE PRE-01 : Le proxy NE DOIT JAMAIS pouvoir dechiffrer le contenu.
Cette propriete est garantie a deux niveaux :
- Garde architectural : Aucune operation
decryptn'existe dans le modele formel (TLA+, Alloy, Z, Prolog). C'est une garantie structurelle par absence de construction. - Garantie cryptographique : Les garanties de securite du schema Umbral (NuCypher, "Umbral: A Threshold Proxy Re-Encryption Scheme") assurent que le proxy, meme avec tous les KFrags, ne peut pas reconstruire la cle privee du proprietaire ni dechiffrer le contenu. Seul le destinataire (
sk_recipient) peut dechiffrer apres reconstruction des CFrags.
Prouve par : Alloy NoDecryptInModel, Prolog check_pre_no_decrypt.
2.3 Cycle de vie d'un ReKey¶
GenerateReKey
[PKI + Mandate binding]
|
v
+---------+
| ACTIVE |
+----+----+
|
+------------+------------+
| | |
v v v
+---------+ +---------+ +-----------+
| REVOKED | | EXPIRED | | COMPLETED |
+---------+ +---------+ +-----------+
| | |
+------------+------------+
|
v
+------------+
| DESTROYED |
| (zeroize |
| KFrags + |
| DB + cache)|
+------------+
| Transition | Declencheur | Condition |
|---|---|---|
| ACTIVE -> COMPLETED | cfrags >= threshold.t | Seuil atteint |
| ACTIVE -> REVOKED | Revocation manuelle | Ordre DPO ou proprietaire |
| ACTIVE -> EXPIRED | TTL = 0 | Horloge logique |
| {terminal} -> DESTROYED | Destruction cryptographique | Etat terminal atteint |
EXIGENCE PRE-02 : Les etats terminaux (REVOKED, EXPIRED, COMPLETED) sont IRREVERSIBLES. Un ReKey terminal ne peut pas revenir a ACTIVE. Prouve formellement (TLA+ TerminalIsFinal, Alloy AllTerminalAreFinal).
EXIGENCE PRE-03 : Un ReKey DESTROYED ne peut plus etre utilise pour aucune operation. L'etat DESTROYED est final et absorbant.
3. Specifications detaillees¶
3.1 Generation de ReKey¶
Procedure :
- Le proprietaire genere un ReKey avec les parametres (t, n, context, TTL)
- PKI : Les cles publiques
pk_owneretpk_recipientsont validees via certificats eIDAS - Mandate binding : Le mandat judiciaire est lie cryptographiquement au contexte du ReKey (
mandate.scope = rekey.context,mandate.boundReKey = rekey.id) - Le ReKey est initialise a l'etat ACTIVE avec
kfragsZeroized = false - n KFrags sont generes par le schema polynomial Umbral
- L'ensemble des nonces utilises est initialise a vide
EXIGENCE PRE-04 : Le seuil DOIT respecter 1 <= t <= n <= 10. Prouve formellement (TLA+ ThresholdValid, Alloy ThresholdValid).
EXIGENCE PRE-05 : Le proprietaire et le requerant DOIVENT etre des entites DIFFERENTES (owner != recipient). Prouve formellement (Alloy RequesterNotOwner).
EXIGENCE PRE-06 : Les cles publiques utilisent secp256k1 en format compresse (33 bytes). Chaque cle DOIT etre liee a un certificat eIDAS valide (INV-11 PKIAuthenticity). Le provider Umbral DOIT supporter secp256k1. Prouve formellement (Alloy AuthenticatedKeys, PKIAlwaysPresent).
3.2 Double validation¶
EXIGENCE PRE-07 : Aucun re-chiffrement n'est autorise sans double validation prealable. Cette regle est prouvee formellement (TLA+ DualValidationRequired, Alloy DualValidationRequired).
La double validation requiert :
| Validateur | Role | Verification |
|---|---|---|
| DPO | Verifie la conformite RGPD de la requete | Certificat electronique eIDAS |
| Autorite legale | Verifie le mandat judiciaire | Ordonnance signee |
Procedure :
- Le requerant soumet un mandat (
Mandate) avec un certificat (Certificate) - Le mandat DOIT couvrir le meme contexte que le ReKey (binding verifie)
- Le DPO approuve ou rejette
- L'autorite legale approuve ou rejette
- La
DualValidationpasse aapproved = TRUEseulement si BOTH approuvent - Le re-chiffrement est alors debloque
3.3 Re-chiffrement¶
Preconditions :
- ReKey a l'etat ACTIVE
- Double validation approuvee (
dual_validated[id] = TRUE) - TTL > 0 (non expire)
- Nombre de CFrags < n (borne du seuil)
- Nonce unique : chaque operation fournit un nonce qui n'a pas encore ete utilise pour ce ReKey
EXIGENCE PRE-08 : Le nombre de CFrags produits NE DOIT PAS depasser n (le parametre du seuil). Prouve formellement (TLA+ CFragBound, Alloy CFragBound).
EXIGENCE PRE-18 : Chaque KFrag NE DOIT produire au plus qu'un CFrag pour une capsule donnee. Cette propriete est une consequence de PRE-08 (CFrags <= n) combinees aux n KFrags generes et au nonce anti-rejeu (PRE-15). L'implementation DOIT garantir qu'un KFrag consomme n'est pas reutilisable.
EXIGENCE PRE-15 : Chaque operation de re-encryption DOIT fournir un nonce unique. Le proxy DOIT rejeter tout nonce deja utilise pour le meme ReKey. Le nombre de nonces utilises DOIT etre egal au nombre de CFrags produits. Prouve formellement (TLA+ NoReplay, Alloy NonceAntiReplay).
EXIGENCE PRE-15a : Le nonce DOIT etre >= 96 bits (12 bytes) d'aleatoire genere par un CSPRNG. Les nonces bases sur un timestamp ou un compteur simple sont INTERDITS.
EXIGENCE PRE-15b : L'unicite du nonce est exigee au moins par ReKey. Le systeme DOIT rester sur en cas de retry reseau : une re-soumission avec le meme nonce DOIT etre rejetee de maniere idempotente (pas de double CFrag, pas d'erreur fatale).
Procedure :
- Le proxy recoit un KFrag, le ciphertext original (Capsule), et un nonce unique
- Le proxy verifie que le nonce n'est pas dans l'ensemble des nonces deja utilises
- Le proxy produit un CFrag via l'operation Umbral
- Le CFrag est enregistre avec le contexte du ReKey
- Le nonce est ajoute a l'ensemble des nonces utilises
- L'operation est tracee dans l'audit log
3.4 Coherence de contexte¶
EXIGENCE PRE-09 : Tous les artefacts d'un meme flux de re-chiffrement (KFrags, CFrags) DOIVENT partager le meme ContextId que le ReKey. Prouve formellement (Alloy ContextCoherence).
3.5 Binding mandate-contexte¶
EXIGENCE PRE-16 : Le mandat judiciaire DOIT etre lie cryptographiquement au contexte du ReKey. Cette liaison empeche la reutilisation d'un mandat pour un autre ReKey. Prouve formellement (Alloy MandateContextBinding, MandateAlwaysBound).
EXIGENCE PRE-16a : Le binding mandat-contexte DOIT etre verifiable independamment de la base de donnees : toute modification de mandate, contextId ou rekey.id DOIT etre detectable sans interroger l'etat serveur. Prouve formellement (Alloy MandateBindingVerifiable).
EXIGENCE PRE-16b : Le binding est calcule comme suit :
- Construire l'objet binding :
{ "mandateHash": "<SHA3-256 du mandat canonique (JCS), hex 64 chars>", "pkOwner": "<cle publique owner, SEC1 compresse hex 66 chars (33 bytes)>", "pkRecipient": "<cle publique recipient, SEC1 compresse hex 66 chars (33 bytes)>", "scope": "<contextId UUID>", "rekeyId": "<rekey UUID>", "validationTimestamp": "<ISO 8601 UTC>" } - Canonicaliser via JCS (RFC 8785)
bindingHash = SHA3-256(JCS(bindingObject))bindingSignature = ECDSA_P384(bindingHash, hsmPrivateKey)
Le binding est stocke avec le ReKey. La verification par un tiers recalcule bindingHash a partir des champs en clair et verifie bindingSignature avec la cle publique HSM.
EXIGENCE PRE-16c : Toute modification d'un champ couvert par le binding (mandateHash, pkOwner, pkRecipient, scope, rekeyId, validationTimestamp) invalide le binding. La verification DOIT echouer (fail-closed) si le bindingHash recalcule ne correspond pas au bindingHash stocke. La verification DOIT egalement echouer si la signature bindingSignature est invalide ou si la cle publique HSM n'est pas dans le trust-store.
3.6 Reconstruction¶
Le requerant collecte t CFrags et reconstruit la cle symetrique du document avec sa cle privee (sk_recipient). Cette operation se fait EXCLUSIVEMENT cote requerant — le proxy n'y participe pas.
3.7 Revocation¶
EXIGENCE PRE-10 : La revocation est immediate et irreversible. Un ReKey revoque ne peut plus produire de CFrags.
Declencheurs de revocation :
- Ordre du DPO (violation RGPD detectee)
- Demande du proprietaire
- Invalidation du mandat judiciaire
- Detection d'anomalie par le systeme de monitoring
3.8 Expiration (TTL)¶
EXIGENCE PRE-11 : Chaque ReKey a un TTL exprime en secondes de temps reel, borne par REKEY_MAX_TTL (defaut : 259200 secondes = 72 heures, bornes [3600, 2592000] = [1h, 30j]). Le TTL est fixe a la creation par le demandeur et clamp dans les bornes. L'expiration est evaluee par comparaison now() >= created_at + ttl_seconds. Quand le TTL est ecoule, le ReKey passe automatiquement a EXPIRED. L'horloge logique du modele formel (Tick) est une abstraction du temps reel ; chaque Tick correspond a un quantum de temps configurable. Prouve formellement (TLA+ TTLBound).
3.9 Destruction cryptographique¶
EXIGENCE PRE-12 : Un ReKey dans un etat terminal (REVOKED, EXPIRED, COMPLETED) DOIT etre DESTROYED. La destruction couvre explicitement :
| Composant | Action | Verification |
|---|---|---|
| KFrags en memoire | Zeroization (ecrasement tampon memoire) | kfragsZeroized = true |
| Entree base de donnees | Suppression ou marquage DESTROYED | Colonne status |
| Cache applicatif | Invalidation des entrees en cache | Prolog check_destruction_scope |
| Metadonnees sensibles | Purge des references contextuelles | Audit log trace |
Prouve formellement : TLA+ DestroyedImpliesZeroized, Alloy DestructionZeroizes.
EXIGENCE PRE-13 : Chaque ReKey DOIT etre associe a un contexte. Prouve formellement (TLA+ ContextPresent).
3.10 Audit trail¶
EXIGENCE PRE-14 : Chaque operation DOIT etre tracee dans un audit trail append-only. L'audit NE DOIT contenir AUCUN secret cryptographique (cles, KFrags, CFrags). Prouve structurellement (Alloy NoSecretsInAudit : AuditEntry ne contient que operation + contextId). Prouve en TLA+ par AuditAppendOnly.
EXIGENCE PRE-14a : L'audit DOIT etre stocke sur un support offrant des proprietes d'immutabilite ou de verifiabilite a posteriori (ex: stockage WORM, chainage de hash, ancrage blockchain). L'append-only logique seul (contrainte applicative) ne suffit pas face a un attaquant DB.
| Champ | Type | Description |
|---|---|---|
operation | Enum | GENERATE, RE_ENCRYPT, REVOKE, DESTROY |
contextId | UUID | Identifiant du contexte legal |
timestamp | DateTime | Horodatage RFC 3161 |
3.11 PKI et authenticite des cles¶
EXIGENCE PRE-17 : Chaque cle publique utilisee dans le protocole (owner et recipient) DOIT etre liee a un certificat eIDAS valide. Cette PKI previent les attaques par substitution de cle (rogue key attack). Prouve formellement (Alloy AuthenticatedKeys, Z INV-11 PKIAuthenticity).
3.12 Format de serialisation des artefacts PRE¶
EXIGENCE PRE-19 : Les artefacts PRE sont serialises selon les formats suivants :
| Artefact | Serialisation | Taille | Validation |
|---|---|---|---|
| PublicKey | SEC1 compresse (02/03 ‖ x) | 33 bytes exact | Premier byte 0x02 ou 0x03 |
| KFrag | Format NuCypher Umbral serialise | <= 256 bytes | Deserialisation + verification preuve |
| CFrag | Format NuCypher Umbral serialise | <= 256 bytes | Deserialisation + verification preuve |
| Capsule | Format NuCypher Umbral serialise | <= 256 bytes | Deserialisation + verification points E, V |
Toute entree dont la taille depasse la borne ou dont la deserialisation echoue DOIT etre rejetee (fail-closed). Les tailles indicatives sont basees sur l'implementation NuCypher reference (secp256k1) ; les bornes max (256 bytes) sont les contraintes validees par les modeles formels.
Note sur secp256k1 : La courbe secp256k1 utilise des points de 33 bytes en representation compressee (SEC1). Les KFrags, CFrags et Capsules encapsulent des points de courbe + preuves dont la taille varie selon l'implementation du provider Umbral. Le format de serialisation exact depend du provider utilise ; l'exigence normative porte sur les bornes de taille et la validation de deserialisation.
3.13 Stockage et transport des KFrags¶
EXIGENCE PRE-20 : Les KFrags DOIVENT etre stockes chiffres au repos (AES-256-GCM avec cle derivee de l'envelope HSM). Le transport des KFrags entre composants DOIT utiliser TLS 1.3 minimum. Les KFrags NE DOIVENT JAMAIS transiter en clair sur le reseau ni etre stockes en clair sur disque.
EXIGENCE PRE-20a : La cle de chiffrement des KFrags au repos DOIT etre derivee via HKDF-SHA256 a partir de la cle HSM du service, avec le rekeyId comme salt et "pv-kfrag-storage-v1" comme info. La rotation de la cle HSM entraine le re-chiffrement de tous les KFrags stockes.
4. Modele formel¶
4.1 Etats et transitions¶
Le protocole est modelise comme un systeme a etats avec 8 actions :
GenerateReKey ----> DualValidate ----> ReEncrypt(nonce) ----> CompleteReKey
|
RevokeReKey <----------------+
|
ExpireReKey <--- Tick
|
DestroyReKey <---------------+
(zeroize KFrags)
| Action | Preconditions | Postconditions |
|---|---|---|
| GenerateReKey(id) | id n'existe pas, t <= n, PKI valide, mandate bound | ReKey ACTIVE, TTL=MAX, cfrags=0, nonces={} |
| DualValidate(id) | ACTIVE, non valide | dual_validated=TRUE |
| ReEncrypt(id, nonce) | ACTIVE, valide, TTL>0, cfrags<n, nonce unique | cfrags++, nonces += |
| CompleteReKey(id) | ACTIVE, cfrags>=t | status=COMPLETED |
| RevokeReKey(id) | ACTIVE | status=REVOKED |
| ExpireReKey(id) | ACTIVE, TTL=0 | status=EXPIRED |
| DestroyReKey(id) | status in | status=DESTROYED, kfragsZeroized=TRUE |
| Tick | clock < MAX | clock++, TTL decremente pour tous les ReKeys actifs |
Note sur la verification bornee : Le model checking TLC explore exhaustivement l'espace d'etats pour les bornes specifiees dans
PV_PRE.cfg(MAX_REKEYS=2, MAX_THRESHOLD=2, REKEY_MAX_TTL=2, MAX_ITERATIONS=12). Cela couvre toutes les combinaisons possibles dans ces bornes. Pour des bornes plus grandes, les theoremes TLA+ fournissent des preuves par induction (non bornees). Alloy fournit des preuves structurelles complementaires (scope 5).
4.2 Invariants de surete¶
Les proprietes suivantes sont verifiees par model checking :
| ID | Invariant | Description | Preuve |
|---|---|---|---|
| INV-01 | TypeInvariant | Types corrects pour toutes les variables | TLC |
| INV-02 | TerminalIsFinal | Etats terminaux irreversibles | TLC + Alloy |
| INV-03 | ThresholdValid | 1 <= t <= n <= MAX_THRESHOLD | TLC + Alloy |
| INV-04 | TTLBound | TTL <= REKEY_MAX_TTL | TLC |
| INV-05 | DualValidationRequired | CFrags > 0 implique validation prealable | TLC + Alloy |
| INV-06 | CFragBound | CFrags <= n (borne du seuil) | TLC + Alloy |
| INV-07 | ContextPresent | Chaque ReKey a un contexte | TLC |
| INV-08 | DestroyedIsFinal | DESTROYED est absorbant | TLC |
| INV-09 | NoReplay | Nonce unique par re-encryption | TLC + Alloy |
| INV-10 | DestroyedImpliesZeroized | KFrags zeroizes apres destruction | TLC + Alloy |
| INV-11 | AuditAppendOnly | Audit log ne perd jamais d'entrees | TLC |
4.3 Theoremes prouves¶
Les theoremes suivants sont demontres en logique temporelle (TLA+) :
- THM-01 :
Spec => []TypeInvariant - THM-02 :
Spec => []TerminalIsFinal - THM-03 :
Spec => []ThresholdValid - THM-04 :
Spec => []DualValidationRequired - THM-05 :
Spec => []CFragBound - THM-06 :
Spec => []NoReplay - THM-07 :
Spec => []DestroyedImpliesZeroized - THM-08 :
Spec => []AuditAppendOnly
4.4 Assertions structurelles (Alloy)¶
Les assertions suivantes sont prouvees par le solveur SAT (UNSAT = pas de contre-exemple) :
| Assertion | Propriete | Resultat |
|---|---|---|
| NoDecryptInModel | Zero-knowledge garanti structurellement | UNSAT (prouve) |
| AllTerminalAreFinal | Etats terminaux irreversibles | UNSAT (prouve) |
| ThresholdAlwaysValid | Seuil toujours 1 <= t <= n | UNSAT (prouve) |
| ContextAlwaysCoherent | Artefacts coherents avec contexte ReKey | UNSAT (prouve) |
| RequesterNeverOwner | Proprietaire != requerant | UNSAT (prouve) |
| PKIAlwaysPresent | Chaque cle a un certificat | UNSAT (prouve) |
| MandateAlwaysBound | Mandat lie au contexte du ReKey | UNSAT (prouve) |
| NonceAntiReplay | Nonce unique par re-encryption | UNSAT (prouve) |
| DestructionZeroizes | DESTROYED implique KFrags zeroizes | UNSAT (prouve) |
4.5 Propriete zero-knowledge (garde architectural)¶
La propriete zero-knowledge du proxy est garantie a deux niveaux :
Niveau architectural (garde formel) :
- Le modele Alloy ne contient aucune signature
Decrypt - Le modele TLA+ ne contient aucune action
Decrypt - La spec Z ne definit aucun schema
Decrypt - Les regles Prolog verifient l'absence de methode
decryptdans le code (check_no_decrypt)
Niveau cryptographique (garantie Umbral) :
Les garanties de securite du schema Umbral (NuCypher, "Umbral: A Threshold Proxy Re-Encryption Scheme") assurent que le proxy, meme en possession de tous les KFrags, ne peut pas :
- Reconstruire la cle privee du proprietaire (
sk_owner) - Dechiffrer le ciphertext original
- Produire un plaintext a partir des CFrags seuls
Seul le destinataire (sk_recipient) peut dechiffrer apres reconstruction des t CFrags.
5. Considerations de securite¶
5.1 Modele de menace¶
| Menace | Mitigation | Verification |
|---|---|---|
| Proxy malveillant | Zero-knowledge : garde architectural + garantie Umbral | PRE-01, Alloy NoDecryptInModel |
| Re-chiffrement non autorise | Double validation (DPO + legal) obligatoire | PRE-07, INV-05 |
| Exces de CFrags | Borne par le seuil n | PRE-08, INV-06 |
| ReKey perime | TTL avec expiration automatique | PRE-11, INV-04 |
| Rejeu de re-encryption | Nonce unique par operation, rejet des doublons | PRE-15, INV-09 |
| Substitution de cle (rogue key) | PKI : certificats eIDAS sur chaque cle publique | PRE-17, INV-11 |
| Mandat detourne | Binding cryptographique mandat-contexte-ReKey | PRE-16, Alloy MandateContextBinding |
| Rejeu apres revocation | Etat terminal irreversible | PRE-02, INV-02 |
| Abus par le proprietaire | owner != recipient enforced | PRE-05, Alloy RequesterNotOwner |
| Fuite via audit | Audit ne contient que operation + contextId | PRE-14, Alloy NoSecretsInAudit |
| Non-destruction | Destruction explicite : KFrags + DB + cache | PRE-12, INV-10 |
5.2 Conformite RGPD¶
Le protocole est concu pour la conformite RGPD :
- Art. 17 (Droit a l'effacement) : La destruction cryptographique (DESTROYED) couvre KFrags memoire, entrees DB, et cache applicatif
- Art. 25 (Protection par defaut) : Zero-knowledge par construction (garde + Umbral)
- Art. 35 (DPIA) : L'audit trail append-only exhaustif permet la verification a posteriori
- Art. 32 (Securite) : Seuil (t, n) empeche un acteur unique d'acceder aux donnees ; PKI previent la substitution de cle
5.3 Limitations connues¶
- La destruction cryptographique (DESTROYED) detruit les artefacts PRE (KFrags, metadonnees) mais pas le ciphertext original. Le proprietaire conserve l'acces a ses propres donnees.
- Le seuil (t, n) est fixe a la creation du ReKey. Il ne peut pas etre modifie apres coup.
- Le choix de secp256k1 est motive par l'interoperabilite blockchain ; pour des usages sans blockchain, Curve25519 serait preferable.
6. Ancrage au code reel¶
Les specifications formelles sont ancrees aux artefacts reels du code ProbatioVault via extract-facts.py. Cet ancrage garantit que les modeles ne divergent pas de l'implementation.
| Systeme | Mecanisme d'ancrage | Verification |
|---|---|---|
| TLA+ | ASSUME verifiant les etats du code | Echec TLC si divergence |
| Alloy | one sig Real_* + fact some Real_* | Echec SAT si artefact manquant |
| Z | Schemas valides contre entities TypeORM | Lint FAIL si non matche |
| Prolog | Facts extraits du code vs 24 regles de conformite | Checks code reel |
6.1 Etat d'implementation¶
Note implementation : Les composants marques "Non implemente" representent des ecarts spec/code bloquants. Le protocole n'est pas considere comme verrouille operationnellement tant que ces composants ne sont pas implementes et que les checks Prolog ne passent pas a PASS.
| Composant | Statut | Checks Prolog |
|---|---|---|
| PreService (generateReKey, reEncrypt, validate) | Implemente | 4/4 PASS |
| Zero-knowledge (pas de decrypt) | Verifie | 1/1 PASS |
| LegalPreOrchestratorService | Implemente | 1/1 PASS |
| MandateValidatorService | Implemente | 1/1 PASS |
| DualValidationService | Implemente | 1/1 PASS |
| LegalCompositeProofService | Implemente | 1/1 PASS |
| LegalDestructionService.destroy() | Non implemente | 0/1 FAIL |
| legal_rekey entity (columns, enum) | Non implemente | 0/3 FAIL |
| LegalAuditTrailService | Non implemente | 0/1 FAIL |
| Validators (artefact, context, size) | Non implemente | 0/3 FAIL |
| UmbralWasmProvider | Non implemente | 0/1 FAIL |
| LegalReKeyManagerService | Non implemente | 0/1 FAIL |
| MandateValidatorService.validateContextBinding() | Non implemente | 0/1 FAIL |
| LegalDestructionService.zeroizeKFrags() | Non implemente | 0/1 FAIL |
| legal_rekey.used_nonces column | Non implemente | 0/1 FAIL |
| legal_rekey.certificate_id columns (PKI) | Non implemente | 0/1 FAIL |
7. Annexes¶
7.1 Specifications formelles associees¶
| Fichier | Systeme | Contenu |
|---|---|---|
PV_PRE.tla | TLA+ | Modele temporel (8 actions, 11 invariants, 8 theoremes) |
PV_PRE.cfg | TLA+ | Configuration TLC (MAX_REKEYS=2, MAX_THRESHOLD=2, MAX_ITERATIONS=12) |
PV_PRE.als | Alloy | Modele structurel (12 facts, 10 assertions) |
PV_PRE.zed | Z | Specification ensembliste (15 invariants, 9 theoremes) |
pv_pre_compliance.pl | Prolog | 24 regles de conformite code |
7.2 Matrice de tracabilite¶
| Exigence | TLA+ | Alloy | Z | Prolog |
|---|---|---|---|---|
| PRE-01 (zero-knowledge) | structurel | NoDecryptInModel | INV-02 | check_pre_no_decrypt |
| PRE-02 (terminal final) | TerminalIsFinal | AllTerminalAreFinal | INV-03 | - |
| PRE-03 (DESTROYED final) | DestroyedIsFinal | - | INV-03 | - |
| PRE-04 (threshold) | ThresholdValid | ThresholdAlwaysValid | INV-04 | - |
| PRE-05 (owner!=recipient) | - | RequesterNeverOwner | INV-09 | - |
| PRE-06 (secp256k1 + PKI) | - | AuthenticatedKeys | INV-11 | check_pki_certificate_binding |
| PRE-07 (dual validation) | DualValidationRequired | DualValidationRequired | INV-05 | check_dual_validation_service |
| PRE-08 (cfrag bound) | CFragBound | CFragBound | INV-07 | - |
| PRE-09 (context coherence) | ContextPresent | ContextAlwaysCoherent | INV-06 | check_context_validator |
| PRE-10 (revocation) | TerminalIsFinal | AllTerminalAreFinal | INV-03 | - |
| PRE-11 (TTL) | TTLBound | - | INV-08 | - |
| PRE-12 (destruction) | DestroyedImpliesZeroized | DestructionZeroizes | INV-14 | check_destruction_scope |
| PRE-13 (context present) | ContextPresent | - | INV-06 | - |
| PRE-14 (audit) | AuditAppendOnly | NoSecretsInAudit | INV-10, INV-15 | check_legal_audit_trail |
| PRE-14a (audit immutability) | A COUVRIR | A COUVRIR | A COUVRIR | A COUVRIR |
| PRE-15 (anti-rejeu) | NoReplay | NonceAntiReplay | INV-13 | check_anti_replay_nonce |
| PRE-15a (nonce CSPRNG >= 96 bits) | - | - | Z: Nonce.size >= 12 | - |
| PRE-15b (idempotence retry) | A COUVRIR | A COUVRIR | A COUVRIR | A COUVRIR |
| PRE-16 (mandate binding) | - | MandateAlwaysBound | INV-12 | check_mandate_context_binding |
| PRE-16a (binding verifiable hors DB) | - | MandateBindingVerifiable | Z: Mandate.bindingHash | - |
| PRE-16b (binding crypto complet) | - | MandateBindingVerifiable | Z: Mandate.bindingHash | check_mandate_context_binding |
| PRE-16c (binding fail-closed) | - | - | - | - |
| PRE-19 (wire format artefacts) | - | - | - | check_artefact_size_validator |
| PRE-20 (KFrag stockage chiffre) | - | - | - | - |
| PRE-20a (KFrag derivation cle) | - | - | - | - |
| PRE-17 (PKI) | - | PKIAlwaysPresent | INV-11 | check_pki_certificate_binding |
| PRE-18 (KFrag single-use) | derive de PRE-08 + PRE-15 | derive de CFragBound + NonceAntiReplay | - | - |
7.3 Vecteurs de test¶
| Test | Entree | Sortie attendue |
|---|---|---|
| Threshold valide | t=2, n=3 | ReKey cree, ACTIVE |
| Threshold invalide | t=4, n=3 | ERREUR (t > n) |
| Re-chiffrement sans validation | ReEncrypt avant DualValidate | ERREUR |
| Depassement CFrags | n=3, puis 4eme ReEncrypt | ERREUR (CFragBound) |
| Expiration | TTL=0 + ReEncrypt | ERREUR (EXPIRED) |
| Revocation | RevokeReKey + ReEncrypt | ERREUR (REVOKED) |
| Owner == Recipient | generateReKey(pk, pk) | ERREUR (RequesterNotOwner) |
| Zero-knowledge | Rechercher methode decrypt | NOT FOUND |
| Nonce duplique | ReEncrypt(id, nonce_1) x2 | ERREUR (NoReplay) |
| PKI manquante | generateReKey sans certificat | ERREUR (PKIAuthenticity) |
| Mandat hors contexte | mandate.scope != rekey.context | ERREUR (MandateContextBinding) |
| Binding mandat altere | modifier bindingHash apres validation | ERREUR (MandateBindingVerifiable) |
| Nonce < 96 bits | nonce de 8 bytes | ERREUR (PRE-15a, taille insuffisante) |
| KFrag reutilise | re-encryption avec meme KFrag, meme capsule | ERREUR (PRE-18, nonce duplique) |
| Retry reseau | re-soumission identique (meme nonce) | Rejet idempotent, pas de double CFrag |
| Binding recalcul OK | bindingHash recalcule = bindingHash stocke | Verification PASS |
| Binding champ altere | modifier pkRecipient dans le binding | Verification FAIL (PRE-16c, fail-closed) |
| Binding signature invalide | signature HSM invalide | Verification FAIL (PRE-16c) |
| TTL bornes | TTL = 1800 (< 3600 min) | Clamp a 3600 secondes |
| TTL bornes max | TTL = 3000000 (> 2592000 max) | Clamp a 2592000 secondes |
| KFrag taille max | KFrag de 300 bytes | ERREUR (PRE-19, > 256 bytes) |
| PublicKey format invalide | premier byte 0x04 (non compresse) | ERREUR (PRE-19, SEC1 compresse requis) |
| KFrag stocke en clair | KFrag non chiffre sur disque | ERREUR (PRE-20, chiffrement obligatoire) |
7.4 Historique des revisions¶
| Version | Date | Description |
|---|---|---|
| 1.0.0 | 2026-02-25 | Version initiale, generee depuis modeles formels verifies |
| 1.1.0 | 2026-02-25 | PKI binding, mandate-context binding, anti-rejeu nonce, destruction scope, tailles reelles, secp256k1 note, TLC bounded caveat |
| 1.2.0 | 2026-02-25 | PRE-16a/b binding verifiable hors DB + champs minimum, PRE-15a/b nonce CSPRNG >= 96 bits + idempotence retry, PRE-18 KFrag single-use (derive), PRE-14a audit immutability WORM/blockchain, Umbral provider MUST secp256k1, tailles artefacts qualifiees indicatives, reference Umbral corrigee |
| 1.3.0 | 2026-03-02 | PRE-16b binding crypto complet (algorithme JCS + SHA3-256 + ECDSA_P384 HSM), PRE-16c fail-closed binding, PRE-11 TTL en secondes reelles avec bornes [1h, 30j], PRE-19 wire format exact avec validation, PRE-20/20a stockage et transport KFrags chiffres, note ecarts spec/code bloquants, PRE-14a/PRE-15b signales A COUVRIR |