I was thrilled to read this draft. It roughly matches what I had hoped and imagined could come to be back when JWP and BBS began their standardization journeys.
I'd love to help work on it. On Mon, Jul 6, 2026 at 1:49 PM Christian Bormann <chris.bormann= [email protected]> wrote: > Hi David, > > I’ve tried to make the initial design simple on purpose - for a lot of > these I had thought about more complex solutions, but realised it would > likely be beneficial to propose a simpler version and discuss trade-offs of > more complex parts from there. > It was also my lessons learned from starting an implementation for most of > the parts of this construction: the current version feels like a somewhat > natural replacement for business logic currently using SD-JWT VC type > credentials, while keeping the complexity of the implementation rather low > (apart from some of the crypto parts). > > 1. The new “cmap” issuer header has overlap with the “claims” header in > JPT. I notice one significant difference is a document > substitution/structural mapping approach to support sub-claims - rather > than using a path/pointer primitive to define the name of each top level > claim or sub-claim, it replicates a claim/sub-claim tree and provides > positional metadata. > > > This somewhat surprised me, as the sd-jwt vc draft ( > https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-13.html#name-example-2) > and OpenID4VP ( > https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-claims-path-pointer > ) > both seem to use more of a pointer syntax to decompose the document. While > not yet published, I have been working based on feedback that this is more > of the direction that implementors preferred, so I’m curious if there was a > particular set of motivations to go with the “cmap" format. > > > I had called it “claims” initially before I realized it clashed with JPT > definitions. As I had shown at October 2025 IIW I had also started with a > more complex design based on a JSON path logic (basically the DCQL paths > from OpenID4VP), but realized that there was very little real-world gain > compared to a static mapping at a lot of additional complexity. I did an > implementation of both and decided to start with this proposal as a > starting point. > > Happy to discuss how to best align between the different constructions. > > 2. The scalar encoding is defined as an ASCII decimal encoding of the > integer value. I have two related observations here: > > 2a. When operating in scalar=true mode, I’m curious why this is not an > I2OSP big-endian representation of the integer value. JSON numbers are a > complicated substrate for exact integer handling, as JSON implementations > typically use double-precision floats for numeric values, which both allow > for decimals and lose integer accuracy above 53 bits. A binary > representation seems like it would decouple from these issues. > > 2b. I’m curious whether it is worth limiting scalar claim values as > defined here to uint64, when they are meant to be disclosable data. > > I have not designed these proof constructions myself, so I may be missing > something here. However, my assumption is that there may be an efficiency > case made between these two points: a proof over a bounded binary value may > be substantially simpler than a proof that can span the scalar field and is > currently allowed by the current decimal encoding. > > > In general, there is a bit of discussion currently happening where to > define the scalar encoding and how to limit - I tried to make choices that > are easiest to implement, but my current mental model would be that we will > likely define the scalar encoding in the BBS blind signature draft and only > define how to convey that information in the Issuer Header in data models / > credential formats (since there might also be additional type information > depending on format). > > On the costs for full range: Yes, a range proof over the full range would > be roughly 4x as costly. We probably want to limit the range, the question > is if that happens as a general limitation in the BBS blind signature > draft, or as a policy that can be chosen by the issuer (conveyed via issuer > header). > > On the Why JSON: The canonical decimal encoding fully aligns with the JSON > serialization of the integer —> BBS message value and disclosed payload are > identical - otherwise we will very likely run into weird implementation > problems of conflicting representation of integers. > On the float concern: the message is the integer denoted by those octets, > so nothing is ever round-tripped through a JSON number type. > > 3. The encoding for the device binding key is little endian, which > surprised me considering both BBS and P-256 are big endian. Any elaboration > on the motivation behind this decision? > > > That is the construction that was proposed in the paper for device binding > and how the sigma protocol currently works on the commitments: > https://www.ietf.org/archive/id/draft-cllz-cfrg-ecdsa-pop-00.html#section-4.2. > I tried to touch as little crypto as possible for this proposal (or rather > reverted a lot of the initial proposal I had on those things). > > 4. For decoys, I assume JWP-BBS-DECOY was chosen partially because it > isn’t a legal JSON Text value. Would it make sense if the scalar=true > alternative was also defined to be a fixed, not valid value that e.g. > proofs could be written to check against? > > > Yeah, we should definitely iterate over that mechanism and values. I > wanted to have a properly defined DECOY value to allow for things like > “proof all entires in this array” - to allow the verifier to validate that > all other entires are invalid basically. Once we properly define the max > range of integer values, I’d make propose to make sure the raw_scalar value > is out of range (invalid). > > 5. Device binding hits a case I hadn’t thought of, partly because I hadn’t > considered a case for payloads both being candidates for disclosure and for > commitments - that a conceptual payload might need to be represented over > more than one slot. Is reserving space at a particular offset (e.g. the > first four scalars) going to be appropriate? For example, is there a > potential for a credential to be issued with more than one key encoded into > it? > > > I had thought about instead defining it as a claim and reserve more > message indexes, something like this: > > “kb”: [0,1,2,3] > > But it again complicates parsing logic. There might be other proofs that > also need multiple message slots, so maybe it makes sense to shift the > design in that direction. Current proposal was the simplest I could come up > with that fulfils the use-cases we have in mind. > > 6. For sub-proofs, my suspicion is that the metadata/setup would be > encoded into the presentation header, while the actual proof values would > be part of the presentation proofs sequence. Is that your expectation as > well? > > > Commitments are protected via the core proof, we need to figure out if we > need to lock in the sub-proofs in that one as well (e.g., via the > presentation header). I left it out for the time being since I wasn’t sure > and the dangers of not binding seemed not too big? The paper currently > binds more into the sub-proofs than the current proposal of mine does, but > that is something I’d probably like to solve w/ the presentation header > (e.g., including all commitments in the header to guarantee that nothing > can be removed), but right now the BBS blind signature draft proposal > slightly differs from the LSZ25 proposal in that in LSZ25 the commitments > are inputs to core_proof, in the blind BBS draft they are currently > outputs. Since that is one of the things currently being discussed with the > BBS blind signature draft afaik, I wanted to wait for a resolution of that > before making sure we have the right binding input to core & sub-proofs. > > Currently the whole sub-proof objects (alg, public inputs, proof bytes) > are self-contained entries in the proofs sequence - only the binding runs > through the core proof. > > 7. The draft currently says that the “kb” device binding header must be > present to denote that there are slots reserved for holding the key, but > also that the key MUST be asserted via a sub-proof. Baking this usage > policy in seems limiting, but I have not yet come up with a concrete > example to back that up. > > > We could loosen that to allow something like “traditional” device binding > for certain high assurance use-cases as well. Optionality always comes at a > cost though - the MUST was a conservative choice I made for the initial > draft to keep things simple. > > 8. For sub-claims in particular, I’m noodling over whether this would be > feasible to have in JWP rather than as an algorithm-specific feature - > partly because I could see other algorithms wanting an identical facility > in the future. There might be some commonality in how the constructions > work across some algorithms, but certainly not all - and I suspect > differences might be hard to reconcile at the presentation header level > (such as equality taking a BBS12-381 G1 point as input). We could specify > specifically e.g. range-proof for BBS-MOD in a single registry, but > I haven’t figured out if there’s a way to encourage commonality or if that > is just mapping out an overlapping namespace. > > > Yeah, I was also contemplating where to best fit what. Given that we are > also using BBS blind signature instead of core BBS for the commitments, my > initial thought was to solve all problems in this draft right now and then > discuss which of these should move to other drafts (like the raw scalars in > the BBS blind signature draft). My goal was to basically use what is > available in terms of other drafts and define something that can be (apart > from some of the sub-proof details) implemented. > I had initially also defined more concrete sub-proof constructions to have > a fully implementable draft, but chose to remove them since those should > definitely not live in this document (e.g., the device binding proof). > > 9. With the exclusion of the device binding claim above, it appears all > sub-claim usage is opt-in - such that a holder can support verifiers with > differing capabilities without needing different credentials. This was a > concern of mine with the BBS extensions published so far, and I’m delighted > to see this. > > > Yes, that was exactly the idea of this construction. We’ve roughly > sketched out several bigger use-cases (age verification, verifiable > pseudonyms, identity credentials) that can easily be built on top of such a > construction with different sub-proof types. > > Best Regards, > Christian > > On 6. Jul 2026, at 16:00, David Waite <david= > [email protected]> wrote: > > Hello Christian - I’m excited to see this work! > > Some initial comments and questions from a brief read (in no semblance of > priority order:) > > 1. The new “cmap” issuer header has overlap with the “claims” header in > JPT. I notice one significant difference is a document > substitution/structural mapping approach to support sub-claims - rather > than using a path/pointer primitive to define the name of each top level > claim or sub-claim, it replicates a claim/sub-claim tree and provides > positional metadata. > > This somewhat surprised me, as the sd-jwt vc draft ( > https://www.ietf.org/archive/id/draft-ietf-oauth-sd-jwt-vc-13.html#name-example-2) > and OpenID4VP ( > https://openid.net/specs/openid-4-verifiable-presentations-1_0.html#name-claims-path-pointer > ) > both seem to use more of a pointer syntax to decompose the document. While > not yet published, I have been working based on feedback that this is more > of the direction that implementors preferred, so I’m curious if there was a > particular set of motivations to go with the “cmap" format. > > Ideally I think I would like to see a credential profiling of JPT, > analogous to the SD-JWT VC work. That would motivate me to push for one of > “cmap” or “claims” that can bend to support both generalized JPT and > specific credential use cases, including the usage here. > > 2. The scalar encoding is defined as an ASCII decimal encoding of the > integer value. I have two related observations here: > > 2a. When operating in scalar=true mode, I’m curious why this is not an > I2OSP big-endian representation of the integer value. JSON numbers are a > complicated substrate for exact integer handling, as JSON implementations > typically use double-precision floats for numeric values, which both allow > for decimals and lose integer accuracy above 53 bits. A binary > representation seems like it would decouple from these issues. > > 2b. I’m curious whether it is worth limiting scalar claim values as > defined here to uint64, when they are meant to be disclosable data. > > I have not designed these proof constructions myself, so I may be missing > something here. However, my assumption is that there may be an efficiency > case made between these two points: a proof over a bounded binary value may > be substantially simpler than a proof that can span the scalar field and is > currently allowed by the current decimal encoding. > > 3. The encoding for the device binding key is little endian, which > surprised me considering both BBS and P-256 are big endian. Any elaboration > on the motivation behind this decision? > > 4. For decoys, I assume JWP-BBS-DECOY was chosen partially because it > isn’t a legal JSON Text value. Would it make sense if the scalar=true > alternative was also defined to be a fixed, not valid value that e.g. > proofs could be written to check against? > > 5. Device binding hits a case I hadn’t thought of, partly because I hadn’t > considered a case for payloads both being candidates for disclosure and for > commitments - that a conceptual payload might need to be represented over > more than one slot. Is reserving space at a particular offset (e.g. the > first four scalars) going to be appropriate? For example, is there a > potential for a credential to be issued with more than one key encoded into > it? > > 6. For sub-proofs, my suspicion is that the metadata/setup would be > encoded into the presentation header, while the actual proof values would > be part of the presentation proofs sequence. Is that your expectation as > well? > > 7. The draft currently says that the “kb” device binding header must be > present to denote that there are slots reserved for holding the key, but > also that the key MUST be asserted via a sub-proof. Baking this usage > policy in seems limiting, but I have not yet come up with a concrete > example to back that up. > > 8. For sub-claims in particular, I’m noodling over whether this would be > feasible to have in JWP rather than as an algorithm-specific feature - > partly because I could see other algorithms wanting an identical facility > in the future. There might be some commonality in how the constructions > work across some algorithms, but certainly not all - and I suspect > differences might be hard to reconcile at the presentation header level > (such as equality taking a BBS12-381 G1 point as input). We could specify > specifically e.g. range-proof for BBS-MOD in a single registry, but > I haven’t figured out if there’s a way to encourage commonality or if that > is just mapping out an overlapping namespace. > > 9. With the exclusion of the device binding claim above, it appears all > sub-claim usage is opt-in - such that a holder can support verifiers with > differing capabilities without needing different credentials. This was a > concern of mine with the BBS extensions published so far, and I’m delighted > to see this. > > -DW > > > > > On Jul 3, 2026, at 2:02 PM, Christian Bormann <chris.bormann= > [email protected]> wrote: > > Dear JOSE & OAuth WG, > > Sorry for cross-posting, but this seems to be a topic that would fit both > WGs and cross-posting seemed to be the best way. > > I have submitted a new ID that proposes a digital credential format > building on top of JSON Web Proofs, SD-JWT VC, and blind BBS Signatures: > Datatracker: > https://datatracker.ietf.org/doc/draft-bormann-jwp-modular-bbs/ - > GitHub: https://github.com/c2bo/draft-bormann-jwp-modular-bbs > > This document defines a digital credential format that uses JSON Web > Proofs (JWP) as its container format and Blind BBS Signatures as its > signature scheme combined with a modular framework for attaching > zero-knowledge sub-proofs. This allows a Holder to reveal some > attributes directly while proving predicates such as range or > equality over the ones they keep hidden. A credential can > additionally be bound to an ECDSA P-256 device key, with possession > of the key proven in every presentation without revealing the public > key. The credential type definition and data model follow SD-JWT VC > [I-D.ietf-oauth-sd-jwt-vc]. > > The core idea behind this draft is to enable a credential format that > functions similar to SD-JWT VC, but powered by a modular Anonymous > Credentials framework. > Instead of building on top of JWS/JWT, the container format is JWP > (currently JSON / compact serialisation only) and the core data model & > credential type system > of SD-JWT VC are re-used. The core signature mechanism is BBS, > specifically the blind BBS draft, since it adds committed disclosure - > fresh Pedersen commitments > to hidden messages at presentation time. > > The proposed construction allows for a digital credential format with > unlinkable presentations where each claim/value can individually be > > - hidden > - disclosed > - committed > > Commitments can then be used as inputs to chained sub-proofs (also called > Commit-and-Prove). This allows for sub-proofs like a range proof over > issuance or expiration time (proving that the credential is not expired > instead of disclosing the expiration time), or equality proofs (e.g., > proving two credentials > contain the same name without disclosing the value). The draft introduces > a registry and a few core sub-proofs, with one important sub-proof allowing > for a key > binding to a P-256 public key where a Zero Knowledge Proof of Knowledge > over a valid signature replaces the KB-JWT of SD-JWT. > The concrete constructions for these sub-proofs will be leveraged from > existing work (e.g., for range proofs) and the key binding sub-proof is > expected to be a > separate draft in CFRG: > https://datatracker.ietf.org/doc/draft-cllz-cfrg-ecdsa-pop/. > > The general idea for such a construction has been discussed for some time > in the context of EU Digital Identity Wallets / eIDAS and the draft roughly > follows the concepts of: > > - > https://github.com/eu-digital-identity-wallet/eudi-doc-standards-and-technical-specifications/blob/main/docs/technical-specifications/ts14-zkps-from-mms.md > - https://eprint.iacr.org/2025/1981 (Vision: A Modular Framework for > Anonymous Credential Systems) > > This is a rough first draft and especially the sub-proof parts definitely > need further work, but I’d love to get some feedback on the draft and the > general concept. > > Given the reliance on JWP for serialisation, I thought JOSE would be a > natural home, but since some parts of SD-JWT VC are re-used, there > definitely > is an argument to be made for OAuth as well. Are people interested in this > kind of work and if so where should it happen? > > Happy to present the draft in Vienna if possible / still fits into the > agenda. > > Best Regards, > Christian > _______________________________________________ > OAuth mailing list -- [email protected] > To unsubscribe send an email to [email protected] > > > _______________________________________________ > OAuth mailing list -- [email protected] > To unsubscribe send an email to [email protected] > > > _______________________________________________ > jose mailing list -- [email protected] > To unsubscribe send an email to [email protected] > -- Brent Zundel Standards Architect | Yubico <http://www.yubico.com/>
_______________________________________________ OAuth mailing list -- [email protected] To unsubscribe send an email to [email protected]
