Skip to content

Commit 1c5808b

Browse files
authored
Merge pull request #690 from IntersectMBO/jj/leios-cert-constructor
Remove `LeiosCert` encoder/decoder, export `BitField` constructor
2 parents c61a885 + 9522950 commit 1c5808b

6 files changed

Lines changed: 15 additions & 135 deletions

File tree

cardano-crypto-leios/CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
# Changelog for `cardano-crypto-leios`
22

3-
## 0.1.0.2
3+
## 0.2.0.0
44

5-
*
5+
* Remove:
6+
- `encodeLeiosCert`
7+
- `decodeLeiosCert`
8+
- `encodeLeiosVoterId`
9+
- `decodeLeiosVoterId`
10+
- `encodeBitField`
11+
- `decodeBitField`
12+
* Export `BitField` constructor
613

714
## 0.1.0.1
815

cardano-crypto-leios/cardano-crypto-leios.cabal

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 3.0
22
name: cardano-crypto-leios
3-
version: 0.1.0.1
3+
version: 0.2.0.0
44
synopsis: Crypto primitives for Leios
55
description:
66
Data types for the Leios cryptographic artifacts as specified in CIP-0164.
@@ -38,10 +38,8 @@ library
3838

3939
build-depends:
4040
bytestring,
41-
cardano-base >=0.1.6,
4241
cardano-binary,
4342
cardano-crypto-class >=2.5.1,
44-
cborg,
4543
containers,
4644
deepseq,
4745
nothunks,
@@ -74,16 +72,12 @@ test-suite tests
7472

7573
build-depends:
7674
QuickCheck,
77-
base16-bytestring,
7875
bytestring,
7976
cardano-base:testlib,
80-
cardano-binary >=1.9.1,
8177
cardano-crypto-class >=2.5.1,
82-
cardano-crypto-leios:{cardano-crypto-leios, testlib},
83-
cborg,
78+
cardano-crypto-leios,
8479
containers,
8580
hspec,
86-
hspec-golden,
8781
vector,
8882

8983
ghc-options:

cardano-crypto-leios/src/Cardano/Crypto/Leios.hs

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ module Cardano.Crypto.Leios (
2727
-- * Voting committee
2828
Weight,
2929
LeiosVoterId (..),
30-
encodeLeiosVoterId,
31-
decodeLeiosVoterId,
3230
LeiosVoter (..),
3331
LeiosCommittee (..),
3432
leiosCommitteeSize,
@@ -37,8 +35,6 @@ module Cardano.Crypto.Leios (
3735

3836
-- * Leios certificates
3937
LeiosCert (..),
40-
encodeLeiosCert,
41-
decodeLeiosCert,
4238

4339
-- ** Construction
4440
AggregationError (..),
@@ -49,17 +45,11 @@ module Cardano.Crypto.Leios (
4945
verifyLeiosCert,
5046

5147
-- * Bitfield wire-format helpers
52-
BitField,
53-
encodeBitField,
54-
decodeBitField,
48+
BitField (..),
5549
) where
5650

57-
import Cardano.Base.Bytes (byteArrayFromByteString)
58-
import Cardano.Binary (matchSize, toCBOR)
5951
import Cardano.Binary.FixedSizeCodec (
6052
FixedSizeCodec (..),
61-
decodeFixedSized,
62-
encodeFixedSized,
6353
fixedSize,
6454
)
6555
import Cardano.Crypto.DSIGN (
@@ -71,10 +61,8 @@ import Cardano.Crypto.DSIGN (
7161
)
7262
import Cardano.Crypto.DSIGN.BLS12381 (BLS12381MinSigDSIGN, BLS12381SignContext, minSigPoPDST)
7363
import Cardano.Crypto.Util (SignableRepresentation)
74-
import Codec.CBOR.Decoding (Decoder, decodeBreakOr, decodeBytes, decodeListLenOrIndef, decodeWord16)
75-
import Codec.CBOR.Encoding (Encoding, encodeListLen, encodeWord16)
7664
import Control.DeepSeq (NFData)
77-
import Control.Monad (forM_, unless, when)
65+
import Control.Monad (forM_, when)
7866
import Data.Array.Byte (ByteArray)
7967
import Data.Bifunctor (first)
8068
import Data.Bits (setBit, shiftR, testBit, (.&.))
@@ -138,14 +126,6 @@ newtype LeiosVoterId = LeiosVoterId {leiosVoterIndex :: Word16}
138126
deriving stock (Eq, Ord, Show, Generic)
139127
deriving newtype (NFData, NoThunks)
140128

141-
-- | Plain CBOR encoder for 'LeiosVoterId'.
142-
encodeLeiosVoterId :: LeiosVoterId -> Encoding
143-
encodeLeiosVoterId (LeiosVoterId idx) = encodeWord16 idx
144-
145-
-- | Plain CBOR decoder for 'LeiosVoterId'.
146-
decodeLeiosVoterId :: Decoder s LeiosVoterId
147-
decodeLeiosVoterId = LeiosVoterId <$> decodeWord16
148-
149129
-- | A single seat in a 'LeiosCommittee': a voter's normalised weight paired with
150130
-- its BLS verification key.
151131
data LeiosVoter = LeiosVoter
@@ -239,32 +219,6 @@ data LeiosCert = LeiosCert
239219
deriving stock (Show, Eq, Generic)
240220
deriving anyclass (NFData, NoThunks)
241221

242-
-- | Plain CBOR encoder for 'LeiosCert', matching the CDDL in 'LeiosCert'.
243-
encodeLeiosCert :: LeiosCert -> Encoding
244-
encodeLeiosCert cert =
245-
encodeListLen 2
246-
<> encodeBitField cert.leiosCertSigners
247-
<> encodeFixedSized cert.leiosCertSignature
248-
249-
-- | Plain CBOR decoder for 'LeiosCert', matching the CDDL in 'LeiosCert'.
250-
-- Accepts both definite-length and indefinite-length encodings of the
251-
-- outer 2-element array.
252-
decodeLeiosCert :: Decoder s LeiosCert
253-
decodeLeiosCert = do
254-
isIndef <-
255-
decodeListLenOrIndef >>= \case
256-
Just n -> False <$ matchSize "LeiosCert" 2 n
257-
Nothing -> pure True
258-
cert <-
259-
LeiosCert
260-
<$> decodeBitField
261-
<*> decodeFixedSized
262-
when isIndef $ do
263-
isBreak <- decodeBreakOr
264-
unless isBreak $
265-
fail "LeiosCert: expected break after 2 elements of indefinite-length list"
266-
pure cert
267-
268222
data AggregationError
269223
= -- | One or more voter indices in the sigs are past the committee bound.
270224
VoterIdsOutOfBounds (NonEmpty LeiosVoterId)
@@ -411,11 +365,3 @@ newtype BitField = BitField {bitFieldBytes :: ByteArray}
411365
deriving stock (Show, Eq, Generic)
412366
deriving newtype (NFData)
413367
deriving (NoThunks) via OnlyCheckWhnfNamed "BitField" BitField
414-
415-
-- | Encode a 'BitField' to CBOR bytes.
416-
encodeBitField :: BitField -> Encoding
417-
encodeBitField = toCBOR . bitFieldBytes
418-
419-
-- | Decode a 'BitField' from CBOR bytes.
420-
decodeBitField :: Decoder s BitField
421-
decodeBitField = BitField . byteArrayFromByteString <$> decodeBytes

cardano-crypto-leios/test/Test/Cardano/Crypto/Leios.hs

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
module Test.Cardano.Crypto.Leios (spec, exampleCert) where
77

8-
import qualified Cardano.Binary as CBOR
9-
import Cardano.Binary.FixedSizeCodec (encodeFixedSized)
108
import 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
)
3831
import Cardano.Crypto.Seed (mkSeedFromBytes)
39-
import Codec.CBOR.Encoding (Encoding, encodeBreak, encodeListLenIndef)
4032
import 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
4433
import Data.Foldable (toList)
4534
import Data.List.NonEmpty (NonEmpty (..), fromList)
4635
import Data.Map.Strict (Map)
@@ -49,9 +38,7 @@ import Data.Proxy (Proxy (Proxy))
4938
import qualified Data.Vector.Strict as V
5039
import Data.Word (Word16, Word8)
5140
import 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)
5542
import Test.Hspec.QuickCheck (prop)
5643
import Test.QuickCheck (
5744
Property,
@@ -65,11 +52,6 @@ import qualified Test.QuickCheck as QC
6552
spec :: Spec
6653
spec = 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-
13375
exampleCert :: LeiosCert
13476
exampleCert = 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'
-178 Bytes
Binary file not shown.

cardano-crypto-leios/test/golden/LeiosVoterId

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)