module SMCDEL.Examples.DiningCrypto where import Data.List (delete) import SMCDEL.Language import SMCDEL.Symbolic.S5 dcScnInit :: Int -> (Bool,Bool,Bool) -> KnowScene dcScnInit payer (b1,b2,b3) = ( KnS props law obs , truths ) where props = [ P 0 -- The NSA paid , P 1 -- Alice paid , P 2 -- Bob paid , P 3 -- Charlie paid , P 4 -- shared bit of Alice and Bob , P 5 -- shared bit of Alice and Charlie , P 6 ] -- shared bit of Bob and Charlie law = boolBddOf $ Conj [ someonepaid, notwopaid ] obs = [ (show (1::Int),[P 1, P 4, P 5]) , (show (2::Int),[P 2, P 4, P 6]) , (show (3::Int),[P 3, P 5, P 6]) ] truths = [ P payer ] ++ [ P 4 | b1 ] ++ [ P 5 | b2 ] ++ [ P 6 | b3 ] dcScn1 :: KnowScene dcScn1 = dcScnInit 1 (True,True,False) someonepaid, notwopaid :: Form someonepaid = Disj (map (PrpF . P) [0..3]) notwopaid = Conj [ Neg $ Conj [ PrpF $ P x, PrpF $ P y ] | x<-[0..3], y<-[(x+1)..3] ] reveal :: Int -> Form reveal 1 = Xor (map PrpF [P 1, P 4, P 5]) reveal 2 = Xor (map PrpF [P 2, P 4, P 6]) reveal _ = Xor (map PrpF [P 3, P 5, P 6]) dcScn2 :: KnowScene dcScn2 = update dcScn1 (Conj [reveal 1, reveal 2, reveal 3]) everyoneKnowsWhetherNSApaid :: Form everyoneKnowsWhetherNSApaid = Conj [ Kw (show i) (PrpF $ P 0) | i <- [1..3]::[Int] ] nobodyknowsWhoPaid :: Form nobodyknowsWhoPaid = Conj [ Impl (PrpF (P 1)) (Conj [Neg $ K "2" (PrpF $ P 1), Neg $ K "3" (PrpF $ P 1) ]) , Impl (PrpF (P 2)) (Conj [Neg $ K "1" (PrpF $ P 2), Neg $ K "3" (PrpF $ P 2) ]) , Impl (PrpF (P 3)) (Conj [Neg $ K "1" (PrpF $ P 3), Neg $ K "2" (PrpF $ P 3) ]) ] dcCheckForm :: Form dcCheckForm = PubAnnounceW (reveal 1) $ PubAnnounceW (reveal 2) $ PubAnnounceW (reveal 3) $ Conj [ everyoneKnowsWhetherNSApaid, nobodyknowsWhoPaid ] dcValid :: Bool dcValid = validViaBdd dcStruct dcCheckForm where (dcStruct,_) = dcScn1 genDcSomeonepaid :: Int -> Form genDcSomeonepaid n = Disj (map (PrpF . P) [0..n]) genDcNotwopaid :: Int -> Form genDcNotwopaid n = Conj [ Neg $ Conj [ PrpF $ P x, PrpF $ P y ] | x<-[0..n], y<-[(x+1)..n] ] -- | Initial structure for Dining Cryptographers (complete graph!) genDcKnsInit :: Int -> KnowStruct genDcKnsInit n = KnS props law obs where props = [ P 0 ] -- The NSA paid ++ [ (P 1) .. (P n) ] -- agent i paid ++ sharedbits law = boolBddOf $ Conj [genDcSomeonepaid n, genDcNotwopaid n] obs = [ (show i, obsfor i) | i<-[1..n] ] sharedbitLabels = [ [k,l] | k <- [1..n], l <- [1..n], k i `elem` label) sharedbitRel) genDcEveryoneKnowsWhetherNSApaid :: Int -> Form genDcEveryoneKnowsWhetherNSApaid n = Conj [ Kw (show i) (PrpF $ P 0) | i <- [1..n] ] genDcReveal :: Int -> Int -> Form genDcReveal n i = Xor (map PrpF ps) where (KnS _ _ obs) = genDcKnsInit n (Just ps) = lookup (show i) obs genDcNobodyknowsWhoPaid :: Int -> Form genDcNobodyknowsWhoPaid n = Conj [ Impl (PrpF (P i)) (Conj [Neg $ K (show k) (PrpF $ P i) | k <- delete i [1..n] ]) | i <- [1..n] ] genDcCheckForm :: Int -> Form genDcCheckForm n = pubAnnounceWhetherStack [ genDcReveal n i | i<-[1..n] ] $ Conj [ genDcEveryoneKnowsWhetherNSApaid n, genDcNobodyknowsWhoPaid n ] genDcValid :: Int -> Bool genDcValid n = validViaBdd (genDcKnsInit n) (genDcCheckForm n)