-
Notifications
You must be signed in to change notification settings - Fork 61
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
One step signature and verification #552
Conversation
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.
Could you push again to trigger the CI fully? Some jobs are skipped because it was a draft PR.
I didn't review in full details, but we discussed it and I'm fully in favour of simplifying the API.
A couple of question:
- is
CryptographicSuite
the correct term? I know "cryptosuite" is often used in specs, should we use that instead? - how does one provide the context loader now? Is it as part of the VM/DID resolver?
7af98e7
to
ea0dbc0
Compare
I often ask myself the same question. "Cryptographic Suite" is clearly the official name as you can see here, but "cryptosuite" is used everywhere as a shorthand, so much that its starting to feel like the de facto name. I don't have a strong opinion on which one we should use. My only argument is that my spell checker doesn't recognize "cryptosuite".
Instead of |
I used the opportunity to remove the |
This PR is about simplifying how
ssi
process a set of claims for signature and/or verification.How it works currently
Currently signature and verification are both done in two steps.
Signature
T
and use a security-specific function to build aVerifiable<T, P>
whereP
is a proof type. For JWS the proof type isssi_jws::Signature
. For Data-Integrity the proof type isssi_data_integrity::Proof<S>
whereS
is a cryptosuite type (S: CryptographicSuite
). The Data-Integrity-specific signature function isCryptographicSuite::sign
.Verifiable::unprepare
to discard byproducts of the signature, what we call the proof "preparation". This will merge the claims and proof into a single type determined by<P as MergeProof>::Merged
. In the case of JWS this type isDecodedJWS<T>
. In the case of Data-Integrity proofs this type isDataIntegrity<T, S>
.Here is how it looks from the user point of view:
Here the
context
holds all the parameters required by the proof preparation algorithm.Verification
VerifiableClaims
. This can beDecodedJWS<T>
orDataIntegrity<T, S>
.VerifiableClaims::into_verifiable
to create aVerifiable<T, P>
type "preparing" the proof.Verifiable::verify
to verify the proof.Here is how it looks from the user point of view:
Once again,
context
here holds all the parameters required by the proof preparation algorithm (although in this case we provide good defaults by usinginto_verifiable()
instead ofinto_verifiable_with(context)
).The
Verifiable
typeThe
Verifiable<T, P>
type is here to hold the "prepared" proof. The preparation holds all the intermediate data common to signature and verification. For instance for Data-Integrity suites using Linked-Data, preparing the proof will mean doing the JSON-LD expansion and RDF canonicalization, required by both signature and verification.In theory this has a number of advantages:
The issue
After using this design for a while, I've found a lot of issue that I think are not worth the benefits:
Verifiable
type and having to useinto_verifiable
is annoying. What if you have aVerifiable
instance and want to change the claims or the proof? Then you have to callunprepare
andinto_verifiable
again. There is an helper method calledtemper
, but it's still annoying.Verifiable
,Proof
,PrepareProof
,ExtractProof
,MergeProof
, etc. that's a lot we could get rid of.json-ld
crate. Data-Integrity cryptosuites need to use the JSON-LD expansion algorithm, which requires a JSON-LD loader that we pass to the proof preparation environment using thecontext
variable that should provide a loader. The issue is, theLoader
trait expects a type parameter leaking the RDF vocabulary type used by the application. Which means the cryptosuite implementation cannot use any RDF vocabulary it wants, but one provided by the user so it is compatible with the loader. So now instead of just the loader, the context needs to provide an RDF vocabulary and interpretation with a lot of trait bounds to satisfy the requirements of the cryptosuite. Here is how this hell looks like (C
is the environment type, andT
the claim type):Solution
The solution implemented by this PR is as follows:
json-ld
that removes the type parameter on theLoader
trait. This allowed me to reduce the number of bounds above toVerifier
type and all the traits related to proof preparation.sign
function directly produces a type implementingVerifiableClaims
such asDecodedJWS<T>
orDataIntegrity<T, S>
:verify
method is now directly provided by theVerifiableClaims
trait: