hide-protocol for Python
Experimental and unaudited. HIDE is hybrid post-quantum (X25519 + ML-KEM-768, Ed25519 + ML-DSA-65). See the security policy.
Python 3.10+ binding, through ctypes, to the same Rust core (crates/hide-ffi)
that the CLI and every other HIDE SDK use. This package contains no cryptography
of its own.
Install
pip install hide-protocol
The wheel bundles the compiled core, so no toolchain is needed. Wheels are
published for three platforms: manylinux_2_28_x86_64, win_amd64 and
macosx_11_0_arm64. On any other platform, build the core yourself and point
the binding at it (see Native library).
Quick start
import hide_protocol as hide
with hide.SecretKey.generate() as secret:
box = hide.encrypt(b"hello", [secret.public_key()], filename="note.txt")
opened = hide.decrypt(box, secret)
assert opened.data == b"hello" and opened.filename == "note.txt"
tampered = bytearray(box)
tampered[-1] ^= 0x01
try:
hide.decrypt(bytes(tampered), secret)
except hide.AuthenticationError as e:
print("refused:", e) # refused: authentication failed; the data was altered
encrypt takes 1..64 recipient public keys, each exactly PUBLIC_KEY_LEN
(1216) bytes, plus optional filename= and media_type=. decrypt returns a
Decrypted with .data, .filename and .media_type; nothing is returned
unless the whole payload authenticates. The filename is attacker-controlled:
never use it to choose an output path.
Keys on disk: secret.protect(passphrase) returns a sealed key file
(MIN_PASSPHRASE_LEN is 8, and there is no escrow); SecretKey.load(data, passphrase) opens one; inspect_key(data) reports "raw" or "protected"
without the passphrase. armor_public_key / dearmor_public_key give a public
key a pasteable text form.
Errors: every failure is a subclass of hide.HideError — AuthenticationError
(altered, or not a container), its subclass Malformed (did not decode at
all), WrongPassphrase, NoMatchingRecipient, NotAKeyFile,
ChallengeExpired, ChallengeReplayed. Arguments this binding rejects before
calling the core raise ValueError.
Signing and verification
One seed backs both encryption and signing, so there is a single thing to back up.
sealed = hide.SigningIdentity.generate("correct horse battery") # store this
with hide.SigningIdentity.load(sealed, "correct horse battery") as signer:
context, message = b"myapp/v1 release", b"payload"
signature = signer.sign(context, message) # 3373 bytes
hide.verify(signer.public_key(), context, message, signature) # None, or raises
# Challenge/response: good once, here, now.
import time
now = int(time.time())
challenge = hide.new_challenge("app.example", now, 60)
answer = signer.answer(challenge)
with hide.SpentNonces() as spent: # must outlive one request
spent.accept(challenge, answer, signer.public_key(), now)
spent.accept(challenge, answer, signer.public_key(), now) # ChallengeReplayed
context separates uses of one identity so a signature made for one purpose
cannot be replayed as another; never let a remote party choose it. verify
returns None and raises AuthenticationError on failure rather than
returning a boolean a caller could forget to check. A key file written before
signatures existed carries no signing seed and raises NotAKeyFile.
Identity logs, epoch chains, transparency proofs
| Function | Returns |
|---|---|
verify_identity(log, recovery_key) |
int — how many devices the log trusts now |
identity_trusts_device(log, recovery_key, device_public_key) |
bool — membership, after verifying the log |
identity_head(log, recovery_key) |
32 bytes naming this exact history |
verify_epoch_chain(chain) |
int — how many epochs it holds |
epoch_public_key(chain, epoch) |
the public key to encrypt to for epoch |
verify_inclusion(leaf, index, size, path, root) |
None |
verify_consistency(old_size, new_size, path, old_root, new_root) |
None |
A cryptographic verify raises on failure (Malformed if the bytes did not
decode, AuthenticationError if they decoded but did not verify) and never
returns False. The one boolean is identity_trusts_device: the log is
verified first, so False means "not a member", never "did not verify".
Native library
The core is located in this order:
HIDE_LIBRARY, if it names a file andHIDE_ALLOW_LIBRARY_OVERRIDE=1is also set;- the library bundled inside the package (
hide_ffi.dll,libhide_ffi.dyliborlibhide_ffi.sobeside_binding.py); - the system loader, by name.
HIDE_LIBRARY is a development override: it replaces the entire cryptographic
core, so a single settable environment variable must not be enough to redirect
it. Against a local build:
cargo build --release -p hide-ffi
export HIDE_LIBRARY="$PWD/target/release/libhide_ffi.so" # hide_ffi.dll / libhide_ffi.dylib
export HIDE_ALLOW_LIBRARY_OVERRIDE=1
Key material
SecretKey and SigningIdentity are opaque handles. The seed bytes stay in the
native library and this SDK exposes no accessor for them; repr() shows only
whether the handle is open. Release a handle with close() or a with block
(it is also released on garbage collection, but that leaves key material in
memory for an unbounded time). A closed handle raises ValueError on use.
Limits
- Unaudited. Do not protect data you cannot afford to lose or expose.
- An identity is a key, not a person: a verified signature proves possession of a seed, nothing about who holds it.
- Full threat model: docs/threat-model.md.
Links
- Repository: https://github.com/hide-protocol/hide
- Documentation: docs/
- Specification: spec/hide-0.1.md
- CHANGELOG
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
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 hide_protocol-0.7.0-py3-none-win_amd64.whl.
File metadata
- Download URL: hide_protocol-0.7.0-py3-none-win_amd64.whl
- Upload date:
- Size: 347.5 kB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1be5f231925578c60a1cd07d8325b93d57a82a90d0a636e01e1c1196f39d5666
|
|
| MD5 |
5503eb6b8889bcee62a9dac26ef84631
|
|
| BLAKE2b-256 |
b1d218bd65abd73e2e7c5fd45301966c4613e5e8ca11f70f3c172276198f0309
|
Provenance
The following attestation bundles were made for hide_protocol-0.7.0-py3-none-win_amd64.whl:
Publisher:
publish-sdks.yml on hide-protocol/hide
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hide_protocol-0.7.0-py3-none-win_amd64.whl -
Subject digest:
1be5f231925578c60a1cd07d8325b93d57a82a90d0a636e01e1c1196f39d5666 - Sigstore transparency entry: 2755315484
- Sigstore integration time:
-
Permalink:
hide-protocol/hide@d3907ac09cb261338f59ffde8a9571120bbb08cb -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/hide-protocol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdks.yml@d3907ac09cb261338f59ffde8a9571120bbb08cb -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file hide_protocol-0.7.0-py3-none-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: hide_protocol-0.7.0-py3-none-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 441.3 kB
- Tags: Python 3, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8767c838941f1117d8bfa4df841507d12f0d3d65b7a52e037949c7373af20a7c
|
|
| MD5 |
c154f594f17d6f4962cf11751c1318a9
|
|
| BLAKE2b-256 |
ff0c5895f5f717e0b79c631e5957120ecc70994796df55bd22a055657d0c5f31
|
Provenance
The following attestation bundles were made for hide_protocol-0.7.0-py3-none-manylinux_2_28_x86_64.whl:
Publisher:
publish-sdks.yml on hide-protocol/hide
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hide_protocol-0.7.0-py3-none-manylinux_2_28_x86_64.whl -
Subject digest:
8767c838941f1117d8bfa4df841507d12f0d3d65b7a52e037949c7373af20a7c - Sigstore transparency entry: 2755315497
- Sigstore integration time:
-
Permalink:
hide-protocol/hide@d3907ac09cb261338f59ffde8a9571120bbb08cb -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/hide-protocol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdks.yml@d3907ac09cb261338f59ffde8a9571120bbb08cb -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file hide_protocol-0.7.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: hide_protocol-0.7.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 375.0 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4dcd5628eb8fa7376da14f59b69f1b46e6c95b0a098d7baf45d5998c70a868a3
|
|
| MD5 |
df8b5c7457c1532b94775ad5a38b3aca
|
|
| BLAKE2b-256 |
8f2eb82d59bf93fe56aa65248b589d6338489ff886fd9c6dcb94b3aa73c26ee8
|
Provenance
The following attestation bundles were made for hide_protocol-0.7.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
publish-sdks.yml on hide-protocol/hide
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hide_protocol-0.7.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
4dcd5628eb8fa7376da14f59b69f1b46e6c95b0a098d7baf45d5998c70a868a3 - Sigstore transparency entry: 2755315490
- Sigstore integration time:
-
Permalink:
hide-protocol/hide@d3907ac09cb261338f59ffde8a9571120bbb08cb -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/hide-protocol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdks.yml@d3907ac09cb261338f59ffde8a9571120bbb08cb -
Trigger Event:
workflow_dispatch
-
Statement type: