github.com/hyperledger/aries-framework-go@v0.3.2/pkg/doc/presexch/example_v2_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package presexch_test 8 9 import ( 10 "crypto/sha256" 11 "encoding/json" 12 "fmt" 13 "testing" 14 "time" 15 16 "github.com/piprate/json-gold/ld" 17 "github.com/stretchr/testify/require" 18 19 "github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub" 20 . "github.com/hyperledger/aries-framework-go/pkg/doc/presexch" 21 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld" 22 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite" 23 "github.com/hyperledger/aries-framework-go/pkg/doc/signature/suite/bbsblssignature2020" 24 "github.com/hyperledger/aries-framework-go/pkg/doc/util" 25 jsonutil "github.com/hyperledger/aries-framework-go/pkg/doc/util/json" 26 "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" 27 "github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil" 28 ) 29 30 func ExamplePresentationDefinition_CreateVP_v2() { 31 required := Required 32 33 pd := &PresentationDefinition{ 34 ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 35 Purpose: "To sell you a drink we need to know that you are an adult.", 36 InputDescriptors: []*InputDescriptor{{ 37 ID: "age_descriptor", 38 Purpose: "Your age should be greater or equal to 18.", 39 Constraints: &Constraints{ 40 LimitDisclosure: &required, 41 Fields: []*Field{ 42 { 43 Path: []string{"$.credentialSubject.age", "$.vc.credentialSubject.age", "$.age"}, 44 Predicate: &required, 45 Filter: &Filter{ 46 Type: &intFilterType, 47 Minimum: 18, 48 }, 49 }, 50 { 51 Path: []string{"$.credentialSchema[0].id", "$.credentialSchema.id", "$.vc.credentialSchema.id"}, 52 Filter: &Filter{ 53 Type: &strFilterType, 54 Const: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 55 }, 56 }, 57 }, 58 }, 59 }}, 60 } 61 62 loader, err := ldtestutil.DocumentLoader() 63 if err != nil { 64 panic(err) 65 } 66 67 vp, err := pd.CreateVP([]*verifiable.Credential{ 68 { 69 ID: "http://example.edu/credentials/777", 70 Context: []string{verifiable.ContextURI}, 71 Types: []string{verifiable.VCType}, 72 Issuer: verifiable.Issuer{ 73 ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", 74 }, 75 Issued: &util.TimeWrapper{ 76 Time: time.Time{}, 77 }, 78 Schemas: []verifiable.TypedID{{ 79 ID: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 80 Type: "JsonSchemaValidator2018", 81 }}, 82 83 Subject: map[string]interface{}{ 84 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 85 "first_name": "Jesse", 86 "last_name": "Pinkman", 87 "age": 21, 88 }, 89 }, 90 }, loader, verifiable.WithJSONLDDocumentLoader(loader)) 91 if err != nil { 92 panic(err) 93 } 94 95 vp.ID = dummy 96 vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy 97 98 vpBytes, err := json.MarshalIndent(vp, "", "\t") 99 if err != nil { 100 panic(err) 101 } 102 103 fmt.Println(string(vpBytes)) 104 // Output: 105 // { 106 // "@context": [ 107 // "https://www.w3.org/2018/credentials/v1", 108 // "https://identity.foundation/presentation-exchange/submission/v1" 109 // ], 110 // "id": "DUMMY", 111 // "presentation_submission": { 112 // "id": "DUMMY", 113 // "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 114 // "descriptor_map": [ 115 // { 116 // "id": "age_descriptor", 117 // "format": "ldp_vp", 118 // "path": "$", 119 // "path_nested": { 120 // "id": "age_descriptor", 121 // "format": "ldp_vc", 122 // "path": "$.verifiableCredential[0]" 123 // } 124 // } 125 // ] 126 // }, 127 // "type": [ 128 // "VerifiablePresentation", 129 // "PresentationSubmission" 130 // ], 131 // "verifiableCredential": [ 132 // { 133 // "@context": [ 134 // "https://www.w3.org/2018/credentials/v1" 135 // ], 136 // "credentialSubject": { 137 // "age": true, 138 // "first_name": "Jesse", 139 // "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 140 // "last_name": "Pinkman" 141 // }, 142 // "id": "http://example.edu/credentials/777", 143 // "issuanceDate": "0001-01-01T00:00:00Z", 144 // "issuer": "did:example:76e12ec712ebc6f1c221ebfeb1f", 145 // "type": "VerifiableCredential" 146 // } 147 // ] 148 // } 149 } 150 151 func ExamplePresentationDefinition_CreateVP_with_LdpVC_Format() { 152 required := Required 153 154 pd := &PresentationDefinition{ 155 ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 156 Purpose: "To sell you a drink we need to know that you are an adult.", 157 Format: &Format{ 158 LdpVC: &LdpType{ 159 ProofType: []string{"Ed25519Signature2018"}, 160 }, 161 }, 162 InputDescriptors: []*InputDescriptor{{ 163 ID: "age_descriptor", 164 Purpose: "Your age should be greater or equal to 18.", 165 Constraints: &Constraints{ 166 LimitDisclosure: &required, 167 Fields: []*Field{ 168 { 169 Path: []string{"$.credentialSubject.age", "$.vc.credentialSubject.age", "$.age"}, 170 Predicate: &required, 171 Filter: &Filter{ 172 Type: &intFilterType, 173 Minimum: 18, 174 }, 175 }, 176 { 177 Path: []string{"$.credentialSchema[0].id", "$.credentialSchema.id", "$.vc.credentialSchema.id"}, 178 Filter: &Filter{ 179 Type: &strFilterType, 180 Const: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 181 }, 182 }, 183 }, 184 }, 185 }}, 186 } 187 188 loader, err := ldtestutil.DocumentLoader() 189 if err != nil { 190 panic(err) 191 } 192 193 vp, err := pd.CreateVP([]*verifiable.Credential{ 194 { 195 ID: "http://example.edu/credentials/777", 196 Context: []string{verifiable.ContextURI}, 197 Types: []string{verifiable.VCType}, 198 Issuer: verifiable.Issuer{ 199 ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", 200 }, 201 Issued: &util.TimeWrapper{ 202 Time: time.Time{}, 203 }, 204 Schemas: []verifiable.TypedID{{ 205 ID: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 206 Type: "JsonSchemaValidator2018", 207 }}, 208 209 Subject: map[string]interface{}{ 210 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 211 "first_name": "Jesse", 212 "last_name": "Pinkman", 213 "age": 21, 214 }, 215 Proofs: []verifiable.Proof{ 216 {"type": "Ed25519Signature2018"}, 217 }, 218 }, 219 }, loader, verifiable.WithJSONLDDocumentLoader(loader)) 220 if err != nil { 221 panic(err) 222 } 223 224 vp.ID = dummy 225 vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy 226 227 vpBytes, err := json.MarshalIndent(vp, "", "\t") 228 if err != nil { 229 panic(err) 230 } 231 232 fmt.Println(string(vpBytes)) 233 // Output: 234 // { 235 // "@context": [ 236 // "https://www.w3.org/2018/credentials/v1", 237 // "https://identity.foundation/presentation-exchange/submission/v1" 238 // ], 239 // "id": "DUMMY", 240 // "presentation_submission": { 241 // "id": "DUMMY", 242 // "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 243 // "descriptor_map": [ 244 // { 245 // "id": "age_descriptor", 246 // "format": "ldp_vc", 247 // "path": "$", 248 // "path_nested": { 249 // "id": "age_descriptor", 250 // "format": "ldp_vc", 251 // "path": "$.verifiableCredential[0]" 252 // } 253 // } 254 // ] 255 // }, 256 // "type": [ 257 // "VerifiablePresentation", 258 // "PresentationSubmission" 259 // ], 260 // "verifiableCredential": [ 261 // { 262 // "@context": [ 263 // "https://www.w3.org/2018/credentials/v1" 264 // ], 265 // "credentialSubject": { 266 // "age": true, 267 // "first_name": "Jesse", 268 // "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 269 // "last_name": "Pinkman" 270 // }, 271 // "id": "http://example.edu/credentials/777", 272 // "issuanceDate": "0001-01-01T00:00:00Z", 273 // "issuer": "did:example:76e12ec712ebc6f1c221ebfeb1f", 274 // "type": "VerifiableCredential" 275 // } 276 // ] 277 // } 278 } 279 280 func ExamplePresentationDefinition_CreateVP_with_Ldp_Format() { 281 required := Required 282 283 pd := &PresentationDefinition{ 284 ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 285 Purpose: "To sell you a drink we need to know that you are an adult.", 286 Format: &Format{ 287 Ldp: &LdpType{ 288 ProofType: []string{"Ed25519Signature2018"}, 289 }, 290 }, 291 InputDescriptors: []*InputDescriptor{{ 292 ID: "age_descriptor", 293 Purpose: "Your age should be greater or equal to 18.", 294 Constraints: &Constraints{ 295 LimitDisclosure: &required, 296 Fields: []*Field{ 297 { 298 Path: []string{"$.credentialSubject.age", "$.vc.credentialSubject.age", "$.age"}, 299 Predicate: &required, 300 Filter: &Filter{ 301 Type: &intFilterType, 302 Minimum: 18, 303 }, 304 }, 305 { 306 Path: []string{"$.credentialSchema[0].id", "$.credentialSchema.id", "$.vc.credentialSchema.id"}, 307 Filter: &Filter{ 308 Type: &strFilterType, 309 Const: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 310 }, 311 }, 312 }, 313 }, 314 }}, 315 } 316 317 loader, err := ldtestutil.DocumentLoader() 318 if err != nil { 319 panic(err) 320 } 321 322 vp, err := pd.CreateVP([]*verifiable.Credential{ 323 { 324 ID: "http://example.edu/credentials/777", 325 Context: []string{verifiable.ContextURI}, 326 Types: []string{verifiable.VCType}, 327 Issuer: verifiable.Issuer{ 328 ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", 329 }, 330 Issued: &util.TimeWrapper{ 331 Time: time.Time{}, 332 }, 333 Schemas: []verifiable.TypedID{{ 334 ID: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 335 Type: "JsonSchemaValidator2018", 336 }}, 337 338 Subject: map[string]interface{}{ 339 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 340 "first_name": "Jesse", 341 "last_name": "Pinkman", 342 "age": 21, 343 }, 344 Proofs: []verifiable.Proof{ 345 {"type": "Ed25519Signature2018"}, 346 }, 347 }, 348 }, loader, verifiable.WithJSONLDDocumentLoader(loader)) 349 if err != nil { 350 panic(err) 351 } 352 353 vp.ID = dummy 354 vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy 355 356 vpBytes, err := json.MarshalIndent(vp, "", "\t") 357 if err != nil { 358 panic(err) 359 } 360 361 fmt.Println(string(vpBytes)) 362 // Output: 363 // { 364 // "@context": [ 365 // "https://www.w3.org/2018/credentials/v1", 366 // "https://identity.foundation/presentation-exchange/submission/v1" 367 // ], 368 // "id": "DUMMY", 369 // "presentation_submission": { 370 // "id": "DUMMY", 371 // "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 372 // "descriptor_map": [ 373 // { 374 // "id": "age_descriptor", 375 // "format": "ldp", 376 // "path": "$", 377 // "path_nested": { 378 // "id": "age_descriptor", 379 // "format": "ldp_vc", 380 // "path": "$.verifiableCredential[0]" 381 // } 382 // } 383 // ] 384 // }, 385 // "type": [ 386 // "VerifiablePresentation", 387 // "PresentationSubmission" 388 // ], 389 // "verifiableCredential": [ 390 // { 391 // "@context": [ 392 // "https://www.w3.org/2018/credentials/v1" 393 // ], 394 // "credentialSubject": { 395 // "age": true, 396 // "first_name": "Jesse", 397 // "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 398 // "last_name": "Pinkman" 399 // }, 400 // "id": "http://example.edu/credentials/777", 401 // "issuanceDate": "0001-01-01T00:00:00Z", 402 // "issuer": "did:example:76e12ec712ebc6f1c221ebfeb1f", 403 // "type": "VerifiableCredential" 404 // } 405 // ] 406 // } 407 } 408 409 func ExamplePresentationDefinition_CreateVP_withFormatInInputDescriptor() { 410 required := Required 411 412 pd := &PresentationDefinition{ 413 ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 414 Purpose: "To sell you a drink we need to know that you are an adult.", 415 InputDescriptors: []*InputDescriptor{{ 416 ID: "age_descriptor", 417 Purpose: "Your age should be greater or equal to 18.", 418 Format: &Format{ 419 LdpVP: &LdpType{ 420 ProofType: []string{"Ed25519Signature2018"}, 421 }, 422 }, 423 Constraints: &Constraints{ 424 LimitDisclosure: &required, 425 Fields: []*Field{ 426 { 427 Path: []string{"$.credentialSubject.age", "$.vc.credentialSubject.age", "$.age"}, 428 Predicate: &required, 429 Filter: &Filter{ 430 Type: &intFilterType, 431 Minimum: 18, 432 }, 433 }, 434 { 435 Path: []string{"$.credentialSchema[0].id", "$.credentialSchema.id", "$.vc.credentialSchema.id"}, 436 Filter: &Filter{ 437 Type: &strFilterType, 438 Const: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 439 }, 440 }, 441 }, 442 }, 443 }}, 444 } 445 446 loader, err := ldtestutil.DocumentLoader() 447 if err != nil { 448 panic(err) 449 } 450 451 vp, err := pd.CreateVP([]*verifiable.Credential{ 452 { 453 ID: "http://example.edu/credentials/777", 454 Context: []string{verifiable.ContextURI}, 455 Types: []string{verifiable.VCType}, 456 Issuer: verifiable.Issuer{ 457 ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", 458 }, 459 Issued: &util.TimeWrapper{ 460 Time: time.Time{}, 461 }, 462 Schemas: []verifiable.TypedID{{ 463 ID: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 464 Type: "JsonSchemaValidator2018", 465 }}, 466 467 Subject: map[string]interface{}{ 468 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 469 "first_name": "Jesse", 470 "last_name": "Pinkman", 471 "age": 21, 472 }, 473 Proofs: []verifiable.Proof{ 474 {"type": "Ed25519Signature2018"}, 475 }, 476 }, 477 }, loader, verifiable.WithJSONLDDocumentLoader(loader)) 478 if err != nil { 479 panic(err) 480 } 481 482 vp.ID = dummy 483 vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy 484 485 vpBytes, err := json.MarshalIndent(vp, "", "\t") 486 if err != nil { 487 panic(err) 488 } 489 490 fmt.Println(string(vpBytes)) 491 // Output: 492 // { 493 // "@context": [ 494 // "https://www.w3.org/2018/credentials/v1", 495 // "https://identity.foundation/presentation-exchange/submission/v1" 496 // ], 497 // "id": "DUMMY", 498 // "presentation_submission": { 499 // "id": "DUMMY", 500 // "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 501 // "descriptor_map": [ 502 // { 503 // "id": "age_descriptor", 504 // "format": "ldp_vp", 505 // "path": "$", 506 // "path_nested": { 507 // "id": "age_descriptor", 508 // "format": "ldp_vc", 509 // "path": "$.verifiableCredential[0]" 510 // } 511 // } 512 // ] 513 // }, 514 // "type": [ 515 // "VerifiablePresentation", 516 // "PresentationSubmission" 517 // ], 518 // "verifiableCredential": [ 519 // { 520 // "@context": [ 521 // "https://www.w3.org/2018/credentials/v1" 522 // ], 523 // "credentialSubject": { 524 // "age": true, 525 // "first_name": "Jesse", 526 // "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 527 // "last_name": "Pinkman" 528 // }, 529 // "id": "http://example.edu/credentials/777", 530 // "issuanceDate": "0001-01-01T00:00:00Z", 531 // "issuer": "did:example:76e12ec712ebc6f1c221ebfeb1f", 532 // "type": "VerifiableCredential" 533 // } 534 // ] 535 // } 536 } 537 538 func TestExamplePresentationDefinition_CreateVPWithFormat_NoMatch(t *testing.T) { 539 required := Required 540 541 pd := &PresentationDefinition{ 542 ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 543 Purpose: "To sell you a drink we need to know that you are an adult.", 544 Format: &Format{ 545 LdpVP: &LdpType{ 546 ProofType: []string{"Ed25519Signature2018"}, 547 }, 548 }, 549 InputDescriptors: []*InputDescriptor{{ 550 ID: "age_descriptor", 551 Purpose: "Your age should be greater or equal to 18.", 552 Constraints: &Constraints{ 553 LimitDisclosure: &required, 554 Fields: []*Field{ 555 { 556 Path: []string{"$.credentialSubject.age", "$.vc.credentialSubject.age", "$.age"}, 557 Predicate: &required, 558 Filter: &Filter{ 559 Type: &intFilterType, 560 Minimum: 18, 561 }, 562 }, 563 { 564 Path: []string{"$.credentialSchema[0].id", "$.credentialSchema.id", "$.vc.credentialSchema.id"}, 565 Filter: &Filter{ 566 Type: &strFilterType, 567 Const: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 568 }, 569 }, 570 }, 571 }, 572 }}, 573 } 574 575 loader, err := ldtestutil.DocumentLoader() 576 if err != nil { 577 panic(err) 578 } 579 580 _, err = pd.CreateVP([]*verifiable.Credential{ 581 { 582 ID: "http://example.edu/credentials/777", 583 Context: []string{verifiable.ContextURI}, 584 Types: []string{verifiable.VCType}, 585 Issuer: verifiable.Issuer{ 586 ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", 587 }, 588 Issued: &util.TimeWrapper{ 589 Time: time.Time{}, 590 }, 591 Schemas: []verifiable.TypedID{{ 592 ID: "hub://did:foo:123/Collections/schema.us.gov/passport.json", 593 Type: "JsonSchemaValidator2018", 594 }}, 595 596 Subject: map[string]interface{}{ 597 "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", 598 "first_name": "Jesse", 599 "last_name": "Pinkman", 600 "age": 21, 601 }, 602 Proofs: []verifiable.Proof{ 603 {"type": "JsonWebSignature2020"}, 604 }, 605 }, 606 }, loader, verifiable.WithJSONLDDocumentLoader(loader)) 607 608 require.EqualError(t, err, "credentials do not satisfy requirements") 609 } 610 611 func ExamplePresentationDefinition_CreateVP_withFrame() { 612 vcJSON := ` 613 { 614 "@context": [ 615 "https://www.w3.org/2018/credentials/v1", 616 "https://w3id.org/citizenship/v1", 617 "https://w3id.org/security/bbs/v1" 618 ], 619 "id": "https://issuer.oidp.uscis.gov/credentials/83627465", 620 "type": [ 621 "VerifiableCredential", 622 "PermanentResidentCard" 623 ], 624 "issuer": "did:example:489398593", 625 "identifier": "83627465", 626 "name": "Permanent Resident Card", 627 "description": "Government of Example Permanent Resident Card.", 628 "issuanceDate": "2019-12-03T12:19:52Z", 629 "expirationDate": "2029-12-03T12:19:52Z", 630 "credentialSubject": { 631 "id": "did:example:b34ca6cd37bbf23", 632 "type": [ 633 "PermanentResident", 634 "Person" 635 ], 636 "givenName": "JOHN", 637 "familyName": "SMITH", 638 "gender": "Male", 639 "image": "data:image/png;base64,iVBORw0KGgokJggg==", 640 "residentSince": "2015-01-01", 641 "lprCategory": "C09", 642 "lprNumber": "999-999-999", 643 "commuterClassification": "C1", 644 "birthCountry": "Bahamas", 645 "birthDate": "1958-07-17" 646 } 647 } 648 ` 649 650 frameJSONWithMissingIssuer := ` 651 { 652 "@context": [ 653 "https://www.w3.org/2018/credentials/v1", 654 "https://w3id.org/citizenship/v1", 655 "https://w3id.org/security/bbs/v1" 656 ], 657 "type": ["VerifiableCredential", "PermanentResidentCard"], 658 "@explicit": true, 659 "identifier": {}, 660 "issuer": {}, 661 "issuanceDate": {}, 662 "credentialSubject": { 663 "@explicit": true, 664 "type": ["PermanentResident", "Person"], 665 "givenName": {}, 666 "familyName": {}, 667 "gender": {}, 668 "birthCountry": {} 669 } 670 } 671 ` 672 673 frameDoc, err := jsonutil.ToMap(frameJSONWithMissingIssuer) 674 if err != nil { 675 panic(err) 676 } 677 678 required := Required 679 680 pd := &PresentationDefinition{ 681 ID: "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 682 Frame: frameDoc, 683 InputDescriptors: []*InputDescriptor{{ 684 ID: "country_descriptor", 685 Constraints: &Constraints{ 686 Fields: []*Field{ 687 { 688 Path: []string{"$.credentialSubject.birthCountry", "$.vc.credentialSubject.birthCountry"}, 689 Predicate: &required, 690 Filter: &Filter{ 691 Type: &strFilterType, 692 Const: "Bahamas", 693 }, 694 }, 695 }, 696 }, 697 }}, 698 } 699 700 loader, err := ldtestutil.DocumentLoader() 701 if err != nil { 702 panic(err) 703 } 704 705 vc, err := verifiable.ParseCredential([]byte(vcJSON), verifiable.WithJSONLDDocumentLoader(loader)) 706 if err != nil { 707 panic(err) 708 } 709 710 pubKey, privKey, err := bbs12381g2pub.GenerateKeyPair(sha256.New, nil) 711 if err != nil { 712 panic(err) 713 } 714 715 pubKeyBytes, err := pubKey.Marshal() 716 if err != nil { 717 panic(err) 718 } 719 720 signVCWithBBS(privKey, vc, loader) 721 722 vp, err := pd.CreateVP([]*verifiable.Credential{vc}, loader, verifiable.WithJSONLDDocumentLoader(loader), verifiable.WithPublicKeyFetcher( 723 verifiable.SingleKey(pubKeyBytes, "Bls12381G2Key2020"))) 724 if err != nil { 725 panic(err) 726 } 727 728 vp.ID = dummy 729 vp.CustomFields["presentation_submission"].(*PresentationSubmission).ID = dummy 730 vp.Credentials()[0].(*verifiable.Credential).Proofs[0]["created"] = dummy 731 vp.Credentials()[0].(*verifiable.Credential).Proofs[0]["proofValue"] = dummy 732 733 vpBytes, err := json.MarshalIndent(vp, "", "\t") 734 if err != nil { 735 panic(err) 736 } 737 738 fmt.Println(string(vpBytes)) 739 // Output: 740 // { 741 // "@context": [ 742 // "https://www.w3.org/2018/credentials/v1", 743 // "https://identity.foundation/presentation-exchange/submission/v1" 744 // ], 745 // "id": "DUMMY", 746 // "presentation_submission": { 747 // "id": "DUMMY", 748 // "definition_id": "c1b88ce1-8460-4baf-8f16-4759a2f055fd", 749 // "descriptor_map": [ 750 // { 751 // "id": "country_descriptor", 752 // "format": "ldp_vp", 753 // "path": "$", 754 // "path_nested": { 755 // "id": "country_descriptor", 756 // "format": "ldp_vc", 757 // "path": "$.verifiableCredential[0]" 758 // } 759 // } 760 // ] 761 // }, 762 // "type": [ 763 // "VerifiablePresentation", 764 // "PresentationSubmission" 765 // ], 766 // "verifiableCredential": [ 767 // { 768 // "@context": [ 769 // "https://www.w3.org/2018/credentials/v1", 770 // "https://w3id.org/citizenship/v1", 771 // "https://w3id.org/security/bbs/v1" 772 // ], 773 // "credentialSubject": { 774 // "birthCountry": true, 775 // "familyName": "SMITH", 776 // "gender": "Male", 777 // "givenName": "JOHN", 778 // "id": "did:example:b34ca6cd37bbf23", 779 // "type": [ 780 // "Person", 781 // "PermanentResident" 782 // ] 783 // }, 784 // "id": "https://issuer.oidp.uscis.gov/credentials/83627465", 785 // "identifier": "83627465", 786 // "issuanceDate": "2019-12-03T12:19:52Z", 787 // "issuer": "did:example:489398593", 788 // "proof": { 789 // "created": "DUMMY", 790 // "nonce": "", 791 // "proofPurpose": "assertionMethod", 792 // "proofValue": "DUMMY", 793 // "type": "BbsBlsSignatureProof2020", 794 // "verificationMethod": "did:example:123456#key1" 795 // }, 796 // "type": [ 797 // "PermanentResidentCard", 798 // "VerifiableCredential" 799 // ] 800 // } 801 // ] 802 // } 803 } 804 805 func signVCWithBBS(privKey *bbs12381g2pub.PrivateKey, vc *verifiable.Credential, documentLoader ld.DocumentLoader) { 806 bbsSigner, err := newBBSSigner(privKey) 807 if err != nil { 808 panic(err) 809 } 810 811 sigSuite := bbsblssignature2020.New( 812 suite.WithSigner(bbsSigner), 813 suite.WithVerifier(bbsblssignature2020.NewG2PublicKeyVerifier())) 814 815 ldpContext := &verifiable.LinkedDataProofContext{ 816 SignatureType: "BbsBlsSignature2020", 817 SignatureRepresentation: verifiable.SignatureProofValue, 818 Suite: sigSuite, 819 VerificationMethod: "did:example:123456#key1", 820 } 821 822 err = vc.AddLinkedDataProof(ldpContext, jsonld.WithDocumentLoader(documentLoader)) 823 if err != nil { 824 panic(err) 825 } 826 }