puantum 1.0.1__tar.gz → 1.2.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.
@@ -1,3 +1,5 @@
1
- Cargo.lock
2
- .env
1
+ # dir
3
2
  target/
3
+
4
+ # file
5
+ Cargo.lock
@@ -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-1.2.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,17 +1,19 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: puantum
3
- Version: 1.0.1
3
+ Version: 1.2.3
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Operating System :: OS Independent
7
7
  Classifier: License :: Public Domain
8
8
  Classifier: License :: OSI Approved :: The Unlicense (Unlicense)
9
+ License-File: license.md
9
10
  Summary: Python Cryptography
10
11
  Keywords: python,cryptography,quantum,security
11
- Author-email: Anonymous <no@thanks.com>
12
+ Author-email: Anonymous <217687495+1xfakebit@users.noreply.github.com>
12
13
  License: Unlicense
13
14
  Description-Content-Type: text/markdown
14
- Project-URL: Source, https://github.com/0xf4ck/puantum
15
+ Project-URL: source, https://github.com/1xfakebit/puantum
16
+ Project-URL: x, https://x.com/1xfakebit
15
17
 
16
18
  # 🔐 Python Cryptography
17
19
 
@@ -0,0 +1,14 @@
1
+ # IMPORT
2
+ from puantum.quantum.dsa import Algorithm, KeyPair
3
+
4
+ # MAIN
5
+ alicesk, alicepk = KeyPair(Algorithm.MLDSA.MLDSA87)
6
+ message = "Hello".encode()
7
+
8
+ signature = alicesk.sign(message=message)
9
+ valid = alicepk.verify(signature=signature, message=message)
10
+
11
+ assert valid, "Signature verification failed!"
12
+
13
+ print(f"Message: [{message.decode()}]")
14
+ print(f"Signature: [{signature.hex()[:len(message)]}]")
@@ -0,0 +1,14 @@
1
+ # IMPORT
2
+ from puantum.quantum.kem import Algorithm, KeyPair
3
+
4
+ # MAIN
5
+ alicesk, alicepk = KeyPair(Algorithm.MLKEM.MLKEM1024)
6
+ _bobsk, _bobpk = KeyPair(Algorithm.MLKEM.MLKEM1024)
7
+
8
+ bobss, bobct = alicepk.encapsulate()
9
+ alicess = alicesk.decapsulate(bobct)
10
+
11
+ assert alicess == bobss, "Shared secrets do not match!"
12
+
13
+ print(f"Alice's Shared Secret: [{alicess.hex()}]")
14
+ print(f"Bob's Shared Secret: [{bobss.hex()}]")
@@ -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}")
@@ -50,182 +50,6 @@ class Algorithm:
50
50
 
51
51
 
52
52
 
