Skip to content

Commit

Permalink
previous/next safe prime
Browse files Browse the repository at this point in the history
  • Loading branch information
teschlg committed Nov 6, 2024
1 parent 8119780 commit cb3844c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
2 changes: 1 addition & 1 deletion kryptools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
__email__ = "Gerald.Teschl@univie.ac.at"

from .nt import egcd, cf, convergents, legendre_symbol, jacobi_symbol, sqrt_mod, euler_phi, carmichael_lambda, moebius_mu, is_carmichael_number, order, crt
from .primes import sieve_eratosthenes, prime_pi, is_prime, next_prime, previous_prime, random_prime, random_strongprime, is_safeprime, random_safeprime, is_blumprime, random_blumprime, miller_rabin_test, lucas_test
from .primes import sieve_eratosthenes, prime_pi, is_prime, next_prime, previous_prime, next_safeprime, previous_safeprime, random_prime, random_strongprime, is_safeprime, random_safeprime, is_blumprime, random_blumprime, miller_rabin_test, lucas_test
from .intfuncs import iroot, ilog, perfect_square, perfect_power, prime_power
from .factor import factorint, divisors
from .dlp import dlog
Expand Down
30 changes: 29 additions & 1 deletion kryptools/primes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
is_prime(n) test if n is probably prime
next_prime(n) find the next prime larger or equal n
previous_prime(n) find the previous prime smaller or equal n
next_safeprime(n) find the next safe prime larger or equal n
previous_safeprime(n) find the previous safe prime smaller or equal n
random_bitlength(l) return a random number with bit lenght l
random_prime(l) return a random prime with bit length l
random_strongprime(l) return a random strong prime with factors of bit length l
Expand Down Expand Up @@ -188,7 +190,9 @@ def is_prime(n: int, trialdivision: bool = True) -> bool:

def is_safeprime(p: int) -> bool:
"""Tests if a number is a safe prime."""
return is_prime(p) and is_prime((p - 1) // 2)
if p < 107:
return p in (5, 7, 11, 23, 47, 59, 83)
return p % 12 == 11 and is_prime(p) and is_prime((p - 1) // 2)

def is_blumprime(p: int) -> bool:
"""Tests if a number is a Blum prime."""
Expand Down Expand Up @@ -218,6 +222,30 @@ def previous_prime(n: int) -> int:
n -= 2
return n

def next_safeprime(n: int) -> int:
"""Find the next safe prime larger or equal `n`."""
if n < 6:
return 5
if n < 8:
return 7
n = n - (n % 12) + 11 # make sure p % 12 = 11
while not is_safeprime(n):
n += 12
return n

def previous_safeprime(n: int) -> int:
"""Find the previous safe prime smaller or equal `n`."""
if n < 7:
return 5
if n < 11:
return 7
tmp = (n % 12) + 1
if tmp != 12:
n = n - tmp # make sure p % 12 = 11
while not is_safeprime(n):
n -= 12
return n

def random_bitlength(l: int) -> int:
"Return a random number with bit lenght `l`."
l = max(2, l)
Expand Down
14 changes: 11 additions & 3 deletions tests/test_primes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from math import isqrt
from random import randint, seed
from kryptools import sieve_eratosthenes, prime_pi, next_prime, previous_prime, is_prime, is_safeprime, is_blumprime
from kryptools import sieve_eratosthenes, prime_pi, next_prime, previous_prime, next_safeprime, previous_safeprime, is_prime, is_safeprime, is_blumprime
from kryptools import miller_rabin_test, lucas_test, random_prime, random_safeprime, random_blumprime, random_strongprime
seed(0)

Expand Down Expand Up @@ -46,6 +46,8 @@ def sieve(max: int) -> list:
def test_sieve_eratosthenes():
for i, p in enumerate(sieve_eratosthenes(OEIS_A000010[-1])):
assert p == OEIS_A000010[i]
assert previous_prime(p) == p
assert next_prime(p) == p
if i > 0:
assert previous_prime(p-1) == OEIS_A000010[i-1]
if i < len(OEIS_A000010) - 1:
Expand Down Expand Up @@ -74,8 +76,14 @@ def test_is_prime():
def test_is_safeprime():
for n in range(OEIS_A005385[-1]+1):
assert is_safeprime(n) == (n in OEIS_A005385)
for n in OEIS_A005385:
assert is_safeprime(n) == True
for i, p in enumerate(OEIS_A005385):
assert is_safeprime(p) == True
assert previous_safeprime(p) == p
assert next_safeprime(p) == p
if i > 0:
assert previous_safeprime(p-1) == OEIS_A005385[i-1]
if i < len(OEIS_A005385) - 1:
assert next_safeprime(p+1) == OEIS_A005385[i+1]

#https://oeis.org/A014233
OEIS_A014233 = [ 2047, 1373653, 25326001, 3215031751, 2152302898747, 3474749660383,
Expand Down

0 comments on commit cb3844c

Please sign in to comment.