transcrypto 1.6.0__py3-none-any.whl → 1.8.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.
transcrypto/rsa.py CHANGED
@@ -1,7 +1,5 @@
1
- #!/usr/bin/env python3
2
- #
3
- # Copyright 2025 Daniel Balparda (balparda@github.com) - Apache-2.0 license
4
- #
1
+ # SPDX-FileCopyrightText: Copyright 2026 Daniel Balparda <balparda@github.com>
2
+ # SPDX-License-Identifier: Apache-2.0
5
3
  """Balparda's TransCrypto RSA (Rivest-Shamir-Adleman) library.
6
4
 
7
5
  <https://en.wikipedia.org/wiki/RSA_cryptosystem>
@@ -11,20 +9,14 @@ from __future__ import annotations
11
9
 
12
10
  import dataclasses
13
11
  import logging
14
- # import pdb
15
12
  from typing import Self
16
13
 
17
- import gmpy2 # type:ignore
18
-
19
- from . import base, modmath, aes
20
-
21
- __author__ = 'balparda@github.com'
22
- __version__: str = base.__version__ # version comes from base!
23
- __version_tuple__: tuple[int, ...] = base.__version_tuple__
14
+ import gmpy2
24
15
 
16
+ from . import aes, base, modmath
25
17
 
26
18
  _SMALL_ENCRYPTION_EXPONENT = 7
27
- _BIG_ENCRYPTION_EXPONENT = 2 ** 16 + 1 # 65537
19
+ _BIG_ENCRYPTION_EXPONENT = 2**16 + 1 # 65537
28
20
 
29
21
  _MAX_KEY_GENERATION_FAILURES = 15
30
22
 
@@ -46,6 +38,7 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
46
38
  Attributes:
47
39
  public_modulus (int): modulus (p * q), ≥ 6
48
40
  encrypt_exp (int): encryption exponent, 3 ≤ e < modulus, (e * decrypt) % ((p-1) * (q-1)) == 1
41
+
49
42
  """
50
43
 
51
44
  public_modulus: int
@@ -56,13 +49,13 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
56
49
 
57
50
  Raises:
58
51
  InputError: invalid inputs
52
+
59
53
  """
60
- super(RSAPublicKey, self).__post_init__() # pylint: disable=super-with-arguments # needed here b/c: dataclass
61
- if self.public_modulus < 6 or modmath.IsPrime(self.public_modulus):
54
+ if self.public_modulus < 6 or modmath.IsPrime(self.public_modulus): # noqa: PLR2004
62
55
  # only a full factors check can prove modulus is product of only 2 primes, which is impossible
63
56
  # to do for large numbers here; the private key checks the relationship though
64
57
  raise base.InputError(f'invalid public_modulus: {self}')
65
- if not 2 < self.encrypt_exp < self.public_modulus or not modmath.IsPrime(self.encrypt_exp):
58
+ if not 2 < self.encrypt_exp < self.public_modulus or not modmath.IsPrime(self.encrypt_exp): # noqa: PLR2004
66
59
  # technically, encrypt_exp < phi, but again the private key tests for this explicitly
67
60
  raise base.InputError(f'invalid encrypt_exp: {self}')
68
61
 
@@ -71,11 +64,14 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
71
64
 
72
65
  Returns:
73
66
  string representation of RSAPublicKey
67
+
74
68
  """
75
- return ('RSAPublicKey('
76
- f'bits={self.public_modulus.bit_length()}, '
77
- f'public_modulus={base.IntToEncoded(self.public_modulus)}, '
78
- f'encrypt_exp={base.IntToEncoded(self.encrypt_exp)})')
69
+ return (
70
+ 'RSAPublicKey('
71
+ f'bits={self.public_modulus.bit_length()}, '
72
+ f'public_modulus={base.IntToEncoded(self.public_modulus)}, '
73
+ f'encrypt_exp={base.IntToEncoded(self.encrypt_exp)})'
74
+ )
79
75
 
80
76
  @property
81
77
  def modulus_size(self) -> int:
@@ -97,12 +93,13 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
97
93
 
98
94
  Raises:
99
95
  InputError: invalid inputs