53
- class Ciphertext:
54
- def __init__(self, ciphertext: bytes) -> None:
55
- if not isinstance(ciphertext, bytes):
56
- raise TypeError("Ciphertext Not Valid")
57
- #
58
- self.ciphertext = ciphertext
59
- #
60
- return None
61
-
62
-
63
-
64
- class BIKECiphertext(Ciphertext):
65
- def __init__(self, name: Algorithm.BIKE, ciphertext: bytes) -> None:
66
- if not isinstance(name, Algorithm.BIKE):
67
- raise ValueError(f"Unsupported algorithm: {name}")
68
- else:
69
- super().__init__(ciphertext)
70
- #
71
- return None
72
-
73
-
74
-
75
- class CLASSICMCELIECECiphertext(Ciphertext):
76
- def __init__(self, name: Algorithm.CLASSICMCELIECE, ciphertext: bytes) -> None:
77
- if not isinstance(name, Algorithm.CLASSICMCELIECE):
78
- raise ValueError(f"Unsupported algorithm: {name}")
79
- else:
80
- super().__init__(ciphertext)
81
- #
82
- return None
83
-
84
-
85
-
86
- class HQCCiphertext(Ciphertext):
87
- def __init__(self, name: Algorithm.HQC, ciphertext: bytes) -> None:
88
- if not isinstance(name, Algorithm.HQC):
89
- raise ValueError(f"Unsupported algorithm: {name}")
90
- else:
91
- super().__init__(ciphertext)
92
- #
93
- return None
94
-
95
-
96
-
97
- class KYBERCiphertext(Ciphertext):
98
- def __init__(self, name: Algorithm.KYBER, ciphertext: bytes) -> None:
99
- if not isinstance(name, Algorithm.KYBER):
100
- raise ValueError(f"Unsupported algorithm: {name}")
101
- else:
102
- super().__init__(ciphertext)
103
- #
104
- return None
105
-
106
-
107
-
108
- class MLKEMCiphertext(Ciphertext):
109
- def __init__(self, name: Algorithm.MLKEM, ciphertext: bytes) -> None:
110
- if not isinstance(name, Algorithm.MLKEM):
111
- raise ValueError(f"Unsupported algorithm: {name}")
112
- else:
113
- super().__init__(ciphertext)
114
- #
115
- return None
116
-
117
-
118
-
119
- class NTRUPRIMECiphertext(Ciphertext):
120
- def __init__(self, name: Algorithm.NTRUPRIME, ciphertext: bytes) -> None:
121
- if not isinstance(name, Algorithm.NTRUPRIME):
122
- raise ValueError(f"Unsupported algorithm: {name}")
123
- else:
124
- super().__init__(ciphertext)
125
- #
126
- return None
127
-
128
-
129
-
130
- class FRODOKEMCiphertext(Ciphertext):
131
- def __init__(self, name: Algorithm.FRODOKEM, ciphertext: bytes) -> None:
132
- if not isinstance(name, Algorithm.FRODOKEM):
133
- raise ValueError(f"Unsupported algorithm: {name}")
134
- else:
135
- super().__init__(ciphertext)
136
- #
137
- return None
138
-
139
-
140
-
141
- class SharedSecret:
142
- def __init__(self, sharedsecret: bytes) -> None:
143
- if not isinstance(sharedsecret, bytes):
144
- raise TypeError("SharedSecret Not Valid")
145
- #
146
- self.sharedsecret = sharedsecret
147
- #
148
- return None
149
-
150
-
151
-
152
- class BIKESharedSecret(SharedSecret):
153
- def __init__(self, name: Algorithm.BIKE, sharedsecret: bytes) -> None:
154
- if not isinstance(name, Algorithm.BIKE):
155
- raise ValueError(f"Unsupported algorithm: {name}")
156
- else:
157
- super().__init__(sharedsecret)
158
- #
159
- return None
160
-
161
-
162
-
163
- class CLASSICMCELIECESharedSecret(SharedSecret):
164
- def __init__(self, name: Algorithm.CLASSICMCELIECE, sharedsecret: bytes) -> None:
165
- if not isinstance(name, Algorithm.CLASSICMCELIECE):
166
- raise ValueError(f"Unsupported algorithm: {name}")
167
- else:
168
- super().__init__(sharedsecret)
169
- #
170
- return None
171
-
172
-
173
-
174
- class HQCSharedSecret(SharedSecret):
175
- def __init__(self, name: Algorithm.HQC, sharedsecret: bytes) -> None:
176
- if not isinstance(name, Algorithm.HQC):
177
- raise ValueError(f"Unsupported algorithm: {name}")
178
- else:
179
- super().__init__(sharedsecret)
180
- #
181
- return None
182
-
183
-
184
-
185
- class KYBERSharedSecret(SharedSecret):
186
- def __init__(self, name: Algorithm.KYBER, sharedsecret: bytes) -> None:
187
- if not isinstance(name, Algorithm.KYBER):
188
- raise ValueError(f"Unsupported algorithm: {name}")
189
- else:
190
- super().__init__(sharedsecret)
191
- #
192
- return None
193
-
194
-
195
-
196
- class MLKEMSharedSecret(SharedSecret):
197
- def __init__(self, name: Algorithm.MLKEM, sharedsecret: bytes) -> None:
198
- if not isinstance(name, Algorithm.MLKEM):
199
- raise ValueError(f"Unsupported algorithm: {name}")
200
- else:
201
- super().__init__(sharedsecret)
202
- #
203
- return None
204
-
205
-
206
-
207
- class NTRUPRIMESharedSecret(SharedSecret):
208
- def __init__(self, name: Algorithm.NTRUPRIME, sharedsecret: bytes) -> None:
209
- if not isinstance(name, Algorithm.NTRUPRIME):
210
- raise ValueError(f"Unsupported algorithm: {name}")
211
- else:
212
- super().__init__(sharedsecret)
213
- #
214
- return None
215
-
216
-
217
-
218
- class FRODOKEMSharedSecret(SharedSecret):
219
- def __init__(self, name: Algorithm.FRODOKEM, sharedsecret: bytes) -> None:
220
- if not isinstance(name, Algorithm.FRODOKEM):
221
- raise ValueError(f"Unsupported algorithm: {name}")
222
- else:
223
- super().__init__(sharedsecret)
224
- #
225
- return None
226
-
227
-
228
-
229
53
  class PublicKey:
230
54
  def __init__(self, publickey: bytes) -> None:
