github.com/hyperledger/aries-framework-go@v0.3.2/pkg/doc/cl/ursa/prover.go (about) 1 //go:build ursa 2 // +build ursa 3 4 /* 5 Copyright Avast Software. All Rights Reserved. 6 7 SPDX-License-Identifier: Apache-2.0 8 */ 9 10 package ursa 11 12 import ( 13 "fmt" 14 15 "github.com/hyperledger/aries-framework-go/pkg/crypto" 16 "github.com/hyperledger/aries-framework-go/pkg/doc/cl" 17 ) 18 19 // Prover is an ursa implementation of the CL Prover API. 20 type Prover struct { 21 crypto crypto.Crypto 22 kh interface{} 23 } 24 25 // NewProver insaniates a Prover service for the provided keyID. 26 func NewProver(provider cl.Provider, keyID string) (*Prover, error) { 27 km := provider.KMS() 28 29 kh, err := km.Get(keyID) 30 if err != nil { 31 return nil, fmt.Errorf("failed to get KeyHandle for %s: %w", keyID, err) 32 } 33 34 return &Prover{kh: kh, crypto: provider.Crypto()}, nil 35 } 36 37 // RequestCredential generates CredRequest which contains blinded secrets with MS, using issuer's CredDef public data 38 // and CredOffer from the previous step 39 // returns: 40 // request as *CredentialRequest 41 // error in case of errors 42 func (s *Prover) RequestCredential( 43 credOffer *cl.CredentialOffer, 44 credDef *cl.CredentialDefinition, 45 proverID string, 46 ) (*cl.CredentialRequest, error) { 47 blindedMs, err := s.crypto.Blind(s.kh) 48 if err != nil { 49 return nil, err 50 } 51 52 nonce, err := newNonce() 53 if err != nil { 54 return nil, err 55 } 56 57 secrets, err := blindCredentialSecrets( 58 credDef.CredPubKey, 59 credDef.CredDefCorrectnessProof, 60 credOffer.Nonce, 61 blindedMs[0], 62 ) 63 if err != nil { 64 return nil, err 65 } 66 67 return &cl.CredentialRequest{BlindedCredentialSecrets: secrets, Nonce: nonce, ProverID: proverID}, nil 68 } 69 70 // ProcessCredential updates issued Credential signature for CredDef, using blinding factor from a CredRequest 71 // returns: 72 // credential as *Credential 73 // error in case of errors 74 func (s *Prover) ProcessCredential( 75 credential *cl.Credential, 76 credRequest *cl.CredentialRequest, 77 credDef *cl.CredentialDefinition, 78 ) error { 79 blindedVals, err := s.crypto.Blind(s.kh, credential.Values) 80 if err != nil { 81 return err 82 } 83 84 err = processCredentialSignature( 85 credential, 86 credRequest, 87 credDef, 88 blindedVals[0], 89 ) 90 91 return err 92 } 93 94 // CreateProof composes Proof for the provided Credentials for CredDefs 95 // matching revealead attrs and predicates specified in PresentationRequest 96 // returns: 97 // proof as *Proof 98 // error in case of errors 99 func (s *Prover) CreateProof( 100 presentationRequest *cl.PresentationRequest, 101 credentials []*cl.Credential, 102 credDefs []*cl.CredentialDefinition, 103 ) (*cl.Proof, error) { 104 if len(presentationRequest.Items) != len(credentials) { 105 return nil, fmt.Errorf("not enough credentials provided to fulfill the presentsation request") 106 } 107 108 if len(presentationRequest.Items) != len(credDefs) { 109 return nil, fmt.Errorf("not enough credential definitions provided to fulfill the presentsation request") 110 } 111 112 var multivals []map[string]interface{} 113 for _, cred := range credentials { 114 multivals = append(multivals, cred.Values) 115 } 116 117 blindedMultiVals, err := s.crypto.Blind(s.kh, multivals...) 118 if err != nil { 119 return nil, err 120 } 121 122 var subProofItems []*subProofItem 123 124 for i, item := range presentationRequest.Items { 125 subProofItem := &subProofItem{ 126 BlindedVals: blindedMultiVals[i], 127 Credential: credentials[i], 128 CredentialDefinition: credDefs[i], 129 Item: item, 130 } 131 132 subProofItems = append(subProofItems, subProofItem) 133 } 134 135 proof, err := createProof(subProofItems, presentationRequest.Nonce) 136 if err != nil { 137 return nil, err 138 } 139 140 return &cl.Proof{Proof: proof}, nil 141 }