module Signet.Unstable.Type.SignatureTest where import qualified Crypto.Error as Error import qualified Crypto.Hash as Hash import qualified Crypto.PubKey.Ed25519 as Ed25519 import qualified Data.ByteString as ByteString import qualified Data.ByteString.Char8 as Ascii import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature import qualified Signet.Unstable.Extra.Tasty as Tasty import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature import qualified Signet.Unstable.Type.Signature as Signature import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature import qualified Signet.Unstable.Type.UnknownSignature as UnknownSignature import Test.Tasty.HUnit ((@?=)) spec :: Tasty.Spec spec :: Spec spec = TestName -> Spec -> Spec Tasty.describe TestName "Signet.Unstable.Type.Signature" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do TestName -> Spec -> Spec Tasty.describe TestName "parse" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do TestName -> Assertion -> Spec Tasty.it TestName "fails with invalid asymmetric signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "invalid" let result :: Either InvalidSignature (Either UnknownSignature Signature) result = ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse (ByteString -> Either InvalidSignature (Either UnknownSignature Signature)) -> ByteString -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. (a -> b) -> a -> b $ TestName -> ByteString Ascii.pack TestName "v1a," ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> ByteString byteString Either InvalidSignature (Either UnknownSignature Signature) result Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= InvalidSignature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. a -> Either a b Left (InvalidAsymmetricSignature -> InvalidSignature InvalidSignature.InvalidAsymmetricSignature (InvalidAsymmetricSignature -> InvalidSignature) -> InvalidAsymmetricSignature -> InvalidSignature forall a b. (a -> b) -> a -> b $ ByteString -> InvalidAsymmetricSignature InvalidAsymmetricSignature.MkInvalidAsymmetricSignature ByteString byteString) TestName -> Assertion -> Spec Tasty.it TestName "fails with invalid symmetric signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "invalid" let result :: Either InvalidSignature (Either UnknownSignature Signature) result = ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse (ByteString -> Either InvalidSignature (Either UnknownSignature Signature)) -> ByteString -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. (a -> b) -> a -> b $ TestName -> ByteString Ascii.pack TestName "v1," ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> ByteString byteString Either InvalidSignature (Either UnknownSignature Signature) result Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= InvalidSignature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. a -> Either a b Left (InvalidSymmetricSignature -> InvalidSignature InvalidSignature.InvalidSymmetricSignature (InvalidSymmetricSignature -> InvalidSignature) -> InvalidSymmetricSignature -> InvalidSignature forall a b. (a -> b) -> a -> b $ ByteString -> InvalidSymmetricSignature InvalidSymmetricSignature.MkInvalidSymmetricSignature ByteString byteString) TestName -> Assertion -> Spec Tasty.it TestName "returns unknown signature with unrecognized prefix" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "unknown" let result :: Either InvalidSignature (Either UnknownSignature Signature) result = ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse ByteString byteString Either InvalidSignature (Either UnknownSignature Signature) result Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= Either UnknownSignature Signature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. b -> Either a b Right (UnknownSignature -> Either UnknownSignature Signature forall a b. a -> Either a b Left (UnknownSignature -> Either UnknownSignature Signature) -> UnknownSignature -> Either UnknownSignature Signature forall a b. (a -> b) -> a -> b $ ByteString -> UnknownSignature UnknownSignature.MkUnknownSignature ByteString byteString) TestName -> Assertion -> Spec Tasty.it TestName "succeeds with valid asymmetric signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==" Signature signature <- (Signature -> Signature) -> IO Signature -> IO Signature forall a b. (a -> b) -> IO a -> IO b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (AsymmetricSignature -> Signature Signature.Asymmetric (AsymmetricSignature -> Signature) -> (Signature -> AsymmetricSignature) -> Signature -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Signature -> AsymmetricSignature AsymmetricSignature.MkAsymmetricSignature) (IO Signature -> IO Signature) -> (ByteString -> IO Signature) -> ByteString -> IO Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . CryptoFailable Signature -> IO Signature forall a. CryptoFailable a -> IO a Error.throwCryptoErrorIO (CryptoFailable Signature -> IO Signature) -> (ByteString -> CryptoFailable Signature) -> ByteString -> IO Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> CryptoFailable Signature forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature Ed25519.signature (ByteString -> IO Signature) -> ByteString -> IO Signature forall a b. (a -> b) -> a -> b $ TestName -> ByteString Ascii.pack TestName "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz" ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse ByteString byteString Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= Either UnknownSignature Signature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. b -> Either a b Right (Signature -> Either UnknownSignature Signature forall a b. b -> Either a b Right Signature signature) TestName -> Assertion -> Spec Tasty.it TestName "succeeds with valid symmetric signature" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = TestName -> ByteString Ascii.pack TestName "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" let signature :: Signature signature = SymmetricSignature -> Signature Signature.Symmetric (SymmetricSignature -> Signature) -> (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> Signature) -> Digest SHA256 -> Signature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty ByteString -> Either InvalidSignature (Either UnknownSignature Signature) Signature.parse ByteString byteString Either InvalidSignature (Either UnknownSignature Signature) -> Either InvalidSignature (Either UnknownSignature Signature) -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= Either UnknownSignature Signature -> Either InvalidSignature (Either UnknownSignature Signature) forall a b. b -> Either a b Right (Signature -> Either UnknownSignature Signature forall a b. b -> Either a b Right Signature signature) TestName -> Spec -> Spec Tasty.describe TestName "render" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do TestName -> Assertion -> Spec Tasty.it TestName "renders asymmetric signature correctly" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do Signature signature <- (Signature -> Signature) -> IO Signature -> IO Signature forall a b. (a -> b) -> IO a -> IO b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (AsymmetricSignature -> Signature Signature.Asymmetric (AsymmetricSignature -> Signature) -> (Signature -> AsymmetricSignature) -> Signature -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Signature -> AsymmetricSignature AsymmetricSignature.MkAsymmetricSignature) (IO Signature -> IO Signature) -> (ByteString -> IO Signature) -> ByteString -> IO Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . CryptoFailable Signature -> IO Signature forall a. CryptoFailable a -> IO a Error.throwCryptoErrorIO (CryptoFailable Signature -> IO Signature) -> (ByteString -> CryptoFailable Signature) -> ByteString -> IO Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> CryptoFailable Signature forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature Ed25519.signature (ByteString -> IO Signature) -> ByteString -> IO Signature forall a b. (a -> b) -> a -> b $ TestName -> ByteString Ascii.pack TestName "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz" Signature -> ByteString Signature.render Signature signature ByteString -> ByteString -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= TestName -> ByteString Ascii.pack TestName "v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==" TestName -> Assertion -> Spec Tasty.it TestName "renders symmetric signature correctly" (Assertion -> Spec) -> Assertion -> Spec forall a b. (a -> b) -> a -> b $ do let signature :: Signature signature = SymmetricSignature -> Signature Signature.Symmetric (SymmetricSignature -> Signature) -> (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> Signature) -> Digest SHA256 -> Signature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty Signature -> ByteString Signature.render Signature signature ByteString -> ByteString -> Assertion forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion @?= TestName -> ByteString Ascii.pack TestName "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="