{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Test.Consensus.Committee.TestCrypto
(
TestCrypto
, VoteSignature (TestVoteSignature, unTestVoteSignature)
, VRFElectionInput (TestVRFElectionInput, unTestVRFElectionInput)
, VRFOutput (TestVRFOutput, unTestVRFOutput)
, genElectionId
, genVoteCandidate
, genKeyPair
, prop_SignAndVerifyVote
, prop_SignAndVerifyAggregateVote
, prop_EvalAndVerifyVRFOutput
, prop_EvalAndVerifyAggregateVRFOutput
, tests
) where
import Cardano.Crypto.DSIGN
( BLS12381MinSigDSIGN
, DSIGNAlgorithm (..)
)
import Cardano.Crypto.Hash (ByteString, Hash)
import qualified Cardano.Crypto.Hash as Hash
import Cardano.Ledger.BaseTypes (Nonce (..))
import Cardano.Ledger.Binary (runByteBuilder)
import Cardano.Ledger.Hashes (HASH)
import Control.Monad (when)
import Control.Monad.Zip (MonadZip (..))
import Data.Bifunctor (Bifunctor (..))
import qualified Data.ByteString as BS
import qualified Data.ByteString.Builder as BS
import qualified Data.ByteString.Builder.Extra as BS
import Data.Containers.NonEmpty (HasNonEmpty (..))
import Data.Either (fromRight)
import qualified Data.List.NonEmpty as NonEmpty
import Data.Maybe (fromMaybe)
import Data.Proxy (Proxy (..))
import Data.Word (Word64)
import GHC.Word (Word8)
import Ouroboros.Consensus.Committee.Crypto
( CryptoSupportsAggregateVoteSigning (..)
, CryptoSupportsBatchVRFVerification (..)
, CryptoSupportsVRF (..)
, CryptoSupportsVoteSigning (..)
, ElectionId
, PrivateKey
, PublicKey
, VRFPoolContext (..)
, VoteCandidate
)
import Ouroboros.Consensus.Committee.Crypto.BLS (KeyRole (..))
import qualified Ouroboros.Consensus.Committee.Crypto.BLS as BLS
import Test.Consensus.Committee.Utils (genEpochNonce)
import Test.QuickCheck
( Arbitrary (..)
, Gen
, Property
, Small (..)
, Testable (..)
, choose
, counterexample
, forAll
, suchThat
, tabulate
, vectorOf
, (===)
)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.QuickCheck (testProperty)
import Test.Util.TestEnv (adjustQuickCheckTests)
data TestCrypto
type instance ElectionId TestCrypto = Word64
type instance VoteCandidate TestCrypto = ByteString
type instance PrivateKey TestCrypto = (BLS.PrivateKey SIGN, BLS.PrivateKey VRF)
type instance PublicKey TestCrypto = (BLS.PublicKey SIGN, BLS.PublicKey VRF)
hashVoteSignature ::
ElectionId TestCrypto ->
VoteCandidate TestCrypto ->
Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
hashVoteSignature :: ElectionId TestCrypto
-> VoteCandidate TestCrypto
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
hashVoteSignature ElectionId TestCrypto
electionId VoteCandidate TestCrypto
candidate =
Hash HASH ByteString -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
forall h a b. Hash h a -> Hash h b
Hash.castHash
(Hash HASH ByteString -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN))
-> (Builder -> Hash HASH ByteString)
-> Builder
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> ByteString) -> ByteString -> Hash HASH ByteString
forall h a. HashAlgorithm h => (a -> ByteString) -> a -> Hash h a
Hash.hashWith ByteString -> ByteString
forall a. a -> a
id
(ByteString -> Hash HASH ByteString)
-> (Builder -> ByteString) -> Builder -> Hash HASH ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Builder -> ByteString
runByteBuilder (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
32)
(Builder -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN))
-> Builder -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
forall a b. (a -> b) -> a -> b
$ Builder
electionIdBytes Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
candidateBytes
where
electionIdBytes :: Builder
electionIdBytes =
Word64 -> Builder
BS.word64BE Word64
ElectionId TestCrypto
electionId
candidateBytes :: Builder
candidateBytes =
ByteString -> Builder
BS.byteStringCopy ByteString
VoteCandidate TestCrypto
candidate
hashVRFInput ::
ElectionId TestCrypto ->
Nonce ->
Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
hashVRFInput :: ElectionId TestCrypto
-> Nonce -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
hashVRFInput ElectionId TestCrypto
electionId Nonce
epochNonce =
Hash HASH ByteString -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
forall h a b. Hash h a -> Hash h b
Hash.castHash
(Hash HASH ByteString -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN))
-> (Builder -> Hash HASH ByteString)
-> Builder
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> ByteString) -> ByteString -> Hash HASH ByteString
forall h a. HashAlgorithm h => (a -> ByteString) -> a -> Hash h a
Hash.hashWith ByteString -> ByteString
forall a. a -> a
id
(ByteString -> Hash HASH ByteString)
-> (Builder -> ByteString) -> Builder -> Hash HASH ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Builder -> ByteString
runByteBuilder (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
32)
(Builder -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN))
-> Builder -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
forall a b. (a -> b) -> a -> b
$ Builder
electionIdBytes Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
epochNonceBytes
where
electionIdBytes :: Builder
electionIdBytes =
Word64 -> Builder
BS.word64BE Word64
ElectionId TestCrypto
electionId
epochNonceBytes :: Builder
epochNonceBytes =
case Nonce
epochNonce of
Nonce
NeutralNonce -> Builder
forall a. Monoid a => a
mempty
Nonce Hash HASH Nonce
h -> ByteString -> Builder
BS.byteStringCopy (Hash HASH Nonce -> ByteString
forall h a. Hash h a -> ByteString
Hash.hashToBytes Hash HASH Nonce
h)
instance CryptoSupportsVoteSigning TestCrypto where
type VoteSigningKey TestCrypto = BLS.PrivateKey SIGN
type VoteVerificationKey TestCrypto = BLS.PublicKey SIGN
newtype VoteSignature TestCrypto
= TestVoteSignature
{ VoteSignature TestCrypto -> Signature SIGN
unTestVoteSignature :: BLS.Signature SIGN
}
deriving newtype (Int -> VoteSignature TestCrypto -> ShowS
[VoteSignature TestCrypto] -> ShowS
VoteSignature TestCrypto -> String
(Int -> VoteSignature TestCrypto -> ShowS)
-> (VoteSignature TestCrypto -> String)
-> ([VoteSignature TestCrypto] -> ShowS)
-> Show (VoteSignature TestCrypto)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VoteSignature TestCrypto -> ShowS
showsPrec :: Int -> VoteSignature TestCrypto -> ShowS
$cshow :: VoteSignature TestCrypto -> String
show :: VoteSignature TestCrypto -> String
$cshowList :: [VoteSignature TestCrypto] -> ShowS
showList :: [VoteSignature TestCrypto] -> ShowS
Show, VoteSignature TestCrypto -> VoteSignature TestCrypto -> Bool
(VoteSignature TestCrypto -> VoteSignature TestCrypto -> Bool)
-> (VoteSignature TestCrypto -> VoteSignature TestCrypto -> Bool)
-> Eq (VoteSignature TestCrypto)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VoteSignature TestCrypto -> VoteSignature TestCrypto -> Bool
== :: VoteSignature TestCrypto -> VoteSignature TestCrypto -> Bool
$c/= :: VoteSignature TestCrypto -> VoteSignature TestCrypto -> Bool
/= :: VoteSignature TestCrypto -> VoteSignature TestCrypto -> Bool
Eq)
getVoteSigningKey :: Proxy TestCrypto
-> PrivateKey TestCrypto -> VoteSigningKey TestCrypto
getVoteSigningKey Proxy TestCrypto
_ = (PrivateKey SIGN, PrivateKey VRF) -> PrivateKey SIGN
PrivateKey TestCrypto -> VoteSigningKey TestCrypto
forall a b. (a, b) -> a
fst
getVoteVerificationKey :: Proxy TestCrypto
-> PublicKey TestCrypto -> VoteVerificationKey TestCrypto
getVoteVerificationKey Proxy TestCrypto
_ = (PublicKey SIGN, PublicKey VRF) -> PublicKey SIGN
PublicKey TestCrypto -> VoteVerificationKey TestCrypto
forall a b. (a, b) -> a
fst
signVote :: VoteSigningKey TestCrypto
-> ElectionId TestCrypto
-> VoteCandidate TestCrypto
-> VoteSignature TestCrypto
signVote VoteSigningKey TestCrypto
sk ElectionId TestCrypto
electionId VoteCandidate TestCrypto
candidate =
Signature SIGN -> VoteSignature TestCrypto
TestVoteSignature
(Signature SIGN -> VoteSignature TestCrypto)
-> (Hash HASH (SigDSIGN BLS12381MinSigDSIGN) -> Signature SIGN)
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
-> VoteSignature TestCrypto
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: KeyRole) msg.
(SignableRepresentation msg, HasBLSContext r) =>
PrivateKey r -> msg -> Signature r
BLS.signWithRole @SIGN VoteSigningKey TestCrypto
PrivateKey SIGN
sk
(Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
-> VoteSignature TestCrypto)
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
-> VoteSignature TestCrypto
forall a b. (a -> b) -> a -> b
$ ElectionId TestCrypto
-> VoteCandidate TestCrypto
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
hashVoteSignature ElectionId TestCrypto
electionId VoteCandidate TestCrypto
candidate
verifyVoteSignature :: VoteVerificationKey TestCrypto
-> ElectionId TestCrypto
-> VoteCandidate TestCrypto
-> VoteSignature TestCrypto
-> Either String ()
verifyVoteSignature VoteVerificationKey TestCrypto
pk ElectionId TestCrypto
electionId VoteCandidate TestCrypto
candidate (TestVoteSignature Signature SIGN
sig) =
forall (r :: KeyRole) msg.
(SignableRepresentation msg, HasBLSContext r) =>
PublicKey r -> msg -> Signature r -> Either String ()
BLS.verifyWithRole @SIGN
VoteVerificationKey TestCrypto
PublicKey SIGN
pk
(ElectionId TestCrypto
-> VoteCandidate TestCrypto
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
hashVoteSignature ElectionId TestCrypto
electionId VoteCandidate TestCrypto
candidate)
Signature SIGN
sig
instance CryptoSupportsAggregateVoteSigning TestCrypto where
type AggregateVoteVerificationKey TestCrypto = VoteVerificationKey TestCrypto
type AggregateVoteSignature TestCrypto = VoteSignature TestCrypto
aggregateVoteVerificationKeys :: Proxy TestCrypto
-> NE [VoteVerificationKey TestCrypto]
-> Either String (AggregateVoteVerificationKey TestCrypto)
aggregateVoteVerificationKeys Proxy TestCrypto
_ NE [VoteVerificationKey TestCrypto]
pks =
forall (r :: KeyRole).
NE [PublicKey r] -> Either String (PublicKey r)
BLS.aggregatePublicKeys @SIGN NE [VoteVerificationKey TestCrypto]
NE [PublicKey SIGN]
pks
aggregateVoteSignatures :: Proxy TestCrypto
-> NE [VoteSignature TestCrypto]
-> Either String (AggregateVoteSignature TestCrypto)
aggregateVoteSignatures Proxy TestCrypto
_ NE [VoteSignature TestCrypto]
sigs = do
aggSig <-
forall (r :: KeyRole).
NE [Signature r] -> Either String (Signature r)
BLS.aggregateSignatures @SIGN
(NonEmpty (Signature SIGN) -> Either String (Signature SIGN))
-> (NE [VoteSignature TestCrypto] -> NonEmpty (Signature SIGN))
-> NE [VoteSignature TestCrypto]
-> Either String (Signature SIGN)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VoteSignature TestCrypto -> Signature SIGN)
-> NonEmpty (VoteSignature TestCrypto) -> NonEmpty (Signature SIGN)
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VoteSignature TestCrypto -> Signature SIGN
unTestVoteSignature
(NE [VoteSignature TestCrypto] -> Either String (Signature SIGN))
-> NE [VoteSignature TestCrypto] -> Either String (Signature SIGN)
forall a b. (a -> b) -> a -> b
$ NE [VoteSignature TestCrypto]
sigs
pure (TestVoteSignature aggSig)
verifyAggregateVoteSignature :: Proxy TestCrypto
-> AggregateVoteVerificationKey TestCrypto
-> ElectionId TestCrypto
-> VoteCandidate TestCrypto
-> AggregateVoteSignature TestCrypto
-> Either String ()
verifyAggregateVoteSignature
Proxy TestCrypto
_
AggregateVoteVerificationKey TestCrypto
aggPk
ElectionId TestCrypto
electionId
VoteCandidate TestCrypto
candidate
AggregateVoteSignature TestCrypto
aggSig = do
forall (r :: KeyRole) msg.
(SignableRepresentation msg, HasBLSContext r) =>
PublicKey r -> msg -> Signature r -> Either String ()
BLS.verifyWithRole @SIGN
AggregateVoteVerificationKey TestCrypto
PublicKey SIGN
aggPk
(ElectionId TestCrypto
-> VoteCandidate TestCrypto
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
hashVoteSignature ElectionId TestCrypto
electionId VoteCandidate TestCrypto
candidate)
(VoteSignature TestCrypto -> Signature SIGN
unTestVoteSignature AggregateVoteSignature TestCrypto
VoteSignature TestCrypto
aggSig)
instance CryptoSupportsVRF TestCrypto where
type VRFSigningKey TestCrypto = BLS.PrivateKey VRF
type VRFVerificationKey TestCrypto = BLS.PublicKey VRF
newtype VRFElectionInput TestCrypto
= TestVRFElectionInput
{ VRFElectionInput TestCrypto
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
unTestVRFElectionInput ::
Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
}
deriving newtype (Int -> VRFElectionInput TestCrypto -> ShowS
[VRFElectionInput TestCrypto] -> ShowS
VRFElectionInput TestCrypto -> String
(Int -> VRFElectionInput TestCrypto -> ShowS)
-> (VRFElectionInput TestCrypto -> String)
-> ([VRFElectionInput TestCrypto] -> ShowS)
-> Show (VRFElectionInput TestCrypto)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VRFElectionInput TestCrypto -> ShowS
showsPrec :: Int -> VRFElectionInput TestCrypto -> ShowS
$cshow :: VRFElectionInput TestCrypto -> String
show :: VRFElectionInput TestCrypto -> String
$cshowList :: [VRFElectionInput TestCrypto] -> ShowS
showList :: [VRFElectionInput TestCrypto] -> ShowS
Show, VRFElectionInput TestCrypto -> VRFElectionInput TestCrypto -> Bool
(VRFElectionInput TestCrypto
-> VRFElectionInput TestCrypto -> Bool)
-> (VRFElectionInput TestCrypto
-> VRFElectionInput TestCrypto -> Bool)
-> Eq (VRFElectionInput TestCrypto)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VRFElectionInput TestCrypto -> VRFElectionInput TestCrypto -> Bool
== :: VRFElectionInput TestCrypto -> VRFElectionInput TestCrypto -> Bool
$c/= :: VRFElectionInput TestCrypto -> VRFElectionInput TestCrypto -> Bool
/= :: VRFElectionInput TestCrypto -> VRFElectionInput TestCrypto -> Bool
Eq)
newtype VRFOutput TestCrypto
= TestVRFOutput
{ VRFOutput TestCrypto -> Signature VRF
unTestVRFOutput ::
BLS.Signature VRF
}
deriving newtype (Int -> VRFOutput TestCrypto -> ShowS
[VRFOutput TestCrypto] -> ShowS
VRFOutput TestCrypto -> String
(Int -> VRFOutput TestCrypto -> ShowS)
-> (VRFOutput TestCrypto -> String)
-> ([VRFOutput TestCrypto] -> ShowS)
-> Show (VRFOutput TestCrypto)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VRFOutput TestCrypto -> ShowS
showsPrec :: Int -> VRFOutput TestCrypto -> ShowS
$cshow :: VRFOutput TestCrypto -> String
show :: VRFOutput TestCrypto -> String
$cshowList :: [VRFOutput TestCrypto] -> ShowS
showList :: [VRFOutput TestCrypto] -> ShowS
Show, VRFOutput TestCrypto -> VRFOutput TestCrypto -> Bool
(VRFOutput TestCrypto -> VRFOutput TestCrypto -> Bool)
-> (VRFOutput TestCrypto -> VRFOutput TestCrypto -> Bool)
-> Eq (VRFOutput TestCrypto)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VRFOutput TestCrypto -> VRFOutput TestCrypto -> Bool
== :: VRFOutput TestCrypto -> VRFOutput TestCrypto -> Bool
$c/= :: VRFOutput TestCrypto -> VRFOutput TestCrypto -> Bool
/= :: VRFOutput TestCrypto -> VRFOutput TestCrypto -> Bool
Eq)
getVRFSigningKey :: Proxy TestCrypto
-> PrivateKey TestCrypto -> VRFSigningKey TestCrypto
getVRFSigningKey Proxy TestCrypto
_ = (PrivateKey SIGN, PrivateKey VRF) -> PrivateKey VRF
PrivateKey TestCrypto -> VRFSigningKey TestCrypto
forall a b. (a, b) -> b
snd
getVRFVerificationKey :: Proxy TestCrypto
-> PublicKey TestCrypto -> VRFVerificationKey TestCrypto
getVRFVerificationKey Proxy TestCrypto
_ = (PublicKey SIGN, PublicKey VRF) -> PublicKey VRF
PublicKey TestCrypto -> VRFVerificationKey TestCrypto
forall a b. (a, b) -> b
snd
mkVRFElectionInput :: Nonce -> ElectionId TestCrypto -> VRFElectionInput TestCrypto
mkVRFElectionInput Nonce
epochNonce ElectionId TestCrypto
electionId =
Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
-> VRFElectionInput TestCrypto
TestVRFElectionInput (Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
-> VRFElectionInput TestCrypto)
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
-> VRFElectionInput TestCrypto
forall a b. (a -> b) -> a -> b
$
ElectionId TestCrypto
-> Nonce -> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
hashVRFInput ElectionId TestCrypto
electionId Nonce
epochNonce
evalVRF :: VRFPoolContext TestCrypto
-> VRFElectionInput TestCrypto
-> Either String (VRFOutput TestCrypto)
evalVRF VRFPoolContext TestCrypto
context (TestVRFElectionInput Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
input) =
case VRFPoolContext TestCrypto
context of
VRFSignContext VRFSigningKey TestCrypto
sk -> do
let sig :: Signature VRF
sig = forall (r :: KeyRole) msg.
(SignableRepresentation msg, HasBLSContext r) =>
PrivateKey r -> msg -> Signature r
BLS.signWithRole @VRF VRFSigningKey TestCrypto
PrivateKey VRF
sk Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
input
VRFOutput TestCrypto -> Either String (VRFOutput TestCrypto)
forall a. a -> Either String a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VRFOutput TestCrypto -> Either String (VRFOutput TestCrypto))
-> VRFOutput TestCrypto -> Either String (VRFOutput TestCrypto)
forall a b. (a -> b) -> a -> b
$ Signature VRF -> VRFOutput TestCrypto
TestVRFOutput Signature VRF
sig
VRFVerifyContext VRFVerificationKey TestCrypto
pk (TestVRFOutput Signature VRF
sig) -> do
forall (r :: KeyRole) msg.
(SignableRepresentation msg, HasBLSContext r) =>
PublicKey r -> msg -> Signature r -> Either String ()
BLS.verifyWithRole @VRF VRFVerificationKey TestCrypto
PublicKey VRF
pk Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
input Signature VRF
sig
VRFOutput TestCrypto -> Either String (VRFOutput TestCrypto)
forall a. a -> Either String a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VRFOutput TestCrypto -> Either String (VRFOutput TestCrypto))
-> VRFOutput TestCrypto -> Either String (VRFOutput TestCrypto)
forall a b. (a -> b) -> a -> b
$ Signature VRF -> VRFOutput TestCrypto
TestVRFOutput Signature VRF
sig
normalizeVRFOutput :: VRFOutput TestCrypto -> NormalizedVRFOutput
normalizeVRFOutput (TestVRFOutput Signature VRF
sig) =
Signature VRF -> NormalizedVRFOutput
BLS.toNormalizedVRFOutput Signature VRF
sig
instance CryptoSupportsBatchVRFVerification TestCrypto where
batchVerifyVRFOutputs :: NE [VRFVerificationKey TestCrypto]
-> VRFElectionInput TestCrypto
-> NE [VRFOutput TestCrypto]
-> Either String ()
batchVerifyVRFOutputs
NE [VRFVerificationKey TestCrypto]
pks
(TestVRFElectionInput Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
input)
NE [VRFOutput TestCrypto]
sigs = do
NE [PublicKey VRF]
-> Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
-> NE [Signature VRF]
-> Either String ()
forall msg.
SignableRepresentation msg =>
NE [PublicKey VRF] -> msg -> NE [Signature VRF] -> Either String ()
BLS.linearizeAndVerifyVRFs
NE [VRFVerificationKey TestCrypto]
NE [PublicKey VRF]
pks
Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
input
(NonEmpty (Signature VRF) -> Either String ())
-> (NE [VRFOutput TestCrypto] -> NonEmpty (Signature VRF))
-> NE [VRFOutput TestCrypto]
-> Either String ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (VRFOutput TestCrypto -> Signature VRF)
-> NonEmpty (VRFOutput TestCrypto) -> NonEmpty (Signature VRF)
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap VRFOutput TestCrypto -> Signature VRF
unTestVRFOutput
(NE [VRFOutput TestCrypto] -> Either String ())
-> NE [VRFOutput TestCrypto] -> Either String ()
forall a b. (a -> b) -> a -> b
$ NE [VRFOutput TestCrypto]
sigs
genElectionId :: Gen (ElectionId TestCrypto)
genElectionId :: Gen (ElectionId TestCrypto)
genElectionId =
Small Word64 -> Word64
forall a. Small a -> a
getSmall (Small Word64 -> Word64) -> Gen (Small Word64) -> Gen Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Small Word64)
forall a. Arbitrary a => Gen a
arbitrary
genVoteCandidate :: Gen (VoteCandidate TestCrypto)
genVoteCandidate :: Gen (VoteCandidate TestCrypto)
genVoteCandidate =
[Word8] -> ByteString
BS.pack ([Word8] -> ByteString) -> Gen [Word8] -> Gen ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen Word8 -> Gen [Word8]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
32 (forall a. Arbitrary a => Gen a
arbitrary @Word8)
genKeyPair :: Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair :: Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair = do
voteSigningKey <- forall (r :: KeyRole). Gen (PrivateKey r)
genPrivateKey @SIGN
vrfSigningKey <- genPrivateKey @VRF
let voteVerificationKey = PrivateKey SIGN -> PublicKey SIGN
forall (r :: KeyRole). PrivateKey r -> PublicKey r
BLS.derivePublicKey PrivateKey SIGN
voteSigningKey
let vrfVerificationKey = PrivateKey VRF -> PublicKey VRF
forall (r :: KeyRole). PrivateKey r -> PublicKey r
BLS.derivePublicKey PrivateKey VRF
vrfSigningKey
return
( (voteSigningKey, vrfSigningKey)
, (voteVerificationKey, vrfVerificationKey)
)
where
genPrivateKey :: forall r. Gen (BLS.PrivateKey r)
genPrivateKey :: forall (r :: KeyRole). Gen (PrivateKey r)
genPrivateKey = do
PrivateKey r -> Maybe (PrivateKey r) -> PrivateKey r
forall a. a -> Maybe a -> a
fromMaybe (String -> PrivateKey r
forall a. HasCallStack => String -> a
error String
"Failed to generate BLS private key")
(Maybe (PrivateKey r) -> PrivateKey r)
-> ([Word8] -> Maybe (PrivateKey r)) -> [Word8] -> PrivateKey r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (r :: KeyRole).
ByteString -> ByteString -> Maybe (PrivateKey r)
BLS.rawDeserialisePrivateKey @r ByteString
"TEST"
(ByteString -> Maybe (PrivateKey r))
-> ([Word8] -> ByteString) -> [Word8] -> Maybe (PrivateKey r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
BS.pack
([Word8] -> PrivateKey r) -> Gen [Word8] -> Gen (PrivateKey r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen Word8 -> Gen [Word8]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
32 (forall a. Arbitrary a => Gen a
arbitrary @Word8)
swapTwoElements :: NE [a] -> Gen (Int, Int, NE [a])
swapTwoElements :: forall a. NE [a] -> Gen (Int, Int, NE [a])
swapTwoElements NE [a]
xs = do
let len :: Int
len = NonEmpty a -> Int
forall a. NonEmpty a -> Int
NonEmpty.length NonEmpty a
NE [a]
xs
Bool -> Gen () -> Gen ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2) (Gen () -> Gen ()) -> Gen () -> Gen ()
forall a b. (a -> b) -> a -> b
$
String -> Gen ()
forall a. HasCallStack => String -> a
error String
"swapTwoElements requires a list with at least two elements"
i <- (Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
j <- choose (0, len - 1) `suchThat` (/= i)
let maybeSwap Int
k
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
i = NonEmpty a -> Int -> a
forall a. HasCallStack => NonEmpty a -> Int -> a
(NonEmpty.!!) NonEmpty a
NE [a]
xs Int
j
| Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
j = NonEmpty a -> Int -> a
forall a. HasCallStack => NonEmpty a -> Int -> a
(NonEmpty.!!) NonEmpty a
NE [a]
xs Int
i
| Bool
otherwise = NonEmpty a -> Int -> a
forall a. HasCallStack => NonEmpty a -> Int -> a
(NonEmpty.!!) NonEmpty a
NE [a]
xs Int
k
let xs' =
[a] -> NonEmpty a
forall a. HasCallStack => [a] -> NonEmpty a
NonEmpty.fromList
[ Int -> a
maybeSwap Int
k
| Int
k <- [Int
0 .. Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
]
return (i, j, xs')
prop_SignAndVerifyVote :: Property
prop_SignAndVerifyVote :: Property
prop_SignAndVerifyVote =
Gen Word64 -> (Word64 -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Word64
Gen (ElectionId TestCrypto)
genElectionId ((Word64 -> Property) -> Property)
-> (Word64 -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Word64
electionId ->
Gen ByteString -> (ByteString -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen ByteString
Gen (VoteCandidate TestCrypto)
genVoteCandidate ((ByteString -> Property) -> Property)
-> (ByteString -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \ByteString
candidate ->
Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair ((((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property)
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \((PrivateKey SIGN, PrivateKey VRF)
sk, (PublicKey SIGN, PublicKey VRF)
pk) -> do
let voteSigningKey :: VoteSigningKey TestCrypto
voteSigningKey = Proxy TestCrypto
-> PrivateKey TestCrypto -> VoteSigningKey TestCrypto
forall crypto.
CryptoSupportsVoteSigning crypto =>
Proxy crypto -> PrivateKey crypto -> VoteSigningKey crypto
getVoteSigningKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto) (PrivateKey SIGN, PrivateKey VRF)
PrivateKey TestCrypto
sk
let voteVerificationKey :: VoteVerificationKey TestCrypto
voteVerificationKey = Proxy TestCrypto
-> PublicKey TestCrypto -> VoteVerificationKey TestCrypto
forall crypto.
CryptoSupportsVoteSigning crypto =>
Proxy crypto -> PublicKey crypto -> VoteVerificationKey crypto
getVoteVerificationKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto) (PublicKey SIGN, PublicKey VRF)
PublicKey TestCrypto
pk
let sig :: VoteSignature TestCrypto
sig = forall crypto.
CryptoSupportsVoteSigning crypto =>
VoteSigningKey crypto
-> ElectionId crypto
-> VoteCandidate crypto
-> VoteSignature crypto
signVote @TestCrypto VoteSigningKey TestCrypto
voteSigningKey Word64
ElectionId TestCrypto
electionId ByteString
VoteCandidate TestCrypto
candidate
case ( forall crypto.
CryptoSupportsVoteSigning crypto =>
VoteVerificationKey crypto
-> ElectionId crypto
-> VoteCandidate crypto
-> VoteSignature crypto
-> Either String ()
verifyVoteSignature @TestCrypto
VoteVerificationKey TestCrypto
voteVerificationKey
Word64
ElectionId TestCrypto
electionId
ByteString
VoteCandidate TestCrypto
candidate
VoteSignature TestCrypto
sig
) of
Left String
err ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
(String
"Round trip verification failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err)
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
Right () ->
Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
prop_SignAndVerifyAggregateVote :: Property
prop_SignAndVerifyAggregateVote :: Property
prop_SignAndVerifyAggregateVote =
Gen Word64 -> (Word64 -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Word64
Gen (ElectionId TestCrypto)
genElectionId ((Word64 -> Property) -> Property)
-> (Word64 -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Word64
electionId ->
Gen ByteString -> (ByteString -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen ByteString
Gen (VoteCandidate TestCrypto)
genVoteCandidate ((ByteString -> Property) -> Property)
-> (ByteString -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \ByteString
candidate ->
Gen Int -> (Int -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll ((Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
1, Int
10)) ((Int -> Property) -> Property) -> (Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Int
numSigners ->
Gen
[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll (Int
-> Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Gen
[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
numSigners Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair) (([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property)
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
keyPairs -> do
let (NonEmpty (PrivateKey SIGN)
voteSigningKeys, NonEmpty (PublicKey SIGN)
voteVerificationKeys) =
NonEmpty (PrivateKey SIGN, PublicKey SIGN)
-> (NonEmpty (PrivateKey SIGN), NonEmpty (PublicKey SIGN))
forall a b. NonEmpty (a, b) -> (NonEmpty a, NonEmpty b)
forall (m :: * -> *) a b. MonadZip m => m (a, b) -> (m a, m b)
munzip
(NonEmpty (PrivateKey SIGN, PublicKey SIGN)
-> (NonEmpty (PrivateKey SIGN), NonEmpty (PublicKey SIGN)))
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> NonEmpty (PrivateKey SIGN, PublicKey SIGN))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey SIGN), NonEmpty (PublicKey SIGN))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(PrivateKey SIGN, PublicKey SIGN)]
-> NonEmpty (PrivateKey SIGN, PublicKey SIGN)
forall a. HasCallStack => [a] -> NonEmpty a
NonEmpty.fromList
([(PrivateKey SIGN, PublicKey SIGN)]
-> NonEmpty (PrivateKey SIGN, PublicKey SIGN))
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [(PrivateKey SIGN, PublicKey SIGN)])
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> NonEmpty (PrivateKey SIGN, PublicKey SIGN)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((PrivateKey SIGN, PrivateKey VRF), PublicKey SIGN)
-> (PrivateKey SIGN, PublicKey SIGN))
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey SIGN)]
-> [(PrivateKey SIGN, PublicKey SIGN)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((PrivateKey SIGN, PrivateKey VRF) -> PrivateKey SIGN)
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey SIGN)
-> (PrivateKey SIGN, PublicKey SIGN)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Proxy TestCrypto
-> PrivateKey TestCrypto -> VoteSigningKey TestCrypto
forall crypto.
CryptoSupportsVoteSigning crypto =>
Proxy crypto -> PrivateKey crypto -> VoteSigningKey crypto
getVoteSigningKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)))
([((PrivateKey SIGN, PrivateKey VRF), PublicKey SIGN)]
-> [(PrivateKey SIGN, PublicKey SIGN)])
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey SIGN)])
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [(PrivateKey SIGN, PublicKey SIGN)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey SIGN))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey SIGN)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((PublicKey SIGN, PublicKey VRF) -> PublicKey SIGN)
-> ((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey SIGN)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (Proxy TestCrypto
-> PublicKey TestCrypto -> VoteVerificationKey TestCrypto
forall crypto.
CryptoSupportsVoteSigning crypto =>
Proxy crypto -> PublicKey crypto -> VoteVerificationKey crypto
getVoteVerificationKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)))
([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey SIGN), NonEmpty (PublicKey SIGN)))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey SIGN), NonEmpty (PublicKey SIGN))
forall a b. (a -> b) -> a -> b
$ [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
keyPairs
let aggVoteSignature :: VoteSignature TestCrypto
aggVoteSignature =
VoteSignature TestCrypto
-> Either String (VoteSignature TestCrypto)
-> VoteSignature TestCrypto
forall b a. b -> Either a b -> b
fromRight (String -> VoteSignature TestCrypto
forall a. HasCallStack => String -> a
error String
"Failed to aggregate vote signatures")
(Either String (VoteSignature TestCrypto)
-> VoteSignature TestCrypto)
-> (NonEmpty (PrivateKey SIGN)
-> Either String (VoteSignature TestCrypto))
-> NonEmpty (PrivateKey SIGN)
-> VoteSignature TestCrypto
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy TestCrypto
-> NE [VoteSignature TestCrypto]
-> Either String (AggregateVoteSignature TestCrypto)
forall crypto.
CryptoSupportsAggregateVoteSigning crypto =>
Proxy crypto
-> NE [VoteSignature crypto]
-> Either String (AggregateVoteSignature crypto)
aggregateVoteSignatures (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)
(NonEmpty (VoteSignature TestCrypto)
-> Either String (VoteSignature TestCrypto))
-> (NonEmpty (PrivateKey SIGN)
-> NonEmpty (VoteSignature TestCrypto))
-> NonEmpty (PrivateKey SIGN)
-> Either String (VoteSignature TestCrypto)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PrivateKey SIGN -> VoteSignature TestCrypto)
-> NonEmpty (PrivateKey SIGN)
-> NonEmpty (VoteSignature TestCrypto)
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\PrivateKey SIGN
sk -> forall crypto.
CryptoSupportsVoteSigning crypto =>
VoteSigningKey crypto
-> ElectionId crypto
-> VoteCandidate crypto
-> VoteSignature crypto
signVote @TestCrypto VoteSigningKey TestCrypto
PrivateKey SIGN
sk Word64
ElectionId TestCrypto
electionId ByteString
VoteCandidate TestCrypto
candidate)
(NonEmpty (PrivateKey SIGN) -> VoteSignature TestCrypto)
-> NonEmpty (PrivateKey SIGN) -> VoteSignature TestCrypto
forall a b. (a -> b) -> a -> b
$ NonEmpty (PrivateKey SIGN)
voteSigningKeys
let aggVoteVerificationKey :: PublicKey SIGN
aggVoteVerificationKey =
PublicKey SIGN -> Either String (PublicKey SIGN) -> PublicKey SIGN
forall b a. b -> Either a b -> b
fromRight (String -> PublicKey SIGN
forall a. HasCallStack => String -> a
error String
"Failed to aggregate vote verification keys")
(Either String (PublicKey SIGN) -> PublicKey SIGN)
-> (NonEmpty (PublicKey SIGN) -> Either String (PublicKey SIGN))
-> NonEmpty (PublicKey SIGN)
-> PublicKey SIGN
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy TestCrypto
-> NE [VoteVerificationKey TestCrypto]
-> Either String (AggregateVoteVerificationKey TestCrypto)
forall crypto.
CryptoSupportsAggregateVoteSigning crypto =>
Proxy crypto
-> NE [VoteVerificationKey crypto]
-> Either String (AggregateVoteVerificationKey crypto)
aggregateVoteVerificationKeys (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)
(NonEmpty (PublicKey SIGN) -> PublicKey SIGN)
-> NonEmpty (PublicKey SIGN) -> PublicKey SIGN
forall a b. (a -> b) -> a -> b
$ NonEmpty (PublicKey SIGN)
voteVerificationKeys
String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulate String
"Number of vote signers" [Int -> String
forall a. Show a => a -> String
show Int
numSigners] (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
case ( Proxy TestCrypto
-> AggregateVoteVerificationKey TestCrypto
-> ElectionId TestCrypto
-> VoteCandidate TestCrypto
-> AggregateVoteSignature TestCrypto
-> Either String ()
forall crypto.
CryptoSupportsAggregateVoteSigning crypto =>
Proxy crypto
-> AggregateVoteVerificationKey crypto
-> ElectionId crypto
-> VoteCandidate crypto
-> AggregateVoteSignature crypto
-> Either String ()
verifyAggregateVoteSignature
(forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)
AggregateVoteVerificationKey TestCrypto
PublicKey SIGN
aggVoteVerificationKey
Word64
ElectionId TestCrypto
electionId
ByteString
VoteCandidate TestCrypto
candidate
AggregateVoteSignature TestCrypto
VoteSignature TestCrypto
aggVoteSignature
) of
Left String
err ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
(String
"Aggregate vote verification failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err)
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
Right () ->
Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
prop_EvalAndVerifyVRFOutput :: Property
prop_EvalAndVerifyVRFOutput :: Property
prop_EvalAndVerifyVRFOutput =
Gen Word64 -> (Word64 -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Word64
Gen (ElectionId TestCrypto)
genElectionId ((Word64 -> Property) -> Property)
-> (Word64 -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Word64
electionId ->
Gen Nonce -> (Nonce -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Nonce
genEpochNonce ((Nonce -> Property) -> Property)
-> (Nonce -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Nonce
epochNonce ->
Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair ((((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property)
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \((PrivateKey SIGN, PrivateKey VRF)
sk, (PublicKey SIGN, PublicKey VRF)
pk) -> do
let vrfSigningKey :: VRFSigningKey TestCrypto
vrfSigningKey = Proxy TestCrypto
-> PrivateKey TestCrypto -> VRFSigningKey TestCrypto
forall crypto.
CryptoSupportsVRF crypto =>
Proxy crypto -> PrivateKey crypto -> VRFSigningKey crypto
getVRFSigningKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto) (PrivateKey SIGN, PrivateKey VRF)
PrivateKey TestCrypto
sk
let vrfVerificationKey :: VRFVerificationKey TestCrypto
vrfVerificationKey = Proxy TestCrypto
-> PublicKey TestCrypto -> VRFVerificationKey TestCrypto
forall crypto.
CryptoSupportsVRF crypto =>
Proxy crypto -> PublicKey crypto -> VRFVerificationKey crypto
getVRFVerificationKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto) (PublicKey SIGN, PublicKey VRF)
PublicKey TestCrypto
pk
let input :: VRFElectionInput TestCrypto
input = forall crypto.
CryptoSupportsVRF crypto =>
Nonce -> ElectionId crypto -> VRFElectionInput crypto
mkVRFElectionInput @TestCrypto Nonce
epochNonce Word64
ElectionId TestCrypto
electionId
case ( forall crypto.
CryptoSupportsVRF crypto =>
VRFPoolContext crypto
-> VRFElectionInput crypto -> Either String (VRFOutput crypto)
evalVRF @TestCrypto
(VRFSigningKey TestCrypto -> VRFPoolContext TestCrypto
forall crypto. VRFSigningKey crypto -> VRFPoolContext crypto
VRFSignContext VRFSigningKey TestCrypto
vrfSigningKey)
VRFElectionInput TestCrypto
input
) of
Left String
err ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
(String
"VRF evaluation failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err)
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
Right VRFOutput TestCrypto
output ->
case ( forall crypto.
CryptoSupportsVRF crypto =>
VRFPoolContext crypto
-> VRFElectionInput crypto -> Either String (VRFOutput crypto)
evalVRF @TestCrypto
(VRFVerificationKey TestCrypto
-> VRFOutput TestCrypto -> VRFPoolContext TestCrypto
forall crypto.
VRFVerificationKey crypto
-> VRFOutput crypto -> VRFPoolContext crypto
VRFVerifyContext VRFVerificationKey TestCrypto
vrfVerificationKey VRFOutput TestCrypto
output)
VRFElectionInput TestCrypto
input
) of
Left String
err ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
(String
"VRF verification failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err)
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
Right VRFOutput TestCrypto
output' ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
String
"VRF output mismatch"
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ VRFOutput TestCrypto
output VRFOutput TestCrypto -> VRFOutput TestCrypto -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== VRFOutput TestCrypto
output'
prop_EvalAndVerifyAggregateVRFOutput :: Property
prop_EvalAndVerifyAggregateVRFOutput :: Property
prop_EvalAndVerifyAggregateVRFOutput =
Gen Word64 -> (Word64 -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Word64
Gen (ElectionId TestCrypto)
genElectionId ((Word64 -> Property) -> Property)
-> (Word64 -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Word64
electionId ->
Gen Nonce -> (Nonce -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Nonce
genEpochNonce ((Nonce -> Property) -> Property)
-> (Nonce -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Nonce
epochNonce ->
Gen Int -> (Int -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll ((Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
1, Int
10)) ((Int -> Property) -> Property) -> (Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Int
numSigners ->
Gen
[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll (Int
-> Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Gen
[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
numSigners Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair) (([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property)
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
keyPairs -> do
let (NonEmpty (PrivateKey VRF)
vrfSigningKeys, NonEmpty (PublicKey VRF)
vrfVerificationKeys) =
NonEmpty (PrivateKey VRF, PublicKey VRF)
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF))
forall a b. NonEmpty (a, b) -> (NonEmpty a, NonEmpty b)
forall (m :: * -> *) a b. MonadZip m => m (a, b) -> (m a, m b)
munzip
(NonEmpty (PrivateKey VRF, PublicKey VRF)
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF)))
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> NonEmpty (PrivateKey VRF, PublicKey VRF))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(PrivateKey VRF, PublicKey VRF)]
-> NonEmpty (PrivateKey VRF, PublicKey VRF)
forall a. HasCallStack => [a] -> NonEmpty a
NonEmpty.fromList
([(PrivateKey VRF, PublicKey VRF)]
-> NonEmpty (PrivateKey VRF, PublicKey VRF))
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [(PrivateKey VRF, PublicKey VRF)])
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> NonEmpty (PrivateKey VRF, PublicKey VRF)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)
-> (PrivateKey VRF, PublicKey VRF))
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)]
-> [(PrivateKey VRF, PublicKey VRF)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((PrivateKey SIGN, PrivateKey VRF) -> PrivateKey VRF)
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)
-> (PrivateKey VRF, PublicKey VRF)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Proxy TestCrypto
-> PrivateKey TestCrypto -> VRFSigningKey TestCrypto
forall crypto.
CryptoSupportsVRF crypto =>
Proxy crypto -> PrivateKey crypto -> VRFSigningKey crypto
getVRFSigningKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)))
([((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)]
-> [(PrivateKey VRF, PublicKey VRF)])
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)])
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [(PrivateKey VRF, PublicKey VRF)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((PublicKey SIGN, PublicKey VRF) -> PublicKey VRF)
-> ((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (Proxy TestCrypto
-> PublicKey TestCrypto -> VRFVerificationKey TestCrypto
forall crypto.
CryptoSupportsVRF crypto =>
Proxy crypto -> PublicKey crypto -> VRFVerificationKey crypto
getVRFVerificationKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)))
([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF)))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF))
forall a b. (a -> b) -> a -> b
$ [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
keyPairs
let input :: VRFElectionInput TestCrypto
input = forall crypto.
CryptoSupportsVRF crypto =>
Nonce -> ElectionId crypto -> VRFElectionInput crypto
mkVRFElectionInput @TestCrypto Nonce
epochNonce Word64
ElectionId TestCrypto
electionId
String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulate String
"Number of VRF signers" [Int -> String
forall a. Show a => a -> String
show Int
numSigners] (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
case ( (PrivateKey VRF -> Either String (VRFOutput TestCrypto))
-> NonEmpty (PrivateKey VRF)
-> Either String (NonEmpty (VRFOutput TestCrypto))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmpty a -> f (NonEmpty b)
traverse
(\PrivateKey VRF
sk -> forall crypto.
CryptoSupportsVRF crypto =>
VRFPoolContext crypto
-> VRFElectionInput crypto -> Either String (VRFOutput crypto)
evalVRF @TestCrypto (VRFSigningKey TestCrypto -> VRFPoolContext TestCrypto
forall crypto. VRFSigningKey crypto -> VRFPoolContext crypto
VRFSignContext VRFSigningKey TestCrypto
PrivateKey VRF
sk) VRFElectionInput TestCrypto
input)
NonEmpty (PrivateKey VRF)
vrfSigningKeys
) of
Left String
err ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
(String
"VRF evaluation failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err)
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
Right NonEmpty (VRFOutput TestCrypto)
vrfOutputs -> do
case ( forall crypto.
CryptoSupportsBatchVRFVerification crypto =>
NE [VRFVerificationKey crypto]
-> VRFElectionInput crypto
-> NE [VRFOutput crypto]
-> Either String ()
batchVerifyVRFOutputs @TestCrypto
NonEmpty (PublicKey VRF)
NE [VRFVerificationKey TestCrypto]
vrfVerificationKeys
VRFElectionInput TestCrypto
input
NonEmpty (VRFOutput TestCrypto)
NE [VRFOutput TestCrypto]
vrfOutputs
) of
Left String
err ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
(String
"Aggregate VRF verification failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err)
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
Right () ->
Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
prop_SwapAttackOnAggregateVRF :: Property
prop_SwapAttackOnAggregateVRF :: Property
prop_SwapAttackOnAggregateVRF =
Gen Word64 -> (Word64 -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Word64
Gen (ElectionId TestCrypto)
genElectionId ((Word64 -> Property) -> Property)
-> (Word64 -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Word64
electionId ->
Gen Nonce -> (Nonce -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Nonce
genEpochNonce ((Nonce -> Property) -> Property)
-> (Nonce -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Nonce
epochNonce ->
Gen Int -> (Int -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll ((Int, Int) -> Gen Int
forall a. Random a => (a, a) -> Gen a
choose (Int
2, Int
10)) ((Int -> Property) -> Property) -> (Int -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Int
numSigners ->
Gen
[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll (Int
-> Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Gen
[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
forall a. Int -> Gen a -> Gen [a]
vectorOf Int
numSigners Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair) (([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property)
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \[((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
keyPairs -> do
let (NonEmpty (PrivateKey VRF)
vrfSigningKeys, NonEmpty (PublicKey VRF)
vrfVerificationKeys) =
NonEmpty (PrivateKey VRF, PublicKey VRF)
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF))
forall a b. NonEmpty (a, b) -> (NonEmpty a, NonEmpty b)
forall (m :: * -> *) a b. MonadZip m => m (a, b) -> (m a, m b)
munzip
(NonEmpty (PrivateKey VRF, PublicKey VRF)
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF)))
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> NonEmpty (PrivateKey VRF, PublicKey VRF))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(PrivateKey VRF, PublicKey VRF)]
-> NonEmpty (PrivateKey VRF, PublicKey VRF)
forall a. HasCallStack => [a] -> NonEmpty a
NonEmpty.fromList
([(PrivateKey VRF, PublicKey VRF)]
-> NonEmpty (PrivateKey VRF, PublicKey VRF))
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [(PrivateKey VRF, PublicKey VRF)])
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> NonEmpty (PrivateKey VRF, PublicKey VRF)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)
-> (PrivateKey VRF, PublicKey VRF))
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)]
-> [(PrivateKey VRF, PublicKey VRF)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((PrivateKey SIGN, PrivateKey VRF) -> PrivateKey VRF)
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)
-> (PrivateKey VRF, PublicKey VRF)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Proxy TestCrypto
-> PrivateKey TestCrypto -> VRFSigningKey TestCrypto
forall crypto.
CryptoSupportsVRF crypto =>
Proxy crypto -> PrivateKey crypto -> VRFSigningKey crypto
getVRFSigningKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)))
([((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)]
-> [(PrivateKey VRF, PublicKey VRF)])
-> ([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)])
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [(PrivateKey VRF, PublicKey VRF)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> [((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((PublicKey SIGN, PublicKey VRF) -> PublicKey VRF)
-> ((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> ((PrivateKey SIGN, PrivateKey VRF), PublicKey VRF)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (Proxy TestCrypto
-> PublicKey TestCrypto -> VRFVerificationKey TestCrypto
forall crypto.
CryptoSupportsVRF crypto =>
Proxy crypto -> PublicKey crypto -> VRFVerificationKey crypto
getVRFVerificationKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)))
([((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF)))
-> [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
-> (NonEmpty (PrivateKey VRF), NonEmpty (PublicKey VRF))
forall a b. (a -> b) -> a -> b
$ [((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))]
keyPairs
let input :: VRFElectionInput TestCrypto
input = forall crypto.
CryptoSupportsVRF crypto =>
Nonce -> ElectionId crypto -> VRFElectionInput crypto
mkVRFElectionInput @TestCrypto Nonce
epochNonce Word64
ElectionId TestCrypto
electionId
String -> [String] -> Property -> Property
forall prop.
Testable prop =>
String -> [String] -> prop -> Property
tabulate String
"Number of VRF signers" [Int -> String
forall a. Show a => a -> String
show Int
numSigners] (Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$
case ( (PrivateKey VRF -> Either String (VRFOutput TestCrypto))
-> NonEmpty (PrivateKey VRF)
-> Either String (NonEmpty (VRFOutput TestCrypto))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmpty a -> f (NonEmpty b)
traverse
(\PrivateKey VRF
sk -> forall crypto.
CryptoSupportsVRF crypto =>
VRFPoolContext crypto
-> VRFElectionInput crypto -> Either String (VRFOutput crypto)
evalVRF @TestCrypto (VRFSigningKey TestCrypto -> VRFPoolContext TestCrypto
forall crypto. VRFSigningKey crypto -> VRFPoolContext crypto
VRFSignContext VRFSigningKey TestCrypto
PrivateKey VRF
sk) VRFElectionInput TestCrypto
input)
NonEmpty (PrivateKey VRF)
vrfSigningKeys
) of
Left String
err ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
(String
"VRF evaluation failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
err)
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
Right NonEmpty (VRFOutput TestCrypto)
vrfOutputs -> do
Gen (Int, Int, NonEmpty (VRFOutput TestCrypto))
-> ((Int, Int, NonEmpty (VRFOutput TestCrypto)) -> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll (NE [VRFOutput TestCrypto]
-> Gen (Int, Int, NE [VRFOutput TestCrypto])
forall a. NE [a] -> Gen (Int, Int, NE [a])
swapTwoElements NonEmpty (VRFOutput TestCrypto)
NE [VRFOutput TestCrypto]
vrfOutputs) (((Int, Int, NonEmpty (VRFOutput TestCrypto)) -> Property)
-> Property)
-> ((Int, Int, NonEmpty (VRFOutput TestCrypto)) -> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \(Int
i, Int
j, NonEmpty (VRFOutput TestCrypto)
swappedVRFOutputs) -> do
case ( forall crypto.
CryptoSupportsBatchVRFVerification crypto =>
NE [VRFVerificationKey crypto]
-> VRFElectionInput crypto
-> NE [VRFOutput crypto]
-> Either String ()
batchVerifyVRFOutputs @TestCrypto
NonEmpty (PublicKey VRF)
NE [VRFVerificationKey TestCrypto]
vrfVerificationKeys
VRFElectionInput TestCrypto
input
NonEmpty (VRFOutput TestCrypto)
NE [VRFOutput TestCrypto]
swappedVRFOutputs
) of
Left String
_ ->
Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
Right () ->
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
( String
"Aggregate VRF verification should have failed when "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"swapping outputs at indices "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
i
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" and "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
j
)
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False
prop_AssociativityOfAggregateKeys :: Property
prop_AssociativityOfAggregateKeys :: Property
prop_AssociativityOfAggregateKeys =
Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair ((((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property)
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \((PrivateKey SIGN, PrivateKey VRF)
_, (PublicKey SIGN, PublicKey VRF)
pk1) ->
Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair ((((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property)
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \((PrivateKey SIGN, PrivateKey VRF)
_, (PublicKey SIGN, PublicKey VRF)
pk2) ->
Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair ((((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property)
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \((PrivateKey SIGN, PrivateKey VRF)
_, (PublicKey SIGN, PublicKey VRF)
pk3) -> do
let toAggKey :: (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey SIGN)
toAggKey (PublicKey SIGN, PublicKey VRF)
pk =
PublicKey SIGN -> NonEmpty (PublicKey SIGN)
forall a. a -> NonEmpty a
NonEmpty.singleton
(PublicKey SIGN -> NonEmpty (PublicKey SIGN))
-> ((PublicKey SIGN, PublicKey VRF) -> PublicKey SIGN)
-> (PublicKey SIGN, PublicKey VRF)
-> NonEmpty (PublicKey SIGN)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy TestCrypto
-> PublicKey TestCrypto -> VoteVerificationKey TestCrypto
forall crypto.
CryptoSupportsVoteSigning crypto =>
Proxy crypto -> PublicKey crypto -> VoteVerificationKey crypto
getVoteVerificationKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)
((PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey SIGN))
-> (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey SIGN)
forall a b. (a -> b) -> a -> b
$ (PublicKey SIGN, PublicKey VRF)
pk
let pk1' :: NonEmpty (PublicKey SIGN)
pk1' = (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey SIGN)
toAggKey (PublicKey SIGN, PublicKey VRF)
pk1
let pk2' :: NonEmpty (PublicKey SIGN)
pk2' = (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey SIGN)
toAggKey (PublicKey SIGN, PublicKey VRF)
pk2
let pk3' :: NonEmpty (PublicKey SIGN)
pk3' = (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey SIGN)
toAggKey (PublicKey SIGN, PublicKey VRF)
pk3
let lhs :: Either String (PublicKey SIGN)
lhs = do
pk12' <- PublicKey SIGN -> NonEmpty (PublicKey SIGN)
forall a. a -> NonEmpty a
NonEmpty.singleton (PublicKey SIGN -> NonEmpty (PublicKey SIGN))
-> Either String (PublicKey SIGN)
-> Either String (NonEmpty (PublicKey SIGN))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NE [PublicKey SIGN] -> Either String (PublicKey SIGN)
forall (r :: KeyRole).
NE [PublicKey r] -> Either String (PublicKey r)
BLS.aggregatePublicKeys (NonEmpty (PublicKey SIGN)
pk1' NonEmpty (PublicKey SIGN)
-> NonEmpty (PublicKey SIGN) -> NonEmpty (PublicKey SIGN)
forall a. Semigroup a => a -> a -> a
<> NonEmpty (PublicKey SIGN)
pk2')
BLS.aggregatePublicKeys (pk12' <> pk3')
let rhs :: Either String (PublicKey SIGN)
rhs = do
pk23' <- PublicKey SIGN -> NonEmpty (PublicKey SIGN)
forall a. a -> NonEmpty a
NonEmpty.singleton (PublicKey SIGN -> NonEmpty (PublicKey SIGN))
-> Either String (PublicKey SIGN)
-> Either String (NonEmpty (PublicKey SIGN))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NE [PublicKey SIGN] -> Either String (PublicKey SIGN)
forall (r :: KeyRole).
NE [PublicKey r] -> Either String (PublicKey r)
BLS.aggregatePublicKeys (NonEmpty (PublicKey SIGN)
pk2' NonEmpty (PublicKey SIGN)
-> NonEmpty (PublicKey SIGN) -> NonEmpty (PublicKey SIGN)
forall a. Semigroup a => a -> a -> a
<> NonEmpty (PublicKey SIGN)
pk3')
BLS.aggregatePublicKeys (pk1' <> pk23')
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
String
"Aggregate vote verification keys should be associative"
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Either String (PublicKey SIGN)
lhs Either String (PublicKey SIGN)
-> Either String (PublicKey SIGN) -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Either String (PublicKey SIGN)
rhs
prop_AssociativityOfAggregateVRFKeys :: Property
prop_AssociativityOfAggregateVRFKeys :: Property
prop_AssociativityOfAggregateVRFKeys =
Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair ((((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property)
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \((PrivateKey SIGN, PrivateKey VRF)
_, (PublicKey SIGN, PublicKey VRF)
pk1) ->
Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair ((((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property)
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \((PrivateKey SIGN, PrivateKey VRF)
_, (PublicKey SIGN, PublicKey VRF)
pk2) ->
Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen
((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
Gen (PrivateKey TestCrypto, PublicKey TestCrypto)
genKeyPair ((((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property)
-> (((PrivateKey SIGN, PrivateKey VRF),
(PublicKey SIGN, PublicKey VRF))
-> Property)
-> Property
forall a b. (a -> b) -> a -> b
$ \((PrivateKey SIGN, PrivateKey VRF)
_, (PublicKey SIGN, PublicKey VRF)
pk3) -> do
let toAggKey :: (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey VRF)
toAggKey (PublicKey SIGN, PublicKey VRF)
pk =
PublicKey VRF -> NonEmpty (PublicKey VRF)
forall a. a -> NonEmpty a
NonEmpty.singleton
(PublicKey VRF -> NonEmpty (PublicKey VRF))
-> ((PublicKey SIGN, PublicKey VRF) -> PublicKey VRF)
-> (PublicKey SIGN, PublicKey VRF)
-> NonEmpty (PublicKey VRF)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy TestCrypto
-> PublicKey TestCrypto -> VRFVerificationKey TestCrypto
forall crypto.
CryptoSupportsVRF crypto =>
Proxy crypto -> PublicKey crypto -> VRFVerificationKey crypto
getVRFVerificationKey (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @TestCrypto)
((PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey VRF))
-> (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey VRF)
forall a b. (a -> b) -> a -> b
$ (PublicKey SIGN, PublicKey VRF)
pk
let pk1' :: NonEmpty (PublicKey VRF)
pk1' = (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey VRF)
toAggKey (PublicKey SIGN, PublicKey VRF)
pk1
let pk2' :: NonEmpty (PublicKey VRF)
pk2' = (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey VRF)
toAggKey (PublicKey SIGN, PublicKey VRF)
pk2
let pk3' :: NonEmpty (PublicKey VRF)
pk3' = (PublicKey SIGN, PublicKey VRF) -> NonEmpty (PublicKey VRF)
toAggKey (PublicKey SIGN, PublicKey VRF)
pk3
let lhs :: Either String (PublicKey VRF)
lhs = do
pk12' <- PublicKey VRF -> NonEmpty (PublicKey VRF)
forall a. a -> NonEmpty a
NonEmpty.singleton (PublicKey VRF -> NonEmpty (PublicKey VRF))
-> Either String (PublicKey VRF)
-> Either String (NonEmpty (PublicKey VRF))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NE [PublicKey VRF] -> Either String (PublicKey VRF)
forall (r :: KeyRole).
NE [PublicKey r] -> Either String (PublicKey r)
BLS.aggregatePublicKeys (NonEmpty (PublicKey VRF)
pk1' NonEmpty (PublicKey VRF)
-> NonEmpty (PublicKey VRF) -> NonEmpty (PublicKey VRF)
forall a. Semigroup a => a -> a -> a
<> NonEmpty (PublicKey VRF)
pk2')
BLS.aggregatePublicKeys (pk12' <> pk3')
let rhs :: Either String (PublicKey VRF)
rhs = do
pk23' <- PublicKey VRF -> NonEmpty (PublicKey VRF)
forall a. a -> NonEmpty a
NonEmpty.singleton (PublicKey VRF -> NonEmpty (PublicKey VRF))
-> Either String (PublicKey VRF)
-> Either String (NonEmpty (PublicKey VRF))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NE [PublicKey VRF] -> Either String (PublicKey VRF)
forall (r :: KeyRole).
NE [PublicKey r] -> Either String (PublicKey r)
BLS.aggregatePublicKeys (NonEmpty (PublicKey VRF)
pk2' NonEmpty (PublicKey VRF)
-> NonEmpty (PublicKey VRF) -> NonEmpty (PublicKey VRF)
forall a. Semigroup a => a -> a -> a
<> NonEmpty (PublicKey VRF)
pk3')
BLS.aggregatePublicKeys (pk1' <> pk23')
String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample
String
"Aggregate VRF verification keys should be associative"
(Property -> Property) -> Property -> Property
forall a b. (a -> b) -> a -> b
$ Either String (PublicKey VRF)
lhs Either String (PublicKey VRF)
-> Either String (PublicKey VRF) -> Property
forall a. (Eq a, Show a) => a -> a -> Property
=== Either String (PublicKey VRF)
rhs
tests :: TestTree
tests :: TestTree
tests =
String -> [TestTree] -> TestTree
testGroup
String
"TestCrypto properties"
[ (Int -> Int) -> TestTree -> TestTree
adjustQuickCheckTests (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10) (TestTree -> TestTree) -> TestTree -> TestTree
forall a b. (a -> b) -> a -> b
$
String -> Property -> TestTree
forall a. Testable a => String -> a -> TestTree
testProperty
String
"prop_SignAndVerifyVote"
Property
prop_SignAndVerifyVote
, (Int -> Int) -> TestTree -> TestTree
adjustQuickCheckTests (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10) (TestTree -> TestTree) -> TestTree -> TestTree
forall a b. (a -> b) -> a -> b
$
String -> Property -> TestTree
forall a. Testable a => String -> a -> TestTree
testProperty
String
"prop_SignAndVerifyAggregateVote"
Property
prop_SignAndVerifyAggregateVote
, (Int -> Int) -> TestTree -> TestTree
adjustQuickCheckTests (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10) (TestTree -> TestTree) -> TestTree -> TestTree
forall a b. (a -> b) -> a -> b
$
String -> Property -> TestTree
forall a. Testable a => String -> a -> TestTree
testProperty
String
"prop_EvalAndVerifyVRFOutput"
Property
prop_EvalAndVerifyVRFOutput
, (Int -> Int) -> TestTree -> TestTree
adjustQuickCheckTests (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10) (TestTree -> TestTree) -> TestTree -> TestTree
forall a b. (a -> b) -> a -> b
$
String -> Property -> TestTree
forall a. Testable a => String -> a -> TestTree
testProperty
String
"prop_EvalAndVerifyAggregateVRFOutput"
Property
prop_EvalAndVerifyAggregateVRFOutput
, (Int -> Int) -> TestTree -> TestTree
adjustQuickCheckTests (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10) (TestTree -> TestTree) -> TestTree -> TestTree
forall a b. (a -> b) -> a -> b
$
String -> Property -> TestTree
forall a. Testable a => String -> a -> TestTree
testProperty
String
"prop_SwapAttackOnAggregateVRF"
Property
prop_SwapAttackOnAggregateVRF
, (Int -> Int) -> TestTree -> TestTree
adjustQuickCheckTests (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10) (TestTree -> TestTree) -> TestTree -> TestTree
forall a b. (a -> b) -> a -> b
$
String -> Property -> TestTree
forall a. Testable a => String -> a -> TestTree
testProperty
String
"prop_AssociativityOfAggregateKeys"
Property
prop_AssociativityOfAggregateKeys
, (Int -> Int) -> TestTree -> TestTree
adjustQuickCheckTests (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10) (TestTree -> TestTree) -> TestTree -> TestTree
forall a b. (a -> b) -> a -> b
$
String -> Property -> TestTree
forall a. Testable a => String -> a -> TestTree
testProperty
String
"prop_AssociativityOfAggregateVRFKeys"
Property
prop_AssociativityOfAggregateVRFKeys
]