Path: blob/main/shared/tests/test_number_theory.py
483 views
unlisted
"""Tests for cryptolab.number_theory."""12import sys, os3sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))45from cryptolab.number_theory import (6gcd, extended_gcd, euler_phi, factor, divisors, is_prime,7power_mod, inverse_mod, primitive_root, crt, discrete_log,8)9import pytest101112# --- gcd ---1314def test_gcd_basic():15assert gcd(12, 8) == 416assert gcd(17, 13) == 117assert gcd(0, 5) == 518assert gcd(5, 0) == 519assert gcd(0, 0) == 02021def test_gcd_negative():22assert gcd(-12, 8) == 423assert gcd(12, -8) == 4242526# --- extended_gcd ---2728def test_extended_gcd():29g, s, t = extended_gcd(35, 15)30assert g == 531assert 35 * s + 15 * t == g3233def test_extended_gcd_coprime():34g, s, t = extended_gcd(7, 11)35assert g == 136assert 7 * s + 11 * t == 1373839# --- factor ---4041def test_factor():42assert factor(60) == {2: 2, 3: 1, 5: 1}43assert factor(1) == {}44assert factor(17) == {17: 1}45assert factor(2**10) == {2: 10}4647def test_factor_zero():48assert factor(0) == {}495051# --- divisors ---5253def test_divisors():54assert divisors(12) == [1, 2, 3, 4, 6, 12]55assert divisors(1) == [1]56assert divisors(17) == [1, 17]57assert divisors(0) == []585960# --- is_prime ---6162def test_is_prime():63assert is_prime(2) is True64assert is_prime(3) is True65assert is_prime(4) is False66assert is_prime(17) is True67assert is_prime(1) is False68assert is_prime(0) is False69assert is_prime(97) is True70assert is_prime(100) is False717273# --- euler_phi ---7475def test_euler_phi():76assert euler_phi(1) == 177assert euler_phi(7) == 678assert euler_phi(12) == 479assert euler_phi(30) == 880# phi(p) = p - 1 for prime p81assert euler_phi(97) == 96828384# --- power_mod ---8586def test_power_mod():87assert power_mod(2, 10, 1000) == 1024 % 100088assert power_mod(3, 0, 7) == 189assert power_mod(5, 1, 13) == 590assert power_mod(2, 10, 1) == 09192def test_power_mod_negative_exp():93# 3^(-1) mod 7 = 5 (since 3*5 = 15 = 1 mod 7)94assert power_mod(3, -1, 7) == 5959697# --- inverse_mod ---9899def test_inverse_mod():100assert inverse_mod(3, 7) == 5 # 3*5 = 15 = 1 mod 7101assert inverse_mod(2, 11) == 6 # 2*6 = 12 = 1 mod 11102103def test_inverse_mod_no_inverse():104with pytest.raises(ValueError):105inverse_mod(2, 4)106107108# --- primitive_root ---109110def test_primitive_root():111g = primitive_root(7)112assert g == 3 # 3 is the smallest primitive root mod 7113# Verify it has order 6114assert power_mod(g, 6, 7) == 1115for k in range(1, 6):116assert power_mod(g, k, 7) != 1117118def test_primitive_root_small():119assert primitive_root(2) == 1120assert primitive_root(5) == 2121122123# --- crt ---124125def test_crt():126# x = 2 mod 3, x = 3 mod 5 -> x = 8 mod 15127assert crt([2, 3], [3, 5]) == 8128129def test_crt_three_moduli():130# x = 1 mod 2, x = 2 mod 3, x = 3 mod 5 -> x = 23 mod 30131assert crt([1, 2, 3], [2, 3, 5]) == 23132133134# --- discrete_log ---135136def test_discrete_log():137# 3^x = 6 mod 7138# 3^1=3, 3^2=2, 3^3=6 -> x=3139assert discrete_log(6, 3, 7) == 3140141def test_discrete_log_identity():142# g^0 = 1143assert discrete_log(1, 3, 7) == 0144145146