11/-
22Copyright (c) 2024 Devon Tuma. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
4- Authors: Devon Tuma
4+ Authors: Devon Tuma, Quang Dao
55-/
66import VCVio.CryptoFoundations.SecExp
77import VCVio.OracleComp.QueryTracking.SeededOracle
@@ -261,7 +261,6 @@ private lemma probOutput_collision_le_main_div (s : Fin (qb i + 1)) :
261261 (qc := qb) (js := js) (oa := main) (f := cf)
262262 (y := (some s : Option (Fin (qb i + 1 )))))
263263
264- set_option maxHeartbeats 800000 in
265264/-- Key bound of the forking lemma: the probability that both runs succeed with fork point `s`
266265is at least `Pr[cf(main) = s]² - Pr[cf(main) = s] / |Range i|`. -/
267266theorem le_probOutput_fork (s : Fin (qb i + 1 )) :
@@ -402,8 +401,8 @@ theorem le_probOutput_fork (s : Fin (qb i + 1)) :
402401 let a_1 ← (simulateQ seededOracle main).run
403402 ((seed.takeAtIndex i ↑s).addValue i u)
404403 if cf a_1.1 = some s then pure (some (a.1 , a_1.1 )) else pure none] + 1 := by
405- simpa using (add_le_add_right hnonneg ( 1 : ℝ≥ 0 ∞))
406- simpa [hu'] using haux
404+ simp
405+ simp [hu']
407406 exact le_trans h1 h2
408407 · have hmono :
409408 Pr[= z |
@@ -417,7 +416,7 @@ theorem le_probOutput_fork (s : Fin (qb i + 1)) :
417416 refine probOutput_bind_mono ?_
418417 intro x hx
419418 by_cases hxs : cf x.1 = some s
420- · simpa [hxs, hca, z]
419+ · simp [hxs, hca, z]
421420 · have hrhs_nonneg :
422421 0 ≤ Pr[= z |
423422 (fun r ↦ Option.map (Prod.map cf cf) r) <$>
@@ -426,7 +425,7 @@ theorem le_probOutput_fork (s : Fin (qb i + 1)) :
426425 else pure none)] := zero_le _
427426 have hxs' : (some s : Option (Fin (qb i + 1 ))) ≠ cf x.1 := by
428427 simpa [eq_comm] using hxs
429- simpa [hxs, hxs', z] using hrhs_nonneg
428+ simp [hxs, hxs', z]
430429 have hu'' : (seed i)[↑s]? ≠ some u := by simpa using hu'
431430 have hif :
432431 (if (seed i)[↑s]? = some u then
@@ -496,8 +495,137 @@ theorem le_probOutput_fork (s : Fin (qb i + 1)) :
496495 exact (tsub_le_iff_right).2 hNoGuardLeAdd
497496 have hNoGuardGeSquare :
498497 Pr[= s | cf <$> main] ^ 2 ≤ Pr[= z | noGuardComp] := by
499- -- Remaining core: seed-factorization and weighted-square lower bound.
500- sorry
498+ -- Step 1: Express Pr[= s | cf <$> main] as E_σ[ P(σ) ] via seeded oracle factorization
499+ have hMain : (Pr[= s | cf <$> main] : ℝ≥0 ∞) =
500+ ∑' σ, Pr[= σ | generateSeed spec qb js] *
501+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
502+ cf <$> (simulateQ seededOracle main).run' σ] := by
503+ rw [show (Pr[= s | cf <$> main] : ℝ≥0 ∞) =
504+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
505+ (do let seed ← liftComp (generateSeed spec qb js) spec
506+ cf <$> (simulateQ seededOracle main).run' seed :
507+ OracleComp spec (Option (Fin (qb i + 1 ))))] from by
508+ simpa using (seededOracle.probOutput_generateSeed_bind_map_simulateQ
509+ (qc := qb) (js := js) (oa := main) (f := cf)
510+ (y := (some s : Option (Fin (qb i + 1 ))))).symm]
511+ rw [probOutput_bind_eq_tsum]
512+ simp_rw [probOutput_liftComp]
513+ -- Step 2: Factor Pr[= z | noGuardComp] = ∑' σ, w(σ) * P(σ) * P(take(σ))
514+ -- Uses conditional independence (probOutput_bind_bind_prod_mk_eq_mul')
515+ -- and the addValue factorization lemma.
516+ have hFactor : Pr[= z | noGuardComp] =
517+ ∑' σ, Pr[= σ | generateSeed spec qb js] *
518+ (Pr[= (some s : Option (Fin (qb i + 1 ))) |
519+ cf <$> (simulateQ seededOracle main).run' σ] *
520+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
521+ cf <$> (simulateQ seededOracle main).run'
522+ (σ.takeAtIndex i ↑s)]) := by
523+ simp only [noGuardComp, z]
524+ rw [probOutput_bind_eq_tsum]
525+ simp_rw [probOutput_liftComp]
526+ congr 1 ; ext σ; congr 1
527+ have hcomp : (do let x₁ ← (simulateQ seededOracle main).run' σ
528+ let u ← liftComp ($ᵗ spec.Range i) spec
529+ let x₂ ← (simulateQ seededOracle main).run'
530+ ((σ.takeAtIndex i ↑s).addValue i u)
531+ pure (some (cf x₁, cf x₂)) : OracleComp spec _) =
532+ some <$> (do let x₁ ← (simulateQ seededOracle main).run' σ
533+ let x₂ ← (liftComp ($ᵗ spec.Range i) spec >>= fun u =>
534+ (simulateQ seededOracle main).run'
535+ ((σ.takeAtIndex i ↑s).addValue i u))
536+ pure (cf x₁, cf x₂)) := by
537+ simp only [map_eq_bind_pure_comp, bind_assoc, Function.comp, pure_bind]
538+ rw [hcomp, probOutput_some_map_some, probOutput_bind_bind_prod_mk_eq_mul']
539+ congr 1
540+ have h := seededOracle.evalDist_liftComp_uniformSample_bind_simulateQ_run'_addValue
541+ (σ.takeAtIndex i ↑s) i main
542+ exact congrFun (congrArg DFunLike.coe (by simp only [evalDist_map, h])) (some s)
543+ -- Step 3: Jensen/Cauchy-Schwarz via prefix grouping
544+ -- (∑ w * P)² ≤ ∑ w * P * P(take) by decomposing into prefix groups
545+ -- and applying sq_tsum_le_tsum_sq.
546+ have hJensen :
547+ (∑' σ, Pr[= σ | generateSeed spec qb js] *
548+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
549+ cf <$> (simulateQ seededOracle main).run' σ]) ^ 2 ≤
550+ ∑' σ, Pr[= σ | generateSeed spec qb js] *
551+ (Pr[= (some s : Option (Fin (qb i + 1 ))) |
552+ cf <$> (simulateQ seededOracle main).run' σ] *
553+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
554+ cf <$> (simulateQ seededOracle main).run'
555+ (σ.takeAtIndex i ↑s)]) := by
556+ -- Notation: w(σ) = Pr[ =σ|gen ] , P(σ) = Pr[ =y|run'(σ) ] , Q(σ) = Pr[ =y|run'(take(σ)) ]
557+ -- hEq: ∑ w * P = ∑ w * Q (both equal Pr[= some s | cf <$> main])
558+ have hMainTake : ∑' σ, Pr[= σ | generateSeed spec qb js] *
559+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
560+ cf <$> (simulateQ seededOracle main).run' (σ.takeAtIndex i ↑s)] =
561+ Pr[= (some s : Option (Fin (qb i + 1 ))) | cf <$> main] := by
562+ have hTake :=
563+ seededOracle.probOutput_generateSeed_bind_map_simulateQ_takeAtIndex
564+ (qc := qb) (js := js) (i₀ := i) (k := ↑s) (oa := main) (f := cf)
565+ (y := (some s : Option (Fin (qb i + 1 ))))
566+ rw [probOutput_bind_eq_tsum] at hTake
567+ simp_rw [probOutput_liftComp] at hTake
568+ exact hTake
569+ have hEq : ∑' σ, Pr[= σ | generateSeed spec qb js] *
570+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
571+ cf <$> (simulateQ seededOracle main).run' σ] =
572+ ∑' σ, Pr[= σ | generateSeed spec qb js] *
573+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
574+ cf <$> (simulateQ seededOracle main).run' (σ.takeAtIndex i ↑s)] :=
575+ by
576+ calc
577+ ∑' σ, Pr[= σ | generateSeed spec qb js] *
578+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
579+ cf <$> (simulateQ seededOracle main).run' σ]
580+ = Pr[= (some s : Option (Fin (qb i + 1 ))) | cf <$> main] := by
581+ simpa using hMain.symm
582+ _ = ∑' σ, Pr[= σ | generateSeed spec qb js] *
583+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
584+ cf <$> (simulateQ seededOracle main).run' (σ.takeAtIndex i ↑s)] := by
585+ simpa using hMainTake.symm
586+ -- Jensen: (∑ w * Q)² ≤ ∑ w * Q²
587+ set w : QuerySeed spec → ℝ≥0 ∞ := fun σ => Pr[= σ | generateSeed spec qb js]
588+ set Q : QuerySeed spec → ℝ≥0 ∞ := fun σ =>
589+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
590+ cf <$> (simulateQ seededOracle main).run' (σ.takeAtIndex i ↑s)]
591+ have hw : ∑' σ, w σ ≤ 1 := tsum_probOutput_le_one
592+ -- hEq2: ∑ w * Q² = ∑ w * (P * Q) via weighted takeAtIndex faithfulness
593+ have hEq2 : ∑' σ, w σ * Q σ ^ 2 =
594+ ∑' σ, w σ *
595+ (Pr[= (some s : Option (Fin (qb i + 1 ))) |
596+ cf <$> (simulateQ seededOracle main).run' σ] * Q σ) := by
597+ simp only [sq, Q, w]
598+ have hSim : ∀ σ', (simulateQ seededOracle (cf <$> main :
599+ OracleComp spec (Option (Fin (qb i + 1 ))))).run' σ' =
600+ cf <$> (simulateQ seededOracle main).run' σ' := by
601+ intro σ'
602+ simp only [simulateQ_map]
603+ show Prod.fst <$> (Prod.map cf id <$> (simulateQ seededOracle main).run σ') =
604+ cf <$> (Prod.fst <$> (simulateQ seededOracle main).run σ')
605+ simp [Functor.map_map]
606+ have hWF := seededOracle.tsum_probOutput_generateSeed_weight_takeAtIndex
607+ qb js i (↑s) (cf <$> main : OracleComp spec (Option (Fin (qb i + 1 ))))
608+ (some s : Option (Fin (qb i + 1 )))
609+ (fun τ => Pr[= (some s : Option (Fin (qb i + 1 ))) |
610+ (simulateQ seededOracle (cf <$> main :
611+ OracleComp spec (Option (Fin (qb i + 1 ))))).run' τ])
612+ simp_rw [hSim] at hWF
613+ exact hWF.symm.trans (by congr 1 ; ext σ; congr 1 ; exact mul_comm _ _)
614+ calc _ = (∑' σ, w σ * Q σ) ^ 2 := by rw [hEq]
615+ _ ≤ ∑' σ, w σ * Q σ ^ 2 := ENNReal.sq_tsum_le_tsum_sq w Q hw
616+ _ = _ := hEq2
617+ calc Pr[= s | cf <$> main] ^ 2
618+ = (∑' σ, Pr[= σ | generateSeed spec qb js] *
619+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
620+ cf <$> (simulateQ seededOracle main).run' σ]) ^ 2 := by
621+ rw [hMain]
622+ _ ≤ ∑' σ, Pr[= σ | generateSeed spec qb js] *
623+ (Pr[= (some s : Option (Fin (qb i + 1 ))) |
624+ cf <$> (simulateQ seededOracle main).run' σ] *
625+ Pr[= (some s : Option (Fin (qb i + 1 ))) |
626+ cf <$> (simulateQ seededOracle main).run'
627+ (σ.takeAtIndex i ↑s)]) := hJensen
628+ _ = Pr[= z | noGuardComp] := hFactor.symm
501629 exact le_trans
502630 (tsub_le_tsub_right hNoGuardGeSquare (Pr[= (some s : Option (Fin (qb i + 1 ))) | collisionComp]))
503631 hNoGuardMinusLeRhs
0 commit comments