module Signet.Unstable.Type.VerifierTest where

import qualified Control.Monad.Catch as Exception
import qualified Data.ByteString.Char8 as Ascii
import qualified Signet.Unstable.Exception.InvalidVerifier as InvalidVerifier
import qualified Signet.Unstable.Exception.VerificationException as VerificationException
import qualified Signet.Unstable.Extra.Either as Either
import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature
import qualified Signet.Unstable.Type.Message as Message
import qualified Signet.Unstable.Type.PublicKey as PublicKey
import qualified Signet.Unstable.Type.Secret as Secret
import qualified Signet.Unstable.Type.Signature as Signature
import qualified Signet.Unstable.Type.Signatures as Signatures
import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature
import qualified Signet.Unstable.Type.Test as Test
import qualified Signet.Unstable.Type.Verifier as Verifier

spec :: (Exception.MonadThrow io, Monad tree) => Test.Test io tree -> tree ()
spec :: forall (io :: * -> *) (tree :: * -> *).
(MonadThrow io, Monad tree) =>
Test io tree -> tree ()
spec Test io tree
test = Test io tree -> String -> tree () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> tree () -> tree ()
Test.describe Test io tree
test String
"Signet.Unstable.Type.Verifier" (tree () -> tree ()) -> tree () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
  Test io tree -> String -> tree () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> tree () -> tree ()
Test.describe Test io tree
test String
"parse" (tree () -> tree ()) -> tree () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"succeeds with a valid public key" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="
      let actual :: Either InvalidVerifier Verifier
actual = ByteString -> Either InvalidVerifier Verifier
Verifier.parse ByteString
byteString
      publicKey <- Either InvalidPublicKey PublicKey -> io PublicKey
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidPublicKey PublicKey -> io PublicKey)
-> Either InvalidPublicKey PublicKey -> io PublicKey
forall a b. (a -> b) -> a -> b
$ ByteString -> Either InvalidPublicKey PublicKey
PublicKey.parse ByteString
byteString
      Test.assertEq test actual (Right (Verifier.Asymmetric publicKey))

    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"succeeds with a valid secret" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      let actual :: Either InvalidVerifier Verifier
actual = ByteString -> Either InvalidVerifier Verifier
Verifier.parse ByteString
byteString
      secret <- Either InvalidSecret Secret -> io Secret
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecret Secret -> io Secret)
-> Either InvalidSecret Secret -> io Secret
forall a b. (a -> b) -> a -> b
$ ByteString -> Either InvalidSecret Secret
Secret.parse ByteString
byteString
      Test.assertEq test actual (Right (Verifier.Symmetric secret))

    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"fails with invalid input" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"invalid"
      let actual :: Either InvalidVerifier Verifier
actual = ByteString -> Either InvalidVerifier Verifier
Verifier.parse ByteString
byteString
      Test io tree
-> Either InvalidVerifier Verifier
-> Either InvalidVerifier Verifier
-> io ()
forall (io :: * -> *) a (tree :: * -> *).
(HasCallStack, Applicative io, Eq a, Show a) =>
Test io tree -> a -> a -> io ()
Test.assertEq Test io tree
test Either InvalidVerifier Verifier
actual (InvalidVerifier -> Either InvalidVerifier Verifier
forall a b. a -> Either a b
Left (ByteString -> InvalidVerifier
InvalidVerifier.MkInvalidVerifier ByteString
byteString))

  Test io tree -> String -> tree () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> tree () -> tree ()
Test.describe Test io tree
test String
"render" (tree () -> tree ()) -> tree () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"works with a public key" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="
      publicKey <- Either InvalidPublicKey PublicKey -> io PublicKey
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidPublicKey PublicKey -> io PublicKey)
-> (ByteString -> Either InvalidPublicKey PublicKey)
-> ByteString
-> io PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidPublicKey PublicKey
PublicKey.parse (ByteString -> io PublicKey) -> ByteString -> io PublicKey
forall a b. (a -> b) -> a -> b
$ ByteString
byteString
      Test.assertEq test (Verifier.render (Verifier.Asymmetric publicKey)) byteString

    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"works with a secret" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      secret <- Either InvalidSecret Secret -> io Secret
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecret Secret -> io Secret)
-> (ByteString -> Either InvalidSecret Secret)
-> ByteString
-> io Secret
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSecret Secret
Secret.parse (ByteString -> io Secret) -> ByteString -> io Secret
forall a b. (a -> b) -> a -> b
$ ByteString
byteString
      Test.assertEq test (Verifier.render (Verifier.Symmetric secret)) byteString

  Test io tree -> String -> tree () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> tree () -> tree ()
Test.describe Test io tree
test String
"verify" (tree () -> tree ()) -> tree () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"succeeds with a valid asymmetric signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      verifier <- Either InvalidVerifier Verifier -> io Verifier
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidVerifier Verifier -> io Verifier)
-> (ByteString -> Either InvalidVerifier Verifier)
-> ByteString
-> io Verifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidVerifier Verifier
Verifier.parse (ByteString -> io Verifier) -> ByteString -> io Verifier
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="
      let actual = Verifier
