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

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