231
55
  if not isinstance(publickey, bytes):
@@ -251,9 +75,9 @@ class BIKEPublicKey(PublicKey):
251
75
  #
252
76
  return None
253
77
  #
254
- def encapsulate(self) -> tuple[BIKESharedSecret, BIKECiphertext]:
78
+ def encapsulate(self) -> tuple[bytes, bytes]:
255
79
  sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
256
- return BIKESharedSecret(self._algorithm, sharedsecret), BIKECiphertext(self._algorithm, ciphertext) # type: ignore
80
+ return sharedsecret, ciphertext # type: ignore
257
81
 
258
82
 
259
83
 
@@ -268,9 +92,9 @@ class CLASSICMCELIECEPublicKey(PublicKey):
268
92
  #
269
93
  return None
270
94
  #
271
- def encapsulate(self) -> tuple[CLASSICMCELIECESharedSecret, CLASSICMCELIECECiphertext]:
95
+ def encapsulate(self) -> tuple[bytes, bytes]:
272
96
  sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
273
- return CLASSICMCELIECESharedSecret(self._algorithm, sharedsecret), CLASSICMCELIECECiphertext(self._algorithm, ciphertext) # type: ignore
97
+ return sharedsecret, ciphertext # type: ignore
274
98
 
275
99
 
276
100
 
@@ -285,9 +109,9 @@ class HQCPublicKey(PublicKey):
285
109
  #
286
110
  return None
287
111
  #
288
- def encapsulate(self) -> tuple[HQCSharedSecret, HQCCiphertext]:
112
+ def encapsulate(self) -> tuple[bytes, bytes]:
289
113
  sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
290
- return HQCSharedSecret(self._algorithm, sharedsecret), HQCCiphertext(self._algorithm, ciphertext) # type: ignore
114
+ return sharedsecret, ciphertext # type: ignore
291
115
 
292
116
 
293
117
 
@@ -302,9 +126,9 @@ class KYBERPublicKey(PublicKey):
302
126
  #
303
127
  return None
304
128
  #
305
- def encapsulate(self) -> tuple[KYBERSharedSecret, KYBERCiphertext]:
129
+ def encapsulate(self) -> tuple[bytes, bytes]:
306
130
  sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
307
- return KYBERSharedSecret(self._algorithm, sharedsecret), KYBERCiphertext(self._algorithm, ciphertext) # type: ignore
131
+ return sharedsecret, ciphertext # type: ignore
308
132
 
309
133
 
310
134
 
@@ -319,9 +143,9 @@ class MLKEMPublicKey(PublicKey):
319
143
  #
320
144
  return None
321
145
  #
322
- def encapsulate(self) -> tuple[MLKEMSharedSecret, MLKEMCiphertext]:
146
+ def encapsulate(self) -> tuple[bytes, bytes]:
323
147
  sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
324
- return MLKEMSharedSecret(self._algorithm, sharedsecret), MLKEMCiphertext(self._algorithm, ciphertext) # type: ignore
148
+ return sharedsecret, ciphertext # type: ignore
325
149
 
326
150
 
327
151
 
@@ -336,9 +160,9 @@ class NTRUPRIMEPublicKey(PublicKey):
336
160
  #
337
161
  return None
338
162
  #
339
- def encapsulate(self) -> tuple[NTRUPRIMESharedSecret, NTRUPRIMECiphertext]:
163
+ def encapsulate(self) -> tuple[bytes, bytes]:
340
164
  sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
341
- return NTRUPRIMESharedSecret(self._algorithm, sharedsecret), NTRUPRIMECiphertext(self._algorithm, ciphertext) # type: ignore
165
+ return sharedsecret, ciphertext # type: ignore
342
166
 
343
167
 
344
168
 
@@ -353,9 +177,9 @@ class FRODOKEMPublicKey(PublicKey):
353
177
  #
354
178
  return None
355
179
  #
356
- def encapsulate(self) -> tuple[FRODOKEMSharedSecret, FRODOKEMCiphertext]:
180
+ def encapsulate(self) -> tuple[bytes, bytes]:
357
181
  sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
358
- return FRODOKEMSharedSecret(self._algorithm, sharedsecret), FRODOKEMCiphertext(self._algorithm, ciphertext) # type: ignore
182
+ return sharedsecret, ciphertext # type: ignore
359
183
 
360
184
 
361
185
 
@@ -384,9 +208,9 @@ class BIKESecretKey(SecretKey):
384
208
  #
385
209
  return None
386
210
  #
