puantum 1.0.0.0__cp310-cp310-macosx_11_0_arm64.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.
@@ -0,0 +1,526 @@
1
+ # IMPORT
2
+ from puantum import __internal__ as _internal # type: ignore
3
+ import typing as _typing
4
+ import enum as _enum
5
+
6
+ # MAIN
7
+ class Algorithm:
8
+ class BIKE(_enum.Enum):
9
+ BIKEL1 = "BikeL1"
10
+ BIKEL3 = "BikeL3"
11
+ BIKEL5 = "BikeL5"
12
+ #
13
+ class CLASSICMCELIECE(_enum.Enum):
14
+ CLASSICMCELIECE348864 = "ClassicMcEliece348864"
15
+ CLASSICMCELIECE348864F = "ClassicMcEliece348864f"
16
+ CLASSICMCELIECE460896 = "ClassicMcEliece460896"
17
+ CLASSICMCELIECE460896F = "ClassicMcEliece460896f"
18
+ CLASSICMCELIECE6688128 = "ClassicMcEliece6688128"
19
+ CLASSICMCELIECE6688128F = "ClassicMcEliece6688128f"
20
+ CLASSICMCELIECE6960119 = "ClassicMcEliece6960119"
21
+ CLASSICMCELIECE6960119F = "ClassicMcEliece6960119f"
22
+ CLASSICMCELIECE8192128 = "ClassicMcEliece8192128"
23
+ CLASSICMCELIECE8192128F = "ClassicMcEliece8192128f"
24
+ #
25
+ class HQC(_enum.Enum):
26
+ HQC128 = "Hqc128"
27
+ HQC192 = "Hqc192"
28
+ HQC256 = "Hqc256"
29
+ #
30
+ class KYBER(_enum.Enum):
31
+ KYBER512 = "Kyber512"
32
+ KYBER768 = "Kyber768"
33
+ KYBER1024 = "Kyber1024"
34
+ #
35
+ class MLKEM(_enum.Enum):
36
+ MLKEM512 = "MlKem512"
37
+ MLKEM768 = "MlKem768"
38
+ MLKEM1024 = "MlKem1024"
39
+ #
40
+ class NTRUPRIME(_enum.Enum):
41
+ NTRUPRIME = "NtruPrimeSntrup761"
42
+ #
43
+ class FRODOKEM(_enum.Enum):
44
+ FRODOKEM640AES = "FrodoKem640Aes"
45
+ FRODOKEM640SHAKE = "FrodoKem640Shake"
46
+ FRODOKEM976AES = "FrodoKem976Aes"
47
+ FRODOKEM976SHAKE = "FrodoKem976Shake"
48
+ FRODOKEM1344AES = "FrodoKem1344Aes"
49
+ FRODOKEM1344SHAKE = "FrodoKem1344Shake"
50
+
51
+
52
+
53
+ class PublicKey:
54
+ def __init__(self, publickey: bytes) -> None:
55
+ if not isinstance(publickey, bytes):
56
+ raise TypeError("PublicKey Not Valid")
57
+ #
58
+ self.publickey = publickey
59
+ #
60
+ return None
61
+ #
62
+ def encapsulate(self) -> tuple[_typing.Any, _typing.Any]:
63
+ raise NotImplementedError()
64
+
65
+
66
+
67
+ class BIKEPublicKey(PublicKey):
68
+ def __init__(self, name: Algorithm.BIKE, publickey: bytes) -> None:
69
+ if not isinstance(name, Algorithm.BIKE):
70
+ raise ValueError(f"Unsupported algorithm: {name}")
71
+ else:
72
+ super().__init__(publickey)
73
+ #
74
+ self._algorithm = name
75
+ #
76
+ return None
77
+ #
78
+ def encapsulate(self) -> tuple[bytes, bytes]:
79
+ sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
80
+ return sharedsecret, ciphertext # type: ignore
81
+
82
+
83
+
84
+ class CLASSICMCELIECEPublicKey(PublicKey):
85
+ def __init__(self, name: Algorithm.CLASSICMCELIECE, publickey: bytes) -> None:
86
+ if not isinstance(name, Algorithm.CLASSICMCELIECE):
87
+ raise ValueError(f"Unsupported algorithm: {name}")
88
+ else:
89
+ super().__init__(publickey)
90
+ #
91
+ self._algorithm = name
92
+ #
93
+ return None
94
+ #
95
+ def encapsulate(self) -> tuple[bytes, bytes]:
96
+ sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
97
+ return sharedsecret, ciphertext # type: ignore
98
+
99
+
100
+
101
+ class HQCPublicKey(PublicKey):
102
+ def __init__(self, name: Algorithm.HQC, publickey: bytes) -> None:
103
+ if not isinstance(name, Algorithm.HQC):
104
+ raise ValueError(f"Unsupported algorithm: {name}")
105
+ else:
106
+ super().__init__(publickey)
107
+ #
108
+ self._algorithm = name
109
+ #
110
+ return None
111
+ #
112
+ def encapsulate(self) -> tuple[bytes, bytes]:
113
+ sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
114
+ return sharedsecret, ciphertext # type: ignore
115
+
116
+
117
+
118
+ class KYBERPublicKey(PublicKey):
119
+ def __init__(self, name: Algorithm.KYBER, publickey: bytes) -> None:
120
+ if not isinstance(name, Algorithm.KYBER):
121
+ raise ValueError(f"Unsupported algorithm: {name}")
122
+ else:
123
+ super().__init__(publickey)
124
+ #
125
+ self._algorithm = name
126
+ #
127
+ return None
128
+ #
129
+ def encapsulate(self) -> tuple[bytes, bytes]:
130
+ sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
131
+ return sharedsecret, ciphertext # type: ignore
132
+
133
+
134
+
135
+ class MLKEMPublicKey(PublicKey):
136
+ def __init__(self, name: Algorithm.MLKEM, publickey: bytes) -> None:
137
+ if not isinstance(name, Algorithm.MLKEM):
138
+ raise ValueError(f"Unsupported algorithm: {name}")
139
+ else:
140
+ super().__init__(publickey)
141
+ #
142
+ self._algorithm = name
143
+ #
144
+ return None
145
+ #
146
+ def encapsulate(self) -> tuple[bytes, bytes]:
147
+ sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
148
+ return sharedsecret, ciphertext # type: ignore
149
+
150
+
151
+
152
+ class NTRUPRIMEPublicKey(PublicKey):
153
+ def __init__(self, name: Algorithm.NTRUPRIME, publickey: bytes) -> None:
154
+ if not isinstance(name, Algorithm.NTRUPRIME):
155
+ raise ValueError(f"Unsupported algorithm: {name}")
156
+ else:
157
+ super().__init__(publickey)
158
+ #
159
+ self._algorithm = name
160
+ #
161
+ return None
162
+ #
163
+ def encapsulate(self) -> tuple[bytes, bytes]:
164
+ sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
165
+ return sharedsecret, ciphertext # type: ignore
166
+
167
+
168
+
169
+ class FRODOKEMPublicKey(PublicKey):
170
+ def __init__(self, name: Algorithm.FRODOKEM, publickey: bytes) -> None:
171
+ if not isinstance(name, Algorithm.FRODOKEM):
172
+ raise ValueError(f"Unsupported algorithm: {name}")
173
+ else:
174
+ super().__init__(publickey)
175
+ #
176
+ self._algorithm = name
177
+ #
178
+ return None
179
+ #
180
+ def encapsulate(self) -> tuple[bytes, bytes]:
181
+ sharedsecret, ciphertext = _internal.kemencapsulate(self._algorithm.value, self.publickey) # type: ignore
182
+ return sharedsecret, ciphertext # type: ignore
183
+
184
+
185
+
186
+ class SecretKey:
187
+ def __init__(self, secretkey: bytes) -> None:
188
+ if not isinstance(secretkey, bytes):
189
+ raise TypeError("SecretKey Not Valid")
190
+ #
191
+ self.secretkey = secretkey
192
+ #
193
+ return None
194
+ #
195
+ def decapsulate(self, ciphertext: _typing.Any) -> _typing.Any:
196
+ raise NotImplementedError()
197
+
198
+
199
+
200
+ class BIKESecretKey(SecretKey):
201
+ def __init__(self, name: Algorithm.BIKE, secretkey: bytes) -> None:
202
+ if not isinstance(name, Algorithm.BIKE):
203
+ raise ValueError(f"Unsupported algorithm: {name}")
204
+ else:
205
+ super().__init__(secretkey)
206
+ #
207
+ self._algorithm = name
208
+ #
209
+ return None
210
+ #
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
214
+
215
+
216
+
217
+ class CLASSICMCELIECESecretKey(SecretKey):
218
+ def __init__(self, name: Algorithm.CLASSICMCELIECE, secretkey: bytes) -> None:
219
+ if not isinstance(name, Algorithm.CLASSICMCELIECE):
220
+ raise ValueError(f"Unsupported algorithm: {name}")
221
+ else:
222
+ super().__init__(secretkey)
223
+ #
224
+ self._algorithm = name
225
+ #
226
+ return None
227
+ #
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
231
+
232
+
233
+
234
+ class HQCSecretKey(SecretKey):
235
+ def __init__(self, name: Algorithm.HQC, secretkey: bytes) -> None:
236
+ if not isinstance(name, Algorithm.HQC):
237
+ raise ValueError(f"Unsupported algorithm: {name}")
238
+ else:
239
+ super().__init__(secretkey)
240
+ #
241
+ self._algorithm = name
242
+ #
243
+ return None
244
+ #
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
248
+
249
+
250
+
251
+ class KYBERSecretKey(SecretKey):
252
+ def __init__(self, name: Algorithm.KYBER, secretkey: bytes) -> None:
253
+ if not isinstance(name, Algorithm.KYBER):
254
+ raise ValueError(f"Unsupported algorithm: {name}")
255
+ else:
256
+ super().__init__(secretkey)
257
+ #
258
+ self._algorithm = name
259
+ #
260
+ return None
261
+ #
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
265
+
266
+
267
+
268
+ class MLKEMSecretKey(SecretKey):
269
+ def __init__(self, name: Algorithm.MLKEM, secretkey: bytes) -> None:
270
+ if not isinstance(name, Algorithm.MLKEM):
271
+ raise ValueError(f"Unsupported algorithm: {name}")
272
+ else:
273
+ super().__init__(secretkey)
274
+ #
275
+ self._algorithm = name
276
+ #
277
+ return None
278
+ #
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
282
+
283
+
284
+
285
+ class NTRUPRIMESecretKey(SecretKey):
286
+ def __init__(self, name: Algorithm.NTRUPRIME, secretkey: bytes) -> None:
287
+ if not isinstance(name, Algorithm.NTRUPRIME):
288
+ raise ValueError(f"Unsupported algorithm: {name}")
289
+ else:
290
+ super().__init__(secretkey)
291
+ #
292
+ self._algorithm = name
293
+ #
294
+ return None
295
+ #
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
299
+
300
+
301
+
302
+ class FRODOKEMSecretKey(SecretKey):
303
+ def __init__(self, name: Algorithm.FRODOKEM, secretkey: bytes) -> None:
304
+ if not isinstance(name, Algorithm.FRODOKEM):
305
+ raise ValueError(f"Unsupported algorithm: {name}")
306
+ else:
307
+ super().__init__(secretkey)
308
+ #
309
+ self._algorithm = name
310
+ #
311
+ return None
312
+ #
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
316
+
317
+
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: ...
330
+ @_typing.overload
331
+ def KeyPair(name: Algorithm) -> tuple[SecretKey, PublicKey]: ...
332
+
333
+
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: ...
346
+ @_typing.overload
347
+ def KeyPair(name: Algorithm.BIKE) -> tuple[BIKESecretKey, BIKEPublicKey]: ...
348
+
349
+
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: ...
362
+ @_typing.overload
363
+ def KeyPair(name: Algorithm.CLASSICMCELIECE) -> tuple[CLASSICMCELIECESecretKey, CLASSICMCELIECEPublicKey]: ...
364
+
365
+
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: ...
378
+ @_typing.overload
379
+ def KeyPair(name: Algorithm.HQC) -> tuple[HQCSecretKey, HQCPublicKey]: ...
380
+
381
+
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: ...
394
+ @_typing.overload
395
+ def KeyPair(name: Algorithm.KYBER) -> tuple[KYBERSecretKey, KYBERPublicKey]: ...
396
+
397
+
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: ...
410
+ @_typing.overload
411
+ def KeyPair(name: Algorithm.MLKEM) -> tuple[MLKEMSecretKey, MLKEMPublicKey]: ...
412
+
413
+
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: ...
426
+ @_typing.overload
427
+ def KeyPair(name: Algorithm.NTRUPRIME) -> tuple[NTRUPRIMESecretKey, NTRUPRIMEPublicKey]: ...
428
+
429
+
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: ...
442
+ @_typing.overload
443
+ def KeyPair(name: Algorithm.FRODOKEM) -> tuple[FRODOKEMSecretKey, FRODOKEMPublicKey]: ...
444
+
445
+
446
+
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:
454
+ algorithm = name
455
+ if isinstance(algorithm, Algorithm.BIKE):
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
465
+ elif isinstance(algorithm, Algorithm.CLASSICMCELIECE):
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
475
+ elif isinstance(algorithm, Algorithm.HQC):
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
485
+ elif isinstance(algorithm, Algorithm.KYBER):
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
495
+ elif isinstance(algorithm, Algorithm.MLKEM):
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
505
+ elif isinstance(algorithm, Algorithm.NTRUPRIME):
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
515
+ elif isinstance(algorithm, Algorithm.FRODOKEM):
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
525
+ else:
526
+ raise ValueError(f"Unsupported algorithm: {name}")