Weight.hs (5807B)
1 {-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-} 2 {-# LANGUAGE BangPatterns #-} 3 {-# LANGUAGE OverloadedStrings #-} 4 5 module Main where 6 7 import qualified Data.ByteString as BS 8 import qualified Data.ByteString.Base16 as B16 9 import Data.Maybe (fromJust) 10 import Data.Word.Wider (Wider(..)) 11 import Control.DeepSeq 12 import qualified Crypto.Curve.Secp256k1 as S 13 import qualified Weigh as W 14 15 instance NFData S.Projective 16 instance NFData S.Affine 17 instance NFData S.ECDSA 18 instance NFData S.Context 19 20 decodeLenient :: BS.ByteString -> BS.ByteString 21 decodeLenient bs = case B16.decode bs of 22 Nothing -> error "bang" 23 Just b -> b 24 25 parse_int :: BS.ByteString -> Wider 26 parse_int bs = case S.parse_int256 bs of 27 Nothing -> error "bang" 28 Just v -> v 29 30 -- note that 'weigh' doesn't work properly in a repl 31 main :: IO () 32 main = W.mainWith $ do 33 parse_int256 34 ge 35 add 36 double 37 mul 38 mul_wnaf 39 derive_pub 40 schnorr 41 ecdsa 42 ecdh 43 44 ge :: W.Weigh () 45 ge = 46 let !t = 2 47 !b = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed 48 in W.wgroup "ge" $ do 49 W.func' "small" S.ge t 50 W.func' "large" S.ge b 51 52 parse_int256 :: W.Weigh () 53 parse_int256 = 54 let !a = BS.replicate 32 0x00 55 !b = BS.replicate 32 0xFF 56 in W.wgroup "parse_int256" $ do 57 W.func' "parse_int (small)" parse_int a 58 W.func' "parse_int (big)" parse_int b 59 60 add :: W.Weigh () 61 add = 62 let !p = fromJust . S.parse_point . decodeLenient $ 63 "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" 64 !r = fromJust . S.parse_point . decodeLenient $ 65 "03a2113cf152585d96791a42cdd78782757fbfb5c6b2c11b59857eb4f7fda0b0e8" 66 !q = fromJust . S.parse_point . decodeLenient $ 67 "02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9" 68 !s = fromJust . S.parse_point . decodeLenient $ 69 "0306413898a49c93cccf3db6e9078c1b6a8e62568e4a4770e0d7d96792d1c580ad" 70 in W.wgroup "add" $ do 71 W.func' "p + q (trivial projective points)" (S.add p) q 72 W.func' "s + p (nontrivial mixed points)" (S.add s) p 73 W.func' "r + s (nontrivial projective points)" (S.add r) s 74 75 double :: W.Weigh () 76 double = 77 let !p = fromJust . S.parse_point . decodeLenient $ 78 "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" 79 !r = fromJust . S.parse_point . decodeLenient $ 80 "03a2113cf152585d96791a42cdd78782757fbfb5c6b2c11b59857eb4f7fda0b0e8" 81 in W.wgroup "double" $ do 82 W.func' "2 p (double, trivial projective point)" S.double p 83 W.func' "2 r (double, nontrivial projective point)" S.double r 84 85 mul :: W.Weigh () 86 mul = 87 let !g = S._CURVE_G 88 !t = 2 89 !b = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed 90 in W.wgroup "mul" $ do 91 W.func' "2 G" (S.mul g) t 92 W.func' "(2 ^ 255 - 19) G" (S.mul g) b 93 94 mul_wnaf :: W.Weigh () 95 mul_wnaf = 96 let !t = 2 97 !b = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed 98 !con = S.precompute 99 in W.wgroup "mul_wnaf" $ do 100 W.func' "precompute" S._precompute (8 :: Int) 101 W.func' "2 G" (S.mul_wnaf con) t 102 W.func' "(2 ^ 255 - 19) G" (S.mul_wnaf con) b 103 104 derive_pub :: W.Weigh () 105 derive_pub = 106 let !t = 2 107 !b = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed 108 !con = S.precompute 109 in W.wgroup "derive_pub" $ do 110 W.func' "sk = 2" S.derive_pub t 111 W.func' "sk = 2 ^ 255 - 19" S.derive_pub b 112 W.func' "wnaf, sk = 2" (S.derive_pub' con) t 113 W.func' "wnaf, sk = 2 ^ 255 - 19" (S.derive_pub' con) b 114 115 schnorr :: W.Weigh () 116 schnorr = 117 let !t = 2 118 !b = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed 119 !con = S.precompute 120 !s_msg = decodeLenient 121 "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89" 122 !s_aux = decodeLenient 123 "0000000000000000000000000000000000000000000000000000000000000001" 124 !s_sig = decodeLenient 125 "6896BD60EEAE296DB48A229FF71DFE071BDE413E6D43F917DC8DCF8C78DE33418906D11AC976ABCCB20B091292BFF4EA897EFCB639EA871CFA95F6DE339E4B0A" 126 !(Just !s_pk) = S.parse_point . decodeLenient $ 127 "DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659" 128 in W.wgroup "schnorr" $ do 129 W.func "sign_schnorr (small)" (S.sign_schnorr t s_msg) s_aux 130 W.func "sign_schnorr (large)" (S.sign_schnorr b s_msg) s_aux 131 W.func "sign_schnorr' (small)" (S.sign_schnorr' con t s_msg) s_aux 132 W.func "sign_schnorr' (large)" (S.sign_schnorr' con b s_msg) s_aux 133 W.func "verify_schnorr" (S.verify_schnorr s_msg s_pk) s_sig 134 W.func "verify_schnorr'" (S.verify_schnorr' con s_msg s_pk) s_sig 135 136 ecdsa :: W.Weigh () 137 ecdsa = 138 let !t = 2 139 !b = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed 140 !con = S.precompute 141 !msg = "i approve of this message" 142 !s_msg = decodeLenient 143 "243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89" 144 !(Just !pub) = S.derive_pub b 145 !(Just !sig) = S.sign_ecdsa b s_msg 146 in W.wgroup "ecdsa" $ do 147 W.func "sign_ecdsa (small)" (S.sign_ecdsa t) s_msg 148 W.func "sign_ecdsa (large)" (S.sign_ecdsa b) s_msg 149 W.func "sign_ecdsa' (small)" (S.sign_ecdsa' con t) s_msg 150 W.func "sign_ecdsa' (large)" (S.sign_ecdsa' con b) s_msg 151 W.func "verify_ecdsa" (S.verify_ecdsa msg pub) sig 152 W.func "verify_ecdsa'" (S.verify_ecdsa' con msg pub) sig 153 154 ecdh :: W.Weigh () 155 ecdh = 156 let !b = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed 157 !(Just !pub) = S.parse_point . decodeLenient $ 158 "bd02b9dfc8ef760708950bd972f2dc244893b61b6b46c3b19be1b2da7b034ac5" 159 in W.wgroup "ecdh" $ do 160 W.func "ecdh (small)" (S.ecdh pub) 2 161 W.func "ecdh (large)" (S.ecdh pub) b 162