Post-quantum (Falcon-1024) inscription tooling for Algorand: a deterministic signer in the exact encoding the native falcon_verify opcode accepts, on-chain message construction, and the pubkey-box-commit / 2048-byte arg-cap helpers.
Project description
trelyan-pq
Post-quantum (Falcon-1024) inscription tooling for Algorand. An open, MIT-licensed Python
SDK that turns the TRELYAN reference implementation
into importable infrastructure: build post-quantum-authenticated, write-once records on Algorand
using the network's native falcon_verify opcode.
This package exists so you don't lose a week to the two non-obvious integration traps the reference solved:
- The opcode needs deterministic, COMPRESSED Falcon-1024 with header
0xBA— generic liboqs/pqcrypto Falcon is randomized and gets rejected on-chain.trelyan_pq.falconproduces exactly the accepted bytes. - A single app call's ApplicationArgs are capped at 2048 bytes, but a Falcon-1024 public key
(1793 B) + compressed signature (≤1423 B) is ~3 KB.
trelyan_pq.messagegives you the pubkey-box-commit + box-name helpers that mirror the contract's layout, so you commit the key once and pass only the signature at inscribe.
Status: alpha. Validated on localnet (20/20) and Algorand TestNet. Not externally audited; not for MainNet value. Treat as a reference/building block.
Install
pip install trelyan-pq # core: message + encoding + signer (stdlib-only)
pip install "trelyan-pq[algorand]" # + the high-level on-chain client (algokit-utils)
The signer needs the algorand/falcon C library built once (it is not a pip package):
git clone https://github.com/algorand/falcon && cd falcon
cc -O3 -fPIC -shared -o libfalcondet1024.so \
codec.c common.c falcon.c fft.c fpr.c keygen.c rng.c shake.c sign.c vrfy.c deterministic.c
export FALCON_DET1024_LIB="$PWD/libfalcondet1024.so" # .dylib on macOS, .dll on Windows
Core API (no network needed)
from trelyan_pq import FalconDet1024, build_message, sha512_256, box_refs
falcon = FalconDet1024() # uses $FALCON_DET1024_LIB
pubkey, privkey = falcon.keygen() # 1793-byte pubkey, 2305-byte privkey
# Reconstruct the EXACT message the contract verifies on-chain (do not pre-hash it):
M = build_message(app_id=1001, cell_id=1,
artifact_hash=sha512_256(b"my artifact"),
genesis_hash=GENESIS_32_BYTES)
sig = falcon.sign(privkey, M) # first byte is 0xBA
assert falcon.verify(sig, pubkey, M)
assert box_refs(1) == [b"k_...", b"o_...", b"i_..."] # the 3 boxes an inscribe touches
On-chain client
from trelyan_client import TrelyanInscriptionFactory # generated from the contract ARC-56
from trelyan_pq.inscription import TrelyanInscriptionClient
c = TrelyanInscriptionClient.deploy_testnet(MNEMONIC, TrelyanInscriptionFactory)
c.fund_app()
pk, sk = c.signer.keygen()
cell = c.mint_cell() # clean pure-NFT cell ASA
c.register_cell(cell, c.deployer.address, pk) # commit the Falcon key (once)
c.inscribe_bytes(cell, b"my artifact", sk, b"ipfs://...")
assert c.read_back_matches(cell, b"my artifact")
The generated TrelyanInscriptionFactory is build-specific — produce it from the contract's
ARC-56 with algokit generate client ... (see the reference repo) and pass the class in.
What's in the box
| Module | Needs | Purpose |
|---|---|---|
trelyan_pq.message |
stdlib only | byte-exact message M, sha512_256, box names/refs, constants |
trelyan_pq.falcon |
the Falcon C lib | deterministic Falcon-1024 keygen / sign / verify (0xBA encoding) |
trelyan_pq.inscription |
[algorand] extra |
high-level deploy / register / inscribe / read-back client |
Develop / test
pip install "trelyan-pq[dev]"
PYTHONPATH=src pytest tests -v # pure-Python wire-format tests (no lib/network needed)
Security & scope
- Scope: this is app-level post-quantum inscription signing — a contract verifies a Falcon-1024 signature and writes a write-once record. It is not a replacement for Algorand account/transaction authentication or consensus security.
- Unaudited, alpha. Validated on localnet (20/20) and TestNet; not externally audited and not for MainNet value. An independent audit is planned before any MainNet use.
- Native C dependency. The signer is a
ctypesbinding to thealgorand/falconC library you build yourself — provenance and a reproducible build are your responsibility. No constant-time / side-channel guarantees are claimed for the binding. - Sign through
sign_inscription(), not rawsign(): the domain-separated message bindsapp_id,cell_id, artifact, and network genesis, which is what makes a signature non-replayable across apps/cells/networks. - Disclosure: report security issues privately per the reference repo's
SECURITY.md. - Independent of, and not endorsed by, the Algorand Foundation.
License
MIT. See the reference repository for the protocol spec, threat model, and validation record.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file trelyan_pq-0.1.0.tar.gz.
File metadata
- Download URL: trelyan_pq-0.1.0.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf66583aebd00981d0d4816bfb2f0ad469049425a59138ea1171d793cd3f5a64
|
|
| MD5 |
84f2140bd7321d21ffebb411d1dd357e
|
|
| BLAKE2b-256 |
109f9f72624f9ce472618caf3e0ef1520dc9ab5e5872bd8e8da839ce3bc59d5f
|
File details
Details for the file trelyan_pq-0.1.0-py3-none-any.whl.
File metadata
- Download URL: trelyan_pq-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf470973ded5e5686eed3af841a54a857701e5304659c9c1d920d8d815efa334
|
|
| MD5 |
2bbb8420a8260e10dda9148475f04350
|
|
| BLAKE2b-256 |
72e14cf9ad5f5f0c8a95ce03d5273168fa3162aeba250ba68c54796263f10816
|