module Botan.OneTimeAuth.Poly1305
( Poly1305(..)
, Poly1305OneTimeAuthKey(..)
, Poly1305OneTimeAuthNonce(..)
, Poly1305OneTimeAuthCode(..)
, poly1305OneTimeAuth
-- , poly1305AuthOneTimeAuthLazy
) where

import Data.Maybe

import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Lazy as Lazy
import qualified Data.Text as Text

import qualified Botan.MAC as Botan
import qualified Botan.Utility as Botan

import Botan.OneTimeAuth.Class
import Botan.Prelude

-- Poly1305 type

data Poly1305

newtype instance OneTimeAuthKey Poly1305 = Poly1305OneTimeAuthKey
    { OneTimeAuthKey Poly1305 -> ByteString
getPoly1305OneTimeAuthKey :: ByteString {- ByteVector n -} }
    deriving newtype (OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
(OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool)
-> (OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool)
-> Eq (OneTimeAuthKey Poly1305)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
== :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
$c/= :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
/= :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
Eq, Eq (OneTimeAuthKey Poly1305)
Eq (OneTimeAuthKey Poly1305) =>
(OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Ordering)
-> (OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool)
-> (OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool)
-> (OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool)
-> (OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool)
-> (OneTimeAuthKey Poly1305
    -> OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305)
-> (OneTimeAuthKey Poly1305
    -> OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305)
-> Ord (OneTimeAuthKey Poly1305)
OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Ordering
OneTimeAuthKey Poly1305
-> OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Ordering
compare :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Ordering
$c< :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
< :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
$c<= :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
<= :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
$c> :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
> :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
$c>= :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
>= :: OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305 -> Bool
$cmax :: OneTimeAuthKey Poly1305
-> OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305
max :: OneTimeAuthKey Poly1305
-> OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305
$cmin :: OneTimeAuthKey Poly1305
-> OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305
min :: OneTimeAuthKey Poly1305
-> OneTimeAuthKey Poly1305 -> OneTimeAuthKey Poly1305
Ord)

type Poly1305OneTimeAuthKey = OneTimeAuthKey Poly1305

-- NOTE: Poly1305 combines its nonce into a One-Time-Key, so we set its nonce type
-- to be a singleton, and thus the invariant that key+nonce be one time use makes
-- the key itself one-time use.
newtype instance OneTimeAuthNonce Poly1305 = Poly1305OneTimeAuthNonce
    ()
    deriving newtype (OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
(OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool)
-> (OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool)
-> Eq (OneTimeAuthNonce Poly1305)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
== :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
$c/= :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
/= :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
Eq, Eq (OneTimeAuthNonce Poly1305)
Eq (OneTimeAuthNonce Poly1305) =>
(OneTimeAuthNonce Poly1305
 -> OneTimeAuthNonce Poly1305 -> Ordering)
-> (OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool)
-> (OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool)
-> (OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool)
-> (OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool)
-> (OneTimeAuthNonce Poly1305
    -> OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305)
-> (OneTimeAuthNonce Poly1305
    -> OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305)
-> Ord (OneTimeAuthNonce Poly1305)
OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Ordering
OneTimeAuthNonce Poly1305
-> OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Ordering
compare :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Ordering
$c< :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
< :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
$c<= :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
<= :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
$c> :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
> :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
$c>= :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
>= :: OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305 -> Bool
$cmax :: OneTimeAuthNonce Poly1305
-> OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305
max :: OneTimeAuthNonce Poly1305
-> OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305
$cmin :: OneTimeAuthNonce Poly1305
-> OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305
min :: OneTimeAuthNonce Poly1305
-> OneTimeAuthNonce Poly1305 -> OneTimeAuthNonce Poly1305
Ord)

type Poly1305OneTimeAuthNonce = OneTimeAuthNonce Poly1305

