Skip to content

Commit

Permalink
Move project to uv
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
andrew000 committed Nov 13, 2024
1 parent 7a1c2f6 commit 36be44b
Show file tree
Hide file tree
Showing 17 changed files with 648 additions and 319 deletions.
45 changes: 24 additions & 21 deletions .github/workflows/python_detailed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: GitHub actions detailed

on:
push:
branches: ["**"]
branches: [ "**" ]
pull_request:
branches: ["**"]
branches: [ "**" ]
repository_dispatch:
types: ["**"]
types: [ "**" ]

permissions:
contents: read
Expand All @@ -20,21 +20,24 @@ jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ ubuntu-latest, macos-latest, windows-latest ]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python 3.10
uses: actions/setup-python@v3
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
python-version: "3.10"
version: "latest"
enable-cache: true
cache-dependency-glob: "**/pyproject.toml"

- name: Set up Python 3.9
run: uv python install 3.9

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install nose2
run: uv sync --extra dev

- name: Install liboqs POSIX
if: matrix.os != 'windows-latest'
Expand All @@ -47,17 +50,17 @@ jobs:
- name: Run examples POSIX
if: matrix.os != 'windows-latest'
run: |
pip install .
python examples/kem.py
uv sync --extra dev
uv run examples/kem.py
echo
python examples/sig.py
uv run examples/sig.py
echo
python examples/rand.py
uv run examples/rand.py
- name: Run unit tests POSIX
if: matrix.os != 'windows-latest'
run: |
nose2 --verbose
uv run nose2 --verbose
- name: Install liboqs Windows
if: matrix.os == 'windows-latest'
Expand All @@ -73,16 +76,16 @@ jobs:
shell: cmd
run: |
set PATH=%PATH%;${{env.WIN_LIBOQS_INSTALL_PATH}}\bin
pip install .
python examples/kem.py
uv sync --extra dev
uv run examples/kem.py
echo.
python examples/sig.py
uv run examples/sig.py
echo.
python examples/rand.py
uv run examples/rand.py
- name: Run unit tests Windows
shell: cmd
if: matrix.os == 'windows-latest'
run: |
set PATH=%PATH%;${{env.WIN_LIBOQS_INSTALL_PATH}}\bin
nose2 --verbose
uv run nose2 --verbose
32 changes: 18 additions & 14 deletions .github/workflows/python_simplified.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: GitHub actions simplified

on:
push:
branches: ["**"]
branches: [ "**" ]
pull_request:
branches: ["**"]
branches: [ "**" ]
repository_dispatch:
types: ["**"]
types: [ "**" ]

permissions:
contents: read
Expand All @@ -15,25 +15,29 @@ jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ ubuntu-latest, macos-latest, windows-latest ]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Python 3.10
uses: actions/setup-python@v3
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
python-version: "3.10"
version: "latest"
enable-cache: true
cache-dependency-glob: "**/pyproject.toml"

- name: Set up Python 3.9
run: uv python install 3.9

- name: Run examples
run: |
python -m pip install --upgrade pip
pip install .
python examples/kem.py
python examples/sig.py
python examples/rand.py
uv sync --extra dev
uv run examples/kem.py
uv run examples/sig.py
uv run examples/rand.py
- name: Run unit tests
run: |
nose2 --verbose
uv run nose2 --verbose
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,5 @@ pip-selfcheck.json
pyvenv.cfg

# vim
*.swp
*.swp
/uv.lock
38 changes: 38 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
fail_fast: false
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: "trailing-whitespace"
- id: "check-case-conflict"
- id: "check-merge-conflict"
- id: "debug-statements"
- id: "end-of-file-fixer"
- id: "mixed-line-ending"
args: [ "--fix", "crlf" ]
types:
- python
- yaml
- toml
- text
- id: "detect-private-key"
- id: "check-yaml"
- id: "check-toml"
- id: "check-json"

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.7.3
hooks:
- id: ruff
args: [ "--fix" ]
files: "oqs"

- id: ruff-format
files: "oqs"

- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
files: "oqs"
37 changes: 37 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
src-dir = oqs
tests-dir = tests
examples-dir = examples

.PHONY pull:
pull:
git pull origin master
git submodule update --init --recursive

.PHONY lint:
lint:
echo "Running ruff..."
uv run ruff check --config pyproject.toml --diff $(src-dir) $(tests-dir) $(examples-dir)

.PHONY format:
format:
echo "Running ruff check with --fix..."
uv run ruff check --config pyproject.toml --fix --unsafe-fixes $(src-dir) $(tests-dir) $(examples-dir)

echo "Running ruff..."
uv run ruff format --config pyproject.toml $(src-dir) $(tests-dir) $(examples-dir)

echo "Running isort..."
uv run isort --settings-file pyproject.toml $(src-dir) $(tests-dir) $(examples-dir)

.PHONE mypy:
mypy:
echo "Running MyPy..."
uv run mypy --config-file pyproject.toml

.PHONY outdated:
outdated:
uv tree --outdated --universal

.PHONY sync:
sync:
uv sync --extra dev --extra lint
Empty file added examples/__init__.py
Empty file.
51 changes: 27 additions & 24 deletions examples/kem.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
# Key encapsulation Python example
import logging
from pprint import pformat

import oqs
from pprint import pprint

print("liboqs version:", oqs.oqs_version())
print("liboqs-python version:", oqs.oqs_python_version())
print("Enabled KEM mechanisms:")
kems = oqs.get_enabled_kem_mechanisms()
pprint(kems, compact=True)
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.INFO)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

