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