Skip to content

Commit fc13597

Browse files
committed
Re-change Peras target to use Point blk instead of PerasBoostedBlock
1 parent 4197f46 commit fc13597

4 files changed

Lines changed: 126 additions & 90 deletions

File tree

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Cert/V1.hs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{-# LANGUAGE LambdaCase #-}
33
{-# LANGUAGE NamedFieldPuns #-}
44
{-# LANGUAGE ScopedTypeVariables #-}
5+
{-# LANGUAGE TypeApplications #-}
56
{-# LANGUAGE UndecidableInstances #-}
67

78
-- | Concrete Peras certificate types using BLS signatures.
@@ -29,10 +30,17 @@ import qualified Data.List.NonEmpty as NonEmpty
2930
import qualified Data.Map.NonEmpty as NEMap
3031
import Data.Map.Strict (Map)
3132
import Data.Maybe (catMaybes)
33+
import Data.Proxy (Proxy (..))
34+
import Data.Typeable (Typeable)
3235
import Data.Word (Word16)
36+
import Ouroboros.Consensus.Block
37+
( ConvertRawHash (..)
38+
, Point
39+
, decodeRawHash
40+
, encodeRawHash
41+
)
3342
import Ouroboros.Consensus.Block.SupportsPeras
34-
( PerasBoostedBlock
35-
, PerasRoundNo
43+
( PerasRoundNo
3644
, PerasSeatIndex (..)
3745
)
3846
import Ouroboros.Consensus.Committee.Crypto
@@ -45,27 +53,33 @@ import Ouroboros.Consensus.Peras.Crypto.BLS
4553
import Ouroboros.Consensus.Peras.Vote.V1 (PerasVoteEligibilityProof (..))
4654
import Ouroboros.Consensus.Util.Bitmap (Bitmap)
4755
import qualified Ouroboros.Consensus.Util.Bitmap as Bitmap
56+
import Ouroboros.Network.Block (decodePoint, encodePoint)
4857

4958
-- | Concrete Peras certificates using BLS signatures
50-
data PerasCert
59+
-- 'blk' is mainly used here to ensure type family injectivity.
60+
-- For convenience/preventing annoying conversions, we also use it to indicate
61+
-- in 'Point blk' for the boosted block.
62+
data PerasCert blk
5163
= PerasCert
5264
{ pcRoundNo :: !PerasRoundNo
5365
-- ^ Election identifier
54-
, pcBoostedBlock :: !PerasBoostedBlock
66+
, pcBoostedBlock :: !(Point blk)
5567
-- ^ Certificate message, i.e., the hash of the block being boosted
56-
, pcVoters :: !PerasCertVoters
68+
-- TODO: 'blk' here may not refer to the actual era of the boosted block,
69+
-- see https://github.com/tweag/cardano-peras/issues/251
70+
, pcVoters :: !(PerasCertVoters blk)
5771
-- ^ Voters who contributed to this certificate
58-
, pcSignature :: !(AggregateVoteSignature PerasBLSCrypto)
72+
, pcSignature :: !(AggregateVoteSignature (PerasBLSCrypto blk))
5973
-- ^ Aggregate BLS signature on the hash of the election identifier and
6074
-- the certificate message
6175
}
6276
deriving (Show, Eq)
6377

64-
instance FromCBOR PerasCert where
78+
instance (Typeable blk, ConvertRawHash blk) => FromCBOR (PerasCert blk) where
6579
fromCBOR = do
6680
decodeListLenOf 4
6781
pcRoundNo <- fromCBOR
68-
pcBoostedBlock <- fromCBOR
82+
pcBoostedBlock <- decodePoint (decodeRawHash (Proxy @blk))
6983
pcVoters <- fromCBOR
7084
pcSignature <- fromCBOR
7185
pure
@@ -76,23 +90,23 @@ instance FromCBOR PerasCert where
7690
, pcSignature
7791
}
7892

79-
instance ToCBOR PerasCert where
93+
instance (Typeable blk, ConvertRawHash blk) => ToCBOR (PerasCert blk) where
8094
toCBOR cert =
8195
encodeListLen 4
8296
<> toCBOR (pcRoundNo cert)
83-
<> toCBOR (pcBoostedBlock cert)
97+
<> encodePoint (encodeRawHash (Proxy @blk)) (pcBoostedBlock cert)
8498
<> toCBOR (pcVoters cert)
8599
<> toCBOR (pcSignature cert)
86100

87101
-- | Voters contained in a certificate with their appropriate eligibility proof
88-
newtype PerasCertVoters
102+
newtype PerasCertVoters blk
89103
= PerasCertVoters
90104
{ unPerasCertVoters ::
91-
NE (Map PerasSeatIndex PerasVoteEligibilityProof)
105+
NE (Map PerasSeatIndex (PerasVoteEligibilityProof blk))
92106
}
93107
deriving (Eq, Show)
94108

95-
instance FromCBOR PerasCertVoters where
109+
instance Typeable blk => FromCBOR (PerasCertVoters blk) where
96110
fromCBOR = do
97111
decodeListLenOf 2
98112
votersBitmap <- fromCBOR
@@ -105,7 +119,7 @@ instance FromCBOR PerasCertVoters where
105119
, nonPersistentSigs
106120
}
107121

108-
instance ToCBOR PerasCertVoters where
122+
instance Typeable blk => ToCBOR (PerasCertVoters blk) where
109123
toCBOR voters =
110124
encodeListLen 2
111125
<> toCBOR votersBitmap
@@ -141,19 +155,19 @@ instance ToCBOR PerasCertVoters where
141155
-- 7 => non-persistent(np3)
142156
-- }
143157
-- @
144-
data CompactPerasCertVoters
158+
data CompactPerasCertVoters blk
145159
= CompactPerasCertVoters
146160
{ votersBitmap :: !(Bitmap Word16)
147-
, nonPersistentSigs :: ![VRFOutput PerasBLSCrypto]
161+
, nonPersistentSigs :: ![VRFOutput (PerasBLSCrypto blk)]
148162
}
149163
deriving (Eq, Show)
150164

151165
-- | Decode 'PerasCertVoters' from their compact representation.
152166
--
153167
-- See 'CompactPerasCertVoters' for the encoding scheme used here.
154168
fromCompactRepr ::
155-
CompactPerasCertVoters ->
156-
Either String PerasCertVoters
169+
CompactPerasCertVoters blk ->
170+
Either String (PerasCertVoters blk)
157171
fromCompactRepr
158172
CompactPerasCertVoters
159173
{ votersBitmap
@@ -195,8 +209,8 @@ fromCompactRepr
195209
--
196210
-- See 'CompactPerasCertVoters' for the encoding scheme used here.
197211
toCompactRepr ::
198-
PerasCertVoters ->
199-
CompactPerasCertVoters
212+
PerasCertVoters blk ->
213+
CompactPerasCertVoters blk
200214
toCompactRepr (PerasCertVoters voters) =
201215
CompactPerasCertVoters
202216
{ votersBitmap

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Peras/Crypto/BLS.hs

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
{-# LANGUAGE DataKinds #-}
12
{-# LANGUAGE DerivingStrategies #-}
3+
{-# LANGUAGE FlexibleContexts #-}
4+
{-# LANGUAGE FlexibleInstances #-}
25
{-# LANGUAGE GADTs #-}
36
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7+
{-# LANGUAGE PatternSynonyms #-}
48
{-# LANGUAGE RankNTypes #-}
59
{-# LANGUAGE ScopedTypeVariables #-}
610
{-# LANGUAGE TypeApplications #-}
@@ -34,14 +38,16 @@ import Cardano.Ledger.Binary (runByteBuilder)
3438
import Cardano.Ledger.Hashes (HASH)
3539
import qualified Data.ByteString.Builder as BS
3640
import qualified Data.ByteString.Builder.Extra as BS
41+
import Data.Proxy (Proxy (..))
3742
import qualified Data.ByteString.Short as BS
38-
import Ouroboros.Consensus.Block.RealPoint
39-
( bytes32RealPointHash
40-
, bytes32RealPointSlot
43+
import Ouroboros.Consensus.Block
44+
( ConvertRawHash (..)
45+
, Point
46+
, pattern BlockPoint
47+
, pattern GenesisPoint
4148
)
4249
import Ouroboros.Consensus.Block.SupportsPeras
43-
( PerasBoostedBlock (..)
44-
, PerasRoundNo (..)
50+
( PerasRoundNo (..)
4551
)
4652
import Ouroboros.Consensus.Committee.Crypto
4753
( CryptoSupportsAggregateVoteSigning (..)
@@ -58,10 +64,10 @@ import Ouroboros.Consensus.Committee.Crypto.BLS (KeyRole (..))
5864
import qualified Ouroboros.Consensus.Committee.Crypto.BLS as BLS
5965

6066
-- | BLS-based crypto scheme used in Peras voting committees
61-
data PerasBLSCrypto
67+
data PerasBLSCrypto blk
6268

63-
type instance ElectionId PerasBLSCrypto = PerasRoundNo
64-
type instance VoteCandidate PerasBLSCrypto = PerasBoostedBlock
69+
type instance ElectionId (PerasBLSCrypto blk) = PerasRoundNo
70+
type instance VoteCandidate (PerasBLSCrypto blk) = Point blk
6571

6672
-- | Private key of a Peras committee member
6773
data PerasPrivateKey
@@ -70,7 +76,7 @@ data PerasPrivateKey
7076
, perasVRFSignKey :: BLS.PrivateKey VRF
7177
}
7278

73-
type instance PrivateKey PerasBLSCrypto = PerasPrivateKey
79+
type instance PrivateKey (PerasBLSCrypto blk) = PerasPrivateKey
7480

7581
-- | Public key of a Peras committee member
7682
data PerasPublicKey
@@ -79,47 +85,49 @@ data PerasPublicKey
7985
, perasVRFVerKey :: BLS.PublicKey VRF
8086
}
8187

82-
type instance PublicKey PerasBLSCrypto = PerasPublicKey
88+
type instance PublicKey (PerasBLSCrypto blk) = PerasPublicKey
8389

8490
-- | Hash the message of a Peras vote
8591
--
8692
-- NOTE: this is inspired by the implementation used by the Praos VRF check in
8793
-- 'Ouroboros.Consensus.Protocol.Praos.VRF.mkInputVRF'.
8894
hashVoteSignature ::
89-
ElectionId PerasBLSCrypto ->
90-
VoteCandidate PerasBLSCrypto ->
95+
forall blk.
96+
ConvertRawHash blk =>
97+
ElectionId (PerasBLSCrypto blk) ->
98+
VoteCandidate (PerasBLSCrypto blk) ->
9199
Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
92-
hashVoteSignature roundNo boostedBlock =
100+
hashVoteSignature roundNo point =
93101
Hash.castHash
94102
. Hash.hashWith id
95103
. runByteBuilder (8 + 8 + 32)
96104
$ roundNoBytes
97-
<> boostedBlockSlotBytes
98-
<> boostedBlockHashBytes
105+
<> pointSlotBytes
106+
<> pointHashBytes
99107
where
100108
roundNoBytes =
101109
BS.word64BE
102110
. unPerasRoundNo
103111
$ roundNo
104-
boostedBlockSlotBytes =
105-
BS.word64BE
106-
. unSlotNo
107-
. bytes32RealPointSlot
108-
. unPerasBoostedBlock
109-
$ boostedBlock
110-
boostedBlockHashBytes =
111-
BS.byteStringCopy
112-
. BS.fromShort
113-
. bytes32RealPointHash
114-
. unPerasBoostedBlock
115-
$ boostedBlock
112+
(pointSlotBytes, pointHashBytes) = case point of
113+
GenesisPoint ->
114+
( BS.word64BE 0
115+
, mempty
116+
)
117+
BlockPoint slotNo headerHash ->
118+
( BS.word64BE (unSlotNo slotNo)
119+
, BS.byteStringCopy
120+
. BS.fromShort
121+
. toShortRawHash (Proxy @blk)
122+
$ headerHash
123+
)
116124

117125
-- | Hash the input for the VRF used in Peras elections
118126
--
119127
-- NOTE: this is inspired by the implementation used by the Praos VRF check in
120128
-- 'Ouroboros.Consensus.Protocol.Praos.VRF.mkInputVRF'.
121129
hashVRFInput ::
122-
ElectionId PerasBLSCrypto ->
130+
ElectionId (PerasBLSCrypto blk) ->
123131
Nonce ->
124132
Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
125133
hashVRFInput roundNo epochNonce =
@@ -137,11 +145,11 @@ hashVRFInput roundNo epochNonce =
137145

138146
-- * Crypto instances
139147

140-
instance CryptoSupportsVoteSigning PerasBLSCrypto where
141-
type VoteSigningKey PerasBLSCrypto = BLS.PrivateKey SIGN
142-
type VoteVerificationKey PerasBLSCrypto = BLS.PublicKey SIGN
148+
instance ConvertRawHash blk => CryptoSupportsVoteSigning (PerasBLSCrypto blk) where
149+
type VoteSigningKey (PerasBLSCrypto blk) = BLS.PrivateKey SIGN
150+
type VoteVerificationKey (PerasBLSCrypto blk) = BLS.PublicKey SIGN
143151

144-
newtype VoteSignature PerasBLSCrypto
152+
newtype VoteSignature (PerasBLSCrypto blk)
145153
= PerasBLSCryptoVoteSignature
146154
{ unPerasBLSCryptoVoteSignature ::
147155
BLS.Signature BLS.SIGN
@@ -157,7 +165,7 @@ instance CryptoSupportsVoteSigning PerasBLSCrypto where
157165
signVote sk roundNo boostedBlock =
158166
PerasBLSCryptoVoteSignature
159167
. BLS.signWithRole @SIGN sk
160-
$ hashVoteSignature roundNo boostedBlock
168+
$ hashVoteSignature @blk roundNo boostedBlock
161169

162170
verifyVoteSignature
163171
pk
@@ -166,21 +174,21 @@ instance CryptoSupportsVoteSigning PerasBLSCrypto where
166174
(PerasBLSCryptoVoteSignature sig) =
167175
BLS.verifyWithRole @SIGN
168176
pk
169-
(hashVoteSignature roundNo boostedBlock)
177+
(hashVoteSignature @blk roundNo boostedBlock)
170178
sig
171179

172-
instance CryptoSupportsVRF PerasBLSCrypto where
173-
type VRFSigningKey PerasBLSCrypto = BLS.PrivateKey VRF
174-
type VRFVerificationKey PerasBLSCrypto = BLS.PublicKey VRF
180+
instance CryptoSupportsVRF (PerasBLSCrypto blk) where
181+
type VRFSigningKey (PerasBLSCrypto blk) = BLS.PrivateKey VRF
182+
type VRFVerificationKey (PerasBLSCrypto blk) = BLS.PublicKey VRF
175183

176-
newtype VRFElectionInput PerasBLSCrypto
184+
newtype VRFElectionInput (PerasBLSCrypto blk)
177185
= PerasBLSCryptoVRFElectionInput
178186
{ unPerasBLSCryptoVRFElectionInput ::
179187
Hash HASH (SigDSIGN BLS12381MinSigDSIGN)
180188
}
181189
deriving stock (Eq, Show)
182190

183-
newtype VRFOutput PerasBLSCrypto
191+
newtype VRFOutput (PerasBLSCrypto blk)
184192
= PerasBLSCryptoVRFOutput
185193
{ unPerasBLSCryptoVRFOutput ::
186194
BLS.Signature VRF
@@ -229,12 +237,12 @@ newtype PerasBLSCryptoAggregateVoteSignature
229237
deriving stock (Eq, Show)
230238
deriving newtype (FromCBOR, ToCBOR)
231239

232-
instance CryptoSupportsAggregateVoteSigning PerasBLSCrypto where
240+
instance ConvertRawHash blk => CryptoSupportsAggregateVoteSigning (PerasBLSCrypto blk) where
233241
type
234-
AggregateVoteVerificationKey PerasBLSCrypto =
242+
AggregateVoteVerificationKey (PerasBLSCrypto blk) =
235243
PerasBLSCryptoAggregateVoteVerificationKey
236244
type
237-
AggregateVoteSignature PerasBLSCrypto =
245+
AggregateVoteSignature (PerasBLSCrypto blk) =
238246
PerasBLSCryptoAggregateVoteSignature
239247

240248
aggregateVoteVerificationKeys _ pks = do
@@ -256,10 +264,10 @@ instance CryptoSupportsAggregateVoteSigning PerasBLSCrypto where
256264
aggSig = do
257265
BLS.verifyWithRole @SIGN
258266
(unPerasBLSCryptoAggregateVoteVerificationKey aggPk)
259-
(hashVoteSignature roundNo boostedBlock)
267+
(hashVoteSignature @blk roundNo boostedBlock)
260268
(unPerasBLSCryptoAggregateVoteSignature aggSig)
261269

262-
instance CryptoSupportsBatchVRFVerification PerasBLSCrypto where
270+
instance CryptoSupportsBatchVRFVerification (PerasBLSCrypto blk) where
263271
-- NOTE: in contrast to vote signatures, we cannot aggregate multiple VRF
264272
-- outputs into a single one when forging a certificate (because we need to
265273
-- derive non-persistent seat numbers from each individual one). This means

0 commit comments

Comments
 (0)