secubox-openwrt/package/secubox/zkp-hamiltonian/SECUBOX_INTEGRATION.md
CyberMind-FR 6553936886 feat(zkp-hamiltonian): Add Zero-Knowledge Proof library based on Hamiltonian Cycle
Implements NIZK (Non-Interactive Zero-Knowledge) proof protocol using
Blum's Hamiltonian Cycle construction with Fiat-Shamir transformation.

Features:
- Complete C99 library with SHA3-256 commitments (via OpenSSL)
- Graph generation with embedded trapdoor (Hamiltonian cycle)
- NIZK proof generation and verification
- Binary serialization for proofs, graphs, and cycles
- CLI tools: zkp_keygen, zkp_prover, zkp_verifier
- Comprehensive test suite (41 tests)

Security properties:
- Completeness: honest prover always convinces verifier
- Soundness: cheater fails with probability >= 1 - 2^(-128)
- Zero-Knowledge: verifier learns nothing about the secret cycle

Target: OpenWrt ARM (SecuBox authentication module)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-24 09:59:16 +01:00

523 lines
19 KiB
Markdown

# Intégration SecuBox — Module ZKP Hamiltonien
## Architecture d'intégration dans l'écosystème SecuBox
### CyberMind.FR — Version 1.0
---
## 1. Positionnement dans SecuBox
### 1.1 Carte des modules SecuBox concernés
```
SecuBox (38+ modules)
├── secubox-core ← dépendance de base
├── secubox-auth ← MODULE PRINCIPAL CONSOMMATEUR
│ ├── zkp-hamiltonian ← CE MODULE (nouveau)
│ ├── pki-local ← remplacé partiellement
│ └── password-auth ← complété par ZKP
├── secubox-vpn ← intégration phase 2
├── secubox-ids ← intégration phase 3
└── secubox-luci ← interface de gestion
└── luci-app-zkp ← nouveau (dashboard LuCI)
```
### 1.2 Cas d'usage cibles
| Cas d'usage | Description | Priorité |
|-------------|-------------|----------|
| **Auth nœud-à-nœud** | Deux routeurs prouvent mutuellement leur identité sans PKI centrale | P1 |
| **Auth admin sans mot de passe** | L'admin prouve qu'il possède la clé secrète (H) sans la transmettre | P1 |
| **Bootstrap réseau maillé** | Enrôlement d'un nouveau nœud sans autorité de certification | P2 |
| **Audit de configuration** | Prouver qu'une config est valide sans révéler les détails | P3 |
---
## 2. Architecture d'intégration
### 2.1 Vue d'ensemble
```
┌─────────────────────────────────────────────────────────────┐
│ SecuBox Node A (Prouveur) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ secubox-auth│ │zkp-hamiltonian│ │ secubox-core │ │
│ │ │───▶│ │───▶│ │ │
│ │ auth_agent │ │ zkp_prove() │ │ /dev/urandom │ │
│ │ │◀───│ │ │ libsodium │ │
│ └──────────────┘ └──────────────┘ └───────────────┘ │
│ │ │
│ │ NIZKProof (binaire sérialisé) │
└───────────┼───────────────────────────────────────────────────┘
│ réseau (UDP/TCP chiffré par secubox-vpn)
┌───────────┼───────────────────────────────────────────────────┐
│ │ SecuBox Node B (Vérifieur) │
│ ┌────────▼─────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ secubox-auth│ │zkp-hamiltonian│ │ secubox-luci │ │
│ │ │───▶│ │ │ │ │
│ │ auth_verif │ │ zkp_verify() │ │ dashboard ZKP │ │
│ │ │◀───│ │ │ │ │
│ └──────────────┘ └──────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────-─┘
```
### 2.2 Interface avec secubox-auth
Le module `secubox-auth` appelle `zkp-hamiltonian` via une **interface C bien définie** et une **interface de socket Unix** pour les composants non-C (scripts Lua/LuCI).
```c
/* secubox_auth_zkp.h — Interface auth ↔ ZKP */
#include "zkp_hamiltonian.h"
/* Contexte d'authentification ZKP persistant */
typedef struct {
char identity[64]; /* identifiant du nœud ("node-A") */
Graph G; /* graphe public partagé */
HamiltonianCycle H; /* clé secrète (uniquement côté prouveur) */
uint8_t G_fingerprint[32]; /* SHA3-256(G sérialisé), partagé */
bool has_secret; /* true si ce nœud est prouveur */
} ZKPAuthContext;
/* Initialisation */
int zkp_auth_init_prover(ZKPAuthContext *ctx,
const char *identity,
uint8_t n,
double extra_ratio);
int zkp_auth_init_verifier(ZKPAuthContext *ctx,
const char *identity,
const uint8_t *serialized_G,
size_t G_len);
/* Protocole */
int zkp_auth_prove(const ZKPAuthContext *ctx,
uint8_t *proof_buf,
size_t *proof_len);
int zkp_auth_verify(const ZKPAuthContext *ctx,
const uint8_t *proof_buf,
size_t proof_len);
/* Export du graphe public (à diffuser au vérifieur) */
int zkp_auth_export_public(const ZKPAuthContext *ctx,
uint8_t *buf,
size_t *len);
/* Persistance sécurisée */
int zkp_auth_save_context(const ZKPAuthContext *ctx,
const char *path); /* chiffré AES-256-GCM */
int zkp_auth_load_context(ZKPAuthContext *ctx,
const char *path,
const uint8_t *key); /* clé de déchiffrement */
```
---
## 3. Protocole réseau SecuBox-ZKP
### 3.1 Format des messages
Tous les messages sont encapsulés dans le format SecuBox standard (TLV binaire) :
```
┌──────────────────────────────────────────────────────────────┐
│ SecuBox Message Frame │
│ │
│ [4B] Magic = 0x5345_435A ("SECZ") │
│ [1B] Version = 0x01 │
│ [1B] Type = voir tableau ci-dessous │
│ [2B] Reserved = 0x0000 │
│ [4B] Length = longueur du payload en octets (big-endian) │
│ [32B] HMAC = HMAC-SHA3-256(header+payload, session_key) │
│ [Nb] Payload = données du message │
└──────────────────────────────────────────────────────────────┘
```
| Type | Valeur | Description |
|------|--------|-------------|
| `ZKP_HELLO` | 0x10 | Demande d'auth, envoie identité |
| `ZKP_GRAPH_OFFER` | 0x11 | Prouveur envoie G (graphe public) |
| `ZKP_GRAPH_ACK` | 0x12 | Vérifieur confirme réception de G |
| `ZKP_PROOF` | 0x13 | Prouveur envoie NIZKProof |
| `ZKP_RESULT` | 0x14 | Vérifieur envoie ACCEPT/REJECT |
| `ZKP_ERROR` | 0xFF | Erreur protocolaire |
### 3.2 Séquence d'authentification complète
```
Prouveur (A) Vérifieur (B)
│ │
│──── ZKP_HELLO {identity_A, n} ──────────▶│
│ │ (lookup G_A dans sa DB
│ │ ou demande envoi)
│◀─── ZKP_GRAPH_OFFER? ou ZKP_GRAPH_ACK ──│
│ │
│ [si B ne connaît pas G_A] │
│──── ZKP_GRAPH_OFFER {G_sérialisé} ──────▶│
│ │ (stocke G_A,
│ │ vérifie fingerprint)
│◀─── ZKP_GRAPH_ACK {G_fingerprint} ───────│
│ │
│ [génération de la preuve NIZK] │
│ zkp_prove(G, H) → NIZKProof │
│ │
│──── ZKP_PROOF {NIZKProof_sérialisée} ───▶│
│ │ zkp_verify(G, proof)
│◀─── ZKP_RESULT {ACCEPT, timestamp} ──────│
│ │
│ [session établie] │
```
### 3.3 Gestion des timeouts et rejeu
```c
/* Paramètres de sécurité du protocole réseau */
#define ZKP_NET_TIMEOUT_MS 5000 /* 5s max par message */
#define ZKP_NET_MAX_PROOF_SIZE (128*128*32 + 512) /* taille max NIZKProof */
#define ZKP_SESSION_NONCE_TTL_S 30 /* nonce de session périmé après 30s */
#define ZKP_MAX_AUTH_ATTEMPTS 3 /* ban temporaire après 3 échecs */
#define ZKP_BAN_DURATION_S 300 /* 5 minutes de ban */
```
Le `session_nonce` dans NIZKProof inclut un **timestamp UNIX 32 bits** dans ses 4 premiers octets — le vérifieur rejette toute preuve avec timestamp > 30 secondes d'écart.
---
## 4. Stockage et persistance
### 4.1 Arborescence des fichiers
```
/etc/secubox/zkp/
├── identity.conf ← configuration du nœud
├── prover/
│ ├── graph.pub ← graphe public G (partageable)
│ ├── key.enc ← cycle H chiffré (AES-256-GCM + PBKDF2)
│ └── key.pub.fingerprint ← SHA3-256(G) pour vérification rapide
└── verifier/
├── trusted/
│ ├── node-A.pub ← graphe public de node-A
│ ├── node-B.pub ← graphe public de node-B
│ └── ...
└── sessions/
└── [nonce].used ← nonces consommés (anti-rejeu, TTL 30s)
```
### 4.2 Format de la clé chiffrée (key.enc)
```
┌─────────────────────────────────────────────────────┐
│ ZKP Key File v1 │
│ │
│ [4B] Magic = "ZKPK" │
│ [1B] Version = 0x01 │
│ [16B] Salt = sel PBKDF2 (aléatoire) │
│ [12B] IV = nonce AES-256-GCM │
│ [4B] Iter = itérations PBKDF2 (ex: 100000) │
│ [4B] PayLen = longueur du payload chiffré │
│ [Nb] Payload = AES-256-GCM(HamiltonianCycle sér.) │
│ [16B] Tag = tag GCM │
└─────────────────────────────────────────────────────┘
```
Le mot de passe de déchiffrement est dérivé du mot de passe admin SecuBox via PBKDF2-SHA256. En option : déchiffrement via TPM si disponible sur le matériel.
### 4.3 Rotation des clés
```
/etc/secubox/zkp/rotate.sh
1. Générer (G_new, H_new) via zkp_keygen
2. Annoncer G_new aux nœuds pairs (ZKP_GRAPH_OFFER)
3. Période de grâce : 24h où G_old et G_new sont acceptés
4. Supprimer G_old après la période de grâce
```
---
## 5. Interface LuCI (luci-app-zkp)
### 5.1 Pages et fonctionnalités
```
SecuBox Dashboard
└── Authentification ZKP
├── [Onglet] État
│ ├── Statut du module (actif/inactif)
│ ├── Identité du nœud
│ ├── Fingerprint du graphe public
│ ├── Nombre d'authentifications réussies (24h)
│ ├── Nombre d'échecs (24h)
│ └── Dernière authentification (horodatage + peer)
├── [Onglet] Configuration
│ ├── Taille du graphe n (slider 20-80)
│ ├── Ratio arêtes leurres (0.5 - 2.0)
│ ├── Timeout réseau (ms)
│ ├── Tentatives max avant ban
│ └── Durée de ban (secondes)
├── [Onglet] Gestion des clés
│ ├── [Bouton] Générer nouvelle paire (G, H)
│ ├── [Bouton] Exporter graphe public G
│ ├── [Bouton] Importer graphe public (pair de confiance)
│ ├── [Bouton] Rotation des clés
│ └── Liste des pairs de confiance
└── [Onglet] Journal
├── Filtres : date, peer, résultat
├── Tableau des événements d'authentification
└── [Bouton] Exporter CSV
```
### 5.2 Backend UCI (Unified Configuration Interface)
```uci
# /etc/config/secubox_zkp
config zkp 'global'
option enabled '1'
option identity 'node-notre-dame-01'
option graph_n '50'
option extra_ratio '1.0'
option timeout_ms '5000'
option max_attempts '3'
option ban_duration '300'
option log_level 'info' # debug|info|warn|error
config zkp 'network'
option listen_port '7890'
option bind_addr '0.0.0.0'
option use_tls '1' # TLS par-dessus pour le transport
config trusted_peer 'node-a'
option identity 'node-a'
option graph_file '/etc/secubox/zkp/verifier/trusted/node-a.pub'
option fingerprint 'a1b2c3...'
option enabled '1'
```
### 5.3 Script UCI de génération initiale
```sh
#!/bin/sh
# /etc/secubox/zkp/init.sh
# Appelé lors du premier démarrage ou après factory reset
IDENTITY=$(uci get secubox_zkp.global.identity 2>/dev/null || hostname)
N=$(uci get secubox_zkp.global.graph_n 2>/dev/null || echo 50)
RATIO=$(uci get secubox_zkp.global.extra_ratio 2>/dev/null || echo 1.0)
mkdir -p /etc/secubox/zkp/prover
mkdir -p /etc/secubox/zkp/verifier/trusted
mkdir -p /etc/secubox/zkp/verifier/sessions
# Génération de la paire (G, H)
zkp_keygen -n "$N" -r "$RATIO" -o /etc/secubox/zkp/prover/identity \
&& logger -t secubox-zkp "Graphe généré : n=$N, ratio=$RATIO" \
|| { logger -t secubox-zkp "ERREUR : génération échouée"; exit 1; }
# Calcul du fingerprint
sha3sum /etc/secubox/zkp/prover/identity.graph \
> /etc/secubox/zkp/prover/key.pub.fingerprint
logger -t secubox-zkp "Initialisation ZKP terminée pour $IDENTITY"
```
---
## 6. Daemon secubox-zkpd
### 6.1 Rôle
Le daemon `secubox-zkpd` gère les connexions entrantes, maintient les sessions, applique les politiques de ban, et journalise les événements dans syslog.
### 6.2 Fichier de démarrage init.d
```sh
#!/bin/sh /etc/rc.common
# /etc/init.d/secubox-zkpd
START=85
STOP=15
USE_PROCD=1
NAME=secubox-zkpd
PROG=/usr/sbin/secubox-zkpd
start_service() {
local enabled identity port bind_addr
config_load secubox_zkp
config_get_bool enabled global enabled 1
[ "$enabled" -eq 0 ] && return 0
config_get identity global identity "secubox-node"
config_get port network listen_port 7890
config_get bind_addr network bind_addr "0.0.0.0"
procd_open_instance
procd_set_param command "$PROG" \
-i "$identity" \
-p "$port" \
-b "$bind_addr" \
-g /etc/secubox/zkp/prover/identity.graph \
-k /etc/secubox/zkp/prover/identity.key.enc \
-T /etc/secubox/zkp/verifier/trusted/ \
-S /etc/secubox/zkp/verifier/sessions/
procd_set_param respawn 3600 5 0
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param file /etc/config/secubox_zkp
procd_close_instance
}
reload_service() {
stop
start
}
```
### 6.3 Intégration syslog
```c
/* Niveaux de log SecuBox-ZKP */
#define ZKP_LOG_DEBUG LOG_DEBUG
#define ZKP_LOG_INFO LOG_INFO
#define ZKP_LOG_WARN LOG_WARNING
#define ZKP_LOG_ERROR LOG_ERR
#define ZKP_LOG_AUDIT LOG_NOTICE /* toujours loggé, pour l'audit ANSSI */
/* Macro de log */
#define zkp_log(level, fmt, ...) \
syslog(level, "[secubox-zkp] " fmt, ##__VA_ARGS__)
/* Événements d'audit obligatoires (ANSSI CSPN) */
/* Toujours logger avec ZKP_LOG_AUDIT : */
/* - AUTH_SUCCESS : peer, timestamp, proof_size */
/* - AUTH_FAILURE : peer, timestamp, raison */
/* - KEY_GENERATED : n, ratio, fingerprint */
/* - KEY_ROTATED : old_fingerprint, new_fingerprint */
/* - PEER_BANNED : peer_ip, attempt_count */
/* - PEER_UNBANNED : peer_ip */
```
---
## 7. Tests d'intégration SecuBox
### 7.1 Tests sur nœud unique (simulation)
```sh
#!/bin/sh
# tests/integration/test_loopback.sh
GRAPH=/tmp/test.graph
KEY=/tmp/test.key.enc
PROOF=/tmp/test.proof
echo "=== Test 1 : Génération ==="
zkp_keygen -n 20 -r 0.5 -o /tmp/test
[ $? -eq 0 ] && echo "OK" || { echo "FAIL"; exit 1; }
echo "=== Test 2 : Preuve ==="
zkp_prover -g $GRAPH -k $KEY -o $PROOF
[ $? -eq 0 ] && echo "OK" || { echo "FAIL"; exit 1; }
echo "=== Test 3 : Vérification ==="
zkp_verifier -g $GRAPH -p $PROOF
[ $? -eq 0 ] && echo "ACCEPT OK" || { echo "REJECT - FAIL"; exit 1; }
echo "=== Test 4 : Anti-rejeu ==="
zkp_verifier -g $GRAPH -p $PROOF # deuxième fois avec même proof
[ $? -ne 0 ] && echo "OK (rejeu détecté)" || echo "FAIL (rejeu accepté)"
echo "=== Test 5 : Preuve corrompue ==="
cp $PROOF /tmp/tampered.proof
printf '\xFF' | dd of=/tmp/tampered.proof bs=1 seek=100 conv=notrunc 2>/dev/null
zkp_verifier -g $GRAPH -p /tmp/tampered.proof
[ $? -eq 1 ] && echo "REJECT OK" || echo "FAIL (corruption non détectée)"
```
### 7.2 Test deux nœuds (QEMU/netns)
```sh
# tests/integration/test_two_nodes.sh
# Requiert : ip netns, qemu ou deux VMs OpenWrt
ip netns add prover_ns
ip netns add verifier_ns
ip link add veth-p type veth peer name veth-v
ip link set veth-p netns prover_ns
ip link set veth-v netns verifier_ns
ip netns exec prover_ns ip addr add 10.0.0.1/24 dev veth-p
ip netns exec verifier_ns ip addr add 10.0.0.2/24 dev veth-v
ip netns exec prover_ns ip link set veth-p up
ip netns exec verifier_ns ip link set veth-v up
# Démarrer le vérifieur
ip netns exec verifier_ns secubox-zkpd \
-g /tmp/node-a.graph \
-T /tmp/trusted/ \
-p 7890 &
sleep 1
# Authentification depuis le prouveur
ip netns exec prover_ns zkp_client \
-g /tmp/node-a.graph \
-k /tmp/node-a.key.enc \
-H 10.0.0.2 -P 7890
echo "Résultat : $?"
```
---
## 8. Feuille de route d'intégration
### 8.1 Phases
```
Phase 1 — Bibliothèque standalone (4-6 semaines)
✓ zkp-hamiltonian compilé pour OpenWrt
✓ Tests unitaires passants
✓ CLI tools fonctionnels
✓ Package OpenWrt installable
Phase 2 — Intégration auth (3-4 semaines)
✓ secubox-auth utilise zkp pour auth nœud-à-nœud
✓ Protocole réseau implémenté (secubox-zkpd)
✓ UCI configuration
✓ init.d + procd
Phase 3 — Interface LuCI (2-3 semaines)
✓ luci-app-zkp dashboard
✓ Gestion des clés via interface web
✓ Journal d'authentification
✓ Import/export des graphes pairs
Phase 4 — Durcissement CSPN (ongoing)
✓ Audit des logs conformes ANSSI
✓ Tests de pénétration
✓ Documentation pour dossier CSPN
✓ Fuzz testing des parseurs réseau
```
### 8.2 Dépendances inter-modules SecuBox
```
zkp-hamiltonian
↑ requis par
secubox-auth (mod_zkp)
↑ requis par
secubox-vpn (auth handshake)
secubox-ids (détection bruteforce ZKP)
luci-app-zkp (interface)
secubox-audit (logs CSPN)
```