Hi Emil,from you explanations below this all seems fine. However, in my review, I commented a specific statement in the draft that had caught my attention:
Quote from the draft: /“The signer executes the PureEdDSA signing procedure, where the value denoted M in the PureEdDSA signing procedure takes the value denoted PH(M) in the EdDSA signing procedure.”/
My review comment: /"The newly defined COSE algorithm identifier Ed25519ph (where Ed25519ph would still have to be registered (?) together with Ed25519ph-split) defined in this draft would conflict in this sense with EdDSA as it is already defined in COSE: Both these algorithm IDs internally use PureEdDSA, and thus the said ambiguity would arise."/
M taking on the value of PH(M) reads like the potential problem of confusing M and H(M). So it seems to me that either
- the above quote is formulated wrong and needs to be corrected, but the intended design itself is sound (editorial error only),
- or there is a design problem that needs to be corrected,- or the statement is correct and still there is no design problem – in that case I would expect an explanation in the draft why confusion of M vs. H(M) is not possible.
Best regards, Falko Am 21.11.25 um 13:52 schrieb Emil Lundberg:
Hi Falko,Thanks, I may have misunderstood what kind of ambiguity you meant, then. These identifiers do not introduce any ambiguity in whether a given signature S over a message M verifies as verify(PK, M, S) or as verify(PK, H(M), S), if that is what you meant? The split signing algorithm identifiers indeed do not change the mechanism of signing. The signing algorithm is the same, only the algorithm steps are split up between two separate entities. Rather, the ambiguity I meant is in whether the private key holder came in contact with the raw message M or only with H(M).In particular, I believe that concerns like draft-ietf-lamps-cms-euf-cma-signeddata-00 <https://datatracker.ietf.org/doc/draft-ietf-lamps-cms-euf-cma-signeddata/00/> do not apply here because we do not change verification procedures in any way.But to make sure we're talking about the same thing, let me lay it all out concretely, using ECDSA as an example:Given a message M and a hash function H, ECDSA computes a message representative e = H(M) and then computes the signature (r, s) over e. A verifier can verify the signature over M by recomputing the same e = H(M) and validating the correctness of (r, s) against e and the public key. These steps are all the same with or without use of the split signing algorithm identifiers.Now, say we want to create an ECDSA signature using a key held in a separate hardware module. The hardware module may expose an API ESP256.Sign(M) which takes the raw message M, computes e = SHA256(M) internally and then returns the signature over M using the private key held in the hardware module. This works, but it requires sending the entire M to the hardware module, for example via a USB or NFC connection. This may not be feasible if M is large. For example, in our motivating use case the hardware module is a FIDO CTAP2 authenticator, and the CTAP2 USB protocol <https://fidoalliance.org/specs/fido-v2.3-rd-20251023/fido-client-to-authenticator-protocol-v2.3-rd-20251023.html#usb-message-and-packet-structure> has a payload length limit of 7609 bytes (for now - this might get expanded to better support PQC, but I'd still be surprised if it expands into the megabytes range).So instead, we define the split signing identifier ESP256-split which defines that the e = H(M) step will be performed by the software application (the /digester/), and the CTAP2 authenticator (the /signer/) continues from there. This means the authenticator can expose the signing API ESP256-split.Sign(e) in addition to ESP256.Sign(M). As a whole it'll still be the same algorithm steps taken as if the CTAP2 authenticator had performed the e = H(M) step, and in both cases verifiers will still verify the resulting signature as verify(PK, M, S), not as verify(PK, H(M), S). In particular, if the ECDSA nonce is deterministic [RFC 6979 <https://datatracker.ietf.org/doc/html/rfc6979.html>] , then both ESP256-split.Sign(e) and ESP256.Sign(M) will return exactly the same signature if e = SHA256(M). The only difference is that the CTAP2 authenticator didn't see the raw M, only H(M). That might be significant for "what you see is what you sign" certification programs, but it doesn't affect the signature output. The signature is still only valid over the message M (and any SHA256 collisions, of course).The only possible confusion here would be if ESP256-split.Sign(e) is called with e = M instead of e = H(M), and M happens to be exactly 32 bytes long. But the resulting signature would fail verification against verify(PK, M, S), it would instead verify against the SHA256 preimage of M: verify(PK, SHA256-inverse(M), S).So I don't think this affects the EUF-CMA security of the signature scheme, because the signature scheme as a whole is the same. The EUF-CMA security game also doesn't allow the adversary to trivially query the signature oracle for the sought signature, so it's fair to assume a trusted /digester/ in the split signing case. A malicious /digester/ in the split signing case is largely equivalent to the attacker having possession (but not knowledge) of the private key in the monolithic signing case, in which case no forgery is needed since the attacker can just request the signature directly.Does that seem to hold up, and address your concerns?I would gladly add some of this discussion to a Security Considerations subsection in the draft, if that seems useful.And to your last point: I generally recommend to use cryptographic algorithms in COSE only through their external interfaces and according to their specifications in the form of RFCs or other standards. In case cryptographic algorithms are being "opened up", in the sense of accessing their internals, or their inputs redefined or reinterpreted, I suggest to let the design undergo a detailed review [...]I agree, and in draft -03 the introduction now cites existing standards for precedent. Specifically, OpenPGP <https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.1.pdf> (see section 7.2.10 PSO: COMPUTE DIGITAL SIGNATURE, page 63), PKCS #11 <https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/os/pkcs11-spec-v3.1-os.html#_Toc111203427> (see section 6.3.12 ECDSA without hashing) and FIPS-201 <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73pt2-5.pdf> (see section 3.2.4. GENERAL AUTHENTICATE Card Command, page 18). We should probably make those references more precise (right now we only refer to each standard as a whole) and expand on how exactly they relate to this draft, though. I've logged this an issue in the draft repo <https://github.com/YubicoLabs/cose-two-party-signing-algs-rfc/issues/19>.But yes, reaching into internals like this certainly does need to be done carefully. In a way, that's why we're proposing this draft in the first place - to have a concrete registry of precisely how to "reach into internals" in a way that's known to be safe for each respective algorithm (where applicable).Thanks again for your review and feedback! Cheers, Emil Lundberg Staff Engineer | Yubico <http://www.yubico.com/>Den ons 19 nov. 2025 kl 09:56 skrev Falko Strenzke <[email protected]>:Hi Emil, Am 24.10.25 um 14:50 schrieb Emil Lundberg:Security-wise, I would like to point out that it is necessary that with the introduction of the split signing algorithms no ambiguity is created as to whether a specific signature algorithm is applied to the message directly or the message digest. If that was the case, then an attacker could potentially exchange the directly signed message with a hash of the message without invalidating the signature. The entire point of this is to /keep/ that ambiguity, though, and intentionally /not/ invalidate the signature: we want to generate, for example, ESP256 signatures that can be successfully verified by an existing ESP256 verifier that is not (and indeed should not be) aware of ESP256-split. As you mentioned in your first paragraph: [...] Otherwise such a separation seems to be an implementation detail that typically has no relevance for interoperability.The quote you give here doesn't imply an ambiguity with respect to what is exactly signed. The separation is only an implementation detail if it doesn't change the mechanism (e.g., signing directly or signing a hash) of signing. Just to make sure this aspect doesn't t get lost: If this draft (or another) should in any way introduce an ambiguity with respect to what exactly is being signed, then this will result in formal violation of the EUF-CMA security notion, which means allowing signature forgeries. Whether or not or to which degree this can be exploited might require further analysis. I generally recommend to use cryptographic algorithms in COSE only through their external interfaces and according to their specifications in the form of RFCs or other standards. In case cryptographic algorithms are being "opened up", in the sense of accessing their internals, or their inputs redefined or reinterpreted, I suggest to let the design undergo a detailed review from one or multiple experts in cryptographic engineering. My existing review doesn't live up to that as I lack knowledge of the application context and, as I become aware after your response, apparently don't understand the design and its exact goals. Best regards, Falko--*MTG AG* Dr. Falko Strenzke Phone: +49 6151 8000 24 E-Mail: [email protected] Web: mtg.de <https://www.mtg.de> ------------------------------------------------------------------------ MTG AG - Dolivostr. 11 - 64293 Darmstadt, Germany Commercial register: HRB 8901 Register Court: Amtsgericht Darmstadt Management Board: Jürgen Ruf (CEO), Tamer Kemeröz Chairman of the Supervisory Board: Dr. Thomas Milde This email may contain confidential and/or privileged information. If you are not the correct recipient or have received this email in error, please inform the sender immediately and delete this email.Unauthorised copying or distribution of this email is not permitted. Data protection information: Privacy policy <https://www.mtg.de/en/privacy-policy>
-- *MTG AG* Dr. Falko Strenzke Phone: +49 6151 8000 24 E-Mail: [email protected] Web: mtg.de <https://www.mtg.de> ------------------------------------------------------------------------ MTG AG - Dolivostr. 11 - 64293 Darmstadt, Germany Commercial register: HRB 8901 Register Court: Amtsgericht Darmstadt Management Board: Jürgen Ruf (CEO), Tamer Kemeröz Chairman of the Supervisory Board: Dr. Thomas MildeThis email may contain confidential and/or privileged information. If you are not the correct recipient or have received this email in error, please inform the sender immediately and delete this email.Unauthorised copying or distribution of this email is not permitted.
Data protection information: Privacy policy <https://www.mtg.de/en/privacy-policy>
smime.p7s
Description: Kryptografische S/MIME-Signatur
_______________________________________________ COSE mailing list -- [email protected] To unsubscribe send an email to [email protected]
