File: Blake2.hs

package info (click to toggle)
haskell-cryptonite 0.29-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,368 kB
  • sloc: ansic: 22,009; haskell: 18,416; makefile: 8
file content (162 lines) | stat: -rw-r--r-- 6,659 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
-- |
-- Module      : Crypto.Hash.Blake2
-- License     : BSD-style
-- Maintainer  : Nicolas Di Prima <nicolas@primetype.co.uk>
-- Stability   : experimental
-- Portability : unknown
--
-- Module containing the binding functions to work with the
-- Blake2
--
-- Implementation based from [RFC7693](https://tools.ietf.org/html/rfc7693)
--
-- Please consider the following when chosing a hash:
--
--      Algorithm     | Target | Collision | Digest Size |
--         Identifier |  Arch  |  Security |   in bytes  |
--     ---------------+--------+-----------+-------------+
--      id-blake2b160 | 64-bit |   2**80   |         20  |
--      id-blake2b256 | 64-bit |   2**128  |         32  |
--      id-blake2b384 | 64-bit |   2**192  |         48  |
--      id-blake2b512 | 64-bit |   2**256  |         64  |
--     ---------------+--------+-----------+-------------+
--      id-blake2s128 | 32-bit |   2**64   |         16  |
--      id-blake2s160 | 32-bit |   2**80   |         20  |
--      id-blake2s224 | 32-bit |   2**112  |         28  |
--      id-blake2s256 | 32-bit |   2**128  |         32  |
--     ---------------+--------+-----------+-------------+
--
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
module Crypto.Hash.Blake2
    ( Blake2s(..)
    , Blake2sp(..)
    , Blake2b(..)
    , Blake2bp(..)
    ) where

import           Crypto.Hash.Types
import           Foreign.Ptr (Ptr)
import           Data.Data
import           Data.Word (Word8, Word32)
import           GHC.TypeLits (Nat, KnownNat)
import           Crypto.Internal.Nat

-- | Fast and secure alternative to SHA1 and HMAC-SHA1
--
-- It is espacially known to target 32bits architectures.
--
-- Known supported digest sizes:
--
-- * Blake2s 160
-- * Blake2s 224
-- * Blake2s 256
--
data Blake2s (bitlen :: Nat) = Blake2s
    deriving (Show,Data)

instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256)
      => HashAlgorithm (Blake2s bitlen)
      where
    type HashBlockSize           (Blake2s bitlen) = 64
    type HashDigestSize          (Blake2s bitlen) = Div8 bitlen
    type HashInternalContextSize (Blake2s bitlen) = 136
    hashBlockSize  _          = 64
    hashDigestSize _          = byteLen (Proxy :: Proxy bitlen)
    hashInternalContextSize _ = 136
    hashInternalInit p        = c_blake2s_init p (integralNatVal (Proxy :: Proxy bitlen))
    hashInternalUpdate        = c_blake2s_update
    hashInternalFinalize p    = c_blake2s_finalize p (integralNatVal (Proxy :: Proxy bitlen))

foreign import ccall unsafe "cryptonite_blake2s_init"
    c_blake2s_init :: Ptr (Context a) -> Word32 -> IO ()
foreign import ccall "cryptonite_blake2s_update"
    c_blake2s_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_blake2s_finalize"
    c_blake2s_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()

-- | Fast cryptographic hash.
--
-- It is especially known to target 64bits architectures.
--
-- Known supported digest sizes:
--
-- * Blake2b 160
-- * Blake2b 224
-- * Blake2b 256
-- * Blake2b 384
-- * Blake2b 512
--
data Blake2b (bitlen :: Nat) = Blake2b
    deriving (Show,Data)

instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512)
      => HashAlgorithm (Blake2b bitlen)
      where
    type HashBlockSize           (Blake2b bitlen) = 128
    type HashDigestSize          (Blake2b bitlen) = Div8 bitlen
    type HashInternalContextSize (Blake2b bitlen) = 248
    hashBlockSize  _          = 128
    hashDigestSize _          = byteLen (Proxy :: Proxy bitlen)
    hashInternalContextSize _ = 248
    hashInternalInit p        = c_blake2b_init p (integralNatVal (Proxy :: Proxy bitlen))
    hashInternalUpdate        = c_blake2b_update
    hashInternalFinalize p    = c_blake2b_finalize p (integralNatVal (Proxy :: Proxy bitlen))

foreign import ccall unsafe "cryptonite_blake2b_init"
    c_blake2b_init :: Ptr (Context a) -> Word32 -> IO ()
foreign import ccall "cryptonite_blake2b_update"
    c_blake2b_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_blake2b_finalize"
    c_blake2b_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()

data Blake2sp (bitlen :: Nat) = Blake2sp
    deriving (Show,Data)

instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256)
      => HashAlgorithm (Blake2sp bitlen)
      where
    type HashBlockSize           (Blake2sp bitlen) = 64
    type HashDigestSize          (Blake2sp bitlen) = Div8 bitlen
    type HashInternalContextSize (Blake2sp bitlen) = 2185
    hashBlockSize  _          = 64
    hashDigestSize _          = byteLen (Proxy :: Proxy bitlen)
    hashInternalContextSize _ = 2185
    hashInternalInit p        = c_blake2sp_init p (integralNatVal (Proxy :: Proxy bitlen))
    hashInternalUpdate        = c_blake2sp_update
    hashInternalFinalize p    = c_blake2sp_finalize p (integralNatVal (Proxy :: Proxy bitlen))

foreign import ccall unsafe "cryptonite_blake2sp_init"
    c_blake2sp_init :: Ptr (Context a) -> Word32 -> IO ()
foreign import ccall "cryptonite_blake2sp_update"
    c_blake2sp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_blake2sp_finalize"
    c_blake2sp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()

data Blake2bp (bitlen :: Nat) = Blake2bp
    deriving (Show,Data)

instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512)
      => HashAlgorithm (Blake2bp bitlen)
      where
    type HashBlockSize           (Blake2bp bitlen) = 128
    type HashDigestSize          (Blake2bp bitlen) = Div8 bitlen
    type HashInternalContextSize (Blake2bp bitlen) = 2325
    hashBlockSize  _          = 128
    hashDigestSize _          = byteLen (Proxy :: Proxy bitlen)
    hashInternalContextSize _ = 2325
    hashInternalInit p        = c_blake2bp_init p (integralNatVal (Proxy :: Proxy bitlen))
    hashInternalUpdate        = c_blake2bp_update
    hashInternalFinalize p    = c_blake2bp_finalize p (integralNatVal (Proxy :: Proxy bitlen))


foreign import ccall unsafe "cryptonite_blake2bp_init"
    c_blake2bp_init :: Ptr (Context a) -> Word32 -> IO ()
foreign import ccall "cryptonite_blake2bp_update"
    c_blake2bp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_blake2bp_finalize"
    c_blake2bp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()