async def add( *, document: dict, suite: LinkedDataProof, purpose: ProofPurpose, document_loader: DocumentLoaderMethod, ) -> dict: """Add a Linked Data proof to the document. If the document contains other proofs, the proof will be appended to the existing set of proofs. Important note: This method assumes that the term `proof` in the given document has the same definition as the `https://w3id.org/security/v2` JSON-LD @context. Args: document (dict): JSON-LD document to be signed. suite (LinkedDataProof): A signature suite instance that will create the proof purpose (ProofPurpose): A proof purpose instance that will augment the proof with information describing its intended purpose. document_loader (DocumentLoader): Document loader to use. Returns: dict: The signed document, with the signature in the top-level `proof` property. """ # Shallow copy document to allow removal of existing proofs input = document.copy() input.pop("proof", None) # create the new proof, suites MUST output a proof using security-v2 `@context` proof = await suite.create_proof( document=input, purpose=purpose, document_loader=document_loader ) JsonLdProcessor.add_value(document, "proof", proof) return document
async def derive( *, document: dict, reveal_document: dict, # TODO: I think this could support multiple suites? # But then, why do multiple proofs? suite: LinkedDataProof, document_loader: DocumentLoaderMethod, nonce: bytes = None, ) -> dict: """Create new derived Linked Data proof(s) on document using the reveal document. Important note: This method assumes that the term `proof` in the given document has the same definition as the `https://w3id.org/security/v2` JSON-LD @context. (v3 because BBS?) Args: document (dict): JSON-LD document with one or more proofs to be derived. reveal_document (dict): JSON-LD frame specifying the attributes to reveal. suite (LinkedDataProof): A signature suite instance to derive the proof. document_loader (DocumentLoader): Document loader to use. nonce (bytes, optional): Nonce to use for the proof. Defaults to None. Returns: dict: The derived document with the derived proof(s) in the top-level `proof` property. """ # Shallow copy document to allow removal of existing proofs input = document.copy() # Check if suite supports derivation if not suite.supported_derive_proof_types: raise LinkedDataProofException( f"{suite.signature_type} does not support derivation" ) # Get proofs, remove proof from document proof_set = await ProofSet._get_proofs( document=input, proof_types=suite.supported_derive_proof_types ) input.pop("proof", None) # Derive proof, remove context derived_proof = await suite.derive_proof( proof=proof_set[0], document=input, reveal_document=reveal_document, document_loader=document_loader, nonce=nonce, ) if len(proof_set) > 1: derived_proof["proof"] = [derived_proof["proof"]] proof_set.pop(0) for proof in proof_set: additional_derived_proof = await suite.derive_proof( proof=proof, document=input, reveal_document=reveal_document, document_loader=document_loader, ) derived_proof["proof"].append(additional_derived_proof["proof"]) JsonLdProcessor.add_value( derived_proof["document"], "proof", derived_proof["proof"] ) return derived_proof["document"]