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 valid, Decapsulate returns an error.
    76  //
    77  // The shared key must be kept secret.
    78  func (dk *DecapsulationKey768) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) {
    79  	return dk.key.Decapsulate(ciphertext)
    80  }
    81  
    82  // EncapsulationKey returns the public encapsulation key necessary to produce
    83  // ciphertexts.
    84  func (dk *DecapsulationKey768) EncapsulationKey() *EncapsulationKey768 {
    85  	return &EncapsulationKey768{dk.key.EncapsulationKey()}
    86  }
    87  
    88  // Encapsulator returns the encapsulation key, like
    89  // [DecapsulationKey768.EncapsulationKey].
    90  //
    91  // It implements [crypto.Decapsulator].
    92  func (dk *DecapsulationKey768) Encapsulator() crypto.Encapsulator {
    93  	return dk.EncapsulationKey()
    94  }
    95  
    96  var _ crypto.Decapsulator = (*DecapsulationKey768)(nil)
    97  
    98  // An EncapsulationKey768 is the public key used to produce ciphertexts to be
    99  // decapsulated by the corresponding DecapsulationKey768.
   100  type EncapsulationKey768 struct {
   101  	key *mlkem.EncapsulationKey768
   102  }
   103  
   104  // NewEncapsulationKey768 parses an encapsulation key from its encoded form. If
   105  // the encapsulation key is not valid, NewEncapsulationKey768 returns an error.
   106  func NewEncapsulationKey768(encapsulationKey []byte) (*EncapsulationKey768, error) {
   107  	key, err := mlkem.NewEncapsulationKey768(encapsulationKey)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  
   112  	return &EncapsulationKey768{key}, nil
   113  }
   114  
   115  // Bytes returns the encapsulation key as a byte slice.
   116  func (ek *EncapsulationKey768) Bytes() []byte {
   117  	return ek.key.Bytes()
   118  }
   119  
   120  // Encapsulate generates a shared key and an associated ciphertext from an
   121  // encapsulation key, drawing random bytes from a secure source.
   122  //
   123  // The shared key must be kept secret.
   124  //
   125  // For testing, derandomized encapsulation is provided by the
   126  // [crypto/mlkem/mlkemtest] package.
   127  func (ek *EncapsulationKey768) Encapsulate() (sharedKey, ciphertext []byte) {
   128  	return ek.key.Encapsulate()
   129  }
   130  
   131  // DecapsulationKey1024 is the secret key used to decapsulate a shared key
   132  // from a ciphertext. It includes various precomputed values.
   133  type DecapsulationKey1024 struct {
   134  	key *mlkem.DecapsulationKey1024
   135  }
   136  
   137  // GenerateKey1024 generates a new decapsulation key, drawing random bytes from
   138  // a secure source. The decapsulation key must be kept secret.
   139  func GenerateKey1024() (*DecapsulationKey1024, error) {
   140  	key, err := mlkem.GenerateKey1024()
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  
   145  	return &DecapsulationKey1024{key}, nil
   146  }
   147  
   148  // NewDecapsulationKey1024 expands a decapsulation key from a 64-byte seed in the
   149  // "d || z" form. The seed must be uniformly random.
   150  func NewDecapsulationKey1024(seed []byte) (*DecapsulationKey1024, error) {
   151  	key, err := mlkem.NewDecapsulationKey1024(seed)
   152  	if err != nil {
   153  		return nil, err
   154  	}
   155  
   156  	return &DecapsulationKey1024{key}, nil
   157  }
   158  
   159  // Bytes returns the decapsulation key as a 64-byte seed in the "d || z" form.
   160  //
   161  // The decapsulation key must be kept secret.
   162  func (dk *DecapsulationKey1024) Bytes() []byte {
   163  	return dk.key.Bytes()
   164  }
   165  
   166  // Decapsulate generates a shared key from a ciphertext and a decapsulation
   167  // key. If the ciphertext is not valid, Decapsulate returns an error.
   168  //
   169  // The shared key must be kept secret.
   170  func (dk *DecapsulationKey1024) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) {
   171  	return dk.key.Decapsulate(ciphertext)
   172  }
   173  
   174  // EncapsulationKey returns the public encapsulation key necessary to produce
   175  // ciphertexts.
   176  func (dk *DecapsulationKey1024) EncapsulationKey() *EncapsulationKey1024 {
   177  	return &EncapsulationKey1024{dk.key.EncapsulationKey()}
   178  }
   179  
   180  // Encapsulator returns the encapsulation key, like
   181  // [DecapsulationKey1024.EncapsulationKey].
   182  //
   183  // It implements [crypto.Decapsulator].
   184  func (dk *DecapsulationKey1024) Encapsulator() crypto.Encapsulator {
   185  	return dk.EncapsulationKey()
   186  }
   187  
   188  var _ crypto.Decapsulator = (*DecapsulationKey1024)(nil)
   189  
   190  // An EncapsulationKey1024 is the public key used to produce ciphertexts to be
   191  // decapsulated by the corresponding DecapsulationKey1024.
   192  type EncapsulationKey1024 struct {
   193  	key *mlkem.EncapsulationKey1024
   194  }
   195  
   196  // NewEncapsulationKey1024 parses an encapsulation key from its encoded form. If
   197  // the encapsulation key is not valid, NewEncapsulationKey1024 returns an error.
   198  func NewEncapsulationKey1024(encapsulationKey []byte) (*EncapsulationKey1024, error) {
   199  	key, err := mlkem.NewEncapsulationKey1024(encapsulationKey)
   200  	if err != nil {
   201  		return nil, err
   202  	}
   203  
   204  	return &EncapsulationKey1024{key}, nil
   205  }
   206  
   207  // Bytes returns the encapsulation key as a byte slice.
   208  func (ek *EncapsulationKey1024) Bytes() []byte {
   209  	return ek.key.Bytes()
   210  }
   211  
   212  // Encapsulate generates a shared key and an associated ciphertext from an
   213  // encapsulation key, drawing random bytes from a secure source.
   214  //
   215  // The shared key must be kept secret.
   216  //
   217  // For testing, derandomized encapsulation is provided by the
   218  // [crypto/mlkem/mlkemtest] package.
   219  func (ek *EncapsulationKey1024) Encapsulate() (sharedKey, ciphertext []byte) {
   220  	return ek.key.Encapsulate()
   221  }
   222  

View as plain text