Source file src/crypto/mlkem/mlkem.go

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package mlkem implements the quantum-resistant key encapsulation method
     6  // ML-KEM (formerly known as Kyber), as specified in [NIST FIPS 203].
     7  //
     8  // Most applications should use the ML-KEM-768 parameter set, as implemented by
     9  // [DecapsulationKey768] and [EncapsulationKey768].
    10  //
    11  // [NIST FIPS 203]: https://doi.org/10.6028/NIST.FIPS.203
    12  package mlkem
    13  
    14  import (
    15  	"crypto"
    16  	"crypto/internal/fips140/mlkem"
    17  )
    18  
    19  const (
    20  	// SharedKeySize is the size of a shared key produced by ML-KEM.
    21  	SharedKeySize = 32
    22  
    23  	// SeedSize is the size of a seed used to generate a decapsulation key.
    24  	SeedSize = 64
    25  
    26  	// CiphertextSize768 is the size of a ciphertext produced by ML-KEM-768.
    27  	CiphertextSize768 = 1088
    28  
    29  	// EncapsulationKeySize768 is the size of an ML-KEM-768 encapsulation key.
    30  	EncapsulationKeySize768 = 1184
    31  
    32  	// CiphertextSize1024 is the size of a ciphertext produced by ML-KEM-1024.
    33  	CiphertextSize1024 = 1568
    34  
    35  	// EncapsulationKeySize1024 is the size of an ML-KEM-1024 encapsulation key.
    36  	EncapsulationKeySize1024 = 1568
    37  )
    38  
    39  // DecapsulationKey768 is the secret key used to decapsulate a shared key
    40  // from a ciphertext. It includes various precomputed values.
    41  type DecapsulationKey768 struct {
    42  	key *mlkem.DecapsulationKey768
    43  }
    44  
    45  // GenerateKey768 generates a new decapsulation key, drawing random bytes from
    46  // a secure source. The decapsulation key must be kept secret.
    47  func GenerateKey768() (*DecapsulationKey768, error) {
    48  	key, err := mlkem.GenerateKey768()
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	return &DecapsulationKey768{key}, nil
    54  }
    55  
    56  // NewDecapsulationKey768 expands a decapsulation key from a 64-byte seed in the
    57  // "d || z" form. The seed must be uniformly random.
    58  func NewDecapsulationKey768(seed []byte) (*DecapsulationKey768, error) {
    59  	key, err := mlkem.NewDecapsulationKey768(seed)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	return &DecapsulationKey768{key}, nil
    65  }
    66  
    67  // Bytes returns the decapsulation key as a 64-byte seed in the "d || z" form.
    68  //
    69  // The decapsulation key must be kept secret.
    70  func (dk *DecapsulationKey768) Bytes() []byte {
    71  	return dk.key.Bytes()
    72  }
    73  
    74  // Decapsulate generates a shared key from a ciphertext and a decapsulation
    75  // key. If the ciphertext is not the correct length, Decapsulate returns an
    76  // error. A ciphertext that is the correct length but otherwise invalid will
    77  // not return an error; instead, it will produce a shared key that does not
    78  // match the sender's, according to FIPS 203.
    79  //
    80  // The shared key must be kept secret.
    81  func (dk *DecapsulationKey768) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) {
    82  	return dk.key.Decapsulate(ciphertext)
    83  }
    84  
    85  // EncapsulationKey returns the public encapsulation key necessary to produce
    86  // ciphertexts.
    87  func (dk *DecapsulationKey768) EncapsulationKey() *EncapsulationKey768 {
    88  	return &EncapsulationKey768{dk.key.EncapsulationKey()}
    89  }
    90  
    91  // Encapsulator returns the encapsulation key, like
    92  // [DecapsulationKey768.EncapsulationKey].
    93  //
    94  // It implements [crypto.Decapsulator].
    95  func (dk *DecapsulationKey768) Encapsulator() crypto.Encapsulator {
    96  	return dk.EncapsulationKey()
    97  }
    98  
    99  var _ crypto.Decapsulator = (*DecapsulationKey768)(nil)
   100  
   101  // An EncapsulationKey768 is the public key used to produce ciphertexts to be
   102  // decapsulated by the corresponding DecapsulationKey768.
   103  type EncapsulationKey768 struct {
   104  	key *mlkem.EncapsulationKey768
   105  }
   106  
   107  // NewEncapsulationKey768 parses an encapsulation key from its encoded form. If
   108  // the encapsulation key is not valid, NewEncapsulationKey768 returns an error.
   109  func NewEncapsulationKey768(encapsulationKey []byte) (*EncapsulationKey768, error) {
   110  	key, err := mlkem.NewEncapsulationKey768(encapsulationKey)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	return &EncapsulationKey768{key}, nil
   116  }
   117  
   118  // Bytes returns the encapsulation key as a byte slice.
   119  func (ek *EncapsulationKey768) Bytes() []byte {
   120  	return ek.key.Bytes()
   121  }
   122  
   123  // Encapsulate generates a shared key and an associated ciphertext from an
   124  // encapsulation key, drawing random bytes from a secure source.
   125  //
   126  // The shared key must be kept secret.
   127  //
   128  // For testing, derandomized encapsulation is provided by the
   129  // [crypto/mlkem/mlkemtest] package.
   130  func (ek *EncapsulationKey768) Encapsulate() (sharedKey, ciphertext []byte) {
   131  	return ek.key.Encapsulate()
   132  }
   133  
   134  // DecapsulationKey1024 is the secret key used to decapsulate a shared key
   135  // from a ciphertext. It includes various precomputed values.
   136  type DecapsulationKey1024 struct {
   137  	key *mlkem.DecapsulationKey1024
   138  }
   139  
   140  // GenerateKey1024 generates a new decapsulation key, drawing random bytes from
   141  // a secure source. The decapsulation key must be kept secret.
   142  func GenerateKey1024() (*DecapsulationKey1024, error) {
   143  	key, err := mlkem.GenerateKey1024()
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	return &DecapsulationKey1024{key}, nil
   149  }
   150  
   151  // NewDecapsulationKey1024 expands a decapsulation key from a 64-byte seed in the
   152  // "d || z" form. The seed must be uniformly random.
   153  func NewDecapsulationKey1024(seed []byte) (*DecapsulationKey1024, error) {
   154  	key, err := mlkem.NewDecapsulationKey1024(seed)
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  
   159  	return &DecapsulationKey1024{key}, nil
   160  }
   161  
   162  // Bytes returns the decapsulation key as a 64-byte seed in the "d || z" form.
   163  //
   164  // The decapsulation key must be kept secret.
   165  func (dk *DecapsulationKey1024) Bytes() []byte {
   166  	return dk.key.Bytes()
   167  }
   168  
   169  // Decapsulate generates a shared key from a ciphertext and a decapsulation
   170  // key. If the ciphertext is not the correct length, Decapsulate returns an
   171  // error. A ciphertext that is the correct length but otherwise invalid will
   172  // not return an error; instead, it will produce a shared key that does not
   173  // match the sender's, according to FIPS 203.
   174  //
   175  // The shared key must be kept secret.
   176  func (dk *DecapsulationKey1024) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) {
   177  	return dk.key.Decapsulate(ciphertext)
   178  }
   179  
   180  // EncapsulationKey returns the public encapsulation key necessary to produce
   181  // ciphertexts.
   182  func (dk *DecapsulationKey1024) EncapsulationKey() *EncapsulationKey1024 {
   183  	return &EncapsulationKey1024{dk.key.EncapsulationKey()}
   184  }
   185  
   186  // Encapsulator returns the encapsulation key, like
   187  // [DecapsulationKey1024.EncapsulationKey].
   188  //
   189  // It implements [crypto.Decapsulator].
   190  func (dk *DecapsulationKey1024) Encapsulator() crypto.Encapsulator {
   191  	return dk.EncapsulationKey()
   192  }
   193  
   194  var _ crypto.Decapsulator = (*DecapsulationKey1024)(nil)
   195  
   196  // An EncapsulationKey1024 is the public key used to produce ciphertexts to be
   197  // decapsulated by the corresponding DecapsulationKey1024.
   198  type EncapsulationKey1024 struct {
   199  	key *mlkem.EncapsulationKey1024
   200  }
   201  
   202  // NewEncapsulationKey1024 parses an encapsulation key from its encoded form. If
   203  // the encapsulation key is not valid, NewEncapsulationKey1024 returns an error.
   204  func NewEncapsulationKey1024(encapsulationKey []byte) (*EncapsulationKey1024, error) {
   205  	key, err := mlkem.NewEncapsulationKey1024(encapsulationKey)
   206  	if err != nil {
   207  		return nil, err
   208  	}
   209  
   210  	return &EncapsulationKey1024{key}, nil
   211  }
   212  
   213  // Bytes returns the encapsulation key as a byte slice.
   214  func (ek *EncapsulationKey1024) Bytes() []byte {
   215  	return ek.key.Bytes()
   216  }
   217  
   218  // Encapsulate generates a shared key and an associated ciphertext from an
   219  // encapsulation key, drawing random bytes from a secure source.
   220  //
   221  // The shared key must be kept secret.
   222  //
   223  // For testing, derandomized encapsulation is provided by the
   224  // [crypto/mlkem/mlkemtest] package.
   225  func (ek *EncapsulationKey1024) Encapsulate() (sharedKey, ciphertext []byte) {
   226  	return ek.key.Encapsulate()
   227  }
   228  

View as plain text