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