@@ -75,6 +75,17 @@ extension MLDSA65 {
7575 try self . backing. signature ( for: data, context: context)
7676 }
7777
78+ /// Generate a signature for the prehashed message representative (a.k.a. "external mu").
79+ ///
80+ /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``.
81+ ///
82+ /// - Parameter mu: The prehashed message representative (a.k.a. "external mu").
83+ ///
84+ /// - Returns: The signature of the prehashed message representative.
85+ public func signature< M: DataProtocol > ( forPrehashedMessageRepresentative mu: M ) throws -> Data {
86+ try self . backing. signature ( forPrehashedMessageRepresentative: mu)
87+ }
88+
7889 /// The size of the private key in bytes.
7990 static let byteCount = Backing . byteCount
8091
@@ -175,6 +186,38 @@ extension MLDSA65 {
175186 return signature
176187 }
177188
189+ /// Generate a signature for the prehashed message representative (a.k.a. "external mu").
190+ ///
191+ /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``.
192+ ///
193+ /// - Parameter mu: The prehashed message representative (a.k.a. "external mu").
194+ ///
195+ /// - Returns: The signature of the prehashed message representative.
196+ func signature< M: DataProtocol > ( forPrehashedMessageRepresentative mu: M ) throws -> Data {
197+ guard mu. count == MLDSA . muByteCount else {
198+ throw CryptoKitError . incorrectParameterSize
199+ }
200+
201+ var signature = Data ( repeating: 0 , count: MLDSA65 . signatureByteCount)
202+
203+ let rc : CInt = signature. withUnsafeMutableBytes { signaturePtr in
204+ let muBytes : ContiguousBytes = mu. regions. count == 1 ? mu. regions. first! : Array ( mu)
205+ return muBytes. withUnsafeBytes { muPtr in
206+ CCryptoBoringSSL_MLDSA65_sign_message_representative (
207+ signaturePtr. baseAddress,
208+ & self . key,
209+ muPtr. baseAddress
210+ )
211+ }
212+ }
213+
214+ guard rc == 1 else {
215+ throw CryptoKitError . internalBoringSSLError ( )
216+ }
217+
218+ return signature
219+ }
220+
178221 /// The size of the private key in bytes.
179222 static let byteCount = Int ( MLDSA65_PRIVATE_KEY_BYTES)
180223 }
@@ -233,6 +276,27 @@ extension MLDSA65 {
233276 self . backing. isValidSignature ( signature, for: data, context: context)
234277 }
235278
279+ /// Generate a prehashed message representative (a.k.a. "external mu") for the given message.
280+ ///
281+ /// - Parameter data: The message to prehash.
282+ ///
283+ /// - Returns: The prehashed message representative (a.k.a. "external mu").
284+ public func prehash< D: DataProtocol > ( for data: D ) throws -> Data {
285+ let context : Data ? = nil
286+ return try self . backing. prehash ( for: data, context: context)
287+ }
288+
289+ /// Generate a prehashed message representative (a.k.a. "external mu") for the given message.
290+ ///
291+ /// - Parameters:
292+ /// - data: The message to prehash.
293+ /// - context: The context of the message.
294+ ///
295+ /// - Returns: The prehashed message representative (a.k.a. "external mu").
296+ public func prehash< D: DataProtocol , C: DataProtocol > ( for data: D , context: C ) throws -> Data {
297+ try self . backing. prehash ( for: data, context: context)
298+ }
299+
236300 /// The size of the public key in bytes.
237301 static let byteCount = Backing . byteCount
238302
@@ -314,6 +378,41 @@ extension MLDSA65 {
314378 }
315379 }
316380
381+ /// Generate a prehashed message representative (a.k.a. "external mu") for the given message.
382+ ///
383+ /// - Parameters:
384+ /// - data: The message to prehash.
385+ /// - context: The context of the message.
386+ ///
387+ /// - Returns: The prehashed message representative (a.k.a. "external mu").
388+ func prehash< D: DataProtocol , C: DataProtocol > ( for data: D , context: C ? ) throws -> Data {
389+ var mu = Data ( repeating: 0 , count: MLDSA . muByteCount)
390+
391+ let dataBytes : ContiguousBytes = data. regions. count == 1 ? data. regions. first! : Array ( data)
392+ let rc : CInt = mu. withUnsafeMutableBytes { muPtr in
393+ dataBytes. withUnsafeBytes { dataPtr in
394+ context. withUnsafeBytes { contextPtr in
395+ var prehash = MLDSA65_prehash ( )
396+ let rc = CCryptoBoringSSL_MLDSA65_prehash_init (
397+ & prehash,
398+ & key,
399+ contextPtr. baseAddress,
400+ contextPtr. count
401+ )
402+ CCryptoBoringSSL_MLDSA65_prehash_update ( & prehash, dataPtr. baseAddress, dataPtr. count)
403+ CCryptoBoringSSL_MLDSA65_prehash_finalize ( muPtr. baseAddress, & prehash)
404+ return rc
405+ }
406+ }
407+ }
408+
409+ guard rc == 1 else {
410+ throw CryptoKitError . internalBoringSSLError ( )
411+ }
412+
413+ return mu
414+ }
415+
317416 /// The size of the public key in bytes.
318417 static let byteCount = Int ( MLDSA65_PUBLIC_KEY_BYTES)
319418 }
@@ -381,6 +480,17 @@ extension MLDSA87 {
381480 try self . backing. signature ( for: data, context: context)
382481 }
383482
483+ /// Generate a signature for the prehashed message representative (a.k.a. "external mu").
484+ ///
485+ /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``.
486+ ///
487+ /// - Parameter mu: The prehashed message representative (a.k.a. "external mu").
488+ ///
489+ /// - Returns: The signature of the prehashed message representative.
490+ public func signature< M: DataProtocol > ( forPrehashedMessageRepresentative mu: M ) throws -> Data {
491+ try self . backing. signature ( forPrehashedMessageRepresentative: mu)
492+ }
493+
384494 /// The size of the private key in bytes.
385495 static let byteCount = Backing . byteCount
386496
@@ -481,6 +591,38 @@ extension MLDSA87 {
481591 return signature
482592 }
483593
594+ /// Generate a signature for the prehashed message representative (a.k.a. "external mu").
595+ ///
596+ /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``.
597+ ///
598+ /// - Parameter mu: The prehashed message representative (a.k.a. "external mu").
599+ ///
600+ /// - Returns: The signature of the prehashed message representative.
601+ func signature< M: DataProtocol > ( forPrehashedMessageRepresentative mu: M ) throws -> Data {
602+ guard mu. count == MLDSA . muByteCount else {
603+ throw CryptoKitError . incorrectParameterSize
604+ }
605+
606+ var signature = Data ( repeating: 0 , count: MLDSA87 . signatureByteCount)
607+
608+ let rc : CInt = signature. withUnsafeMutableBytes { signaturePtr in
609+ let muBytes : ContiguousBytes = mu. regions. count == 1 ? mu. regions. first! : Array ( mu)
610+ return muBytes. withUnsafeBytes { muPtr in
611+ CCryptoBoringSSL_MLDSA87_sign_message_representative (
612+ signaturePtr. baseAddress,
613+ & self . key,
614+ muPtr. baseAddress
615+ )
616+ }
617+ }
618+
619+ guard rc == 1 else {
620+ throw CryptoKitError . internalBoringSSLError ( )
621+ }
622+
623+ return signature
624+ }
625+
484626 /// The size of the private key in bytes.
485627 static let byteCount = Int ( MLDSA87_PRIVATE_KEY_BYTES)
486628 }
@@ -539,6 +681,27 @@ extension MLDSA87 {
539681 self . backing. isValidSignature ( signature, for: data, context: context)
540682 }
541683
684+ /// Generate a prehashed message representative (a.k.a. "external mu") for the given message.
685+ ///
686+ /// - Parameter data: The message to prehash.
687+ ///
688+ /// - Returns: The prehashed message representative (a.k.a. "external mu").
689+ public func prehash< D: DataProtocol > ( for data: D ) throws -> Data {
690+ let context : Data ? = nil
691+ return try self . backing. prehash ( for: data, context: context)
692+ }
693+
694+ /// Generate a prehashed message representative (a.k.a. "external mu") for the given message.
695+ ///
696+ /// - Parameters:
697+ /// - data: The message to prehash.
698+ /// - context: The context of the message.
699+ ///
700+ /// - Returns: The prehashed message representative (a.k.a. "external mu").
701+ public func prehash< D: DataProtocol , C: DataProtocol > ( for data: D , context: C ) throws -> Data {
702+ try self . backing. prehash ( for: data, context: context)
703+ }
704+
542705 /// The size of the public key in bytes.
543706 static let byteCount = Backing . byteCount
544707
@@ -620,6 +783,41 @@ extension MLDSA87 {
620783 }
621784 }
622785
786+ /// Generate a prehashed message representative (a.k.a. "external mu") for the given message.
787+ ///
788+ /// - Parameters:
789+ /// - data: The message to prehash.
790+ /// - context: The context of the message.
791+ ///
792+ /// - Returns: The prehashed message representative (a.k.a. "external mu").
793+ func prehash< D: DataProtocol , C: DataProtocol > ( for data: D , context: C ? ) throws -> Data {
794+ var mu = Data ( repeating: 0 , count: MLDSA . muByteCount)
795+
796+ let dataBytes : ContiguousBytes = data. regions. count == 1 ? data. regions. first! : Array ( data)
797+ let rc : CInt = mu. withUnsafeMutableBytes { muPtr in
798+ dataBytes. withUnsafeBytes { dataPtr in
799+ context. withUnsafeBytes { contextPtr in
800+ var prehash = MLDSA87_prehash ( )
801+ let rc = CCryptoBoringSSL_MLDSA87_prehash_init (
802+ & prehash,
803+ & key,
804+ contextPtr. baseAddress,
805+ contextPtr. count
806+ )
807+ CCryptoBoringSSL_MLDSA87_prehash_update ( & prehash, dataPtr. baseAddress, dataPtr. count)
808+ CCryptoBoringSSL_MLDSA87_prehash_finalize ( muPtr. baseAddress, & prehash)
809+ return rc
810+ }
811+ }
812+ }
813+
814+ guard rc == 1 else {
815+ throw CryptoKitError . internalBoringSSLError ( )
816+ }
817+
818+ return mu
819+ }
820+
623821 /// The size of the public key in bytes.
624822 static let byteCount = Int ( MLDSA87_PUBLIC_KEY_BYTES)
625823 }
@@ -635,4 +833,7 @@ extension MLDSA87 {
635833private enum MLDSA {
636834 /// The size of the seed in bytes.
637835 fileprivate static let seedByteCount = 32
836+
837+ /// The size of the "mu" value in bytes.
838+ fileprivate static let muByteCount = 64
638839}
0 commit comments