Sortes — true ECVRF verifiable-randomness oracle
Sortes draws lots you can verify. It is a true Verifiable Random Function
implementing ECVRF-EDWARDS25519-SHA512-TAI exactly per
RFC 9381 (suite octet 0x03, over the
edwards25519 curve).
For a fixed (public_key, alpha) there is exactly one valid output beta.
The oracle's secret key selects it deterministically, so — unlike a trusted
randomness beacon — the oracle cannot grind or bias the result, and anyone
holding the VRF public key can verify the draw offline from the 80-byte proof.
Capabilities
| capability | price | what it does |
|---|---|---|
sortes.draw@v1 |
$0.006 | Draw verifiable randomness for alpha. Returns public_key, proof (gamma, c, s, pi), beta, and output (uniform num_bytes). The secret key is never returned. |
sortes.verify@v1 |
$0.001 | Verify (public_key, alpha, pi) offline and trustlessly → {valid, beta}. |
alpha is UTF-8 by default; prefix with hex: to pass raw bytes.
Why it is correct
The implementation is pure Python (hashlib + integer math) — the edwards25519
group arithmetic (RFC 8032 §5.1) and the ECVRF construction (RFC 9381 §5) are
written from scratch, no external crypto libraries. Correctness is proven by the
RFC 9381 Appendix B.3 test vectors: the tests assert that our implementation
reproduces the published SK→PK, the hash-to-curve point H, the proof
commitment Gamma, the VRF output beta, and the full 80-byte proof pi
byte-for-byte for all three vectors. The full-pi check pins the little-endian
c || s encoding mandated by RFC 9381 §5.5, so the proofs are byte-interoperable
with a conformant verifier (e.g. libsodium), not merely self-consistent; the tests
also confirm the RFC's own published pi bytes verify under our verifier. See
tests/test_sortes.py.
VRF keypair
The oracle holds one VRF keypair. The 32-byte secret key is resolved from
SORTES_VRF_SK (64 hex chars), else a persisted key at SORTES_VRF_SK_PATH
(default data/sortes_vrf_sk), else generated once and persisted so the public
key stays stable across restarts. The secret key never leaves the process; the
public key is published in every draw and in the manifest description.
Run
# tests (from the monorepo root)
PYTHONPATH="oracles/core:oracles/oracles/sortes" \
platon/backend/.venv/bin/python -m pytest oracles/oracles/sortes/tests/ -q
# serve (port 9310 by default)
PYTHONPATH="oracles/core:oracles/oracles/sortes" python -m sortes.main
Environment
| var | default | meaning |
|---|---|---|
SORTES_PORT |
9310 |
listen port |
SORTES_PUBLIC_URL |
http://localhost:9310 |
advertised base URL |
SORTES_SIGNING_KEY |
data/sortes_signing_key |
manifest/receipt signing key path |
SORTES_VRF_SK |
(unset) | explicit 32-byte VRF secret key (hex) |
SORTES_VRF_SK_PATH |
data/sortes_vrf_sk |
persisted VRF secret key path |
SORTES_CORS_ORIGINS |
* |
allowed CORS origins |
Metadata
Release files for aimarket-oracle-sortes 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aimarket_oracle_sortes-0.1.0.tar.gz | 16.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aimarket_oracle_sortes-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.4 kB
Release files / aimarket_oracle_sortes-0.1.0.tar.gz
| Download URL | aimarket_oracle_sortes-0.1.0.tar.gz |
|---|---|
| Size | 16.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b405f49b8182cd90081ff1b0005e62748645343887e68478cfb4477951b65e96
|
|
BLAKE2b-256 checksum How to use checksums |
823db0b77960616fbffc81115d98787b6ce7412ebc7c32123e876ada595e25f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / aimarket_oracle_sortes-0.1.0-py3-none-any.whl
| Download URL | aimarket_oracle_sortes-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bc4d75c3d8b5fe0dd2c8041642b2c4a1209a1473d2b0399a089eb61a345b607d
|
|
BLAKE2b-256 checksum How to use checksums |
a6c9df6193fed84bdc797f122817cbc1e36f3f2d5c3671dbe9750196c3ba112c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|