<commit_before>{-# LANGUAGE OverloadedStrings #-}
{-# Language ScopedTypeVariables #-}

module Unison.Runtime.Cryptography where

import Unison.Cryptography
import Data.ByteString (ByteString)
--import qualified Data.ByteString as BS
import Data.ByteArray as BA
import qualified Crypto.Random as R
import qualified Crypto.Noise.Cipher as C
import qualified Crypto.Noise.Cipher.ChaChaPoly1305 as CCP

-- cryptonite
-- import Crypto.Cipher.Types.Base ()
-- import Crypto.Cipher.AES.Primitive (AES)
import qualified Crypto.Cipher.AES as AES
import Crypto.Cipher.Types
import Crypto.Error

-- Creates a Unison.Cryptography object specialized to use the noise protocol
-- (http://noiseprotocol.org/noise.html).
mkCrypto :: forall cleartext symmetricKey . (ByteArrayAccess cleartext, ByteArray cleartext, ByteArrayAccess symmetricKey, ByteArray symmetricKey) => ByteString -> Cryptography ByteString symmetricKey () () () () cleartext
mkCrypto key = Cryptography key gen hash sign verify randomBytes encryptAsymmetric decryptAsymmetric encrypt decrypt pipeInitiator pipeResponder where
  -- generates an elliptic curve keypair, for use in ECDSA
  gen = undefined
  hash = undefined
  sign _ = undefined
  verify _ _ _ = undefined
  randomBytes = randomBytes'
  encryptAsymmetric _ cleartext = undefined
  decryptAsymmetric ciphertext = undefined

  encrypt :: symmetricKey -> [cleartext] -> IO Ciphertext
  encrypt = encrypt'
      
  decrypt :: symmetricKey -> ByteString -> Either String cleartext
  decrypt = decrypt'

  pipeInitiator _ = undefined
  pipeResponder = undefined

randomBytes' :: Int -> IO ByteString
randomBytes' n = do drg <- R.getSystemDRG
                    let bts = fst $ R.randomBytesGenerate n drg
                    return bts

authTagBitLength = 128 :: Int

encrypt' :: forall cleartext symmetricKey .
            ( ByteArrayAccess cleartext
            , ByteArray cleartext
            , ByteArrayAccess symmetricKey
            , ByteArray symmetricKey)
         => symmetricKey
         -> [cleartext]
         -> IO Ciphertext
encrypt' k cts = do
  iv <- randomBytes' 16
  let clrtext = BA.concat cts :: cleartext
      cipher = throwCryptoError $ cipherInit k :: AES.AES128
      ciphertext = case throwCryptoError $ aeadInit AEAD_GCM cipher iv of
        (AEAD aead st) -> let (out, st') = (aeadImplEncrypt aead st clrtext)
                              (AuthTag auth) = aeadImplFinalize aead st authTagBitLength
                              ciphertext = BA.append (BA.convert auth) out
                          in (BA.convert ciphertext)
  return ciphertext

decrypt' :: ( ByteArrayAccess symmetricKey
            , ByteArray cleartext)
         => symmetricKey<commit_msg>Refactor `encrypt` implementation.<commit_after>{-# LANGUAGE OverloadedStrings #-}
{-# Language ScopedTypeVariables #-}

module Unison.Runtime.Cryptography where

import Unison.Cryptography
import Data.ByteString (ByteString)
--import qualified Data.ByteString as BS
import Data.ByteArray as BA
import qualified Crypto.Random as R
import qualified Crypto.Noise.Cipher as C
import qualified Crypto.Noise.Cipher.ChaChaPoly1305 as CCP

-- cryptonite
-- import Crypto.Cipher.Types.Base ()
-- import Crypto.Cipher.AES.Primitive (AES)
import qualified Crypto.Cipher.AES as AES
import Crypto.Cipher.Types
import Crypto.Error

-- Creates a Unison.Cryptography object specialized to use the noise protocol
-- (http://noiseprotocol.org/noise.html).
mkCrypto :: forall cleartext symmetricKey . (ByteArrayAccess cleartext, ByteArray cleartext, ByteArrayAccess symmetricKey, ByteArray symmetricKey) => ByteString -> Cryptography ByteString symmetricKey () () () () cleartext
mkCrypto key = Cryptography key gen hash sign verify randomBytes encryptAsymmetric decryptAsymmetric encrypt decrypt pipeInitiator pipeResponder where
  -- generates an elliptic curve keypair, for use in ECDSA
  gen = undefined
  hash = undefined
  sign _ = undefined
  verify _ _ _ = undefined
  randomBytes = randomBytes'
  encryptAsymmetric _ cleartext = undefined
  decryptAsymmetric ciphertext = undefined

  encrypt :: symmetricKey -> [cleartext] -> IO Ciphertext
  encrypt = encrypt'
      
  decrypt :: symmetricKey -> ByteString -> Either String cleartext
  decrypt = decrypt'

  pipeInitiator _ = undefined
  pipeResponder = undefined

randomBytes' :: Int -> IO ByteString
randomBytes' n = do drg <- R.getSystemDRG
                    let bts = fst $ R.randomBytesGenerate n drg
                    return bts

authTagBitLength = 128 :: Int

encrypt' :: forall cleartext symmetricKey .
            ( ByteArrayAccess cleartext
            , ByteArray cleartext
            , ByteArrayAccess symmetricKey
            , ByteArray symmetricKey)
         => symmetricKey
         -> [cleartext]
         -> IO Ciphertext
encrypt' k cts = do
  iv <- randomBytes' 16
  let clrtext = BA.concat cts :: cleartext
      cipher = throwCryptoError $ cipherInit k :: AES.AES128
      aead = throwCryptoError $ aeadInit AEAD_GCM cipher iv
      ad = "" :: ByteString -- associated data
      ((AuthTag auth), out) = aeadSimpleEncrypt aead ad clrtext authTagBitLength
      ciphertext = BA.convert (BA.append (BA.convert auth) out)
  return ciphertext

decrypt' :: ( ByteArrayAccess symmetricKey
            , ByteArray cleartext)
         => symmetricKey
{'fraction_non_alphanumeric': 0.0744780891480158, 'fraction_numerical': 0.00451382358472823, 'mean_word_length': 3.217287866772403, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '397632', 'n_tokens_mistral': 1549, 'n_tokens_neox': 1474, 'n_words': 459}