Closed lemoustachiste closed 9 months ago
This test (https://github.com/digitalbazaar/ecdsa-sd-2023-cryptosuite/blob/main/test/derive.spec.js#L281) in the test suite still passes.
It could be that the examples were generated with a bug in them in the past, so I just regenerated them now. The examples are produced from the test suite -- so if those tests are passing, the examples should be as well. Perhaps take another look now with the updated example data? If you're having trouble at that point, could you provide an example to run or more details / code snippets and the error text you're seeing? Thanks!
Hi Dave,
this is the error I am getting:
file:///Users/julien/work/poc-ecdsa-sd-blockcerts/node_modules/@digitalbazaar/ecdsa-sd-2023-cryptosuite/lib/disclose.js:51
throw new Error('Nothing selected for disclosure.');
^
I have put the branch as a repro, here is the entry point:
And here the implementation of the library: https://github.com/blockchain-certificates/poc-ecdsa-sd-2023-blockcerts/blob/repro/error-no-disclosure/src/suite/ecdsa-sd-2023.ts#L72
I have tried setting the options
to an empty object or to null
, both to no avail.
@lemoustachiste,
I ran the above and hit that error. It looks like there aren't any pointers provided at all -- no mandatory pointers and no selective pointers. This would, in fact, result in no data being generated, hence the error. When the original VC is signed, if it has no mandatory pointers provided, then something selective will have to be provided later, but I suspect you should be passing some mandatory pointer when signing the VC to begin with, such as requiring the issuer
and issuanceDate
fields, minimally.
You could make this change here:
const suite = new DataIntegrityProof({
signer: keyPair.signer(),
cryptosuite: createSignCryptosuite({
mandatoryPointers: [
'/issuanceDate',
'/issuer'
]
})
});
If I make that change locally, then npm run derive
passes without an error.
I'll note that even in the case that nothing is mandatory in credentialSubject
, a holder would need to selectively disclose something from credentialSubject
to generate a valid VC (because a VC requires a credentialSubject
property). The ecdsa-sd cryptosuite doesn't care about this (it's at a lower layer), but a VC consumer would.
Ah I must have missed that possibility. That's great that answers one of the questions I asked in the CCG group.
From a philosophical standpoint, would it be expected from the issuer to always specify what are mandatory fields in the VC, or since we can specify them at derive
time, we could have either the wallet or the verifier specify those? And subsidiary question, can you augment the initial list from the issuer at derive
time, or would that overwrite it?
Thanks
@lemoustachiste,
Ah I must have missed that possibility. That's great that answers one of the questions I asked in the CCG group.
From a philosophical standpoint, would it be expected from the issuer to always specify what are mandatory fields in the VC, or since we can specify them at
derive
time, we could have either the wallet or the verifier specify those?
To be clear, there are two different kinds of fields to be disclosed: mandatory and selective (and either set of these can be empty but not both). Only the issuer can define what is mandatory to disclose and must do so when the original VC is issued and the base proof is added. If these fields are not disclosed at derive
time, the design is such that verification of the derived VC will fail.
The cryptosuite algorithms are also designed such that the mandatory to disclose fields are automatically disclosed when deriving. Which fields are mandatory to disclose is expressed in the base proof data so implementations just use this information automatically -- and then add any additionally specified selective-to-disclose fields specified at derive
time.
So, at derive
time, any other (non-mandatory) fields can be selectively disclosed, including nothing extra at all. Of course, something needs to be disclosed, so if an issuer didn't say anything was mandatory, then the disclosure must add something selective -- or else the VC would be totally empty which is treated as an error.
The cryptosuite isn't meant to be prescriptive at the VC layer in what MUST be mandatory or not, so it's up to VC designers and issuers to make those choices. But, in general, issuers are expected to make things like issuer
and issuanceDate
/expirationDate
(for VC 1.1 and validFrom
/validUntil
if present, for VC 2.0) mandatory to disclose.
As for what is selectively disclosed, expectations are also that verifiers will ask for what they want. The way this is done today with, for example, a VPR with a QueryByExample
query coming in from VC API / CHAPI, is that the QueryByExample
query can be translated into JSON pointers and passed to the disclose/derive cryptosuite. A digital wallet can show the user which fields will be disclosed then, based on what the verifier is looking for. A more advanced digital wallet could allow the user to add / remove certain fields at-will, however, doing so might just make the verifier refuse to continue whatever workflow is in progress (or perhaps they will ask again for something different, it is all use case specific).
In implementations we're finding that if a verifier does not ask for any information in the credential subject to be disclosed, then a digital wallet may recommend disclosing the whole credential subject or just its id
, if present. This is because a VC MUST have a credentialSubject
with something in to be a valid VC. Either way, users should be made aware of what will be disclosed. Digital wallets will evolve over time to figure out how to best serve users in these circumstances.
And subsidiary question, can you augment the initial list from the
issuer
at derive time, or would that overwrite it?
So you can't override the list of mandatory fields from the issuer, but providing selective disclosure JSON pointers "augments it" by disclosing more than what is mandatory.
Note: Technically speaking (down in the cryptosuite layer / spec itself), the way mandatory fields are revealed and secured is different from the selectively disclosable fields. The mandatory ones are bound together and secured with a single hash and signature whereas the selectively disclosable ones each get their own signature, which is only revealed if the selectively disclosable field is also revealed (this approach provides some additional benefits such as hiding side channel information around the number of fields and a reduction in proof size). The mandatory hash is always recomputed by the verifier from the presented data, and if it does not match the original value, the signature verification will fail.
Thanks Dave,
I have been able to work with a mandatory fields derived cert and verify, so at a high level I understand the features of this library.
May I suggest that for a better understanding the example on the README highlights that you can/should pass mandatory fields at sign time?
When I looked at the API of createSignCryptosuite
it became obvious but I missed that as I just re-implemented the example to get to the initial signature of the document.
@lemoustachiste,
I've added a quick fix with a commented mandatoryPointers
option to the existing example and filed an issue (#22) to add more examples in the future. Thanks!
Hi,
this example https://github.com/digitalbazaar/ecdsa-sd-2023-cryptosuite#creating-a-derived-proof-with-only-mandatory-fields-revealed does not seem to be possible with the latest version. I am getting an error along the lines of having to specify some disclosable data.