Skip to content

Commit

Permalink
feat: added support for JSON-LD signing for VC status
Browse files Browse the repository at this point in the history
  • Loading branch information
arnabghose997 committed Nov 13, 2023
1 parent ad004f4 commit 89e82e7
Show file tree
Hide file tree
Showing 12 changed files with 439 additions and 255 deletions.
36 changes: 30 additions & 6 deletions client/docs/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ paths:
credentialStatusDocument:
type: object
properties:
context:
type: array
items:
type: string
id:
type: string
revoked:
Expand All @@ -40,7 +44,7 @@ paths:
type: string
issuanceDate:
type: string
merkleRootHash:
credentialMerkleRootHash:
type: string
credentialStatusProof:
type: object
Expand Down Expand Up @@ -159,6 +163,10 @@ paths:
credentialStatusDocument:
type: object
properties:
context:
type: array
items:
type: string
id:
type: string
revoked:
Expand All @@ -171,7 +179,7 @@ paths:
type: string
issuanceDate:
type: string
merkleRootHash:
credentialMerkleRootHash:
type: string
credentialStatusProof:
type: object
Expand Down Expand Up @@ -24666,6 +24674,10 @@ definitions:
hypersign.ssi.v1.CredentialStatusDocument:
type: object
properties:
context:
type: array
items:
type: string
id:
type: string
revoked:
Expand All @@ -24678,14 +24690,18 @@ definitions:
type: string
issuanceDate:
type: string
merkleRootHash:
credentialMerkleRootHash:
type: string
hypersign.ssi.v1.CredentialStatusState:
type: object
properties:
credentialStatusDocument:
type: object
properties:
context:
type: array
items:
type: string
id:
type: string
revoked:
Expand All @@ -24698,7 +24714,7 @@ definitions:
type: string
issuanceDate:
type: string
merkleRootHash:
credentialMerkleRootHash:
type: string
credentialStatusProof:
type: object
Expand Down Expand Up @@ -25023,6 +25039,10 @@ definitions:
credentialStatusDocument:
type: object
properties:
context:
type: array
items:
type: string
id:
type: string
revoked:
Expand All @@ -25035,7 +25055,7 @@ definitions:
type: string
issuanceDate:
type: string
merkleRootHash:
credentialMerkleRootHash:
type: string
credentialStatusProof:
type: object
Expand Down Expand Up @@ -25071,6 +25091,10 @@ definitions:
credentialStatusDocument:
type: object
properties:
context:
type: array
items:
type: string
id:
type: string
revoked:
Expand All @@ -25083,7 +25107,7 @@ definitions:
type: string
issuanceDate:
type: string
merkleRootHash:
credentialMerkleRootHash:
type: string
credentialStatusProof:
type: object
Expand Down
36 changes: 31 additions & 5 deletions cmd/hid-noded/cmd/debug_extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -475,13 +475,13 @@ func signSchemaDocCmd() *cobra.Command {

func signCredStatusDocCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "cred-status-doc [doc] [private-key] [signing-algo]",
Use: "cred-status-doc [doc] [private-key] [proof-object-without-signature]",
Short: "Credential Status Document signature",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
argCredStatusDoc := args[0]
argPrivateKey := args[1]
argSigningAlgo := args[2]
argProofObjectWithoutSignature := args[2]

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
Expand All @@ -494,33 +494,59 @@ func signCredStatusDocCmd() *cobra.Command {
if err != nil {
return err
}
credStatusDocBytes := credStatusDoc.GetSignBytes()

// Unmarshal Proof Object
var credStatusDocProof types.DocumentProof
err = clientCtx.Codec.UnmarshalJSON([]byte(argProofObjectWithoutSignature), &credStatusDocProof)
if err != nil {
return err
}

// Sign Credential Status Document
var signature string
switch argSigningAlgo {
switch credStatusDocProof.Type {
case types.Ed25519Signature2020:
credStatusDocBytes, err := ldcontext.Ed25519Signature2020Normalize(&credStatusDoc, &credStatusDocProof)
if err != nil {
return err
}

signature, err = hidnodecli.GetEd25519Signature2020(argPrivateKey, credStatusDocBytes)
if err != nil {
return err
}
case types.EcdsaSecp256k1Signature2019:
credStatusDocBytes, err := ldcontext.EcdsaSecp256k1Signature2019Normalize(&credStatusDoc, &credStatusDocProof)
if err != nil {
return err
}

signature, err = hidnodecli.GetEcdsaSecp256k1Signature2019(argPrivateKey, credStatusDocBytes)
if err != nil {
return err
}
case types.EcdsaSecp256k1RecoverySignature2020:
credStatusDocBytes, err := ldcontext.EcdsaSecp256k1RecoverySignature2020Normalize(&credStatusDoc, &credStatusDocProof)
if err != nil {
return err
}

signature, err = hidnodecli.GetEcdsaSecp256k1RecoverySignature2020(argPrivateKey, credStatusDocBytes)
if err != nil {
return err
}
case types.BbsBlsSignature2020:
credStatusDocBytes, err := ldcontext.BbsBlsSignature2020Normalize(&credStatusDoc, &credStatusDocProof)
if err != nil {
return err
}

signature, err = hidnodecli.GetBbsBlsSignature2020(argPrivateKey, credStatusDocBytes)
if err != nil {
return err
}
case types.BabyJubJubSignature2023:
signature, err = hidnodecli.GetBabyJubJubSignature2023(argPrivateKey, credStatusDocBytes)
signature, err = hidnodecli.GetBabyJubJubSignature2023(argPrivateKey, credStatusDoc.GetSignBytes())
if err != nil {
return err
}
Expand Down
16 changes: 9 additions & 7 deletions proto/ssi/v1/credential_status.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ syntax = "proto3";
package hypersign.ssi.v1;

import "ssi/v1/proof.proto";
import "gogoproto/gogo.proto";

option go_package = "github.com/hypersign-protocol/hid-node/x/ssi/types";

message CredentialStatusDocument {
string id = 1;
bool revoked = 2;
bool suspended = 3;
string remarks = 4;
string issuer = 5;
string issuanceDate = 6;
string credentialMerkleRootHash = 7;
repeated string context = 1 [json_name = "@context", (gogoproto.jsontag) = "@context"];
string id = 2;
bool revoked = 3;
bool suspended = 4;
string remarks = 5;
string issuer = 6;
string issuanceDate = 7;
string credentialMerkleRootHash = 8;
}

message CredentialStatusState {
Expand Down
12 changes: 9 additions & 3 deletions tests/e2e/ssi_tests/generate_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
SECP256K1_RECOVERY_CONTEXT = "https://ns.did.ai/suites/secp256k1-2020/v1"
SECP256K1_VER_KEY_2019_CONTEXT = "https://ns.did.ai/suites/secp256k1-2019/v1"
BBS_CONTEXT = "https://ns.did.ai/suites/bls12381-2020/v1"
CREDENTIAL_STATUS_CONTEXT = "https://raw.githubusercontent.com/hypersign-protocol/hypersign-contexts/main/CredentialStatus.jsonld"

def generate_did_document(key_pair, algo="Ed25519Signature2020", bech32prefix="hid", is_uuid=False):
base_document = {
Expand Down Expand Up @@ -151,6 +152,7 @@ def generate_schema_document(key_pair, schema_author, vm, signature=None, algo="

def generate_cred_status_document(key_pair, cred_author, vm, signature=None, algo="Ed25519Signature2020", updated_credstatus_doc=None):
base_cred_status_doc = {
"@context": [CREDENTIAL_STATUS_CONTEXT],
"id": "",
"issuer": "did:hid:devnet:z3861habXtUFLNuu6J7m5p8VPsoBMduYbYeUxfx9CnWZR",
"issuanceDate": "2022-08-16T09:37:12Z",
Expand All @@ -160,17 +162,21 @@ def generate_cred_status_document(key_pair, cred_author, vm, signature=None, alg
proof_type = ""
if algo == "Ed25519Signature2020":
proof_type = "Ed25519Signature2020"
base_cred_status_doc["@context"].append(ED25519_CONTEXT)
elif algo == "EcdsaSecp256k1Signature2019":
proof_type = "EcdsaSecp256k1Signature2019"
base_cred_status_doc["@context"].append(SECP256K1_VER_KEY_2019_CONTEXT)
elif algo == "EcdsaSecp256k1RecoverySignature2020":
proof_type = "EcdsaSecp256k1RecoverySignature2020"
base_cred_status_doc["@context"].append(SECP256K1_RECOVERY_CONTEXT)
elif algo == "BbsBlsSignature2020":
proof_type = "BbsBlsSignature2020"
base_cred_status_doc["@context"].append(BBS_CONTEXT)
elif algo == "BabyJubJubSignature2023":
proof_type = "BabyJubJubSignature2023"
else:
raise Exception("Invalid signing algo: " + algo)

base_cred_status_proof = {
"type": proof_type,
"created": "2022-08-16T09:37:12Z",
Expand All @@ -187,11 +193,11 @@ def generate_cred_status_document(key_pair, cred_author, vm, signature=None, alg
# Form Signature
if not updated_credstatus_doc:
if not signature:
signature = get_document_signature(base_cred_status_doc, "cred-status", key_pair, algo)
signature = get_document_signature(base_cred_status_doc, "cred-status", key_pair, algo, proofObj=base_cred_status_proof)
base_cred_status_proof["proofValue"] = signature
return base_cred_status_doc, base_cred_status_proof
else:
if not signature:
signature = get_document_signature(updated_credstatus_doc, "cred-status", key_pair, algo)
signature = get_document_signature(updated_credstatus_doc, "cred-status", key_pair, algo, proofObj=base_cred_status_proof)
base_cred_status_proof["proofValue"] = signature
return updated_credstatus_doc, base_cred_status_proof
3 changes: 1 addition & 2 deletions tests/e2e/ssi_tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ def get_document_signature(doc: dict, doc_type: str, key_pair: dict, algo: str =
else:
raise Exception("Invalid value for doc_type param: " + doc_type)

if doc_type == "did":
print()
if doc_type == "did" or doc_type == "cred-status":
cmd_string = f"hid-noded debug sign-ssi-doc {doc_cmd} '{json.dumps(doc)}' {private_key} '{json.dumps(proofObj)}'"
else:
cmd_string = f"hid-noded debug sign-ssi-doc {doc_cmd} '{json.dumps(doc)}' {private_key} {algo}"
Expand Down
10 changes: 2 additions & 8 deletions x/ssi/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func (k msgServer) getControllerVmFromState(ctx sdk.Context, verificationMethodI
}

// VerifyDocumentProof verifies the proof of a SSI Document
func (k msgServer) VerifyDocumentProof(ctx sdk.Context, ssiMsg types.SsiMsg, inputDocProof types.SSIProofInterface) error {
func (k msgServer) VerifyDocumentProof(ctx sdk.Context, ssiMsg types.SsiMsg, inputDocProof *types.DocumentProof) error {
// Get DID Document from State
docProofVmId := inputDocProof.GetVerificationMethod()
didId, _ := types.SplitDidUrl(docProofVmId)
Expand Down Expand Up @@ -225,13 +225,7 @@ func (k msgServer) VerifyDocumentProof(ctx sdk.Context, ssiMsg types.SsiMsg, inp
)
}

// Verify signature
documentProof := &types.DocumentProof{
VerificationMethod: inputDocProof.GetVerificationMethod(),
ProofValue: inputDocProof.GetProofValue(),
ClientSpecType: inputDocProof.GetClientSpecType(),
}
err = verification.VerifyDocumentProofSignature(ssiMsg, docVm, documentProof)
err = verification.VerifyDocumentProofSignature(ssiMsg, docVm, inputDocProof)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 89e82e7

Please sign in to comment.