Skip to content

Commit e1a6fc7

Browse files
committed
Move project to uv
Add typing Add pre-commit Reformat code Make code more secure Update workflow python_simplified.yml Update workflow python_detailed.yml Signed-off-by: andrew000 <[email protected]>
1 parent 7a1c2f6 commit e1a6fc7

File tree

17 files changed

+648
-319
lines changed

17 files changed

+648
-319
lines changed

.github/workflows/python_detailed.yml

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ name: GitHub actions detailed
22

33
on:
44
push:
5-
branches: ["**"]
5+
branches: [ "**" ]
66
pull_request:
7-
branches: ["**"]
7+
branches: [ "**" ]
88
repository_dispatch:
9-
types: ["**"]
9+
types: [ "**" ]
1010

1111
permissions:
1212
contents: read
@@ -20,21 +20,24 @@ jobs:
2020
build:
2121
strategy:
2222
matrix:
23-
os: [ubuntu-latest, macos-latest, windows-latest]
23+
os: [ ubuntu-latest, macos-latest, windows-latest ]
2424
runs-on: ${{ matrix.os }}
2525

2626
steps:
27-
- uses: actions/checkout@v3
27+
- uses: actions/checkout@v4
2828

29-
- name: Set up Python 3.10
30-
uses: actions/setup-python@v3
29+
- name: Install uv
30+
uses: astral-sh/setup-uv@v3
3131
with:
32-
python-version: "3.10"
32+
version: "latest"
33+
enable-cache: true
34+
cache-dependency-glob: "**/pyproject.toml"
35+
36+
- name: Set up Python 3.9
37+
run: uv python install 3.9
3338

3439
- name: Install dependencies
35-
run: |
36-
python -m pip install --upgrade pip
37-
pip install nose2
40+
run: uv sync --extra dev
3841

3942
- name: Install liboqs POSIX
4043
if: matrix.os != 'windows-latest'
@@ -47,17 +50,17 @@ jobs:
4750
- name: Run examples POSIX
4851
if: matrix.os != 'windows-latest'
4952
run: |
50-
pip install .
51-
python examples/kem.py
53+
uv sync --extra dev
54+
uv run examples/kem.py
5255
echo
53-
python examples/sig.py
56+
uv run examples/sig.py
5457
echo
55-
python examples/rand.py
58+
uv run examples/rand.py
5659
5760
- name: Run unit tests POSIX
5861
if: matrix.os != 'windows-latest'
5962
run: |
60-
nose2 --verbose
63+
uv run nose2 --verbose
6164
6265
- name: Install liboqs Windows
6366
if: matrix.os == 'windows-latest'
@@ -73,16 +76,16 @@ jobs:
7376
shell: cmd
7477
run: |
7578
set PATH=%PATH%;${{env.WIN_LIBOQS_INSTALL_PATH}}\bin
76-
pip install .
77-
python examples/kem.py
79+
uv sync --extra dev
80+
uv run examples/kem.py
7881
echo.
79-
python examples/sig.py
82+
uv run examples/sig.py
8083
echo.
81-
python examples/rand.py
84+
uv run examples/rand.py
8285
8386
- name: Run unit tests Windows
8487
shell: cmd
8588
if: matrix.os == 'windows-latest'
8689
run: |
8790
set PATH=%PATH%;${{env.WIN_LIBOQS_INSTALL_PATH}}\bin
88-
nose2 --verbose
91+
uv run nose2 --verbose

.github/workflows/python_simplified.yml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ name: GitHub actions simplified
22

33
on:
44
push:
5-
branches: ["**"]
5+
branches: [ "**" ]
66
pull_request:
7-
branches: ["**"]
7+
branches: [ "**" ]
88
repository_dispatch:
9-
types: ["**"]
9+
types: [ "**" ]
1010

1111
permissions:
1212
contents: read
@@ -15,25 +15,29 @@ jobs:
1515
build:
1616
strategy:
1717
matrix:
18-
os: [ubuntu-latest, macos-latest, windows-latest]
18+
os: [ ubuntu-latest, macos-latest, windows-latest ]
1919
runs-on: ${{ matrix.os }}
2020

2121
steps:
22-
- uses: actions/checkout@v3
22+
- uses: actions/checkout@v4
2323

24-
- name: Set up Python 3.10
25-
uses: actions/setup-python@v3
24+
- name: Install uv
25+
uses: astral-sh/setup-uv@v3
2626
with:
27-
python-version: "3.10"
27+
version: "latest"
28+
enable-cache: true
29+
cache-dependency-glob: "**/pyproject.toml"
30+
31+
- name: Set up Python 3.9
32+
run: uv python install 3.9
2833

2934
- name: Run examples
3035
run: |
31-
python -m pip install --upgrade pip
32-
pip install .
33-
python examples/kem.py
34-
python examples/sig.py
35-
python examples/rand.py
36+
uv sync --extra dev
37+
uv run examples/kem.py
38+
uv run examples/sig.py
39+
uv run examples/rand.py
3640
3741
- name: Run unit tests
3842
run: |
39-
nose2 --verbose
43+
uv run nose2 --verbose

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,5 @@ pip-selfcheck.json
117117
pyvenv.cfg
118118