newtype instance OneTimeAuthCode Poly1305 = Poly1305OneTimeAuthCode
    { OneTimeAuthCode Poly1305 -> ByteString
getPoly1305OneTimeAuthCode :: ByteString {- ByteVector n -} }
    deriving newtype (OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
(OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool)
-> (OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool)
-> Eq (OneTimeAuthCode Poly1305)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
== :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
$c/= :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
/= :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
Eq, Eq (OneTimeAuthCode Poly1305)
Eq (OneTimeAuthCode Poly1305) =>
(OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Ordering)
-> (OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool)
-> (OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool)
-> (OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool)
-> (OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool)
-> (OneTimeAuthCode Poly1305
    -> OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305)
-> (OneTimeAuthCode Poly1305
    -> OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305)
-> Ord (OneTimeAuthCode Poly1305)
OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Ordering
OneTimeAuthCode Poly1305
-> OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Ordering
compare :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Ordering
$c< :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
< :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
$c<= :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
<= :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
$c> :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
> :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
$c>= :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
>= :: OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305 -> Bool
$cmax :: OneTimeAuthCode Poly1305
-> OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305
max :: OneTimeAuthCode Poly1305
-> OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305
$cmin :: OneTimeAuthCode Poly1305
-> OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305
min :: OneTimeAuthCode Poly1305
-> OneTimeAuthCode Poly1305 -> OneTimeAuthCode Poly1305
Ord)

type Poly1305OneTimeAuthCode = OneTimeAuthCode Poly1305

instance OneTimeAuth Poly1305 where

    -- mkOneTimeAuthCode = Poly1305OneTimeAuthCode

    oneTimeAuth :: OneTimeAuthKey Poly1305 -> OneTimeAuthNonce Poly1305 -> ByteString -> OneTimeAuthCode Poly1305
    oneTimeAuth :: OneTimeAuthKey Poly1305
-> OneTimeAuthNonce Poly1305
-> ByteString
-> OneTimeAuthCode Poly1305
oneTimeAuth (Poly1305OneTimeAuthKey ByteString
k) (Poly1305OneTimeAuthNonce ()
_) = ByteString -> OneTimeAuthCode Poly1305
Poly1305OneTimeAuthCode (ByteString -> OneTimeAuthCode Poly1305)
-> (ByteString -> ByteString)
-> ByteString
-> OneTimeAuthCode Poly1305
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe ByteString -> ByteString
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe ByteString -> ByteString)
-> (ByteString -> Maybe ByteString) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MAC -> ByteString -> ByteString -> Maybe ByteString
Botan.mac MAC
Botan.poly1305 ByteString
k

instance IncrementalOneTimeAuth Poly1305 where

    -- mkIncrementalOneTimeAuthCode = Poly1305IncrementalOneTimeAuthCode
    -- fromIncremental (Poly1305IncrementalOneTimeAuthCode ct) = Poly1305OneTimeAuthCode $ ByteString.toStrict ct
    -- toIncremental (Poly1305OneTimeAuthCode ct) = Poly1305IncrementalOneTimeAuthCode $ ByteString.fromStrict ct

    oneTimeAuthLazy :: OneTimeAuthKey Poly1305 -> OneTimeAuthNonce Poly1305 -> Lazy.ByteString -> OneTimeAuthCode Poly1305
    oneTimeAuthLazy :: OneTimeAuthKey Poly1305
-> OneTimeAuthNonce Poly1305
-> ByteString
-> OneTimeAuthCode Poly1305
oneTimeAuthLazy (Poly1305OneTimeAuthKey ByteString
k) (Poly1305OneTimeAuthNonce ()
_) = ByteString -> OneTimeAuthCode Poly1305
Poly1305OneTimeAuthCode (ByteString -> OneTimeAuthCode Poly1305)
-> (ByteString -> ByteString)
-> ByteString
-> OneTimeAuthCode Poly1305
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe ByteString -> ByteString
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe ByteString -> ByteString)
-> (ByteString -> Maybe ByteString) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MAC -> ByteString -> ByteString -> Maybe ByteString
Botan.macLazy MAC
Botan.poly1305 ByteString
k

-- Poly1305 One Time Auth

poly1305OneTimeAuth :: OneTimeAuthKey Poly1305 -> OneTimeAuthNonce Poly1305 -> ByteString -> Poly1305OneTimeAuthCode
poly1305OneTimeAuth :: OneTimeAuthKey Poly1305
-> OneTimeAuthNonce Poly1305
-> ByteString
-> OneTimeAuthCode Poly1305
poly1305OneTimeAuth = OneTimeAuthKey Poly1305
-> OneTimeAuthNonce Poly1305
-> ByteString
-> OneTimeAuthCode Poly1305
forall ota.
OneTimeAuth ota =>
OneTimeAuthKey ota
-> OneTimeAuthNonce ota -> ByteString -> OneTimeAuthCode ota
oneTimeAuth