@@ -45,7 +45,7 @@ def _countdown(seconds):
4545def _load_shared_obj (name , additional_searching_paths = None ):
4646 """Attempts to load shared library."""
4747 paths = []
48- dll = ct .windll if platform .system () == "Windows" else ct .cdll
48+ dll = ct .windll if platform .system () == "Windows" else ct .cdll # type: ignore
4949
5050 # Search additional path, if any
5151 if additional_searching_paths :
@@ -138,7 +138,6 @@ def _load_liboqs():
138138 assert _liboqs
139139 except RuntimeError :
140140 sys .exit ("Could not load liboqs shared library" )
141-
142141 return _liboqs
143142
144143
@@ -162,7 +161,7 @@ def native():
162161def oqs_version ():
163162 """liboqs version string."""
164163 native ().OQS_version .restype = ct .c_char_p
165- return ct .c_char_p (native ().OQS_version ()).value .decode ("UTF-8" )
164+ return ct .c_char_p (native ().OQS_version ()).value .decode () # type: ignore
166165
167166
168167# Warn the user if the liboqs version differs from liboqs-python version
@@ -262,7 +261,7 @@ def __init__(self, alg_name, secret_key=None):
262261 def __enter__ (self ):
263262 return self
264263
265- def __exit__ (self , ctx_type , ctx_value , ctx_traceback ):
264+ def __exit__ (self , _ctx_type , _ctx_value , _ctx_traceback ):
266265 self .free ()
267266
268267 def generate_keypair (self ):
@@ -276,7 +275,10 @@ def generate_keypair(self):
276275 rv = native ().OQS_KEM_keypair (
277276 self ._kem , ct .byref (public_key ), ct .byref (self .secret_key )
278277 )
279- return bytes (public_key ) if rv == OQS_SUCCESS else 0
278+ if rv == OQS_SUCCESS :
279+ return bytes (public_key )
280+ else :
281+ raise RuntimeError ("Can not generate keypair" )
280282
281283 def export_secret_key (self ):
282284 """Exports the secret key."""
@@ -288,30 +290,36 @@ def encap_secret(self, public_key):
288290
289291 :param public_key: the peer's public key.
290292 """
291- my_public_key = ct .create_string_buffer (
293+ c_public_key = ct .create_string_buffer (
292294 public_key , self ._kem .contents .length_public_key
293295 )
294296 ciphertext = ct .create_string_buffer (self ._kem .contents .length_ciphertext )
295297 shared_secret = ct .create_string_buffer (self ._kem .contents .length_shared_secret )
296298 rv = native ().OQS_KEM_encaps (
297- self ._kem , ct .byref (ciphertext ), ct .byref (shared_secret ), my_public_key
299+ self ._kem , ct .byref (ciphertext ), ct .byref (shared_secret ), c_public_key
298300 )
299- return bytes (ciphertext ), bytes (shared_secret ) if rv == OQS_SUCCESS else 0
301+ if rv == OQS_SUCCESS :
302+ return bytes (ciphertext ), bytes (shared_secret )
303+ else :
304+ raise RuntimeError ("Can not encapsulate secret" )
300305
301306 def decap_secret (self , ciphertext ):
302307 """
303308 Decapsulates the ciphertext and returns the secret.
304309
305310 :param ciphertext: the ciphertext received from the peer.
306311 """
307- my_ciphertext = ct .create_string_buffer (
312+ c_ciphertext = ct .create_string_buffer (
308313 ciphertext , self ._kem .contents .length_ciphertext
309314 )
310315 shared_secret = ct .create_string_buffer (self ._kem .contents .length_shared_secret )
311316 rv = native ().OQS_KEM_decaps (
312- self ._kem , ct .byref (shared_secret ), my_ciphertext , self .secret_key
317+ self ._kem , ct .byref (shared_secret ), c_ciphertext , self .secret_key
313318 )
314- return bytes (shared_secret ) if rv == OQS_SUCCESS else 0
319+ if rv == OQS_SUCCESS :
320+ return bytes (shared_secret )
321+ else :
322+ raise RuntimeError ("Can not decapsulate secret" )
315323
316324 def free (self ):
317325 """Releases the native resources."""
@@ -374,6 +382,7 @@ class Signature(ct.Structure):
374382 ("alg_version" , ct .c_char_p ),
375383 ("claimed_nist_level" , ct .c_ubyte ),
376384 ("euf_cma" , ct .c_ubyte ),
385+ ("sig_with_ctx_support" , ct .c_ubyte ),
377386 ("length_public_key" , ct .c_size_t ),
378387 ("length_secret_key" , ct .c_size_t ),
379388 ("length_signature" , ct .c_size_t ),
@@ -404,6 +413,7 @@ def __init__(self, alg_name, secret_key=None):
404413 "version" : self ._sig .contents .alg_version .decode (),
405414 "claimed_nist_level" : int (self ._sig .contents .claimed_nist_level ),
406415 "is_euf_cma" : bool (self ._sig .contents .euf_cma ),
416+ "sig_with_ctx_support" : bool (self ._sig .contents .sig_with_ctx_support ),
407417 "length_public_key" : int (self ._sig .contents .length_public_key ),
408418 "length_secret_key" : int (self ._sig .contents .length_secret_key ),
409419 "length_signature" : int (self ._sig .contents .length_signature ),
@@ -417,7 +427,7 @@ def __init__(self, alg_name, secret_key=None):
417427 def __enter__ (self ):
418428 return self
419429
420- def __exit__ (self , ctx_type , ctx_value , ctx_traceback ):
430+ def __exit__ (self , _ctx_type , _ctx_value , _ctx_traceback ):
421431 self .free ()
422432
423433 def generate_keypair (self ):
@@ -431,7 +441,10 @@ def generate_keypair(self):
431441 rv = native ().OQS_SIG_keypair (
432442 self ._sig , ct .byref (public_key ), ct .byref (self .secret_key )
433443 )
434- return bytes (public_key ) if rv == OQS_SUCCESS else 0
444+ if rv == OQS_SUCCESS :
445+ return bytes (public_key )
446+ else :
447+ raise RuntimeError ("Can not generate keypair" )
435448
436449 def export_secret_key (self ):
437450 """Exports the secret key."""
@@ -444,22 +457,25 @@ def sign(self, message):
444457 :param message: the message to sign.
445458 """
446459 # Provide length to avoid extra null char
447- my_message = ct .create_string_buffer (message , len (message ))
448- message_len = ct .c_int (len (my_message ))
449- signature = ct .create_string_buffer (self ._sig .contents .length_signature )
450- sig_len = ct .c_int (
451- self ._sig .contents .length_signature
452- ) # initialize to maximum signature size
460+ c_message = ct .create_string_buffer (message , len (message ))
461+ c_message_len = ct .c_size_t (len (c_message ))
462+ c_signature = ct .create_string_buffer (self ._sig .contents .length_signature )
463+
464+ # Initialize to maximum signature size
465+ signature_len = ct .c_size_t (self ._sig .contents .length_signature )
466+
453467 rv = native ().OQS_SIG_sign (
454468 self ._sig ,
455- ct .byref (signature ),
456- ct .byref (sig_len ),
457- my_message ,
458- message_len ,
469+ ct .byref (c_signature ),
470+ ct .byref (signature_len ),
471+ c_message ,
472+ c_message_len ,
459473 self .secret_key ,
460474 )
461-
462- return bytes (signature [: sig_len .value ]) if rv == OQS_SUCCESS else 0
475+ if rv == OQS_SUCCESS :
476+ return bytes (c_signature [: signature_len .value ])
477+ else :
478+ raise RuntimeError ("Can not sign message" )
463479
464480 def verify (self , message , signature , public_key ):
465481 """
@@ -470,17 +486,85 @@ def verify(self, message, signature, public_key):
470486 :param public_key: the signer's public key.
471487 """
472488 # Provide length to avoid extra null char
473- my_message = ct .create_string_buffer (message , len (message ))
474- message_len = ct .c_int (len (my_message ))
475-
476- # Provide length to avoid extra null char in sig
477- my_signature = ct .create_string_buffer (signature , len (signature ))
478- sig_len = ct .c_int (len (my_signature ))
479- my_public_key = ct .create_string_buffer (
489+ c_message = ct .create_string_buffer (message , len (message ))
490+ c_message_len = ct .c_size_t (len (c_message ))
491+ c_signature = ct .create_string_buffer (signature , len (signature ))
492+ signature_len = ct .c_size_t (len (c_signature ))
493+ c_public_key = ct .create_string_buffer (
480494 public_key , self ._sig .contents .length_public_key
481495 )
496+
482497 rv = native ().OQS_SIG_verify (
483- self ._sig , my_message , message_len , my_signature , sig_len , my_public_key
498+ self ._sig ,
499+ c_message ,
500+ c_message_len ,
501+ c_signature ,
502+ signature_len ,
503+ c_public_key ,
504+ )
505+ return True if rv == OQS_SUCCESS else False
506+
507+ def sign_with_ctx_str (self , message , context ):
508+ """
509+ Signs the provided message with context string and returns the signature.
510+
511+ :param context: the context string.
512+ :param message: the message to sign.
513+ """
514+ # Provide length to avoid extra null char
515+ c_message = ct .create_string_buffer (message , len (message ))
516+ c_message_len = ct .c_size_t (len (c_message ))
517+ c_context = ct .create_string_buffer (context , len (context ))
518+ context_len = ct .c_size_t (len (c_context ))
519+ c_signature = ct .create_string_buffer (self ._sig .contents .length_signature )
520+
521+ # Initialize to maximum signature size
522+ c_signature_len = ct .c_size_t (self ._sig .contents .length_signature )
523+
524+ rv = native ().OQS_SIG_sign_with_ctx_str (
525+ self ._sig ,
526+ ct .byref (c_signature ),
527+ ct .byref (c_signature_len ),
528+ c_message ,
529+ c_message_len ,
530+ c_context ,
531+ context_len ,
532+ self .secret_key ,
533+ )
534+ if rv == OQS_SUCCESS :
535+ return bytes (c_signature [: c_signature_len .value ])
536+ else :
537+ raise RuntimeError ("Can not sign message with context string" )
538+
539+ def verify_with_ctx_str (self , message , signature , context , public_key ):
540+ """
541+ Verifies the provided signature on the message with context string; returns True if valid.
542+
543+ :param message: the signed message.
544+ :param signature: the signature on the message.
545+ :param context: the context string.
546+ :param public_key: the signer's public key.
547+ """
548+ # Provide length to avoid extra null char
549+ c_message = ct .create_string_buffer (message , len (message ))
550+ c_message_len = ct .c_size_t (len (c_message ))
551+ c_signature = ct .create_string_buffer (signature , len (signature ))
552+ c_signature_len = ct .c_size_t (len (c_signature ))
553+ c_context = ct .create_string_buffer (context , len (context ))
554+ c_context_len = ct .c_size_t (len (c_context ))
555+ c_public_key = ct .create_string_buffer (
556+ public_key , self ._sig .contents .length_public_key
557+ )
558+
559+ rv = native ().OQS_SIG_verify_with_ctx_str (
560+ self ._sig ,
561+ c_message ,
562+ c_message_len ,
563+ c_signature ,
564+ c_signature_len ,
565+ c_context ,
566+ c_context_len ,
567+ c_public_key ,
484568 )
485569 return True if rv == OQS_SUCCESS else False
486570
0 commit comments