DSA.hs (4431B)
1 module Cryptopals.DSA ( 2 Params(..) 3 , defaultParams 4 5 , Keypair(..) 6 , Key(..) 7 , keygen 8 9 , Sig(..) 10 , sign 11 , sign' 12 , verify 13 14 , unsafeSign 15 , unsafeVerify 16 ) where 17 18 import Control.Monad.Primitive 19 import qualified Cryptopals.Digest.Pure.SHA as CS 20 import qualified Cryptopals.DH as DH 21 import qualified Cryptopals.RSA as RSA 22 import qualified Data.ByteString as BS 23 import qualified Data.ByteString.Lazy as BL 24 import Numeric.Natural 25 import qualified System.Random.MWC as MWC 26 27 fi :: (Integral a, Num b) => a -> b 28 fi = fromIntegral 29 30 data Params = Params { 31 dsap :: Natural 32 , dsaq :: Natural 33 , dsag :: Natural 34 } deriving (Eq, Show) 35 36 p :: Natural 37 p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1 38 39 q :: Natural 40 q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b 41 42 g :: Natural 43 g = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291 44 45 defaultParams :: Params 46 defaultParams = Params p q g 47 48 data Keypair = Keypair { 49 sec :: Key 50 , pub :: Key 51 } deriving (Eq, Show) 52 53 data Key = 54 Pub Natural 55 | Sec Natural 56 deriving (Eq, Show) 57 58 keygen :: PrimMonad m => Params -> MWC.Gen (PrimState m) -> m Keypair 59 keygen Params {..} gen = do 60 x <- MWC.uniformRM (1, dsaq - 1) gen 61 let y = DH.modexp dsag x dsap 62 pure $ Keypair (Sec x) (Pub y) 63 64 data Sig = Sig { 65 sigr :: Natural 66 , sigs :: Natural 67 } deriving (Eq, Show) 68 69 sign 70 :: PrimMonad m 71 => Params 72 -> Key 73 -> BS.ByteString 74 -> MWC.Gen (PrimState m) 75 -> m Sig 76 sign ps@Params {..} key msg gen = case key of 77 Pub {} -> error "sign: need secret key" 78 Sec x -> do 79 k <- MWC.uniformRM (1, dsaq - 1) gen 80 let r = DH.modexp dsag k p `rem` dsaq 81 if r == 0 82 then sign ps key msg gen 83 else do 84 let h = fi . CS.integerDigest . CS.sha1 $ BL.fromStrict msg 85 s = (RSA.modinv' k dsaq * (h + x * r)) `rem` dsaq 86 if s == 0 87 then sign ps key msg gen 88 else pure (Sig r s) 89 90 -- sign with provided subkey/nonce 91 sign' 92 :: Params 93 -> Key 94 -> Natural 95 -> BS.ByteString 96 -> Sig 97 sign' ps@Params {..} key k msg = case key of 98 Pub {} -> error "sign: need secret key" 99 Sec x -> 100 let r = DH.modexp dsag k p `rem` dsaq 101 in if r == 0 102 then error "sign': invalid nonce (r)" 103 else 104 let h = fi . CS.integerDigest . CS.sha1 $ BL.fromStrict msg 105 s = (RSA.modinv' k dsaq * (h + x * r)) `rem` dsaq 106 in if s == 0 107 then error "sign': invalid nonce (s)" 108 else Sig r s 109 110 -- don't check for bad signature values 111 unsafeSign 112 :: PrimMonad m 113 => Params 114 -> Key 115 -> BS.ByteString 116 -> MWC.Gen (PrimState m) 117 -> m Sig 118 unsafeSign ps@Params {..} key msg gen = case key of 119 Pub {} -> error "sign: need secret key" 120 Sec x -> do 121 k <- MWC.uniformRM (1, dsaq - 1) gen 122 let r = DH.modexp dsag k p `rem` dsaq 123 h = fi . CS.integerDigest . CS.sha1 $ BL.fromStrict msg 124 s = (RSA.modinv' k dsaq * (h + x * r)) `rem` dsaq 125 pure (Sig r s) 126 127 verify 128 :: Params 129 -> Key 130 -> BS.ByteString 131 -> Sig 132 -> Bool 133 verify Params {..} key msg Sig {..} = case key of 134 Sec {} -> error "verify: need public key" 135 Pub y 136 | or [sigr == 0, sigr >= dsaq, sigs == 0, sigs >= dsaq] -> False 137 | otherwise -> 138 let w = RSA.modinv' sigs dsaq 139 h = fi . CS.integerDigest . CS.sha1 $ BL.fromStrict msg 140 u1 = (h * w) `rem` dsaq 141 u2 = (sigr * w) `rem` dsaq 142 v = (((DH.modexp dsag u1 dsap) * (DH.modexp y u2 dsap)) `rem` dsap) 143 `rem` dsaq 144 in v == sigr 145 146 -- don't check for bad signature parameters 147 unsafeVerify 148 :: Params 149 -> Key 150 -> BS.ByteString 151 -> Sig 152 -> Bool 153 unsafeVerify Params {..} key msg Sig {..} = case key of 154 Sec {} -> error "verify: need public key" 155 Pub y -> 156 let w = RSA.modinv' sigs dsaq 157 h = fi . CS.integerDigest . CS.sha1 $ BL.fromStrict msg 158 u1 = (h * w) `rem` dsaq 159 u2 = (sigr * w) `rem` dsaq 160 v = (((DH.modexp dsag u1 dsap) * (DH.modexp y u2 dsap)) `rem` dsap) 161 `rem` dsaq 162 in v == sigr 163