boxInternal :: Maybe Chain
     -> KeyPair              -- ^ Ephemeral keys
     -> Maybe KeyPair        -- ^ Sender keys
     -> PublicKey Noise -- ^ Receiver public key
     -> Word32               -- ^ Padding length
     -> ByteString           -- ^ Plaintext
     -> IO (Box, Chain)      -- ^ Output
boxInternal chain eph sender recvPK pad plaintext = do
  let (hdr, key2) = header chainIn eph sender recvPK
  (ct, chainOut) <- ciphertext key2 pad (Just hdr) plaintext
  return (Box hdr ct, chainOut)
  where
    chainIn = maybe (Chain chain1) id chain
      where chain1 = B8.pack "Noise_Box_IV" <> B.replicate 32 0x0
boxInternal :: Maybe Chain
     -> KeyPair              -- ^ Ephemeral keys
     -> Maybe KeyPair        -- ^ Sender keys
     -> PublicKey Noise -- ^ Receiver public key
     -> Word32               -- ^ Padding length
     -> ByteString           -- ^ Plaintext
     -> IO (Box, Chain)
boxInternal chain eph sender recvPK pad plaintext = do
  let (hdr, key2) = header chainIn eph sender recvPK
  (ct, chainOut) <- ciphertext key2 pad (Just hdr) plaintext
  return (Box hdr ct, chainOut)
  where
    chainIn = maybe (Chain chain1) id chain
      where chain1 = B8.pack "Noise_Box_IV" <> B.replicate 32 0x0
boxInternal chain eph sender recvPK pad plaintext = do
  let (hdr, key2) = header chainIn eph sender recvPK
  (ct, chainOut) <- ciphertext key2 pad (Just hdr) plaintext
  return (Box hdr ct, chainOut)
  where
    chainIn = maybe (Chain chain1) id chain
      where chain1 = B8.pack "Noise_Box_IV" <> B.replicate 32 0x0