@@ -17,6 +17,10 @@ module Cardano.Api.Key.Internal.Leios
1717 , Hash (.. )
1818 , VerificationKey (.. )
1919 , SigningKey (.. )
20+
21+ -- * Possession proof
22+ , BlsPossessionProof
23+ , createBlsPossessionProof
2024 )
2125where
2226
@@ -35,6 +39,7 @@ import Cardano.Crypto.DSIGN.Class qualified as Crypto
3539import Cardano.Crypto.Hash.Class qualified as Crypto
3640import Cardano.Ledger.Hashes (HASH )
3741
42+ import Data.ByteString (ByteString )
3843import Data.Either.Combinators (maybeToRight )
3944import Data.String (IsString (.. ))
4045
@@ -149,3 +154,57 @@ instance HasTextEnvelope (SigningKey BlsKey) where
149154
150155 textEnvelopeDefaultDescr :: SigningKey BlsKey -> TextEnvelopeDescr
151156 textEnvelopeDefaultDescr _ = " BLS12-381 signing key"
157+
158+ -- | BlsPossessionProof is used in the Leios protocol to prove ownership of a BLS signing key
159+ -- when registering a BLS verification key for a stake pool. This is required to prevent malicious
160+ -- actors from registering a BLS verification key for a stake pool without actually owning the
161+ -- corresponding signing key.
162+ newtype BlsPossessionProof = BlsPossessionProof (Crypto. PossessionProofDSIGN Crypto. BLS12381MinSigDSIGN )
163+ deriving stock Eq
164+ deriving newtype (ToCBOR , FromCBOR )
165+ deriving anyclass SerialiseAsCBOR
166+
167+ instance Show BlsPossessionProof where
168+ show _ = " BlsPossessionProof"
169+
170+ instance Pretty BlsPossessionProof where
171+ pretty _ = " BlsPossessionProof"
172+
173+ -- | Proof-of-possession ciphersuite DST for the minimal-signature-size BLS12-381 variant.
174+ --
175+ -- It is used when creating and verifying proofs of possession to ensure domain separation
176+ -- between signing contexts.
177+ minSigPoPContext :: Crypto. BLS12381SignContext
178+ minSigPoPContext = Crypto. BLS12381SignContext (Just minSigPoPDST) Nothing
179+
180+ -- TODO: This is a provisional definition. Import @minSigPoPDST@ from
181+ -- @Cardano.Crypto.DSIGN.BLS12381@ (cardano-crypto-class) when
182+ -- IntersectMBO/cardano-base#635 is merged and the dependency is bumped.
183+ minSigPoPDST :: ByteString
184+ minSigPoPDST = " BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_"
185+
186+ -- | Create a proof of possession for a BLS signing key.
187+ --
188+ -- This proof demonstrates that the holder of a BLS verification key knows the corresponding
189+ -- secret key, which is required before the key can safely participate in signature aggregation.
190+ -- Without this proof, an attacker could register a crafted verification key that cancels out
191+ -- honest participants' keys during aggregation (a rogue key attack).
192+ createBlsPossessionProof :: SigningKey BlsKey -> BlsPossessionProof
193+ createBlsPossessionProof (BlsSigningKey sk) =
194+ BlsPossessionProof (Crypto. createPossessionProofDSIGN minSigPoPContext sk)
195+
196+ instance HasTypeProxy BlsPossessionProof where
197+ data AsType BlsPossessionProof = AsBlsPossessionProof
198+ proxyToAsType _ = AsBlsPossessionProof
199+
200+ instance HasTextEnvelope BlsPossessionProof where
201+ textEnvelopeType :: AsType BlsPossessionProof -> TextEnvelopeType
202+ textEnvelopeType _ =
203+ " BlsPossessionProof_"
204+ <> fromString (Crypto. algorithmNameDSIGN proxy)
205+ where
206+ proxy :: Proxy Crypto. BLS12381MinSigDSIGN
207+ proxy = Proxy
208+
209+ textEnvelopeDefaultDescr :: BlsPossessionProof -> TextEnvelopeDescr
210+ textEnvelopeDefaultDescr _ = " BLS12-381 possession proof"
0 commit comments