smcdel-1.0.0: src/SMCDEL/Examples/DiningCrypto.hs
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 = pubAnnounceOnScn 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<l ] -- n(n-1)/2 shared bits
sharedbitRel = zip sharedbitLabels [ (P $ n+1) .. ]
sharedbits = map snd sharedbitRel
obsfor i = P i : map snd (filter (\(label,_) -> 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)