Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit be9b2d1

Browse files
committed
Merge branch 'CO-346' into Squad1/CO-325/api-v1-improvements
2 parents 5077aaa + fda4447 commit be9b2d1

File tree

3 files changed

+51
-43
lines changed

3 files changed

+51
-43
lines changed

stack.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ packages:
5656

5757
- location:
5858
git: https://github.com/input-output-hk/cardano-crypto
59-
commit: 33c7ecc6e4bd71c3ea0195e9d796eeace7be22cf
59+
commit: e87fcd3fea18f664d6e4f39c11abb8cafbd25785
6060
extra-dep: true
6161
# to be removed when haskell-ip is in the current stackage version
6262
- location:

wallet/src/Pos/Util/Mnemonic.hs

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ module Pos.Util.Mnemonic
1212
, MnemonicWords
1313

1414
-- * Errors
15-
, MnemonicErr(..)
15+
, MnemonicError(..)
1616
, MnemonicException(..)
17+
-- ** Re-exports from 'cardano-crypto'
18+
, EntropyError(..)
19+
, DictionaryError(..)
20+
, MnemonicWordsError(..)
1721

1822
-- * Creating @Mnemonic@ (resp. @Entropy@)
1923
, mkEntropy
20-
, eitherToParser
2124
, mkMnemonic
2225
, genEntropy
2326

@@ -27,14 +30,17 @@ module Pos.Util.Mnemonic
2730
, mnemonicToAesKey
2831
, entropyToMnemonic
2932
, entropyToByteString
33+
34+
-- * Helper (FIXME: Move to a separated module)
35+
, eitherToParser
3036
) where
3137

3238
import Universum
3339

3440
import Basement.Sized.List (unListN)
41+
import Control.Arrow (left)
3542
import Control.Lens ((?~))
3643
import Crypto.Encoding.BIP39
37-
import Crypto.Encoding.BIP39.Dictionary (mnemonicSentenceToListN)
3844
import Crypto.Hash (Blake2b_256, Digest, hash)
3945
import Data.Aeson (FromJSON (..), ToJSON (..))
4046
import Data.Aeson.Types (Parser)
@@ -75,14 +81,15 @@ data Mnemonic (mw :: Nat) = Mnemonic
7581
-- ERRORS
7682
--
7783

78-
data MnemonicException = UnexpectedMnemonicErr MnemonicErr
84+
data MnemonicException csz = UnexpectedEntropyError (EntropyError csz)
7985
deriving (Show, Typeable)
8086

8187

82-
data MnemonicErr
83-
= MnemonicErrInvalidEntropyLength Int
84-
| MnemonicErrFailedToCreate
85-
| MnemonicErrForbiddenMnemonic
88+
data MnemonicError csz
89+
= ErrMnemonicWords MnemonicWordsError
90+
| ErrEntropy (EntropyError csz)
91+
| ErrDictionary DictionaryError
92+
| ErrForbidden
8693
deriving (Show)
8794

8895

@@ -94,12 +101,8 @@ data MnemonicErr
94101
mkEntropy
95102
:: forall n csz. (ValidEntropySize n, ValidChecksumSize n csz)
96103
=> ByteString
97-
-> Either MnemonicErr (Entropy n)
98-
mkEntropy =
99-
let
100-
n = fromIntegral $ natVal (Proxy @n)
101-
in
102-
maybe (Left $ MnemonicErrInvalidEntropyLength n) Right . toEntropy @n
104+
-> Either (EntropyError csz) (Entropy n)
105+
mkEntropy = toEntropy
103106

104107

105108
-- | Generate Entropy of a given size using a random seed.
@@ -115,7 +118,7 @@ genEntropy =
115118
size =
116119
fromIntegral $ natVal (Proxy @n)
117120
eitherToIO =
118-
either (throwM . UnexpectedMnemonicErr) return
121+
either (throwM . UnexpectedEntropyError) return
119122
in
120123
(eitherToIO . mkEntropy) =<< Crypto.getEntropy (size `div` 8)
121124

@@ -127,22 +130,20 @@ mkMnemonic
127130
, EntropySize mw ~ n
128131
)
129132
=> [Text]
130-
-> Either MnemonicErr (Mnemonic mw)
133+
-> Either (MnemonicError csz) (Mnemonic mw)
131134
mkMnemonic wordsm = do
132-
sentence <- maybe
133-
(Left MnemonicErrFailedToCreate)
134-
(Right . mnemonicPhraseToMnemonicSentence Dictionary.english)
135-
(mnemonicPhrase @mw (toUtf8String <$> wordsm))
135+
phrase <- left ErrMnemonicWords
136+
$ mnemonicPhrase @mw (toUtf8String <$> wordsm)
137+
138+
sentence <- left ErrDictionary
139+
$ mnemonicPhraseToMnemonicSentence Dictionary.english phrase
136140

