63a9cb5273
Datascience: aggregate_by_group, deduplicate_entities/relations, detect_drift, diff_entities/relations, extract_entities/relations_llm, hotness_score, melt, merge_graphs, pivot, build_entity/relation_schema_prompt. Finance: avellaneda_stoikov_quotes, generate_gbm_prices, generate_taker_order, hawkes_intensity + módulo finance.py. Cybersecurity: envelope_encrypt/decrypt + módulo cybersecurity.py. Pipelines: extraction_pipeline, monte_carlo_market, run_market_sim. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
102 lines
3.1 KiB
Python
102 lines
3.1 KiB
Python
"""Tests para envelope_encrypt y envelope_decrypt."""
|
|
|
|
import secrets
|
|
import sys
|
|
import os
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
|
|
from cybersecurity import envelope_encrypt, envelope_decrypt
|
|
|
|
|
|
def test_encrypt_decrypt_roundtrip():
|
|
master_key = secrets.token_bytes(32)
|
|
plaintext = b"datos de prueba para envelope encryption"
|
|
ciphertext = envelope_encrypt(plaintext, master_key)
|
|
result = envelope_decrypt(ciphertext, master_key)
|
|
assert result == plaintext
|
|
|
|
|
|
def test_datos_vacios():
|
|
master_key = secrets.token_bytes(32)
|
|
ciphertext = envelope_encrypt(b"", master_key)
|
|
result = envelope_decrypt(ciphertext, master_key)
|
|
assert result == b""
|
|
|
|
|
|
def test_datos_grandes():
|
|
master_key = secrets.token_bytes(32)
|
|
plaintext = secrets.token_bytes(1024 * 1024) # 1 MB
|
|
ciphertext = envelope_encrypt(plaintext, master_key)
|
|
result = envelope_decrypt(ciphertext, master_key)
|
|
assert result == plaintext
|
|
|
|
|
|
def test_decrypt_datos_no_cifrados_passthrough():
|
|
master_key = secrets.token_bytes(32)
|
|
plain = b"archivo no cifrado, sin magic bytes"
|
|
result = envelope_decrypt(plain, master_key)
|
|
assert result == plain
|
|
|
|
|
|
def test_key_incorrecta():
|
|
master_key = secrets.token_bytes(32)
|
|
wrong_key = secrets.token_bytes(32)
|
|
ciphertext = envelope_encrypt(b"secreto", master_key)
|
|
try:
|
|
envelope_decrypt(ciphertext, wrong_key)
|
|
assert False, "deberia haber lanzado excepcion"
|
|
except Exception:
|
|
pass # esperado: InvalidTag de cryptography
|
|
|
|
|
|
def test_envelope_truncado():
|
|
master_key = secrets.token_bytes(32)
|
|
ciphertext = envelope_encrypt(b"datos", master_key)
|
|
truncated = ciphertext[:6] # header incompleto
|
|
try:
|
|
envelope_decrypt(truncated, master_key)
|
|
assert False, "deberia haber lanzado ValueError"
|
|
except ValueError:
|
|
pass
|
|
|
|
|
|
def test_magic_invalido():
|
|
master_key = secrets.token_bytes(32)
|
|
# Construir datos con magic valido para pasar el check del passthrough
|
|
# pero con header corrupto
|
|
bad_envelope = b"OVE1" + b"\x00" * 20 # magic correcto pero header invalido
|
|
try:
|
|
envelope_decrypt(bad_envelope, master_key)
|
|
assert False, "deberia haber lanzado excepcion"
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def test_ciphertext_tiene_magic_correcto():
|
|
master_key = secrets.token_bytes(32)
|
|
ciphertext = envelope_encrypt(b"test", master_key)
|
|
assert ciphertext[:4] == b"OVE1"
|
|
|
|
|
|
def test_ciphertext_es_distinto_cada_vez():
|
|
master_key = secrets.token_bytes(32)
|
|
plaintext = b"mismo mensaje"
|
|
ct1 = envelope_encrypt(plaintext, master_key)
|
|
ct2 = envelope_encrypt(plaintext, master_key)
|
|
# IVs aleatorios garantizan ciphertexts distintos
|
|
assert ct1 != ct2
|
|
|
|
|
|
if __name__ == "__main__":
|
|
test_encrypt_decrypt_roundtrip()
|
|
test_datos_vacios()
|
|
test_datos_grandes()
|
|
test_decrypt_datos_no_cifrados_passthrough()
|
|
test_key_incorrecta()
|
|
test_envelope_truncado()
|
|
test_magic_invalido()
|
|
test_ciphertext_tiene_magic_correcto()
|
|
test_ciphertext_es_distinto_cada_vez()
|
|
print("Todos los tests pasaron.")
|