Alexis Bruneteau 67a2b3ec6f fix: Restore backend infrastructure and complete Phase 2 & 3
Restores all missing project files and fixes:
- Restored backend/blockchain.py with full blockchain implementation
- Restored backend/routes/votes.py with all API endpoints
- Restored frontend/components/voting-interface.tsx voting UI
- Fixed backend/crypto/hashing.py to handle both str and bytes
- Fixed pyproject.toml for Poetry compatibility
- All cryptographic modules tested and working
- ElGamal encryption, ZK proofs, digital signatures functional
- Blockchain integrity verification working
- Homomorphic vote counting implemented and tested

Phase 2 Backend API: ✓ COMPLETE
Phase 3 Frontend Interface: ✓ COMPLETE

Verification:
✓ Frontend builds successfully (12 routes)
✓ Backend crypto modules all import correctly
✓ Full voting simulation works end-to-end
✓ Blockchain records and verifies votes
✓ Homomorphic vote counting functional

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 01:56:10 +01:00

81 lines
2.2 KiB
Python

"""
Fonctions de hachage cryptographique pour intégrité et dérivation de clés.
"""
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from typing import Tuple
import os
class SecureHash:
"""
Hachage cryptographique sécurisé avec SHA-256.
Utilisé pour:
- Vérifier l'intégrité des données
- Dériver des clés
- Identifier les votes
"""
@staticmethod
def sha256(data: bytes) -> bytes:
"""Calculer le hash SHA-256"""
if isinstance(data, str):
data = data.encode()
digest = hashes.Hash(
hashes.SHA256(),
backend=default_backend()
)
digest.update(data)
return digest.finalize()
@staticmethod
def sha256_hex(data: bytes) -> str:
"""SHA-256 en hexadécimal"""
if isinstance(data, str):
data = data.encode()
return SecureHash.sha256(data).hex()
@staticmethod
def derive_key(password: bytes, salt: bytes = None, length: int = 32) -> Tuple[bytes, bytes]:
"""
Dériver une clé à partir d'un mot de passe avec PBKDF2.
Returns:
(key, salt) - salt pour stocker et retrouver la clé
"""
if salt is None:
salt = os.urandom(16)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=length,
salt=salt,
iterations=100000,
backend=default_backend()
)
key = kdf.derive(password)
return key, salt
@staticmethod
def hash_bulletin(vote_id: int, candidate_id: int, timestamp: int) -> str:
"""
Générer un identifiant unique pour un bulletin.
Utilisé pour l'anonymat + traçabilité.
"""
data = f"{vote_id}:{candidate_id}:{timestamp}".encode()
return SecureHash.sha256_hex(data)
@staticmethod
def hash_vote_commitment(encrypted_vote: bytes, random_salt: bytes) -> str:
"""
Hash d'un vote chiffré pour commitments.
"""
combined = encrypted_vote + random_salt
return SecureHash.sha256_hex(combined)
from typing import Tuple