Verifiable Verification in Cryptographic Protocols

Common verification steps in cryptographic protocols, such as signature or message authentication code checks or the validation of elliptic curve points, are crucial for the overall security of the protocol. Yet implementation errors omitting these steps easily remain unnoticed, as often the protocol will function perfectly anyways. One of the most prominent examples is Apple's goto fail bug where the erroneous certificate verification skipped over several of the required steps, marking invalid certificates as correctly verified. This vulnerability went undetected for at least 17 months. We propose here a mechanism which supports the detection of such errors on a cryptographic level. Instead of merely returning the binary acceptance decision, we let the verification return more fine-grained information in form of what we call a confirmation code. The reader may think of the confirmation code as disposable information produced as part of the relevant verification steps. In case of an implementation error like the goto fail bug, the confirmation code would then miss essential elements. The question arises now how to verify the confirmation code itself. We show how to use confirmation codes to tie security to basic functionality at the overall protocol level, making erroneous implementations be detected through the protocol not functioning properly. More concretely, we discuss the usage of confirmation codes in secure connections, established via a key exchange protocol and secured through the derived keys. If some verification steps in a key exchange protocol execution are faulty, then so will be the confirmation codes, and because we can let the confirmation codes enter key derivation, the connection of the two parties will eventually fail. In consequence, an implementation error like goto fail would now be detectable through a simple connection test. We propose here a mechanism which supports the detection of such errors on a cryptographic level. Instead of merely returning the binary acceptance decision, we let the verification return more fine-grained information in form of what we call a confirmation code. The reader may think of the confirmation code as disposable information produced as part of the relevant verification steps. In case of an implementation error like the goto fail bug, the confirmation code would then miss essential elements. The question arises now how to verify the confirmation code itself. We show how to use confirmation codes to tie security to basic functionality at the overall protocol level, making erroneous implementations be detected through the protocol not functioning properly. More concretely, we discuss the usage of confirmation codes in secure connections, established via a key exchange protocol and secured through the derived keys. If some verification steps in a key exchange protocol execution are faulty, then so will be the confirmation codes, and because we can let the confirmation codes enter key derivation, the connection of the two parties will eventually fail. In consequence, an implementation error like goto fail would now be detectable through a simple connection test.


INTRODUCTION
Programming errors in software code keep on reoccurring.While detecting such bugs is already a tedious task in general, the situation gets exacerbated in the context of security and cryptographic code in particular.The reason is that cryptographic implementations are extremely brittle: bugs can be entirely unnoticeable from a functionality point of view, yet lead to a complete failure of security.Such bugs are most hidden when cryptography is used within a single implementation; a prominent recent example being a faulty key rotation mechanism at Amazon AWS using all-zero keys for TLS session ticket encryption [27], leading to a perfectly functional and simultaneously perfectly insecure cryptosystem.
But even when a cryptographic implementation is interoperating with others, implementation mistakes can go unnoticed, for as long as months or years.Some of the best-known examples include Apple's goto fail bug [43] where some certificate validation steps had been skipped due to a superflous goto fail; code line, causing even invalid certificates to pass verification.A similar case of erroneous certificate validation happened in the GnuTLS library [46] where a procedure could return negative values, but only zero values were interpreted as an error by the calling procedure.As yet another example, such misinterpretation of parameters also caused programmers to use restricted certificate validation in cURL, as pointed out in [25], when setting the parameters unintentionally to true (interpreted as 1) instead of integer value 2 for a full certificate check, including matching the name in the certificate with the requested name.
Similarly widely exploited and remaining issues arise from missing soundness checks of cryptographic parameters.The most prominent examples are presumably the small-subgroup attacks on discrete logarithms [4,35,48] where the verifier does not check that the received values belong to the sufficiently large subgroup.The attack keeps on resurfacing in various forms, e.g., [1,3,47], and can also be applied to RSA-based settings, e.g., see [2] for a recent attack on the MEGA encryption system.Another nasty variation of this attack is the fixed-coordinate attack on Bluetooth [13].

Tying Security to Functional Correctness
One may hope that testing of cryptographic code, e.g., via NIST's Cryptographic Algorithm Validation Program [41], or verified implementations of cryptographic protocols (such as the miTLS implementation of TLS [12]) may mitigate the problem.This, however, does not match the community's experience with the persistence of such weaknesses.As Adam Langley put it in connection with the Poodle attack [33]: "the Internet is vast and full of bugs."We are not going to discuss potential reasons for this, but instead ask ourselves whether it is inherent that cryptographic implementation errors remain unnoticeable.Put differently, what if we could make crypto bugs surface through inflicted, noticeable errors in a program's functionality?Such functional errors would in turn be easily detected already during basic interoperability testing of a cryptographic implementation, leading to an early mitigation of the underlying bug in the cryptographic code.
Our approach is inspired by a talk by Nadia Heninger [28] at the Workshop on Attacks in Cryptography 2 (WAC2), affiliated with Crypto 2019.In her talk she proposed to minimize the damage caused by inevitable human errors by "tying security to basic functionality."Our work is perfectly aligned with this idea.If the implementations enable attacks like the goto fail bug or the fixedcoordinate attack on Bluetooth, then the goal is to make this visible via the functional behavior of the cryptographic protocol.More concretely, an example -which we will explore in more detail-is a secure connection protocol in which the two parties fail to connect if verification steps are erroneous.
While the idea of linking functionality to security is applicable in general, our focus here lies on cryptographic verification steps in protocols, as discussed above.In particular, we assume that the unwary implementer of the verification step may have introduced accidental errors, such as skipping some steps.We do not protect against fully malicious behavior like fault injection attacks [14,16].Our approach focuses on detecting bugs by simple interoperability testing, where we presume that the faulty implementation tries to establish a connection with another, sound implementation.

Enter Confirmation Codes
Recall the issue with the goto fail bug: the verification routine simply jumped over some steps and always claimed verification was successful.Suppose now that, instead of having an error-prone decision bit returned by the verification step, we would have a more precise description of which of the essential steps of the full verification have actually been carried out.One observation is that such verification steps usually compute some intermediate values and base their decision on comparing these values.One option, which we also follow here, is thus to gather (some relevant subset of) these intermediate values in what we call a "confirmation code".Instead of returning merely the decision, the verification procedure will then also hand back this confirmation code.Implementation errors like skipping some verification steps as in the goto fail bug, misinterpretation of return values as in GnuTLS or parameters as in cURL, or reading invalid inputs as in the Bluetooth attack, are hence surfaced through (changes in) the confirmation code.
Note that with the above approach the computation of the confirmation code basically comes for free as part of the actual verification.
A side condition, when envisioning the usage of the same confirmation code by two parties, is that the creator (e.g., the signer of a message or the sampler of an elliptic curve point) should also be able to derive the same confirmation code when performing its calculation.Ideally, this should also come without significant overhead for the creator, e.g., without having to run verification itself.
The next step is to take advantage of the extra information gathered in the confirmation code.A naive attempt would be to have two communicating parties check whether they derived the same value.This however simply introduces another layer of verification, likewise prone to implementation errors.Instead, we will use the confirmation code implicitly in the overall protocol.This enables verifiability of the verification steps of the cryptographic protocol, on a cryptographic level.
Since the use of confirmation codes is specific to the type of protocol, in this work we focus on secure connection establishment through key exchange protocols and consider confirmation codes derived through usual verification steps in such settings.This includes signature and MAC verifications or membership tests for group elements.In a key exchange protocol, we can now accumulate the confirmation codes  1 , . . .,   produced by its components and include them in a single, additional key derivation step: we use the established key K in a key derivation function KDF, with the collection of confirmation codes as the label, K ′ ← KDF(K,  1 ∥ . . .∥  ).The resulting key K ′ is the final key of the augmented key exchange protocol.Note that, if the confirmation codes on either side differ (e.g., due to an implementation error), then the parties in the key exchange protocol will now derive different session keys as well.This in turn makes the subsequent connection fail, leading to a clearly noticeable functionality error.

