Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2384 from kdimak/issue-2295-ldp
Browse files Browse the repository at this point in the history
feat: BbsBlsSignatureProof2020 LDP suite for VC
  • Loading branch information
fqutishat authored Dec 8, 2020
2 parents f648795 + 8301ac0 commit b1d78bb
Show file tree
Hide file tree
Showing 23 changed files with 1,782 additions and 13 deletions.
30 changes: 30 additions & 0 deletions pkg/doc/signature/jsonld/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,36 @@ func (p *Processor) Compact(input, context map[string]interface{},
return proc.Compact(input, context, options)
}

// Frame makes a frame from the input view using frameDoc.
func (p *Processor) Frame(view []string, frameDoc map[string]interface{},
opts ...ProcessorOpts) (map[string]interface{}, error) {
proc := ld.NewJsonLdProcessor()
options := ld.NewJsonLdOptions("")
options.ProcessingMode = ld.JsonLd_1_1
options.Format = format
options.ProduceGeneralizedRdf = true

procOptions := prepareOpts(opts)

useDocumentLoader(options, procOptions.documentLoader, procOptions.documentLoaderCache)

filteredJSONLd, err := proc.FromRDF(strings.Join(view, "\n"), options)
if err != nil {
return nil, err
}

options.OmitGraph = true

frame, err := proc.Frame(filteredJSONLd, frameDoc, options)
if err != nil {
return nil, err
}

frame["@context"] = frameDoc["@context"]

return frame, err
}

// removeMatchingInvalidRDFs validates normalized view to find any invalid RDF and
// returns filtered view after removing all invalid data except the ones given in rdfMatches argument.
// [Note : handling invalid RDF data, by following pattern https://github.com/digitalbazaar/jsonld.js/issues/199]
Expand Down
42 changes: 42 additions & 0 deletions pkg/doc/signature/jsonld/processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1490,3 +1490,45 @@ const trustblocExampleDoc = `
}
}
`

func TestProcessor_Frame(t *testing.T) {
processor := Default()

var doc map[string]interface{}

err := json.Unmarshal([]byte(jsonLdSample1), &doc)
require.NoError(t, err)

canonizedDoc, err := processor.GetCanonicalDocument(doc)
require.NoError(t, err)

t.Logf("canonizedDoc=\n%v", string(canonizedDoc))

frameJSON := `
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"credentialSubject": {
"@explicit": true,
"spouse": {}
}
}
`

var frameDoc map[string]interface{}

err = json.Unmarshal([]byte(frameJSON), &frameDoc)
require.NoError(t, err)

view := strings.Split(string(canonizedDoc), "\n")
framedView, err := processor.Frame(view, frameDoc)
require.NoError(t, err)

require.Equal(t, map[string]interface{}{
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1",
}, framedView["credentialSubject"])
}
5 changes: 3 additions & 2 deletions pkg/doc/signature/proof/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,13 @@ const (
proofID excludedKey = iota + 1
proofValue
jws
nonce
)

//nolint:gochecknoglobals
var (
excludedKeysStr = [...]string{"id", "proofValue", "jws"}
excludedKeys = [...]excludedKey{proofID, proofValue, jws}
excludedKeysStr = [...]string{"id", "proofValue", "jws", "nonce"}
excludedKeys = [...]excludedKey{proofID, proofValue, jws, nonce}
)

