Skip to content

Reformat source files #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Setup.hs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import Distribution.Simple

main = defaultMain
133 changes: 67 additions & 66 deletions cmd/interop-entrypoint/Main.hs
Original file line number Diff line number Diff line change
@@ -1,101 +1,99 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}
-- | Entrypoint for testing interoperability.
--
-- Interoperability harness lives at <https://github.com/leastauthority/spake2-interop-test>
--
-- Any entry point for the harness needs to:
-- - take everything it needs as command-line parameters
-- - print the outbound message to stdout, base16-encoded
-- - read the inbound message from stdin, base16-encoded
-- - print the session key, base16-encoded
-- - terminate
--
-- Much of the code in here will probably move to the library as we figure out
-- what we need to do to implement the protocol properly.

{- | Entrypoint for testing interoperability.

Interoperability harness lives at <https://github.com/leastauthority/spake2-interop-test>

Any entry point for the harness needs to:
- take everything it needs as command-line parameters
- print the outbound message to stdout, base16-encoded
- read the inbound message from stdin, base16-encoded
- print the session key, base16-encoded
- terminate

Much of the code in here will probably move to the library as we figure out
what we need to do to implement the protocol properly.
-}
module Main (main) where

import Protolude hiding (group, toS)
import Protolude.Conv (toS)

import Crypto.Hash (SHA256(..))
import Data.ByteArray.Encoding (convertFromBase, convertToBase, Base(Base16))
import Crypto.Hash (SHA256 (..))
import Data.ByteArray.Encoding (Base (Base16), convertFromBase, convertToBase)
import Data.String (String)
import Options.Applicative
import System.IO (hFlush, hGetLine)

import qualified Crypto.Spake2 as Spake2
import Crypto.Spake2
( Password
, Protocol
, SideID(..)
, makeSymmetricProtocol
, makeAsymmetricProtocol
, makePassword
, spake2Exchange
)
import Crypto.Spake2.Group (AbelianGroup, Group(..))
import Crypto.Spake2.Groups (Ed25519(..))

( Password
, Protocol
, SideID (..)
, makeAsymmetricProtocol
, makePassword
, makeSymmetricProtocol
, spake2Exchange
)
import qualified Crypto.Spake2 as Spake2
import Crypto.Spake2.Group (AbelianGroup, Group (..))
import Crypto.Spake2.Groups (Ed25519 (..))

data Config = Config Side Password deriving (Eq, Ord)

data Side = SideA | SideB | Symmetric deriving (Eq, Ord, Show)

configParser :: Parser Config
configParser =
Config
<$> argument sideParser (metavar "SIDE")
<*> argument passwordParser (metavar "PASSWORD")
Config
<$> argument sideParser (metavar "SIDE")
<*> argument passwordParser (metavar "PASSWORD")
where
sideParser = eitherReader $ \s ->
case s of
"A" -> pure SideA
"B" -> pure SideB
"Symmetric" -> pure Symmetric
unknown -> throwError $ "Unrecognized side: " <> unknown
case s of
"A" -> pure SideA
"B" -> pure SideB
"Symmetric" -> pure Symmetric
unknown -> throwError $ "Unrecognized side: " <> unknown
passwordParser = makePassword . toS @String <$> str

-- | Terminate the test with a failure, printing a message to stderr.
abort :: HasCallStack => Text -> IO ()
abort message = do
hPutStrLn stderr ("ERROR: " <> message)
exitWith (ExitFailure 1)

hPutStrLn stderr ("ERROR: " <> message)
exitWith (ExitFailure 1)

runInteropTest
:: (HasCallStack, AbelianGroup group)
=> Protocol group SHA256
-> Password
-> Handle
-> Handle
-> IO ()
:: (HasCallStack, AbelianGroup group)
=> Protocol group SHA256
-> Password
-> Handle
-> Handle
-> IO ()
runInteropTest protocol password inH outH = do
sessionKey' <- spake2Exchange protocol password output input
case sessionKey' of
Left err -> abort $ show err
Right sessionKey -> output sessionKey
sessionKey' <- spake2Exchange protocol password output input
case sessionKey' of
Left err -> abort $ show err
Right sessionKey -> output sessionKey
where
output :: ByteString -> IO ()
output message = do
hPutStrLn outH (convertToBase Base16 message :: ByteString)
hFlush outH
hPutStrLn outH (convertToBase Base16 message :: ByteString)
hFlush outH

input :: IO (Either Text ByteString)
input = do
line <- hGetLine inH
case convertFromBase Base16 (toS line :: ByteString) of
Left err -> pure . Left . toS $ "Could not decode line (reason: " <> err <> "): " <> show line
Right bytes -> pure (Right bytes)

line <- hGetLine inH
case convertFromBase Base16 (toS line :: ByteString) of
Left err -> pure . Left . toS $ "Could not decode line (reason: " <> err <> "): " <> show line
Right bytes -> pure (Right bytes)

makeProtocolFromSide :: Side -> Protocol Ed25519 SHA256
makeProtocolFromSide side =
case side of
SideA -> makeAsymmetricProtocol hashAlg group m n idA idB Spake2.SideA
SideB -> makeAsymmetricProtocol hashAlg group m n idA idB Spake2.SideB
Symmetric -> makeSymmetricProtocol hashAlg group s idSymmetric
case side of
SideA -> makeAsymmetricProtocol hashAlg group m n idA idB Spake2.SideA
SideB -> makeAsymmetricProtocol hashAlg group m n idA idB Spake2.SideB
Symmetric -> makeSymmetricProtocol hashAlg group s idSymmetric
where
hashAlg = SHA256
group = Ed25519
Expand All @@ -108,11 +106,14 @@ makeProtocolFromSide side =

main :: IO ()
main = do
Config side password <- execParser opts
let protocol = makeProtocolFromSide side
runInteropTest protocol password stdin stdout
exitSuccess
Config side password <- execParser opts
let protocol = makeProtocolFromSide side
runInteropTest protocol password stdin stdout
exitSuccess
where
opts = info (helper <*> configParser)
(fullDesc <>
header "interop-entrypoint - tool to help test SPAKE2 interop")
opts =
info
(helper <*> configParser)
( fullDesc
<> header "interop-entrypoint - tool to help test SPAKE2 interop"
)
14 changes: 14 additions & 0 deletions fourmolu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
indentation: 4
function-arrows: "leading"
comma-style: "leading"
import-export-style: "leading"
indent-wheres: false
record-brace-space: false
newlines-between-decls: 1
haddock-style: "multi-line"
haddock-style-module:
let-style: "auto"
in-style: "right-align"
respectful: true
fixities: []
unicode: "detect"
2 changes: 2 additions & 0 deletions spake2.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ test-suite tasty
, protolude >=0.3 && <0.4
, spake2
, tasty
, hspec >= 2.10 && <3
, tasty-hspec
, hspec-expectations >= 0.8.2 && <0.9
other-modules:
Groups
Integration
Expand Down
Loading