transcrypto 1.8.0__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,8 @@ from collections import abc
12
12
 
13
13
  import gmpy2
14
14
 
15
- from . import base, constants
15
+ from transcrypto.core import constants
16
+ from transcrypto.utils import base, saferandom
16
17
 
17
18
  _MAX_PRIMALITY_SAFETY = 100 # this is an absurd number, just to have a max
18
19
 
@@ -21,6 +22,79 @@ class ModularDivideError(base.Error):
21
22
  """Divide-by-zero-like exception (TransCrypto)."""
22
23
 
23
24
 
25
+ def GCD(a: int, b: int, /) -> int:
26
+ """Greatest Common Divisor for `a` and `b`, integers ≥0. Uses the Euclid method.
27
+
28
+ O(log(min(a, b)))
29
+
30
+ Args:
31
+ a (int): integer a ≥ 0
32
+ b (int): integer b ≥ 0 (can't be both zero)
33
+
34
+ Returns:
35
+ gcd(a, b)
36
+
37
+ Raises:
38
+ base.InputError: invalid inputs
39
+
40
+ """
41
+ # test inputs
42
+ if a < 0 or b < 0 or (not a and not b):
43
+ raise base.InputError(f'negative input or undefined gcd(0, 0): {a=} , {b=}')
44
+ # algo needs to start with a >= b
45
+ if a < b:
46
+ a, b = b, a
47
+ # euclid
48
+ while b:
49
+ r: int = a % b
50
+ a, b = b, r
51
+ return a
52
+
53
+
54
+ def ExtendedGCD(a: int, b: int, /) -> tuple[int, int, int]:
55
+ """Greatest Common Divisor Extended for `a` and `b`, integers ≥0. Uses the Euclid method.
56
+
57
+ O(log(min(a, b)))
58
+
59
+ Args:
60
+ a (int): integer a ≥ 0
61
+ b (int): integer b ≥ 0 (can't be both zero)
62
+
63
+ Returns:
64
+ (gcd, x, y) so that a * x + b * y = gcd
65
+ x and y may be negative integers or zero but won't be both zero.
66
+
67
+ Raises:
68
+ base.InputError: invalid inputs
69
+
70
+ """
71
+ # test inputs
72
+ if a < 0 or b < 0 or (not a and not b):
73
+ raise base.InputError(f'negative input or undefined gcd(0, 0): {a=} , {b=}')
74
+ # algo needs to start with a >= b (but we remember if we did swap)
75
+ swapped = False
76
+ if a < b:
77
+ a, b = b, a
78
+ swapped = True
79
+ # trivial case
80
+ if not b:
81
+ return (a, 0 if swapped else 1, 1 if swapped else 0)
82
+ # euclid
83
+ x1: int = 0
84
+ x2: int = 1
85
+ y1: int = 1
86
+ y2: int = 0
87
+ q: int
88
+ r: int
89
+ x: int
90
+ y: int
91
+ while b:
92
+ q, r = divmod(a, b)
93
+ x, y = x2 - q * x1, y2 - q * y1
94
+ a, b, x1, x2, y1, y2 = b, r, x, x1, y, y1
95
+ return (a, y2 if swapped else x2, x2 if swapped else y2)
96
+
97
+
24
98
  def ModInv(x: int, m: int, /) -> int:
25
99
  """Modular inverse of `x` mod `m`: a `y` such that (x * y) % m == 1 if GCD(x, m) == 1.
26
100
 
@@ -33,7 +107,7 @@ def ModInv(x: int, m: int, /) -> int:
33
107
  this only exists if GCD(x, m) == 1, so to guarantee an inverse `m` must be prime
34
108
 
35
109
  Raises:
36
- InputError: invalid modulus or x
110
+ base.InputError: invalid modulus or x
37
111
  ModularDivideError: divide-by-zero, i.e., GCD(x, m) != 1 or x == 0
38
112
 
39
113
  """
@@ -47,7 +121,7 @@ def ModInv(x: int, m: int, /) -> int:
47
121
  if reduced_x == 1: # trivial degenerate case
48
122
  return 1
49
123
  # compute actual extended GCD and see if we will have an inverse
50
- gcd, y, w = base.ExtendedGCD(reduced_x, m)
124
+ gcd, y, w = ExtendedGCD(reduced_x, m)
51
125
  if gcd != 1:
52
126
  raise ModularDivideError(f'invalid inverse {x=} mod {m=} with {gcd=}')
53
127
  assert y and w and y >= -m, f'should never happen: {x=} mod {m=} -> {w=} ; {y=}' # noqa: PT018, S101
@@ -67,7 +141,7 @@ def ModDiv(x: int, y: int, m: int, /) -> int:
67
141
  this only exists if GCD(y, m) == 1, so to guarantee an inverse `m` must be prime
68
142
 
69
143
  Raises:
70
- InputError: invalid modulus or x or y
144
+ base.InputError: invalid modulus or x or y
71
145
  ModularDivideError: divide-by-zero, i.e., GCD(y, m) != 1 or y == 0
72
146
 
73
147
  """
@@ -105,7 +179,7 @@ def CRTPair(a1: int, m1: int, a2: int, m2: int) -> int:
105
179
  the least non-negative solution `x` such that a1 = x % m1 and a2 = x % m2 and 0 ≤ x < m1 * m2
106
180
 
107
181
  Raises:
108
- InputError: invalid inputs
182
+ base.InputError: invalid inputs
109
183
  ModularDivideError: moduli are not co-prime, i.e. gcd(m1, m2) != 1
110
184
 
111
185
  """
@@ -137,7 +211,7 @@ def ModExp(x: int, y: int, m: int, /) -> int:
137
211
  (x ** y) mod m
138
212
 
139
213
  Raises:
140
- InputError: invalid inputs
214
+ base.InputError: invalid inputs
141
215
 
142
216
  """
143
217
  # test inputs
@@ -184,7 +258,7 @@ def ModPolynomial(x: int, polynomial: abc.Reversible[int], m: int, /) -> int:
184
258
  f(x) mod m
185
259
 
186
260
  Raises:
187
- InputError: invalid inputs
261
+ base.InputError: invalid inputs
188
262
 
189
263
  """
190
264
  # test inputs
@@ -228,7 +302,7 @@ def ModLagrangeInterpolate(x: int, points: dict[int, int], m: int, /) -> int:
228
302
  y-value solution for f(x) mod m given `points` mapping
229
303
 
230
304
  Raises:
231
- InputError: invalid inputs
305
+ base.InputError: invalid inputs
232
306
 
233
307
  """
234
308
  # test inputs
@@ -275,7 +349,7 @@ def FermatIsPrime(n: int, /, *, safety: int = 10, witnesses: set[int] | None = N
275
349
  False if certainly not prime ; True if (probabilistically) prime
276
350
 
277
351
  Raises:
278
- InputError: invalid inputs
352
+ base.InputError: invalid inputs
279
353
 
280
354
  """
281
355
  # test inputs and test for trivial cases: 1, 2, 3, divisible by 2