137-
entropy <- maybe
138-
(Left MnemonicErrFailedToCreate)
139-
Right
140-
(wordsToEntropy sentence :: Maybe (Entropy n))
141+
entropy <- left ErrEntropy
142+
$ wordsToEntropy sentence
141143

142-
when (isForbiddenMnemonic sentence) $
143-
Left MnemonicErrForbiddenMnemonic
144+
when (isForbiddenMnemonic sentence) $ Left ErrForbidden
144145

145-
pure $ Mnemonic
146+
pure Mnemonic
146147
{ mnemonicToEntropy = entropy
147148
, mnemonicToSentence = sentence
148149
}
@@ -260,7 +261,7 @@ instance
260261
size = fromIntegral $ natVal (Proxy @n)
261262
entropy = mkEntropy @n . B8.pack <$> vectorOf (size `quot` 8) arbitrary
262263
in
263-
either (error . show . UnexpectedMnemonicErr) identity <$> entropy
264+
either (error . show . UnexpectedEntropyError) identity <$> entropy
264265

265266

266267
-- Same remark from 'Arbitrary Entropy' applies here.
@@ -276,7 +277,7 @@ instance
276277
entropyToMnemonic <$> arbitrary @(Entropy n)
277278

278279

279-
instance Exception MnemonicException
280+
instance (KnownNat csz) => Exception (MnemonicException csz)
280281

281282

282283
-- FIXME: Suggestion, we could -- when certain flags are turned on -- display
@@ -294,15 +295,22 @@ instance Buildable (SecureLog (Mnemonic mw)) where
294295
build _ =
295296
"<mnemonic>"
296297

297-
instance Buildable MnemonicErr where
298+
instance Buildable (MnemonicError csz) where
298299
build = \case
299-
MnemonicErrInvalidEntropyLength l ->
300-
bprint ("Entropy must be a sequence of " % build % " bytes") l
301-
MnemonicErrFailedToCreate ->
302-
bprint "Invalid Mnemonic words"
303-
MnemonicErrForbiddenMnemonic ->
300+
ErrMnemonicWords (ErrWrongNumberOfWords a e) ->
301+
bprint ("Invalid number of mnemonic words: got "%build%" words, expected "%build%" words") a e
302+
ErrDictionary (ErrInvalidDictionaryWord w) ->
303+
bprint ("Invalid dictionary word: "%build%"") (fromUtf8String w)
304+
ErrEntropy (ErrInvalidEntropyLength a e) ->
305+
bprint ("Invalid entropy length: got "%build%" bits, expected "%build%" bits") a e
306+
ErrEntropy (ErrInvalidEntropyChecksum a e) ->
307+
bprint ("Invalid entropy checksum: got "%build%", expected "%build) (show' a) (show' e)
308+
ErrForbidden ->
304309
bprint "Forbidden Mnemonic: an example Mnemonic has been submitted. \
305310
\Please generate a fresh and private Mnemonic from a trusted source"
311+
where
312+
show' :: Checksum csz -> String
313+
show' = show
306314

307315

308316
-- | To use everytime we need to show an example of a Mnemonic. This particular
@@ -325,13 +333,13 @@ instance Default (Mnemonic 12) where
325333
, "flee"
326334
]
327335

328-
sentence = maybe
329-
(error $ show $ UnexpectedMnemonicErr MnemonicErrFailedToCreate)
330-
(mnemonicPhraseToMnemonicSentence Dictionary.english)
336+
phrase = either (error . show) id
331337
(mnemonicPhrase @12 (toUtf8String <$> wordsm))
332338

333-
entropy = fromMaybe
334-
(error $ show $ UnexpectedMnemonicErr MnemonicErrFailedToCreate)
339+
sentence = either (error . show) id
340+
(mnemonicPhraseToMnemonicSentence Dictionary.english phrase)
341+
342+
entropy = either (error . show) id
335343
(wordsToEntropy @(EntropySize 12) sentence)
336344
in Mnemonic
337345
{ mnemonicToSentence = sentence

wallet/test/Test/Pos/Util/MnemonicSpec.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ spec = do
138138
)
139139
]
140140
where
141+
orFail :: Show e => Either e a -> a
141142
orFail =
142143
either (error . (<>) "Failed to create golden Mnemonic: " . show) identity
143-
mkEntropy' =
144-
maybe (Left MnemonicErrFailedToCreate) Right . toEntropy @128 @4 @ByteString
144+
mkEntropy' = toEntropy @128 @4 @ByteString
145145

146146
-- | V0 Mnemonics are wrapped in a singleton object with a `bpToList` prop
147147
jsonV0Compat :: BL.ByteString -> BL.ByteString

0 commit comments

Comments
 (0)