119119
# vim
120-
*.swp
120+
*.swp
121+
/uv.lock

.pre-commit-config.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
fail_fast: false
2+
repos:
3+
- repo: https://github.com/pre-commit/pre-commit-hooks
4+
rev: v5.0.0
5+
hooks:
6+
- id: "trailing-whitespace"
7+
- id: "check-case-conflict"
8+
- id: "check-merge-conflict"
9+
- id: "debug-statements"
10+
- id: "end-of-file-fixer"
11+
- id: "mixed-line-ending"
12+
args: [ "--fix", "crlf" ]
13+
types:
14+
- python
15+
- yaml
16+
- toml
17+
- text
18+
- id: "detect-private-key"
19+
- id: "check-yaml"
20+
- id: "check-toml"
21+
- id: "check-json"
22+
23+
- repo: https://github.com/charliermarsh/ruff-pre-commit
24+
rev: v0.7.3
25+
hooks:
26+
- id: ruff
27+
args: [ "--fix" ]
28+
files: "oqs"
29+
30+
- id: ruff-format
31+
files: "oqs"
32+
33+
- repo: https://github.com/pycqa/isort
34+
rev: 5.13.2
35+
hooks:
36+
- id: isort
37+
name: isort (python)
38+
files: "oqs"

Makefile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
src-dir = oqs
2+
tests-dir = tests
3+
examples-dir = examples
4+
5+
.PHONY pull:
6+
pull:
7+
git pull origin master
8+
git submodule update --init --recursive
9+
10+
.PHONY lint:
11+
lint:
12+
echo "Running ruff..."
13+
uv run ruff check --config pyproject.toml --diff $(src-dir) $(tests-dir) $(examples-dir)
14+
15+
.PHONY format:
16+
format:
17+
echo "Running ruff check with --fix..."
18+
uv run ruff check --config pyproject.toml --fix --unsafe-fixes $(src-dir) $(tests-dir) $(examples-dir)
19+
20+
echo "Running ruff..."
21+
uv run ruff format --config pyproject.toml $(src-dir) $(tests-dir) $(examples-dir)
22+
23+
echo "Running isort..."
24+
uv run isort --settings-file pyproject.toml $(src-dir) $(tests-dir) $(examples-dir)
25+
26+
.PHONE mypy:
27+
mypy:
28+
echo "Running MyPy..."
29+
uv run mypy --config-file pyproject.toml
30+
31+
.PHONY outdated:
32+
outdated:
33+
uv tree --outdated --universal
34+
35+
.PHONY sync:
36+
sync:
37+
uv sync --extra dev --extra lint

examples/__init__.py

Whitespace-only changes.

examples/kem.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,39 @@
11
# Key encapsulation Python example
2+
import logging
3+
from pprint import pformat
24

35
import oqs
4-
from pprint import pprint
56

6-
print("liboqs version:", oqs.oqs_version())
7-
print("liboqs-python version:", oqs.oqs_python_version())
8-
print("Enabled KEM mechanisms:")
9-
kems = oqs.get_enabled_kem_mechanisms()
10-
pprint(kems, compact=True)
7+
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.INFO)
8+
logger = logging.getLogger(__name__)
9+
logger.setLevel(logging.INFO)
10+
11+
logger.info("liboqs version: %s", oqs.oqs_version())
12+
logger.info("liboqs-python version: %s", oqs.oqs_python_version())
13+
logger.info("Enabled KEM mechanisms: %s", pformat(oqs.get_enabled_kem_mechanisms(), compact=True))
1114

1215
# Create client and server with sample KEM mechanisms
1316
kemalg = "Kyber512"
14-
with oqs.KeyEncapsulation(kemalg) as client:
15-
with oqs.KeyEncapsulation(kemalg) as server:
16-
print("\nKey encapsulation details:")
17-
pprint(client.details)
17+
with oqs.KeyEncapsulation(kemalg) as client, oqs.KeyEncapsulation(kemalg) as server:
18+
# print("\nKey encapsulation details:")
19+
logger.info("Client details: %s", pformat(client.details))
1820

19-
# Client generates its keypair
20-
public_key_client = client.generate_keypair()
21-
# Optionally, the secret key can be obtained by calling export_secret_key()
22-
# and the client can later be re-instantiated with the key pair:
23-
# secret_key_client = client.export_secret_key()
21+
# Client generates its keypair
22+
public_key_client = client.generate_keypair()
23+
# Optionally, the secret key can be obtained by calling export_secret_key()
24+
# and the client can later be re-instantiated with the key pair:
25+
# secret_key_client = client.export_secret_key()
2426

25-
# Store key pair, wait... (session resumption):
26-
# client = oqs.KeyEncapsulation(kemalg, secret_key_client)
27+
# Store key pair, wait... (session resumption):
28+
# client = oqs.KeyEncapsulation(kemalg, secret_key_client)
2729

