ppad-bech32 0.1.1 → 0.1.2
raw patch · 6 files changed
+63/−21 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG +3/−0
- bench/Main.hs +22/−11
- lib/Data/ByteString/Base32.hs +34/−8
- lib/Data/ByteString/Bech32.hs +1/−0
- lib/Data/ByteString/Bech32m.hs +2/−1
- ppad-bech32.cabal +1/−1
CHANGELOG view
@@ -1,5 +1,8 @@ # Changelog +- 0.1.2 (2024-12-15)+ * Minor performance improvements.+ - 0.1.1 (2024-12-14) * Simply improves generated Haddocks.
bench/Main.hs view
@@ -7,6 +7,7 @@ import Criterion.Main import qualified Data.ByteString as BS+import qualified Data.ByteString.Base32 as Base32 import qualified Data.ByteString.Bech32 as Bech32 import GHC.Generics import qualified Reference.Bech32 as R@@ -20,24 +21,34 @@ suite ] +base32 :: Benchmark+base32 = bgroup "base32 encode" [+ bench "120b" $ nf Base32.encode "jtobin was here"+ , bench "128b (non 40-bit multiple length)" $+ nf Base32.encode "jtobin was here!"+ , bench "240b" $ nf Base32.encode "jtobin was herejtobin was here"+ ]++bech32 :: Benchmark+bech32 = bgroup "bech32 encode" [+ bench "120b" $ nf (Bech32.encode "bc") "jtobin was here"+ , bench "128b (non 40-bit multiple length)" $+ nf (Bech32.encode "bc") "jtobin was here!"+ , bench "240b" $ nf (Bech32.encode "bc") "jtobin was herejtobin was here"+ ]+ suite :: Benchmark suite = env setup $ \ ~(a, b, c) -> bgroup "benchmarks" [ bgroup "ppad-bech32" [- bgroup "bech32" [- bench "120b" $ whnf (Bech32.encode "bc")- "jtobin was here"- , bench "128b (non 40-bit multiple length)" $ whnf (Bech32.encode "bc")- "jtobin was here!"- , bench "240b" $ whnf (Bech32.encode "bc")- "jtobin was herejtobin was here"- ]+ base32+ , bech32 ] , bgroup "reference" [ bgroup "bech32" [- bench "120b" $ whnf (R.bech32Encode "bc") a+ bench "120b" $ nf (R.bech32Encode "bc") a , bench "128b (non 40-bit multiple length)" $- whnf (R.bech32Encode "bc") b- , bench "240b" $ whnf (R.bech32Encode "bc") c+ nf (R.bech32Encode "bc") b+ , bench "240b" $ nf (R.bech32Encode "bc") c ] ] ]
lib/Data/ByteString/Base32.hs view
@@ -44,6 +44,7 @@ toStrict :: BSB.Builder -> BS.ByteString toStrict = BS.toStrict . BE.toLazyByteStringWith (BE.safeStrategy 128 BE.smallChunkSize) mempty+{-# INLINE toStrict #-} bech32_charset :: BS.ByteString bech32_charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"@@ -52,6 +53,7 @@ encode :: BS.ByteString -> BS.ByteString encode dat = toStrict (go dat) where bech32_char = fi . BS.index bech32_charset . fi+ go bs = case BS.splitAt 5 bs of (chunk, etc) -> case BS.length etc of -- https://datatracker.ietf.org/doc/html/rfc4648#section-6@@ -63,8 +65,12 @@ let a = BU.unsafeIndex chunk 0 t = bech32_char ((a .&. 0b11111000) `B.shiftR` 3) u = bech32_char ((a .&. 0b00000111) `B.shiftL` 2)- in BSB.word8 t <> BSB.word8 u + !w16 = fi t+ .|. fi u `B.shiftL` 8++ in BSB.word16LE w16+ | BS.length chunk == 2 -> let a = BU.unsafeIndex chunk 0 b = BU.unsafeIndex chunk 1@@ -74,8 +80,14 @@ .|. ((b .&. 0b11000000) `B.shiftR` 6) v = bech32_char ((b .&. 0b00111110) `B.shiftR` 1) w = bech32_char ((b .&. 0b00000001) `B.shiftL` 4)- in BSB.word8 t <> BSB.word8 u <> BSB.word8 v <> BSB.word8 w + !w32 = fi t+ .|. fi u `B.shiftL` 8+ .|. fi v `B.shiftL` 16+ .|. fi w `B.shiftL` 24++ in BSB.word32LE w32+ | BS.length chunk == 3 -> let a = BU.unsafeIndex chunk 0 b = BU.unsafeIndex chunk 1@@ -89,9 +101,14 @@ ((b .&. 0b00000001) `B.shiftL` 4) .|. ((c .&. 0b11110000) `B.shiftR` 4) x = bech32_char ((c .&. 0b00001111) `B.shiftL` 1)- in BSB.word8 t <> BSB.word8 u <> BSB.word8 v <> BSB.word8 w- <> BSB.word8 x + !w32 = fi t+ .|. fi u `B.shiftL` 8+ .|. fi v `B.shiftL` 16+ .|. fi w `B.shiftL` 24++ in BSB.word32LE w32 <> BSB.word8 x+ | BS.length chunk == 4 -> let a = BU.unsafeIndex chunk 0 b = BU.unsafeIndex chunk 1@@ -110,9 +127,17 @@ .|. ((d .&. 0b10000000) `B.shiftR` 7) y = bech32_char ((d .&. 0b01111100) `B.shiftR` 2) z = bech32_char ((d .&. 0b00000011) `B.shiftL` 3)- in BSB.word8 t <> BSB.word8 u <> BSB.word8 v <> BSB.word8 w- <> BSB.word8 x <> BSB.word8 y <> BSB.word8 z + !w32 = fi t+ .|. fi u `B.shiftL` 8+ .|. fi v `B.shiftL` 16+ .|. fi w `B.shiftL` 24++ !w16 = fi x+ .|. fi y `B.shiftL` 8++ in BSB.word32LE w32 <> BSB.word16LE w16 <> BSB.word8 z+ | otherwise -> mempty _ -> case BS.unsnoc chunk of@@ -134,7 +159,7 @@ w8_6 = bech32_char (mask .&. (w32 `B.shiftL` 03 .|. w8 `B.shiftR` 05)) w8_7 = bech32_char (mask .&. w8) - w64 = w8_0+ !w64 = w8_0 .|. w8_1 `B.shiftL` 8 .|. w8_2 `B.shiftL` 16 .|. w8_3 `B.shiftL` 24@@ -144,6 +169,7 @@ .|. w8_7 `B.shiftL` 56 in BSB.word64LE w64+{-# INLINE arrange #-} -- naive base32 -> word5 as_word5 :: BS.ByteString -> BS.ByteString@@ -209,7 +235,7 @@ verify enc b32 = case BS.elemIndexEnd 0x31 b32 of Nothing -> False Just idx ->- let (hrp, BS.drop 1 -> dat) = BS.splitAt idx b32+ let (hrp, BU.unsafeDrop 1 -> dat) = BS.splitAt idx b32 bs = hrp_expand hrp <> as_word5 dat in polymod bs == case enc of Bech32 -> 1
lib/Data/ByteString/Bech32.hs view
@@ -32,6 +32,7 @@ toStrict :: BSB.Builder -> BS.ByteString toStrict = BS.toStrict . BE.toLazyByteStringWith (BE.safeStrategy 128 BE.smallChunkSize) mempty+{-# INLINE toStrict #-} create_checksum :: BS.ByteString -> BS.ByteString -> BS.ByteString create_checksum = B32.create_checksum Bech32
lib/Data/ByteString/Bech32m.hs view
@@ -32,6 +32,7 @@ toStrict :: BSB.Builder -> BS.ByteString toStrict = BS.toStrict . BE.toLazyByteStringWith (BE.safeStrategy 128 BE.smallChunkSize) mempty+{-# INLINE toStrict #-} create_checksum :: BS.ByteString -> BS.ByteString -> BS.ByteString create_checksum = B32.create_checksum Bech32m@@ -44,7 +45,7 @@ encode :: BS.ByteString -- ^ base255-encoded human-readable part -> BS.ByteString -- ^ base255-encoded data part- -> Maybe BS.ByteString -- ^ bech32-encoded bytestring+ -> Maybe BS.ByteString -- ^ bech32m-encoded bytestring encode hrp (B32.encode -> dat) = do guard (B32.valid_hrp hrp) let check = create_checksum hrp (B32.as_word5 dat)
ppad-bech32.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: ppad-bech32-version: 0.1.1+version: 0.1.2 synopsis: The bech32 and bech32m encodings, per BIPs 173 & 350. license: MIT license-file: LICENSE