-
Notifications
You must be signed in to change notification settings - Fork 92
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
AleCla97
wants to merge
187
commits into
iotaledger:main
Choose a base branch
from
Cybersecurity-LINKS:feat/pq-t-integration
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+6,007
−49
Open
Changes from all commits
Commits
Show all changes
187 commits
Select commit
Hold shift + click to select a range
12722a3
mapping from Jwk (JwkExt) from json-proof-token to Jwk from identity_…
AlbertoSvg b012e97
implemented JwpDocumentExt for IotaDocument and CoreDocument
AlbertoSvg b170249
generate_method_extended that handles both JWS and JWP algorithm
AlbertoSvg 7d9fee0
new trait JwpDocumentExt separated from JwkDocumentExt using macros d…
AlbertoSvg d948aea
json-proof-token dependency update
AlbertoSvg db46722
From<CredentialJwtClaims> trait for JptClaims and create_credential_j…
AlbertoSvg 21b9588
new JwpOptions
AlbertoSvg fb8e303
successful issuing of a jpt VC
AlbertoSvg 732e4c6
fix stronhold path
AlbertoSvg 234843f
fix JPT type
AlbertoSvg e783430
update to latest version of json-proof-token library
AlbertoSvg 55749ca
Merge branch 'iotaledger:main' into jwp-integration
AlbertoSvg 53051fe
fix key conversion
AlbertoSvg 4b9a199
alternative selective disclosure method
AlbertoSvg a7fbe6b
Jwp Presentation creation
AlbertoSvg 9e5a595
remove JwpOptions and introduce JptCredentialValidationOptions and Jp…
AlbertoSvg 217a754
JWP Presentation verification
AlbertoSvg b33a604
removed multiple issuers during JWP verification since only one Crede…
AlbertoSvg 6429817
extract_issuer_from_presented_jpt util and remove identity_zk module
AlbertoSvg 820672f
add some comments
AlbertoSvg 1fea3be
fix jti undisclose
AlbertoSvg ef77d68
comments and fix nbf undisclosing
AlbertoSvg 4becafb
new RevocationTimeframeStatus and revocation check
AlbertoSvg b03bdc1
remove unused 'use' statements
AlbertoSvg f274243
remove ValidityTimeframeGranularity::SECOND
AlbertoSvg 2e4ad45
Merge remote-tracking branch 'origin/main' into zk-revocation-integra…
AlbertoSvg 9f3a5d9
rename examples and minor fix
AlbertoSvg a74f5aa
add RevocationTimeframeStatus
AlbertoSvg 23938a7
revocation in credential and presentation validation
AlbertoSvg 071e6b8
add TimeframeRevocationExtension for Core/IotaDocument
AlbertoSvg 1992b28
update 10_zkp_revocation example
AlbertoSvg 572518b
implement ML-DSA algorithm keygen
AlbertoSvg 8323975
create post quantum cleartext vc
AlbertoSvg a542b49
post quantum JwsVerifier
AlbertoSvg 4ecb480
implement PQ VC/VP
AlbertoSvg f9208d8
support SLH-DSA
AlbertoSvg 5561a01
support all FALCON and SLH-DSA algs
AlbertoSvg cc0a76e
add WebDID, WebDocument and a new Resolver (not working)
AlbertoSvg 91efeb6
add identity_did_methods module
AlbertoSvg 2b4c9a1
Merge branch 'main' into PQ-T
AlbertoSvg d8d8d69
fix errors
AlbertoSvg 4717d60
Merge remote-tracking branch 'origin/main' into PQ-T
AlbertoSvg f19ee07
fix version
AlbertoSvg fc9c171
fix did web
AlbertoSvg 8f0dd74
Merge remote-tracking branch 'origin/main' into web-did-method
AlbertoSvg 4debbac
VC/VP hybrid
AlbertoSvg 1aaa59e
minor fix and code cleaning
AlbertoSvg 86dca1f
fix and code cleaning
AlbertoSvg 1f7b71b
pqc features
AlbertoSvg fc6c9c4
fix pqc/hybrid features
AlbertoSvg 7e75a35
Merge branch 'iotaledger:main' into hybrid
AlbertoSvg 29693e4
Merge pull request #2 from Cybersecurity-LINKS/pqc-wasm-bindings
AlbertoSvg 6476cc5
implement pqc bindings
AlbertoSvg 0b9e633
update cargo
AlbertoSvg 2fc785a
Merge remote-tracking branch 'origin/main' into hybrid
AlbertoSvg d71af7b
fix example names
AlbertoSvg 4c9058c
Merge remote-tracking branch 'origin/web-did-method' into T-PQ-Hybrid
AlbertoSvg 84b1670
change example name
AlbertoSvg 161853c
introduce DidJwkDocumentExt for DIDJwk creation
AlbertoSvg 1b240f0
pqc demo
AlbertoSvg 9071cc2
change print format
AleCla97 1c7bd0e
impl compositeJwk and hybrid demo
AlbertoSvg 2251d1b
new demo traditional_zk
AlbertoSvg 11ad65b
code cleaning
AlbertoSvg 6be4f64
remove unused imports
AleCla97 c9f16ea
cleanup examples
AleCla97 02dcd7d
raname demos
AlbertoSvg da974f6
Update README.md
AlbertoSvg 79b316e
Update README.md
AlbertoSvg 0ec3de9
Update README.md
AlbertoSvg 06566bb
implement server for did web
AlbertoSvg fd5c2ea
Merge branch 'PQ/T-Hybrid' of https://github.com/Cybersecurity-LINKS/…
AlbertoSvg a5db02a
fix
AlbertoSvg 5901885
Update README.md
AlbertoSvg 43b4515
fix pqc bindings
AlbertoSvg 08ae148
Update README.md
AlbertoSvg 0be14f6
Add pqc bindings
AleCla97 4790387
fix wasm compilation
AleCla97 defdbd7
add ts examples
AleCla97 9f892cd
add binding for did jwk
AleCla97 e989cf6
clean up warning
AleCla97 106457b
remove warning
AleCla97 374a797
add fragment fn
AleCla97 f10ce34
more cleanup
AleCla97 752907f
add pq stprage for examples
AleCla97 c783e09
bindings for new_did_jwk_pqc
AleCla97 1bee110
bindings for new_did_compositejwk
AleCla97 489489a
binding for new_did_jwk_zk
AleCla97 63d4a53
update demos
AleCla97 d0915e1
add license or modification license
AleCla97 09ff6ea
Update README.md
andreavesco 748683e
Update README.md
andreavesco 4e87903
Update README.md
andreavesco ea2ea16
Update README.md
andreavesco 09ca21f
Update README.md
andreavesco ea21e91
Update README.md
andreavesco 13be77c
Update README.md
andreavesco 6e9c561
typo
AleCla97 0d06706
print
AleCla97 39c7969
typo
AleCla97 ea13ea6
Add revocation zk example
AleCla97 c2790e3
Merge pull request #5 from Cybersecurity-LINKS/PQ/T-Hybrid
AleCla97 4b6872e
cleanup examples
AleCla97 a333b17
cleanup
AleCla97 c5be81e
add license
AleCla97 f37f721
cleanup
AleCla97 14f9082
Merge branch 'PQ/T-Hybrid' into PQ/T-Hybrid-bindings-did-jwk
AleCla97 6b35247
Merge branch 'PQ/T-Hybrid-bindings' into PQ/T-Hybrid-bindings-did-jwk
AleCla97 48e219d
Merge pull request #4 from Cybersecurity-LINKS/PQ/T-Hybrid-bindings-d…
AleCla97 80a7aed
Update README.md
andreavesco 3072318
Update README.md
andreavesco 0de1101
Update README.md
andreavesco 6041883
Update README.md
andreavesco 04e12d6
Update README.md
andreavesco 70e34dc
Update README.md
andreavesco 99735fd
update example names
AleCla97 660326e
Update README.md
andreavesco 537e58f
update Readme
AleCla97 6c279bd
Update README.md
andreavesco 47523ba
Update README.md
andreavesco 76b46d7
Update README.md
andreavesco cbd30cc
Update README.md
AleCla97 cf58d2d
Update README.md
AleCla97 eb1156a
Merge pull request #6 from Cybersecurity-LINKS/PQ/T-Hybrid
AleCla97 87e42a4
fix import
AleCla97 66ab227
pq sign
AleCla97 0db936c
implement expand_did_compositejwk
AleCla97 634026c
bind create jws for hybrid
AleCla97 787274f
create bindings fro create_jws_pqc
AleCla97 2071dd5
add ml dsa 44 verifier
AleCla97 ec1a20e
typo
AleCla97 6e3aa70
minimal update to generate and sign mldsa44, tbc
AleCla97 bdc6d21
typo
AleCla97 9786a7b
pqc verifier depending only on liboqs
mikeus9908 60d1c72
remove pqclean from memstore
mikeus9908 2aec60b
Merge pull request #7 from Cybersecurity-LINKS/update-liboqs
mikeus9908 b459e4d
remove useless print
AleCla97 9699991
bind hybrid JWT credential validator
AleCla97 76aaaf8
add methods to create JWT presentations for PQC and hybrid
AleCla97 14cb5f6
Merge branch 'PQ/T-Hybrid-bindings' into upstream_merge
AleCla97 c445b6e
Merge pull request #9 from Cybersecurity-LINKS/upstream_merge
AleCla97 bb9d762
Revert "Merge pull request #9 from Cybersecurity-LINKS/upstream_merge"
mikeus9908 dc8337e
Add createPresentationJpt bind
AleCla97 7e29b7d
remove pq from default features
mikeus9908 046ab9b
update storage
mikeus9908 1bad545
fix feature for bbs trait and remove warnings
mikeus9908 a199692
Move import
mikeus9908 843d649
Merge pull request #10 from Cybersecurity-LINKS/features
mikeus9908 da0da64
Merge pull request #12 from Cybersecurity-LINKS/PQ/T-Hybrid-bindings
AleCla97 5b535f8
Merge remote-tracking branch 'upstream/main' into feat/pq-t-integration
AleCla97 c0b2def
Remove unwanted changes
AleCla97 bf3d64a
Remove unwanted changes
AleCla97 15d5527
Remove unwanted changes
AleCla97 3cad376
Remove unwanted changes
AleCla97 966019c
Remove unwanted changes
AleCla97 85d0083
revert changes
AleCla97 2307e1d
update examples readme
AleCla97 e096881
revert more changes
AleCla97 333c059
Update CompositeAlgId to latest draft version
AleCla97 22c5f7c
add missing modification license header
AleCla97 ccba2f9
Update README and dependencies for oqs verifier
AleCla97 5c86685
fix
AleCla97 8ce32d0
update to Jwktype Algorithm Key Pair (AKP)
AleCla97 fb41fd5
fix
AleCla97 a24fad0
remove old todo
AleCla97 4f84977
revert changes
AleCla97 0ef1e93
revert changes
AleCla97 82b5195
Enhance documentation
AleCla97 bc063d5
Bump zkryptium and json proof token to match to latest BBS and JPT draft
AleCla97 00bd898
Wasm: Bump zkryptium and json proof token version to match the latest…
AleCla97 1c6c692
Update VerificationMethod to use CompositeJsonWebKey type
AleCla97 ed4ecb1
Add missing wasm bindings
AleCla97 b4f8b6d
wasm: JwtPresentationValidatorHybrid bindings
AleCla97 043e115
wasm: PQ and PQ/T examples
AleCla97 b2288cf
add noble pq
AleCla97 f7dd7c3
fix
AleCla97 df13906
fix
AleCla97 0335674
hybrid signature implementation update to the latest draft
AleCla97 18c4894
WASM: hydrid signature update
AleCla97 bfbbd47
Merge branch 'main' into feat/pq-t-integration
AleCla97 1f1a4e2
fix and cleanup
AleCla97 4dab177
fix fmt
AleCla97 12a0674
fix fmt
AleCla97 40192b3
synch
AleCla97 bd9cfed
Revert "synch"
AleCla97 f38f0ee
remove example number
AleCla97 e13d256
Adding missing copyright headers
alessandropino File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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`); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless it's really needed, let's try to avoid pinning dependencies to a specific patch version. For instance:
oqs = { version = "0.10.0", ... }
should beoqs = { version = "0.10", ... }