Skip to content

bovine.crypto.helper

content_digest_sha256(content)

Computes the SHA256 digest of given content

Parameters:

Name Type Description Default
content str | bytes

Content to be encoded

required
Source code in bovine/bovine/crypto/helper.py
def content_digest_sha256(content: str | bytes) -> str:
    """Computes the SHA256 digest of given content

    :param content: Content to be encoded"""
    if isinstance(content, str):
        content = content.encode("utf-8")

    digest = base64.standard_b64encode(hashlib.sha256(content).digest()).decode("utf-8")
    return "sha-256=" + digest

content_digest_sha256_rfc_9530(content)

Computes the content digest according to RFC 9530

>>> content_digest_sha256_rfc_9530(b'{"hello": "world"}\n')
('content-digest', 'sha-256=:RK/0qy18MlBSVnWgjwz6lZEWjP/lF5HF9bvEF8FabDg=:')

Parameters:

Name Type Description Default
content bytes

Usually the request body to compute the digest from

required

Returns:

Type Description
Tuple[str, str]

Tuple of header name, header value

Source code in bovine/bovine/crypto/helper.py
def content_digest_sha256_rfc_9530(content: bytes) -> Tuple[str, str]:
    """Computes the content digest according to [RFC 9530](https://www.rfc-editor.org/authors/rfc9530.html)

    ```pycon
    >>> content_digest_sha256_rfc_9530(b'{"hello": "world"}\\n')
    ('content-digest', 'sha-256=:RK/0qy18MlBSVnWgjwz6lZEWjP/lF5HF9bvEF8FabDg=:')

    ```

    :param content: Usually the request body to compute the digest from
    :return: Tuple of header name, header value"""
    return "content-digest", ser({"sha-256": hashlib.sha256(content).digest()})

ensure_data_integrity_context(doc)

Performs context injection according to Verifiable Credentials: Data Integrity. The data integrity context being added is https://w3id.org/security/data-integrity/v2.

Parameters:

Name Type Description Default
doc dict

Document

required

Returns:

Type Description
dict

The same document with the data integrity context added.

Source code in bovine/bovine/crypto/helper.py
def ensure_data_integrity_context(doc: dict) -> dict:
    """Performs context injection according to
    [Verifiable Credentials: Data Integrity](https://w3c.github.io/vc-data-integrity/#context-injection). The data integrity
    context being added is `https://w3id.org/security/data-integrity/v2`.

    :param doc: Document
    :return: The same document with the data integrity context added.
    """
    integrity_context = "https://w3id.org/security/data-integrity/v2"
    alternate_context = "https://w3id.org/security/data-integrity/v1"
    context = doc.get("@context")
    if context is None:
        return {"@context": integrity_context, **doc}
    if isinstance(context, str):
        context: list = [context]
    if integrity_context in context or alternate_context in context:
        return doc
    return jsonld.compact(doc, context + [integrity_context])

jcs_sha256(doc, context=None)

Returns the sha256 digest of the representation of dict according to JCS. This assumes that doc is JSON serializable.

JCS is defined in RFC8785.

Parameters:

Name Type Description Default
doc dict

The document

required
context dict | None

ignored used in rdfc_sha256

None
Source code in bovine/bovine/crypto/helper.py
def jcs_sha256(doc: dict, context: dict | None = None) -> bytes:
    """Returns the sha256 digest of the representation
    of dict according to JCS. This assumes that `doc`
    is JSON serializable.

    JCS is defined in [RFC8785](https://www.rfc-editor.org/rfc/rfc8785).

    :param doc: The document
    :param context: ignored used in [rdfc_sha256][bovine.crypto.helper.rdfc_sha256]
    """
    return hashlib.sha256(jcs.canonicalize(doc)).digest()

jcs_sha384(doc, context=None)

Returns the sha384 digest of the representation of dict according to JCS. This assumes that doc is JSON serializable.

JCS is defined in RFC8785.

Parameters:

Name Type Description Default
doc dict

The document

required
context dict | None

ignored used in rdfc_sha256

None
Source code in bovine/bovine/crypto/helper.py
def jcs_sha384(doc: dict, context: dict | None = None) -> bytes:
    """Returns the sha384 digest of the representation
    of dict according to JCS. This assumes that `doc`
    is JSON serializable.

    JCS is defined in [RFC8785](https://www.rfc-editor.org/rfc/rfc8785).

    :param doc: The document
    :param context: ignored used in [rdfc_sha256][bovine.crypto.helper.rdfc_sha256]
    """
    return hashlib.sha384(jcs.canonicalize(doc)).digest()

public_key_to_did_key(public_key)

Converts a public key to a did:key.

Parameters:

Name Type Description Default
public_key Union[Ed25519PublicKey, RSAPublicKey, EllipticCurvePublicKey]

The public key

required
Source code in bovine/bovine/crypto/helper.py
def public_key_to_did_key(
    public_key: Union[
        ed25519.Ed25519PublicKey, rsa.RSAPublicKey, ec.EllipticCurvePublicKey
    ],
) -> str:
    """Converts a public key to a [did:key](https://w3c-ccg.github.io/did-method-key/).

    :param public_key: The public key
    """
    return "did:key:" + encode_public_key_to_multibase(public_key)

rdfc_sha256(doc, context={})

Returns the sha256 digest of the representation of dict according to RDF-Canon

The algorithm used is URDNA2015 and the result are n-quads.

Parameters:

Name Type Description Default
doc dict

The document

required
context dict

If doc has no @context property, it is set to this parameter

{}
Source code in bovine/bovine/crypto/helper.py
def rdfc_sha256(doc: dict, context: dict = {}) -> bytes:
    """Returns the sha256 digest of the representation
    of dict according to [RDF-Canon](https://www.w3.org/TR/rdf-canon/)

    The algorithm used is URDNA2015 and the result are n-quads.

    :param doc: The document
    :param context: If doc has no `@context` property, it is set to this parameter
    """
    if "@context" not in doc:
        doc["@context"] = context

    normalized = jsonld.normalize(
        doc, {"algorithm": "URDNA2015", "format": "application/n-quads"}
    )
    return hashlib.sha256(normalized.encode("utf-8")).digest()

rdfc_sha384(doc, context={})

Returns the sha384 digest of the representation of dict according to RDF-Canon

The algorithm used is URDNA2015 and the result are n-quads.

Parameters:

Name Type Description Default
doc dict

The document

required
context dict

If doc has no @context property, it is set to this parameter

{}
Source code in bovine/bovine/crypto/helper.py
def rdfc_sha384(doc: dict, context: dict = {}) -> bytes:
    """Returns the sha384 digest of the representation
    of dict according to [RDF-Canon](https://www.w3.org/TR/rdf-canon/)

    The algorithm used is URDNA2015 and the result are n-quads.

    :param doc: The document
    :param context: If doc has no `@context` property, it is set to this parameter
    """
    if "@context" not in doc:
        doc["@context"] = context

    normalized = jsonld.normalize(
        doc, {"algorithm": "URDNA2015", "format": "application/n-quads"}
    )
    logger.debug(normalized)
    return hashlib.sha384(normalized.encode("utf-8")).digest()