@@ -294,7 +368,7 @@ def FermatIsPrime(n: int, /, *, safety: int = 10, witnesses: set[int] | None = N
294
368
  safety = min(safety, max_safety)
295
369
  witnesses = set()
296
370
  while len(witnesses) < safety:
297
- witnesses.add(base.RandInt(2, n - 2))
371
+ witnesses.add(saferandom.RandInt(2, n - 2))
298
372
  # we have our witnesses: do the actual Fermat algo
299
373
  for w in sorted(witnesses):
300
374
  if not 2 <= w <= (n - 2): # noqa: PLR2004
@@ -323,7 +397,7 @@ def _MillerRabinWitnesses(n: int, /) -> set[int]: # noqa: PLR0911
323
397
  {witness1, witness2, ...} for either "certainty" of primality or error chance < 10**25
324
398
 
325
399
  Raises:
326
- InputError: invalid inputs
400
+ base.InputError: invalid inputs
327
401
 
328
402
  """
329
403
  # test inputs
@@ -364,7 +438,7 @@ def _MillerRabinSR(n: int, /) -> tuple[int, int]:
364
438
  (s, r) so that (2 ** s) * r == (n - 1)
365
439
 
366
440
  Raises:
367
- InputError: invalid inputs
441
+ base.InputError: invalid inputs
368
442
 
369
443
  """
370
444
  # test inputs
@@ -395,7 +469,7 @@ def MillerRabinIsPrime(n: int, /, *, witnesses: set[int] | None = None) -> bool:
395
469
  False if certainly not prime ; True if (probabilistically) prime
396
470
 
397
471
  Raises:
398
- InputError: invalid inputs
472
+ base.InputError: invalid inputs
399
473
 
400
474
  """
401
475
  # test inputs and test for trivial cases: 1, 2, 3, divisible by 2
@@ -456,7 +530,7 @@ def PrimeGenerator(start: int, /) -> abc.Generator[int]:
456
530
  prime numbers (int)
457
531
 
458
532
  Raises:
459
- InputError: invalid inputs
533
+ base.InputError: invalid inputs
460
534
 
461
535
  """
462
536
  # test inputs and make sure we start at an odd number
@@ -508,8 +582,8 @@ def NBitRandomPrimes(n_bits: int, /, *, serial: bool = True, n_primes: int = 1)
508
582
  set[int]: `n_primes` random primes with `n_bits` bits
509
583
 
510
584
  Raises:
511
- InputError: invalid inputs
512
- Error: prime search failed
585
+ base.InputError: invalid inputs
586
+ base.Error: prime search failed
513
587
 
514
588
  """
515
589
  # test inputs
@@ -563,7 +637,7 @@ def _PrimeSearchShard(n_bits: int) -> int | None:
563
637
 
564
638
  """
565
639
  shard_len: int = max(2000, 6 * int(0.693 * n_bits)) # ~6x expected prime gap ~2^k (≈ 0.693*k)
566
- pr: int = base.RandBits(n_bits) | 1 # random position; make ODD
640
+ pr: int = saferandom.RandBits(n_bits) | 1 # random position; make ODD
567
641
  count: int = 0
568
642
  while count < shard_len and pr.bit_length() == n_bits:
569
643
  if IsPrime(pr):
@@ -13,7 +13,8 @@ from typing import Self
13
13
 
14
14
  import gmpy2
15
15
 
16
- from . import aes, base, modmath
16
+ from transcrypto.core import aes, hashes, key, modmath
17
+ from transcrypto.utils import base, saferandom
17
18
 
18
19
  _SMALL_ENCRYPTION_EXPONENT = 7
19
20
  _BIG_ENCRYPTION_EXPONENT = 2**16 + 1 # 65537
@@ -26,7 +27,7 @@ _RSA_SIGNATURE_HASH_PREFIX = b'transcrypto.RSA.Signature.1.0\x00'
26
27
 
27
28
 
28
29
  @dataclasses.dataclass(kw_only=True, slots=True, frozen=True, repr=False)
29
- class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
30
+ class RSAPublicKey(key.CryptoKey, key.Encryptor, key.Verifier):
30
31
  """RSA (Rivest-Shamir-Adleman) key, with the public part of the key.
31
32
 
32
33
  No measures are taken here to prevent timing attacks.
@@ -48,7 +49,7 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
48
49
  """Check data.
49
50
 
50
51
  Raises:
51
- InputError: invalid inputs
52
+ base.InputError: invalid inputs
52
53
 
53
54
  """
54
55
  if self.public_modulus < 6 or modmath.IsPrime(self.public_modulus): # noqa: PLR2004
@@ -92,7 +93,7 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
92
93
  ciphertext message (int, 1 ≤ c < modulus) = (m ** encrypt_exp) mod modulus
93
94
 
94
95
  Raises:
95
- InputError: invalid inputs
96
+ base.InputError: invalid inputs
96
97
 
97
98
  """
98
99
  # test inputs
@@ -128,13 +129,13 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
128
129
  """
129
130
  # generate random r and encrypt it
130
131
  r: int = 0
131
- while not 1 < r < self.public_modulus or base.GCD(r, self.public_modulus) != 1:
132
- r = base.RandBits(self.public_modulus.bit_length())
132
+ while not 1 < r < self.public_modulus or modmath.GCD(r, self.public_modulus) != 1:
133
+ r = saferandom.RandBits(self.public_modulus.bit_length())
133
134
  k: int = self.modulus_size
134
135
  ct: bytes = base.IntToFixedBytes(self.RawEncrypt(r), k)
135
136
  assert len(ct) == k, 'should never happen: c_kem should be exactly k bytes' # noqa: S101
136
137
  # encrypt plaintext with AES-256-GCM using SHA512(r)[32:] as key; return ct || Encrypt(...)
137
- ss: bytes = base.Hash512(base.IntToFixedBytes(r, k))
138
+ ss: bytes = hashes.Hash512(base.IntToFixedBytes(r, k))
138
139
  aad: bytes = b'' if associated_data is None else associated_data
139
140
  aad_prime: bytes = _RSA_ENCRYPTION_AAD_PREFIX + base.IntToFixedBytes(len(aad), 8) + aad + ct
140
141
  return ct + aes.AESKey(key256=ss[32:]).Encrypt(plaintext, associated_data=aad_prime)
@@ -172,16 +173,16 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
172
173
  Hash512("prefix" || len(aad) || aad || message || salt)
173
174
 
174
175
  Raises:
175
- CryptoError: hash output is out of range
176
+ key.CryptoError: hash output is out of range
176
177
 
177
178
  """
178
179
  aad: bytes = b'' if associated_data is None else associated_data
179
180
  la: bytes = base.IntToFixedBytes(len(aad), 8)
180
181
  assert len(salt) == 64, 'should never happen: salt should be exactly 64 bytes' # noqa: PLR2004, S101
181
- y: int = base.BytesToInt(base.Hash512(_RSA_SIGNATURE_HASH_PREFIX + la + aad + message + salt))
182
- if not 1 < y < self.public_modulus or base.GCD(y, self.public_modulus) != 1:
182
+ y: int = base.BytesToInt(hashes.Hash512(_RSA_SIGNATURE_HASH_PREFIX + la + aad + message + salt))
183
+ if not 1 < y < self.public_modulus or modmath.GCD(y, self.public_modulus) != 1:
183
184
  # will only reasonably happen if modulus is small
184
- raise base.CryptoError(f'hash output {y} is out of range/invalid {self.public_modulus}')
185
+ raise key.CryptoError(f'hash output {y} is out of range/invalid {self.public_modulus}')
185
186
  return y
186
187
 
187
188
  def Verify(
@@ -204,7 +205,7 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
204
205
  True if signature is valid, False otherwise
205
206
 
206
207
  Raises:
207
- InputError: invalid inputs
208
+ base.InputError: invalid inputs
208
209
 
209
210
  """
210
211
  k: int = self.modulus_size
@@ -257,8 +258,8 @@ class RSAObfuscationPair(RSAPublicKey):
257
258
  """Check data.
258
259
 
259
260
  Raises:
260
- InputError: invalid inputs
261
- CryptoError: modulus math is inconsistent with values
261
+ base.InputError: invalid inputs
262
+ key.CryptoError: modulus math is inconsistent with values
262
263
 
263
264
  """
264
265
  super(RSAObfuscationPair, self).__post_init__()
@@ -269,7 +270,7 @@ class RSAObfuscationPair(RSAPublicKey):
269
270
  ):
270
271
  raise base.InputError(f'invalid keys: {self}')
271
272
  if (self.random_key * self.key_inverse) % self.public_modulus != 1:
272
- raise base.CryptoError(f'inconsistent keys: {self}')
273
+ raise key.CryptoError(f'inconsistent keys: {self}')
273
274
 
274
275
  def __str__(self) -> str:
275
276
  """Safe (no secrets) string representation of the RSAObfuscationPair.
@@ -281,8 +282,8 @@ class RSAObfuscationPair(RSAPublicKey):
281
282
  return (
282
283
  'RSAObfuscationPair('
283
284
  f'{super(RSAObfuscationPair, self).__str__()}, '
284
- f'random_key={base.ObfuscateSecret(self.random_key)}, '
285
- f'key_inverse={base.ObfuscateSecret(self.key_inverse)})'
285
+ f'random_key={hashes.ObfuscateSecret(self.random_key)}, '
286
+ f'key_inverse={hashes.ObfuscateSecret(self.key_inverse)})'
286
287
  )
287
288
 
288
289
  def ObfuscateMessage(self, message: int, /) -> int:
@@ -297,7 +298,7 @@ class RSAObfuscationPair(RSAPublicKey):
297
298
  obfuscated message (int, 1 ≤ o < modulus) = (m * (random_key ** encrypt_exp)) mod modulus
298
299
 
299
300
  Raises:
300
- InputError: invalid inputs
301
+ base.InputError: invalid inputs
301
302
 
302
303
  """
303
304
  # test inputs
@@ -322,31 +323,31 @@ class RSAObfuscationPair(RSAPublicKey):
322
323
  signature * key_inverse mod modulus
323
324
 
324
325
  Raises:
325
- CryptoError: some signatures were invalid (either plain or obfuscated)
326
+ key.CryptoError: some signatures were invalid (either plain or obfuscated)
326
327
 
327
328
  """
328
329
  # verify that obfuscated signature is valid
329
330
  obfuscated: int = self.ObfuscateMessage(message)
330
331
  if not self.RawVerify(obfuscated, signature):
331
- raise base.CryptoError(f'obfuscated message was not signed: {message=} ; {signature=}')
332
+ raise key.CryptoError(f'obfuscated message was not signed: {message=} ; {signature=}')
332
333
  # compute signature for original message and check it
333
334
  original: int = (signature * self.key_inverse) % self.public_modulus
334
335
  if not self.RawVerify(message, original):
335
- raise base.CryptoError(f'failed signature recovery: {message=} ; {signature=}')
336
+ raise key.CryptoError(f'failed signature recovery: {message=} ; {signature=}')
336
337
  return original
337
338
 
338
339
  @classmethod
339
- def New(cls, key: RSAPublicKey, /) -> Self:
340
- """Generate new obfuscation pair for this `key`, respecting the size of the public modulus.
340
+ def New(cls, rsa_key: RSAPublicKey, /) -> Self:
341
+ """Generate new obfuscation pair for this `rsa_key`, respecting the size of the public modulus.
341
342
 
342
343
  Args:
343
- key (RSAPublicKey): public RSA key to use as base for a new RSAObfuscationPair
344
+ rsa_key (RSAPublicKey): public RSA key to use as base for a new RSAObfuscationPair
344
345
 
345
346
  Returns:
346
347
  RSAObfuscationPair object ready for use
347
348
 
348
349
  Raises:
349
- CryptoError: failed generation
350
+ key.CryptoError: failed generation
350
351
 
351
352
  """
352
353
  # find a suitable random key based on the bit_length
@@ -356,29 +357,29 @@ class RSAObfuscationPair(RSAPublicKey):
356
357
  while (
357
358
  not random_key
358
359
  or not key_inverse
359
- or random_key in {key.encrypt_exp, key_inverse}
360
- or key_inverse == key.encrypt_exp
360
+ or random_key in {rsa_key.encrypt_exp, key_inverse}
361
+ or key_inverse == rsa_key.encrypt_exp
361
362
  ):
362
- random_key = base.RandBits(key.public_modulus.bit_length() - 1)
363
+ random_key = saferandom.RandBits(rsa_key.public_modulus.bit_length() - 1)
363
364
  try:
364
- key_inverse = modmath.ModInv(random_key, key.public_modulus)
365
+ key_inverse = modmath.ModInv(random_key, rsa_key.public_modulus)
365
366
  except modmath.ModularDivideError as err:
366
367
  key_inverse = 0
367
368
  failures += 1
368
369
  if failures >= _MAX_KEY_GENERATION_FAILURES:
369
- raise base.CryptoError(f'failed key generation {failures} times') from err
370
+ raise key.CryptoError(f'failed key generation {failures} times') from err
370
371
  logging.warning(err)
371
372
  # build object
372
373
  return cls(
373
- public_modulus=key.public_modulus,
374
- encrypt_exp=key.encrypt_exp,
374
+ public_modulus=rsa_key.public_modulus,
375
+ encrypt_exp=rsa_key.encrypt_exp,
375
376
  random_key=random_key,
376
377
  key_inverse=key_inverse,
377
378
  )
378
379
 
379
380
 
380
381
  @dataclasses.dataclass(kw_only=True, slots=True, frozen=True, repr=False)
381
- class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
382
+ class RSAPrivateKey(RSAPublicKey, key.Decryptor, key.Signer):
382
383
  """RSA (Rivest-Shamir-Adleman) private key.
383
384
 
384
385
  No measures are taken here to prevent timing attacks.
@@ -409,8 +410,8 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
409
410
  """Check data.
410
411
 
411
412
  Raises:
412
- InputError: invalid inputs
413
- CryptoError: modulus math is inconsistent with values
413
+ base.InputError: invalid inputs
414
+ key.CryptoError: modulus math is inconsistent with values
414
415
 
415
416
  """
416
417
  super(RSAPrivateKey, self).__post_init__()
@@ -438,15 +439,15 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
438
439
  if self.remainder_p < 2 or self.remainder_q < 2 or self.q_inverse_p < 2: # noqa: PLR2004
439
440
  raise base.InputError(f'trivial remainder_p/remainder_q/q_inverse_p: {self}')
440
441
  if self.modulus_p * self.modulus_q != self.public_modulus:
441
- raise base.CryptoError(f'inconsistent modulus_p * modulus_q: {self}')
442
+ raise key.CryptoError(f'inconsistent modulus_p * modulus_q: {self}')
442
443
  if (self.encrypt_exp * self.decrypt_exp) % phi != 1:
443
- raise base.CryptoError(f'inconsistent exponents: {self}')
444
+ raise key.CryptoError(f'inconsistent exponents: {self}')
444
445
  if (
445
446
  self.remainder_p != self.decrypt_exp % (self.modulus_p - 1)
446
447
  or self.remainder_q != self.decrypt_exp % (self.modulus_q - 1)
447
448
  or (self.q_inverse_p * self.modulus_q) % self.modulus_p != 1
448
449
  ):
449
- raise base.CryptoError(f'inconsistent speedup remainder_p/remainder_q/q_inverse_p: {self}')
450
+ raise key.CryptoError(f'inconsistent speedup remainder_p/remainder_q/q_inverse_p: {self}')
450
451
 
451
452
  def __str__(self) -> str:
452
453
  """Safe (no secrets) string representation of the RSAPrivateKey.
@@ -458,9 +459,9 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
458
459
  return (
459
460
  'RSAPrivateKey('
460
461
  f'{super(RSAPrivateKey, self).__str__()}, '
461
- f'modulus_p={base.ObfuscateSecret(self.modulus_p)}, '
462
- f'modulus_q={base.ObfuscateSecret(self.modulus_q)}, '
463
- f'decrypt_exp={base.ObfuscateSecret(self.decrypt_exp)})'
462
+ f'modulus_p={hashes.ObfuscateSecret(self.modulus_p)}, '
463
+ f'modulus_q={hashes.ObfuscateSecret(self.modulus_q)}, '
464
+ f'decrypt_exp={hashes.ObfuscateSecret(self.decrypt_exp)})'
464
465
  )
465
466
 
466
467
  def RawDecrypt(self, ciphertext: int, /) -> int:
@@ -477,7 +478,7 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
477
478
  decrypted message (int, 1 ≤ m < modulus) = (m ** decrypt_exp) mod modulus
478
479
 
479
480
  Raises:
480
- InputError: invalid inputs
481
+ base.InputError: invalid inputs
481
482
 
482
483
  """
483
484
  # test inputs
@@ -509,7 +510,7 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
509
510
  bytes: Decrypted plaintext bytes
510
511
 
511
512
  Raises:
512
- InputError: invalid inputs
513
+ base.InputError: invalid inputs
513
514
 
514
515
  """
515
516
  k: int = self.modulus_size
@@ -518,7 +519,7 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
518
519
  # split ciphertext in two parts: the first k bytes is ct, the rest is AES-256-GCM
519
520
  rsa_ct, aes_ct = ciphertext[:k], ciphertext[k:]
520
521
  r: int = self.RawDecrypt(base.BytesToInt(rsa_ct))
521
- ss: bytes = base.Hash512(base.IntToFixedBytes(r, k))
522
+ ss: bytes = hashes.Hash512(base.IntToFixedBytes(r, k))
522
523
  aad: bytes = b'' if associated_data is None else associated_data
523
524
  aad_prime: bytes = _RSA_ENCRYPTION_AAD_PREFIX + base.IntToFixedBytes(len(aad), 8) + aad + rsa_ct
524
525
  return aes.AESKey(key256=ss[32:]).Decrypt(aes_ct, associated_data=aad_prime)
@@ -538,7 +539,7 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
538
539
  identical to Decrypt()
539
540
 
540
541
  Raises:
541
- InputError: invalid inputs
542
+ base.InputError: invalid inputs
542
543
 
543
544
  """
544
545
  # test inputs
@@ -569,13 +570,13 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
569
570
  bytes: Signature; salt || Padded(s, k) - see above
570
571
 
571
572
  Raises:
572
- InputError: invalid inputs
573
+ base.InputError: invalid inputs
573
574
 
574
575
  """
575
576
  k: int = self.modulus_size
576
577
  if k <= 64: # noqa: PLR2004
577
578
  raise base.InputError(f'modulus too small for signing operations: {k} bytes')
578
- salt: bytes = base.RandBytes(64)
579
+ salt: bytes = saferandom.RandBytes(64)
579
580
  s_int: int = self.RawSign(self._DomainSeparatedHash(message, associated_data, salt))
580
581
  s_bytes: bytes = base.IntToFixedBytes(s_int, k)
581
582
  assert len(s_bytes) == k, 'should never happen: s_bytes should be exactly k bytes' # noqa: S101
@@ -592,8 +593,8 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
592
593
  RSAPrivateKey object ready for use
593
594
 
594
595
  Raises:
595
- InputError: invalid inputs
596
- CryptoError: failed generation
596
+ base.InputError: invalid inputs
597
+ key.CryptoError: failed generation
597
598
 
598
599
  """
599
600
  # test inputs
@@ -632,5 +633,5 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
632
633
  except (base.InputError, modmath.ModularDivideError) as err:
633
634
  failures += 1
634
635
  if failures >= _MAX_KEY_GENERATION_FAILURES:
635
- raise base.CryptoError(f'failed key generation {failures} times') from err
636
+ raise key.CryptoError(f'failed key generation {failures} times') from err
636
637
  logging.warning(err)