Skip to content

Commit 292557e

Browse files
authored
Merge pull request #100 from roberthdevries/add-typing
Start adding typing information.
2 parents e7300e9 + 61c7990 commit 292557e

7 files changed

Lines changed: 118 additions & 18 deletions

File tree

ChangeLog.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
wolfCrypt-py Release NEXT (TBD, 2026)
2+
==========================================
3+
4+
* Add extra nonce parameter to Random generator
5+
6+
17
wolfCrypt-py Release 5.8.4 (Jan 7, 2026)
28
==========================================
39

requirements/test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
-r prod.txt
22
tox
33
pytest
4+
types-cffi

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
u"Programming Language :: Python :: 3.7",
7575
u"Programming Language :: Python :: 3.8",
7676
u"Programming Language :: Python :: 3.9",
77+
u"Programming Language :: Python :: 3.10",
7778
u"Topic :: Security",
7879
u"Topic :: Security :: Cryptography",
7980
u"Topic :: Software Development"
@@ -83,5 +84,5 @@
8384
install_requires=["cffi>=1.0.0"],
8485
cffi_modules=["./scripts/build_ffi.py:ffibuilder"],
8586

86-
package_data={"wolfcrypt": ["*.dll"]}
87+
package_data={"wolfcrypt": ["*.dll", "**/*.pyi"]}
8788
)

wolfcrypt/_ffi/__init__.pyi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import _cffi_backend
2+
import wolfcrypt._ffi.lib as lib
3+
4+
ffi: _cffi_backend.FFI
5+
6+
__all__ = ["ffi", "lib"]

wolfcrypt/_ffi/lib.pyi

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
2+
from _cffi_backend import FFI
3+
from typing import TypeAlias
4+
5+
INVALID_DEVID: int
6+
7+
AES_ENABLED: int
8+
AES_SIV_ENABLED: int
9+
AESGCM_STREAM_ENABLED: int
10+
ASN_ENABLED: int
11+
CHACHA_ENABLED: int
12+
CHACHA_STREAM_ENABLED: int
13+
CHACHA20_POLY1305_ENABLED: int
14+
DES3_ENABLED: int
15+
ECC_ENABLED: int
16+
ED25519_ENABLED: int
17+
ED448_ENABLED: int
18+
FIPS_ENABLED: int
19+
HMAC_ENABLED: int
20+
KEYGEN_ENABLED: int
21+
HKDF_ENABLED: int
22+
ML_DSA_ENABLED: int
23+
ML_KEM_ENABLED: int
24+
MPAPI_ENABLED: int
25+
PWDBASED_ENABLED: int
26+
RSA_ENABLED: int
27+
RSA_PSS_ENABLED: int
28+
SHA_ENABLED: int
29+
SHA3_ENABLED: int
30+
SHA256_ENABLED: int
31+
SHA384_ENABLED: int
32+
SHA512_ENABLED: int
33+
WC_RNG_SEED_CB_ENABLED: int
34+
35+
FIPS_VERSION: int
36+
37+
WC_MGF1NONE: int
38+
WC_MGF1SHA1: int
39+
WC_MGF1SHA224: int
40+
WC_MGF1SHA256: int
41+
WC_MGF1SHA384: int
42+
WC_MGF1SHA512: int
43+
44+
WC_HASH_TYPE_NONE: int
45+
WC_HASH_TYPE_MD2: int
46+
WC_HASH_TYPE_MD4: int
47+
WC_HASH_TYPE_MD5: int
48+
WC_HASH_TYPE_SHA: int
49+
WC_HASH_TYPE_SHA224: int
50+
WC_HASH_TYPE_SHA256: int
51+
WC_HASH_TYPE_SHA384: int
52+
WC_HASH_TYPE_SHA512: int
53+
WC_HASH_TYPE_MD5_SHA: int
54+
WC_HASH_TYPE_SHA3_224: int
55+
WC_HASH_TYPE_SHA3_256: int
56+
WC_HASH_TYPE_SHA3_384: int
57+
WC_HASH_TYPE_SHA3_512: int
58+
WC_HASH_TYPE_BLAKE2B: int
59+
WC_HASH_TYPE_BLAKE2S: int
60+
61+
WC_ML_KEM_512: int
62+
WC_ML_KEM_768: int
63+
WC_ML_KEM_1024: int
64+
65+
WC_ML_DSA_44: int
66+
WC_ML_DSA_65: int
67+
WC_ML_DSA_87: int
68+
69+
WC_KEYTYPE_ALL: int
70+
71+
RNG: TypeAlias = FFI.CData
72+
73+
def wc_InitRngNonce_ex(rng: RNG, nonce: bytes, nonce_size: int, heap: FFI.CData, device_id: int) -> int: ...
74+
def wc_RNG_GenerateByte(rng: RNG, buffer: FFI.CData) -> int: ...
75+
def wc_RNG_GenerateBlock(rng: RNG, buffer: FFI.CData, len: int) -> int: ...
76+
def wc_FreeRng(rng: RNG) -> None: ...

