| License | BSD-style |
|---|---|
| Maintainer | Kazu Yamamoto <kazu@iij.ad.jp> |
| Stability | experimental |
| Portability | unknown |
| Safe Haskell | None |
| Language | Haskell2010 |
Crypto.PubKey.MLDSA
Description
ML-DSA, the Module-Lattice-Based Digital Signature Algorithm of FIPS 204, in all three parameter sets.
(vk, sk) <- generateKeyPair MLDSA65 sig <- sign sk emptyContext message verify vk emptyContext message sig
What generateKeyPair and sign draw their randomness from is the
MonadRandom instance in use. Its documentation says what
an instance of your own has to be.
The parameter set is a type, so an ML-DSA-65 key cannot be passed where an ML-DSA-87 one is expected. The three are fixed by FIPS 204 and the class has no other instances.
This is pure ML-DSA: the message goes in whole. The pre-hash variant (HashML-DSA) is a different algorithm with a different domain separator and is not offered here.
Synopsis
- data MLDSA44 = MLDSA44
- data MLDSA65 = MLDSA65
- data MLDSA87 = MLDSA87
- class MLDSA p where
- verificationKeySize :: proxy p -> Int
- signingKeySize :: proxy p -> Int
- signatureSize :: proxy p -> Int
- data VerificationKey p
- data SigningKey p
- data Signature p
- verificationKey :: (MLDSA p, ByteArrayAccess ba) => ba -> CryptoFailable (VerificationKey p)
- signingKey :: (MLDSA p, ByteArrayAccess ba) => ba -> CryptoFailable (SigningKey p)
- signature :: (MLDSA p, ByteArrayAccess ba) => ba -> CryptoFailable (Signature p)
- generateKeyPair :: forall p proxy m. (MLDSA p, MonadRandom m) => proxy p -> m (VerificationKey p, SigningKey p)
- generateKeyPairAndSeed :: forall p proxy m. (MLDSA p, MonadRandom m) => proxy p -> m (VerificationKey p, SigningKey p, ScrubbedBytes)
- keyPairFromSeed :: forall p proxy ba. (MLDSA p, ByteArrayAccess ba) => proxy p -> ba -> CryptoFailable (VerificationKey p, SigningKey p)
- toPublic :: MLDSA p => SigningKey p -> VerificationKey p
- data Context
- context :: ByteArrayAccess ba => ba -> CryptoFailable Context
- emptyContext :: Context
- data Mu
- mu :: ByteArrayAccess ba => ba -> CryptoFailable Mu
- messageRepresentative :: (MLDSA p, ByteArrayAccess msg) => VerificationKey p -> Context -> msg -> Mu
- data MuContext
- muInit :: MLDSA p => VerificationKey p -> Context -> MuContext
- muUpdate :: ByteArrayAccess msg => MuContext -> msg -> MuContext
- muUpdates :: ByteArrayAccess msg => MuContext -> [msg] -> MuContext
- muFinalize :: MuContext -> Mu
- sign :: (MLDSA p, MonadRandom m, ByteArrayAccess msg) => SigningKey p -> Context -> msg -> m (Signature p)
- signWith :: (MLDSA p, ByteArrayAccess msg, ByteArrayAccess rnd) => SigningKey p -> Context -> msg -> rnd -> CryptoFailable (Signature p)
- signDeterministic :: (MLDSA p, ByteArrayAccess msg) => SigningKey p -> Context -> msg -> Signature p
- verify :: (MLDSA p, ByteArrayAccess msg) => VerificationKey p -> Context -> msg -> Signature p -> Bool
- signExternalMu :: (MLDSA p, MonadRandom m) => SigningKey p -> Mu -> m (Signature p)
- signExternalMuWith :: (MLDSA p, ByteArrayAccess rnd) => SigningKey p -> Mu -> rnd -> CryptoFailable (Signature p)
- signExternalMuDeterministic :: MLDSA p => SigningKey p -> Mu -> Signature p
- verifyExternalMu :: MLDSA p => VerificationKey p -> Mu -> Signature p -> Bool
- seedSize :: Int
- signingRandomnessSize :: Int
- maxContextLength :: Int
- muSize :: Int
Parameter sets
ML-DSA-44.
Constructors
| MLDSA44 |
Instances
| Show MLDSA44 Source # | |
| MLDSA MLDSA44 Source # | |
Defined in Crypto.PubKey.MLDSA Methods verificationKeySize :: proxy MLDSA44 -> Int Source # signingKeySize :: proxy MLDSA44 -> Int Source # signatureSize :: proxy MLDSA44 -> Int Source # c_keypair :: proxy MLDSA44 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_sign :: proxy MLDSA44 -> Ptr Word8 -> Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> Ptr Word8 -> Ptr Word8 -> CInt -> IO CInt c_verify :: proxy MLDSA44 -> Ptr Word8 -> Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> Ptr Word8 -> CInt -> IO CInt c_pkFromSk :: proxy MLDSA44 -> Ptr Word8 -> Ptr Word8 -> IO CInt | |
| Eq MLDSA44 Source # | |
ML-DSA-65.
Constructors
| MLDSA65 |
Instances
| Show MLDSA65 Source # | |
| MLDSA MLDSA65 Source # | |
Defined in Crypto.PubKey.MLDSA Methods verificationKeySize :: proxy MLDSA65 -> Int Source # signingKeySize :: proxy MLDSA65 -> Int Source # signatureSize :: proxy MLDSA65 -> Int Source # c_keypair :: proxy MLDSA65 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_sign :: proxy MLDSA65 -> Ptr Word8 -> Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> Ptr Word8 -> Ptr Word8 -> CInt -> IO CInt c_verify :: proxy MLDSA65 -> Ptr Word8 -> Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> Ptr Word8 -> CInt -> IO CInt c_pkFromSk :: proxy MLDSA65 -> Ptr Word8 -> Ptr Word8 -> IO CInt | |
| Eq MLDSA65 Source # | |
ML-DSA-87.
Constructors
| MLDSA87 |
Instances
| Show MLDSA87 Source # | |
| MLDSA MLDSA87 Source # | |
Defined in Crypto.PubKey.MLDSA Methods verificationKeySize :: proxy MLDSA87 -> Int Source # signingKeySize :: proxy MLDSA87 -> Int Source # signatureSize :: proxy MLDSA87 -> Int Source # c_keypair :: proxy MLDSA87 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_sign :: proxy MLDSA87 -> Ptr Word8 -> Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> Ptr Word8 -> Ptr Word8 -> CInt -> IO CInt c_verify :: proxy MLDSA87 -> Ptr Word8 -> Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> Ptr Word8 -> CInt -> IO CInt c_pkFromSk :: proxy MLDSA87 -> Ptr Word8 -> Ptr Word8 -> IO CInt | |
| Eq MLDSA87 Source # | |
The three parameter sets of FIPS 204.
Named for the algorithm rather than "DSA", which is a different one that crypton also has, in Crypto.PubKey.DSA. It is the three sets FIPS 204 defines, closed, carrying their sizes and the calls into the implementation; only the sizes are exported.
Minimal complete definition
verificationKeySize, signingKeySize, signatureSize, c_keypair, c_sign, c_verify, c_pkFromSk
Methods
verificationKeySize :: proxy p -> Int Source #
Size in bytes of a VerificationKey of this parameter set.
signingKeySize :: proxy p -> Int Source #
Size in bytes of a SigningKey of this parameter set.
signatureSize :: proxy p -> Int Source #
Size in bytes of a Signature of this parameter set.
Instances
Keys and signatures
data VerificationKey p Source #
A public verification key.
Instances
| Show (VerificationKey p) Source # | |
Defined in Crypto.PubKey.MLDSA Methods showsPrec :: Int -> VerificationKey p -> ShowS # show :: VerificationKey p -> String # showList :: [VerificationKey p] -> ShowS # | |
| NFData (VerificationKey p) Source # | |
Defined in Crypto.PubKey.MLDSA Methods rnf :: VerificationKey p -> () # | |
| Eq (VerificationKey p) Source # | |
Defined in Crypto.PubKey.MLDSA Methods (==) :: VerificationKey p -> VerificationKey p -> Bool # (/=) :: VerificationKey p -> VerificationKey p -> Bool # | |
| ByteArrayAccess (VerificationKey p) Source # | |
Defined in Crypto.PubKey.MLDSA Methods length :: VerificationKey p -> Int # withByteArray :: VerificationKey p -> (Ptr p0 -> IO a) -> IO a # copyByteArrayToPtr :: VerificationKey p -> Ptr p0 -> IO () # | |
data SigningKey p Source #
A private signing key.
Instances
| Show (SigningKey p) Source # | |
Defined in Crypto.PubKey.MLDSA Methods showsPrec :: Int -> SigningKey p -> ShowS # show :: SigningKey p -> String # showList :: [SigningKey p] -> ShowS # | |
| DebugShow (SigningKey p) Source # | |
Defined in Crypto.PubKey.MLDSA Methods debugShow :: SigningKey p -> String Source # | |
| NFData (SigningKey p) Source # | |
Defined in Crypto.PubKey.MLDSA Methods rnf :: SigningKey p -> () # | |
| Eq (SigningKey p) Source # | |
Defined in Crypto.PubKey.MLDSA | |
| ByteArrayAccess (SigningKey p) Source # | |
Defined in Crypto.PubKey.MLDSA Methods length :: SigningKey p -> Int # withByteArray :: SigningKey p -> (Ptr p0 -> IO a) -> IO a # copyByteArrayToPtr :: SigningKey p -> Ptr p0 -> IO () # | |
A signature.
Smart constructors
verificationKey :: (MLDSA p, ByteArrayAccess ba) => ba -> CryptoFailable (VerificationKey p) Source #
Try to read a verification key. Only the length is checked: a verification key is a packed encoding with no redundancy to test, and one that is not a real key simply verifies nothing.
signingKey :: (MLDSA p, ByteArrayAccess ba) => ba -> CryptoFailable (SigningKey p) Source #
Try to read a signing key.
Beyond the length this runs the validity checks of the implementation: the secret polynomials must have coefficients in range, and the commitment and the public-key hash the key carries must match what is recomputed from the rest of it. A key that fails has been damaged or was never a key, and signing with it would produce signatures nothing verifies.
signature :: (MLDSA p, ByteArrayAccess ba) => ba -> CryptoFailable (Signature p) Source #
Try to read a signature. Only the length is checked; whether it is a
signature of anything is what verify answers.
Generating a key pair
generateKeyPair :: forall p proxy m. (MLDSA p, MonadRandom m) => proxy p -> m (VerificationKey p, SigningKey p) Source #
Generate a key pair.
The seed it is derived from is drawn here and thrown away. Use
generateKeyPairAndSeed where it has to be kept.
generateKeyPairAndSeed :: forall p proxy m. (MLDSA p, MonadRandom m) => proxy p -> m (VerificationKey p, SigningKey p, ScrubbedBytes) Source #
Generate a key pair and hand back the seed it was derived from, xi
in FIPS 204.
A SigningKey is the expanded key and nothing else, so the seed cannot
be recovered from a pair afterwards. An application that has to write
the key out in a form that keeps the seed -- RFC 9881 lets an ML-DSA
private key be the seed, the expanded key, or both -- has to generate it
here:
(vk, sk, seed) <- generateKeyPairAndSeed MLDSA65
The seed is as secret as the signing key: keyPairFromSeed turns it
back into the same pair.
keyPairFromSeed :: forall p proxy ba. (MLDSA p, ByteArrayAccess ba) => proxy p -> ba -> CryptoFailable (VerificationKey p, SigningKey p) Source #
Derive a key pair from a seed, xi in FIPS 204, which must be
seedSize bytes.
toPublic :: MLDSA p => SigningKey p -> VerificationKey p Source #
Recover the verification key a signing key was made with.
The context string
The context string a signature is bound to, at most
maxContextLength bytes.
FIPS 204 mixes it into what is signed, so a signature made under one
context does not verify under another. Two uses of one key that don't
agree on a context string cannot be made to accept each other's
signatures. Use emptyContext where there is nothing to separate -- TLS,
for one, signs with an empty context.
context :: ByteArrayAccess ba => ba -> CryptoFailable Context Source #
Try to build a context string.
emptyContext :: Context Source #
The context string of length zero, which is what to sign under when there is nothing to separate.
It is a context and not the absence of one: sign always takes one, and
what this separates from is every non-empty context there is.
The message representative
The message representative, mu in FIPS 204: a 64-byte commitment to
the verification key, the context string and the message, and the only
part of them that signing and verification actually read.
Signing it directly is the "external mu" interface. It is for a caller that has the representative without having the message in one piece: a message arriving as a stream, or hashed on another machine, or by a device that holds the key and is handed only this. TLS does not need it.
mu :: ByteArrayAccess ba => ba -> CryptoFailable Mu Source #
Try to read a message representative.
messageRepresentative :: (MLDSA p, ByteArrayAccess msg) => VerificationKey p -> Context -> msg -> Mu Source #
Compute the message representative, for a caller that wants to make it here and sign it later, or sign it elsewhere.
and signExternalMuDeterministic sk (messageRepresentative (toPublic sk) ctx msg) are the same signature.signDeterministic sk ctx msg
A message that does not arrive in one piece
muInit :: MLDSA p => VerificationKey p -> Context -> MuContext Source #
Begin a message representative. The key and the context string are what it is bound to, and they are all that is needed before the message.
muFinalize (muUpdates (muInit vk ctx) chunks)
is messageRepresentative of the chunks joined, so a message too large
to hold at once never has to be.
muUpdate :: ByteArrayAccess msg => MuContext -> msg -> MuContext Source #
Absorb a piece of the message.
muUpdates :: ByteArrayAccess msg => MuContext -> [msg] -> MuContext Source #
Absorb several pieces, which is muUpdate one after the other.
muFinalize :: MuContext -> Mu Source #
The message representative of everything absorbed so far.
Signing and verifying
sign :: (MLDSA p, MonadRandom m, ByteArrayAccess msg) => SigningKey p -> Context -> msg -> m (Signature p) Source #
Sign a message.
This is the hedged signing FIPS 204 recommends: fresh randomness goes in alongside the key and the message, so two signatures of one message differ and a fault in one reveals less. Verification does not care which of the three entry points made the signature.
signWith :: (MLDSA p, ByteArrayAccess msg, ByteArrayAccess rnd) => SigningKey p -> Context -> msg -> rnd -> CryptoFailable (Signature p) Source #
Sign with the randomness supplied, which must be
signingRandomnessSize bytes.
For test vectors, and for callers who draw their own randomness. Ordinary
use wants sign.
signDeterministic :: (MLDSA p, ByteArrayAccess msg) => SigningKey p -> Context -> msg -> Signature p Source #
Sign deterministically, as FIPS 204 section 3.4 allows: the randomness is replaced by zeroes, so one key and one message always give one signature.
This is what test vectors are written against, and what to use where the
signature must be reproducible. It gives up what hedging buys, so where
there is a usable random source sign is the better default.
verify :: (MLDSA p, ByteArrayAccess msg) => VerificationKey p -> Context -> msg -> Signature p -> Bool Source #
Verify a signature.
The context must be the one it was signed under; anything else is a rejection, which is what the context is for.
Signing and verifying a message representative
signExternalMu :: (MLDSA p, MonadRandom m) => SigningKey p -> Mu -> m (Signature p) Source #
Sign a message representative, drawing the randomness.
The context string is already inside the representative, which is why this does not take one.
signExternalMuWith :: (MLDSA p, ByteArrayAccess rnd) => SigningKey p -> Mu -> rnd -> CryptoFailable (Signature p) Source #
Sign a message representative with the randomness supplied.
signExternalMuDeterministic :: MLDSA p => SigningKey p -> Mu -> Signature p Source #
Sign a message representative deterministically.
verifyExternalMu :: MLDSA p => VerificationKey p -> Mu -> Signature p -> Bool Source #
Verify a signature of a message representative.
Sizes
Size in bytes of the seed keyPairFromSeed takes, xi in FIPS 204.
signingRandomnessSize :: Int Source #
Size in bytes of the randomness signWith takes.
maxContextLength :: Int Source #
The longest context string FIPS 204 allows, which is 255 bytes because its length is encoded in one byte.