A Cryptographic Task
What is at hand now is the cryptographic task to make precise what properties confirmation codes should have and what their effects on protocols employing them should be.We approach it as such, through formal definitions, constructions, and security proofs, always keeping a focus on practice by aiming for simple, low-overhead, and deployable solutions for existing cryptographic settings.Concretely, our contributions are as follows.
1.3.1 Defining confirmation codes and their goal.We begin, in Section 2, by generalizing classical verification algorithms like signatures, MACs, or parameter validation under a common syntax for verification schemes, involving algorithms for creating and verifying tokens (e.g., signatures, MACs, . . . ) for objects (e.g., messages, elliptic curve points, . . .).We then augment these classical schemes by adding the concept of confirmation codes to our generic syntax, allowing the creation and verification algorithms to output a confirmation code (in form of a generic vector ì ), in addition to the usual token resp.decision bit output.
The next step is to define what security property we expect from confirmation codes, in order to make sure that verification errors translate into changes in confirmation codes which can then be noticed in a higher-level protocol.At first glance, this might seem unachievable: since confirmation codes are computable by the verifier, in the case for example of signatures even from fully public knowledge, a malicious implementation may simply ignore the actual verification procedure and just make sure to compute the confirmation code correctly.We cannot protect against such malicious implementations, and the crucial point here is that we actually do not intend to.Our aim is rather to safeguard the benign implementer from accidentally introducing an error in the verification implementation (without intend to cover up their mistake by retrofitting confirmation codes).
We model such accidental but benign faults in verification steps cryptographically via a non-adaptive adversary.More precisely, we let the non-adaptive adversary decide beforehand which parts of the confirmation code to modify, reflecting the idea that these are the erroneous parts in the program which are put there independently of the actual cryptographic data. 1 Quantifying over all non-adaptive adversaries means to capture all such potential programming errors.This leads to a notion of unpredictability of confirmation codes, which we formalize in Section 3, meaning that the non-adaptively placed errors cannot let the faulty confirmation code accidentally coincide with the actual confirmation code.

Adding confirmation codes to practical verification schemes.
The next task is then to show that common cryptographic schemes support such unpredictable confirmation codes.In Section 4, we discuss and prove secure concrete instances for the RSA-PSS signature scheme, the HMAC message authentication code, and the validation of elliptic curve points.In each case, our constructions' goal is minimal overhead: we base the confirmation codes on intermediate values already computed in the original schemes, allowing to add these codes in practice with little to no additional computation and zero communication effort. 2.3.3Making connections fail noticeably.Finally, we apply the idea of verifiable verification through tying security to functionality to the setting of secure connection establishment via key exchange protocols.In Section 5, we show that via a generic transform adding a single extra key derivation step to the protocol, confirmation codes can be bound to the derived session key in such a way that implementation errors in verification (like Apple's goto fail bug) break basic functionality: a verification error leading to non-matching confirmation codes now translates to non-matching keys, and those in turn to connection establishment failing, which the implementer will immediately discover during a simple connection test.
We formalize this through measuring correct functionality of the key exchange under faulty verification implementations, again capturing accidental implementation errors as modifications by a non-adaptive adversary.We then prove that confirmation-code unpredictability of verification schemes ensures that a key exchange protocol with our transform applied will fail (via keys with high probability not matching) whenever there are faults in the implementation of those verification schemes.Finally, we argue that the so-augmented key exchange protocol is as secure as the original protocol.While seemingly intuitive, showing this formally turns out to be non-trivial due to our transform -purposefully-collecting the confirmation codes from the verification steps in the original key exchange protocol in a black-box manner, without access to the verification keys, requiring the reduction to rely on publicly computable codes.

Related Work
While we are not aware of prior attempts to cryptographically tie security to basic functionality, our work both in concepts and techniques connects to various other areas.
Proof-carrying code.Proof-carrying code, introduced by Necula and Lee [38,39], should allow to check if a program from an untrusted source satisfies certain safety properties.For this, the verifier provides a safety policy and the code producer creates an additional safety proof which the verifier can use to check efficiently that the program obeys the policy.One may view our approach with confirmation codes as an implementation of this idea, but where the programmer is usually simultaneously producer and verifier and where verification of the safety proof is done implicitly.Indeed, Necula [38] in his original paper argued that cryptography mechanisms rather implement trust relationships between parties and do not necessarily allow to detect coding errors.Our solution bridges to the possibility that cryptography can also be used to check that parts of the code are sound.
Cryptographic Algorithm Validation Program.NIST runs the Cryptographic Algorithm Validation Program (CAVP) [41] to support tests for recommended algorithms.This includes common block ciphers such as AES but also public-key schemes like DSA.Recently, NIST added hash functions to the suite of algorithms [37], due to vulnerabilities found in Apple's CoreCrypto library.The idea of the program is to specify tests -including also false inputs-and to have a Cryptographic & Security Testing (CST) lab check the validity.This blends in into other testing methods for cryptographic algorithms, and yet does not seem to be able to capture all potential bugs.
Verifiable computation.The notion of verifiable computation dates back to a work of Gennaro et al. [24] and aims at verifying the results of outsourced computations.The idea of checking such computations already appears in earlier works, especially in [5], and boils down to be able to check if a derived value  coincides with some expected value  () for input .The approach is to let the verifier transform the input (e.g., by encrypting it under a fully homomorphic encryption scheme as in [24]), then letting the computing party perform the computation, and allowing the verifier to check (interactively or non-interactively) that the result is correct.The most promising direction is to deploy efficient zeroknowledge proofs where the verifying party augments the input by paramters for such a proof system, and the computing party eventually prepares a proof of correctness of the result [26].
While our approach here is related to verifiable computations in the sense that one should be able to check that steps have been carried out, it is fundamentally different, though.In our setting we do not outsource the computation to another party but run the verification locally with potential errors in the code.We neither check for the correctness of result of the computation-in our case the decision bit-but instead augment the output by more information.This output, however, needs to be synchronized with the other party whose data we verify, e.g., both signer and verifier need to compute the same confirmation code.Finally, verifying verifications such as for signatures should be lightweight, such that transforming inputs via fully homomorphic encryption or using zero-knowledge proofs to verify appear to be prohibitively expensive.
Progressive verification.The notion of progressive verification [21,22] of cryptographic primitives relates the error probability in verification to the actual time spent on verification: the more verification steps are carried out, the more reliable is the result.Talen and Vergnaud [45] recently showed that progressive verification is possible with ECDSA, RSA, and the GPV lattice-based signature scheme.Boschini et al. [17] discuss solutions for further latticebased and multivariate signature schemes.Le et al. [34] considered the related concept of flexible signature schemes and showed than Lamport's one-time signature scheme is flexible.
While the goal of progressive verification, relating time investment to confidence, is different from the one of verifiable verification for detecting programming errors, in some cases the techniques coincide.To progressively verify hash chains, for example, Fischlin [22] uses intermediate outputs when iterating through the chain, resembling the approach we use here to put results of the verification into the confirmation code.However, other approaches in [17,21,34,45] rather use random ordering of sub-steps to achieve progressiveness.
Simultaneous verification.In the context of hybrid (post-quantum and classical) signature schemes, Bindel and Hale [15] informally discuss a concept called "simultaneous verification", which asks that, when combining two signature schemes, the joint verifier may not "quit" before both sub-verification processes completed.Confirmation codes could be seen as one approach to ensure that the execution of a verification algorithm completes correctly.Checksums.Our security goal for confirmation codes, unpredictability, aims to capture a non-malicious implementer introducing verification errors and, implicitly, relies on honestly created tokens to have certain entropy to make them unpredictable.This conceptually resembles non-cryptographic checksums like cyclic redundancy checks, which likewise aim to detect unintentional flaws (in data) and which should catch, e.g., random bit flips.
Attacks skipping verification.Related in their effect of bypassing proper verification are protocol-level attacks that make a protocol skip verification entirely, like the "Early ChangeCipherSuite" attack on OpenSSL [32].While those would also trigger non-matching confirmation codes in our setting, our goal is not to defend against malicious adversaries, but to make unintentional implementation errors that always skip some verification steps become noticeable.

