Skip to content

Add FixedSizeBytes, lift VRF sizes to the type level#665

Draft
Soupstraw wants to merge 31 commits into
masterfrom
jj/fixedsizebytes
Draft

Add FixedSizeBytes, lift VRF sizes to the type level#665
Soupstraw wants to merge 31 commits into
masterfrom
jj/fixedsizebytes

Conversation

@Soupstraw

@Soupstraw Soupstraw commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Description

This PR lifts the sizes of VerKeyVRF, SignKeyVRF and CertVRF to the type level, which is similar to what we already do for DSIGN and KES. I also added the FixedSizeBytes typeclass, which gives a uniform interface to all the rawDeserialise* and encode* functions for DSIGN/KES/VRF types.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated
  • All visible changes are prepended to the latest section of a CHANGELOG.md for the affected packages.
    New section is never added with the code changes. (See RELEASING.md)
  • When applicable, versions are updated in .cabal and CHANGELOG.md files according to the
    versioning process.
  • The version bounds in .cabal files for all affected packages are updated.
    If you change the bounds in a cabal file, that package itself must have a version increase. (See RELEASING.md)
  • Self-reviewed the diff

@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch 5 times, most recently from 91ae16a to f5bc0ae Compare June 1, 2026 11:49
@Soupstraw Soupstraw marked this pull request as ready for review June 1, 2026 12:12
@Soupstraw Soupstraw requested a review from lehins as a code owner June 1, 2026 12:12
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch 4 times, most recently from 9304d9a to 4956ff8 Compare June 1, 2026 12:24
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch from 4956ff8 to 23c6496 Compare June 12, 2026 11:49

@neilmayhew neilmayhew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. My comments are just suggestions.

Comment thread cardano-crypto-class/src/Cardano/Crypto/VRF/Class.hs Outdated
Comment thread cardano-crypto-class/src/Cardano/Crypto/VRF/Class.hs
Comment thread cardano-crypto-praos/testlib/Test/Crypto/VRF.hs Outdated
Comment thread cardano-crypto-praos/CHANGELOG.md Outdated
Comment thread cardano-crypto-class/src/Cardano/Crypto/FixedSizeBytes.hs Outdated
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch 3 times, most recently from d62deb2 to 52b93c6 Compare June 17, 2026 13:08
@Soupstraw Soupstraw enabled auto-merge June 17, 2026 13:08
@Soupstraw Soupstraw disabled auto-merge June 17, 2026 13:09
@Soupstraw Soupstraw enabled auto-merge June 17, 2026 13:10
@Soupstraw Soupstraw disabled auto-merge June 17, 2026 14:40

@lehins lehins left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am blocking this PR because I want to give my review before it gets merged

@lehins lehins left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very nice direction! Still needs a bit of love though to make ideal.

Comment thread cardano-crypto-class/src/Cardano/Crypto/FixedSizeBytes.hs Outdated
Comment thread cardano-crypto-class/src/Cardano/Crypto/FixedSizeBytes.hs Outdated
Comment thread cardano-crypto-class/src/Cardano/Crypto/FixedSizeBytes.hs Outdated
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch 2 times, most recently from 5bb498c to fe2e04d Compare June 19, 2026 11:11
@Soupstraw Soupstraw requested a review from a team as a code owner June 19, 2026 11:11
@Soupstraw Soupstraw requested a review from lehins June 19, 2026 14:07
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch 2 times, most recently from 1523a46 to 19ee900 Compare June 19, 2026 14:29
Make rawDecodeFixedSized MonadFail-returning and add
mkRawFixedSizedDecoder, which supplies a human-readable noun while
deriving the type name and expected size from the type. DSIGN/KES/VRF
ToCBOR/FromCBOR instances and the Signed/Certified codecs now use
encodeFixedSized/decodeFixedSized; the per-type encode*/decode*
functions are deprecated.

Deserialise error messages now use the type-constructor name (e.g.
"VerKeyDSIGN:") instead of the decoder function name; test
expectations updated accordingly. Rename prop_cbor_with ->
prop_cbor_fixed_sized and prop_cbor_direct_vs_class ->
prop_cbor_fixed_sized_vs_class, dropping their encoder/decoder args.
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch from f093a6b to 5e28649 Compare June 25, 2026 08:42

@lehins lehins left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to reduce duplication if we introducing this new interface, which requires inverting the approach of rawEncodeFixedSized/rawDecodeFixedSized using rawSerialise*/rawDeserialise*

Comment thread cardano-binary/src/Cardano/Binary/FixedSizeCodec.hs
Comment thread cardano-binary/src/Cardano/Binary/FixedSizeCodec.hs Outdated
Comment on lines +26 to +35
-- | Build a raw fixed-size decoder, failing with an informative message when
-- the underlying decoder returns 'Nothing'. The first argument should be a
-- noun describing the type (e.g. "key", "signature")
mkRawFixedSizedDecoder ::
forall a m.
(Typeable a, KnownNat (FixedSize a), MonadFail m) =>
String -> (BS.ByteString -> Maybe a) -> BS.ByteString -> m a
mkRawFixedSizedDecoder name rawDecode bs =
maybe (failFixedSized name (Proxy @a) bs) pure (rawDecode bs)
{-# INLINE mkRawFixedSizedDecoder #-}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you missed the point of my suggestion about MonadFail

The goal is to:

  • avoid duplicate logic of checking the size
  • improve failure messages
  • and later deprecation or extraction into standalone functions of individual rawDeserialise* functions.

Which means we need an instance of FixedSizeCodec for each algorithm, eg. instance FixedSizeCodec (VerKeyDSIGN Ed25519DSIGN) and all of the raw(Des|S)erialise* can get this implementation rawDeserialise* = rawDecodeFixedSized

Suggested change
-- | Build a raw fixed-size decoder, failing with an informative message when
-- the underlying decoder returns 'Nothing'. The first argument should be a
-- noun describing the type (e.g. "key", "signature")
mkRawFixedSizedDecoder ::
forall a m.
(Typeable a, KnownNat (FixedSize a), MonadFail m) =>
String -> (BS.ByteString -> Maybe a) -> BS.ByteString -> m a
mkRawFixedSizedDecoder name rawDecode bs =
maybe (failFixedSized name (Proxy @a) bs) pure (rawDecode bs)
{-# INLINE mkRawFixedSizedDecoder #-}

@Soupstraw Soupstraw marked this pull request as draft June 26, 2026 14:31
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch from 8ad5a6a to 592a5c3 Compare June 26, 2026 14:56
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch from 592a5c3 to bffd13f Compare June 26, 2026 14:57
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch 2 times, most recently from a23cc29 to 24cc783 Compare June 26, 2026 15:16
@Soupstraw Soupstraw force-pushed the jj/fixedsizebytes branch from 03cb8bd to a6753eb Compare June 26, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants