55
66module Test.Cardano.Crypto.Leios (spec , exampleCert ) where
77
8- import qualified Cardano.Binary as CBOR
9- import Cardano.Binary.FixedSizeCodec (encodeFixedSized )
108import Cardano.Crypto.DSIGN (
119 DSIGNAlgorithm (deriveVerKeyDSIGN ),
1210 genKeyDSIGN ,
@@ -25,22 +23,13 @@ import Cardano.Crypto.Leios (
2523 VerificationError (.. ),
2624 Weight ,
2725 aggregateLeiosCert ,
28- decodeLeiosCert ,
29- decodeLeiosVoterId ,
30- encodeBitField ,
31- encodeLeiosCert ,
32- encodeLeiosVoterId ,
3326 getLeiosVoterId ,
3427 leiosSignContext ,
3528 resolveLeiosVoter ,
3629 verifyLeiosCert ,
3730 )
3831import Cardano.Crypto.Seed (mkSeedFromBytes )
39- import Codec.CBOR.Encoding (Encoding , encodeBreak , encodeListLenIndef )
4032import qualified Data.ByteString as BS
41- import qualified Data.ByteString.Base16 as BS16
42- import qualified Data.ByteString.Char8 as BS8
43- import qualified Data.ByteString.Lazy as BSL
4433import Data.Foldable (toList )
4534import Data.List.NonEmpty (NonEmpty (.. ), fromList )
4635import Data.Map.Strict (Map )
@@ -49,9 +38,7 @@ import Data.Proxy (Proxy (Proxy))
4938import qualified Data.Vector.Strict as V
5039import Data.Word (Word16 , Word8 )
5140import Test.Cardano.Base.Bytes (genByteString )
52- import Test.Cardano.Crypto.Leios.Gen (genLeiosCert )
53- import Test.Hspec (Spec , context , describe , it )
54- import Test.Hspec.Golden (Golden (.. ))
41+ import Test.Hspec (Spec , context , describe )
5542import Test.Hspec.QuickCheck (prop )
5643import Test.QuickCheck (
5744 Property ,
@@ -65,11 +52,6 @@ import qualified Test.QuickCheck as QC
6552spec :: Spec
6653spec = do
6754 describe " LeiosCert" $ do
68- prop " round-trips through CBOR" prop_roundtrip_LeiosCert
69- prop " decodes indefinite-length encoding" prop_decode_indefinite_LeiosCert
70- it " matches golden encoding" $
71- goldenEncoding " test/golden/LeiosCert" encodeLeiosCert exampleCert
72-
7355 describe " aggregateLeiosCert" $ do
7456 prop " rejects an out-of-range LeiosVoterId" prop_aggregateLeiosCert_rejects_out_of_range
7557 prop " rejects empty contributions" prop_aggregateLeiosCert_rejects_empty
@@ -84,52 +66,12 @@ spec = do
8466 prop " rejects a bitfield wider than the committee" prop_verifyLeiosCert_rejects_oversized_signers
8567 prop " rejects a tampered bitfield" prop_verifyLeiosCert_rejects_tampered_bitfield
8668
87- describe " LeiosVoterId" $ do
88- prop " round-trips through CBOR" prop_roundtrip_VoterId
89- it " matches golden encoding" $
90- goldenEncoding " test/golden/LeiosVoterId" encodeLeiosVoterId exampleVoterId
91-
9269 describe " LeiosCommittee" $ do
9370 prop
9471 " getLeiosVoterId and resolveLeiosVoter agree on verification keys"
9572 prop_resolveVoter_getVoterId_inverse
9673 prop " getLeiosVoterId returns the first matching index" prop_getVoterId_returns_first_index
9774
98- -- * CBOR roundtrip / golden
99-
100- prop_roundtrip_LeiosCert :: Property
101- prop_roundtrip_LeiosCert = forAll genLeiosCert $ \ cert ->
102- let bs = CBOR. serialize (encodeLeiosCert cert)
103- in CBOR. decodeFullDecoder " LeiosCert" decodeLeiosCert bs === Right cert
104-
105- -- | The decoder must accept indefinite-length encodings of the outer
106- -- 2-element array, not just the canonical definite-length form.
107- prop_decode_indefinite_LeiosCert :: Property
108- prop_decode_indefinite_LeiosCert = forAll genLeiosCert $ \ cert ->
109- let indef =
110- encodeListLenIndef
111- <> encodeBitField (leiosCertSigners cert)
112- <> encodeFixedSized (leiosCertSignature cert)
113- <> encodeBreak
114- in CBOR. decodeFullDecoder " LeiosCert" decodeLeiosCert (CBOR. serialize indef)
115- === Right cert
116-
117- -- | Pin the byte-for-byte CBOR encoding of a value to a golden file using
118- -- 'hspec-golden'. Failure diffs are rendered as base16 hex. Decode
119- -- round-trip of arbitrary values is covered by the matching @roundtrip_@
120- -- property; this only locks the encoding shape.
121- goldenEncoding :: FilePath -> (a -> Encoding ) -> a -> Golden BSL. ByteString
122- goldenEncoding path enc value =
123- Golden
124- { output = CBOR. serialize (enc value)
125- , encodePretty = BS8. unpack . BS16. encode . BSL. toStrict
126- , writeToFile = BSL. writeFile
127- , readFromFile = BSL. readFile
128- , goldenFile = path
129- , actualFile = Nothing
130- , failFirstTime = False
131- }
132-
13375exampleCert :: LeiosCert
13476exampleCert = case aggregateLeiosCert committee contributions of
13577 Right c -> c
@@ -139,15 +81,7 @@ exampleCert = case aggregateLeiosCert committee contributions of
13981 msg = " leios-golden-message" :: BS. ByteString
14082 contributions = signContribs msg (zip [0 .. ] (toList sks))
14183
142- -- * LeiosVoterId CBOR / committee lookup
143-
144- prop_roundtrip_VoterId :: Property
145- prop_roundtrip_VoterId = forAll (LeiosVoterId <$> QC. arbitrary) $ \ vid ->
146- let bs = CBOR. serialize (encodeLeiosVoterId vid)
147- in CBOR. decodeFullDecoder " LeiosVoterId" decodeLeiosVoterId bs === Right vid
148-
149- exampleVoterId :: LeiosVoterId
150- exampleVoterId = LeiosVoterId 0xABCD
84+ -- * LeiosVoterId committee lookup
15185
15286-- | 'getLeiosVoterId' and 'resolveLeiosVoter' are mutual inverses on the verification
15387-- key projection: for any voter in the committee, looking up its 'LeiosVoterId'
0 commit comments