spake2-0.2.0: tests/Spake2.hs
module Spake2 (tests) where
import Protolude hiding (group)
import Test.Tasty (TestTree)
import Test.Tasty.Hspec (testSpec, describe, it, shouldBe, shouldNotBe)
import Crypto.Hash (SHA256(..))
import qualified Crypto.Spake2 as Spake2
import qualified Crypto.Spake2.Group as Group
import Crypto.Spake2.Groups (Ed25519(..))
tests :: IO TestTree
tests = testSpec "Spake2" $ do
describe "Asymmetric protocol" $ do
it "Produces matching session keys when passwords match" $ do
let password = Spake2.makePassword "abc"
let hashAlg = SHA256
let group = Ed25519
let m = Group.arbitraryElement group ("M" :: ByteString)
let n = Group.arbitraryElement group ("N" :: ByteString)
let idA = Spake2.SideID ""
let idB = Spake2.SideID ""
let protocolA = Spake2.makeAsymmetricProtocol hashAlg group m n idA idB Spake2.SideA
let protocolB = Spake2.makeAsymmetricProtocol hashAlg group m n idA idB Spake2.SideB
sideA <- Spake2.startSpake2 protocolA password
sideB <- Spake2.startSpake2 protocolB password
let aOut = Spake2.computeOutboundMessage sideA
let bOut = Spake2.computeOutboundMessage sideB
let aKey = Spake2.generateKeyMaterial sideA bOut
let bKey = Spake2.generateKeyMaterial sideB aOut
let aSessionKey = Spake2.createSessionKey protocolA aOut bOut aKey password
let bSessionKey = Spake2.createSessionKey protocolA aOut bOut bKey password
aSessionKey `shouldBe` bSessionKey
it "Produces differing session keys when passwords do not match" $ do
let password1 = Spake2.makePassword "abc"
let password2 = Spake2.makePassword "cba"
let hashAlg = SHA256
let group = Ed25519
let m = Group.arbitraryElement group ("M" :: ByteString)
let n = Group.arbitraryElement group ("N" :: ByteString)
let idA = Spake2.SideID ""
let idB = Spake2.SideID ""
let protocolA = Spake2.makeAsymmetricProtocol hashAlg group m n idA idB Spake2.SideA
let protocolB = Spake2.makeAsymmetricProtocol hashAlg group m n idA idB Spake2.SideB
sideA <- Spake2.startSpake2 protocolA password1
sideB <- Spake2.startSpake2 protocolB password2
let aOut = Spake2.computeOutboundMessage sideA
let bOut = Spake2.computeOutboundMessage sideB
let aKey = Spake2.generateKeyMaterial sideA bOut
let bKey = Spake2.generateKeyMaterial sideB aOut
let aSessionKey = Spake2.createSessionKey protocolA aOut bOut aKey password1
let bSessionKey = Spake2.createSessionKey protocolA aOut bOut bKey password2
aSessionKey `shouldNotBe` bSessionKey
describe "Symmetric protocol" $ do
it "Produces matching session keys when passwords match" $ do
let password = Spake2.makePassword "abc"
let hashAlg = SHA256
let group = Ed25519
let s = Group.arbitraryElement group ("M" :: ByteString)
let idSymmetric = Spake2.SideID ""
let protocol1 = Spake2.makeSymmetricProtocol hashAlg group s idSymmetric
let protocol2 = Spake2.makeSymmetricProtocol hashAlg group s idSymmetric
side1 <- Spake2.startSpake2 protocol1 password
side2 <- Spake2.startSpake2 protocol2 password
let out1 = Spake2.computeOutboundMessage side1
let out2 = Spake2.computeOutboundMessage side2
let key1 = Spake2.generateKeyMaterial side1 out2
let key2 = Spake2.generateKeyMaterial side2 out1
let sessionKey1 = Spake2.createSessionKey protocol1 out1 out2 key1 password
let sessionKey2 = Spake2.createSessionKey protocol2 out1 out2 key2 password
sessionKey1 `shouldBe` sessionKey2
it "Produces differing session keys when passwords do not match" $ do
let password1 = Spake2.makePassword "abc"
let password2 = Spake2.makePassword "cba"
let hashAlg = SHA256
let group = Ed25519
let s = Group.arbitraryElement group ("M" :: ByteString)
let idSymmetric = Spake2.SideID ""
let protocol1 = Spake2.makeSymmetricProtocol hashAlg group s idSymmetric
let protocol2 = Spake2.makeSymmetricProtocol hashAlg group s idSymmetric
side1 <- Spake2.startSpake2 protocol1 password1
side2 <- Spake2.startSpake2 protocol2 password2
let out1 = Spake2.computeOutboundMessage side1
let out2 = Spake2.computeOutboundMessage side2
let key1 = Spake2.generateKeyMaterial side1 out2
let key2 = Spake2.generateKeyMaterial side2 out1
let sessionKey1 = Spake2.createSessionKey protocol1 out1 out2 key1 password1
let sessionKey2 = Spake2.createSessionKey protocol2 out1 out2 key2 password2
sessionKey1 `shouldNotBe` sessionKey2