387
- def decapsulate(self, ciphertext: BIKECiphertext) -> BIKESharedSecret:
388
- sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext.ciphertext) # type: ignore
389
- return BIKESharedSecret(self._algorithm, sharedsecret) # type: ignore
211
+ def decapsulate(self, ciphertext: bytes) -> bytes:
212
+ sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext) # type: ignore
213
+ return sharedsecret # type: ignore
390
214
 
391
215
 
392
216
 
@@ -401,9 +225,9 @@ class CLASSICMCELIECESecretKey(SecretKey):
401
225
  #
402
226
  return None
403
227
  #
404
- def decapsulate(self, ciphertext: CLASSICMCELIECECiphertext) -> CLASSICMCELIECESharedSecret:
405
- sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext.ciphertext) # type: ignore
406
- return CLASSICMCELIECESharedSecret(self._algorithm, sharedsecret) # type: ignore
228
+ def decapsulate(self, ciphertext: bytes) -> bytes:
229
+ sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext) # type: ignore
230
+ return sharedsecret # type: ignore
407
231
 
408
232
 
409
233
 
@@ -418,9 +242,9 @@ class HQCSecretKey(SecretKey):
418
242
  #
419
243
  return None
420
244
  #
421
- def decapsulate(self, ciphertext: HQCCiphertext) -> HQCSharedSecret:
422
- sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext.ciphertext) # type: ignore
423
- return HQCSharedSecret(self._algorithm, sharedsecret) # type: ignore
245
+ def decapsulate(self, ciphertext: bytes) -> bytes:
246
+ sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext) # type: ignore
247
+ return sharedsecret # type: ignore
424
248
 
425
249
 
426
250
 
@@ -435,9 +259,9 @@ class KYBERSecretKey(SecretKey):
435
259
  #
436
260
  return None
437
261
  #
438
- def decapsulate(self, ciphertext: KYBERCiphertext) -> KYBERSharedSecret:
439
- sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext.ciphertext) # type: ignore
440
- return KYBERSharedSecret(self._algorithm, sharedsecret) # type: ignore
262
+ def decapsulate(self, ciphertext: bytes) -> bytes:
263
+ sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext) # type: ignore
264
+ return sharedsecret # type: ignore
441
265
 
442
266
 
443
267
 
@@ -452,9 +276,9 @@ class MLKEMSecretKey(SecretKey):
452
276
  #
453
277
  return None
454
278
  #
455
- def decapsulate(self, ciphertext: MLKEMCiphertext) -> MLKEMSharedSecret:
456
- sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext.ciphertext) # type: ignore
457
- return MLKEMSharedSecret(self._algorithm, sharedsecret) # type: ignore
279
+ def decapsulate(self, ciphertext: bytes) -> bytes:
280
+ sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext) # type: ignore
281
+ return sharedsecret # type: ignore
458
282
 
459
283
 
460
284
 
@@ -469,9 +293,9 @@ class NTRUPRIMESecretKey(SecretKey):
469
293
  #
470
294
  return None
471
295
  #
472
- def decapsulate(self, ciphertext: NTRUPRIMECiphertext) -> NTRUPRIMESharedSecret:
473
- sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext.ciphertext) # type: ignore
474
- return NTRUPRIMESharedSecret(self._algorithm, sharedsecret) # type: ignore
296
+ def decapsulate(self, ciphertext: bytes) -> bytes:
297
+ sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext) # type: ignore
298
+ return sharedsecret # type: ignore
475
299
 
476
300
 
477
301
 
@@ -486,78 +310,217 @@ class FRODOKEMSecretKey(SecretKey):
486
310
  #
487
311
  return None
488
312
  #
489
- def decapsulate(self, ciphertext: FRODOKEMCiphertext) -> FRODOKEMSharedSecret:
490
- sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext.ciphertext) # type: ignore
491
- return FRODOKEMSharedSecret(self._algorithm, sharedsecret) # type: ignore
492
-
493
-
494
-
495
- Algorithms = Algorithm | Algorithm.BIKE | Algorithm.CLASSICMCELIECE | Algorithm.HQC | Algorithm.KYBER | Algorithm.MLKEM | Algorithm.NTRUPRIME | Algorithm.FRODOKEM
313
+ def decapsulate(self, ciphertext: bytes) -> bytes:
314
+ sharedsecret: bytes = _internal.kemdecapsulate(self._algorithm.value, self.secretkey, ciphertext) # type: ignore
315
+ return sharedsecret # type: ignore
496
316
 
497
317
 
498
318
 