96
+
100
97
  """
101
98
  # test inputs
102
99
  if not 0 < message < self.public_modulus:
103
100
  raise base.InputError(f'invalid message: {message=}')
104
101
  # encrypt
105
- return int(gmpy2.powmod(message, self.encrypt_exp, self.public_modulus)) # type:ignore # pylint:disable=no-member
102
+ return int(gmpy2.powmod(message, self.encrypt_exp, self.public_modulus))
106
103
 
107
104
  def Encrypt(self, plaintext: bytes, /, *, associated_data: bytes | None = None) -> bytes:
108
105
  """Encrypt `plaintext` and return `ciphertext`.
@@ -128,9 +125,6 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
128
125
  Padded(ct, k) + AES-256-GCM(key=SHA512(r)[32:], plaintext,
129
126
  associated_data="prefix" + len(aad) + aad + Padded(ct, k))
130
127
 
131
- Raises:
132
- InputError: invalid inputs
133
- CryptoError: internal crypto failures
134
128
  """
135
129
  # generate random r and encrypt it
136
130
  r: int = 0
@@ -138,7 +132,7 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
138
132
  r = base.RandBits(self.public_modulus.bit_length())
139
133
  k: int = self.modulus_size
140
134
  ct: bytes = base.IntToFixedBytes(self.RawEncrypt(r), k)
141
- assert len(ct) == k, 'should never happen: c_kem should be exactly k bytes'
135
+ assert len(ct) == k, 'should never happen: c_kem should be exactly k bytes' # noqa: S101
142
136
  # encrypt plaintext with AES-256-GCM using SHA512(r)[32:] as key; return ct || Encrypt(...)
143
137
  ss: bytes = base.Hash512(base.IntToFixedBytes(r, k))
144
138
  aad: bytes = b'' if associated_data is None else associated_data
@@ -160,13 +154,12 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
160
154
  True if signature is valid, False otherwise;
161
155
  (signature ** encrypt_exp) mod modulus == message
162
156
 
163
- Raises:
164
- InputError: invalid inputs
165
157
  """
166
158
  return self.RawEncrypt(signature) == message
167
159
 
168
160
  def _DomainSeparatedHash(
169
- self, message: bytes, associated_data: bytes | None, salt: bytes, /) -> int:
161
+ self, message: bytes, associated_data: bytes | None, salt: bytes, /
162
+ ) -> int:
170
163
  """Compute the domain-separated hash for signing and verifying.
171
164
 
172
165
  Args:
@@ -180,10 +173,11 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
180
173
 
181
174
  Raises:
182
175
  CryptoError: hash output is out of range
176
+
183
177
  """
184
178
  aad: bytes = b'' if associated_data is None else associated_data
185
179
  la: bytes = base.IntToFixedBytes(len(aad), 8)
186
- assert len(salt) == 64, 'should never happen: salt should be exactly 64 bytes'
180
+ assert len(salt) == 64, 'should never happen: salt should be exactly 64 bytes' # noqa: PLR2004, S101
187
181
  y: int = base.BytesToInt(base.Hash512(_RSA_SIGNATURE_HASH_PREFIX + la + aad + message + salt))
188
182
  if not 1 < y < self.public_modulus or base.GCD(y, self.public_modulus) != 1:
189
183
  # will only reasonably happen if modulus is small
@@ -191,7 +185,8 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
191
185
  return y
192
186
 
193
187
  def Verify(
194
- self, message: bytes, signature: bytes, /, *, associated_data: bytes | None = None) -> bool:
188
+ self, message: bytes, signature: bytes, /, *, associated_data: bytes | None = None
189
+ ) -> bool:
195
190
  """Verify a `signature` for `message`. True if OK; False if failed verification.
196
191
 
197
192
  • Let k = ceil(log2(n))/8 be the modulus size in bytes.
@@ -210,25 +205,34 @@ class RSAPublicKey(base.CryptoKey, base.Encryptor, base.Verifier):
210
205
 
211
206
  Raises:
212
207
  InputError: invalid inputs
213
- CryptoError: internal crypto failures, authentication failure, key mismatch, etc
208
+
214
209
  """
215
210
  k: int = self.modulus_size
216
- if k <= 64:
211
+ if k <= 64: # noqa: PLR2004
217
212
  raise base.InputError(f'modulus too small for signing operations: {k} bytes')
218
213
  if len(signature) != (64 + k):
219
214
  logging.info(f'invalid signature length: {len(signature)} ; expected {64 + k}')
220
215
  return False
221
216
  try:
