-- | Extract an element on the group from an incoming message.
--
-- Returns a 'MessageError' if we cannot decode the message,
-- or the other side does not appear to be the expected other side.
--
-- TODO: Need to protect against reflection attack at some point.
extractElement :: Group group => Protocol group hashAlgorithm -> ByteString -> Either (MessageError error) (Element group)
extractElement protocol message =
  case ByteString.uncons message of
    Nothing -> throwError EmptyMessage
    Just (prefix, msg)
      | prefix /= theirPrefix (relation protocol) -> throwError $ UnexpectedPrefix prefix (theirPrefix (relation protocol))
      | otherwise ->
        case decodeElement (group protocol) msg of
          CryptoFailed err -> throwError (BadCrypto err msg)
          CryptoPassed element -> pure element


-- | One side of the SPAKE2 protocol.
extractElement :: Group group => Protocol group hashAlgorithm -> ByteString -> Either (MessageError error) (Element group)
extractElement protocol message =
  case ByteString.uncons message of
    Nothing -> throwError EmptyMessage
    Just (prefix, msg)
      | prefix /= theirPrefix (relation protocol) -> throwError $ UnexpectedPrefix prefix (theirPrefix (relation protocol))
      | otherwise ->
        case decodeElement (group protocol) msg of
          CryptoFailed err -> throwError (BadCrypto err msg)
          CryptoPassed element -> pure element


-- | One side of the SPAKE2 protocol.
extractElement protocol message =
  case ByteString.uncons message of
    Nothing -> throwError EmptyMessage
    Just (prefix, msg)
      | prefix /= theirPrefix (relation protocol) -> throwError $ UnexpectedPrefix prefix (theirPrefix (relation protocol))
      | otherwise ->
        case decodeElement (group protocol) msg of
          CryptoFailed err -> throwError (BadCrypto err msg)
          CryptoPassed element -> pure element


-- | One side of the SPAKE2 protocol.