319
+ @_typing.overload
320
+ def KeyPair(
321
+ name: Algorithm,
322
+ *,
323
+ secretkey: bytes,
324
+ publickey: bytes
325
+ ) -> tuple[SecretKey, PublicKey]: ...
326
+ @_typing.overload
327
+ def KeyPair(name: Algorithm, *, secretkey: bytes) -> SecretKey: ...
328
+ @_typing.overload
329
+ def KeyPair(name: Algorithm, *, publickey: bytes) -> PublicKey: ...
499
330
  @_typing.overload
500
331
  def KeyPair(name: Algorithm) -> tuple[SecretKey, PublicKey]: ...
501
332
 
502
333
 
503
334
 
335
+ @_typing.overload
336
+ def KeyPair(
337
+ name: Algorithm.BIKE,
338
+ *,
339
+ secretkey: bytes,
340
+ publickey: bytes
341
+ ) -> tuple[BIKESecretKey, BIKEPublicKey]: ...
342
+ @_typing.overload
343
+ def KeyPair(name: Algorithm.BIKE, *, secretkey: bytes) -> BIKESecretKey: ...
344
+ @_typing.overload
345
+ def KeyPair(name: Algorithm.BIKE, *, publickey: bytes) -> BIKEPublicKey: ...
504
346
  @_typing.overload
505
347
  def KeyPair(name: Algorithm.BIKE) -> tuple[BIKESecretKey, BIKEPublicKey]: ...
506
348
 
507
349
 
508
350
 
351
+ @_typing.overload
352
+ def KeyPair(
353
+ name: Algorithm.CLASSICMCELIECE,
354
+ *,
355
+ secretkey: bytes,
356
+ publickey: bytes
357
+ ) -> tuple[CLASSICMCELIECESecretKey, CLASSICMCELIECEPublicKey]: ...
358
+ @_typing.overload
359
+ def KeyPair(name: Algorithm.CLASSICMCELIECE, *, secretkey: bytes) -> CLASSICMCELIECESecretKey: ...
360
+ @_typing.overload
361
+ def KeyPair(name: Algorithm.CLASSICMCELIECE, *, publickey: bytes) -> CLASSICMCELIECEPublicKey: ...
509
362
  @_typing.overload
510
363
  def KeyPair(name: Algorithm.CLASSICMCELIECE) -> tuple[CLASSICMCELIECESecretKey, CLASSICMCELIECEPublicKey]: ...
511
364
 
512
365
 
513
366
 
367
+ @_typing.overload
368
+ def KeyPair(
369
+ name: Algorithm.HQC,
370
+ *,
371
+ secretkey: bytes,
372
+ publickey: bytes
373
+ ) -> tuple[HQCSecretKey, HQCPublicKey]: ...
374
+ @_typing.overload
375
+ def KeyPair(name: Algorithm.HQC, *, secretkey: bytes) -> HQCSecretKey: ...
376
+ @_typing.overload
377
+ def KeyPair(name: Algorithm.HQC, *, publickey: bytes) -> HQCPublicKey: ...
514
378
  @_typing.overload
515
379
  def KeyPair(name: Algorithm.HQC) -> tuple[HQCSecretKey, HQCPublicKey]: ...
516
380
 
517
381
 
518
382
 
383
+ @_typing.overload
384
+ def KeyPair(
385
+ name: Algorithm.KYBER,
386
+ *,
387
+ secretkey: bytes,
388
+ publickey: bytes
389
+ ) -> tuple[KYBERSecretKey, KYBERPublicKey]: ...
390
+ @_typing.overload
391
+ def KeyPair(name: Algorithm.KYBER, *, secretkey: bytes) -> KYBERSecretKey: ...
392
+ @_typing.overload
393
+ def KeyPair(name: Algorithm.KYBER, *, publickey: bytes) -> KYBERPublicKey: ...
519
394
  @_typing.overload
520
395
  def KeyPair(name: Algorithm.KYBER) -> tuple[KYBERSecretKey, KYBERPublicKey]: ...
521
396
 
522
397
 
523
398
 
399
+ @_typing.overload
400
+ def KeyPair(
401
+ name: Algorithm.MLKEM,
402
+ *,
403
+ secretkey: bytes,
404
+ publickey: bytes
405
+ ) -> tuple[MLKEMSecretKey, MLKEMPublicKey]: ...
406
+ @_typing.overload
407
+ def KeyPair(name: Algorithm.MLKEM, *, secretkey: bytes) -> MLKEMSecretKey: ...
408
+ @_typing.overload
409
+ def KeyPair(name: Algorithm.MLKEM, *, publickey: bytes) -> MLKEMPublicKey: ...
524
410
  @_typing.overload
