Main.hs (4303B)
1 {-# LANGUAGE OverloadedStrings #-} 2 {-# LANGUAGE RecordWildCards #-} 3 4 module Main where 5 6 import qualified Crypto.HDKey.BIP32 as BIP32 7 import qualified Crypto.KDF.BIP39 as BIP39 8 import qualified Data.Aeson as A 9 import qualified Data.Text.ICU.Normalize2 as ICU 10 import qualified Data.Text.IO as TIO 11 import Test.Tasty 12 import Test.Tasty.HUnit 13 import qualified Vectors as V 14 15 data Wordlist = 16 English 17 | ChineseTraditional 18 | ChineseSimplified 19 | Czech 20 | French 21 | Italian 22 | Japanese 23 | Korean 24 | Portuguese 25 | Spanish 26 27 main :: IO () 28 main = do 29 vectors_bip39 <- TIO.readFile "etc/vectors.json" 30 vectors_jp_bip39 <- TIO.readFile "etc/test_JP_BIP39.json" 31 let vectors = do 32 a <- A.decodeStrictText vectors_bip39 :: Maybe V.Vectors 33 b <- A.decodeStrictText vectors_jp_bip39 :: Maybe [V.JPBip39Test] 34 pure (a, b) 35 case vectors of 36 Nothing -> error "couldn't parse bip39 vectors" 37 Just (vs, js) -> defaultMain $ 38 testGroup "ppad-bip39" [ 39 bip39_tests vs 40 , jp_bip39_tests js 41 ] 42 43 jp_bip39_tests :: [V.JPBip39Test] -> TestTree 44 jp_bip39_tests jp_vectors = 45 testGroup "jp bip39 vectors" (fmap execute_jp jp_vectors) 46 47 bip39_tests :: V.Vectors -> TestTree 48 bip39_tests V.Vectors {..} = 49 testGroup "bip39 vectors" [ 50 testGroup "english" 51 (fmap (execute English) v_english) 52 , testGroup "chinese_traditional" 53 (fmap (execute ChineseTraditional) v_chinese_traditional) 54 , testGroup "chinese_simplified" 55 (fmap (execute ChineseSimplified) v_chinese_simplified) 56 , testGroup "french" 57 (fmap (execute French) v_french) 58 , testGroup "czech" 59 (fmap (execute Czech) v_czech) 60 , testGroup "italian" 61 (fmap (execute Italian) v_italian) 62 , testGroup "japanese" 63 (fmap (execute Japanese) v_japanese) 64 , testGroup "korean" 65 (fmap (execute Korean) v_korean) 66 , testGroup "portuguese" 67 (fmap (execute Portuguese) v_portuguese) 68 , testGroup "spanish" 69 (fmap (execute Spanish) v_spanish) 70 ] 71 72 execute :: Wordlist -> V.Bip39Test -> TestTree 73 execute wlist V.Bip39Test {..} = do 74 let entr = bt_entropy 75 mnem = bt_mnemonic 76 seed = bt_seed 77 xprv = bt_xprv 78 out_mnem = BIP39._mnemonic wl entr 79 giv_seed = seed_fn mnem "TREZOR" 80 out_seed = seed_fn out_mnem "TREZOR" 81 out_xprv = case BIP32.master out_seed of 82 Just hd -> BIP32.xprv hd 83 Nothing -> error "bang (bip32)" 84 t_msg = mempty 85 testGroup t_msg [ 86 -- we always output (NFKD) normalized UTF8, but test inputs may not be 87 -- normalized in this fashion 88 testCase "mnemonic" $ assertEqual mempty (ICU.nfkd mnem) out_mnem 89 -- testing from the given mnemonic ensures we're normalizing properly 90 -- before seed calculation 91 , testCase "seed (from given mnemonic)" $ assertEqual mempty seed giv_seed 92 , testCase "seed (from derived mnemonic)" $ assertEqual mempty seed out_seed 93 , testCase "xprv" $ assertEqual mempty xprv out_xprv 94 ] 95 where 96 seed_fn = case wlist of 97 English -> BIP39.seed 98 _ -> BIP39.seed_unsafe 99 wl = case wlist of 100 English -> BIP39.english 101 ChineseTraditional -> BIP39.chinese_traditional 102 ChineseSimplified -> BIP39.chinese_simplified 103 Czech -> BIP39.czech 104 French -> BIP39.french 105 Italian -> BIP39.italian 106 Japanese -> BIP39.japanese 107 Korean -> BIP39.korean 108 Portuguese -> BIP39.portuguese 109 Spanish -> BIP39.spanish 110 111 execute_jp :: V.JPBip39Test -> TestTree 112 execute_jp V.JPBip39Test {..} = do 113 let entr = jp_entropy 114 mnem = jp_mnemonic 115 pass = jp_passphrase 116 seed = jp_seed 117 xprv = jp_xprv 118 out_mnem = BIP39._mnemonic BIP39.japanese entr 119 giv_seed = BIP39.seed_unsafe mnem pass 120 out_seed = BIP39.seed_unsafe out_mnem pass 121 out_xprv = case BIP32.master out_seed of 122 Just hd -> BIP32.xprv hd 123 Nothing -> error "bang (bip32, jp)" 124 testGroup mempty [ 125 testCase "mnemonic" $ assertEqual mempty (ICU.nfkd mnem) out_mnem 126 , testCase "seed (from given mnemonic)" $ assertEqual mempty seed giv_seed 127 , testCase "seed (from derived mnemonic)" $ assertEqual mempty seed out_seed 128 , testCase "xprv" $ assertEqual mempty xprv out_xprv 129 ] 130