puantum 1.1.1__tar.gz → 3.3.3__tar.gz

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.
Files changed (32) hide show
  1. puantum-3.3.3/.github/workflows/publish.yml +36 -0
  2. {puantum-1.1.1 → puantum-3.3.3}/Cargo.toml +1 -0
  3. puantum-3.3.3/Makefile +13 -0
  4. {puantum-1.1.1 → puantum-3.3.3}/PKG-INFO +40 -6
  5. puantum-3.3.3/puantum/classic/__init__.pyi +1 -0
  6. puantum-3.3.3/puantum/quantum/__init__.py +1 -0
  7. puantum-3.3.3/puantum/quantum/__init__.pyi +1 -0
  8. puantum-3.3.3/puantum/quantum/dsa/__init__.pyi +5 -0
  9. {puantum-1.1.1 → puantum-3.3.3}/puantum/quantum/dsa/__internal__.py +186 -134
  10. puantum-3.3.3/puantum/quantum/dsa/__internal__.pyi +388 -0
  11. puantum-3.3.3/puantum/quantum/kem/__init__.pyi +5 -0
  12. {puantum-1.1.1 → puantum-3.3.3}/puantum/quantum/kem/__internal__.py +193 -230
  13. puantum-3.3.3/puantum/quantum/kem/__internal__.pyi +363 -0
  14. {puantum-1.1.1 → puantum-3.3.3}/pyproject.toml +1 -1
  15. puantum-3.3.3/readme.md +82 -0
  16. puantum-1.1.1/README.md +0 -48
  17. puantum-1.1.1/examples/dsa.py +0 -14
  18. puantum-1.1.1/examples/kem.py +0 -14
  19. puantum-1.1.1/readme.md +0 -48
  20. {puantum-1.1.1 → puantum-3.3.3}/.gitignore +0 -0
  21. {puantum-1.1.1 → puantum-3.3.3}/Cargo.lock +0 -0
  22. {puantum-1.1.1 → puantum-3.3.3}/license.md +0 -0
  23. {puantum-1.1.1 → puantum-3.3.3}/puantum/__init__.py +0 -0
  24. /puantum-1.1.1/puantum/quantum/__init__.py → /puantum-3.3.3/puantum/__init__.pyi +0 -0
  25. {puantum-1.1.1 → puantum-3.3.3}/puantum/classic/__init__.py +0 -0
  26. {puantum-1.1.1 → puantum-3.3.3}/puantum/quantum/dsa/__init__.py +0 -0
  27. {puantum-1.1.1 → puantum-3.3.3}/puantum/quantum/kem/__init__.py +0 -0
  28. {puantum-1.1.1 → puantum-3.3.3}/rust/cryptography/classic/mod.rs +0 -0
  29. {puantum-1.1.1 → puantum-3.3.3}/rust/cryptography/mod.rs +0 -0
  30. {puantum-1.1.1 → puantum-3.3.3}/rust/cryptography/quantum/binding.rs +0 -0
  31. {puantum-1.1.1 → puantum-3.3.3}/rust/cryptography/quantum/mod.rs +0 -0
  32. {puantum-1.1.1 → puantum-3.3.3}/rust/python.rs +0 -0