525
411
  def KeyPair(name: Algorithm.MLKEM) -> tuple[MLKEMSecretKey, MLKEMPublicKey]: ...
526
412
 
527
413
 
528
414
 
415
+ @_typing.overload
416
+ def KeyPair(
417
+ name: Algorithm.NTRUPRIME,
418
+ *,
419
+ secretkey: bytes,
420
+ publickey: bytes
421
+ ) -> tuple[NTRUPRIMESecretKey, NTRUPRIMEPublicKey]: ...
422
+ @_typing.overload
423
+ def KeyPair(name: Algorithm.NTRUPRIME, *, secretkey: bytes) -> NTRUPRIMESecretKey: ...
424
+ @_typing.overload
425
+ def KeyPair(name: Algorithm.NTRUPRIME, *, publickey: bytes) -> NTRUPRIMEPublicKey: ...
529
426
  @_typing.overload
530
427
  def KeyPair(name: Algorithm.NTRUPRIME) -> tuple[NTRUPRIMESecretKey, NTRUPRIMEPublicKey]: ...
531
428
 
532
429
 
533
430
 
431
+ @_typing.overload
432
+ def KeyPair(
433
+ name: Algorithm.FRODOKEM,
434
+ *,
435
+ secretkey: bytes,
436
+ publickey: bytes
437
+ ) -> tuple[FRODOKEMSecretKey, FRODOKEMPublicKey]: ...
438
+ @_typing.overload
439
+ def KeyPair(name: Algorithm.FRODOKEM, *, secretkey: bytes) -> FRODOKEMSecretKey: ...
440
+ @_typing.overload
441
+ def KeyPair(name: Algorithm.FRODOKEM, *, publickey: bytes) -> FRODOKEMPublicKey: ...
534
442
  @_typing.overload
535
443
  def KeyPair(name: Algorithm.FRODOKEM) -> tuple[FRODOKEMSecretKey, FRODOKEMPublicKey]: ...
536
444
 
537
445
 
538
446
 
539
- def KeyPair(name: Algorithms) -> tuple[SecretKey, PublicKey]:
447
+ Algorithms = Algorithm.BIKE | Algorithm.CLASSICMCELIECE | Algorithm.HQC | Algorithm.KYBER | Algorithm.MLKEM | Algorithm.NTRUPRIME | Algorithm.FRODOKEM
448
+ def KeyPair(
449
+ name: Algorithm | Algorithms,
450
+ *,
451
+ secretkey: bytes | None = None,
452
+ publickey: bytes | None = None
453
+ ) -> tuple[SecretKey, PublicKey] | SecretKey | PublicKey:
540
454
  algorithm = name
541
455
  if isinstance(algorithm, Algorithm.BIKE):
542
- secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
543
- return BIKESecretKey(algorithm, secretkey), BIKEPublicKey(algorithm, publickey) # type: ignore
456
+ if secretkey is not None and publickey is None:
457
+ return BIKESecretKey(algorithm, secretkey)
458
+ elif publickey is not None and secretkey is None:
459
+ return BIKEPublicKey(algorithm, publickey)
460
+ elif secretkey is not None and publickey is not None:
461
+ return BIKESecretKey(algorithm, secretkey), BIKEPublicKey(algorithm, publickey)
462
+ else:
463
+ secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
464
+ return BIKESecretKey(algorithm, secretkey), BIKEPublicKey(algorithm, publickey) # type: ignore
544
465
  elif isinstance(algorithm, Algorithm.CLASSICMCELIECE):
545
- secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
546
- return CLASSICMCELIECESecretKey(algorithm, secretkey), CLASSICMCELIECEPublicKey(algorithm, publickey) # type: ignore
466
+ if secretkey is not None and publickey is None:
467
+ return CLASSICMCELIECESecretKey(algorithm, secretkey)
468
+ elif publickey is not None and secretkey is None:
469
+ return CLASSICMCELIECEPublicKey(algorithm, publickey)
470
+ elif secretkey is not None and publickey is not None:
471
+ return CLASSICMCELIECESecretKey(algorithm, secretkey), CLASSICMCELIECEPublicKey(algorithm, publickey)
472
+ else:
473
+ secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
474
+ return CLASSICMCELIECESecretKey(algorithm, secretkey), CLASSICMCELIECEPublicKey(algorithm, publickey) # type: ignore
547
475
  elif isinstance(algorithm, Algorithm.HQC):
