Initial commit
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import pytest
|
||||
from core.prime_number import PrimeNumber
|
||||
|
||||
|
||||
def test_from_value_valid():
|
||||
p = PrimeNumber.from_value(61)
|
||||
assert p.value == 61
|
||||
assert repr(p) == "PrimeNumber(61)"
|
||||
|
||||
|
||||
def test_from_value_invalid():
|
||||
with pytest.raises(ValueError):
|
||||
PrimeNumber.from_value(60) # не простое
|
||||
|
||||
|
||||
def test_random_in_range():
|
||||
p = PrimeNumber.random(2, 20)
|
||||
assert isinstance(p, PrimeNumber)
|
||||
assert 2 <= p.value <= 20
|
||||
# дополнительно проверим, что оно действительно простое
|
||||
assert PrimeNumber._is_prime(p.value)
|
||||
|
||||
|
||||
def test_random_no_primes():
|
||||
with pytest.raises(ValueError):
|
||||
PrimeNumber.random(90, 92) # в этом диапазоне простых нет
|
||||
@@ -0,0 +1,50 @@
|
||||
import pytest
|
||||
from core.private_key import PrivateKey
|
||||
from core.prime_number import PrimeNumber
|
||||
|
||||
|
||||
def test_encrypt_decrypt_cycle():
|
||||
"""Проверка: сообщение после encrypt → decrypt восстанавливается"""
|
||||
p1 = PrimeNumber.from_value(61)
|
||||
p2 = PrimeNumber.from_value(53)
|
||||
priv = PrivateKey(p1, p2)
|
||||
pub = priv.make_public_key()
|
||||
|
||||
messages = [1, 2, 42, 123, priv.n - 1]
|
||||
for m in messages:
|
||||
c = pub.encrypt(m)
|
||||
m_back = priv.decrypt(c)
|
||||
assert m == m_back
|
||||
|
||||
|
||||
def test_e_is_prime_and_coprime_with_phi():
|
||||
"""e должно быть простым и взаимно простым с φ(n)"""
|
||||
p1 = PrimeNumber.from_value(61)
|
||||
p2 = PrimeNumber.from_value(53)
|
||||
priv = PrivateKey(p1, p2)
|
||||
|
||||
assert isinstance(priv.e, PrimeNumber)
|
||||
assert (priv.e.value > 1)
|
||||
assert (priv.phi % priv.e.value != 0)
|
||||
|
||||
|
||||
def test_d_is_inverse_of_e_mod_phi():
|
||||
"""e*d ≡ 1 (mod φ(n))"""
|
||||
p1 = PrimeNumber.from_value(61)
|
||||
p2 = PrimeNumber.from_value(53)
|
||||
priv = PrivateKey(p1, p2)
|
||||
|
||||
assert (priv.e.value * priv.d) % priv.phi == 1
|
||||
|
||||
|
||||
def test_decrypt_invalid_inputs():
|
||||
"""Должны бросаться ошибки при неверных входных данных"""
|
||||
p1 = PrimeNumber.from_value(61)
|
||||
p2 = PrimeNumber.from_value(53)
|
||||
priv = PrivateKey(p1, p2)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
priv.decrypt(-5)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
priv.decrypt("not a number") # type: ignore
|
||||
@@ -0,0 +1,47 @@
|
||||
import pytest
|
||||
from core.prime_number import PrimeNumber
|
||||
from core.public_key import PublicKey
|
||||
|
||||
|
||||
def test_encrypt_basic_cycle():
|
||||
"""Шифрование совпадает с pow(m, e, n)"""
|
||||
e = PrimeNumber.from_value(3)
|
||||
n = 11 # n может быть простым или составным числом
|
||||
pub = PublicKey(e, n)
|
||||
|
||||
for m in range(1, 10):
|
||||
expected = pow(m, e.value, n)
|
||||
assert pub.encrypt(m) == expected
|
||||
|
||||
|
||||
def test_encrypt_with_composite_n():
|
||||
"""n = p1 * p2 должно работать корректно"""
|
||||
p1 = PrimeNumber.from_value(5)
|
||||
p2 = PrimeNumber.from_value(11)
|
||||
n = p1.value * p2.value
|
||||
e = PrimeNumber.from_value(3)
|
||||
|
||||
pub = PublicKey(e, n)
|
||||
m = 7
|
||||
expected = pow(m, e.value, n)
|
||||
assert pub.encrypt(m) == expected
|
||||
|
||||
|
||||
def test_encrypt_rejects_negative():
|
||||
"""Отрицательные сообщения запрещены"""
|
||||
e = PrimeNumber.from_value(3)
|
||||
n = 11
|
||||
pub = PublicKey(e, n)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
pub.encrypt(-1)
|
||||
|
||||
|
||||
def test_encrypt_rejects_non_integer():
|
||||
"""Сообщение должно быть int"""
|
||||
e = PrimeNumber.from_value(3)
|
||||
n = 11
|
||||
pub = PublicKey(e, n)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
pub.encrypt(3.14)
|
||||
Reference in New Issue
Block a user