wolfcrypt/random.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
# pylint: disable=no-member,no-name-in-module
2222

23+
from __future__ import annotations
24+
2325
from wolfcrypt._ffi import ffi as _ffi
2426
from wolfcrypt._ffi import lib as _lib
2527

@@ -31,47 +33,45 @@ class Random:
3133
A Cryptographically Secure Pseudo Random Number Generator - CSPRNG
3234
"""
3335

34-
def __init__(self, nonce=_ffi.NULL, device_id=_lib.INVALID_DEVID):
35-
self.native_object = _ffi.new("WC_RNG *")
36+
def __init__(self, nonce: __builtins__.bytes = b"", device_id: int = _lib.INVALID_DEVID) -> None:
37+
self.native_object: _lib.RNG | None = _ffi.new("WC_RNG *")
3638

37-
if nonce == _ffi.NULL:
38-
nonce_size = 0
39-
else:
40-
nonce_size = len(nonce)
41-
ret = _lib.wc_InitRngNonce_ex(self.native_object, nonce, nonce_size, _ffi.NULL, device_id)
39+
ret = _lib.wc_InitRngNonce_ex(self.native_object, nonce, len(nonce), _ffi.NULL, device_id)
4240
if ret < 0: # pragma: no cover
4341
self.native_object = None
4442
raise WolfCryptError("RNG init error (%d)" % ret)
4543

4644
# making sure _lib.wc_FreeRng outlives WC_RNG instances
4745
_delete = _lib.wc_FreeRng
4846

49-
def __del__(self):
47+
def __del__(self) -> None:
5048
if self.native_object:
5149
try:
5250
self._delete(self.native_object)
5351
except AttributeError:
5452
# Can occur during interpreter shutdown
5553
pass
5654

57-
def byte(self):
55+
def byte(self) -> __builtins__.bytes:
5856
"""
5957
Generate and return a random byte.
6058
"""
61-
result = _ffi.new('byte[1]')
59+
result = _ffi.new("byte[1]")
6260

61+
assert self.native_object is not None
6362
ret = _lib.wc_RNG_GenerateByte(self.native_object, result)
6463
if ret < 0: # pragma: no cover
6564
raise WolfCryptError("RNG generate byte error (%d)" % ret)
6665

6766
return _ffi.buffer(result, 1)[:]
6867

69-
def bytes(self, length):
68+
def bytes(self, length: int) -> __builtins__.bytes:
7069
"""
7170
Generate and return a random sequence of length bytes.
7271
"""
73-
result = _ffi.new('byte[%d]' % length)
72+
result = _ffi.new("byte[%d]" % length)
7473

74+
assert self.native_object is not None
7575
ret = _lib.wc_RNG_GenerateBlock(self.native_object, result, length)
7676
if ret < 0: # pragma: no cover
7777
raise WolfCryptError("RNG generate block error (%d)" % ret)

wolfcrypt/utils.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,26 @@
2020

2121
# pylint: disable=unused-import
2222

23+
from __future__ import annotations
24+
2325
from binascii import hexlify as b2h, unhexlify as h2b # noqa: F401
2426

2527

26-
def t2b(string):
28+
def t2b(string: bytes | bytearray | memoryview | str) -> bytes:
2729
"""
28-
Converts text to binary.
30+
Converts text to bytes.
2931
30-
Passes through bytes, bytearray, and memoryview unchanged.
32+
Passes through bytes unchanged.
33+
Objects of type bytearray or memoryview are converted to bytes.
3134
Encodes str to UTF-8 bytes.
35+
36+
:param string: text to convert to bytes.
37+
:raises TypeError: if string is not one of the supported types.
3238
"""
33-
if isinstance(string, (bytes, bytearray, memoryview)):
39+
if isinstance(string, bytes):
3440
return string
35-
return str(string).encode("utf-8")
41+
if isinstance(string, (bytearray, memoryview)):
42+
return bytes(string)
43+
if isinstance(string, str):
44+
return str(string).encode("utf-8")
45+
raise TypeError(f"String parameter of wrong type {type(string).__name__}, expected bytes, bytearray, memoryview or str")

0 commit comments

Comments
 (0)