logger.info("liboqs version: %s", oqs.oqs_version())
logger.info("liboqs-python version: %s", oqs.oqs_python_version())
logger.info("Enabled KEM mechanisms: %s", pformat(oqs.get_enabled_kem_mechanisms(), compact=True))

# Create client and server with sample KEM mechanisms
kemalg = "Kyber512"
with oqs.KeyEncapsulation(kemalg) as client:
with oqs.KeyEncapsulation(kemalg) as server:
print("\nKey encapsulation details:")
pprint(client.details)
with oqs.KeyEncapsulation(kemalg) as client, oqs.KeyEncapsulation(kemalg) as server:
# print("\nKey encapsulation details:")
logger.info("Client details: %s", pformat(client.details))

# Client generates its keypair
public_key_client = client.generate_keypair()
# Optionally, the secret key can be obtained by calling export_secret_key()
# and the client can later be re-instantiated with the key pair:
# secret_key_client = client.export_secret_key()
# Client generates its keypair
public_key_client = client.generate_keypair()
# Optionally, the secret key can be obtained by calling export_secret_key()
# and the client can later be re-instantiated with the key pair:
# secret_key_client = client.export_secret_key()

# Store key pair, wait... (session resumption):
# client = oqs.KeyEncapsulation(kemalg, secret_key_client)
# Store key pair, wait... (session resumption):
# client = oqs.KeyEncapsulation(kemalg, secret_key_client)

# The server encapsulates its secret using the client's public key
ciphertext, shared_secret_server = server.encap_secret(public_key_client)
# The server encapsulates its secret using the client's public key
ciphertext, shared_secret_server = server.encap_secret(public_key_client)

# The client decapsulates the server's ciphertext to obtain the shared secret
shared_secret_client = client.decap_secret(ciphertext)
# The client decapsulates the server's ciphertext to obtain the shared secret
shared_secret_client = client.decap_secret(ciphertext)

print(
"\nShared secretes coincide:", shared_secret_client == shared_secret_server
)
logger.info(
"Shared secretes coincide: %s",
shared_secret_client == shared_secret_server,
)
25 changes: 15 additions & 10 deletions examples/rand.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
# Various RNGs Python example

import logging
import platform # to learn the OS we're on

import oqs.rand as oqsrand # must be explicitly imported
from oqs import oqs_version, oqs_python_version
from oqs import oqs_python_version, oqs_version

logging.basicConfig(format="%(asctime)s %(message)s", level=logging.INFO)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

print("liboqs version:", oqs_version())
print("liboqs-python version:", oqs_python_version())
logger.info("liboqs version: %s", oqs_version())
logger.info("liboqs-python version: %s", oqs_python_version())

oqsrand.randombytes_switch_algorithm("system")
print(
"{:17s}".format("System (default):"),
" ".join("{:02X}".format(x) for x in oqsrand.randombytes(32)),
logger.info(
"System (default): %s",
" ".join(f"{x:02X}" for x in oqsrand.randombytes(32)),
)

# We do not yet support OpenSSL under Windows
if platform.system() != "Windows":
oqsrand.randombytes_switch_algorithm("OpenSSL")
print(
"{:17s}".format("OpenSSL:"),
" ".join("{:02X}".format(x) for x in oqsrand.randombytes(32)),
logger.info(
"OpenSSL: %s",
" ".join(f"{x:02X}" for x in oqsrand.randombytes(32)),
)
50 changes: 27 additions & 23 deletions examples/sig.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
# Signature Python example
import logging
from pprint import pformat

import oqs
from pprint import pprint

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

message = "This is the message to sign".encode()
logger.info("liboqs version: %s", oqs.oqs_version())
logger.info("liboqs-python version: %s", oqs.oqs_python_version())
logger.info(
"Enabled signature mechanisms: %s",
pformat(oqs.get_enabled_sig_mechanisms(), compact=True),
)

message = b"This is the message to sign"

# Create signer and verifier with sample signature mechanisms
sigalg = "Dilithium2"
with oqs.Signature(sigalg) as signer:
with oqs.Signature(sigalg) as verifier:
print("\nSignature details:")
pprint(signer.details)
with oqs.Signature(sigalg) as signer, oqs.Signature(sigalg) as verifier:
logger.info("Signature details: %s", pformat(signer.details))

# Signer generates its keypair
signer_public_key = signer.generate_keypair()
# Optionally, the secret key can be obtained by calling export_secret_key()
# and the signer can later be re-instantiated with the key pair:
# secret_key = signer.export_secret_key()
# Signer generates its keypair
signer_public_key = signer.generate_keypair()
# Optionally, the secret key can be obtained by calling export_secret_key()
# and the signer can later be re-instantiated with the key pair:
# secret_key = signer.export_secret_key()

# Store key pair, wait... (session resumption):
# signer = oqs.Signature(sigalg, secret_key)
# Store key pair, wait... (session resumption):
# signer = oqs.Signature(sigalg, secret_key)

# Signer signs the message
signature = signer.sign(message)
# Signer signs the message
signature = signer.sign(message)

# Verifier verifies the signature
is_valid = verifier.verify(message, signature, signer_public_key)
# Verifier verifies the signature
is_valid = verifier.verify(message, signature, signer_public_key)

print("\nValid signature?", is_valid)
logger.info("Valid signature? %s", is_valid)
Loading

0 comments on commit 36be44b

Please sign in to comment.