packages feed

multihash-serialise (empty) → 0.1.0.0

raw patch · 6 files changed

+209/−0 lines, 6 filesdep +basedep +bytestringdep +cryptonite

Dependencies added: base, bytestring, cryptonite, hedgehog, memory, multibase, multihash-cryptonite, multihash-serialise, serialise

Files

+ CHANGELOG.md view
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2018, Monadic GmbH++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Monadic GmbH nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,1 @@+CBOR encoding of [multihashes](../multihash-cryptonite), via [serialise](https://hackage.haskell.org/package/serialise).
+ multihash-serialise.cabal view
@@ -0,0 +1,77 @@+cabal-version: 2.2+build-type:    Simple++name:          multihash-serialise+version:       0.1.0.0+synopsis:      CBOR encoding of multihashes+homepage:      https://github.com/oscoin/ipfs+bug-reports:   https://github.com/oscoin/ipfs/issues+license:       BSD-3-Clause+license-file:  LICENSE+author:        Kim Altintop+maintainer:    Kim Altintop <kim@monadic.xyz>, Monadic Team <team@monadic.xyz>+copyright:     2018 Monadic GmbH++category:      Codec++extra-source-files:+      CHANGELOG.md+    , README.md++source-repository head+    type: git+    location: https://github.com/oscoin/ipfs++common common+    default-language: Haskell2010+    ghc-options:+        -Wall+        -Wcompat+        -Wincomplete-uni-patterns+        -Wincomplete-record-updates+        -Wredundant-constraints+        -fprint-expanded-synonyms+        -funbox-small-strict-fields++library+    import: common+    hs-source-dirs: src+    exposed-modules:+        Codec.Serialise.Multihash++    build-depends:+        base >= 4.9 && < 5+      , bytestring+      , cryptonite > 0.13+      , memory >= 0.11+      , multibase+      , multihash-cryptonite+      , serialise++    ghc-options:+        -Wall+        -Wcompat+        -Wincomplete-uni-patterns+        -Wincomplete-record-updates+        -Wredundant-constraints+        -fprint-expanded-synonyms+        -funbox-small-strict-fields++test-suite properties+    import: common+    main-is: Main.hs+    hs-source-dirs: test/properties+    type: exitcode-stdio-1.0++    build-depends:+        base+      , cryptonite+      , hedgehog+      , multihash-serialise+      , serialise++    ghc-options:+        -threaded+        -rtsopts+        -with-rtsopts=-N+
+ src/Codec/Serialise/Multihash.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE TypeApplications          #-}++-- |+-- Copyright   : 2018 Monadic GmbH+-- License     : BSD3+-- Maintainer  : kim@monadic.xyz, team@monadic.xyz+-- Stability   : provisional+-- Portability : non-portable (GHC extensions)+--+-- A mapping of <https://github.com/multiformats/multihash multihash> to CBOR.+--+-- Instead of an opaque, multihash-encoded blob, this provides a tagged CBOR+-- encoding where the hash algorithm used is a 'Word16' field containing the+-- multihash code for the algorithm, followed by the digest bytes.+module Codec.Serialise.Multihash+    ( encode+    , decode++    -- * Re-exports+    , Multihashable+    )+where++import qualified Codec.Serialise as CBOR+import qualified Codec.Serialise.Decoding as CBOR+import qualified Codec.Serialise.Encoding as CBOR+import           Control.Applicative (liftA2)+import qualified Crypto.Hash as C+import           Data.ByteArray (convert)+import           Data.Multihash (Multihashable)+import qualified Data.Multihash as Multi+import           Data.Proxy (Proxy(..))++-- | Multihash-like CBOR 'CBOR.Encoding' of a 'C.Digest'.+encode :: Multihashable a => C.Digest a -> CBOR.Encoding+encode dig =+       CBOR.encodeListLen 3+    <> CBOR.encodeWord 0    -- constructor tag / version+    <> CBOR.encode (Multi.toCode (Multi.fromCryptonite dig))+    <> CBOR.encodeBytes (convert dig)++-- | CBOR 'CBOR.Decoder' to decode a 'C.Digest' encoded via 'encodeCBOR'.+decode :: forall s a. Multihashable a => CBOR.Decoder s (C.Digest a)+decode = do+    pre <- liftA2 (,) CBOR.decodeListLen CBOR.decodeWord+    case pre of+        (3, 0) -> do+            rithm <- Multi.fromCode <$> CBOR.decode+            case rithm of+                Nothing -> fail "Unknown HashAlgorithm"+                Just  a+                    | Multi.fromCryptonite (Proxy @a) /= a ->+                        fail "Algorithm Mismatch"+                    | otherwise -> do+                        bytes <- CBOR.decodeBytes+                        maybe (fail "Invalid Digest") pure+                            $ C.digestFromByteString bytes++        _ -> fail "Multihash: Invalid Tag"
+ test/properties/Main.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE TemplateHaskell #-}++module Main (main) where++import           Control.Monad (unless)+import qualified Crypto.Hash as C+import           System.Exit (exitFailure)+import           System.IO (BufferMode(..), hSetBuffering, stderr, stdout)++import qualified Codec.Serialise as CBOR+import           Codec.Serialise.Multihash (Multihashable)+import qualified Codec.Serialise.Multihash as Multihash++import           Hedgehog+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++main :: IO ()+main = do+    hSetBuffering stdout LineBuffering+    hSetBuffering stderr LineBuffering++    ok <- props+    unless ok exitFailure++props :: IO Bool+props = checkParallel $$(discover)++newtype Digest' a = Digest' { unDigest' :: C.Digest a }+    deriving (Eq, Show)++instance Multihashable a => CBOR.Serialise (Digest' a) where+    encode = Multihash.encode . unDigest'+    decode = Digest' <$> Multihash.decode++prop_roundtrip :: Property+prop_roundtrip = property $ do+    bs <- forAll $ Gen.bytes (Range.singleton 128)+    let digest = Digest' $ C.hashWith C.Blake2b_256 bs+    tripping digest CBOR.serialise CBOR.deserialiseOrFail