@@ -0,0 +1,36 @@
1
+ name: Build and Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main # Trigger on every push to the main branch
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: '3.13' # Adjust if needed
20
+
21
+ - name: Install Rust
22
+ uses: dtolnay/rust-toolchain@stable
23
+
24
+ - name: Install maturin
25
+ run: pip install maturin
26
+
27
+ - name: Build the wheel and sdist
28
+ run: maturin build --sdist --release
29
+
30
+ - name: Publish to PyPI
31
+ env:
32
+ TWINE_USERNAME: __token__
33
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
34
+ run: |
35
+ pip install twine
36
+ twine upload target/wheels/*
@@ -2,6 +2,7 @@
2
2
  name = "puantum"
3
3
  version = "1.0.0"
4
4
  edition = "2024"
5
+ license = "Unlicense"
5
6
 
6
7
  [lib]
7
8
  crate-type = ["cdylib"]
puantum-3.3.3/Makefile ADDED
@@ -0,0 +1,13 @@
1
+ all: release
2
+
3
+ clean:
4
+ cargo clean
5
+
6
+ release: clean
7
+ cargo build --release
8
+
9
+ python: clean
10
+ maturin build --release
11
+
12
+ pypi: clean
13
+ maturin build --release --sdist
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: puantum
3
- Version: 1.1.1
3
+ Version: 3.3.3
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Operating System :: OS Independent
@@ -19,7 +19,7 @@ Project-URL: x, https://x.com/1xfakebit
19
19
 
20
20
  A blazing-fast cryptography library for Python, built on Rust.
21
21
 
22
- Puantum supports an extensive set of **post-quantum** key encapsulation mechanisms (KEM) and digital signature algorithms (DSA), and will soon support **classic cryptography** as well.
22
+ Pryptography supports an extensive set of **post-quantum** digital signature algorithms (DSA) and key encapsulation mechanisms (KEM).
23
23
 
24
24
  ---
25
25
  ## ⚡ Features
@@ -48,15 +48,49 @@ Puantum supports an extensive set of **post-quantum** key encapsulation mechanis
48
48
  - #### Sphincs
49
49
  - #### Uov
50
50
 
51
- ### 🚧 Coming Soon
52
- - #### AES, ChaCha20, XChaCha20
53
- - #### RSA, EC
54
- - #### Argon2, Bcrypt
51
+ ### Examples
52
+
53
+ #### DSA Example
54
+ ```python
55
+ # IMPORT
56
+ from puantum.quantum.dsa import Algorithm, KeyPair
57
+
58
+ # MAIN
59
+ alicesk, alicepk = KeyPair(Algorithm.MLDSA.MLDSA87)
60
+ message = "Hello".encode()
61
+
62
+ signature = alicesk.sign(message=message)
63
+ valid = alicepk.verify(signature=signature, message=message)
64
+
65
+ assert valid, "Signature verification failed!"
66
+
67
+ print(f"Message: [{message.decode()}]")
68
+ print(f"Signature: [{signature.hex()[:len(message)]}]")
69
+ ```
70
+
71
+ #### KEM Example
72
+ ```python
73
+ # IMPORT
74
+ from puantum.quantum.kem import Algorithm, KeyPair
75
+
76
+ # MAIN
77
+ alicesk, alicepk = KeyPair(Algorithm.MLKEM.MLKEM1024)
78
+ _bobsk, _bobpk = KeyPair(Algorithm.MLKEM.MLKEM1024)
79
+
80
+ bobss, bobct = alicepk.encapsulate()
81
+ alicess = alicesk.decapsulate(bobct)
82
+
83
+ assert alicess == bobss, "Shared secrets do not match!"
84
+
85
+ print(f"Alice's Shared Secret: [{alicess.hex()}]")
86
+ print(f"Bob's Shared Secret: [{bobss.hex()}]")
87
+ ```
55
88
 
56
89
  ### 📦 Install
57
90
  ```shell
58
91
  pip install puantum
59
92
  ```
93
+
60
94
  #### or from source:
61
95
  ```shell
62
96
  make python
@@ -0,0 +1 @@
1
+ # EMPTY
@@ -0,0 +1 @@
1
+ # EMPTY
@@ -0,0 +1 @@
1
+ # EMPTY
@@ -0,0 +1,5 @@
1
+ # IMPORT
2
+ from puantum.quantum.dsa.__internal__ import Algorithm, KeyPair
3
+
4
+ # MAIN
5
+ __all__: list[str] = ["Algorithm", "KeyPair"]
@@ -75,93 +75,6 @@ class Algorithm:
75
75
 
76
76
 
77
77
 
78
- class Signature:
79
- def __init__(self, signature: bytes) -> None:
80
- if not isinstance(signature, bytes):
81
- raise TypeError("Signature Not Valid")
82
- #
83
- self.signature = signature
84
- #
85
- return None
86
-
87
-
88
-
89
- class CROSSSignature(Signature):
90
- def __init__(self, name: Algorithm.CROSS, signature: bytes) -> None:
91
- if not isinstance(name, Algorithm.CROSS):
92
- raise ValueError(f"Unsupported algorithm: {name}")
93
- else:
94
- super().__init__(signature)
95
- #
96
- return None
97
-
98
-
99
-
100
- class DILITHIUMSignature(Signature):
101
- def __init__(self, name: Algorithm.DILITHIUM, signature: bytes) -> None:
102
- if not isinstance(name, Algorithm.DILITHIUM):
103
- raise ValueError(f"Unsupported algorithm: {name}")
104
- else:
105
- super().__init__(signature)
106
- #
107
- return None
108
-
109
-
110
-
111
- class FALCONSignature(Signature):
112
- def __init__(self, name: Algorithm.FALCON, signature: bytes) -> None:
113
- if not isinstance(name, Algorithm.FALCON):
114
- raise ValueError(f"Unsupported algorithm: {name}")
115
- else:
116
- super().__init__(signature)
117
- #
118
- return None
119
-
120
-
121
-
122
- class MAYOSignature(Signature):
123
- def __init__(self, name: Algorithm.MAYO, signature: bytes) -> None:
124
- if not isinstance(name, Algorithm.MAYO):
125
- raise ValueError(f"Unsupported algorithm: {name}")
126
- else:
127
- super().__init__(signature)
128
- #
129
- return None
130
-
131
-
132
-
133
- class MLDSASignature(Signature):
134
- def __init__(self, name: Algorithm.MLDSA, signature: bytes) -> None:
135
- if not isinstance(name, Algorithm.MLDSA):
136
- raise ValueError(f"Unsupported algorithm: {name}")
137
- else:
138
- super().__init__(signature)
139
- #
140
- return None
141
-
142
-
143
-
144
- class SPHINCSSignature(Signature):
145
- def __init__(self, name: Algorithm.SPHINCS, signature: bytes) -> None:
146
- if not isinstance(name, Algorithm.SPHINCS):
147
- raise ValueError(f"Unsupported algorithm: {name}")
148
- else:
149
- super().__init__(signature)
150
- #
151
- return None
152
-
153
-
154
- class UOVSignature(Signature):
155
- def __init__(self, name: Algorithm.UOV, signature: bytes) -> None:
156
- if not isinstance(name, Algorithm.UOV):
157
- raise ValueError(f"Unsupported algorithm: {name}")
158
- else:
159
- super().__init__(signature)
160
- #
161
- return None
162
-
163
-
164
-
165
78
  class PublicKey:
166
79
  def __init__(self, publickey: bytes) -> None:
167
80
  if not isinstance(publickey, bytes):
@@ -187,8 +100,8 @@ class CROSSPublicKey(PublicKey):
187
100
  #
188
101
  return None
189
102
  #
190
- def verify(self, signature: CROSSSignature, message: bytes) -> bool:
191
- result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature.signature, message) # type: ignore
103
+ def verify(self, signature: bytes, message: bytes) -> bool:
104
+ result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature, message) # type: ignore
192
105
  return result # type: ignore
193
106
 
194
107
 
@@ -204,8 +117,8 @@ class DILITHIUMPublicKey(PublicKey):
204
117
  #
205
118
  return None
206
119
  #
207
- def verify(self, signature: DILITHIUMSignature, message: bytes) -> bool:
208
- result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature.signature, message) # type: ignore
120
+ def verify(self, signature: bytes, message: bytes) -> bool:
121
+ result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature, message) # type: ignore
209
122
  return result # type: ignore
210
123
 
211
124
 
@@ -221,8 +134,8 @@ class FALCONPublicKey(PublicKey):
221
134
  #
222
135
  return None
223
136
  #
224
- def verify(self, signature: FALCONSignature, message: bytes) -> bool:
225
- result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature.signature, message) # type: ignore
137
+ def verify(self, signature: bytes, message: bytes) -> bool:
138
+ result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature, message) # type: ignore
226
139
  return result # type: ignore
227
140
 
228
141
 
@@ -238,8 +151,8 @@ class MAYOPublicKey(PublicKey):
238
151
  #
239
152
  return None
240
153
  #
241
- def verify(self, signature: MAYOSignature, message: bytes) -> bool:
242
- result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature.signature, message) # type: ignore
154
+ def verify(self, signature: bytes, message: bytes) -> bool:
155
+ result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature, message) # type: ignore
243
156
  return result # type: ignore
244
157
 
245
158
 
@@ -255,8 +168,8 @@ class MLDSAPublicKey(PublicKey):
255
168
  #
256
169
  return None
257
170
  #
258
- def verify(self, signature: MLDSASignature, message: bytes) -> bool:
259
- result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature.signature, message) # type: ignore
171
+ def verify(self, signature: bytes, message: bytes) -> bool:
172
+ result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature, message) # type: ignore
260
173
  return result # type: ignore
261
174
 
262
175
 
@@ -272,8 +185,8 @@ class SPHINCSPublicKey(PublicKey):
272
185
  #
273
186
  return None
274
187
  #
275
- def verify(self, signature: SPHINCSSignature, message: bytes) -> bool:
276
- result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature.signature, message) # type: ignore
188
+ def verify(self, signature: bytes, message: bytes) -> bool:
189
+ result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature, message) # type: ignore
277
190
  return result # type: ignore
278
191
 
279
192
 
@@ -289,8 +202,8 @@ class UOVPublicKey(PublicKey):
289
202
  #
290
203
  return None
291
204
  #
292
- def verify(self, signature: UOVSignature, message: bytes) -> bool:
293
- result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature.signature, message) # type: ignore
205
+ def verify(self, signature: bytes, message: bytes) -> bool:
206
+ result: bool = _internal.sigverify(self._algorithm.value, self.publickey, signature, message) # type: ignore
294
207
  return result # type: ignore
295
208
 
296
209
 
@@ -320,9 +233,9 @@ class CROSSSecretKey(SecretKey):
320
233
  #
321
234
  return None
322
235
  #
323
- def sign(self, message: bytes) -> CROSSSignature:
236
+ def sign(self, message: bytes) -> bytes:
324
237
  signature: bytes = _internal.sigsign(self._algorithm.value, self.secretkey, message) # type: ignore
325
- return CROSSSignature(self._algorithm, signature) # type: ignore
238
+ return signature # type: ignore
326
239
 
327
240
 
328
241
 
@@ -337,9 +250,9 @@ class DILITHIUMSecretKey(SecretKey):
337
250
  #
338
251
  return None
339
252
  #
340
- def sign(self, message: bytes) -> DILITHIUMSignature:
253
+ def sign(self, message: bytes) -> bytes:
341
254
  signature: bytes = _internal.sigsign(self._algorithm.value, self.secretkey, message) # type: ignore
342
- return DILITHIUMSignature(self._algorithm, signature) # type: ignore
255
+ return signature # type: ignore
343
256
 
344
257
 
345
258
 
@@ -354,9 +267,9 @@ class FALCONSecretKey(SecretKey):
354
267
  #
355
268
  return None
356
269
  #
357
- def sign(self, message: bytes) -> FALCONSignature:
270
+ def sign(self, message: bytes) -> bytes:
358
271
  signature: bytes = _internal.sigsign(self._algorithm.value, self.secretkey, message) # type: ignore
359
- return FALCONSignature(self._algorithm, signature) # type: ignore
272
+ return signature # type: ignore
360
273
 
361
274
 
362
275
 
@@ -371,9 +284,9 @@ class MAYOSecretKey(SecretKey):
371
284
  #
372
285
  return None
373
286
  #
374
- def sign(self, message: bytes) -> MAYOSignature:
287
+ def sign(self, message: bytes) -> bytes:
375
288
  signature: bytes = _internal.sigsign(self._algorithm.value, self.secretkey, message) # type: ignore
376
- return MAYOSignature(self._algorithm, signature) # type: ignore
289
+ return signature # type: ignore
377
290
 
378
291
 
379
292
 
@@ -388,9 +301,9 @@ class MLDSASecretKey(SecretKey):
388
301
  #
389
302
  return None
390
303
  #
391
- def sign(self, message: bytes) -> MLDSASignature:
304
+ def sign(self, message: bytes) -> bytes:
392
305
  signature: bytes = _internal.sigsign(self._algorithm.value, self.secretkey, message) # type: ignore
393
- return MLDSASignature(self._algorithm, signature) # type: ignore
306
+ return signature # type: ignore
394
307
 
395
308
 
396
309
 
@@ -405,9 +318,9 @@ class SPHINCSSecretKey(SecretKey):
405
318
  #
406
319
  return None
407
320
  #
408
- def sign(self, message: bytes) -> SPHINCSSignature:
321
+ def sign(self, message: bytes) -> bytes:
409
322
  signature: bytes = _internal.sigsign(self._algorithm.value, self.secretkey, message) # type: ignore
410
- return SPHINCSSignature(self._algorithm, signature) # type: ignore
323
+ return signature # type: ignore
411
324
 
412
325
 
413
326
 
@@ -422,77 +335,216 @@ class UOVSecretKey(SecretKey):
422
335
  #
423
336
  return None
424
337
  #
425
- def sign(self, message: bytes) -> UOVSignature:
338
+ def sign(self, message: bytes) -> bytes:
426
339
  signature: bytes = _internal.sigsign(self._algorithm.value, self.secretkey, message) # type: ignore
427
- return UOVSignature(self._algorithm, signature) # type: ignore
428
-
429
-
430
-
431
- Algorithms = Algorithm | Algorithm.CROSS | Algorithm.DILITHIUM | Algorithm.FALCON | Algorithm.MAYO | Algorithm.MLDSA | Algorithm.SPHINCS | Algorithm.UOV
340
+ return signature # type: ignore
432
341
 
433
342
 
434
343
 
344
+ @_typing.overload
345
+ def KeyPair(
346
+ name: Algorithm,
347
+ *,
348
+ secretkey: bytes, publickey: bytes
349
+ ) -> tuple[SecretKey, PublicKey]: ...
350
+ @_typing.overload
351
+ def KeyPair(name: Algorithm, *, secretkey: bytes) -> SecretKey: ...
352
+ @_typing.overload
353
+ def KeyPair(name: Algorithm, *, publickey: bytes) -> PublicKey: ...
435
354
  @_typing.overload
436
355
  def KeyPair(name: Algorithm) -> tuple[SecretKey, PublicKey]: ...
437
356
 
438
357
 
358
+
359
+ @_typing.overload
360
+ def KeyPair(
361
+ name: Algorithm.CROSS,
362
+ *,
363
+ secretkey: bytes,
364
+ publickey: bytes
365
+ ) -> tuple[CROSSSecretKey, CROSSPublicKey]: ...
366
+ @_typing.overload
367
+ def KeyPair(name: Algorithm.CROSS, *, secretkey: bytes) -> CROSSSecretKey: ...
368
+ @_typing.overload
369
+ def KeyPair(name: Algorithm.CROSS, *, publickey: bytes) -> CROSSPublicKey: ...
439
370
  @_typing.overload
440
371
  def KeyPair(name: Algorithm.CROSS) -> tuple[CROSSSecretKey, CROSSPublicKey]: ...
441
372
 
442
373
 
443
374
 
375
+ @_typing.overload
376
+ def KeyPair(
377
+ name: Algorithm.DILITHIUM,
378
+ *,
379
+ secretkey: bytes,
380
+ publickey: bytes
381
+ ) -> tuple[DILITHIUMSecretKey, DILITHIUMPublicKey]: ...
382
+ @_typing.overload
383
+ def KeyPair(name: Algorithm.DILITHIUM, *, secretkey: bytes) -> DILITHIUMSecretKey: ...
384
+ @_typing.overload
385
+ def KeyPair(name: Algorithm.DILITHIUM, *, publickey: bytes) -> DILITHIUMPublicKey: ...
444
386
  @_typing.overload
445
387
  def KeyPair(name: Algorithm.DILITHIUM) -> tuple[DILITHIUMSecretKey, DILITHIUMPublicKey]: ...
446
388
 
447
389
 
448
390
 
391
+ @_typing.overload
392
+ def KeyPair(
393
+ name: Algorithm.FALCON,
394
+ *,
395
+ secretkey: bytes,
396
+ publickey: bytes
397
+ ) -> tuple[FALCONSecretKey, FALCONPublicKey]: ...
398
+ @_typing.overload
399
+ def KeyPair(name: Algorithm.FALCON, *, secretkey: bytes) -> FALCONSecretKey: ...
400
+ @_typing.overload
401
+ def KeyPair(name: Algorithm.FALCON, *, publickey: bytes) -> FALCONPublicKey: ...
449
402
  @_typing.overload
450
403
  def KeyPair(name: Algorithm.FALCON) -> tuple[FALCONSecretKey, FALCONPublicKey]: ...
451
404
 
452
405
 
453
406
 
407
+ @_typing.overload
408
+ def KeyPair(
409
+ name: Algorithm.MAYO,
410
+ *,
411
+ secretkey: bytes,
412
+ publickey: bytes
413
+ ) -> tuple[MAYOSecretKey, MAYOPublicKey]: ...
414
+ @_typing.overload
415
+ def KeyPair(name: Algorithm.MAYO, *, secretkey: bytes) -> MAYOSecretKey: ...
416
+ @_typing.overload
417
+ def KeyPair(name: Algorithm.MAYO, *, publickey: bytes) -> MAYOPublicKey: ...
454
418
  @_typing.overload
455
419
  def KeyPair(name: Algorithm.MAYO) -> tuple[MAYOSecretKey, MAYOPublicKey]: ...
456
420
 
457
421
 
458
422
 
423
+ @_typing.overload
424
+ def KeyPair(
425
+ name: Algorithm.MLDSA,
426
+ *,
427
+ secretkey: bytes,
428
+ publickey: bytes
429
+ ) -> tuple[MLDSASecretKey, MLDSAPublicKey]: ...
430
+ @_typing.overload
431
+ def KeyPair(name: Algorithm.MLDSA, *, secretkey: bytes) -> MLDSASecretKey: ...
432
+ @_typing.overload
433
+ def KeyPair(name: Algorithm.MLDSA, *, publickey: bytes) -> MLDSAPublicKey: ...
459
434
  @_typing.overload
460
435
  def KeyPair(name: Algorithm.MLDSA) -> tuple[MLDSASecretKey, MLDSAPublicKey]: ...
461
436
 
462
437
 
463
438
 
439
+ @_typing.overload
440
+ def KeyPair(
441
+ name: Algorithm.SPHINCS,
442
+ *,
443
+ secretkey: bytes,
444
+ publickey: bytes
445
+ ) -> tuple[SPHINCSSecretKey, SPHINCSPublicKey]: ...
446
+ @_typing.overload
447
+ def KeyPair(name: Algorithm.SPHINCS, *, secretkey: bytes) -> SPHINCSSecretKey: ...
448
+ @_typing.overload
449
+ def KeyPair(name: Algorithm.SPHINCS, *, publickey: bytes) -> SPHINCSPublicKey: ...
464
450
  @_typing.overload
465
451
  def KeyPair(name: Algorithm.SPHINCS) -> tuple[SPHINCSSecretKey, SPHINCSPublicKey]: ...
466
452
 
467
453
 
468
454
 
455
+ @_typing.overload
456
+ def KeyPair(
457
+ name: Algorithm.UOV,
458
+ *,
459
+ secretkey: bytes,
460
+ publickey: bytes
461
+ ) -> tuple[UOVSecretKey, UOVPublicKey]: ...
462
+ @_typing.overload
463
+ def KeyPair(name: Algorithm.UOV, *, secretkey: bytes) -> UOVSecretKey: ...
464
+ @_typing.overload
465
+ def KeyPair(name: Algorithm.UOV, *, publickey: bytes) -> UOVPublicKey: ...
469
466
  @_typing.overload
470
467
  def KeyPair(name: Algorithm.UOV) -> tuple[UOVSecretKey, UOVPublicKey]: ...
471
468
 
472
469
 
473
470
 
474
- def KeyPair(name: Algorithms) -> tuple[SecretKey, PublicKey]:
471
+ Algorithms = Algorithm.CROSS | Algorithm.DILITHIUM | Algorithm.FALCON | Algorithm.MAYO | Algorithm.MLDSA | Algorithm.SPHINCS | Algorithm.UOV
472
+ def KeyPair(
473
+ name: Algorithm | Algorithms,
474
+ *,
475
+ secretkey: bytes | None = None,
476
+ publickey: bytes | None = None
477
+ ) -> tuple[SecretKey, PublicKey] | SecretKey | PublicKey:
475
478
  algorithm = name
476
479
  if isinstance(algorithm, Algorithm.CROSS):
477
- secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
478
- return CROSSSecretKey(algorithm, secretkey), CROSSPublicKey(algorithm, publickey) # type: ignore
480
+ if secretkey is not None and publickey is None:
481
+ return CROSSSecretKey(algorithm, secretkey)
482
+ elif publickey is not None and secretkey is None:
483
+ return CROSSPublicKey(algorithm, publickey)
484
+ elif secretkey is not None and publickey is not None:
485
+ return CROSSSecretKey(algorithm, secretkey), CROSSPublicKey(algorithm, publickey)
486
+ else:
487
+ secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
488
+ return CROSSSecretKey(algorithm, secretkey), CROSSPublicKey(algorithm, publickey) # type: ignore
479
489
  elif isinstance(algorithm, Algorithm.DILITHIUM):
480
- secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
481
- return DILITHIUMSecretKey(algorithm, secretkey), DILITHIUMPublicKey(algorithm, publickey) # type: ignore
490
+ if secretkey is not None and publickey is None:
491
+ return DILITHIUMSecretKey(algorithm, secretkey)
492
+ elif publickey is not None and secretkey is None:
493
+ return DILITHIUMPublicKey(algorithm, publickey)
494
+ elif secretkey is not None and publickey is not None:
495
+ return DILITHIUMSecretKey(algorithm, secretkey), DILITHIUMPublicKey(algorithm, publickey)
496
+ else:
497
+ secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
498
+ return DILITHIUMSecretKey(algorithm, secretkey), DILITHIUMPublicKey(algorithm, publickey) # type: ignore
482
499
  elif isinstance(algorithm, Algorithm.FALCON):
483
- secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
484
- return FALCONSecretKey(algorithm, secretkey), FALCONPublicKey(algorithm, publickey) # type: ignore
500
+ if secretkey is not None and publickey is None:
501
+ return FALCONSecretKey(algorithm, secretkey)
502
+ elif publickey is not None and secretkey is None:
503
+ return FALCONPublicKey(algorithm, publickey)
504
+ elif secretkey is not None and publickey is not None:
505
+ return FALCONSecretKey(algorithm, secretkey), FALCONPublicKey(algorithm, publickey)
506
+ else:
507
+ secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
508
+ return FALCONSecretKey(algorithm, secretkey), FALCONPublicKey(algorithm, publickey) # type: ignore
485
509
  elif isinstance(algorithm, Algorithm.MAYO):
486
- secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
487
- return MAYOSecretKey(algorithm, secretkey), MAYOPublicKey(algorithm, publickey) # type: ignore
510
+ if secretkey is not None and publickey is None:
511
+ return MAYOSecretKey(algorithm, secretkey)
512
+ elif publickey is not None and secretkey is None:
513
+ return MAYOPublicKey(algorithm, publickey)
514
+ elif secretkey is not None and publickey is not None:
515
+ return MAYOSecretKey(algorithm, secretkey), MAYOPublicKey(algorithm, publickey)
516
+ else:
517
+ secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
518
+ return MAYOSecretKey(algorithm, secretkey), MAYOPublicKey(algorithm, publickey) # type: ignore
488
519
  elif isinstance(algorithm, Algorithm.MLDSA):
489
- secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
490
- return MLDSASecretKey(algorithm, secretkey), MLDSAPublicKey(algorithm, publickey) # type: ignore
520
+ if secretkey is not None and publickey is None:
521
+ return MLDSASecretKey(algorithm, secretkey)
522
+ elif publickey is not None and secretkey is None:
523
+ return MLDSAPublicKey(algorithm, publickey)
524
+ elif secretkey is not None and publickey is not None:
525
+ return MLDSASecretKey(algorithm, secretkey), MLDSAPublicKey(algorithm, publickey)
526
+ else:
527
+ secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
528
+ return MLDSASecretKey(algorithm, secretkey), MLDSAPublicKey(algorithm, publickey) # type: ignore
491
529
  elif isinstance(algorithm, Algorithm.SPHINCS):
492
- secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
493
- return SPHINCSSecretKey(algorithm, secretkey), SPHINCSPublicKey(algorithm, publickey) # type: ignore
530
+ if secretkey is not None and publickey is None:
531
+ return SPHINCSSecretKey(algorithm, secretkey)
532
+ elif publickey is not None and secretkey is None:
533
+ return SPHINCSPublicKey(algorithm, publickey)
534
+ elif secretkey is not None and publickey is not None:
535
+ return SPHINCSSecretKey(algorithm, secretkey), SPHINCSPublicKey(algorithm, publickey)
536
+ else:
537
+ secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
538
+ return SPHINCSSecretKey(algorithm, secretkey), SPHINCSPublicKey(algorithm, publickey) # type: ignore
494
539
  elif isinstance(algorithm, Algorithm.UOV):
495
- secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
496
- return UOVSecretKey(algorithm, secretkey), UOVPublicKey(algorithm, publickey) # type: ignore
540
+ if secretkey is not None and publickey is None:
541
+ return UOVSecretKey(algorithm, secretkey)
542
+ elif publickey is not None and secretkey is None:
543
+ return UOVPublicKey(algorithm, publickey)
544
+ elif secretkey is not None and publickey is not None:
545
+ return UOVSecretKey(algorithm, secretkey), UOVPublicKey(algorithm, publickey)
546
+ else:
547
+ secretkey, publickey = _internal.sigkeygen(algorithm.value) # type: ignore
548
+ return UOVSecretKey(algorithm, secretkey), UOVPublicKey(algorithm, publickey) # type: ignore
497
549
  else:
498
550
  raise ValueError(f"Unsupported algorithm: {name}")