-- | -- Module : Crypto.Saltine.Core.OneTimeAuth -- Copyright : (c) Joseph Abrahamson 2013 -- License : MIT -- -- Maintainer : me@jspha.com -- Stability : experimental -- Portability : non-portable -- -- Secret-key single-message authentication: -- "Crypto.Saltine.Core.OneTimeAuth" -- -- The 'auth' function authenticates a message 'ByteString' using a -- secret key The function returns an authenticator. The 'verify' -- function checks if it's passed a correct authenticator of a message -- under the given secret key. -- -- The 'auth' function, viewed as a function of the message for a -- uniform random key, is designed to meet the standard notion of -- unforgeability after a single message. After the sender -- authenticates one message, an attacker cannot find authenticators -- for any other messages. -- -- The sender must not use 'auth' to authenticate more than one -- message under the same key. Authenticators for two messages under -- the same key should be expected to reveal enough information to -- allow forgeries of authenticators on other messages. -- -- "Crypto.Saltine.Core.OneTimeAuth" is -- @crypto_onetimeauth_poly1305@, an authenticator specified in -- "Cryptography in NaCl" (), Section -- 9. This authenticator is proven to meet the standard notion of -- unforgeability after a single message. -- -- This is version 2010.08.30 of the onetimeauth.html web page. module Crypto.Saltine.Core.OneTimeAuth ( Key, Authenticator, newKey, auth, verify ) where import Crypto.Saltine.Internal.OneTimeAuth ( c_onetimeauth , c_onetimeauth_verify , Key(..) , Authenticator(..) ) import Crypto.Saltine.Internal.Util as U import Data.ByteString (ByteString) import qualified Crypto.Saltine.Internal.OneTimeAuth as Bytes import qualified Data.ByteString as S -- | Creates a random key of the correct size for 'auth' and 'verify'. newKey :: IO Key newKey = Key <$> randomByteString Bytes.onetimeauth_keybytes -- | Builds a keyed 'Authenticator' for a message. This -- 'Authenticator' is /impossible/ to forge so long as the 'Key' is -- never used twice. auth :: Key -> ByteString -- ^ Message -> Authenticator auth (Key key) msg = Au . snd . buildUnsafeByteString Bytes.onetimeauth_bytes $ \pa -> constByteStrings [key, msg] $ \[(pk, _), (pm, _)] -> c_onetimeauth pa pm (fromIntegral $ S.length msg) pk -- | Verifies that an 'Authenticator' matches a given message and key. verify :: Key -> Authenticator -> ByteString -- ^ Message -> Bool -- ^ Is this message authentic? verify (Key key) (Au a) msg = unsafeDidSucceed $ constByteStrings [key, msg, a] $ \ [(pk, _), (pm, _), (pa, _)] -> return $ c_onetimeauth_verify pa pm (fromIntegral $ S.length msg) pk