Skip to content

Commit d7b2d95

Browse files
committed
Incorporate feedback from Sophie Schmieg
1 parent ec1a5f4 commit d7b2d95

File tree

1 file changed

+67
-20
lines changed

1 file changed

+67
-20
lines changed

draft-lundberg-cose-two-party-signing-algs.md

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ normative:
6767
title: "SEC 1: Elliptic Curve Cryptography"
6868

6969
informative:
70+
FALCON:
71+
target: https://falcon-sign.info/
72+
title: 'FALCON: Fast-Fourier Lattice-based Compact Signatures over NTRU'
73+
author:
74+
- fullname: Pierre-Alain Fouque
75+
- fullname: Jeffrey Hoffstein
76+
- fullname: Paul Kirchner
77+
- fullname: Vadim Lyubashevsky
78+
- fullname: Thomas Pornin
79+
- fullname: Thomas Prest
80+
- fullname: Thomas Ricosset
81+
- fullname: Gregor Seiler
82+
- fullname: William Whyte
83+
- fullname: Zhenfei Zhang
84+
date: 2017
7085
FIPS-201:
7186
target: https://doi.org/10.6028/NIST.SP.800-73pt2-5
7287
title: 'Interfaces for Personal Identity Verification: Part 2 – PIV Card Application Card Command Interface'
@@ -170,7 +185,8 @@ PKCS #11 [PKCS11-Spec-v3.1], and PIV [FIPS-201].
170185
Since different signature algorithms digest the message in different ways
171186
and at different stages of the algorithm,
172187
it is not possible for a cryptographic API to specify that, for example, "the hash digest is computed by the caller"
173-
generically for all algorithms. Moreover, different algorithms can have different security considerations when split in this way.
188+
generically for all algorithms.
189+
Security considerations for this split may also differ between algorithms.
174190
Instead, the algorithm identifiers defined in this specification
175191
enable the parties of that cryptographic API to signal precisely, for each signature algorithm individually,
176192
which steps of the algorithm are performed by which party.
@@ -188,10 +204,13 @@ Some signature algorithms,
188204
such as PureEdDSA [RFC8032],
189205
by their design, cannot be split in this way, and therefore cannot be assigned split signing algorithm identifiers.
190206
However, if such a signature algorithm defines a "pre-hashed" variant,
191-
such as Ed25519ph [RFC8032],
192207
that "pre-hashed" algorithm can be assigned a split signing algorithm identifier,
193208
enabling the pre-hashing step to be performed by the _digester_
194-
and the remaining steps by the _signer_. Note however that Ed25519ph is not compatible with PureEd25519 for the verifier, so requires a different algorithm identifier.
209+
and the remaining steps by the _signer_.
210+
For example, this specification defines Ed25519ph-split ({{eddsa-split}}) as a split variant of Ed25519ph [RFC8032].
211+
Note that Ed25519 and Ed25519ph have distinct verification algorithms,
212+
but Ed25519ph and Ed25519ph-split use the same verification algorithm.
213+
195214

196215
## Requirements Notation and Conventions
197216

@@ -298,7 +317,6 @@ COSE_Sign_Args = {
298317
}
299318
~~~
300319

301-
COMMENT(sschmieg): For ML-DSA, we have external-µ, which is again a different API in the sense that the digester needs to be aware of the public key. We also have a context argument, but the signer does not need to learn it.
302320

303321
## COSE Signing Arguments Common Parameters {#cose-sign-args-common}
304322

@@ -343,14 +361,25 @@ and a key derived using `ARKG-P256` [I-D.bradleylundberg-ARKG]:
343361