548
- secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
549
- return HQCSecretKey(algorithm, secretkey), HQCPublicKey(algorithm, publickey) # type: ignore
476
+ if secretkey is not None and publickey is None:
477
+ return HQCSecretKey(algorithm, secretkey)
478
+ elif publickey is not None and secretkey is None:
479
+ return HQCPublicKey(algorithm, publickey)
480
+ elif secretkey is not None and publickey is not None:
481
+ return HQCSecretKey(algorithm, secretkey), HQCPublicKey(algorithm, publickey)
482
+ else:
483
+ secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
484
+ return HQCSecretKey(algorithm, secretkey), HQCPublicKey(algorithm, publickey) # type: ignore
550
485
  elif isinstance(algorithm, Algorithm.KYBER):
551
- secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
552
- return KYBERSecretKey(algorithm, secretkey), KYBERPublicKey(algorithm, publickey) # type: ignore
486
+ if secretkey is not None and publickey is None:
487
+ return KYBERSecretKey(algorithm, secretkey)
488
+ elif publickey is not None and secretkey is None:
489
+ return KYBERPublicKey(algorithm, publickey)
490
+ elif secretkey is not None and publickey is not None:
491
+ return KYBERSecretKey(algorithm, secretkey), KYBERPublicKey(algorithm, publickey)
492
+ else:
493
+ secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
494
+ return KYBERSecretKey(algorithm, secretkey), KYBERPublicKey(algorithm, publickey) # type: ignore
553
495
  elif isinstance(algorithm, Algorithm.MLKEM):
554
- secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
555
- return MLKEMSecretKey(algorithm, secretkey), MLKEMPublicKey(algorithm, publickey) # type: ignore
496
+ if secretkey is not None and publickey is None:
497
+ return MLKEMSecretKey(algorithm, secretkey)
498
+ elif publickey is not None and secretkey is None:
499
+ return MLKEMPublicKey(algorithm, publickey)
500
+ elif secretkey is not None and publickey is not None:
501
+ return MLKEMSecretKey(algorithm, secretkey), MLKEMPublicKey(algorithm, publickey)
502
+ else:
503
+ secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
504
+ return MLKEMSecretKey(algorithm, secretkey), MLKEMPublicKey(algorithm, publickey) # type: ignore
556
505
  elif isinstance(algorithm, Algorithm.NTRUPRIME):
557
- secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
558
- return NTRUPRIMESecretKey(algorithm, secretkey), NTRUPRIMEPublicKey(algorithm, publickey) # type: ignore
506
+ if secretkey is not None and publickey is None:
507
+ return NTRUPRIMESecretKey(algorithm, secretkey)
508
+ elif publickey is not None and secretkey is None:
509
+ return NTRUPRIMEPublicKey(algorithm, publickey)
510
+ elif secretkey is not None and publickey is not None:
511
+ return NTRUPRIMESecretKey(algorithm, secretkey), NTRUPRIMEPublicKey(algorithm, publickey)
512
+ else:
513
+ secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
514
+ return NTRUPRIMESecretKey(algorithm, secretkey), NTRUPRIMEPublicKey(algorithm, publickey) # type: ignore
559
515
  elif isinstance(algorithm, Algorithm.FRODOKEM):
560
- secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
561
- return FRODOKEMSecretKey(algorithm, secretkey), FRODOKEMPublicKey(algorithm, publickey) # type: ignore
516
+ if secretkey is not None and publickey is None:
517
+ return FRODOKEMSecretKey(algorithm, secretkey)
518
+ elif publickey is not None and secretkey is None:
519
+ return FRODOKEMPublicKey(algorithm, publickey)
520
+ elif secretkey is not None and publickey is not None:
521
+ return FRODOKEMSecretKey(algorithm, secretkey), FRODOKEMPublicKey(algorithm, publickey)
522
+ else:
523
+ secretkey, publickey = _internal.kemkeygen(algorithm.value) # type: ignore
524
+ return FRODOKEMSecretKey(algorithm, secretkey), FRODOKEMPublicKey(algorithm, publickey) # type: ignore
562
525
  else:
563
526
  raise ValueError(f"Unsupported algorithm: {name}")
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "puantum"
3
- version = "1.0.1"
4
- authors = [{ name = "Anonymous", email = "no@thanks.com" }]
3
+ version = "1.2.3"
4
+ authors = [{name = "Anonymous", email = "217687495+1xfakebit@users.noreply.github.com"}]
5
5
  description = "Python Cryptography"
6
6
  readme = {file = "readme.md", content-type = "text/markdown"}
7
7
  license = "Unlicense"
8
- license-files = ["license"]
8
+ license-files = ["license.md"]
9
9
  keywords = ["python", "cryptography", "quantum", "security"]
10
10
 
