packages feed

nostr-1.3.0.0: test/Test/Nostr/CryptoSpec.hs

{-# LANGUAGE OverloadedStrings #-}

module Test.Nostr.CryptoSpec (spec) where

import Test.Hspec
import Nostr.Crypto
import Nostr.Event hiding (validateEvent)
import qualified Data.Text as T

spec :: Spec
spec = do
  describe "Nostr.Crypto" $ do
    
    describe "Key Generation and Validation" $ do
      it "generates a valid key pair where pub key is derived from sec key" $ do
        (sec, pub) <- generateKeyPair
        let keys = Keys sec pub Nothing
        isValid <- validateKeys keys
        isValid `shouldBe` True

    describe "Signing and Verification" $ do
      it "successfully signs an event and verifies its signature" $ do
        (sec, pub) <- generateKeyPair
        let unsigned = createUnsignedEvent pub 1672531200 1 [] "hello crypto"
        signedResult <- signEvent sec unsigned
        case signedResult of
          Left err -> expectationFailure $ "Signing failed: " <> T.unpack err
          Right signedEvent -> do
            isValid <- verifySignature signedEvent
            isValid `shouldBe` True
            
            isValidFull <- validateEvent signedEvent
            isValidFull `shouldBe` True

      it "fails verification if content is tampered with" $ do
        (sec, pub) <- generateKeyPair
        let unsigned = createUnsignedEvent pub 1672531200 1 [] "hello crypto"
        signedResult <- signEvent sec unsigned
        case signedResult of
          Left err -> expectationFailure $ "Signing failed: " <> T.unpack err
          Right signedEvent -> do
            let tamperedEvent = signedEvent { eventContent = "tampered" }
            isValid <- validateEvent tamperedEvent
            isValid `shouldBe` False

      it "fails verification if signature is tampered with" $ do
        (sec, pub) <- generateKeyPair
        let unsigned = createUnsignedEvent pub 1672531200 1 [] "hello crypto"
        signedResult <- signEvent sec unsigned
        case signedResult of
          Left err -> expectationFailure $ "Signing failed: " <> T.unpack err
          Right signedEvent -> do
            let invalidSigHex = T.replicate 128 "0"
            let invalidSig = case mkSignature invalidSigHex of
                               Right s -> s
                               Left _ -> error "Invalid mock signature"
            let tamperedEvent = signedEvent { eventSig = invalidSig }
            isValid <- validateEvent tamperedEvent
            isValid `shouldBe` False

    describe "Hex conversion" $ do
      it "converts back and forth successfully" $ do
        let originalHex = "deadbeef12345678"
        case hexToBytes originalHex of
          Left err -> expectationFailure $ "Hex conversion failed: " <> T.unpack err
          Right bytes -> do
            bytesToHex bytes `shouldBe` originalHex