DEFINING VERIFIABLE VERIFICATION
Our concept of verifiable verification applies to different types of verification schemes like signatures, MACs, or validity checks.We hence first introduce a common notation for verification schemes, then introduce verifiable verification on top of it.Before we do so, let us define some basic notation first.
Notation.We write a bit as  ∈ {0, 1}, a (bit) string as  ∈ {0, 1} * with | | indicating its (binary) length, and  ∈ {0, 1}  * for a string whose length is a multiple of .By  ∥ we denote the concatenation and by  ⊕  the bit-wise XOR of two strings , .For a vector , we write  [] for the -th entry of .
We write  ←  for assignments and  $ ← −  for sampling  uniformly at random from a finite set  .By  $ ← −  O () and  ←  O () we denote the output  of a randomized resp.deterministic algorithm  run on input  with oracle access to O, where the probability is over 's internal randomness.For a security experiment Expt, we write Expt = 1 for the experiment returning 1.

Classical Verification Schemes
We distinguish between three common cases of verification: signature verification (where the verifier uses a public key matching the signer's secret key), message authentication (where the verifier uses the same key as the signer), and validity verification such as checking validity of elliptic curve points (where no keys are involved).Generalizing the three, we thus use an abstract syntax consisting of: • A key generation algorithm outputting a triple (ck, vk, pk) of a secret creation key, a secret verification key, and a public key; the latter will be given to the adversary in security games.For signatures ck is the signing key, vk is empty, and pk is the public verification key, whereas for MACs we will set ck = vk to be the secret key and pk to be empty.For validity checks ck = vk = ⊥ are empty and pk may for example contain public parameters (like the description of an elliptic curve).• A creation algorithm which takes as input a creation key ck, a public key pk, and some input in, e.g., an input message in =  for signatures and MACs.The algorithm outputs a (cryptographic) token tok together with an object obj which should be verified, e.g., for signatures and MACs the object obj =  is the input message itself.• A verification algorithm taking a verification key vk, a public key pk, an object obj, and a token tok, returning a decision bit .We note that different, and equivalent, choices in syntax are possible; we opt for the distinction of secret and public keys as above, with public keys being inputs to both creation and verification algorithms, for clear indication of what are secret and what are public values in a scheme.Definition 2.1 (Verification scheme).A (classical) verification scheme V = (KGen, Create, Vrfy) with associated spaces for inputs, tokens, and objects I, T , resp.O consists of three efficient algorithms defined as follows.
• KGen() $ − → (ck, vk, pk).This probabilistic algorithm outputs a secret creation key ck, a secret verification key vk, as well as a public key pk.(Either key may be also set to ⊥.) • Create(ck, pk, in) $ − → (obj, tok).For a creation key ck, a public key pk, and an input in ∈ I, this (possibly) probabilistic algorithm outputs an object obj ∈ O and a token tok ∈ T .• Vrfy(vk, pk, obj, tok) → .On input a verification key vk, a public key pk, an object obj, and a token tok, this deterministic algorithm outputs a decision bit  ∈ {0, 1} (where  = 1 indicates validity of the token for the object).
Canonical representation of signatures and MACs.We can canonically capture signature and MAC schemes as (asymmetric, resp.symmetric) verification schemes, as shown in Figure 1.See Appendix A.1 for the standard definitions of signature and MAC schemes.

Verification Schemes with Confirmation
To introduce the concept of confirmation in verification procedures, we augment the outputs of the creation algorithm and the verification algorithm by vectors of confirmation codes.This leads to the following syntax.Definition 2.2 (Verification scheme with confirmation).A verification scheme with confirmation VC = (KGenC, CreateC, VrfyC) with associated spaces for inputs, tokens, objects, and confirmation codes I, T , O, resp.C consists of three efficient algorithms defined as follows.
Correctness.We say that a verification scheme with confirmation, VC, is correct if for any in ∈ I it holds that Pr Augmenting classical verification schemes with confirmation codes.Observe that any classical verification scheme can canonically be written as one with confirmation, by simply letting CreateC and VrfyC output empty confirmation code vectors ì  = ().In practice, we are interested in augmenting a classical verification scheme V to also output (non-empty) confirmation codes, in such a way that the other outputs remain unmodified, for compatibility reasons.We call a verification scheme with confirmation VC a confirmation-augmented version of V, formally defined as follows.
Example.Note that the above definition coincides with the common notions for signature and MAC schemes with regard to messages  = in = obj and tokens (the latter capturing signatures resp.MAC tags), augmented with confirmation codes.We have seen in Figure 1 how signature and MAC schemes can canonically be represented as verification schemes, and hence augmented with verification codes.Here, we briefly discuss how validity checks for randomly generated elliptic curve points fit in, albeit we revisit the approach in more detail later in Section 4.3.In the case of elliptic curves we assume that key generation creates the description of an elliptic curve, with equation  3 +  +  =  2 over a prime field F. (The reader may think of a concrete curve like the FIPS 186-4 curve P-256.)The creation algorithm is supposed to output a random curve point obj = (, ) ∈ F 2 and ignore the input in.The token itself tok is empty in this case.We neglect the confirmation code here, since we discuss this in more detail in light of the security requirements of such values later.The verification algorithm, on receiving an object (, ), checks that indeed  3 +  +  =  2 over F and outputs this result as its decision bit.
Unforgeability.The classical (existential and strong) unforgeability notions for signatures and MACs (given in Appendix A.1 for completeness) generalize to verification schemes without change beyond accounting for confirmation codes being output.These unforgeability notions are not suitable for validity checks and other public verification schemes without secret creation key (ck = ⊥), as the adversary can then simply forge arbitrary "tokens" (which the verifier accepts by correctness).We can nonetheless define the notion for verification schemes in general, as follows.
Definition 2.4 (Existential and strong unforgeability of verification schemes with confirmation).Let VC be a verification scheme with confirmation and let experiments Expt EUF-CMA VC,A and Expt SUF-CMA VC,A for an adversary A be defined as in Figure 2.
We define the advantage of an adversary A against the existential (resp.strong) unforgeability under chosen-message attacks

CONFIRMATION-CODE UNPREDICATABILITY
We next define a simple yet sufficient security notion for verification schemes with confirmation, which we call confirmation-code unpredictability.It should be able to thwart faulty implementations up to a certain severeness.To capture this we consider an adversary playing against our notion of unpredictablity, formalized in Figure 3, albeit one may rather think of this adversary as a benign implementer possibly introducing errors in the verification code.
In particular, we assume that such errors are introduced while implementing the protocol, before executions take place, such that we model this benign adversary in a non-adaptive way.
Recall that we are interested in using confirmation codes in the context of some overall protocol (e.g., key exchange), whose execution should fail if we have a mismatch in the confirmation codes (on the sender's side running CreateC and on the receiver's side running VrfyC).Hence, to capture the bad cases, we are interested in the chance of sender and receiver accidentally agreeing on the confirmation codes although there are programming errors in the verification step while the creation step of the sender is correctly implemented. 3This can happen via two cases: • Either the benign implementer introduces programming errors in the verification step (e.g., skipping instructions as in the goto fail bug [43] or misinterpreting parameters leading to verification not be correctly executed as in the GnuTLS [46] and cURL [25] bugs).This is described by having the adversary A non-adaptively output a vector of modifications ì  *  to the confirmation code, either of the type "⊲" to describe that this step of the verification procedure remains intact, or a new confirmation code entry  ∈ C, e.g., to denote that this verification step has not been executed and the confirmation code is set to some default value .For non-trivial programming errors at least one entry in ì  *  needs to be different from ⊲. Since these programming errors should ideally be detectable for any subsequent input, the adversary also chooses the potentially "bad" input in for the test run on the sender's side.• Or, the implementer introduces input errors in the verification step for obj, like reading only the -coordinate of an elliptic curve point and defaulting the -coordinate to 0 (akin to the Bluetooth attack [13]).Unlike in the first case, this error may now depend on the actual object obj or the other values created by the sender.To ensure that we gave a read error we require that the substituted object obj * is different from obj.This may be even combined with further programming errors, i.e., the adversary may again output ì  *  as in the first case, only that we allow for non-modifying changes (all entries set to ⊲) this time.
More formally, in the confirmation-code unpredictability (c-UP) experiment in Figure 3 • either some verification step modified the confirmation code (e.g., due to an error this particular step is skipped, setting the corresponding confirmation code to some default value): ì   ≠ (⊲, ⊲, . . ., ⊲), • or there is a "bad" object obj * used in verification causing the same confirmation code as on the creator's side which used a different object obj ≠ obj * .Here, the code may on top also contain further errors, once more described by a modification of confirmation codes.
It may appear that the second condition (input errors, possibly with program errors) implies the first one.Note, however, that Expt c-UP VC,A :  both properties are incomparable, since the first case requires some modification in the verification step for an unaltered object, whereas the second property requires some modification in the object.In proofs, it will be helpful to treat both cases separately, which is why in Figure 3 we display both the overall ("combined") unpredictability experiment Expt c-UP VC,A , as well as separate experiments for case (A) "programming errors", Expt c-UP() VC,A , and case (B) "input errors" (with optional programming errors), Expt c-UP() VC,A .Definition 3.1 (Confirmation-code unpredictability of verification schemes with confirmation).Let VC be a verification scheme with confirmation and let experiment Expt c-UP VC,A for an adversary A be defined as in Figure 3.We define the advantage of an adversary A against the confirmation-code unpredictability (c-UP) of VC as Adv c-UP VC,A := Pr Expt c-UP VC,A = 1 .
Generally speaking, confirmation-code unpredictability covers the class of any "hard-coding" in computing confirmation codes, be it due to skipped instructions and hence uninitialized codes returned, or input values wrongly read.We emphasize that protection against arbitrary programming errors is elusive, as this would include the "malicious" error of merely computing the confirmation code (and possibly even a proof of following the verification steps) while ignoring the verification decision.Exploring notions which cover broader classes of implementation errors is an interesting direction for future research.
To illustrate the definition let us argue that simply putting obj into ì  = (obj) to thwart predictability attacks in general does not work.Take a signature scheme as an example, where in = obj =  is the message to be protected via the signature tok.Note that this message is chosen by the adversary.In the first step, our successful attacker A against unpredictability chooses an arbitrary message in =  and also sets ì  *  = ().In the next step it chooses a different message  * ≠  and sets obj * ←  * .Then, running VrfyC on obj * yields the confirmation code ì  input = ( * ), but the ì  *  value overwrites the only confirmation code again with  in ì  * input .Hence, the adversary has successfully created a different object obj * for which VrfyC creates, due to a non-adaptive programming error, the same confirmation code as CreateC, letting A win the unpredictability game.
As another example, let us consider using the signature or MAC tag of a signature resp.MAC scheme as the confirmation code, ì  = (tok).This generically achieves unpredictability, assuming the scheme is (existentially) unforgeable: if the adversary can predict the token for a message (be it the creator's code ì  overwritten by ì  *  or the verifier's code ì  input ), then this prediction together with the corresponding message is indeed a valid forgery.Using the tok as confirmation code however is bad solution in practice: a verification implementation would naturally copy the confirmation code, counteracting the idea that the confirmation code should capture the verification steps taken. 4We hence do not consider this approach further, but instead next turn to better, practical constructions of confirmation codes based on actual intermediate computation values that cannot simply be copied.

PRACTICAL VERIFICATION WITH UNPREDICTABLE CONFIRMATION CODES
Recall the idea that, ideally, confirmation codes should be computable on the verifier's side as a by-product of the verification steps.In this section we give three examples where one can indeed achieve this, one each for asymmetric, symmetric, and public verification schemes.The asymmetric example is the RSA-PSS signature RSA-PSS.Sign(sk, ), RSA-PSS + .CreateC(sk, pk, ):   scheme, for the symmetric example we consider the HMAC message authentication algorithm, and in the public verification setting we discuss curve-point validation in elliptic curves, both that the point is on the curve and also that it belongs to the right subgroup.

RSA-PSS Signatures
As an example of an asymmetric verification scheme, we consider the RSA-PSS signature scheme, proposed by Bellare and Rogaway [10], standardized by the IETF in PKCS #1 v2.1 [29] and NIST [42], and mandated in major protocols like TLS 1.3 [44].Figure 4 shows the RSA-PSS signature scheme, both the classical version (mostly following RFC 3447 [29]), as well as the confirmationaugmented version.For the latter, we leverage that in RSA-PSS, the verifier essentially recomputes the computational steps performed upon signing, re-deriving in particular the signer's randomness.This is allows us to use a single confirmation code, in which the rederived randomness  and signed message  are bundled together in the hash value  (⟨padding⟩∥∥ ).
Confirmation code rationale.When deploying verification schemes with confirmation, the main property we are interested in achieving is confirmation-code unpredictability (c-UP).For RSA-PSS, the confirmation code leverages the randomness  drawn when signing (which is re-derived when verifying) as an a-priori unpredictable value.One might wonder whether using  alone as confirmation code, ì  = ( ), already yields unpredictability.This would indeed be sufficient to satisfy the "programming errors" condition of c-UP (cf. Figure 3).
The "input errors" condition of c-UP however demands that changes to the object obj, i.e., the signed message, lead to unpredictable changes in the confirmation code, too; this is not the case when ì  = ( ).Instead, we employ the hash value  =  (⟨padding⟩∥ ∥ ) computed upon signing.As we will show next, the  value entering the hash ensures unpredictability while the inclusion of  ensures that modifications of the message lead to confirmation code changes.With the confirmation code involving both  and , we can indeed fully establish confirmation code unpredictability. 5t remains to show that the chosen confirmation code does not negatively affect unforgeability of the augmented scheme RSA-PSS + .Concretely, even when outputting confirmation codes along with the signatures in response to signing oracle queries in the unforgeability games (cf.Definition 2.4), RSA-PSS + should remain unforgeable.This is indeed easy to see: Since by correctness VrfyC computes the same confirmation code as CreateC given only public information (vk = pk), the message  and the signing oracle's token output tok, an unforgeability adversary can simply compute the confirmation codes corresponding to the signatures generated by the signing oracle itself.Theorem 4.1.The RSA-PSS + verification scheme with confirmation augmenting the RSA-PSS signature scheme, given in Figure 4, is confirmation-value unpredictable when modeling  as random oracle.Concretely, for any (even possibly unbounded) adversary A we have Proof.We separately consider the two parts (A) "programming errors" and (B) "input errors" of c-UP.
To win in part (A) "programming errors" of c-UP, adversary A must correctly predict, overwriting via ì  *  , the confirmation code  (⟨padding⟩∥∥ ).We leverage that the randomness  sampled within RSA-PSS + .CreateC generating the confirmation code ì  to be predicted, is a uniformly random string of length  bits.Modeling  as random oracle, A must hence either predict  ∈ {0, 1}  (in a query to  ), or otherwise the hash value itself (which in that case is a random ℓ-bit output of  ).Hence, we can bound A's advantage in this case as Adv c-UP() RSA-PSS + ,A ≤ 2 − min(,ℓ ) .In part (B) "input errors" of c-UP, A may arbitrarily overwrite the inputs to VrfyC computing ì  input in the c-UP experiment, as long as this overwriting modifies the message, i.e., obj * obj.Further, A can but need not overwrite the confirmation code ì  input .We analyze A's advantage based on whether it overwrites the confirmation code (i.e., whether ì  *  = (⊲) or not).( 1  A may opt to not overwrite the signature via  * in , in which case VrfyC will use the same value  when computing ì  input .Nevertheless,  serves as a kind of "salt" in the computation: A either needs to predict the value of  ∈ {0, 1}  used in CreateC (from which it may pre-compute a collision under  for distinct messages), or guess the ℓ-bit output of  directly (for pre-computation).This leaves A with chance of Adv c-UP() RSA-PSS + ,A ≤ 2 − min(,ℓ ) for part (B).□

HMAC
Turning towards symmetric verification scheme, we next show how the message authentication code algorithm HMAC [8], standardized by IETF [31] and NIST [40], and universally used as a MAC, PRF, and for key derivation, can be augmented with a confirmation code.Recall that HMAC, in its most simple form for some key  (of full block length of the underlying compression function) and message , is defined as where H is a Merkle-Damgård hash function [19,36] (e.g., SHA-256) and opad, ipad are two distinct (full-block) constants.
If one wanted to opt for a minimalist approach while sending HMAC values, one could use the inner hash value  = H( ⊕ ipad∥) as confirmation code.We show next that this confirmationaugmented version HMAC + of HMAC, given in Figure 5, achieves confirmation-code unpredictability based on assumptions used already in establishing PRF security of the regular HMAC function [6,7]: the dual-PRF security of the underlying compression function h : {0, 1}  × {0, 1}  → {0, 1}  , asking that both h and ℎ(, ) := h(, ), i.e., when keyed via the second input, are secure PRFs (see Appendix A.2 for the definition of PRF security, PRF-sec).
Theorem 4.2.The verification scheme with confirmation HMAC + augmenting the HMAC MAC scheme, given in Figure 5, is confirmationvalue unpredictable.
Concretely, we construct reductions where ℓ 1 , ℓ 2 denotes the block-length of the padded message in output resp.message object obj * modified by A.
For space reasons, we defer the proof to the full version of this paper [23].There, we also discuss that the augmented HMAC version with confirmation codes remains a secure classical MAC, even if one outputs the confirmation value.
Implicit verification of MACs.As an interesting side note, we remark that for a PRF-based MAC scheme like HMAC, the MAC value itself can act as a good confirmation code as long as the MAC is actually not sent in the higher-level protocol, but only implicitly checked, for example by letting it enter a key derivation step in a key exchange protocol.While some key exchange protocols do not sent MAC values explicitly (e.g., the SIGMA [30] protocol variant with MACs under the signature), we are not aware of one enforcing computation of the implicit MAC by binding it to key derivation.We speculate that this is mainly since MACs are usually explicitly added for key confirmation, and an implicit re-computation lacks the explicit verification decision (bit).We leave exploring implicit verification of MACs and the definition of confirmation codes in this context as an interesting avenue for future work.

Validity Checks for Elliptic Curve Points
For the public verification setting, let us consider a scheme for checking if a pair (, ) is a point on the elliptic curve  3 + + =  2 over a field F. As a motivational example consider the fixed-coordinate invalid-curve attack of Biham and Neumann against the Bluetooth protocol [13].The attack works as follows: In the attacked version of the Bluetooth protocol both parties, Alice and Bob, exchange the -and -coordinates of two public Diffie-Hellman shares, (  ,   ) and (  ,   ).The attack sets both -coordinates to 0 for the Diffie-Hellman values in transition, such that the parties use the point (  , 0) resp.(  , 0) to complete the Diffie-Hellman computation.
Although not relevant for us here, let us remark that Biham and Neumann [13] show that these modified points have low order on another curve, such that, with probability 1/4, the parties end up with a trivial Diffie-Hellman key consisting of the neutral element.
Note that the fixed coordinate invalid curve attack above is an active network attack (called "semi-passive" in [13]).But we can envision it to be a programming mistake which erroneously reads the input -coordinate as 0 or some other value, and where no validity check is carried out.The straightforward way to mitigate the attack is to check that the received point indeed lies on the curve.We can model such a verification check in our notion for confirmation codes as shown in Figure 6.The idea is, given an incoming pair (  ,   ) on the verifier's side, to compute the value  3   +   +  and check that it matches the value  2  ; alas, a false implementation may skip this check.Hence, we let the confirmation code computed by the verifier include the value  3  +   +  as well as  2   .
The creator also computes the confirmation code vector, simply placing the square of the -coordinate in both components, ì  ← ( 2  ,  2  ) over F. Note also that we are interested in checking random curve points, as will be used in genuine test runs in, say, an implementation of the Bluetooth key exchange protocol.Formally, we thus set the input space I = {⊥} to be empty, and since the keys are all public, tokens are irrelevant and we also set T = {⊥}.
A caveat lies in the actual encoding of elliptic curve points.We assume that the object of the curve point (  ,   ) uses an encoding,  , where  is the order of the elliptic curve.
For space reasons we only give a proof sketch here and defer the complete proof to the full version [23].
Proof sketch.For case (A) "programming errors", A chooses the modification ì  *  before the random curve point  is selected.If it decides to overwrite the first entry  * with some predefined value, this may either be  * = ∞ (which the random curve point hits when  = 0, hence with probability 1/), or  * ∈ F, for which there are at most 6 valid curve points with matching value  * =  2  , hence hit by  with probability 6/ (two possible roots of  * times at most three roots of the cubic equation).If it instead leaves the first value unchanged but sets the second component  * , similarly  * = ∞ is hit with probability 1/ and a valid square  * is hit by at most 6 curve points, hence probability 6/.
For case (B) "input errors", as above any predetermined change to ì  input is hit with probability at most 6/.For any non-trivial modification of obj, we can conclude once more that a match for the confirmation code of the randomly chosen curve point obj can only occur with probability at most 6/.Only this time we have to add the two probabilities.□ In the full version [23] we additionally give a construction of a verification scheme with confirmation for subgroup membership tests for elliptic curves, leveraging an internal iteration step of the validation process as unpredictable confirmation code.

KEY EXCHANGE WITH VERIFIABLE VERIFICATION
We now show how confirmation codes can be checked in practice with very little overhead, using key exchange protocols as example.Key exchange not only is one of the most widely deployed types of cryptographic protocols, underlying secure communiation protocols like TLS, SSH, QUIC, Signal, and others, it has in the past also been at the heart of severe verification bugs in the past, including Apple's goto fail bug [43] and the erroneous certificate validation in GnuTLS [46] or cURL [25].
Here we show how confirmation codes can be easily integrated into the key derivation step of key exchange protocols.This ensures that programming mistakes that lead to verification steps to be skipped (and hence confirmation codes not properly be computed) immediately lead to functional incorrectness via diverging keys being derived.Such diverging keys will in turn be immediately noticed upon interoperability testing: the erroneous protocol implementation will simply be unable to establish the correct session key, making the programmer aware of the verification bug before deployment.

Basic Key Exchange Syntax
For our setting, we are most concerned with correctness properties of key exchange protocols.It hence suffices to consider the following, simple syntax for key exchange protocols for the most part, and defer more subtle aspects related to security properties to later.

Definition 5.1 (Key exchange protocol).
A key exchange protocol KE = (KGen, Execute) consists of two efficient algorithms defined as follows.KGen() $ − → (sk, pk).This probabilistic algorithm outputs a secret key sk and a public key vk.Execute(sk  , pk  , sk  , pk  ) $ − → (trans, K  , K  ) On input the secret/public keys of two parties  and , this probabilistic algorithm honestly executes a run of the key exchange protocol between the two parties and outputs the resulting communication transcript trans as well as the session keys established by each party, K  resp.K  .
then return 0 // at least one substitution must be made ) ).For technical reasons, we restrict our focus to what we call canonical key exchange protocols where (1) the protocol aborts whenever a verification step fails during the protocol execution, and (2) the users' public keys of the key exchange protocol, generated by KGen, only contain public keys of the verification sub-procedures.We consider both to be reasonable restrictions, adhered by most practical protocols.

Correctness and Faulty Verification
We next consider correctness for key exchange protocols.Classically, correctness is defined as an undisturbed run of a key exchange protocol between two parties leads to the same session key at each party with probability 1.We call this an always correct key exchange protocol.
For detecting accidental mistakes in implementations, we are further interested in what we call noticeable correctness: whether an undisturbed key exchange run leads to matching session keys with noticeable probability.We will see that, for a faulty implementation, verifiable verification should preclude noticeable correctness, to make sure implementation mistakes by one side of the communication lead to correctness failures (i.e., a non-functional protocol run) with high probability in an honest execution of a key exchange.Definition 5.2 (Key exchange correctness).Let KE be a key exchange protocol and let experiment Expt CORR KE be defined as in Figure 7.We define the correctness probability of KE as Corr KE := Pr Expt CORR KE = 1 .We say that KE is always correct iff Corr KE = 1.
To formally capture faulty verification steps, we now strengthen the classical correctness notion for key exchange by introducing an adversary A which is allowed to non-adaptively introduce errors in the execution of certain verification steps at one side of  7. Correctness under faulty verification then measures whether a so-modified run of KE still yields matching keys with noticeable probability-which in practice would mean such mistakes might remain undetected.

Definition 5.3 (Key exchange correctness under faulty verification).
Let KE be a key exchange protocol and let S be a vector of verification schemes with confirmation.Define experiment Expt CORR f KE,S,A for an adversary A as in Figure 7.
We define the advantage of an adversary A in achieving correctness under faulty verification for KE as Adv CORR f KE,S,A := Pr Expt CORR f KE,S,A = 1 .We say that KE is noticeably correct under faulty verification in S iff there exists an adversary A such that Adv CORR f KE,S,A is non-negligible. 6

Detecting Verification Faults with a Generic Key Exchange Transform
We are now ready to introduce our generic transform of a key exchange protocol using classical verification schemes, into one that detects faulty verification steps using confirmation-augmented verification schemes.Our transform will be entirely oblivious to the type of verification schemes, which means it can be used to incorporate and check confirmation codes not only from classical signature-or MAC-based online authentication, but also from certificate checks at lower levels of the protocol execution (which were the sources of Apple's goto fail and other vulnerabilities [25,43,46]), or elliptic curve parameter validation.
Formally, our transform KE + F of a key exchange protocol KE using an additional function F is given in Figure 8.Its approach is simple and modular: the original key exchange protocol KE is executed, replacing instances of some classical verification schemes S with confirmation-augmented versions S + .By definition of being augmented versions (cf.Definition 2.3), this results in identical protocol executions except that, additionally, confirmation codes ì   , ì   are computed by both parties involved in the protocol.Upon successful completion of the original key exchange, each party now takes their derived session key  and their collected confirmation codes ì  and computes the final session key as F(, ì ).In our analysis, we will see that a simple collision-resistant PRF (e.g., HMAC [8,31]) suffices for F; see Appendices A.2 and A.3 for the standard definitions of PRF security (PRF-sec) and collision resistance (CR).
We emphasize that our transform has several desirable properties, namely, it is • simple: beyond introducing confirmation-augmented verification schemes, it only adds a single function call F; • non-intrusive: it does not change the operations of the original key exchange protocol; and • transparent: it does neither modify any of the messages exchanged in the key exchange protocol nor introduce an additional message.
This makes our transform amenable to existing, deployed key exchange protocols, allowing to leverage prior analysis.

Noticeable
Incorrectness.We now formalize and prove that our transform achieves its main goal: making certain implementation faults in verification steps visible via noticeable correctness failures.
Theorem 5.4.Let KE be a canonical, always-correct key exchange protocol and F a collision-resistant function.Let S, S + be two equalsize vectors of verification schemes such that S + [], for 1 ≤  ≤ |S|, is a confirmation-augmented version of S [] (cf.Definition 2.3).Let all schemes in S + provide confirmation-value unpredictability.
Then the key exchange protocol KE + F resulting from the generic transform in Figure 8 applied to KE is not noticeably correct under faulty verification.Concretely, we construct reductions B 1 against the collision resistance (CR) of F and B 2, against the confirmation-code unpredictability (c-UP) of S + [] (for 1 ≤  ≤ |S|) such that Proof.Recall that the goal of A in the CORR f game is to make the executed key exchange sessions agree on the session keys (K  = K  ≠ ⊥) despite introducing some modification to the confirmation code outputs ( ì   ∉ ((⊲) * ) * ) or the verification step inputs ( ì  in ∉ (⊲) * ) at user  .
Since KE is canonical, we can disregard any input modifications that make a verification step fail (i.e., output  = 0), as then K  = ⊥ and also K +  = ⊥ and A loses.Combining this with each S + [] being a confirmation-augmented version of S [], we have that verification outputs   do not change when replacing algorithms S [].Vrfy with S + [].VrfyC, when K  ≠ ⊥.As a result, we have that the outputs (trans, K  , K  ) of KE.Execute[S → S + ] equal those of KE.Execute (with the non-augmented schemes from S, for the same choice of random coins).Since KE is always correct, this means that in the execution of the transformed key exchange KE + F , we are guaranteed that K  = K  in Line 1 of the transform (Figure 8), whenever K  ≠ ⊥.
Next, we rule out collisions under F in Line 3 of KE + F .Execute, i.e., we let Expt CORR f KE + F ,S + ,A abort whenever  7 The concrete flavor of key exchange security (e.g., whether to capture forward security, explicit authentication, extended version of key compromise, etc.) is highly dependent on the respective setting, and we hence refrain from narrowing down a specific formal security model.Instead, we provide a general argument for security within the fundamental game-based definition of key exchange security by Bellare and Rogaway [9] which forms the base of all modern key exchange security notions.
In the Bellare-Rogaway key exchange security model, the adversary is given the power to initiate many key exchange sessions among a large set of users, and arbitrarily interfere with the exchanged messages through tampering, dropping, or rerouting.It is further allowed to corrupt the long-term secret keys of users as well as to reveal the session keys established in sessions of its choice.In brief, key indistinguishability (IND security) then demands that such adversary is unable to distinguish a real session key from a uniformly random key in a challenge session (targeted via some O Test oracle query), conditioned that this session is not trivially compromised ("fresh") through reveal or corruption queries, and denoting its advantage against a protocol KE by Adv IND KE,A .It is within this basic security model that we provide our following security result.Interestingly, for technical reasons related to computing confirmation codes in our reduction, we are only able to show security is maintained generically when confirmation codes can be publicly computed.This covers a large class of practical protocols, especially for asymmetric and public verification schemes, including the signature and/or parameter checks in signed Diffie-Hellman and SIGMA [30], checks for elliptic curve points in Bluetooth protocols [18], and TLS 1.3 [44] when treating handshake encryption modularly [20].Key exchange protocols with confirmation codes that cannot be publicly computed would require an individual treatment; we leave establishing a general result on handling non-public confirmation codes as an open question.Theorem 5.5.Let KE be a key exchange protocol satisfying Bellare-Rogaway key indistinguishability (IND) and F be a PRF.Let S, S + be two equal-size vectors of asymmetric or public verification schemes such that S + [], for 1 ≤  ≤ |S|, is a confirmation-augmented version of S [] (cf.Definition 2.3).Let KE + F be the key exchange protocol resulting from the transform in Figure 8 applied to KE. Assume the confirmation codes derived in each session can be publicly computed from the session's transcript and public keys.
Then KE + F also satisfies IND security.Concretely, we construct reductions B 1 against the key indistinguishability (IND) of KE and B 2 against the PRF security (PRF-sec) of F such that Due to space restrictions, we defer the proof to the full version [23]. 7Note that detecting faulty verification is captured by triggering noticeable correctness errors, as shown in Theorem 5.4.Here, we ask that the confirmation codes and key derivation step via function F introduced by our transform do not infringe with security.

CONCLUSION
Our work takes a first step towards formally tying security to basic functionality in cryptographic protocols, in which, due to the brittleness of cryptographic implementations, critical errors are easily introduced and often remain unnoticed for long, like Apple's goto fail bug.Focusing on verification schemes like signatures, MACs, or parameter validation in elliptic curve groups, we introduced the concept of verifiable verification through confirmation codes that are output by verification algorithms, beyond the verification decision itself.When these confirmation codes achieve a non-adaptive notion of unpredictability, capturing a benign implementer accidentally skipping some verification steps, then they can be used to help implementers detect these implementation errors through basic functionality breaking on the protocol level.We exemplify this in the context of secure connections, providing and formally proving a simple transform for key exchange protocols.As concrete examples for verification schemes, we augment the RSA-PSS signature scheme, HMAC message authentication code, and elliptic curve point and subgroup membership validation with practical confirmation codes that essentially come "for free" as result of the actual verification steps.
Interesting next steps include exploring practical confirmation codes in other cryptographic settings performing verification.Natural candidates include, e.g., authenticated encryption (using integrity check codes to mask decrypted messages, scrambling the latter if verification is flawed), verifiable secret sharing (binding codes into reconstruction), and FO-based KEMs (confirming reencryption steps are executed).For MAC schemes, implicitly verifying a MAC tag through only recomputing but not sending it appears to be a compelling approach for a confirmation code that does not come with an explicit verification decision (bit).On the protocol level, confirmation-code augmented primitives may be deployed, e.g., in code signing (requiring confirmation codes as input during installation), secure messaging (rejecting messages if codes do not match), entity authentication (using codes as challenge within challenge-response protocols), or even blockchain protocols (including codes in blocks to ensure miners verified prior blocks).Ultimately, the idea of tying security to basic functionality is not restricted to verification.Introducing it to other cryptographic settings could further help making implementing cryptography less fragile.A STANDARD DEFINITIONS A.1 Signature and MAC Schemes Definition A.1 (Signature scheme).A signature scheme S = (KGen, Sign, Vrfy) with associated spaces for messages and signatures M resp.S consists of three efficient algorithms defined as follows.
• Sign(sk, ) $ − → .On input a signing key sk and a message  ∈ M, this (possibly) probabilistic algorithm outputs a signature  ∈ S.
Correctness.We say that a signature scheme S is correct, if for any  ∈ M it holds that Definition A.2 (MAC scheme).A message authentication code (MAC) scheme M = (KGen, Tag, Vrfy) with associated spaces for messages and tags M resp.T consists of three efficient algorithms defined as follows.
• Tag(, ) $ − → .On input a MAC key  and a message  ∈ M, this (possibly) probabilistic algorithm outputs a tag  ∈ T .
Correctness.We say that a MAC scheme M is correct, if for any  ∈ M it holds that for an adversary A be defined as in Figure 9, for signatures resp.MAC schemes.
We define the advantage of an adversary A against the existential (resp.strong) unforgeability under chosen-message attacks (EUF-CMA, resp.SUF-CMA) of  as

Figure 3 :
Figure 3: Security experiment for confirmation-code unpredictability (c-UP) for verification schemes with confirmation.Combined experiment on left, split-up experiment on right; see text for the definition of Sub.Note that the first case (A) covers errors in the verification program, and the second case (B) covers input errors and, optionally, further programming errors.

Figure 5 :
Figure 5: The tag creation and verification algorithms of HMAC + , the confirmation-augmented version of HMAC.Key generation as for HMAC samples a -bit key ck $ ← − {0, 1}  .

Figure 7 :
Figure 7: Correctness experiment, regular (left) and under faulty verification (right), for a key exchange protocol KE.

Definition A. 4 (
Pseudorandom function (PRF)).Let F :  ×  →  be a function.We define the advantage of an adversary A against the PRF security (PRF-sec) of F asAdv PRF-sec F,A := Pr A F(,•) = 1 − Pr A R(•) = 1 ,where  $ ← −  and R is randomly sampled from all functions mapping  to  .
, we define the modified confirmation codes, representing the flawed execution, as ì  As mentioned above, the adversary now succeeds if it correctly predicts the confirmation code ì  * = ì  of the verification algorithm, in a non-trivial way.Here, non-trivial means that * ← Sub(ì , ì Sub((vk, pk, obj, tok),  * in ) 5 ( input , ì  input ) ← VrfyC(vk * , pk * , obj * , tok * ) pk, in) 4 (vk * , pk * , obj * , tok * ) ← 1}    mod  8  ←  ( ) 9  ←  ⊕  10  ′ ←  (⟨padding⟩ ∥ ∥ ) 11 If  ′ =  and  [ : . . .] =  and  = 0 2  ←  (⟨padding⟩ ∥ ∥ ) 3  ←  ( ) 4  ∥ ←  ⊕ ( ∥0  ) 5  ← (0∥ ∥ ∥ )  mod  6 return  (, , ( ) )RSA-PSS.Vrfy(pk, ,  ), RSA-PSS + .VrfyC(vk, pk, ,  ):7  ∥ ∥ ∥ ← input output by CreateC resp.VrfyC must collide for A to win.Note that the two algorithms use different message inputs  and  * , which get output as objects obj * obj, where obj =  = in and obj * is the result of applying  * in to obj.Hence the  (⟨padding⟩∥∥ ) values in ì  and ì  input must collide for distinct inputs for .Observe that although  ∈ {0, 1}  is drawn at random in CreateC, 5  ′ ← H(vk ⊕ ipad∥obj) 6 tok ′ ← H(vk ⊕ opad∥ ′ ) 7 if tok = tok ′ sk  , pk  , sk  , pk  ) Every verification step (  , ì   ) ← S  .VrfyC(vk, pk, obj, tok) executed by user  within Execute, where  is a running counter over S, is replaced by (  , Sub( ì , ì  [ ] ) ) ← S [ ].VrfyC(Sub( (vk, pk, obj, tok), ì  in [ ] KE +F .Execute(sk  , pk  , sk  , pk  ): 1 (trans, K  , K  ; ì   , ì   ) $ ← − KE.Execute S→S + (sk  , pk  , sk  , pk  ) // KE.Execute S→S + denotes: Run KE.Execute with scheme S [ ] replaced by scheme S + [ ], for 1 ≤  ≤ | S |.   collect the sequences of confirmation codes ì   output by S + [ ].CreateC resp.S + [ ].VrfyC calls of user  resp., in order of the indices . Figure 8: Generic transform KE + F of a key exchange protocol KE replacing the usage of verification schemes in vector S with corresponding confirmation-augmented versions in vector S + .Key generation remains unmodified, i.e., KE + F .KGen = KE.KGen.the protocol run.Concretely, this means that A may hard-code verification mistakes into the verification steps of a set of verification schemes S, run within a key exchange protocol KE.As for our confirmation-code unpredictability notion (cf.Section 3), we consider both programming and input errors, modeled by modification vectors ì   resp.ì  in in Figure Note that by the above, K  = K  .)The probability of such abort can directly be bounded by the advantage Adv CR F,B 1 of a reduction B 1 to the collision resistance of F, which simulates the CORR f game for A and outputs (K  , ì   ), (K  , ì   ) as the collision under F if it occurs.Finally, we rule out that ì   = ì   in Line 1 of KE + F .Execute, within game Expt CORR f KE + F ,S + ,A , relying on the confirmation-value unpredictability of the schemes in S + .Recall that by the definition of the CORR f game, A must overwrite at least one confirmationvalue output (via ì   ) or input (via ì  in ) of some verification step of a scheme in S + .Let   denote the event that the creation and verification steps corresponding to S + [] yields equal confirmation codes for users  and  in the execution of KE + F .Execute, but the confirmation-value output or input of the verification step is overwritten.Note that for the overall confirmation code vectors to be equal (ì   = ì   ), one of these events   must occur.We bound the probability of each event   individually by the confirmation-value unpredictability of S + [], concretely by the advantage Adv c-UP S + [ ],B 2, of a reduction B 2, .To this end, B 2, simulates the CORR f game for A as follows.It obtains the public key pk for S + [] in the c-UP game and uses this to compute pk  and pk  as per the definition of KE, sampling all other keys itself.(Recall that since KE is canonical, pk  and pk  only depend on the public key for S [].Further, key generation for the augmented scheme S + [] is the same as for S [].)It then invokes A on pk  , pk  to obtain ( , ì   , ì  in ).If no overwriting values in ì   , ì  in corresponding to scheme S + [] are set, i.e., event   is not triggered, B 2, aborts.Otherwise, B 2, extracts the overwriting values from ì   , ì  in for S + [] into values ì  *  ,  * in , and sets in to the input value for S + [].CreateC in the key exchange execution.We now observe that the event   corresponds to the confirmation code ì  output by CreateC equaling that output by the VrfyC step executed by user  , despite ì   , ì  in overwriting verification input or output.This translates to, in the c-UP game, ì Maintaining Security.It remains to argue that our generic transform maintains regular key exchange security, in the form of key indistinguishability under active attackers, if verification is implemented correctly.