222
217
  return self.RawVerify(
223
- self._DomainSeparatedHash(message, associated_data, signature[:64]),
224
- base.BytesToInt(signature[64:]))
218
+ self._DomainSeparatedHash(message, associated_data, signature[:64]),
219
+ base.BytesToInt(signature[64:]),
220
+ )
225
221
  except base.InputError as err:
226
222
  logging.info(err)
227
223
  return False
228
224
 
229
225
  @classmethod
230
226
  def Copy(cls, other: RSAPublicKey, /) -> Self:
231
- """Initialize a public key by taking the public parts of a public/private key."""
227
+ """Initialize a public key by taking the public parts of a public/private key.
228
+
229
+ Args:
230
+ other (RSAPublicKey): object to copy from
231
+
232
+ Returns:
233
+ Self: a new RSAPublicKey
234
+
235
+ """
232
236
  return cls(public_modulus=other.public_modulus, encrypt_exp=other.encrypt_exp)
233
237
 
234
238
 
@@ -243,6 +247,7 @@ class RSAObfuscationPair(RSAPublicKey):
243
247
  Attributes:
244
248
  random_key (int): random value key, 2 ≤ k < modulus
245
249
  key_inverse (int): inverse for `random_key` in relation to the RSA public key, 2 ≤ i < modulus
250
+
246
251
  """
247
252
 
248
253
  random_key: int
@@ -254,11 +259,14 @@ class RSAObfuscationPair(RSAPublicKey):
254
259
  Raises:
255
260
  InputError: invalid inputs
256
261
  CryptoError: modulus math is inconsistent with values
262
+
257
263
  """
258
- super(RSAObfuscationPair, self).__post_init__() # pylint: disable=super-with-arguments # needed here b/c: dataclass
259
- if (not 1 < self.random_key < self.public_modulus or
260
- not 1 < self.key_inverse < self.public_modulus or
261
- self.random_key in (self.key_inverse, self.encrypt_exp, self.public_modulus)):
264
+ super(RSAObfuscationPair, self).__post_init__()
265
+ if (
266
+ not 1 < self.random_key < self.public_modulus
267
+ or not 1 < self.key_inverse < self.public_modulus
268
+ or self.random_key in {self.key_inverse, self.encrypt_exp, self.public_modulus}
269
+ ):
262
270
  raise base.InputError(f'invalid keys: {self}')
263
271
  if (self.random_key * self.key_inverse) % self.public_modulus != 1:
264
272
  raise base.CryptoError(f'inconsistent keys: {self}')
@@ -268,11 +276,14 @@ class RSAObfuscationPair(RSAPublicKey):
268
276
 
269
277
  Returns:
270
278
  string representation of RSAObfuscationPair without leaking secrets
279
+
271
280
  """
272
- return ('RSAObfuscationPair('
273
- f'{super(RSAObfuscationPair, self).__str__()}, ' # pylint: disable=super-with-arguments
274
- f'random_key={base.ObfuscateSecret(self.random_key)}, '
275
- f'key_inverse={base.ObfuscateSecret(self.key_inverse)})')
281
+ return (
282
+ 'RSAObfuscationPair('
283
+ f'{super(RSAObfuscationPair, self).__str__()}, '
284
+ f'random_key={base.ObfuscateSecret(self.random_key)}, '
285
+ f'key_inverse={base.ObfuscateSecret(self.key_inverse)})'
286
+ )
276
287
 
277
288
  def ObfuscateMessage(self, message: int, /) -> int:
278
289
  """Convert message to an obfuscated message to be signed by this key's owner.
@@ -287,13 +298,15 @@ class RSAObfuscationPair(RSAPublicKey):
287
298
 
288
299
  Raises:
289
300
  InputError: invalid inputs
301
+
290
302
  """
291
303
  # test inputs
292
304
  if not 0 < message < self.public_modulus:
293
305
  raise base.InputError(f'invalid message: {message=}')
294
306
  # encrypt
295
- return (message * int(gmpy2.powmod( # type:ignore # pylint:disable=no-member
296
- self.random_key, self.encrypt_exp, self.public_modulus))) % self.public_modulus
307
+ return (
308
+ message * int(gmpy2.powmod(self.random_key, self.encrypt_exp, self.public_modulus))
309
+ ) % self.public_modulus
297
310
 
298
311
  def RevealOriginalSignature(self, message: int, signature: int, /) -> int:
299
312
  """Recover original signature for `message` from obfuscated `signature`.
@@ -309,8 +322,8 @@ class RSAObfuscationPair(RSAPublicKey):
309
322
  signature * key_inverse mod modulus
