{-# LANGUAGE OverloadedStrings #-}
module Crypto.G3P where
import Control.Exception(assert)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Function((&))
import Data.Word
import Data.Stream (Stream(..))
import Data.Vector (Vector)
import qualified Data.Vector as V
import Network.ByteOrder (word32)
import Crypto.Encoding.PHKDF
( add64WhileLt
, cycleByteString
, cycleByteStringWithNull
, usernamePadding
, passwordPaddingBytes
, credentialsPadding
)
import Crypto.Encoding.SHA3.TupleHash
import Crypto.PHKDF.Primitives
import Crypto.PHKDF.Primitives.Assert
import Crypto.G3P.BCrypt
data G3PInputBlock = G3PInputBlock
{ G3PInputBlock -> ByteString
g3pInputBlock_seguid :: !ByteString
, G3PInputBlock -> ByteString
g3pInputBlock_domainTag :: !ByteString
, G3PInputBlock -> ByteString
g3pInputBlock_longTag :: !ByteString
, G3PInputBlock -> Vector ByteString
g3pInputBlock_tags :: !(Vector ByteString)
, G3PInputBlock -> Word32
g3pInputBlock_phkdfRounds :: !Word32
, G3PInputBlock -> Word32
g3pInputBlock_bcryptRounds :: !Word32
, G3PInputBlock -> ByteString
g3pInputBlock_bcryptTag :: !ByteString
} deriving (G3PInputBlock -> G3PInputBlock -> Bool
(G3PInputBlock -> G3PInputBlock -> Bool)
-> (G3PInputBlock -> G3PInputBlock -> Bool) -> Eq G3PInputBlock
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: G3PInputBlock -> G3PInputBlock -> Bool
== :: G3PInputBlock -> G3PInputBlock -> Bool
$c/= :: G3PInputBlock -> G3PInputBlock -> Bool
/= :: G3PInputBlock -> G3PInputBlock -> Bool
Eq, Eq G3PInputBlock
Eq G3PInputBlock =>
(G3PInputBlock -> G3PInputBlock -> Ordering)
-> (G3PInputBlock -> G3PInputBlock -> Bool)
-> (G3PInputBlock -> G3PInputBlock -> Bool)
-> (G3PInputBlock -> G3PInputBlock -> Bool)
-> (G3PInputBlock -> G3PInputBlock -> Bool)
-> (G3PInputBlock -> G3PInputBlock -> G3PInputBlock)
-> (G3PInputBlock -> G3PInputBlock -> G3PInputBlock)
-> Ord G3PInputBlock
G3PInputBlock -> G3PInputBlock -> Bool
G3PInputBlock -> G3PInputBlock -> Ordering
G3PInputBlock -> G3PInputBlock -> G3PInputBlock
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 :: G3PInputBlock -> G3PInputBlock -> Ordering
compare :: G3PInputBlock -> G3PInputBlock -> Ordering
$c< :: G3PInputBlock -> G3PInputBlock -> Bool
< :: G3PInputBlock -> G3PInputBlock -> Bool
$c<= :: G3PInputBlock -> G3PInputBlock -> Bool
<= :: G3PInputBlock -> G3PInputBlock -> Bool
$c> :: G3PInputBlock -> G3PInputBlock -> Bool
> :: G3PInputBlock -> G3PInputBlock -> Bool
$c>= :: G3PInputBlock -> G3PInputBlock -> Bool
>= :: G3PInputBlock -> G3PInputBlock -> Bool
$cmax :: G3PInputBlock -> G3PInputBlock -> G3PInputBlock
max :: G3PInputBlock -> G3PInputBlock -> G3PInputBlock
$cmin :: G3PInputBlock -> G3PInputBlock -> G3PInputBlock
min :: G3PInputBlock -> G3PInputBlock -> G3PInputBlock
Ord, Int -> G3PInputBlock -> ShowS
[G3PInputBlock] -> ShowS
G3PInputBlock -> String
(Int -> G3PInputBlock -> ShowS)
-> (G3PInputBlock -> String)
-> ([G3PInputBlock] -> ShowS)
-> Show G3PInputBlock
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> G3PInputBlock -> ShowS
showsPrec :: Int -> G3PInputBlock -> ShowS
$cshow :: G3PInputBlock -> String
show :: G3PInputBlock -> String
$cshowList :: [G3PInputBlock] -> ShowS
showList :: [G3PInputBlock] -> ShowS
Show)
data G3PInputArgs = G3PInputArgs
{ G3PInputArgs -> ByteString
g3pInputArgs_username :: !ByteString
, G3PInputArgs -> ByteString
g3pInputArgs_password :: !ByteString
, G3PInputArgs -> Vector ByteString
g3pInputArgs_credentials :: !(Vector ByteString)
} deriving (G3PInputArgs -> G3PInputArgs -> Bool
(G3PInputArgs -> G3PInputArgs -> Bool)
-> (G3PInputArgs -> G3PInputArgs -> Bool) -> Eq G3PInputArgs
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: G3PInputArgs -> G3PInputArgs -> Bool
== :: G3PInputArgs -> G3PInputArgs -> Bool
$c/= :: G3PInputArgs -> G3PInputArgs -> Bool
/= :: G3PInputArgs -> G3PInputArgs -> Bool
Eq, Eq G3PInputArgs
Eq G3PInputArgs =>
(G3PInputArgs -> G3PInputArgs -> Ordering)
-> (G3PInputArgs -> G3PInputArgs -> Bool)
-> (G3PInputArgs -> G3PInputArgs -> Bool)
-> (G3PInputArgs -> G3PInputArgs -> Bool)
-> (G3PInputArgs -> G3PInputArgs -> Bool)
-> (G3PInputArgs -> G3PInputArgs -> G3PInputArgs)
-> (G3PInputArgs -> G3PInputArgs -> G3PInputArgs)
-> Ord G3PInputArgs
G3PInputArgs -> G3PInputArgs -> Bool
G3PInputArgs -> G3PInputArgs -> Ordering
G3PInputArgs -> G3PInputArgs -> G3PInputArgs
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 :: G3PInputArgs -> G3PInputArgs -> Ordering
compare :: G3PInputArgs -> G3PInputArgs -> Ordering
$c< :: G3PInputArgs -> G3PInputArgs -> Bool
< :: G3PInputArgs -> G3PInputArgs -> Bool
$c<= :: G3PInputArgs -> G3PInputArgs -> Bool
<= :: G3PInputArgs -> G3PInputArgs -> Bool
$c> :: G3PInputArgs -> G3PInputArgs -> Bool
> :: G3PInputArgs -> G3PInputArgs -> Bool
$c>= :: G3PInputArgs -> G3PInputArgs -> Bool
>= :: G3PInputArgs -> G3PInputArgs -> Bool
$cmax :: G3PInputArgs -> G3PInputArgs -> G3PInputArgs
max :: G3PInputArgs -> G3PInputArgs -> G3PInputArgs
$cmin :: G3PInputArgs -> G3PInputArgs -> G3PInputArgs
min :: G3PInputArgs -> G3PInputArgs -> G3PInputArgs
Ord, Int -> G3PInputArgs -> ShowS
[G3PInputArgs] -> ShowS
G3PInputArgs -> String
(Int -> G3PInputArgs -> ShowS)
-> (G3PInputArgs -> String)
-> ([G3PInputArgs] -> ShowS)
-> Show G3PInputArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> G3PInputArgs -> ShowS
showsPrec :: Int -> G3PInputArgs -> ShowS
$cshow :: G3PInputArgs -> String
show :: G3PInputArgs -> String
$cshowList :: [G3PInputArgs] -> ShowS
showList :: [G3PInputArgs] -> ShowS
Show)
newtype G3PInputRole = G3PInputRole
{ G3PInputRole -> Vector ByteString
g3pInputRole_roleTags :: Vector ByteString
} deriving (G3PInputRole -> G3PInputRole -> Bool
(G3PInputRole -> G3PInputRole -> Bool)
-> (G3PInputRole -> G3PInputRole -> Bool) -> Eq G3PInputRole
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: G3PInputRole -> G3PInputRole -> Bool
== :: G3PInputRole -> G3PInputRole -> Bool
$c/= :: G3PInputRole -> G3PInputRole -> Bool
/= :: G3PInputRole -> G3PInputRole -> Bool
Eq, Eq G3PInputRole
Eq G3PInputRole =>
(G3PInputRole -> G3PInputRole -> Ordering)
-> (G3PInputRole -> G3PInputRole -> Bool)
-> (G3PInputRole -> G3PInputRole -> Bool)
-> (G3PInputRole -> G3PInputRole -> Bool)
-> (G3PInputRole -> G3PInputRole -> Bool)
-> (G3PInputRole -> G3PInputRole -> G3PInputRole)
-> (G3PInputRole -> G3PInputRole -> G3PInputRole)
-> Ord G3PInputRole
G3PInputRole -> G3PInputRole -> Bool
G3PInputRole -> G3PInputRole -> Ordering
G3PInputRole -> G3PInputRole -> G3PInputRole
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 :: G3PInputRole -> G3PInputRole -> Ordering
compare :: G3PInputRole -> G3PInputRole -> Ordering
$c< :: G3PInputRole -> G3PInputRole -> Bool
< :: G3PInputRole -> G3PInputRole -> Bool
$c<= :: G3PInputRole -> G3PInputRole -> Bool
<= :: G3PInputRole -> G3PInputRole -> Bool
$c> :: G3PInputRole -> G3PInputRole -> Bool
> :: G3PInputRole -> G3PInputRole -> Bool
$c>= :: G3PInputRole -> G3PInputRole -> Bool
>= :: G3PInputRole -> G3PInputRole -> Bool
$cmax :: G3PInputRole -> G3PInputRole -> G3PInputRole
max :: G3PInputRole -> G3PInputRole -> G3PInputRole
$cmin :: G3PInputRole -> G3PInputRole -> G3PInputRole
min :: G3PInputRole -> G3PInputRole -> G3PInputRole
Ord, Int -> G3PInputRole -> ShowS
[G3PInputRole] -> ShowS
G3PInputRole -> String
(Int -> G3PInputRole -> ShowS)
-> (G3PInputRole -> String)
-> ([G3PInputRole] -> ShowS)
-> Show G3PInputRole
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> G3PInputRole -> ShowS
showsPrec :: Int -> G3PInputRole -> ShowS
$cshow :: G3PInputRole -> String
show :: G3PInputRole -> String
$cshowList :: [G3PInputRole] -> ShowS
showList :: [G3PInputRole] -> ShowS
Show)
newtype G3PInputEcho = G3PInputEcho
{ G3PInputEcho -> ByteString
g3pInputEcho_echoTag :: ByteString
} deriving (G3PInputEcho -> G3PInputEcho -> Bool
(G3PInputEcho -> G3PInputEcho -> Bool)
-> (G3PInputEcho -> G3PInputEcho -> Bool) -> Eq G3PInputEcho
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: G3PInputEcho -> G3PInputEcho -> Bool
== :: G3PInputEcho -> G3PInputEcho -> Bool
$c/= :: G3PInputEcho -> G3PInputEcho -> Bool
/= :: G3PInputEcho -> G3PInputEcho -> Bool
Eq, Eq G3PInputEcho
Eq G3PInputEcho =>
(G3PInputEcho -> G3PInputEcho -> Ordering)
-> (G3PInputEcho -> G3PInputEcho -> Bool)
-> (G3PInputEcho -> G3PInputEcho -> Bool)
-> (G3PInputEcho -> G3PInputEcho -> Bool)
-> (G3PInputEcho -> G3PInputEcho -> Bool)
-> (G3PInputEcho -> G3PInputEcho -> G3PInputEcho)
-> (G3PInputEcho -> G3PInputEcho -> G3PInputEcho)
-> Ord G3PInputEcho
G3PInputEcho -> G3PInputEcho -> Bool
G3PInputEcho -> G3PInputEcho -> Ordering
G3PInputEcho -> G3PInputEcho -> G3PInputEcho
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 :: G3PInputEcho -> G3PInputEcho -> Ordering
compare :: G3PInputEcho -> G3PInputEcho -> Ordering
$c< :: G3PInputEcho -> G3PInputEcho -> Bool
< :: G3PInputEcho -> G3PInputEcho -> Bool
$c<= :: G3PInputEcho -> G3PInputEcho -> Bool
<= :: G3PInputEcho -> G3PInputEcho -> Bool
$c> :: G3PInputEcho -> G3PInputEcho -> Bool
> :: G3PInputEcho -> G3PInputEcho -> Bool
$c>= :: G3PInputEcho -> G3PInputEcho -> Bool
>= :: G3PInputEcho -> G3PInputEcho -> Bool
$cmax :: G3PInputEcho -> G3PInputEcho -> G3PInputEcho
max :: G3PInputEcho -> G3PInputEcho -> G3PInputEcho
$cmin :: G3PInputEcho -> G3PInputEcho -> G3PInputEcho
min :: G3PInputEcho -> G3PInputEcho -> G3PInputEcho
Ord, Int -> G3PInputEcho -> ShowS
[G3PInputEcho] -> ShowS
G3PInputEcho -> String
(Int -> G3PInputEcho -> ShowS)
-> (G3PInputEcho -> String)
-> ([G3PInputEcho] -> ShowS)
-> Show G3PInputEcho
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> G3PInputEcho -> ShowS
showsPrec :: Int -> G3PInputEcho -> ShowS
$cshow :: G3PInputEcho -> String
show :: G3PInputEcho -> String
$cshowList :: [G3PInputEcho] -> ShowS
showList :: [G3PInputEcho] -> ShowS
Show)
data G3PSeed = G3PSeed
{ G3PSeed -> ByteString
g3pSeed_seguid :: !ByteString
, G3PSeed -> HmacKey
g3pSeed_seguidKey :: !HmacKey
, G3PSeed -> ByteString
g3pSeed_domainTag :: !ByteString
, G3PSeed -> ByteString
g3pSeed_secret :: !ByteString
} deriving (G3PSeed -> G3PSeed -> Bool
(G3PSeed -> G3PSeed -> Bool)
-> (G3PSeed -> G3PSeed -> Bool) -> Eq G3PSeed
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: G3PSeed -> G3PSeed -> Bool
== :: G3PSeed -> G3PSeed -> Bool
$c/= :: G3PSeed -> G3PSeed -> Bool
/= :: G3PSeed -> G3PSeed -> Bool
Eq)
data G3PKey = G3PKey
{ G3PKey -> ByteString
g3pKey_secret :: !ByteString
, G3PKey -> HmacKey
g3pKey_secretKey :: HmacKey
, G3PKey -> ByteString
g3pKey_domainTag :: !ByteString
} deriving (G3PKey -> G3PKey -> Bool
(G3PKey -> G3PKey -> Bool)
-> (G3PKey -> G3PKey -> Bool) -> Eq G3PKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: G3PKey -> G3PKey -> Bool
== :: G3PKey -> G3PKey -> Bool
$c/= :: G3PKey -> G3PKey -> Bool
/= :: G3PKey -> G3PKey -> Bool
Eq)
data G3PGen = G3PGen
{ G3PGen -> ByteString
g3pGen_secret :: !ByteString
, G3PGen -> PhkdfGen
g3pGen_phkdfGen :: !PhkdfGen
}
g3pHash :: G3PInputBlock -> G3PInputArgs -> G3PInputRole -> G3PInputEcho -> Stream ByteString
g3pHash :: G3PInputBlock
-> G3PInputArgs
-> G3PInputRole
-> G3PInputEcho
-> Stream ByteString
g3pHash G3PInputBlock
block G3PInputArgs
args G3PInputRole
role G3PInputEcho
echoTag =
G3PInputBlock -> G3PInputArgs -> G3PSeed
g3pHash_seedInit G3PInputBlock
block G3PInputArgs
args G3PSeed -> (G3PSeed -> G3PKey) -> G3PKey
forall a b. a -> (a -> b) -> b
&
G3PInputRole -> G3PSeed -> G3PKey
g3pHash_keyInit G3PInputRole
role G3PKey -> (G3PKey -> G3PGen) -> G3PGen
forall a b. a -> (a -> b) -> b
&
G3PInputEcho -> G3PKey -> G3PGen
g3pHash_finalizeGen G3PInputEcho
echoTag G3PGen -> (G3PGen -> Stream ByteString) -> Stream ByteString
forall a b. a -> (a -> b) -> b
&
G3PGen -> Stream ByteString
g3pGen_finalizeStream
g3pHash_seedInit :: G3PInputBlock -> G3PInputArgs -> G3PSeed
g3pHash_seedInit :: G3PInputBlock -> G3PInputArgs -> G3PSeed
g3pHash_seedInit G3PInputBlock
block G3PInputArgs
args =
G3PSeed {
g3pSeed_seguid :: ByteString
g3pSeed_seguid = ByteString
seguid,
g3pSeed_seguidKey :: HmacKey
g3pSeed_seguidKey = HmacKey
seguidKey,
g3pSeed_domainTag :: ByteString
g3pSeed_domainTag = ByteString
domainTag,
g3pSeed_secret :: ByteString
g3pSeed_secret = ByteString
secret
}
where
domainTag :: ByteString
domainTag = G3PInputBlock -> ByteString
g3pInputBlock_domainTag G3PInputBlock
block
seguid :: ByteString
seguid = G3PInputBlock -> ByteString
g3pInputBlock_seguid G3PInputBlock
block
longTag :: ByteString
longTag = G3PInputBlock -> ByteString
g3pInputBlock_longTag G3PInputBlock
block
seedTags :: Vector ByteString
seedTags = G3PInputBlock -> Vector ByteString
g3pInputBlock_tags G3PInputBlock
block
phkdfRounds :: Word32
phkdfRounds = G3PInputBlock -> Word32
g3pInputBlock_phkdfRounds G3PInputBlock
block
bcryptRounds :: Word32
bcryptRounds = G3PInputBlock -> Word32
g3pInputBlock_bcryptRounds G3PInputBlock
block
bcryptTag :: ByteString
bcryptTag = G3PInputBlock -> ByteString
g3pInputBlock_bcryptTag G3PInputBlock
block
username :: ByteString
username = G3PInputArgs -> ByteString
g3pInputArgs_username G3PInputArgs
args
password :: ByteString
password = G3PInputArgs -> ByteString
g3pInputArgs_password G3PInputArgs
args
credentials :: Vector ByteString
credentials = G3PInputArgs -> Vector ByteString
g3pInputArgs_credentials G3PInputArgs
args
headerAlfa :: [ByteString]
headerAlfa = [ ByteString
"G3Pb1 alfa username", ByteString
username ]
headerUsername :: [ByteString]
headerUsername = [ByteString]
headerAlfa [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [
[ByteString] -> ByteString -> ByteString -> ByteString
forall (f :: * -> *).
Foldable f =>
f ByteString -> ByteString -> ByteString -> ByteString
usernamePadding [ByteString]
headerAlfa ByteString
bcryptTag
(ByteString
domainTag ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"\x00password G3Pb1\x00")
]
headerLongTag :: [ByteString]
headerLongTag =
[ ByteString
longTag
, [ByteString] -> ByteString
B.concat
[ ByteString
"Global Password Prehash Protocol bcrypt (v1) G3Pb1"
, Word32 -> ByteString
forall b. (Integral b, FiniteBits b) => b -> ByteString
leftEncode Word32
phkdfRounds
, Word32 -> ByteString
forall b. (Integral b, FiniteBits b) => b -> ByteString
bareEncode Word32
bcryptRounds
]
]
longPadding :: ByteString
longPadding = Int
-> [ByteString]
-> [ByteString]
-> ByteString
-> ByteString
-> ByteString
-> ByteString
forall (f :: * -> *).
Foldable f =>
Int
-> f ByteString
-> f ByteString
-> ByteString
-> ByteString
-> ByteString
-> ByteString
passwordPaddingBytes Int
bytes [ByteString]
headerUsername [ByteString]
headerLongTag
ByteString
longTag (ByteString
domainTag ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"\x00creds G3Pb1\x00") ByteString
password
where
bl :: Int
bl = ByteString -> Int
encodedByteLength ByteString
bcryptTag
bytes :: Int
bytes = Int -> Int -> Int
forall a. (Ord a, Num a, Bits a) => a -> a -> a
add64WhileLt (Int
8413 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
bl) Int
8298
credsPadding :: ByteString
credsPadding = Vector ByteString -> ByteString -> ByteString -> ByteString
forall (f :: * -> *).
Foldable f =>
f ByteString -> ByteString -> ByteString -> ByteString
credentialsPadding Vector ByteString
credentials ByteString
bcryptTag
(ByteString
domainTag ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"\x00tags G3Pb1\x00")
seguidKey :: HmacKey
seguidKey = ByteString -> HmacKey
hmacKey_init ByteString
seguid
secretStream :: Stream ByteString
secretStream =
HmacKey -> PhkdfCtx
phkdfCtx_initFromHmacKey HmacKey
seguidKey PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
[ByteString] -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArgs [ByteString]
headerUsername PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
Word64 -> PhkdfCtx -> PhkdfCtx
phkdfCtx_assertBufferPosition' Word64
32 PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArg ByteString
password PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArg ByteString
bcryptTag PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
[ByteString] -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArgs [ByteString]
headerLongTag PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArg ByteString
longPadding PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
Word64 -> PhkdfCtx -> PhkdfCtx
phkdfCtx_assertBufferPosition' Word64
32 PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
Vector ByteString -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArgs Vector ByteString
credentials PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArg ByteString
credsPadding PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
Word64 -> PhkdfCtx -> PhkdfCtx
phkdfCtx_assertBufferPosition' Word64
29 PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
Vector ByteString -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArgs Vector ByteString
seedTags PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArg (Int -> ByteString
forall b. (Integral b, FiniteBits b) => b -> ByteString
bareEncode (Vector ByteString -> Int
forall a. Vector a -> Int
V.length Vector ByteString
seedTags)) PhkdfCtx -> (PhkdfCtx -> PhkdfSlowCtx) -> PhkdfSlowCtx
forall a b. a -> (a -> b) -> b
&
(Int -> ByteString)
-> Word32
-> ByteString
-> ByteString
-> Word32
-> PhkdfCtx
-> PhkdfSlowCtx
phkdfSlowCtx_extract
(ByteString -> Int -> ByteString
cycleByteStringWithNull ByteString
bcryptTag)
(ByteString -> Word32
word32 ByteString
"go\x00\x00" Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
2024) ByteString
domainTag
ByteString
"G3Pb1 bravo" Word32
phkdfRounds PhkdfSlowCtx -> (PhkdfSlowCtx -> PhkdfSlowCtx) -> PhkdfSlowCtx
forall a b. a -> (a -> b) -> b
&
Word64 -> PhkdfSlowCtx -> PhkdfSlowCtx
phkdfSlowCtx_assertBufferPosition' Word64
32 PhkdfSlowCtx -> (PhkdfSlowCtx -> PhkdfSlowCtx) -> PhkdfSlowCtx
forall a b. a -> (a -> b) -> b
&
Vector ByteString -> PhkdfSlowCtx -> PhkdfSlowCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfSlowCtx -> PhkdfSlowCtx
phkdfSlowCtx_addArgs Vector ByteString
seedTags PhkdfSlowCtx
-> (PhkdfSlowCtx -> Stream ByteString) -> Stream ByteString
forall a b. a -> (a -> b) -> b
&
(Int -> ByteString) -> PhkdfSlowCtx -> Stream ByteString
phkdfSlowCtx_finalizeStream (ByteString -> Int -> ByteString
cycleByteStringWithNull ByteString
bcryptTag)
(Cons ByteString
phkdfHash (Cons ByteString
bcryptInput Stream ByteString
_)) = Stream ByteString
secretStream
dup :: b -> (b, b)
dup b
a = (b
a,b
a)
(ByteString
bKeyInput, ByteString
bSaltInput) = Int -> ByteString -> (ByteString, ByteString)
B.splitAt Int
16 ByteString
bcryptInput
(ByteString
bKeyTag, ByteString
bSaltTag) =
if ByteString -> Int
B.length ByteString
bcryptTag Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
56
then ByteString -> (ByteString, ByteString)
forall {b}. b -> (b, b)
dup (ByteString -> (ByteString, ByteString))
-> ByteString -> (ByteString, ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString -> Int -> ByteString
cycleByteString (ByteString
bcryptTag ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"\x00G3Pb1 bcrypt\00") Int
56
else Int -> ByteString -> (ByteString, ByteString)
B.splitAt Int
56 (ByteString -> (ByteString, ByteString))
-> ByteString -> (ByteString, ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString -> Int -> ByteString
cycleByteStringWithNull ByteString
bcryptTag Int
112
bKey :: ByteString
bKey = ByteString
bKeyTag ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
bKeyInput
bSalt :: ByteString
bSalt = ByteString
bSaltInput ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
bSaltTag
bcryptHash :: ByteString
bcryptHash = Bool -> ByteString -> ByteString
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (ByteString -> Int
B.length ByteString
bKey Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
72 Bool -> Bool -> Bool
&& ByteString -> Int
B.length ByteString
bSalt Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
72) (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
ByteString -> ByteString -> Word32 -> ByteString
bcryptRaw ByteString
bKey ByteString
bSalt Word32
bcryptRounds
headerCharlie :: ByteString
headerCharlie = [ByteString] -> ByteString
B.concat [
ByteString
"G3Pb1 charlie",
ByteString
phkdfHash,
ByteString -> Int -> ByteString
cycleByteStringWithNull ByteString
bcryptTag Int
56,
ByteString
bcryptHash,
ByteString -> Int -> ByteString
cycleByteStringWithNull (ByteString
domainTag ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"\x00G3Pb1 charlie\x00") Int
32
]
secret :: ByteString
secret =
HmacKey -> PhkdfCtx
phkdfCtx_initFromHmacKey HmacKey
seguidKey PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArg ByteString
headerCharlie PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
Word64 -> PhkdfCtx -> PhkdfCtx
phkdfCtx_assertBufferPosition' Word64
32 PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
Vector ByteString -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArgs Vector ByteString
seedTags PhkdfCtx -> (PhkdfCtx -> ByteString) -> ByteString
forall a b. a -> (a -> b) -> b
&
(Int -> ByteString)
-> Word32 -> ByteString -> PhkdfCtx -> ByteString
phkdfCtx_finalize (ByteString -> Int -> ByteString
cycleByteStringWithNull ByteString
bcryptTag) (ByteString -> Word32
word32 ByteString
"SEED") ByteString
domainTag
g3pHash_keyInit :: G3PInputRole -> G3PSeed -> G3PKey
g3pHash_keyInit :: G3PInputRole -> G3PSeed -> G3PKey
g3pHash_keyInit G3PInputRole
roleInput G3PSeed
seed = G3PKey
{ g3pKey_secret :: ByteString
g3pKey_secret = ByteString
secretKey
, g3pKey_secretKey :: HmacKey
g3pKey_secretKey = ByteString -> HmacKey
hmacKey_init ByteString
secretKey
, g3pKey_domainTag :: ByteString
g3pKey_domainTag = G3PSeed -> ByteString
g3pSeed_domainTag G3PSeed
seed
}
where
seguidKey :: HmacKey
seguidKey = G3PSeed -> HmacKey
g3pSeed_seguidKey G3PSeed
seed
domainTag :: ByteString
domainTag = G3PSeed -> ByteString
g3pSeed_domainTag G3PSeed
seed
secret :: ByteString
secret = G3PSeed -> ByteString
g3pSeed_secret G3PSeed
seed
role :: Vector ByteString
role = G3PInputRole -> Vector ByteString
g3pInputRole_roleTags G3PInputRole
roleInput
headerDelta :: ByteString
headerDelta = [ByteString] -> ByteString
B.concat [
ByteString
"G3Pb1 delta",
ByteString
secret
]
secretKey :: ByteString
secretKey =
HmacKey -> PhkdfCtx
phkdfCtx_initFromHmacKey HmacKey
seguidKey PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArg ByteString
headerDelta PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
Vector ByteString -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_addArgs Vector ByteString
role PhkdfCtx -> (PhkdfCtx -> ByteString) -> ByteString
forall a b. a -> (a -> b) -> b
&
(Int -> ByteString)
-> Word32 -> ByteString -> PhkdfCtx -> ByteString
phkdfCtx_finalize (ByteString -> Int -> ByteString
cycleByteStringWithNull ByteString
domainTag) (ByteString -> Word32
word32 ByteString
"KEY\x00") ByteString
domainTag
g3pHash_finalizeGen :: G3PInputEcho -> G3PKey -> G3PGen
g3pHash_finalizeGen :: G3PInputEcho -> G3PKey -> G3PGen
g3pHash_finalizeGen G3PInputEcho
inputEcho G3PKey
gKey = G3PGen
{ g3pGen_secret :: ByteString
g3pGen_secret = G3PKey -> ByteString
g3pKey_secret G3PKey
gKey
, g3pGen_phkdfGen :: PhkdfGen
g3pGen_phkdfGen = PhkdfGen
echo
}
where
secretKey :: HmacKey
secretKey = G3PKey -> HmacKey
g3pKey_secretKey G3PKey
gKey
domainTag :: ByteString
domainTag = G3PKey -> ByteString
g3pKey_domainTag G3PKey
gKey
echoTag :: ByteString
echoTag = G3PInputEcho -> ByteString
g3pInputEcho_echoTag G3PInputEcho
inputEcho
echoHeader :: ByteString
echoHeader = ByteString -> Int -> ByteString
cycleByteString (ByteString
domainTag ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"\x00G3Pb1 echo\x00") Int
32
echoCtr :: Word32
echoCtr = ByteString -> Word32
word32 ByteString
"OUT\x00"
echo :: PhkdfGen
echo = ByteString -> Word32 -> ByteString -> HmacKey -> PhkdfGen
phkdfGen_initFromHmacKey ByteString
echoHeader Word32
echoCtr ByteString
echoTag HmacKey
secretKey
g3pGen_read :: G3PGen -> (ByteString, G3PGen)
g3pGen_read :: G3PGen -> (ByteString, G3PGen)
g3pGen_read G3PGen
gen = let (ByteString
out, PhkdfGen
next) = PhkdfGen -> (ByteString, PhkdfGen)
phkdfGen_read (G3PGen -> PhkdfGen
g3pGen_phkdfGen G3PGen
gen)
in (ByteString
out, G3PGen
gen { g3pGen_phkdfGen = next })
g3pGen_finalizeStream :: G3PGen -> Stream ByteString
g3pGen_finalizeStream :: G3PGen -> Stream ByteString
g3pGen_finalizeStream = PhkdfGen -> Stream ByteString
phkdfGen_finalizeStream (PhkdfGen -> Stream ByteString)
-> (G3PGen -> PhkdfGen) -> G3PGen -> Stream ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. G3PGen -> PhkdfGen
g3pGen_phkdfGen