Initial commit
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Dict, Any
|
||||
from core.prime_number import PrimeNumber
|
||||
from core.private_key import PrivateKey
|
||||
|
||||
|
||||
class KeygenMode:
|
||||
MAX_BITS: int = 2**5
|
||||
MIN_VALUE: int = 2
|
||||
MAX_VALUE: int = (1 << MAX_BITS) - 1
|
||||
MAX_ATTEMPTS: int = 1000
|
||||
|
||||
def run(
|
||||
self,
|
||||
*,
|
||||
p: int | None,
|
||||
q: int | None,
|
||||
min: int | None = None,
|
||||
max: int | None = None,
|
||||
bits: int | None = None,
|
||||
seed: int | None = None,
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
if min is None:
|
||||
min = self.MIN_VALUE
|
||||
if max is None:
|
||||
max = self.MAX_VALUE
|
||||
|
||||
self._validate_inputs(p, q, min, max, bits)
|
||||
|
||||
P = self._generate_prime(p, min, max, bits, seed)
|
||||
Q = self._generate_distinct_prime(P, q, min, max, bits, seed)
|
||||
|
||||
priv = PrivateKey(P, Q)
|
||||
pub = priv.make_public_key()
|
||||
|
||||
return {
|
||||
"p": {
|
||||
"dec": P.value,
|
||||
"hex": hex(P.value),
|
||||
},
|
||||
"q": {
|
||||
"dec": Q.value,
|
||||
"hex": hex(Q.value),
|
||||
},
|
||||
"n": {
|
||||
"dec": priv.n,
|
||||
"hex": hex(priv.n),
|
||||
},
|
||||
"phi": {
|
||||
"dec": priv.phi,
|
||||
"hex": hex(priv.phi),
|
||||
},
|
||||
"e": {
|
||||
"dec": pub.e.value,
|
||||
"hex": hex(pub.e.value),
|
||||
},
|
||||
"d": {
|
||||
"dec": priv.d,
|
||||
"hex": hex(priv.d),
|
||||
},
|
||||
}
|
||||
|
||||
# ----------------- helpers -----------------
|
||||
|
||||
def _validate_inputs(
|
||||
self,
|
||||
p: int | None,
|
||||
q: int | None,
|
||||
min: int,
|
||||
max: int,
|
||||
bits: int | None,
|
||||
) -> None:
|
||||
|
||||
if p is not None and q is not None and p == q:
|
||||
raise ValueError("p и q должны быть разными простыми числами.")
|
||||
|
||||
if bits is not None and bits > self.MAX_BITS:
|
||||
raise ValueError(f"Максимальная длина простого: {
|
||||
self.MAX_BITS} бит.")
|
||||
if min > max:
|
||||
raise ValueError("min не может быть больше max.")
|
||||
if max > self.MAX_VALUE:
|
||||
raise ValueError(
|
||||
f"max не может превышать {self.MAX_VALUE} (ограничение {
|
||||
self.MAX_BITS} бит)."
|
||||
)
|
||||
if min == max:
|
||||
raise ValueError("min и max не должны совпадать.")
|
||||
|
||||
def _generate_prime(
|
||||
self,
|
||||
value: int | None,
|
||||
min: int,
|
||||
max: int,
|
||||
bits: int | None,
|
||||
seed: int | None,
|
||||
) -> PrimeNumber:
|
||||
if value is not None:
|
||||
return PrimeNumber.from_value(value)
|
||||
if bits is not None:
|
||||
return PrimeNumber.random_bits(bits=bits, seed=seed)
|
||||
else:
|
||||
return PrimeNumber.random(min_value=min, max_value=max, seed=seed)
|
||||
return PrimeNumber.random_bits(bits=self.MAX_BITS, seed=seed)
|
||||
|
||||
def _generate_distinct_prime(
|
||||
self,
|
||||
other: PrimeNumber,
|
||||
value: int | None,
|
||||
min: int,
|
||||
max: int,
|
||||
bits: int | None,
|
||||
seed: int | None,
|
||||
) -> PrimeNumber:
|
||||
attempts = 0
|
||||
|
||||
while True:
|
||||
|
||||
effective_seed = None if seed is None else seed + attempts
|
||||
|
||||
candidate = self._generate_prime(
|
||||
value, min, max, bits, effective_seed)
|
||||
if candidate.value != other.value:
|
||||
return candidate
|
||||
|
||||
attempts += 1
|
||||
if attempts >= self.MAX_ATTEMPTS:
|
||||
raise RuntimeError(
|
||||
f"Не удалось сгенерировать q, отличное от p, за {
|
||||
self.MAX_ATTEMPTS} попыток."
|
||||
)
|
||||
Reference in New Issue
Block a user