310
323
 
311
324
  Raises:
312
- InputError: invalid inputs
313
325
  CryptoError: some signatures were invalid (either plain or obfuscated)
326
+
314
327
  """
315
328
  # verify that obfuscated signature is valid
316
329
  obfuscated: int = self.ObfuscateMessage(message)
@@ -324,7 +337,7 @@ class RSAObfuscationPair(RSAPublicKey):
324
337
 
325
338
  @classmethod
326
339
  def New(cls, key: RSAPublicKey, /) -> Self:
327
- """New obfuscation pair for this `key`, respecting the size of the public modulus.
340
+ """Generate new obfuscation pair for this `key`, respecting the size of the public modulus.
328
341
 
329
342
  Args:
330
343
  key (RSAPublicKey): public RSA key to use as base for a new RSAObfuscationPair
@@ -334,15 +347,18 @@ class RSAObfuscationPair(RSAPublicKey):
334
347
 
335
348
  Raises:
336
349
  CryptoError: failed generation
350
+
337
351
  """
338
352
  # find a suitable random key based on the bit_length
339
353
  random_key: int = 0
340
354
  key_inverse: int = 0
341
355
  failures: int = 0
342
- while (not random_key or not key_inverse or
343
- random_key == key.encrypt_exp or
344
- random_key == key_inverse or
345
- key_inverse == key.encrypt_exp):
356
+ while (
357
+ not random_key
358
+ or not key_inverse
359
+ or random_key in {key.encrypt_exp, key_inverse}
360
+ or key_inverse == key.encrypt_exp
361
+ ):
346
362
  random_key = base.RandBits(key.public_modulus.bit_length() - 1)
347
363
  try:
348
364
  key_inverse = modmath.ModInv(random_key, key.public_modulus)
@@ -354,12 +370,15 @@ class RSAObfuscationPair(RSAPublicKey):
354
370
  logging.warning(err)
355
371
  # build object
356
372
  return cls(
357
- public_modulus=key.public_modulus, encrypt_exp=key.encrypt_exp,
358
- random_key=random_key, key_inverse=key_inverse)
373
+ public_modulus=key.public_modulus,
374
+ encrypt_exp=key.encrypt_exp,
375
+ random_key=random_key,
376
+ key_inverse=key_inverse,
377
+ )
359
378
 
360
379
 
361
380
  @dataclasses.dataclass(kw_only=True, slots=True, frozen=True, repr=False)
362
- class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disable=too-many-ancestors
381
+ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer):
363
382
  """RSA (Rivest-Shamir-Adleman) private key.
364
383
 
365
384
  No measures are taken here to prevent timing attacks.
@@ -375,6 +394,7 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
375
394
  remainder_p (int): pre-computed, = d % (p - 1), 2 ≤ r_p < modulus
376
395
  remainder_q (int): pre-computed, = d % (q - 1), 2 ≤ r_q < modulus
377
396
  q_inverse_p (int): pre-computed, = ModInv(q, p), 2 ≤ q_i_p < modulus
397
+
378
398
  """
379
399
 
380
400
  modulus_p: int
@@ -391,34 +411,41 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
391
411
  Raises:
392
412
  InputError: invalid inputs
393
413
  CryptoError: modulus math is inconsistent with values