11
11
  classifiers = [
@@ -17,7 +17,8 @@ classifiers = [
17
17
  ]
18
18
 
19
19
  [project.urls]
20
- Source = "https://github.com/0xf4ck/puantum"
20
+ source = "https://github.com/1xfakebit/puantum"
21
+ x = "https://x.com/1xfakebit"
21
22
 
22
23
  [build-system]
23
24
  requires = ["maturin>=1.0,<2.0"]
@@ -0,0 +1,48 @@
1
+ # 🔐 Python Cryptography
2
+
3
+ A blazing-fast cryptography library for Python, built on Rust.
4
+
5
+ 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.
6
+
7
+ ---
8
+ ## ⚡ Features
9
+ - ✅ Dozens of NIST PQC candidates
10
+ - 🦀 Rust core for speed and safety
11
+ - 📦 Easy installation via [`pip`](https://pip.pypa.io)
12
+ ---
13
+
14
+ ### 🧬 Supported Algorithms
15
+
16
+ ### 🛡️ KEM
17
+ - #### Bike
18
+ - #### ClassicMcEliece
19
+ - #### Hqc
20
+ - #### Kyber
21
+ - #### MLKEM
22
+ - #### NtruPrime
23
+ - #### FrodoKem
24
+
25
+ ### ✍️ DSA
26
+ - #### Cross
27
+ - #### Dilithium
28
+ - #### Falcon
29
+ - #### Mayo
30
+ - #### MLDSA
31
+ - #### Sphincs
32
+ - #### Uov
33
+
34
+ ### 🚧 Coming Soon
35
+ - #### AES, ChaCha20, XChaCha20
36
+ - #### RSA, EC
37
+ - #### Argon2, Bcrypt
38
+
39
+ ### 📦 Install
40
+ ```shell
41
+ pip install puantum
42
+ ```
43
+ #### or from source:
44
+ ```shell
45
+ make python
46
+ ```
47
+
48
+ ### 🥳 Enjoy!
puantum-1.0.1/Makefile DELETED
@@ -1,7 +0,0 @@
1
- # Makefile
2
- release:
3
- cargo clean
4
- cargo build --release
5
-
6
- python:
7
- maturin build --release
@@ -1,23 +0,0 @@
1
- # IMPORT
2
- from puantum.quantum.dsa import Algorithm, KeyPair
3
-
4
- # MAIN
5
- def main():
6
- # Step 1: Generate a digital signature key pair for Alice
7
- # - alicesk: Alice's private signing key
8
- # - alicepk: Alice's public key (used for verification)
9
- alicesk, alicepk = KeyPair(Algorithm.MLDSA.MLDSA87)
10
- # Step 2: Define the message to be signed
11
- msg = "Hello".encode() # Convert the string to bytes, as cryptographic functions work with bytes
12
- # Step 3: Sign the message using Alice's private key
13
- sig = alicesk.sign(msg)
14
- # Step 4: Verify the signature using Alice's public key
15
- valid = alicepk.verify(sig, msg)
16
- # Step 5: Display the result
17
- print(f"Message : {msg.decode()}")
18
- print(f"Signature valid? : {valid}")
19
- # Optional: raise an error if the signature fails (useful in tests)
20
- assert valid, "Signature verification failed!"
21
-
22
- if __name__ == "__main__":
23
- main()
@@ -1,21 +0,0 @@
1
- # IMPORT
2
- from puantum.quantum.kem import Algorithm, KeyPair
3
-
4
- # MAIN
5
- def main():
6
- # Generate Alice's KEM keypair (secret and public keys)
7
- alicesk, alicepk = KeyPair(Algorithm.MLKEM.MLKEM1024)
8
- # Generate Bob's KEM keypair (optional here unless Bob also receives messages)
9
- _bobsk, _bobpk = KeyPair(Algorithm.MLKEM.MLKEM1024)
10
- # Bob uses Alice's public key to encapsulate a shared secret and a ciphertext
11
- bob_shared_secret, ciphertext = alicepk.encapsulate()
12
- # Alice decapsulates the ciphertext from bob to derive the same shared secret
13
- alice_shared_secret = alicesk.decapsulate(ciphertext)
14
- # Print shared secrets in hex format
15
- print(f"Alice's Shared Secret : [{alice_shared_secret.sharedsecret.hex()}]")
16
- print(f"Bob's Shared Secret : [{bob_shared_secret.sharedsecret.hex()}]")
17
- # Optional check
18
- assert alice_shared_secret.sharedsecret == bob_shared_secret.sharedsecret, "Shared secrets do not match!"
19
-
20
- if __name__ == "__main__":
21
- main()
File without changes
File without changes
File without changes
File without changes
File without changes