Repository navigation
feat(crypto): Fiat–Shamir signatures in the random-oracle model, exact security (#581 3b-i) #702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
ca0bccb
feat(probability): structural call budgets, presampling and the diffe…
SamuelSchlesinger 7e45c3e
feat(crypto): signatures and EUF-CMA in the random-oracle model
SamuelSchlesinger df5dd4d
feat(crypto): Fiat-Shamir signatures and their exact security
SamuelSchlesinger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
933 changes: 933 additions & 0 deletions
933
Complexity/Crypto/Protocols/SigmaProtocol/FiatShamir.lean
Large diffs are not rendered by default.
Oops, something went wrong.
123 changes: 123 additions & 0 deletions
123
Complexity/Crypto/Protocols/Signature/RandomOracle.lean
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| /- | ||
| Copyright (c) 2026 Samuel Schlesinger. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Samuel Schlesinger | ||
| -/ | ||
|
|
||
| module | ||
| -- upstream: candidate | ||
|
|
||
| public import Complexity.Foundations.Control.Monad.Memoize | ||
| public import Complexity.Languages.Probabilistic.Basic | ||
| public import Cslib.Probability.PMF | ||
| import Complexity.Probability.PMF | ||
|
|
||
| /-! | ||
| # Signatures in the random-oracle model | ||
|
|
||
| A signature scheme in the random-oracle model ([BonehShoup2023], Section 13.2.1) signs and | ||
| verifies with oracle access to a function `H : Query → Digest`, which the security experiment | ||
| draws uniformly at random. Signing draws its coins and then runs an `OracleComp` program against | ||
| `H`; verification is a deterministic `OracleComp` program. The oracle is sampled lazily: each new | ||
| point gets a uniform answer, remembered in an association list (`oracle`), so the query and digest | ||
| types need not be finite beyond the digests. | ||
|
|
||
| The existential-unforgeability experiment (`eufCmaGame`, [BonehShoup2023], Attack Game 13.1 in | ||
| its random-oracle version) gives a forger the public key and oracle access to the signer and to | ||
| `H`; the forger wins with a valid signature on a message it never asked to have signed. A | ||
| `Forger` has explicit coins, drawn first, and is otherwise a deterministic `OracleComp` program; | ||
| this is the form in which a forger can be rerun on the same coins, as forking needs. | ||
|
|
||
| These are exact probability laws for one scheme and one forger, with no efficiency claim. The | ||
| oracle interface is the library's `OracleComp`; it is meant to be re-expressed in the shared | ||
| interactive-protocol core of #643 once that core exists. | ||
|
|
||
| ## Main definitions | ||
|
|
||
| * `Cslib.Crypto.Protocols.ROMSignature.Scheme`: key generation, signing and verification. | ||
| * `Cslib.Crypto.Protocols.ROMSignature.Forger`: a forger with explicit coins. | ||
| * `Cslib.Crypto.Protocols.ROMSignature.oracle`: the lazily sampled uniform random oracle. | ||
| * `Cslib.Crypto.Protocols.ROMSignature.eufCmaGame`: the random-oracle EUF-CMA experiment. | ||
| * `Cslib.Crypto.Protocols.ROMSignature.Scheme.Correct`: honest signatures verify. | ||
|
|
||
| ## References | ||
|
|
||
| * [D. Boneh, V. Shoup, *A Graduate Course in Applied Cryptography*, | ||
| Version 0.6][BonehShoup2023], Sections 13.1 and 13.2.1. | ||
| -/ | ||
|
|
||
| @[expose] public section | ||
|
|
||
| namespace Cslib.Crypto.Protocols.ROMSignature | ||
|
|
||
| open Probability OracleComp | ||
|
|
||
| /-- The calls of a forger: a signing call names a message and returns a signature, and a hash call | ||
| names a point and returns its digest. -/ | ||
| abbrev ForgerSpec (M Query Sig Digest : Type) : M ⊕ Query → Type | ||
| | .inl _ => Sig | ||
| | .inr _ => Digest | ||
|
|
||
| /-- A signature scheme in the random-oracle model, with public keys `PK`, secret keys `SK`, | ||
| messages `M`, signatures `Sig`, and oracle `H : Query → Digest`. Signing first draws coins. -/ | ||
| structure Scheme (PK SK M Sig Query Digest : Type) where | ||
| /-- Draw a public key and a secret key. -/ | ||
| keyGen : PMF (PK × SK) | ||
| /-- The signer's coins. -/ | ||
| SignCoins : Type | ||
| /-- Draw the signer's coins for a message. -/ | ||
| signCoins : SK → M → PMF SignCoins | ||
| /-- Sign, querying the oracle. -/ | ||
| sign : SK → M → SignCoins → OracleComp (fun _ : Query => Digest) Sig | ||
| /-- Verify, querying the oracle. -/ | ||
| verify : PK → M → Sig → OracleComp (fun _ : Query => Digest) Bool | ||
|
|
||
| /-- A forger with explicit coins: it draws its coins, then, given the public key, calls the signer | ||
| and the oracle and outputs a message and a signature. -/ | ||
| structure Forger (PK M Sig Query Digest : Type) where | ||
| /-- The forger's coins. -/ | ||
| Coins : Type | ||
| /-- Draw the forger's coins. -/ | ||
| coins : PMF Coins | ||
| /-- Forge, calling the signer and the oracle. -/ | ||
| forge : PK → Coins → OracleComp (ForgerSpec M Query Sig Digest) (M × Sig) | ||
|
|
||
| variable {PK SK M Sig Query Digest : Type} [DecidableEq Query] [Fintype Digest] [Nonempty Digest] | ||
|
|
||
| variable (Digest) in | ||
| /-- The random oracle: a uniform digest for each new point, remembered thereafter. -/ | ||
| noncomputable def oracle (q : Query) : StateT (List (Query × Digest)) PMF Digest := | ||
| memoize (fun _ => PMF.uniformOfFintype Digest) q | ||
|
|
||
| /-- Answer a forger's calls: sign with the secret key, recording the message, or query the | ||
| oracle. Signing and the forger share the oracle. -/ | ||
| noncomputable def handler (scheme : Scheme PK SK M Sig Query Digest) (sk : SK) : | ||
| (q : M ⊕ Query) → StateT (List (Query × Digest) × List M) PMF (ForgerSpec M Query Sig Digest q) | ||
| | .inl m => fun state => do | ||
| let coins ← scheme.signCoins sk m | ||
| let signed ← (interpret (oracle Digest) (scheme.sign sk m coins)).run state.1 | ||
| return (signed.1, (signed.2, m :: state.2)) | ||
| | .inr x => fun state => do | ||
| let answer ← oracle Digest x state.1 | ||
| return (answer.1, (answer.2, state.2)) | ||
|
|
||
| /-- The random-oracle EUF-CMA experiment ([BonehShoup2023], Attack Game 13.1): the forger wins with | ||
| a valid signature, under the same oracle, on a message it never had signed. -/ | ||
| noncomputable def eufCmaGame [DecidableEq M] (scheme : Scheme PK SK M Sig Query Digest) | ||
| (forger : Forger PK M Sig Query Digest) : PMF Bool := do | ||
| let keys ← scheme.keyGen | ||
| let s ← forger.coins | ||
| let forged ← (interpret (handler scheme keys.2) (forger.forge keys.1 s)).run ([], []) | ||
| let verified ← (interpret (oracle Digest) (scheme.verify keys.1 forged.1.1 forged.1.2)).run | ||
| forged.2.1 | ||
| return (verified.1 && !(forged.2.2.contains forged.1.1)) | ||
|
|
||
| /-- A scheme is correct when every honest signature verifies under the same oracle, from every | ||
| state of the oracle. -/ | ||
| def Scheme.Correct (scheme : Scheme PK SK M Sig Query Digest) : Prop := | ||
| ∀ keys ∈ scheme.keyGen.support, ∀ m coins, coins ∈ (scheme.signCoins keys.2 m).support → | ||
| ∀ cache, ∀ signed ∈ ((interpret (oracle Digest) (scheme.sign keys.2 m coins)).run | ||
| cache).support, ∀ verified ∈ ((interpret (oracle Digest) | ||
| (scheme.verify keys.1 m signed.1)).run signed.2).support, verified.1 = true | ||
|
|
||
| end Cslib.Crypto.Protocols.ROMSignature | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional scope-clarity suggestion: link the existing
Cslib.Crypto.SignatureSchemehere and state why this exact typed ROM interface is separate. That existing API packages word encodings, strict PPT certificates and non-oracle verification; the present interface has arbitrary typed PMF key/sign coins and shared hash access. A computational connection therefore needs encodings, oracle realization and resource certificates from 3b-ii/#643, rather than an unconditional bridge. This short explanation would keep users from treating the two signature notions as competing computational APIs.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. To leave the approved head of #702 untouched, I added the note in the follow-up #708 (
21ce16c6). It explains the separation fromCslib.Crypto.SignatureSchemeand what a computational connection needs.