{-# LANGUAGE DeriveDataTypeable #-}
module Crypto.Types.PubKey.DSA
( Params(..)
, Signature(..)
, PublicNumber
, PublicKey(..)
, PrivateNumber
, PrivateKey(..)
, KeyPair(..)
, toPublicKey
, toPrivateKey
) where
import Data.Data
import Data.ASN1.Types
type PublicNumber = Integer
type PrivateNumber = Integer
data Params = Params
{ params_p :: Integer
, params_g :: Integer
, params_q :: Integer
} deriving (Show,Read,Eq,Data,Typeable)
instance ASN1Object Params where
toASN1 params = \xs -> Start Sequence
: IntVal (params_p params)
: IntVal (params_q params)
: IntVal (params_g params)
: End Sequence
: xs
fromASN1 (Start Sequence:IntVal p:IntVal q:IntVal g:End Sequence:xs) =
Right (Params { params_p = p, params_g = g, params_q = q }, xs)
fromASN1 _ = Left "fromASN1: DSA.Params: unexpected format"
data Signature = Signature
{ sign_r :: Integer
, sign_s :: Integer
} deriving (Show,Read,Eq,Data,Typeable)
instance ASN1Object Signature where
toASN1 sign = \xs -> Start Sequence
: IntVal (sign_r sign)
: IntVal (sign_s sign)
: End Sequence
: xs
fromASN1 (Start Sequence:IntVal r:IntVal s:End Sequence:xs) =
Right (Signature { sign_r = r, sign_s = s }, xs)
fromASN1 _ = Left "fromASN1: DSA.Signature: unexpected format"
data PublicKey = PublicKey
{ public_params :: Params
, public_y :: PublicNumber
} deriving (Show,Read,Eq,Data,Typeable)
instance ASN1Object PublicKey where
toASN1 pubKey = \xs -> Start Sequence
: IntVal (params_p params)
: IntVal (params_q params)
: IntVal (params_g params)
: End Sequence
: IntVal (public_y pubKey)
: xs
where params = public_params pubKey
fromASN1 l = case fromASN1 l of
Left err -> Left err
Right (dsaParams, ls) -> case ls of
IntVal dsaPub : ls2 -> Right (PublicKey dsaParams dsaPub, ls2)
_ -> Left "fromASN1: DSA.PublicKey: unexpected format"
data PrivateKey = PrivateKey
{ private_params :: Params
, private_x :: PrivateNumber
} deriving (Show,Read,Eq,Data,Typeable)
data KeyPair = KeyPair Params PublicNumber PrivateNumber
deriving (Show,Read,Eq,Data,Typeable)
instance ASN1Object KeyPair where
toASN1 (KeyPair params pub priv) = \xs ->
Start Sequence
: IntVal 0
: IntVal (params_p params)
: IntVal (params_q params)
: IntVal (params_g params)
: IntVal pub
: IntVal priv
: End Sequence
: xs
fromASN1 (Start Sequence : IntVal n : xs)
| n == 0 = case xs of
IntVal p : IntVal q : IntVal g : IntVal pub : IntVal priv : End Sequence : xs2 ->
let params = Params { params_p = p, params_g = g, params_q = q }
in Right (KeyPair params pub priv, xs2)
_ ->
Left "fromASN1: DSA.KeyPair: invalid format (version=0)"
| otherwise = Left "fromASN1: DSA.KeyPair: unknown format"
fromASN1 _ = Left "fromASN1: DSA.KeyPair: unexpected format"
toPublicKey :: KeyPair -> PublicKey
toPublicKey (KeyPair params pub _) = PublicKey params pub
toPrivateKey :: KeyPair -> PrivateKey
toPrivateKey (KeyPair params _ priv) = PrivateKey params priv