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]

Reply via email to