func (ek excludedKey) String() string {
Expand Down
12 changes: 6 additions & 6 deletions pkg/doc/signature/proof/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func NewProof(emap map[string]interface{}) (*Proof, error) {
)

if generalProof, ok := emap[jsonldProofValue]; ok {
proofValue, err = decodeProofValue(stringEntry(generalProof))
proofValue, err = decodeBase64(stringEntry(generalProof))
if err != nil {
return nil, err
}
Expand All @@ -86,7 +86,7 @@ func NewProof(emap map[string]interface{}) (*Proof, error) {
return nil, errors.New("signature is not defined")
}

nonce, err := base64.RawURLEncoding.DecodeString(stringEntry(emap[jsonldNonce]))
nonce, err := decodeBase64(stringEntry(emap[jsonldNonce]))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -128,19 +128,19 @@ func decodeCapabilityChain(proof map[string]interface{}) ([]interface{}, error)
return capabilityChain, nil
}

func decodeProofValue(proofStr string) ([]byte, error) {
func decodeBase64(s string) ([]byte, error) {
allEncodings := []*base64.Encoding{
base64.RawURLEncoding, base64.StdEncoding,
}

for _, encoding := range allEncodings {
proofValue, err := encoding.DecodeString(proofStr)
value, err := encoding.DecodeString(s)
if err == nil {
return proofValue, nil
return value, nil
}
}

return nil, errors.New("unsupported proof encoding")
return nil, errors.New("unsupported encoding")
}

// stringEntry.
Expand Down
4 changes: 2 additions & 2 deletions pkg/doc/signature/proof/proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func TestInvalidProofValue(t *testing.T) {
})
require.Error(t, err)
require.Nil(t, p)
require.EqualError(t, err, "unsupported proof encoding")
require.EqualError(t, err, "unsupported encoding")

// proof is not defined (neither "proofValue" nor "jws" is defined)
p, err = NewProof(map[string]interface{}{
Expand All @@ -158,7 +158,7 @@ func TestInvalidNonce(t *testing.T) {
require.Error(t, err)

require.Nil(t, p)
require.Contains(t, err.Error(), "illegal base64 data")
require.Contains(t, err.Error(), "unsupported encoding")
}

func TestProof_JSONLdObject(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package bbsblssignatureproof2020

import "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"

const g2PubKeyType = "Bls12381G2Key2020"

// NewG2PublicKeyVerifier creates a signature verifier that verifies a BbsBlsSignatureProof2020 signature
// taking Bls12381G2Key2020 public key bytes as input.
func NewG2PublicKeyVerifier(nonce []byte) *verifier.PublicKeyVerifier {
return verifier.NewPublicKeyVerifier(verifier.NewBBSG2SignatureProofVerifier(nonce),
verifier.WithExactPublicKeyType(g2PubKeyType))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package bbsblssignatureproof2020_test

import (
"encoding/base64"
"testing"

"github.com/stretchr/testify/require"

"github.com/hyperledger/aries-framework-go/pkg/doc/jose"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignatureproof2020"
sigverifier "github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
)

//nolint:lll
func TestNewG2PublicKeyVerifier(t *testing.T) {
verifier := bbsblssignatureproof2020.NewG2PublicKeyVerifier([]byte("nonce"))

pkBase64 := "sVEbbh9jDPGSBK/oT/EeXQwFvNuC+47rgq9cxXKrwo6G7k4JOY/vEcfgZw9Vf/TpArbIdIAJCFMDyTd7l2atS5zExAKX0B/9Z3E/mgIZeQJ81iZ/1HUnUCT2Om239KFx"
pkBytes, err := base64.RawStdEncoding.DecodeString(pkBase64)
require.NoError(t, err)

sigBase64 := "AAIBiN4EL9psRsIUlwQah7a5VROD369PPt09Z+jfzamP+/114a5RfWVMju3NCUl2Yv6ahyIdHGdEfxhC985ShlGQrRPLa+crFRiu2pfnAk+L6QMNooVMQhzJc2yYgktHen4QhsKV3IGoRRUs42zqPTP3BdqIPQeLgjDVi1d1LXEnP+WFQGEQmTKWTja4u1MsERdmAAAAdIb6HuFznhE3OByXN0Xp3E4hWQlocCdpExyNlSLh3LxK5duCI/WMM7ETTNS0Ozxe3gAAAAIuALkiwplgKW6YmvrEcllWSkG3H+uHEZzZGL6wq6Ac0SuktQ4n84tZPtMtR9vC1Rsu8f7Kwtbq1Kv4v02ct9cvj7LGcitzg3u/ZO516qLz+iitKeGeJhtFB8ggALcJOEsebPFl12cYwkieBbIHCBt4AAAAAxgEHt3iqKIyIQbTYJvtrMjGjT4zuimiZbtE3VXnqFmGaxVTeR7dh89PbPtsBI8LLMrCvFFpks9D/oTzxnw13RBmMgMlc1bcfQOmE9DZBGB7NCdwOnT7q4TVKhswOITKTQ=="
sigBytes, err := base64.StdEncoding.DecodeString(sigBase64)
require.NoError(t, err)

msg := `
message1
message2
`

err = verifier.Verify(&sigverifier.PublicKey{
Type: "Bls12381G2Key2020",
Value: pkBytes,
}, []byte(msg), sigBytes)
require.NoError(t, err)

err = verifier.Verify(&sigverifier.PublicKey{
Type: "NotBls12381G2Key2020",
Value: pkBytes,
}, []byte(msg), sigBytes)
require.Error(t, err)
require.EqualError(t, err, "a type of public key is not 'Bls12381G2Key2020'")

// Failed as we do not support JWK for Bls12381G2Key2020.
err = verifier.Verify(&sigverifier.PublicKey{
Type: "Bls12381G2Key2020",
JWK: &jose.JWK{
Kty: "EC",
Crv: "BLS12381_G2",
},
}, []byte(msg), sigBytes)
require.Error(t, err)
require.EqualError(t, err, "verifier does not match JSON Web Key")
}
Loading

0 comments on commit b1d78bb

Please sign in to comment.