414
+
394
415
  """
395
- super(RSAPrivateKey, self).__post_init__() # pylint: disable=super-with-arguments # needed here b/c: dataclass
416
+ super(RSAPrivateKey, self).__post_init__()
396
417
  phi: int = (self.modulus_p - 1) * (self.modulus_q - 1)
397
418
  min_prime_distance: int = 1 << (self.public_modulus.bit_length() // 4) # ≈ n**(1/4)
398
- if (self.modulus_p < 2 or not modmath.IsPrime(self.modulus_p) or # pylint: disable=too-many-boolean-expressions
399
- self.modulus_q < 3 or not modmath.IsPrime(self.modulus_q) or
400
- self.modulus_q <= self.modulus_p or
401
- (self.modulus_q - self.modulus_p) < min_prime_distance or
402
- self.encrypt_exp in (self.modulus_p, self.modulus_q) or
403
- self.encrypt_exp >= phi or
404
- self.decrypt_exp in (self.encrypt_exp, self.modulus_p, self.modulus_q, phi)):
419
+ if (
420
+ self.modulus_p < 2 # noqa: PLR0916, PLR2004
421
+ or not modmath.IsPrime(self.modulus_p)
422
+ or self.modulus_q < 3 # noqa: PLR2004
423
+ or not modmath.IsPrime(self.modulus_q)
424
+ or self.modulus_q <= self.modulus_p
425
+ or (self.modulus_q - self.modulus_p) < min_prime_distance
426
+ or self.encrypt_exp in {self.modulus_p, self.modulus_q}
427
+ or self.encrypt_exp >= phi
428
+ or self.decrypt_exp in {self.encrypt_exp, self.modulus_p, self.modulus_q, phi}
429
+ ):
405
430
  # encrypt_exp has to be less than phi;
406
- # if p q < 2*(n**(1/4)) then solving for p and q is trivial
431
+ # if p - q < 2*(n**(1/4)) then solving for p and q is trivial
407
432
  raise base.InputError(f'invalid modulus_p or modulus_q: {self}')
408
433
  min_decrypt_length: int = self.public_modulus.bit_length() // 2 + 1
409
- if not (2 ** min_decrypt_length) < self.decrypt_exp < self.public_modulus:
434
+ if not (2**min_decrypt_length) < self.decrypt_exp < self.public_modulus:
410
435
  # if decrypt_exp < public_modulus**(1/4)/3, then decrypt_exp can be computed efficiently
411
436
  # from public_modulus and encrypt_exp so we make sure it is larger than public_modulus**(1/2)
412
437
  raise base.InputError(f'invalid decrypt_exp: {self}')
413
- if self.remainder_p < 2 or self.remainder_p < 2 or self.q_inverse_p < 2:
438
+ if self.remainder_p < 2 or self.remainder_q < 2 or self.q_inverse_p < 2: # noqa: PLR2004
414
439
  raise base.InputError(f'trivial remainder_p/remainder_q/q_inverse_p: {self}')
415
440
  if self.modulus_p * self.modulus_q != self.public_modulus:
416
441
  raise base.CryptoError(f'inconsistent modulus_p * modulus_q: {self}')
417
442
  if (self.encrypt_exp * self.decrypt_exp) % phi != 1:
418
443
  raise base.CryptoError(f'inconsistent exponents: {self}')
419
- if (self.remainder_p != self.decrypt_exp % (self.modulus_p - 1) or
420
- self.remainder_q != self.decrypt_exp % (self.modulus_q - 1) or
421
- (self.q_inverse_p * self.modulus_q) % self.modulus_p != 1):
444
+ if (
445
+ self.remainder_p != self.decrypt_exp % (self.modulus_p - 1)
446
+ or self.remainder_q != self.decrypt_exp % (self.modulus_q - 1)
447
+ or (self.q_inverse_p * self.modulus_q) % self.modulus_p != 1
448
+ ):
422
449
  raise base.CryptoError(f'inconsistent speedup remainder_p/remainder_q/q_inverse_p: {self}')
423
450
 
424
451
  def __str__(self) -> str:
@@ -426,12 +453,15 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
426
453
 
427
454
  Returns:
428
455
  string representation of RSAPrivateKey without leaking secrets
456
+
429
457
  """
430
- return ('RSAPrivateKey('
431
- f'{super(RSAPrivateKey, self).__str__()}, ' # pylint: disable=super-with-arguments
432
- f'modulus_p={base.ObfuscateSecret(self.modulus_p)}, '
433
- f'modulus_q={base.ObfuscateSecret(self.modulus_q)}, '
434
- f'decrypt_exp={base.ObfuscateSecret(self.decrypt_exp)})')
458
+ return (
459
+ 'RSAPrivateKey('
460
+ 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)})'
464
+ )
435
465
 
436
466
  def RawDecrypt(self, ciphertext: int, /) -> int:
437
467
  """Decrypt `ciphertext` with this private key.
@@ -448,14 +478,15 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
448
478
 
449
479
  Raises:
450
480
  InputError: invalid inputs
481
+
451
482
  """
452
483
  # test inputs
453
484
  if not 0 <= ciphertext < self.public_modulus:
454
485
  raise base.InputError(f'invalid message: {ciphertext=}')
455
486
  # decrypt using CRT (Chinese Remainder Theorem); 4x speedup; all the below is equivalent
456
487
  # of doing: return pow(ciphertext, self.decrypt_exp, self.public_modulus)
