Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.

Quipu

License: AGPL v3 crates.io docs.rs CI post-quantum

🇪🇸 Léeme en español → — the Spanish version is the original and both are kept in sync.

An encoding library with cryptographic protection and a pluggable symbol alphabet.

"Wheel and caterpillar track" philosophy: where good cryptography already exists we reuse it (XChaCha20-Poly1305, Argon2id, HKDF, ML-KEM, X25519); where the ground is new (representation, symbols, format) we innovate. We never invent cryptographic primitives: security lives in the key and the AEAD, never in the representation.

What it does

Protects data and renders it as symbols — dense text or an image — reversibly and with authentication.

data → KDF(passphrase+pepper) → AEAD → container → base-N codec → dictionary → symbols

Modes

Mode API (Rust) Description
Symmetric (passphrase) api::encode / api::decode Argon2id + XChaCha20-Poly1305
Post-quantum (public key) api::encode_to_recipient / decode_as_recipient Hybrid X25519 + ML-KEM-1024 (X-Wing-style bound transcript)
Online (hardening) api::encode_online / decode_online VOPRF per RFC 9497 (ristretto255-SHA512, DLEQ proof): the client detects a dishonest server
Signed (authenticity) api::encode_signed / decode_verified Hybrid signature Ed25519 + ML-DSA-87 (AND combiner). Verifiable authenticity and non-repudiation; not confidentiality
Triple-signed (high assurance, feature slh) api::encode_signed_triple / decode_verified_triple Triple-hybrid Ed25519 + ML-DSA-87 + SLH-DSA-256s (AND 3-of-3): unforgeable as long as ≥1 of {curve, lattice, hash} survives. Opt-in; ~34 KB signature
Streaming (large files) api::encrypt_stream / decrypt_stream Chunked encryption (bounded memory) for large data at rest; resistant to truncation, reordering and splicing. QST1 container
Decoys / Honey (feature honey) honey::encrypt_pin / decrypt_pin (and generic encrypt/decrypt) Honey Encryption for low-entropy secrets (a PIN, a mnemonic phrase): any wrong passphrase decrypts to another plausible secret, not to an error → no brute-force oracle. Opt-in. Unauthenticated by design (a tag would itself be an oracle); it does not replace the AEAD core, and only suits uniform sequences
Deniability (feature negacion) negacion::crear / abrir One file, two passphrases: one opens the decoy you hand over under coercion, the other the real volume. Nothing inside the container says whether the second exists, and the remainder is filled with randomness whether it does or not. Opt-in. See the limit in bold below

A scope limit: there is no PUBLIC-KEY streaming

The table above has both modes and they do not cross:

  • encrypt_stream / decrypt_stream (QST1) encrypts in chunks with bounded memory — but it is symmetric: it derives from a passphrase.
  • encode_to_recipient encrypts to a post-quantum public key — but it takes a &[u8] and returns a String: it loads the whole file into memory and runs it through the base-N codec.

So "encrypt a large file to someone else's public key" has no bounded-memory path today. This is not a bug; it is scope nobody has asked for yet, and it is written down here so that nobody discovers it halfway through an integration.

What it would cost, so it need not be re-derived: a QST1 whose header carries the ML-KEM encapsulation instead of the salt and the Argon2id parameters. The content key already comes out of decapsulation, so the rest of the chunk format — per-chunk AAD, resistance to truncation and reordering — carries over unchanged. It is a container variant, not new cryptography.

What actually protects your secret: the three factors, and which to pick

The table above says what each mode does. This one says what it depends on for somebody to be able to open it, which is the question to answer first.

The axis is not "key or file". What decides security is how many attempts the attacker gets, and whether he can make them without asking anyone's permission.

