Main.hs (8195B)
1 {-# LANGUAGE OverloadedStrings #-} 2 3 module Main where 4 5 import qualified Data.ByteString as BS 6 import Crypto.Secp256k1 7 import Test.Tasty 8 import Test.Tasty.HUnit 9 10 main :: IO () 11 main = defaultMain units 12 13 units :: TestTree 14 units = testGroup "unit tests" [ 15 parse_pub_test 16 , serialize_pub_test 17 , serialize_pub_u_test 18 , derive_pub_test 19 , tweak_pub_add_test 20 , tweak_pub_mul_test 21 , tweak_sec_add_test 22 , tweak_sec_mul_test 23 , parse_der_test 24 , serialize_der_test 25 , compact_test 26 , parse_xonly_test 27 , serialize_xonly_test 28 , keypair_test 29 , sign_test 30 , verify_test 31 , sign_schnorr_test 32 , verify_schnorr_test 33 ] 34 35 parse_pub_test :: TestTree 36 parse_pub_test = testCase "parse_pub (success)" $ 37 wcontext $ \tex -> do 38 -- throws on failure, so any return implies success 39 _ <- parse_pub tex _PUB_COMPRESSED 40 assertBool "success" True 41 42 serialize_pub_test :: TestTree 43 serialize_pub_test = testCase "serialize_pub (success)" $ 44 wcontext $ \tex -> do 45 par <- parse_pub tex _PUB_COMPRESSED 46 pub <- serialize_pub tex par 47 assertEqual "success" pub _PUB_COMPRESSED 48 49 serialize_pub_u_test :: TestTree 50 serialize_pub_u_test = testCase "serialize_pub_u (success)" $ 51 wcontext $ \tex -> do 52 par <- parse_pub tex _PUB_UNCOMPRESSED 53 pub <- serialize_pub_u tex par 54 assertEqual "success" pub _PUB_UNCOMPRESSED 55 56 derive_pub_test :: TestTree 57 derive_pub_test = testCase "derive_pub (success)" $ 58 wcontext $ \tex -> do 59 -- throws on failure, so any return implies success 60 _ <- derive_pub tex _SEC 61 assertBool "success" True 62 63 tweak_pub_add_test :: TestTree 64 tweak_pub_add_test = 65 testCase "tweak_pub_add (success)" $ 66 wcontext $ \tex -> do 67 pub <- parse_pub tex _PUB_COMPRESSED 68 add <- tweak_pub_add tex pub _TWEAK 69 eek <- serialize_pub_u tex add 70 assertEqual "success" eek _PUB_ADD_TWEAKED 71 72 tweak_pub_mul_test :: TestTree 73 tweak_pub_mul_test = 74 testCase "tweak_pub_mul (success)" $ 75 wcontext $ \tex -> do 76 pub <- parse_pub tex _PUB_COMPRESSED 77 add <- tweak_pub_mul tex pub _TWEAK 78 eek <- serialize_pub_u tex add 79 assertEqual "success" eek _PUB_MUL_TWEAKED 80 81 tweak_sec_add_test :: TestTree 82 tweak_sec_add_test = 83 testCase "tweak_sec_add (success)" $ 84 wcontext $ \tex -> do 85 eek <- tweak_sec_add tex _SEC _TWEAK 86 assertEqual "success" eek _SEC_ADD_TWEAKED 87 88 tweak_sec_mul_test :: TestTree 89 tweak_sec_mul_test = 90 testCase "tweak_sec_mul (success)" $ 91 wcontext $ \tex -> do 92 eek <- tweak_sec_mul tex _SEC _TWEAK 93 assertEqual "success" eek _SEC_MUL_TWEAKED 94 95 parse_der_test :: TestTree 96 parse_der_test = 97 testCase "parse_der (success)" $ 98 wcontext $ \tex -> do 99 -- throws on failure, so any return implies success 100 _ <- parse_der tex _DER 101 assertBool "success" True 102 103 serialize_der_test :: TestTree 104 serialize_der_test = 105 testCase "serialize_der (success)" $ 106 wcontext $ \tex -> do 107 par <- parse_der tex _DER 108 der <- serialize_der tex par 109 assertEqual "success" der _DER 110 111 -- joint parse, serialize test 112 compact_test :: TestTree 113 compact_test = 114 testCase "{parse, serialize}_compact (success)" $ 115 wcontext $ \tex -> do 116 sig <- parse_der tex _DER 117 com <- serialize_compact tex sig 118 par <- parse_compact tex com 119 der <- serialize_der tex par 120 assertEqual "success" der _DER 121 122 parse_xonly_test :: TestTree 123 parse_xonly_test = 124 testCase "parse_xonly (success)" $ do 125 wcontext $ \tex -> do 126 pux <- parse_xonly tex _PUB_XONLY 127 pub <- serialize_xonly tex pux 128 assertEqual "success" pub _PUB_XONLY 129 130 serialize_xonly_test :: TestTree 131 serialize_xonly_test = 132 testCase "serialize_xonly (success)" $ 133 wcontext $ \tex -> do 134 pub <- parse_pub tex _PUB_COMPRESSED 135 key <- xonly tex pub 136 pux <- serialize_xonly tex key 137 assertEqual "success" pux _PUB_XONLY 138 139 keypair_test :: TestTree 140 keypair_test = 141 testCase "keypair (success)" $ do 142 wcontext $ \tex -> do 143 per <- keypair tex _SEC 144 sec <- keypair_sec tex per 145 pub <- keypair_pub tex per 146 ser <- serialize_pub tex pub 147 assertEqual "success" sec _SEC 148 assertEqual "success" ser _PUB_COMPRESSED 149 150 sign_test :: TestTree 151 sign_test = testCase "sign (success)" $ 152 wcontext $ \tex -> do 153 sig <- sign tex _SEC _HAS 154 der <- serialize_der tex sig 155 assertEqual "success" _DER der 156 157 verify_test :: TestTree 158 verify_test = testCase "verify (success)" $ 159 wcontext $ \tex -> do 160 pub <- parse_pub tex _PUB_UNCOMPRESSED 161 sig <- parse_der tex _DER 162 suc <- verify tex pub _HAS sig 163 assertBool "success" suc 164 165 sign_schnorr_test :: TestTree 166 sign_schnorr_test = testCase "sign_schnorr (success)" $ 167 wcontext $ \tex -> do 168 let enn = BS.replicate 32 0 169 sig <- sign_schnorr tex _HAS _SEC enn 170 assertEqual "success" sig _SIG_SCHNORR 171 172 verify_schnorr_test :: TestTree 173 verify_schnorr_test = testCase "verify_schnorr (success)" $ 174 wcontext $ \tex -> do 175 pub <- parse_pub tex _PUB_UNCOMPRESSED 176 suc <- verify_schnorr tex pub _HAS _SIG_SCHNORR 177 assertBool "success" suc 178 179 ecdh_test :: TestTree 180 ecdh_test = testCase "ecdh (success)" $ 181 wcontext $ \tex -> do 182 pub <- parse_pub tex _PUB_COMPRESSED 183 -- throws on failure, so any return implies success 184 _ <- ecdh tex pub _SEC 185 assertBool "success" True 186 187 -- test inputs 188 189 -- mostly grabbed from haskoin/secp256k1-haskell 190 191 -- DER-encoded signature 192 _DER :: BS.ByteString 193 _DER = mconcat [ 194 "0E\STX!\NUL\245\STX\191\160z\244>~\242ea\139\r\146\154v\EM\238\SOH\214" 195 , "\NAK\SO7\235n\170\242\200\189\&7\251\"\STX o\EOT\NAK\171\SO\154\151z" 196 , "\253x\178\194n\243\155\&9R\tm1\159\212\177\SOH\199h\173l\DC3.0E" 197 ] 198 199 -- a 32-byte message hash 200 _HAS :: BS.ByteString 201 _HAS = mconcat [ 202 "\245\203\231\216\129\130\164\184\228\NUL\249k\ACK\DC2\137!\134J" 203 , "\CAN\CAN}\DC1L\138\232T\ESCVl\138\206\NUL" 204 ] 205 206 -- a 32-byte secret key 207 _SEC :: BS.ByteString 208 _SEC = mconcat [ 209 "\246RU\tMws\237\141\212\ETB\186\220\159\192E\193\248\SI\220[-%\ETB" 210 , "+\ETX\FS\230\147>\ETX\154" 211 ] 212 213 -- 32 bytes 214 _TWEAK :: BS.ByteString 215 _TWEAK = mconcat [ 216 "\245\203\231\216\129\130\164\184\228\NUL\249k\ACK\DC2\137!\134J" 217 , "\CAN\CAN}\DC1L\138\232T\ESCVl\138\206\NUL" 218 ] 219 220 -- _PUB add-tweaked with _TWEAK 221 _PUB_ADD_TWEAKED :: BS.ByteString 222 _PUB_ADD_TWEAKED = mconcat [ 223 "\EOTD\FS9\130\185uvdn\r\240\201g6\ACK=\246\180/.\229f\209;\159d$0-" 224 , "\DC3y\229\CAN\253\200z\DC4\197C[\255z]\180U B\203A \198\184jK\189=" 225 , "\ACKC\243\193J\208\DC3h" 226 ] 227 228 -- _PUB mul-tweaked with _TWEAK 229 _PUB_MUL_TWEAKED :: BS.ByteString 230 _PUB_MUL_TWEAKED = mconcat [ 231 "\EOT\243y\220\153\205\245\200>C=\239\162g\251\179\&7}a\214\183y" 232 , "\192j\SOL\226\154\227\255SS\177*\228\156\157\a\231\&6\143+\165" 233 , "\164F\194\ETX%\\\233\DC22)\145\162\214\169\213\213v\FSa\237\CANE" 234 ] 235 236 -- _SEC add-tweaked with _TWEAK 237 _SEC_ADD_TWEAKED :: BS.ByteString 238 _SEC_ADD_TWEAKED = mconcat [ 239 "\236\RS<\225\206\250\CAN\166q\213\DC1%\226\178Ih\141\147K\SO(\245" 240 , "\209fS\132\217\176/\146\144Y" 241 ] 242 243 -- _SEC mul-tweaked with _TWEAK 244 _SEC_MUL_TWEAKED :: BS.ByteString 245 _SEC_MUL_TWEAKED = mconcat [ 246 "\169oYbI:\203\ETB\159`\168j\151\133\252z0\224\195\155d\192\157$\254" 247 , "\ACKM\154\239\NAK\228\192" 248 ] 249 250 -- 33-byte (compressed) public key 251 _PUB_COMPRESSED :: BS.ByteString 252 _PUB_COMPRESSED = mconcat [ 253 "\ETX\221\237B\ETX\218\201j~\133\242\195t\163|\227\233\201\161U" 254 , "\167+d\180U\ESC\v\254w\157\212G\ENQ" 255 ] 256 257 -- 65-byte (uncompressed) public key 258 _PUB_UNCOMPRESSED :: BS.ByteString 259 _PUB_UNCOMPRESSED = mconcat [ 260 "\EOT\221\237B\ETX\218\201j~\133\242\195t\163|\227\233\201\161U\167" 261 , "+d\180U\ESC\v\254w\157\212G\ENQ\DC2!=^\215\144R,\EOT-\238\142\133" 262 , "\196\192\236_\150\128\vr\188Y@\200\188\FS^\DC1\228\252\191" 263 ] 264 265 -- 32-byte x-only pubkey 266 _PUB_XONLY :: BS.ByteString 267 _PUB_XONLY = mconcat [ 268 "\221\237B\ETX\218\201j~\133\242\195t\163|\227\233\201\161U\167+d" 269 , "\180U\ESC\v\254w\157\212G\ENQ" 270 ] 271 272 -- 64-byte schnorr signature 273 _SIG_SCHNORR :: BS.ByteString 274 _SIG_SCHNORR = mconcat [ 275 "\214\185AtJ\189\250Gp\NAK2\221\DC2[\182\209\192j{\140^\222R\NUL~" 276 , "\139d@<\138\163rh\247\152\r\228\175\236\219\156\151\214~\135\&7" 277 , "\225\&6\234\220;\164R\191\170\186\243\NAK\147\f\144\156ez" 278 ] 279