-> Message -> Signatures -> Either VerificationException Signature
Verifier.verify Verifier
verifier Message
message Signatures
signatures
      signature <- Either.throw =<< Either.throw (Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ==")
      Test.assertEq test actual (Right signature)

    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"fails with an invalid asymmetric signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      verifier <- Either InvalidVerifier Verifier -> io Verifier
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidVerifier Verifier -> io Verifier)
-> (ByteString -> Either InvalidVerifier Verifier)
-> ByteString
-> io Verifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidVerifier Verifier
Verifier.parse (ByteString -> io Verifier) -> ByteString -> io Verifier
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="
      let actual = Verifier
-> Message -> Signatures -> Either VerificationException Signature
Verifier.verify Verifier
verifier Message
message Signatures
signatures
      Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))

    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"succeeds with a valid symmetric signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      verifier <- Either InvalidVerifier Verifier -> io Verifier
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidVerifier Verifier -> io Verifier)
-> (ByteString -> Either InvalidVerifier Verifier)
-> ByteString
-> io Verifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidVerifier Verifier
Verifier.parse (ByteString -> io Verifier) -> ByteString -> io Verifier
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="
      let actual = Verifier
-> Message -> Signatures -> Either VerificationException Signature
Verifier.verify Verifier
verifier Message
message Signatures
signatures
      signature <- Either.throw =<< Either.throw (Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw=")
      Test.assertEq test actual (Right signature)

    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"fails with an invalid symmetric signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      verifier <- Either InvalidVerifier Verifier -> io Verifier
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidVerifier Verifier -> io Verifier)
-> (ByteString -> Either InvalidVerifier Verifier)
-> ByteString
-> io Verifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidVerifier Verifier
Verifier.parse (ByteString -> io Verifier) -> ByteString -> io Verifier
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="
      let actual = Verifier
-> Message -> Signatures -> Either VerificationException Signature
Verifier.verify Verifier
verifier Message
message Signatures
signatures
      Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))

  Test io tree -> String -> tree () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> tree () -> tree ()
Test.describe Test io tree
test String
"asymmetric" (tree () -> tree ()) -> tree () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"succeeds with a valid signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      publicKey <- Either InvalidPublicKey PublicKey -> io PublicKey
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidPublicKey PublicKey -> io PublicKey)
-> (ByteString -> Either InvalidPublicKey PublicKey)
-> ByteString
-> io PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidPublicKey PublicKey
PublicKey.parse (ByteString -> io PublicKey) -> ByteString -> io PublicKey
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="
      let actual = PublicKey
-> Message
-> Signatures
-> Either VerificationException AsymmetricSignature
Verifier.asymmetric PublicKey
publicKey Message
message Signatures
signatures
      asymmetricSignature <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="
      Test.assertEq test actual (Right asymmetricSignature)

    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"fails with an invalid signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      publicKey <- Either InvalidPublicKey PublicKey -> io PublicKey
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidPublicKey PublicKey -> io PublicKey)
-> (ByteString -> Either InvalidPublicKey PublicKey)
-> ByteString
-> io PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidPublicKey PublicKey
PublicKey.parse (ByteString -> io PublicKey) -> ByteString -> io PublicKey
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whpk_wuzPrKxPfWpJSsXgyg/MEoMGvjs5SjDO4ad6X4ZYqqg="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1a,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="
      let actual = PublicKey
-> Message
-> Signatures
-> Either VerificationException AsymmetricSignature
Verifier.asymmetric PublicKey
publicKey Message
message Signatures
signatures
      Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))

  Test io tree -> String -> tree () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> tree () -> tree ()
Test.describe Test io tree
test String
"symmetric" (tree () -> tree ()) -> tree () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"succeeds with a valid signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      secret <- Either InvalidSecret Secret -> io Secret
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecret Secret -> io Secret)
-> (ByteString -> Either InvalidSecret Secret)
-> ByteString
-> io Secret
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSecret Secret
Secret.parse (ByteString -> io Secret) -> ByteString -> io Secret
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="
      let actual = Secret
-> Message
-> Signatures
-> Either VerificationException SymmetricSignature
Verifier.symmetric Secret
secret Message
message Signatures
signatures
      symmetricSignature <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="
      Test.assertEq test actual (Right symmetricSignature)

    Test io tree -> String -> io () -> tree ()
forall (io :: * -> *) (tree :: * -> *).
Test io tree -> String -> io () -> tree ()
Test.it Test io tree
test String
"fails with an invalid signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      secret <- Either InvalidSecret Secret -> io Secret
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecret Secret -> io Secret)
-> (ByteString -> Either InvalidSecret Secret)
-> ByteString
-> io Secret
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSecret Secret
Secret.parse (ByteString -> io Secret) -> ByteString -> io Secret
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      (_, signatures) <- Either.throw . Signatures.parse $ Ascii.pack "v1,0000000000000000000000000000000000000000000="
      let actual = Secret
-> Message
-> Signatures
-> Either VerificationException SymmetricSignature
Verifier.symmetric Secret
secret Message
message Signatures
signatures
      Test.assertEq test actual (Left (VerificationException.MkVerificationException $ Message.id_ message))