344362
This specification assumes that both the _digester_ and _signer_ roles
345363
described in {{split-algs}} are trusted and cooperate honestly.
346-
This is because these split signing procedures concern details
347-
that are considered implementation details from a verifier's perspective.
364+
This is because a similar division between "application" and "secure element"
365+
typically exists already:
366+
even if all steps of the signing algorithm are executed in a trusted secure element,
367+
the inputs to the secure element are provided by some outside component such as a software application.
368+
If the application can provide any input to be signed,
369+
then for all practical purposes it is trusted with possession of any private keys
370+
for as long as it is authorized to exercise the secure element.
371+
The application can in practice obtain a signature over any chosen message
372+
without needing to perform a forgery attack.
373+
The same relationship exists between _digester_ and _signer_.
374+
Applications that cannot trust an external _digester_ -
375+
for example a hardware security device with an integrated secure display of what data is about to be signed -
376+
by definition have no use for split signing algorithm identifiers.
377+
378+
Similarly from a verifier's perspective,
379+
these split signing procedures are implementation details.
348380
When a signature is generated by a single party,
349381
that single party takes on both the _digester_ and the _signer_ roles,
350382
and obviously trusts itself to perform the _digester_ role honestly.
351-
This assumption is carried forward for the split signing use case:
352-
the _digester_ is assumed trusted,
353-
since it is part of the overall procedure of generating a signature over some input data.
354383
From the verifier's perspective,
355384
a malicious _digester_ in the split signing model would have the same powers
356385
as a malicious signature generator in a single-party signing model.
@@ -364,26 +393,26 @@ The reasoning in {{sec-cons-trusted-roles-protocol}} does not hold on the compon
364393
A _signer_ implementation MUST NOT assume that the _digester_ implementation
365394
it interoperates with is necessarily honest.
366395
Split signing algorithms MUST NOT be defined in a way
367-
that enables a malicious _digester_ with access to an honest _signer_
368-
to produce forgeries or extract secrets from the _signer_.
396+
that enables a malicious _digester_ with access to an honest _signer_ to produce forgeries -
397+
any that could not be produced by simply requesting a signature over the desired message -
398+
or extract secrets from the _signer_.
369399

370400
For example, for ECDSA ({{ecdsa-split}}), a malicious _digester_ can choose _H_
371401
in such a way that the _signer_ will derive any _digester_-chosen value of _e_,
372402
including zero or other potentially problematic values.
373403
Fortunately, in this case, this does not enable the _digester_ to extract the signature nonce or private key.
374-
It also does not enable forgeries,
404+
It also does not make forgeries easier,
375405
since the _digester_ still needs to find a preimage of _e_ for the relevant hash function.
376406
Definitions of other algorithms need to ensure that similar chosen-input attacks
377407
do not enable extracting secrets or forging protocol-level messages.
378408

379-
COMMENT(sschmieg): Forgeries are *probably* okay: There is a relatively trivial forgery attack against prehashed RSA and we all seem to be fine with it.
380-
In particular, if the digester wants to forge a signature for m, they compute h(m) (including padding), find to integers a, b such that a * b = h(m) mod n, and have the signer sign both a and b, i.e.
381-
compute a^d and b^d. Since exponentiation is multiplicative, the digester can now compute h(m)^d, a valid signature of m, without ever having asked the signer to sign h(m).
382-
The reason we are usually okay with that issue is that the digester already can ask the signer for any signature they want.
383-
Key compromise attacks on the other hand have to be avoided. A naively prehashed version of Falcon would allow such a key compromise: A Falcon signature is a value s such that both s and s * h - hash(r || m) are short.
384-
(h is the public key and r a randomizer). If the digester gets to query the signer for signatures of arbitrary stand-ins for hash(r || m), they can extract the private key by for example asking for repeated signatures of 0.
385-
The basic construction of Falcon and RSA is the same (they are both hash-then-sign algorithms), but where leaving the hash to an external party only gives forgery attacks in RSA, it can give key compromise attacks.
386-
Essentially, a split algorithm needs to be reviewed and potentially have its security proofs adjusted.
409+
For example, a naively prehashed version of FALCON [FALCON] would allow such a key compromise:
410+
A FALCON signature is a value `s` such that both `s` and `s * h - hash(r || m)` are short,
411+
where `h` is the public key and `r` a randomizer.
412+
If the digester gets to query the signer for signatures of arbitrary stand-ins for `hash(r || m)`,
413+
they can extract the private key by for example asking for repeated signatures of 0.
414+
Therefore, definitions of split signing algorithms need to be reviewed and potentially have security proofs adjusted.
415+
387416

388417
# IANA Considerations {#IANA}
389418

@@ -517,9 +546,27 @@ the Internet-Draft of ARKG [I-D.bradleylundberg-ARKG] extends this specification
517546

518547
--- back
519548

549+
# Acknowledgements
550+
{: numbered="false"}
551+
552+
We would like to thank
553+
Ilari Liusvaara,
554+
Sophie Schmieg
555+
and
556+
Falko Strenzke
557+
for their reviews of and contributions to this specification.
558+
559+
520560
# Document History
521561
{: numbered="false"}
522562

563+
-05
564+
565+
* Clarified in introduction that Ed25519 and Ed25519ph(-split) have distinct verification algorithms.
566+
* Clarified in section "Protocol-Level Trusted Roles" why digester is necessarily trusted.
567+
* Clarified in section "Component-Level Trusted Roles" that redundant forgeries are acceptable,
568+
and added example of key compromise concern for naively hashed FALCON.
569+
523570
-04
524571

525572
* Added Implementation Status section.

0 commit comments

Comments
 (0)