Skip to content

Post-Quantum (PQ) and Post-Quantum/Traditional (PQ/T) hybrid signatures for VCs #1625

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 186 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
186 commits
Select commit Hold shift + click to select a range
12722a3
mapping from Jwk (JwkExt) from json-proof-token to Jwk from identity_…
AlbertoSvg Nov 14, 2023
b012e97
implemented JwpDocumentExt for IotaDocument and CoreDocument
AlbertoSvg Nov 15, 2023
b170249
generate_method_extended that handles both JWS and JWP algorithm
AlbertoSvg Nov 16, 2023
7d9fee0
new trait JwpDocumentExt separated from JwkDocumentExt using macros d…
AlbertoSvg Nov 16, 2023
d948aea
json-proof-token dependency update
AlbertoSvg Nov 16, 2023
db46722
From<CredentialJwtClaims> trait for JptClaims and create_credential_j…
AlbertoSvg Nov 29, 2023
21b9588
new JwpOptions
AlbertoSvg Nov 29, 2023
fb8e303
successful issuing of a jpt VC
AlbertoSvg Nov 30, 2023
732e4c6
fix stronhold path
AlbertoSvg Nov 30, 2023
234843f
fix JPT type
AlbertoSvg Nov 30, 2023
e783430
update to latest version of json-proof-token library
AlbertoSvg Dec 14, 2023
55749ca
Merge branch 'iotaledger:main' into jwp-integration
AlbertoSvg Dec 14, 2023
53051fe
fix key conversion
AlbertoSvg Dec 15, 2023
4b9a199
alternative selective disclosure method
AlbertoSvg Dec 22, 2023
a7fbe6b
Jwp Presentation creation
AlbertoSvg Jan 3, 2024
9e5a595
remove JwpOptions and introduce JptCredentialValidationOptions and Jp…
AlbertoSvg Jan 8, 2024
217a754
JWP Presentation verification
AlbertoSvg Jan 8, 2024
b33a604
removed multiple issuers during JWP verification since only one Crede…
AlbertoSvg Jan 8, 2024
6429817
extract_issuer_from_presented_jpt util and remove identity_zk module
AlbertoSvg Jan 9, 2024
820672f
add some comments
AlbertoSvg Jan 11, 2024
1fea3be
fix jti undisclose
AlbertoSvg Jan 12, 2024
ef77d68
comments and fix nbf undisclosing
AlbertoSvg Jan 15, 2024
4becafb
new RevocationTimeframeStatus and revocation check
AlbertoSvg Jan 25, 2024
b03bdc1
remove unused 'use' statements
AlbertoSvg Jan 25, 2024
f274243
remove ValidityTimeframeGranularity::SECOND
AlbertoSvg Jan 26, 2024
2e4ad45
Merge remote-tracking branch 'origin/main' into zk-revocation-integra…
AlbertoSvg Jan 26, 2024
9f3a5d9
rename examples and minor fix
AlbertoSvg Jan 26, 2024
a74f5aa
add RevocationTimeframeStatus
AlbertoSvg Feb 1, 2024
23938a7
revocation in credential and presentation validation
AlbertoSvg Feb 1, 2024
071e6b8
add TimeframeRevocationExtension for Core/IotaDocument
AlbertoSvg Feb 1, 2024
1992b28
update 10_zkp_revocation example
AlbertoSvg Feb 1, 2024
572518b
implement ML-DSA algorithm keygen
AlbertoSvg Feb 8, 2024
8323975
create post quantum cleartext vc
AlbertoSvg Feb 13, 2024
a542b49
post quantum JwsVerifier
AlbertoSvg Feb 13, 2024
4ecb480
implement PQ VC/VP
AlbertoSvg Feb 13, 2024
f9208d8
support SLH-DSA
AlbertoSvg Feb 15, 2024
5561a01
support all FALCON and SLH-DSA algs
AlbertoSvg Feb 28, 2024
cc0a76e
add WebDID, WebDocument and a new Resolver (not working)
AlbertoSvg May 29, 2024
91efeb6
add identity_did_methods module
AlbertoSvg Jun 6, 2024
2b4c9a1
Merge branch 'main' into PQ-T
AlbertoSvg Jun 12, 2024
d8d8d69
fix errors
AlbertoSvg Jun 12, 2024
4717d60
Merge remote-tracking branch 'origin/main' into PQ-T
AlbertoSvg Jun 12, 2024
f19ee07
fix version
AlbertoSvg Jun 12, 2024
fc9c171
fix did web
AlbertoSvg Jul 8, 2024
8f0dd74
Merge remote-tracking branch 'origin/main' into web-did-method
AlbertoSvg Jul 8, 2024
4debbac
VC/VP hybrid
AlbertoSvg Jul 17, 2024
1aaa59e
minor fix and code cleaning
AlbertoSvg Jul 18, 2024
86dca1f
fix and code cleaning
AlbertoSvg Jul 29, 2024
1f7b71b
pqc features
AlbertoSvg Jul 30, 2024
fc6c9c4
fix pqc/hybrid features
AlbertoSvg Aug 30, 2024
7e75a35
Merge branch 'iotaledger:main' into hybrid
AlbertoSvg Aug 30, 2024
29693e4
Merge pull request #2 from Cybersecurity-LINKS/pqc-wasm-bindings
AlbertoSvg Aug 30, 2024
6476cc5
implement pqc bindings
AlbertoSvg Sep 12, 2024
0b9e633
update cargo
AlbertoSvg Sep 18, 2024
2fc785a
Merge remote-tracking branch 'origin/main' into hybrid
AlbertoSvg Sep 18, 2024
d71af7b
fix example names
AlbertoSvg Sep 18, 2024
4c9058c
Merge remote-tracking branch 'origin/web-did-method' into T-PQ-Hybrid
AlbertoSvg Oct 9, 2024
84b1670
change example name
AlbertoSvg Oct 9, 2024
161853c
introduce DidJwkDocumentExt for DIDJwk creation
AlbertoSvg Oct 10, 2024
1b240f0
pqc demo
AlbertoSvg Oct 10, 2024
9071cc2
change print format
AleCla97 Oct 11, 2024
1c7bd0e
impl compositeJwk and hybrid demo
AlbertoSvg Oct 16, 2024
2251d1b
new demo traditional_zk
AlbertoSvg Oct 16, 2024
11ad65b
code cleaning
AlbertoSvg Oct 17, 2024
6be4f64
remove unused imports
AleCla97 Oct 21, 2024
c9f16ea
cleanup examples
AleCla97 Oct 21, 2024
02dcd7d
raname demos
AlbertoSvg Oct 24, 2024
da974f6
Update README.md
AlbertoSvg Oct 24, 2024
79b316e
Update README.md
AlbertoSvg Oct 24, 2024
0ec3de9
Update README.md
AlbertoSvg Oct 24, 2024
06566bb
implement server for did web
AlbertoSvg Oct 24, 2024
fd5c2ea
Merge branch 'PQ/T-Hybrid' of https://github.com/Cybersecurity-LINKS/…
AlbertoSvg Oct 24, 2024
a5db02a
fix
AlbertoSvg Oct 24, 2024
5901885
Update README.md
AlbertoSvg Oct 28, 2024
43b4515
fix pqc bindings
AlbertoSvg Oct 31, 2024
08ae148
Update README.md
AlbertoSvg Oct 31, 2024
0be14f6
Add pqc bindings
AleCla97 Nov 4, 2024
4790387
fix wasm compilation
AleCla97 Nov 4, 2024
defdbd7
add ts examples
AleCla97 Nov 5, 2024
9f892cd
add binding for did jwk
AleCla97 Nov 5, 2024
e989cf6
clean up warning
AleCla97 Nov 5, 2024
106457b
remove warning
AleCla97 Nov 5, 2024
374a797
add fragment fn
AleCla97 Nov 5, 2024
f10ce34
more cleanup
AleCla97 Nov 6, 2024
752907f
add pq stprage for examples
AleCla97 Nov 6, 2024
c783e09
bindings for new_did_jwk_pqc
AleCla97 Nov 6, 2024
1bee110
bindings for new_did_compositejwk
AleCla97 Nov 6, 2024
489489a
binding for new_did_jwk_zk
AleCla97 Nov 6, 2024
63d4a53
update demos
AleCla97 Nov 7, 2024
d0915e1
add license or modification license
AleCla97 Nov 7, 2024
09ff6ea
Update README.md
andreavesco Nov 7, 2024
748683e
Update README.md
andreavesco Nov 7, 2024
4e87903
Update README.md
andreavesco Nov 8, 2024
ea2ea16
Update README.md
andreavesco Nov 8, 2024
09ca21f
Update README.md
andreavesco Nov 8, 2024
ea21e91
Update README.md
andreavesco Nov 8, 2024
13be77c
Update README.md
andreavesco Nov 8, 2024
6e9c561
typo
AleCla97 Nov 11, 2024
0d06706
print
AleCla97 Nov 11, 2024
39c7969
typo
AleCla97 Nov 11, 2024
ea13ea6
Add revocation zk example
AleCla97 Nov 11, 2024
c2790e3
Merge pull request #5 from Cybersecurity-LINKS/PQ/T-Hybrid
AleCla97 Nov 11, 2024
4b6872e
cleanup examples
AleCla97 Nov 11, 2024
a333b17
cleanup
AleCla97 Nov 11, 2024
c5be81e
add license
AleCla97 Nov 11, 2024
f37f721
cleanup
AleCla97 Nov 11, 2024
14f9082
Merge branch 'PQ/T-Hybrid' into PQ/T-Hybrid-bindings-did-jwk
AleCla97 Nov 11, 2024
6b35247
Merge branch 'PQ/T-Hybrid-bindings' into PQ/T-Hybrid-bindings-did-jwk
AleCla97 Nov 11, 2024
48e219d
Merge pull request #4 from Cybersecurity-LINKS/PQ/T-Hybrid-bindings-d…
AleCla97 Nov 11, 2024
80a7aed
Update README.md
andreavesco Nov 12, 2024
3072318
Update README.md
andreavesco Nov 12, 2024
0de1101
Update README.md
andreavesco Nov 12, 2024
6041883
Update README.md
andreavesco Nov 12, 2024
04e12d6
Update README.md
andreavesco Nov 12, 2024
70e34dc
Update README.md
andreavesco Nov 12, 2024
99735fd
update example names
AleCla97 Nov 12, 2024
660326e
Update README.md
andreavesco Nov 12, 2024
537e58f
update Readme
AleCla97 Nov 12, 2024
6c279bd
Update README.md
andreavesco Nov 12, 2024
47523ba
Update README.md
andreavesco Nov 12, 2024
76b46d7
Update README.md
andreavesco Nov 12, 2024
cbd30cc
Update README.md
AleCla97 Nov 13, 2024
cf58d2d
Update README.md
AleCla97 Nov 13, 2024
eb1156a
Merge pull request #6 from Cybersecurity-LINKS/PQ/T-Hybrid
AleCla97 Nov 18, 2024
87e42a4
fix import
AleCla97 Nov 18, 2024
66ab227
pq sign
AleCla97 Nov 18, 2024
0db936c
implement expand_did_compositejwk
AleCla97 Nov 18, 2024
634026c
bind create jws for hybrid
AleCla97 Nov 18, 2024
787274f
create bindings fro create_jws_pqc
AleCla97 Nov 21, 2024
2071dd5
add ml dsa 44 verifier
AleCla97 Nov 26, 2024
ec1a20e
typo
AleCla97 Nov 27, 2024
6e3aa70
minimal update to generate and sign mldsa44, tbc
AleCla97 Nov 28, 2024
bdc6d21
typo
AleCla97 Dec 2, 2024
9786a7b
pqc verifier depending only on liboqs
mikeus9908 Jan 14, 2025
60d1c72
remove pqclean from memstore
mikeus9908 Jan 14, 2025
2aec60b
Merge pull request #7 from Cybersecurity-LINKS/update-liboqs
mikeus9908 Jan 14, 2025
b459e4d
remove useless print
AleCla97 Jan 15, 2025
9699991
bind hybrid JWT credential validator
AleCla97 Jan 17, 2025
76aaaf8
add methods to create JWT presentations for PQC and hybrid
AleCla97 Jan 21, 2025
14cb5f6
Merge branch 'PQ/T-Hybrid-bindings' into upstream_merge
AleCla97 Jan 23, 2025
c445b6e
Merge pull request #9 from Cybersecurity-LINKS/upstream_merge
AleCla97 Jan 23, 2025
bb9d762
Revert "Merge pull request #9 from Cybersecurity-LINKS/upstream_merge"
mikeus9908 Jan 23, 2025
dc8337e
Add createPresentationJpt bind
AleCla97 Jan 27, 2025
7e29b7d
remove pq from default features
mikeus9908 Feb 19, 2025
046ab9b
update storage
mikeus9908 Feb 19, 2025
1bad545
fix feature for bbs trait and remove warnings
mikeus9908 Feb 20, 2025
a199692
Move import
mikeus9908 Feb 20, 2025
843d649
Merge pull request #10 from Cybersecurity-LINKS/features
mikeus9908 Feb 20, 2025
da0da64
Merge pull request #12 from Cybersecurity-LINKS/PQ/T-Hybrid-bindings
AleCla97 Mar 27, 2025
5b535f8
Merge remote-tracking branch 'upstream/main' into feat/pq-t-integration
AleCla97 Mar 31, 2025
c0b2def
Remove unwanted changes
AleCla97 Apr 1, 2025
bf3d64a
Remove unwanted changes
AleCla97 Apr 1, 2025
15d5527
Remove unwanted changes
AleCla97 Apr 2, 2025
3cad376
Remove unwanted changes
AleCla97 Apr 2, 2025
966019c
Remove unwanted changes
AleCla97 Apr 2, 2025
85d0083
revert changes
AleCla97 Apr 3, 2025
2307e1d
update examples readme
AleCla97 Apr 3, 2025
e096881
revert more changes
AleCla97 Apr 7, 2025
333c059
Update CompositeAlgId to latest draft version
AleCla97 Apr 7, 2025
22c5f7c
add missing modification license header
AleCla97 Apr 7, 2025
ccba2f9
Update README and dependencies for oqs verifier
AleCla97 Apr 7, 2025
5c86685
fix
AleCla97 Apr 7, 2025
8ce32d0
update to Jwktype Algorithm Key Pair (AKP)
AleCla97 Apr 7, 2025
fb41fd5
fix
AleCla97 Apr 7, 2025
a24fad0
remove old todo
AleCla97 Apr 9, 2025
4f84977
revert changes
AleCla97 Apr 9, 2025
0ef1e93
revert changes
AleCla97 Apr 9, 2025
82b5195
Enhance documentation
AleCla97 Apr 9, 2025
bc063d5
Bump zkryptium and json proof token to match to latest BBS and JPT draft
AleCla97 Apr 9, 2025
00bd898
Wasm: Bump zkryptium and json proof token version to match the latest…
AleCla97 Apr 9, 2025
1c6c692
Update VerificationMethod to use CompositeJsonWebKey type
AleCla97 Apr 10, 2025
ed4ecb1
Add missing wasm bindings
AleCla97 Apr 10, 2025
b4f8b6d
wasm: JwtPresentationValidatorHybrid bindings
AleCla97 Apr 14, 2025
043e115
wasm: PQ and PQ/T examples
AleCla97 Apr 14, 2025
b2288cf
add noble pq
AleCla97 Apr 14, 2025
f7dd7c3
fix
AleCla97 Apr 14, 2025
df13906
fix
AleCla97 Apr 14, 2025
0335674
hybrid signature implementation update to the latest draft
AleCla97 Apr 16, 2025
18c4894
WASM: hydrid signature update
AleCla97 Apr 17, 2025
bfbbd47
Merge branch 'main' into feat/pq-t-integration
AleCla97 Apr 17, 2025
1f1a4e2
fix and cleanup
AleCla97 Apr 17, 2025
4dab177
fix fmt
AleCla97 Apr 23, 2025
12a0674
fix fmt
AleCla97 Apr 23, 2025
40192b3
synch
AleCla97 Apr 23, 2025
bd9cfed
Revert "synch"
AleCla97 Apr 23, 2025
f38f0ee
remove example number
AleCla97 Apr 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ members = [
"identity_jose",
"identity_ecdsa_verifier",
"identity_eddsa_verifier",
"identity_pqc_verifier",
"examples",
]

