API Reference
pylongfellow
pylongfellow.Pylongfellow
A Longfellow prover and verifier.
Example
longfellow = Pylongfellow(backend="google-cpp")
longfellow.load_circuit(circuit, 7, 1)
proof = longfellow.prove(mdoc, issuer_public_key, transcript, claims, timestamp)
longfellow.verify(issuer_public_key, transcript, claims, timestamp, proof, doctype)
Attributes:
| Name | Type | Description |
|---|---|---|
backend |
Backend
|
The selected |
__init__
__init__(*, backend: str | Backend) -> None
Initialize with the selected backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
str | Backend
|
Registry name ( |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
|
BackendUnavailableError
|
the backend's native dependency is not installed or built. |
load_circuit
load_circuit(circuit: bytes, version: int, num_attributes: int) -> None
Load the circuit this instance proves and verifies with.
A second call replaces the loaded circuit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
circuit
|
bytes
|
Circuit bytes, as from
|
required |
version
|
int
|
Version of the ZK specification the circuit is declared to be. |
required |
num_attributes
|
int
|
Number of attributes the circuit is declared to prove over. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
No circuit has the declared version and attribute count
(google-cpp); |
prove
prove(mdoc: bytes, issuer_public_key: PublicKey, transcript: bytes, claims: list[RequestedAttribute], timestamp: datetime) -> bytes
Prove the claims hold over the mdoc, bound to the transcript.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mdoc
|
bytes
|
CBOR-encoded mdoc credential. |
required |
issuer_public_key
|
PublicKey
|
The issuer's public key. |
required |
transcript
|
bytes
|
Session transcript to bind the proof to. |
required |
claims
|
list[RequestedAttribute]
|
Claims to prove; |
required |
timestamp
|
datetime
|
Timezone-aware verification time. |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
Proof bytes. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
No circuit is loaded. |
ValueError
|
|
ProverError
|
The prover rejected the inputs. |
verify
verify(issuer_public_key: PublicKey, transcript: bytes, claims: list[RequestedAttribute], timestamp: datetime, proof: bytes, doctype: str, *, device_namespaces: bytes | None = None) -> None
Verify a proof that the claims hold, against the transcript.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
issuer_public_key
|
PublicKey
|
The issuer's public key. |
required |
transcript
|
bytes
|
Session transcript the proof is bound to. |
required |
claims
|
list[RequestedAttribute]
|
Claims to verify; |
required |
timestamp
|
datetime
|
Timezone-aware verification time. |
required |
proof
|
bytes
|
Proof bytes from |
required |
doctype
|
str
|
mdoc doctype the proof is scoped to. |
required |
device_namespaces
|
bytes | None
|
Inner bytes of the tag-24 DeviceNameSpacesBytes; required by the isrg-rust backend. |
None
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
No circuit is loaded. |
ValueError
|
|
VerifierError
|
The proof does not hold. |
pylongfellow.LongfellowError
Bases: Exception
Base class for all exceptions raised by pylongfellow.
pylongfellow.mdoc
Data types
pylongfellow.mdoc.RequestedAttribute
A claim to prove or verify: attribute (namespace, id) holds cbor_value.
Attributes:
| Name | Type | Description |
|---|---|---|
namespace |
str
|
The mdoc namespace of the attribute. |
id |
str
|
Attribute identifier within the namespace. |
cbor_value |
bytes
|
Raw CBOR encoding of the value (e.g. |
pylongfellow.mdoc.PublicKey
A public key, as coordinates x and y.
Errors
LongfellowError
└── mdoc.Error
├── ProverError # .code: mdoc.ProverErrorCode or None
├── VerifierError # .code: mdoc.VerifierErrorCode or None
└── CircuitError # .code: mdoc.CircuitGenerationErrorCode or None
pylongfellow.mdoc.Error
Bases: LongfellowError
Base class for exceptions raised by pylongfellow.mdoc.
pylongfellow.mdoc.ProverError
Bases: Error
A prover call failed.
Attributes:
| Name | Type | Description |
|---|---|---|
code |
The |
pylongfellow.mdoc.VerifierError
Bases: Error
A verifier call failed.
Attributes:
| Name | Type | Description |
|---|---|---|
code |
The |
pylongfellow.mdoc.CircuitError
Bases: Error
Circuit generation failed.
Attributes:
| Name | Type | Description |
|---|---|---|
code |
The |
pylongfellow.mdoc.ProverErrorCode
Bases: IntEnum
Return codes from run_mdoc_prover.
pylongfellow.mdoc.VerifierErrorCode
Bases: IntEnum
Return codes from run_mdoc_verifier.
pylongfellow.mdoc.CircuitGenerationErrorCode
Bases: IntEnum
Return codes from generate_circuit.
pylongfellow.backends
A Backend implements one longfellow implementation. Pylongfellow takes a registry name
("google-cpp", "isrg-rust") or a Backend instance.
pylongfellow.backends.Backend
Bases: Protocol
The operations a backend provides.
pylongfellow.backends.get_backend
get_backend(name: str) -> Backend
Return the named backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Registry name, one of |
required |
Returns:
| Type | Description |
|---|---|
Backend
|
The named backend. |
Raises:
| Type | Description |
|---|---|
ValueError
|
|
pylongfellow.backends.BackendUnavailableError
Bases: LongfellowError
A backend's native dependency is not installed or built.
Backend scope
google-cpp and isrg-rust differ in the following behaviour.
- Circuit versions. google-cpp accepts versions 5, 6, and 7 at the v0.9 pin, each with attribute counts 1 to 4. isrg-rust accepts versions 6 and 7.
- Circuit generation.
google_cpp.generate_circuitgenerates the highest table version for an attribute count. isrg-rust generates no circuits. - Claims count. google-cpp requires
len(claims)to equal the loaded circuit's attribute count on prove and verify. isrg-rust passes the claims through. device_namespaces. isrg-rust's verifier requiresdevice_namespaces. google-cpp does not read it.doctype. google-cpp rejects adoctypeof 256 bytes or longer.- Error codes.
ProverError.codeandVerifierError.codecarry a code on google-cpp and are None on isrg-rust.
pylongfellow.backends.google_cpp
Binds the vendored google/longfellow-zk C++ library through cffi.
pylongfellow.backends.google_cpp.ZkSpec
A row of the library's circuit table; what find_zk_spec and zk_specs return.
Attributes:
| Name | Type | Description |
|---|---|---|
system |
str
|
ZK system name and version (e.g. |
circuit_hash |
str
|
SHA-256 (hex) pinning which circuit the row describes. |
num_attributes |
int
|
Number of attributes the circuit proves over. |
version |
int
|
Version of the ZK specification. |
block_enc_hash |
int
|
|
block_enc_sig |
int
|
|
pylongfellow.backends.google_cpp.circuit_id
circuit_id(circuit: bytes) -> str
Recompute a circuit's canonical id from its bytes.
Binds circuit_id. The id is 64 hex chars and equals
ZkSpec.circuit_hash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
circuit
|
bytes
|
Circuit bytes. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The canonical id, as 64-char hex. |
Raises:
| Type | Description |
|---|---|
Error
|
The bytes could not be parsed. |
pylongfellow.backends.google_cpp.find_zk_spec
find_zk_spec(system: str, circuit_hash: str) -> ZkSpec | None
Look up the built-in ZkSpec for a (system, circuit_hash) pair.
Binds find_zk_spec.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
system
|
str
|
Proof-system identifier the spec is registered under. |
required |
circuit_hash
|
str
|
Canonical circuit id, as from
|
required |
Returns:
| Type | Description |
|---|---|
ZkSpec | None
|
The matching ZkSpec, or None if the build has no spec for that pair. |
pylongfellow.backends.google_cpp.zk_specs
zk_specs() -> tuple[ZkSpec, ...]
Return every ZkSpec in the library's circuit table, in table order.
Binds the kZkSpecs table. Entries include superseded circuit versions:
for a given num_attributes, several (version, circuit_hash) rows may be
present. generate_circuit accepts only the highest version for a given
num_attributes.
Returns:
| Type | Description |
|---|---|
tuple[ZkSpec, ...]
|
The table's ZkSpec entries, in table order. |
pylongfellow.backends.google_cpp.generate_circuit
generate_circuit(version: int, num_attributes: int) -> bytes
Generate the circuit with this version and attribute count.
Binds generate_circuit. C generates only the highest version the table holds
for an attribute count, so an older version of a known count raises
CircuitError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
int
|
Version of the ZK specification. |
required |
num_attributes
|
int
|
Number of attributes the circuit proves over. |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
Circuit bytes. |
Raises:
| Type | Description |
|---|---|
ValueError
|
No circuit has that version and attribute count. |
CircuitError
|
Generation failed. |
Logging
PYLONGFELLOW_GOOGLE_CPP_LOG_LEVEL sets the stderr log level of google/longfellow-zk, read
once when the backend first loads in the process. Values (case-insensitive): error, warning,
info, silent. The default is warning, which hides upstream's per-call info output but
keeps genuine errors and warnings.
google/longfellow-zk logs to stderr, not through Python logging, and exposes no callback to
bridge. There is no Python API and no runtime reconfiguration. The isrg-rust backend emits no
log output.
pylongfellow.backends.isrg_rust
Binds the vendored abetterinternet/zk-cred-longfellow Rust library through generated UniFFI bindings.
pylongfellow.mdoc.testing
Functions
pylongfellow.mdoc.testing.create_presentation
create_presentation(doc_type: str, claims: Mapping[str, Mapping[str, object]], transcript: bytes, valid_from: datetime, valid_until: datetime, *, device_namespaces: Mapping[str, Mapping[str, object]] | None = None, issuer_key: EllipticCurvePrivateKey | None = None, device_key: EllipticCurvePrivateKey | None = None, issuer_certificate: Certificate | None = None) -> PresentationSpecimen
Create a presentation under locally held keys.
Assembles a DeviceResponse holding one document. The
claims are issuer-signed into an MSO. The device signature covers the
transcript, the doctype, and the device namespaces. Both signatures are
verified before returning.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
doc_type
|
str
|
Doctype of the single document. |
required |
claims
|
Mapping[str, Mapping[str, object]]
|
Issuer-signed claims, as namespace to element identifier to
element value. Values are encoded with |
required |
transcript
|
bytes
|
CBOR-encoded session transcript the device signature is
bound to. Presenting under another transcript requires re-signing,
see
|
required |
valid_from
|
datetime
|
MSO |
required |
valid_until
|
datetime
|
MSO |
required |
device_namespaces
|
Mapping[str, Mapping[str, object]] | None
|
Device-signed items, as namespace to element identifier to element value. None issues the empty map. |
None
|
issuer_key
|
EllipticCurvePrivateKey | None
|
Issuer private key; a fresh P-256 key is generated when None. |
None
|
device_key
|
EllipticCurvePrivateKey | None
|
Device private key; a fresh P-256 key is generated when None. |
None
|
issuer_certificate
|
Certificate | None
|
Leaf certificate to embed in the x5chain header;
must certify |
None
|
Returns:
| Type | Description |
|---|---|
PresentationSpecimen
|
The presentation, with the issuer public key, certificate, and device key. |
Raises:
| Type | Description |
|---|---|
ValueError
|
|
Error
|
The encoded credential failed its signature self-check; with a
caller-supplied |
pylongfellow.mdoc.testing.create_certificate
create_certificate(subject: str, public_key: EllipticCurvePublicKey, issuer: str, signing_key: EllipticCurvePrivateKey, valid_from: datetime, valid_until: datetime, *, ca: bool = False) -> x509.Certificate
Create a test X.509 certificate, CA or leaf.
The certificate is signed with ECDSA over SHA-256.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
subject
|
str
|
Subject common name. |
required |
public_key
|
EllipticCurvePublicKey
|
Public key the certificate certifies. |
required |
issuer
|
str
|
Issuer common name; equals |
required |
signing_key
|
EllipticCurvePrivateKey
|
Private key that signs the certificate. |
required |
valid_from
|
datetime
|
Start of the validity window; timezone-aware. |
required |
valid_until
|
datetime
|
End of the validity window; timezone-aware. |
required |
ca
|
bool
|
True builds a CA certificate ( |
False
|
Returns:
| Type | Description |
|---|---|
Certificate
|
The signed certificate. |
Raises:
| Type | Description |
|---|---|
ValueError
|
|
pylongfellow.mdoc.testing.sign_device_authentication
sign_device_authentication(device_key: EllipticCurvePrivateKey, transcript: bytes, doc_type: str, device_namespaces: object) -> bytes
Sign DeviceAuthentication over a session transcript.
Builds the detached DeviceAuthenticationBytes payload from the
transcript, the doctype, and the device namespaces, and signs it as a COSE
Signature1 structure with ES256.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
device_key
|
EllipticCurvePrivateKey
|
The credential's device private key. |
required |
transcript
|
bytes
|
CBOR-encoded session transcript. |
required |
doc_type
|
str
|
The credential's doctype. |
required |
device_namespaces
|
object
|
The data item held in the credential's
|
required |
Returns:
| Type | Description |
|---|---|
bytes
|
The 64-byte |
pylongfellow.mdoc.testing.verify_device_authentication
verify_device_authentication(mdoc: bytes, transcript: bytes) -> None
Verify an mdoc's device signature over a session transcript.
The device key comes from the document's MSO. The signed payload is rebuilt from the document's own doctype and device namespaces.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mdoc
|
bytes
|
CBOR-encoded mdoc credential. |
required |
transcript
|
bytes
|
CBOR-encoded session transcript the signature is bound to. |
required |
Raises:
| Type | Description |
|---|---|
Error
|
The device signature does not verify over the transcript. |
Data types
pylongfellow.mdoc.testing.PresentationSpecimen
A presentation with the issuer public key, certificate, and device key.
Attributes:
| Name | Type | Description |
|---|---|---|
mdoc |
bytes
|
CBOR-encoded |
issuer_public_key |
PublicKey
|
The issuer's public key. |
issuer_certificate |
Certificate
|
Leaf certificate embedded in |
device_key |
EllipticCurvePrivateKey
|
Private key matching the MSO's |