Factor What it is Strong against Weak against
Passphrase (always) what you KNOW. Argon2id turns it into a key theft of the file: there is nothing stored to copy offline, parallel, unlimited guessing — and coercion
pepper (Options::pepper) what you HAVE: an environment variable, code, an HSM. Mixed in before the KDF whoever gets the container but not the pepper cannot even begin to guess being copied without your noticing; if you lose it, the data goes with it
Online VOPRF (encode_online) what a server grants, with a DLEQ proof verified against a pinned key it is the only one that BOUNDS THE NUMBER OF ATTEMPTS: each one requires a query the server can refuse availability — if the server is down, nothing decrypts (R2/N5)

Argon2id makes each attempt expensive; it does not limit how many there are. That sentence orders the table: against somebody holding your container, with time and machines, per-attempt cost only multiplies his bill. The only thing that puts a ceiling on the number of attempts is the VOPRF, and that is why it is the paid service and not an ornament.

Which to use

  • Passphrase alone: if it is long and random (a six-word-plus diceware phrase, not one you made up). No infrastructure, and it is the default. Options::pepper ships empty: by default there is no second factor, and that is worth knowing.
  • Passphrase + pepper: as soon as there is somewhere to keep it that is not the same disk as the container. It is the cheapest improvement available.
  • Passphrase + VOPRF: when the adversary may walk off with the container and has patience. In exchange you accept a dependency on a service — which is why its domain and its key k never rotate: rotating would invalidate everything ever derived.
  • Public-key mode (encode_to_recipient): when whoever encrypts is not who decrypts, or when no human types anything at all (a server encrypting its own database). There is a secret to keep there, and that is what the HSM and k-of-n custody are for.

Why Quipu has no plain "key file"

It would be a single object whose copying leaves no trace and whose loss has no recourse, and it moves the problem to exactly where an attacker with filesystem access is strongest. The pepper is the strictly better version of "something you have": it is not required to be a file — it can live in the environment or in an HSM — and it adds to the passphrase instead of replacing it. Adding a key file on top would look like more protection while introducing a single point of failure.

Deniability: what it promises and what it does NOT (feature negacion)

It protects against PROOF, not against the SUSPICION of somebody who has already decided to suspect. Under physical coercion that distinction may be worth nothing. This is not "undetectable encryption", and whoever uses it may be someone whose freedom depends on understanding the difference.

The threat model assumes the adversary sees the container once. Anyone who keeps successive versions of the same file in a backup — or syncs it to the cloud — loses deniability: comparing two snapshots reveals which region changed.

What is measured, with red cases that turn the bench red: the container is indistinguishable from randomness, no byte position is predictable, one with a hidden volume is indistinguishable from one without, and opening the decoy costs the same as opening the hidden volume (t = 0.73, threshold 10). The design, the deviations and the measurements are in docs/DISENO_NEGACION.md.

It does not ship in the Python wheels in this version: a misused API here does not produce an error, it produces a false sense of deniability.

Key custody (k-of-n, feature escrow)

quipu::shamir splits a secret into n shares of which any k reconstruct it and k-1 reveal nothing. It sits behind an opt-in feature gate: it is an escrow tool, not part of the encryption core, and whoever does not need it does not compile it in. It serves to back up the OPRF server key, to hold an integrator's signing key, or to set up a contractual escrow — without network and without an HSM, which is the condition of an air-gapped deployment.

let shares = quipu::shamir::split(&key, 3, 5)?;   // 3 of 5
let key = quipu::shamir::combine(&shares[..3])?;

Each share carries a verifier, so a corrupt one — or one from a different split — is detected instead of returning garbage. That verifier would allow checking guesses at a guessable secret, so the module rejects secrets shorter than the smallest key material the architecture itself produces (kdf::KEY_LEN, 32 bytes): it is for keys, and for guessable things there is honey. It is not threshold signing — the secret is reconstructed in memory in order to be used.

Device-held signing (HSM/PKCS#11, feature hsm)

The private signing key can live inside an HSM, token or PKCS#11 card and never leave it. This is the answer to a security committee's first question, and it works with the full hybrid signature: both halves — Ed25519 and ML-DSA-87 — are generated and used inside the device; only signatures and the public key come out of the library.

The firmante::Custodio trait separates who holds the key from how the signature is assembled. It asks for operations, never for material: there is no way to extract the key, because that is the entire point. A signature made in an HSM and one made in memory are verified by the same verifier, which cannot tell them apart.

Corrected on 2026-08-01. This sentence used to say they were identical byte for byte, and that is false: PKCS#11 is asked for HedgeType::Preferred, i.e. randomized ML-DSA if the device supports it, while the in-memory path signs deterministically. The bytes differ; what does not change is that both verify under the same key with the same verifier, which is all a caller needs. Hedging is moreover what FIPS-204 recommends against fault injection, so the difference works in our favour.

An independent review found it, and the test that backed the claim — firmar_por_el_trait_da_lo_mismo_que_el_camino_directoonly exercises the in-memory custodian, where the equality holds trivially because both paths call the same code. It was passing for the wrong reason.

// The usual in-memory custodian (default, no feature):
let sig = firmante::firmar(&firmante::EnMemoria::nuevo(sk), message)?;

// Or against a PKCS#11 device, key held inside (feature `hsm`):
let custodian = CustodioPkcs11::por_etiqueta(session, "firma-ed", "firma-ml")?;
let sig = firmante::firmar(&custodian, message)?;  // the key never crosses here

With escrow, firmar_con_comparticiones reconstructs from Shamir, signs and wipes in a single Rust call, without the key crossing into the bindings. Tested end to end — 128 concurrent signatures against a real token, each one verified — and in the Python binding (quipu.CustodioHsm), which ships in the wheel.

Dictionaries (pluggable symbol alphabets)

  • dictionaries::ascii94() — 94 ASCII symbols (universal copy-paste).
  • dictionaries::flagship() — 4096 glyphs (12 bits/symbol, ~2× denser).
  • dictionaries::from_range(start, count) — a custom alphabet.

Security and hardening

  • Pre-layers: NFKC normalization, pepper, Padmé padding (hides length), context binding (AAD), HKDF (subkey separation).

  • Antihacker: key wiping in memory (zeroize), constant-time comparison, KDF parameter validation, uniform errors.

  • Entropy failure, never a silent substitution: when the operating system cannot provide randomness, Quipu does not fall back to a weaker source — no key is ever born from a dead RNG. The failure is reported as an actionable error (do I retry, or do I fix the deployment?) with a bounded retry for the one transient case, rather than a panic: that way memory cleanup (Drop/zeroize) still runs, which is exactly when it matters most. This is the Debian OpenSSL 2008 failure mode — predictable keys that look correct — prevented by construction, and there is a self-test that warns at start-up instead of killing the process.

  • Start-up self-tests (quipu::selftest): 14 known-answer vectors run against the binary that is actually executing, not against the CI build. They run once per process on entry through any core path, and if one fails the module refuses to operate rather than silently producing wrong results.

    A failing self-test does not mean Quipu is broken: it means the machine is not executing the cryptography correctly — a wheel compiled for another processor, a damaged or substituted file, faulty memory. They introduce no failure modes; they make visible the ones that were already there.

    They go beyond what FIPS 140-3 and the Chinese GM/T standards require in three ways: they use published vectors where these exist (HKDF against RFC 5869, not home-made vectors that only prove self-consistency), they include negative tests (tampered input must fail), and they monitor RNG health continuously. Every check is itself proved to discriminate: one that always returned true would pass a conventional battery exactly like a correct one.

    Verified with 1300 simulated operations — 200 passes, 100 concurrent threads, 1000 repeated calls — and with fault injection to exercise the error path, both in CI.

  • Hackerbot: internal red team (tamper/truncation/uniqueness). It found, and we fixed, a DoS via malicious Argon2 parameters.

  • Security Lab (features lab / lab-offline, absent from the published build): an adaptive red team that attacks itself. Core in CI (format leakage + signature forgery) with a chained corpus and meta-tests that fail if an antihacker defence is weakened; plus an isolated offline bench (network- less container) for timing and AI-accelerated guessing cost. cargo run --example securitylab --features lab · bash lab/run.sh. See lab/README.md and THREAT_MODEL.md §9.

Usage (Rust)

use quipu::api::{encode, decode, Options};
use quipu::dictionaries;

let dict = dictionaries::ascii94();
let sym = encode(b"secret", "passphrase", &dict, &Options::default());
let data = decode(&sym, "passphrase", &dict, b"").unwrap();

Hybrid signature (third-party-verifiable authenticity, post-quantum):

use quipu::api::{encode_signed, decode_verified};
use quipu::{dictionaries, pqsign};

let dict = dictionaries::ascii94();
let (vk, sk) = pqsign::generate_keypair();
let signed = encode_signed(b"official record", &sk, &dict);
let msg = decode_verified(&signed, &vk, &dict).unwrap(); // fails if tampered with

Usage (Python)

pip install quipu-crypto   # installs as "quipu-crypto", imports as "quipu"
import quipu
s = quipu.encode(b"secret", "passphrase")
assert quipu.decode(s, "passphrase") == b"secret"

# Post-quantum
pub, sec = quipu.generate_keypair()
s = quipu.encode_to_recipient(b"secret", pub)
assert quipu.decode_as_recipient(s, sec) == b"secret"

# Hybrid signature (authenticity, post-quantum)
vk, sk = quipu.generate_signing_keypair()
signed = quipu.encode_signed(b"official record", sk)
assert quipu.decode_verified(signed, vk) == b"official record"  # fails if tampered with

# Streaming AEAD for large data (binary output, not symbols)
blob = quipu.encrypt_stream(b"...large data...", "passphrase")
assert quipu.decrypt_stream(blob, "passphrase") == b"...large data..."

Runnable examples

Round-trip of every mode, ready to run:

cargo run --example quickstart          # Rust   (examples/quickstart.rs)
python examples/quickstart.py           # Python (examples/quickstart.py)

Build and test

cargo test                      # unit + property tests
cargo clippy --all-targets      # lint
cargo run --example demo        # symmetric demo
cargo run --example v2demo      # post-quantum + OPRF + image
cargo run --example hackerbot   # red team
cargo run --example testplatform --release   # full battery
cargo run --example securitylab --features lab   # security lab (adaptive red team)
cargo run --example redteam --features "lab slh honey" --release   # consolidated red team (all surfaces)
bash lab/run.sh   # isolated offline bench (timing + guessing) — Stage B

# Coverage-guided fuzzing (libFuzzer, nightly). Targets: parse_container,
# honey_decrypt, unpad, codec_roundtrip.
cargo +nightly fuzz run honey_decrypt

# Python bindings
source venv/bin/activate
maturin develop --features python
python tests/python/test_quipu.py

Status

v1 + v1.1 + v2 + streaming AEAD (QST1) + honey (QHNY) + signatures (hybrid Ed25519+ML-DSA-87 and triple with SLH-DSA), all implemented under strict TDD. 380 Rust tests across 38 binaries plus Wycheproof and 15 Python tests, all green; clippy clean, fuzzing without crashes, Miri without UB. Pure Rust: the C ABI, Node and Go are gone — the only binding is the Python wheel (PyO3), published as quipu-crypto on PyPI. Post-quantum parameters at NIST security category 5 (CNSA 2.0): ML-KEM-1024 and ML-DSA-87. Online mode with RFC 9497-conformant VOPRF (ristretto255-SHA512), verified against the official Appendix A.1.2 vectors, hybrid KEM with an X-Wing-style bound transcript, hybrid Ed25519 + ML-DSA-87 signature (AND combiner), and an internal pre-audit (see INFORME_PREAUDITORIA.txt and MODELO_DE_AMENAZA.txt). Security Lab (self-hosted adaptive red team): 14 attacks in CI (--features lab) plus an offline timing/guessing bench (--features lab-offline).

⚠️ Project under development. The internal pre-audit does not substitute for an independent cryptographic audit: do not use this to protect real critical data until that external seal exists.

The family: one core, two profiles

Quipu is not a single crate: it is a primitive-agnostic core with thin profiles on top that declare which cryptography they commit to.

Crate What it is
crates/padme-frame Padmé padding with its length frame, in a separate crate under MIT OR Apache-2.0: no_std, zero dependencies, usable without dragging in everything else's AGPL. It is the only piece here that is useful outside Quipu, and that is why it is the only permissively licensed one.
crates/quipu-nucleo Everything that is not cryptography: container format, base-N codec, Reed-Solomon, the paper-carrier payload. Zero primitives. Padmé padding is re-exported into it from padme-frameprelayers::pad/unpad stay where they were, with the same signature.
quipu (this crate) The default profile: XChaCha20-Poly1305, HKDF-SHA-256, 192-bit extended nonce.
crates/quipu-cnsa The CNSA 2.0-aligned profile: AES-256-GCM, HKDF-SHA-384, 96-bit nonce. NOT FIPS 140-3 validated. And its recipient channel abandons hybridization: it is PURE ML-KEM-1024, with no classical partner. Stronger against a quantum adversary than quipu and weaker against a classical lattice break — whoever picks this profile for a regulatory mandate is also accepting that change of posture, and this is where it gets chosen, so this is where it is said.

The relationship is Devuan's to Debian: not a maintenance fork, but a declared commitment that shares almost everything. The format, the codec and the visual channel live exactly once, in the core, so a bug is fixed once — not two branches diverging until one gets the patch and the other does not.

If you can choose, use quipu. The CNSA profile exists for those under a regulatory mandate: on hardware without AES acceleration, AES-GCM is a regression — slower and harder to write in constant time, because of its substitution tables. ChaCha20 has no tables and is constant-time by construction.

Password hardening (OPRF service)

Argon2 alone:  steal the DB -> offline brute force, at your GPU's speed.
With VOPRF:    steal the DB -> you derive nothing without the server key. Every
               attempt needs a request the operator sees, throttles and cuts off.

There is a managed instance at https://oprf.xiliux.com (beta). The client is a separate crate and Apache-2.0: it does not drag this core's AGPL into your authentication server.

pip install quipu-oprf-django   # Django: only touches PASSWORD_HASHERS
pip install quipu-voprf         # the primitives, for any other stack

The password leaves blinded (the server never sees it) and the server cannot lie: it attaches a DLEQ proof the client verifies against a public key pinned out of band. It fails closed: if the service does not answer or the proof does not validate, it does not degrade to "unhardened".

Documentation

Most documents are in Spanish; the threat model and the pre-audit have English versions, linked above.

⚠️ The internal pre-audit is preparation; it does not substitute for an independent audit. That external seal is the project's next step (an application has been submitted to the OTF Security Lab).

License

A dual licensing (open-core) model. Not the whole repository is AGPL: what a client of the OPRF service links into its own server is permissive.

Component License
quipu (core) and its bindings AGPL-3.0-or-later (see LICENSE)
crates/quipu-nucleo (format, codec, paper carrier) AGPL-3.0-or-later / commercial
crates/padme-frame (Padmé padding, no_std) MIT OR Apache-2.0
crates/quipu-cnsa (CNSA 2.0 profile) AGPL-3.0-or-later / commercial
crates/quipu-voprfquipu-voprf Apache-2.0
integrations/djangoquipu-oprf-django Apache-2.0
crates/quipu-oprf-server AGPL-3.0-or-later / commercial

What exactly is being charged for

Quipu is free/libre and always will be. You can use it today without paying anything. The only condition is publishing the source of what you build on top. If that does not work for you, we sell you an exemption from that obligation.

Put differently: we do not charge for use, we charge for the right not to publish. Copyleft does not forbid charging — the GPL says literally that you may charge any price or none; what it restricts is secrecy, not price.

  • Commercial license — for closed proprietary products or SaaS without opening source. Terms in LICENSE-COMMERCIAL. It is an additional and parallel grant to the AGPL, not a replacement: with or without a contract you keep everything the AGPL grants anyone — use, study, modify, redistribute, sell, fork and even compete. All it adds is exemption from the network copyleft.
  • Managed OPRF server — a different and complementary business: what is sold there is not an exemption but not having to operate the infrastructure or hold the key.

If you can comply with the copyleft, you need not buy anything from us. A free-software project, an academic one, or an organization with an open-source policy uses Quipu for free, and we want them to.

Why AGPL and not GPL: under plain GPL, whoever runs the software as a network service never distributes it, so the copyleft never triggers. AGPL section 13 closes that gap. It was not an ideological choice.

It is the same structure as Qt or MySQL: a free license for those who comply, a commercial license for those who need proprietary terms.

Copyright (c) 2024-2026 Juan Carlos Isaza Arenas — sole holder; see COPYRIGHT. Use of the name "Quipu" is governed by TRADEMARK.md.

The VOPRF primitives live in a separate crate (not merely under a different label): a wrapper's license does not relicense its dependency. Details and the reasoning in LICENSING.md §0. Contact: isazajuancarlos@gmail.com

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quipu_crypto-0.11.1.tar.gz (680.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

quipu_crypto-0.11.1-cp39-abi3-win_amd64.whl (587.6 kB view details)

Uploaded CPython 3.9+Windows x86-64

quipu_crypto-0.11.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (680.6 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

quipu_crypto-0.11.1-cp39-abi3-macosx_11_0_arm64.whl (621.1 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file quipu_crypto-0.11.1.tar.gz.

File metadata

  • Download URL: quipu_crypto-0.11.1.tar.gz
  • Upload date:
  • Size: 680.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for quipu_crypto-0.11.1.tar.gz
Algorithm Hash digest
SHA256 6c05322243d3b873b1b2e565267fa76534398101a888298356889f9a59d49390
MD5 8872b650e78d716a72380bb1c46544e9
BLAKE2b-256 1c580ac7a0d1947d14649c408ac064c665220f438864f7b737f95edc503e0e10

See more details on using hashes here.

Provenance

The following attestation bundles were made for quipu_crypto-0.11.1.tar.gz:

Publisher: release.yml on isazajuancarlos/quipu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quipu_crypto-0.11.1-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: quipu_crypto-0.11.1-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 587.6 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for quipu_crypto-0.11.1-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 e146aebbd5ef634602884b95030fc8747c156c49e50a7aa083242a0466e1f638
MD5 68a5b705dc027a3c6583005e8185e03c
BLAKE2b-256 6cd91ac8e7ae5e2142ea9a66647411e272fe2e47bb898e3eb1110c1d74e34683

See more details on using hashes here.

Provenance

The following attestation bundles were made for quipu_crypto-0.11.1-cp39-abi3-win_amd64.whl:

Publisher: release.yml on isazajuancarlos/quipu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quipu_crypto-0.11.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for quipu_crypto-0.11.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 401cc362e515584b7aae98a1a56ad914727adee81735354b429939328f01a233
MD5 6fdbef8a748603d67559758ac0a3d005
BLAKE2b-256 0c992aa9707ea9da3a161c31285bb5151bbdf4ad3e51867431cd125e27e035d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for quipu_crypto-0.11.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on isazajuancarlos/quipu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quipu_crypto-0.11.1-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for quipu_crypto-0.11.1-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a15e167de4c07803847ffa3d6b0eebfba7dbd1fbeb5569bef2bf38b08daca69c
MD5 93fc27d6783d682e6826c4fb20bb2f33
BLAKE2b-256 e231617a3d132e9d4b35c6d4558b845e9ff4b9c8253d666caf9bb17a611baa9b

See more details on using hashes here.

Provenance

The following attestation bundles were made for quipu_crypto-0.11.1-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on isazajuancarlos/quipu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.11.1 This release

4 files

0.11.0

4 files

0.10.0

4 files

0.9.1

4 files

0.9.0

4 files

0.7.0

4 files

0.6.0

4 files

0.5.0

4 files

0.4.1

4 files

0.4.0

4 files

0.3.0

4 files

0.2.0

4 files

0.1.0

4 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page