Expand All @@ -25,8 +26,10 @@ serde = { version = "1.0", default-features = false, features = ["alloc", "deriv
thiserror = { version = "1.0", default-features = false }
strum = { version = "0.25", default-features = false, features = ["std", "derive"] }
serde_json = { version = "1.0", default-features = false }
json-proof-token = { version = "0.3.5" }
zkryptium = { version = "0.2.2", default-features = false, features = ["bbsplus"] }
json-proof-token = { version = "0.4.1" }
zkryptium = { version = "0.4.0", default-features = false, features = ["bbsplus"] }
oqs = {version = "0.10.0", default-features = false, features = ["sigs", "std", "vendored"] }


[workspace.package]
authors = ["IOTA Stiftung"]
Expand Down
6 changes: 4 additions & 2 deletions bindings/wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ futures = { version = "0.3" }
identity_ecdsa_verifier = { path = "../../identity_ecdsa_verifier", default-features = false, features = ["es256", "es256k"] }
identity_eddsa_verifier = { path = "../../identity_eddsa_verifier", default-features = false, features = ["ed25519"] }
js-sys = { version = "0.3.61" }
json-proof-token = "0.3.4"
json-proof-token = "0.4.1"
proc_typescript = { version = "0.1.0", path = "./proc_typescript" }
serde = { version = "1.0", features = ["derive"] }
serde-wasm-bindgen = "0.6.5"
Expand All @@ -34,7 +34,7 @@ serde_repr = { version = "0.1", default-features = false }
tokio = { version = "1.29", default-features = false, features = ["sync"] }
wasm-bindgen = { version = "0.2.100", features = ["serde-serialize"] }
wasm-bindgen-futures = { version = "0.4", default-features = false }
zkryptium = "0.2.2"
zkryptium = "0.4.0"

[dependencies.identity_iota]
path = "../../identity_iota"
Expand All @@ -48,6 +48,8 @@ features = [
"status-list-2021",
"jpt-bbs-plus",
"sd-jwt-vc",
"pqc",
"hybrid"
]

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/examples/src/1_advanced/8_zkp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export async function createDid(client: Client, secretManager: SecretManagerType

const fragment = await document.generateMethodJwp(
storage,
ProofAlgorithm.BLS12381_SHA256,
ProofAlgorithm.BBS,
undefined,
MethodScope.VerificationMethod(),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export async function createDid(client: Client, secretManager: SecretManagerType

const fragment = await document.generateMethodJwp(
storage,
ProofAlgorithm.BLS12381_SHA256,
ProofAlgorithm.BBS,
undefined,
MethodScope.VerificationMethod(),
);
Expand Down
281 changes: 281 additions & 0 deletions bindings/wasm/examples/src/1_advanced/hybrid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
// Copyright 2024 Fondazione Links
// SPDX-License-Identifier: Apache-2.0

import {
CoreDID,
Credential,
Duration,
FailFast,
IotaDocument,
IotaIdentityClient,
JwkPqMemStore,
JwsSignatureOptions,
JwsVerificationOptions,
Jwt,
PQJwsVerifier,
EdDSAJwsVerifier,
JwtCredentialValidationOptions,
JwtCredentialValidator,
JwtPresentationOptions,
JwtPresentationValidationOptions,
JwtPresentationValidator,
KeyIdMemStore,
MethodScope,
Presentation,
Resolver,
Storage,
SubjectHolderRelationship,
Timestamp,
CompositeAlgId,
JwtCredentialValidatorHybrid,
JwtPresentationValidatorHybrid,
} from "@iota/identity-wasm/node";
import { Address, AliasOutput, Client, MnemonicSecretManager, SecretManager, SecretManagerType, Utils } from "@iota/sdk-wasm/node";
import { API_ENDPOINT, ensureAddressHasFunds } from "../util";

async function createHybridDid(client: Client, secretManager: SecretManagerType, storage: Storage): Promise<{
address: Address;
document: IotaDocument;
fragment: string;
}> {
const didClient = new IotaIdentityClient(client);
const networkHrp: string = await didClient.getNetworkHrp();

const secretManagerInstance = new SecretManager(secretManager);
const walletAddressBech32 = (await secretManagerInstance.generateEd25519Addresses({
accountIndex: 0,
range: {
start: 0,
end: 1,
},
bech32Hrp: networkHrp,
}))[0];

console.log("Wallet address Bech32:", walletAddressBech32);

await ensureAddressHasFunds(client, walletAddressBech32);

const address: Address = Utils.parseBech32Address(walletAddressBech32);

// Create a new DID document with a placeholder DID.
// The DID will be derived from the Alias Id of the Alias Output after publishing.
const document = new IotaDocument(networkHrp);

// Create a new method with PQ/T algorithm.
const fragment = await document.generateMethodHybrid(
storage,
CompositeAlgId.IdMldsa44Ed25519,
"#0",
MethodScope.VerificationMethod(),
);

// Construct an Alias Output containing the DID document, with the wallet address
// set as both the state controller and governor.
const aliasOutput: AliasOutput = await didClient.newDidOutput(address, document);

// Publish the Alias Output and get the published DID document.
const published = await didClient.publishDidOutput(secretManager, aliasOutput);

return { address, document: published, fragment };
}

/**
* This example shows how to create an hybrid Verifiable Presentation and validate it
*/
export async function hybrid() {
// ===========================================================================
// Step 1: Create identities for the issuer and the holder.
// ===========================================================================

const client = new Client({
primaryNode: API_ENDPOINT,
localPow: true,
});
const didClient = new IotaIdentityClient(client);

// Creates a new wallet and identity (see "0_create_did" example).
const issuerSecretManager: MnemonicSecretManager = {
mnemonic: Utils.generateMnemonic(),
};
const issuerStorage: Storage = new Storage(
new JwkPqMemStore(),
new KeyIdMemStore(),
);
let { document: issuerDocument, fragment: issuerFragment } = await createHybridDid(
client,
issuerSecretManager,
issuerStorage,
);

// Create an identity for the holder, in this case also the subject.
const aliceSecretManager: MnemonicSecretManager = {
mnemonic: Utils.generateMnemonic(),
};
const aliceStorage: Storage = new Storage(
new JwkPqMemStore(),
new KeyIdMemStore(),
);
let { document: aliceDocument, fragment: aliceFragment } = await createHybridDid(
client,
aliceSecretManager,
aliceStorage,
);

// ===========================================================================
// Step 2: Issuer creates and signs a Verifiable Credential.
// ===========================================================================

const subject = {
id: aliceDocument.id(),
name: "Alice",
degreeName: "Bachelor of Science and Arts",
degreeType: "BachelorDegree",
GPA: "4.0",
};

// Create an unsigned `UniversityDegree` credential for Alice
const unsignedVc = new Credential({
id: "https://example.edu/credentials/3732",
type: "UniversityDegreeCredential",
issuer: issuerDocument.id(),
credentialSubject: subject,
});

// Create a Credential JWT with the issuer's hybrid verification method.
const credentialJwt = await issuerDocument.createCredentialJwtHybrid(
issuerStorage,
issuerFragment,
unsignedVc,
new JwsSignatureOptions(),
);


const res = new JwtCredentialValidatorHybrid(new EdDSAJwsVerifier, new PQJwsVerifier()).validate(
credentialJwt,
issuerDocument,
new JwtCredentialValidationOptions(),
FailFast.FirstError,
);
console.log("credentialjwt validation", res.intoCredential());

// ===========================================================================
// Step 3: Issuer sends the Verifiable Credential to the holder.
// ===========================================================================

// The credential is then serialized to JSON and transmitted to the holder in a secure manner.
// Note that the credential is NOT published to the IOTA Tangle. It is sent and stored off-chain.
console.log(`Sending credential (as JWT) to the holder`, unsignedVc.toJSON());

// ===========================================================================
// Step 4: Verifier sends the holder a challenge and requests a signed Verifiable Presentation.
// ===========================================================================

// A unique random challenge generated by the requester per presentation can mitigate replay attacks.
const nonce = "475a7984-1bb5-4c4c-a56f-822bccd46440";

// The verifier and holder also agree that the signature should have an expiry date
// 10 minutes from now.
const expires = Timestamp.nowUTC().checkedAdd(Duration.minutes(10));

// ===========================================================================
// Step 5: Holder creates a verifiable presentation from the issued credential for the verifier to validate.
// ===========================================================================

// Create a Verifiable Presentation from the Credential
const unsignedVp = new Presentation({
holder: aliceDocument.id(),
verifiableCredential: [credentialJwt],
});

// Create a Hybrid JWT verifiable presentation using the holder's verification method
// and include the requested challenge and expiry timestamp.
const presentationJwt = await aliceDocument.createPresentationJwtHybrid(
aliceStorage,
aliceFragment,
unsignedVp,
new JwsSignatureOptions({ nonce }),
new JwtPresentationOptions({ expirationDate: expires }),
);

// ===========================================================================
// Step 6: Holder sends a verifiable presentation to the verifier.
// ===========================================================================
console.log(
`Sending presentation (as JWT) to the verifier`,
unsignedVp.toJSON(),
);

// ===========================================================================
// Step 7: Verifier receives the Verifiable Presentation and verifies it.
// ===========================================================================

// The verifier wants the following requirements to be satisfied:
// - JWT verification of the presentation (including checking the requested challenge to mitigate replay attacks)
// - JWT verification of the credentials.
// - The presentation holder must always be the subject, regardless of the presence of the nonTransferable property
// - The issuance date must not be in the future.

const jwtPresentationValidationOptions = new JwtPresentationValidationOptions(
{
presentationVerifierOptions: new JwsVerificationOptions({ nonce }),
},
);

const resolver = new Resolver({
client: didClient,
});
// Resolve the presentation holder.
const presentationHolderDID: CoreDID = JwtPresentationValidator.extractHolder(presentationJwt);
const resolvedHolder = await resolver.resolve(
presentationHolderDID.toString(),
);

// Validate presentation. Note that this doesn't validate the included credentials.
let decodedPresentation = new JwtPresentationValidatorHybrid(new EdDSAJwsVerifier, new PQJwsVerifier()).validate(
presentationJwt,
resolvedHolder,
jwtPresentationValidationOptions,
);

// Validate the hybrid credentials in the presentation.
let credentialValidator = new JwtCredentialValidatorHybrid(new EdDSAJwsVerifier, new PQJwsVerifier());
let validationOptions = new JwtCredentialValidationOptions({
subjectHolderRelationship: [
presentationHolderDID.toString(),
SubjectHolderRelationship.AlwaysSubject,
],
});

let jwtCredentials: Jwt[] = decodedPresentation
.presentation()
.verifiableCredential()
.map((credential) => {
const jwt = credential.tryIntoJwt();
if (!jwt) {
throw new Error("expected a JWT credential");
} else {
return jwt;
}
});

// Concurrently resolve the issuers' documents.
let issuers: string[] = [];
for (let jwtCredential of jwtCredentials) {
let issuer = JwtCredentialValidator.extractIssuerFromJwt(jwtCredential);
issuers.push(issuer.toString());
}
let resolvedIssuers = await resolver.resolveMultiple(issuers);

// Validate the credentials in the presentation.
for (let i = 0; i < jwtCredentials.length; i++) {
credentialValidator.validate(
jwtCredentials[i],
resolvedIssuers[i],
validationOptions,
FailFast.FirstError,
);
}

// Since no errors were thrown we know that the validation was successful.
console.log(`VP successfully validated`);
}
Loading