mirror of
https://github.com/emmansun/gmsm.git
synced 2025-05-10 19:16:18 +08:00
mldsa: supports prehash dsa
This commit is contained in:
parent
dfd4143c65
commit
834873f0e8
@ -7,17 +7,18 @@
|
||||
// Package mldsa implements the quantum-resistant digital signature algorithm
|
||||
// ML-DSA (Module-Lattice-Based Digital Signature Standard) as specified in [NIST FIPS 204].
|
||||
//
|
||||
// [NIST FIPS 204]: https://doi.org/10.6028/NIST.FIPS.204
|
||||
//
|
||||
// This implementations referenced OpenSSL's implementation of ML-DSA and part of Golang ML-KEM
|
||||
// [OpenSSL ML-DSA]: https://github.com/openssl/openssl/blob/master/crypto/ml_dsa
|
||||
// [Golang ML-KEM]: https://github.com/golang/go/blob/master/src/crypto/internal/fips140/mlkem
|
||||
//
|
||||
// [NIST FIPS 204]: https://doi.org/10.6028/NIST.FIPS.204
|
||||
package mldsa
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/sha3"
|
||||
"crypto/subtle"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
@ -403,6 +404,35 @@ func (sk *PrivateKey44) Sign(rand io.Reader, message, context []byte) ([]byte, e
|
||||
return sk.signInternal(seed[:], mu[:])
|
||||
}
|
||||
|
||||
func (sk *PrivateKey44) SignPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
|
||||
if len(message) == 0 {
|
||||
return nil, errors.New("mldsa: empty message")
|
||||
}
|
||||
if len(context) > 255 {
|
||||
return nil, errors.New("mldsa: context too long")
|
||||
}
|
||||
preHashValue, err := preHash(oid, message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var seed [SeedSize]byte
|
||||
if _, err := io.ReadFull(rand, seed[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
H := sha3.NewSHAKE256()
|
||||
H.Write(sk.tr[:])
|
||||
H.Write([]byte{1, byte(len(context))})
|
||||
if len(context) > 0 {
|
||||
H.Write(context)
|
||||
}
|
||||
H.Write(preHashValue)
|
||||
var mu [64]byte
|
||||
H.Read(mu[:])
|
||||
|
||||
return sk.signInternal(seed[:], mu[:])
|
||||
}
|
||||
|
||||
func (sk *PrivateKey44) signInternal(seed, mu []byte) ([]byte, error) {
|
||||
var s1NTT [l44]nttElement
|
||||
var s2NTT [k44]nttElement
|
||||
@ -530,6 +560,33 @@ func (pk *PublicKey44) Verify(sig []byte, message, context []byte) bool {
|
||||
return pk.verifyInternal(sig, mu[:])
|
||||
}
|
||||
|
||||
func (pk *PublicKey44) VerifyPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
|
||||
if len(message) == 0 {
|
||||
return false
|
||||
}
|
||||
if len(context) > 255 {
|
||||
return false
|
||||
}
|
||||
if len(sig) != sigEncodedLen44 {
|
||||
return false
|
||||
}
|
||||
preHashValue, err := preHash(oid, message)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
H := sha3.NewSHAKE256()
|
||||
H.Write(pk.tr[:])
|
||||
H.Write([]byte{1, byte(len(context))})
|
||||
if len(context) > 0 {
|
||||
H.Write(context)
|
||||
}
|
||||
H.Write(preHashValue)
|
||||
var mu [64]byte
|
||||
H.Read(mu[:])
|
||||
|
||||
return pk.verifyInternal(sig, mu[:])
|
||||
}
|
||||
|
||||
func (pk *PublicKey44) verifyInternal(sig, mu []byte) bool {
|
||||
// Decode the signature
|
||||
cTilde := sig[:lambda128/4]
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,6 +10,7 @@ import (
|
||||
"crypto"
|
||||
"crypto/sha3"
|
||||
"crypto/subtle"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
@ -318,6 +319,35 @@ func (sk *PrivateKey65) Sign(rand io.Reader, message, context []byte) ([]byte, e
|
||||
return sk.signInternal(seed[:], mu[:])
|
||||
}
|
||||
|
||||
func (sk *PrivateKey65) SignPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
|
||||
if len(message) == 0 {
|
||||
return nil, errors.New("mldsa: empty message")
|
||||
}
|
||||
if len(context) > 255 {
|
||||
return nil, errors.New("mldsa: context too long")
|
||||
}
|
||||
preHashValue, err := preHash(oid, message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var seed [SeedSize]byte
|
||||
if _, err := io.ReadFull(rand, seed[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
H := sha3.NewSHAKE256()
|
||||
H.Write(sk.tr[:])
|
||||
H.Write([]byte{1, byte(len(context))})
|
||||
if len(context) > 0 {
|
||||
H.Write(context)
|
||||
}
|
||||
H.Write(preHashValue)
|
||||
var mu [64]byte
|
||||
H.Read(mu[:])
|
||||
|
||||
return sk.signInternal(seed[:], mu[:])
|
||||
}
|
||||
|
||||
func (sk *PrivateKey65) signInternal(seed, mu []byte) ([]byte, error) {
|
||||
var s1NTT [l65]nttElement
|
||||
var s2NTT [k65]nttElement
|
||||
@ -443,6 +473,33 @@ func (pk *PublicKey65) Verify(sig []byte, message, context []byte) bool {
|
||||
return pk.verifyInternal(sig, mu[:])
|
||||
}
|
||||
|
||||
func (pk *PublicKey65) VerifyPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
|
||||
if len(message) == 0 {
|
||||
return false
|
||||
}
|
||||
if len(context) > 255 {
|
||||
return false
|
||||
}
|
||||
if len(sig) != sigEncodedLen65 {
|
||||
return false
|
||||
}
|
||||
preHashValue, err := preHash(oid, message)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
H := sha3.NewSHAKE256()
|
||||
H.Write(pk.tr[:])
|
||||
H.Write([]byte{1, byte(len(context))})
|
||||
if len(context) > 0 {
|
||||
H.Write(context)
|
||||
}
|
||||
H.Write(preHashValue)
|
||||
var mu [64]byte
|
||||
H.Read(mu[:])
|
||||
|
||||
return pk.verifyInternal(sig, mu[:])
|
||||
}
|
||||
|
||||
func (pk *PublicKey65) verifyInternal(sig, mu []byte) bool {
|
||||
// Decode the signature
|
||||
cTilde := sig[:lambda192/4]
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,6 +10,7 @@ import (
|
||||
"crypto"
|
||||
"crypto/sha3"
|
||||
"crypto/subtle"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
@ -318,6 +319,35 @@ func (sk *PrivateKey87) Sign(rand io.Reader, message, context []byte) ([]byte, e
|
||||
return sk.signInternal(seed[:], mu[:])
|
||||
}
|
||||
|
||||
func (sk *PrivateKey87) SignPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
|
||||
if len(message) == 0 {
|
||||
return nil, errors.New("mldsa: empty message")
|
||||
}
|
||||
if len(context) > 255 {
|
||||
return nil, errors.New("mldsa: context too long")
|
||||
}
|
||||
preHashValue, err := preHash(oid, message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var seed [SeedSize]byte
|
||||
if _, err := io.ReadFull(rand, seed[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
H := sha3.NewSHAKE256()
|
||||
H.Write(sk.tr[:])
|
||||
H.Write([]byte{1, byte(len(context))})
|
||||
if len(context) > 0 {
|
||||
H.Write(context)
|
||||
}
|
||||
H.Write(preHashValue)
|
||||
var mu [64]byte
|
||||
H.Read(mu[:])
|
||||
|
||||
return sk.signInternal(seed[:], mu[:])
|
||||
}
|
||||
|
||||
func (sk *PrivateKey87) signInternal(seed, mu []byte) ([]byte, error) {
|
||||
var s1NTT [l87]nttElement
|
||||
var s2NTT [k87]nttElement
|
||||
@ -445,6 +475,33 @@ func (pk *PublicKey87) Verify(sig []byte, message, context []byte) bool {
|
||||
return pk.verifyInternal(sig, mu[:])
|
||||
}
|
||||
|
||||
func (pk *PublicKey87) VerifyPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
|
||||
if len(message) == 0 {
|
||||
return false
|
||||
}
|
||||
if len(context) > 255 {
|
||||
return false
|
||||
}
|
||||
if len(sig) != sigEncodedLen87 {
|
||||
return false
|
||||
}
|
||||
preHashValue, err := preHash(oid, message)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
H := sha3.NewSHAKE256()
|
||||
H.Write(pk.tr[:])
|
||||
H.Write([]byte{1, byte(len(context))})
|
||||
if len(context) > 0 {
|
||||
H.Write(context)
|
||||
}
|
||||
H.Write(preHashValue)
|
||||
var mu [64]byte
|
||||
H.Read(mu[:])
|
||||
|
||||
return pk.verifyInternal(sig, mu[:])
|
||||
}
|
||||
|
||||
func (pk *PublicKey87) verifyInternal(sig, mu []byte) bool {
|
||||
// Decode the signature
|
||||
cTilde := sig[:lambda256/4]
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user