457
- m_p: int = int(gmpy2.powmod(ciphertext % self.modulus_p, self.remainder_p, self.modulus_p)) # type:ignore # pylint:disable=no-member
458
- m_q: int = int(gmpy2.powmod(ciphertext % self.modulus_q, self.remainder_q, self.modulus_q)) # type:ignore # pylint:disable=no-member
488
+ m_p: int = int(gmpy2.powmod(ciphertext % self.modulus_p, self.remainder_p, self.modulus_p))
489
+ m_q: int = int(gmpy2.powmod(ciphertext % self.modulus_q, self.remainder_q, self.modulus_q))
459
490
  h: int = (self.q_inverse_p * (m_p - m_q)) % self.modulus_p
460
491
  return (m_q + h * self.modulus_q) % self.public_modulus
461
492
 
@@ -479,7 +510,7 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
479
510
 
480
511
  Raises:
481
512
  InputError: invalid inputs
482
- CryptoError: internal crypto failures, authentication failure, key mismatch, etc
513
+
483
514
  """
484
515
  k: int = self.modulus_size
485
516
  if len(ciphertext) < (k + 32):
@@ -508,6 +539,7 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
508
539
 
509
540
  Raises:
510
541
  InputError: invalid inputs
542
+
511
543
  """
512
544
  # test inputs
513
545
  if not 0 < message < self.public_modulus:
@@ -538,15 +570,15 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
538
570
 
539
571
  Raises:
540
572
  InputError: invalid inputs
541
- CryptoError: internal crypto failures
573
+
542
574
  """
543
575
  k: int = self.modulus_size
544
- if k <= 64:
576
+ if k <= 64: # noqa: PLR2004
545
577
  raise base.InputError(f'modulus too small for signing operations: {k} bytes')
546
578
  salt: bytes = base.RandBytes(64)
547
579
  s_int: int = self.RawSign(self._DomainSeparatedHash(message, associated_data, salt))
548
580
  s_bytes: bytes = base.IntToFixedBytes(s_int, k)
549
- assert len(s_bytes) == k, 'should never happen: s_bytes should be exactly k bytes'
581
+ assert len(s_bytes) == k, 'should never happen: s_bytes should be exactly k bytes' # noqa: S101
550
582
  return salt + s_bytes
551
583
 
552
584
  @classmethod
@@ -562,9 +594,10 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
562
594
  Raises:
563
595
  InputError: invalid inputs
564
596
  CryptoError: failed generation
597
+
565
598
  """
566
599
  # test inputs
567
- if bit_length < 11:
600
+ if bit_length < 11: # noqa: PLR2004
568
601
  raise base.InputError(f'invalid bit length: {bit_length=}')
569
602
  # generate primes / modulus
570
603
  failures: int = 0
@@ -580,18 +613,21 @@ class RSAPrivateKey(RSAPublicKey, base.Decryptor, base.Signer): # pylint: disab
580
613
  modulus = p * q
581
614
  # build object
582
615
  phi: int = (p - 1) * (q - 1)
583
- prime_exp: int = (_SMALL_ENCRYPTION_EXPONENT if phi <= _BIG_ENCRYPTION_EXPONENT else
584
- _BIG_ENCRYPTION_EXPONENT)
616
+ prime_exp: int = (
617
+ _SMALL_ENCRYPTION_EXPONENT
618
+ if phi <= _BIG_ENCRYPTION_EXPONENT
619
+ else _BIG_ENCRYPTION_EXPONENT
620
+ )
585
621
  decrypt_exp: int = modmath.ModInv(prime_exp, phi)
586
622
  return cls(
587
- modulus_p=p,
588
- modulus_q=q,
589
- public_modulus=modulus,
590
- encrypt_exp=prime_exp,
591
- decrypt_exp=decrypt_exp,
592
- remainder_p=decrypt_exp % (p - 1),
593
- remainder_q=decrypt_exp % (q - 1),
594
- q_inverse_p=modmath.ModInv(q, p),
623
+ modulus_p=p,
624
+ modulus_q=q,
625
+ public_modulus=modulus,
626
+ encrypt_exp=prime_exp,
627
+ decrypt_exp=decrypt_exp,
628
+ remainder_p=decrypt_exp % (p - 1),
629
+ remainder_q=decrypt_exp % (q - 1),
630
+ q_inverse_p=modmath.ModInv(q, p),
595
631
  )
596
632
  except (base.InputError, modmath.ModularDivideError) as err:
597
633
  failures += 1