module Signet.Unstable.Type.Signer where

import qualified Crypto.MAC.HMAC as Hmac
import qualified Crypto.PubKey.Ed25519 as Ed25519
import qualified Data.ByteString as ByteString
import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner
import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature
import qualified Signet.Unstable.Type.Message as Message
import qualified Signet.Unstable.Type.Secret as Secret
import qualified Signet.Unstable.Type.SecretKey as SecretKey
import qualified Signet.Unstable.Type.Signature as Signature
import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature

data Signer
  = Asymmetric SecretKey.SecretKey
  | Symmetric Secret.Secret
  deriving (Signer -> Signer -> Bool
(Signer -> Signer -> Bool)
-> (Signer -> Signer -> Bool) -> Eq Signer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Signer -> Signer -> Bool
== :: Signer -> Signer -> Bool
$c/= :: Signer -> Signer -> Bool
/= :: Signer -> Signer -> Bool
Eq, Int -> Signer -> ShowS
[Signer] -> ShowS
Signer -> String
(Int -> Signer -> ShowS)
-> (Signer -> String) -> ([Signer] -> ShowS) -> Show Signer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Signer -> ShowS
showsPrec :: Int -> Signer -> ShowS
$cshow :: Signer -> String
show :: Signer -> String
$cshowList :: [Signer] -> ShowS
showList :: [Signer] -> ShowS
Show)

parse :: ByteString.ByteString -> Either InvalidSigner.InvalidSigner Signer
parse :: ByteString -> Either InvalidSigner Signer
parse ByteString
byteString = case ByteString -> Either InvalidSecretKey SecretKey
SecretKey.parse ByteString
byteString of
  Right SecretKey
secretKey -> Signer -> Either InvalidSigner Signer
forall a b. b -> Either a b
Right (Signer -> Either InvalidSigner Signer)
-> Signer -> Either InvalidSigner Signer
forall a b. (a -> b) -> a -> b
$ SecretKey -> Signer
Asymmetric SecretKey
secretKey
  Left InvalidSecretKey
_ -> case ByteString -> Either InvalidSecret Secret
Secret.parse ByteString
byteString of
    Right Secret
secret -> Signer -> Either InvalidSigner Signer
forall a b. b -> Either a b
Right (Signer -> Either InvalidSigner Signer)
-> Signer -> Either InvalidSigner Signer
forall a b. (a -> b) -> a -> b
$ Secret -> Signer
Symmetric Secret
secret
    Left InvalidSecret
_ -> InvalidSigner -> Either InvalidSigner Signer
forall a b. a -> Either a b
Left (InvalidSigner -> Either InvalidSigner Signer)
-> InvalidSigner -> Either InvalidSigner Signer
forall a b. (a -> b) -> a -> b
$ ByteString -> InvalidSigner
InvalidSigner.MkInvalidSigner ByteString
byteString

render :: Signer -> ByteString.ByteString
render :: Signer -> ByteString
render Signer
signer = case Signer
signer of
  Asymmetric SecretKey
secretKey -> SecretKey -> ByteString
SecretKey.render SecretKey
secretKey
  Symmetric Secret
secret -> Secret -> ByteString
Secret.render Secret
secret

sign :: Signer -> Message.Message -> Signature.Signature
sign :: Signer -> Message -> Signature
sign Signer
signer = case Signer
signer of
  Asymmetric SecretKey
secretKey -> AsymmetricSignature -> Signature
Signature.Asymmetric (AsymmetricSignature -> Signature)
-> (Message -> AsymmetricSignature) -> Message -> Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> Message -> AsymmetricSignature
asymmetric SecretKey
secretKey
  Symmetric Secret
secret -> SymmetricSignature -> Signature
Signature.Symmetric (SymmetricSignature -> Signature)
-> (Message -> SymmetricSignature) -> Message -> Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Secret -> Message -> SymmetricSignature
symmetric Secret
secret

asymmetric :: SecretKey.SecretKey -> Message.Message -> AsymmetricSignature.AsymmetricSignature
asymmetric :: SecretKey -> Message -> AsymmetricSignature
asymmetric SecretKey
secretKey =
  let sk :: SecretKey
sk = SecretKey -> SecretKey
SecretKey.unwrap SecretKey
secretKey
      pk :: PublicKey
pk = SecretKey -> PublicKey
Ed25519.toPublic SecretKey
sk
   in Signature -> AsymmetricSignature
AsymmetricSignature.MkAsymmetricSignature
        (Signature -> AsymmetricSignature)
-> (Message -> Signature) -> Message -> AsymmetricSignature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> PublicKey -> ByteString -> Signature
forall ba.
ByteArrayAccess ba =>
SecretKey -> PublicKey -> ba -> Signature
Ed25519.sign SecretKey
sk PublicKey
pk
        (ByteString -> Signature)
-> (Message -> ByteString) -> Message -> Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Message -> ByteString
Message.render

symmetric :: Secret.Secret -> Message.Message -> SymmetricSignature.SymmetricSignature
symmetric :: Secret -> Message -> SymmetricSignature
symmetric Secret
secret =
  Digest SHA256 -> SymmetricSignature
SymmetricSignature.MkSymmetricSignature
    (Digest SHA256 -> SymmetricSignature)
-> (Message -> Digest SHA256) -> Message -> SymmetricSignature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HMAC SHA256 -> Digest SHA256
forall a. HMAC a -> Digest a
Hmac.hmacGetDigest
    (HMAC SHA256 -> Digest SHA256)
-> (Message -> HMAC SHA256) -> Message -> Digest SHA256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScrubbedBytes -> ByteString -> HMAC SHA256
forall key message a.
(ByteArrayAccess key, ByteArrayAccess message, HashAlgorithm a) =>
key -> message -> HMAC a
Hmac.hmac (Secret -> ScrubbedBytes
Secret.unwrap Secret
secret)
    (ByteString -> HMAC SHA256)
-> (Message -> ByteString) -> Message -> HMAC SHA256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Message -> ByteString
Message.render