github.com/cloudflare/circl@v1.5.0/sign/mldsa/mldsa87/dilithium.go (about)

     1  // Code generated from pkg.templ.go. DO NOT EDIT.
     2  
     3  // mldsa87 implements NIST signature scheme ML-DSA-87 as defined in FIPS204.
     4  package mldsa87
     5  
     6  import (
     7  	"crypto"
     8  	cryptoRand "crypto/rand"
     9  	"errors"
    10  	"io"
    11  
    12  	"github.com/cloudflare/circl/sign"
    13  	common "github.com/cloudflare/circl/sign/internal/dilithium"
    14  	"github.com/cloudflare/circl/sign/mldsa/mldsa87/internal"
    15  )
    16  
    17  const (
    18  	// Size of seed for NewKeyFromSeed
    19  	SeedSize = common.SeedSize
    20  
    21  	// Size of a packed PublicKey
    22  	PublicKeySize = internal.PublicKeySize
    23  
    24  	// Size of a packed PrivateKey
    25  	PrivateKeySize = internal.PrivateKeySize
    26  
    27  	// Size of a signature
    28  	SignatureSize = internal.SignatureSize
    29  )
    30  
    31  // PublicKey is the type of ML-DSA-87 public key
    32  type PublicKey internal.PublicKey
    33  
    34  // PrivateKey is the type of ML-DSA-87 private key
    35  type PrivateKey internal.PrivateKey
    36  
    37  // GenerateKey generates a public/private key pair using entropy from rand.
    38  // If rand is nil, crypto/rand.Reader will be used.
    39  func GenerateKey(rand io.Reader) (*PublicKey, *PrivateKey, error) {
    40  	pk, sk, err := internal.GenerateKey(rand)
    41  	return (*PublicKey)(pk), (*PrivateKey)(sk), err
    42  }
    43  
    44  // NewKeyFromSeed derives a public/private key pair using the given seed.
    45  func NewKeyFromSeed(seed *[SeedSize]byte) (*PublicKey, *PrivateKey) {
    46  	pk, sk := internal.NewKeyFromSeed(seed)
    47  	return (*PublicKey)(pk), (*PrivateKey)(sk)
    48  }
    49  
    50  // SignTo signs the given message and writes the signature into signature.
    51  // It will panic if signature is not of length at least SignatureSize.
    52  //
    53  // ctx is the optional context string. Errors if ctx is larger than 255 bytes.
    54  // A nil context string is equivalent to an empty context string.
    55  func SignTo(sk *PrivateKey, msg, ctx []byte, randomized bool, sig []byte) error {
    56  	var rnd [32]byte
    57  	if randomized {
    58  		_, err := cryptoRand.Read(rnd[:])
    59  		if err != nil {
    60  			return err
    61  		}
    62  	}
    63  
    64  	if len(ctx) > 255 {
    65  		return sign.ErrContextTooLong
    66  	}
    67  
    68  	internal.SignTo(
    69  		(*internal.PrivateKey)(sk),
    70  		func(w io.Writer) {
    71  			_, _ = w.Write([]byte{0})
    72  			_, _ = w.Write([]byte{byte(len(ctx))})
    73  
    74  			if ctx != nil {
    75  				_, _ = w.Write(ctx)
    76  			}
    77  			w.Write(msg)
    78  		},
    79  		rnd,
    80  		sig,
    81  	)
    82  	return nil
    83  }
    84  
    85  // Do not use. Implements ML-DSA.Sign_internal used for compatibility tests.
    86  func (sk *PrivateKey) unsafeSignInternal(msg []byte, rnd [32]byte) []byte {
    87  	var ret [SignatureSize]byte
    88  	internal.SignTo(
    89  		(*internal.PrivateKey)(sk),
    90  		func(w io.Writer) {
    91  			_, _ = w.Write(msg)
    92  		},
    93  		rnd,
    94  		ret[:],
    95  	)
    96  	return ret[:]
    97  }
    98  
    99  // Do not use. Implements ML-DSA.Verify_internal used for compatibility tests.
   100  func unsafeVerifyInternal(pk *PublicKey, msg, sig []byte) bool {
   101  	return internal.Verify(
   102  		(*internal.PublicKey)(pk),
   103  		func(w io.Writer) {
   104  			_, _ = w.Write(msg)
   105  		},
   106  		sig,
   107  	)
   108  }
   109  
   110  // Verify checks whether the given signature by pk on msg is valid.
   111  //
   112  // ctx is the optional context string. Fails if ctx is larger than 255 bytes.
   113  // A nil context string is equivalent to an empty context string.
   114  func Verify(pk *PublicKey, msg, ctx, sig []byte) bool {
   115  	if len(ctx) > 255 {
   116  		return false
   117  	}
   118  	return internal.Verify(
   119  		(*internal.PublicKey)(pk),
   120  		func(w io.Writer) {
   121  			_, _ = w.Write([]byte{0})
   122  			_, _ = w.Write([]byte{byte(len(ctx))})
   123  
   124  			if ctx != nil {
   125  				_, _ = w.Write(ctx)
   126  			}
   127  			_, _ = w.Write(msg)
   128  		},
   129  		sig,
   130  	)
   131  }
   132  
   133  // Sets pk to the public key encoded in buf.
   134  func (pk *PublicKey) Unpack(buf *[PublicKeySize]byte) {
   135  	(*internal.PublicKey)(pk).Unpack(buf)
   136  }
   137  
   138  // Sets sk to the private key encoded in buf.
   139  func (sk *PrivateKey) Unpack(buf *[PrivateKeySize]byte) {
   140  	(*internal.PrivateKey)(sk).Unpack(buf)
   141  }
   142  
   143  // Packs the public key into buf.
   144  func (pk *PublicKey) Pack(buf *[PublicKeySize]byte) {
   145  	(*internal.PublicKey)(pk).Pack(buf)
   146  }
   147  
   148  // Packs the private key into buf.
   149  func (sk *PrivateKey) Pack(buf *[PrivateKeySize]byte) {
   150  	(*internal.PrivateKey)(sk).Pack(buf)
   151  }
   152  
   153  // Packs the public key.
   154  func (pk *PublicKey) Bytes() []byte {
   155  	var buf [PublicKeySize]byte
   156  	pk.Pack(&buf)
   157  	return buf[:]
   158  }
   159  
   160  // Packs the private key.
   161  func (sk *PrivateKey) Bytes() []byte {
   162  	var buf [PrivateKeySize]byte
   163  	sk.Pack(&buf)
   164  	return buf[:]
   165  }
   166  
   167  // Packs the public key.
   168  func (pk *PublicKey) MarshalBinary() ([]byte, error) {
   169  	return pk.Bytes(), nil
   170  }
   171  
   172  // Packs the private key.
   173  func (sk *PrivateKey) MarshalBinary() ([]byte, error) {
   174  	return sk.Bytes(), nil
   175  }
   176  
   177  // Unpacks the public key from data.
   178  func (pk *PublicKey) UnmarshalBinary(data []byte) error {
   179  	if len(data) != PublicKeySize {
   180  		return errors.New("packed public key must be of mldsa87.PublicKeySize bytes")
   181  	}
   182  	var buf [PublicKeySize]byte
   183  	copy(buf[:], data)
   184  	pk.Unpack(&buf)
   185  	return nil
   186  }
   187  
   188  // Unpacks the private key from data.
   189  func (sk *PrivateKey) UnmarshalBinary(data []byte) error {
   190  	if len(data) != PrivateKeySize {
   191  		return errors.New("packed private key must be of mldsa87.PrivateKeySize bytes")
   192  	}
   193  	var buf [PrivateKeySize]byte
   194  	copy(buf[:], data)
   195  	sk.Unpack(&buf)
   196  	return nil
   197  }
   198  
   199  // Sign signs the given message.
   200  //
   201  // opts.HashFunc() must return zero, which can be achieved by passing
   202  // crypto.Hash(0) for opts.  rand is ignored.  Will only return an error
   203  // if opts.HashFunc() is non-zero.
   204  //
   205  // This function is used to make PrivateKey implement the crypto.Signer
   206  // interface.  The package-level SignTo function might be more convenient
   207  // to use.
   208  func (sk *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (
   209  	sig []byte, err error) {
   210  	var ret [SignatureSize]byte
   211  
   212  	if opts.HashFunc() != crypto.Hash(0) {
   213  		return nil, errors.New("dilithium: cannot sign hashed message")
   214  	}
   215  	if err = SignTo(sk, msg, nil, false, ret[:]); err != nil {
   216  		return nil, err
   217  	}
   218  
   219  	return ret[:], nil
   220  }
   221  
   222  // Computes the public key corresponding to this private key.
   223  //
   224  // Returns a *PublicKey.  The type crypto.PublicKey is used to make
   225  // PrivateKey implement the crypto.Signer interface.
   226  func (sk *PrivateKey) Public() crypto.PublicKey {
   227  	return (*PublicKey)((*internal.PrivateKey)(sk).Public())
   228  }
   229  
   230  // Equal returns whether the two private keys equal.
   231  func (sk *PrivateKey) Equal(other crypto.PrivateKey) bool {
   232  	castOther, ok := other.(*PrivateKey)
   233  	if !ok {
   234  		return false
   235  	}
   236  	return (*internal.PrivateKey)(sk).Equal((*internal.PrivateKey)(castOther))
   237  }
   238  
   239  // Equal returns whether the two public keys equal.
   240  func (pk *PublicKey) Equal(other crypto.PublicKey) bool {
   241  	castOther, ok := other.(*PublicKey)
   242  	if !ok {
   243  		return false
   244  	}
   245  	return (*internal.PublicKey)(pk).Equal((*internal.PublicKey)(castOther))
   246  }
   247  
   248  // Boilerplate for generic signatures API
   249  
   250  type scheme struct{}
   251  
   252  var sch sign.Scheme = &scheme{}
   253  
   254  // Scheme returns a generic signature interface for ML-DSA-87.
   255  func Scheme() sign.Scheme { return sch }
   256  
   257  func (*scheme) Name() string        { return "ML-DSA-87" }
   258  func (*scheme) PublicKeySize() int  { return PublicKeySize }
   259  func (*scheme) PrivateKeySize() int { return PrivateKeySize }
   260  func (*scheme) SignatureSize() int  { return SignatureSize }
   261  func (*scheme) SeedSize() int       { return SeedSize }
   262  
   263  // TODO TLSIdentifier() and OID()
   264  
   265  func (*scheme) SupportsContext() bool {
   266  	return true
   267  }
   268  
   269  func (*scheme) GenerateKey() (sign.PublicKey, sign.PrivateKey, error) {
   270  	return GenerateKey(nil)
   271  }
   272  
   273  func (*scheme) Sign(
   274  	sk sign.PrivateKey,
   275  	msg []byte,
   276  	opts *sign.SignatureOpts,
   277  ) []byte {
   278  	var ctx []byte
   279  	sig := make([]byte, SignatureSize)
   280  
   281  	priv, ok := sk.(*PrivateKey)
   282  	if !ok {
   283  		panic(sign.ErrTypeMismatch)
   284  	}
   285  	if opts != nil && opts.Context != "" {
   286  		ctx = []byte(opts.Context)
   287  	}
   288  	err := SignTo(priv, msg, ctx, false, sig)
   289  	if err != nil {
   290  		panic(err)
   291  	}
   292  
   293  	return sig
   294  }
   295  
   296  func (*scheme) Verify(
   297  	pk sign.PublicKey,
   298  	msg, sig []byte,
   299  	opts *sign.SignatureOpts,
   300  ) bool {
   301  	var ctx []byte
   302  	pub, ok := pk.(*PublicKey)
   303  	if !ok {
   304  		panic(sign.ErrTypeMismatch)
   305  	}
   306  	if opts != nil && opts.Context != "" {
   307  		ctx = []byte(opts.Context)
   308  	}
   309  	return Verify(pub, msg, ctx, sig)
   310  }
   311  
   312  func (*scheme) DeriveKey(seed []byte) (sign.PublicKey, sign.PrivateKey) {
   313  	if len(seed) != SeedSize {
   314  		panic(sign.ErrSeedSize)
   315  	}
   316  	var seed2 [SeedSize]byte
   317  	copy(seed2[:], seed)
   318  	return NewKeyFromSeed(&seed2)
   319  }
   320  
   321  func (*scheme) UnmarshalBinaryPublicKey(buf []byte) (sign.PublicKey, error) {
   322  	if len(buf) != PublicKeySize {
   323  		return nil, sign.ErrPubKeySize
   324  	}
   325  
   326  	var (
   327  		buf2 [PublicKeySize]byte
   328  		ret  PublicKey
   329  	)
   330  
   331  	copy(buf2[:], buf)
   332  	ret.Unpack(&buf2)
   333  	return &ret, nil
   334  }
   335  
   336  func (*scheme) UnmarshalBinaryPrivateKey(buf []byte) (sign.PrivateKey, error) {
   337  	if len(buf) != PrivateKeySize {
   338  		return nil, sign.ErrPrivKeySize
   339  	}
   340  
   341  	var (
   342  		buf2 [PrivateKeySize]byte
   343  		ret  PrivateKey
   344  	)
   345  
   346  	copy(buf2[:], buf)
   347  	ret.Unpack(&buf2)
   348  	return &ret, nil
   349  }
   350  
   351  func (sk *PrivateKey) Scheme() sign.Scheme {
   352  	return sch
   353  }
   354  
   355  func (sk *PublicKey) Scheme() sign.Scheme {
   356  	return sch
   357  }