28-
# The server encapsulates its secret using the client's public key
29-
ciphertext, shared_secret_server = server.encap_secret(public_key_client)
30+
# The server encapsulates its secret using the client's public key
31+
ciphertext, shared_secret_server = server.encap_secret(public_key_client)
3032

31-
# The client decapsulates the server's ciphertext to obtain the shared secret
32-
shared_secret_client = client.decap_secret(ciphertext)
33+
# The client decapsulates the server's ciphertext to obtain the shared secret
34+
shared_secret_client = client.decap_secret(ciphertext)
3335

34-
print(
35-
"\nShared secretes coincide:", shared_secret_client == shared_secret_server
36-
)
36+
logger.info(
37+
"Shared secretes coincide: %s",
38+
shared_secret_client == shared_secret_server,
39+
)

examples/rand.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
# Various RNGs Python example
2-
2+
import logging
33
import platform # to learn the OS we're on
4+
45
import oqs.rand as oqsrand # must be explicitly imported
5-
from oqs import oqs_version, oqs_python_version
6+
from oqs import oqs_python_version, oqs_version
7+
8+
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.INFO)
9+
logger = logging.getLogger(__name__)
10+
logger.setLevel(logging.INFO)
611

7-
print("liboqs version:", oqs_version())
8-
print("liboqs-python version:", oqs_python_version())
12+
logger.info("liboqs version: %s", oqs_version())
13+
logger.info("liboqs-python version: %s", oqs_python_version())
914

1015
oqsrand.randombytes_switch_algorithm("system")
11-
print(
12-
"{:17s}".format("System (default):"),
13-
" ".join("{:02X}".format(x) for x in oqsrand.randombytes(32)),
16+
logger.info(
17+
"System (default): %s",
18+
" ".join(f"{x:02X}" for x in oqsrand.randombytes(32)),
1419
)
1520

1621
# We do not yet support OpenSSL under Windows
1722
if platform.system() != "Windows":
1823
oqsrand.randombytes_switch_algorithm("OpenSSL")
19-
print(
20-
"{:17s}".format("OpenSSL:"),
21-
" ".join("{:02X}".format(x) for x in oqsrand.randombytes(32)),
24+
logger.info(
25+
"OpenSSL: %s",
26+
" ".join(f"{x:02X}" for x in oqsrand.randombytes(32)),
2227
)

examples/sig.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
11
# Signature Python example
2+
import logging
3+
from pprint import pformat
24

35
import oqs
4-
from pprint import pprint
56

6-
print("liboqs version:", oqs.oqs_version())
7-
print("liboqs-python version:", oqs.oqs_python_version())
8-
print("Enabled signature mechanisms:")
9-
sigs = oqs.get_enabled_sig_mechanisms()
10-
pprint(sigs, compact=True)
7+
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.INFO)
8+
logger = logging.getLogger(__name__)
9+
logger.setLevel(logging.INFO)
1110

12-
message = "This is the message to sign".encode()
11+
logger.info("liboqs version: %s", oqs.oqs_version())
12+
logger.info("liboqs-python version: %s", oqs.oqs_python_version())
13+
logger.info(
14+
"Enabled signature mechanisms: %s",
15+
pformat(oqs.get_enabled_sig_mechanisms(), compact=True),
16+
)
17+
18+
message = b"This is the message to sign"
1319

1420
# Create signer and verifier with sample signature mechanisms
1521
sigalg = "Dilithium2"
16-
with oqs.Signature(sigalg) as signer:
17-
with oqs.Signature(sigalg) as verifier:
18-
print("\nSignature details:")
19-
pprint(signer.details)
22+
with oqs.Signature(sigalg) as signer, oqs.Signature(sigalg) as verifier:
23+
logger.info("Signature details: %s", pformat(signer.details))
2024

21-
# Signer generates its keypair
22-
signer_public_key = signer.generate_keypair()
23-
# Optionally, the secret key can be obtained by calling export_secret_key()
24-
# and the signer can later be re-instantiated with the key pair:
25-
# secret_key = signer.export_secret_key()
25+
# Signer generates its keypair
26+
signer_public_key = signer.generate_keypair()
27+
# Optionally, the secret key can be obtained by calling export_secret_key()
28+
# and the signer can later be re-instantiated with the key pair:
29+
# secret_key = signer.export_secret_key()
2630

27-
# Store key pair, wait... (session resumption):
28-
# signer = oqs.Signature(sigalg, secret_key)
31+
# Store key pair, wait... (session resumption):
32+
# signer = oqs.Signature(sigalg, secret_key)
2933

30-
# Signer signs the message
31-
signature = signer.sign(message)
34+
# Signer signs the message
35+
signature = signer.sign(message)
3236

33-
# Verifier verifies the signature
34-
is_valid = verifier.verify(message, signature, signer_public_key)
37+
# Verifier verifies the signature
38+
is_valid = verifier.verify(message, signature, signer_public_key)
3539

36-
print("\nValid signature?", is_valid)
40+
logger.info("Valid signature? %s", is_valid)

0 commit comments

Comments
 (0)