|
| 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 | +// [NIST FIPS 203]: https://doi.org/10.6028/NIST.FIPS.203 |
| 9 | +package mlkem |
| 10 | + |
| 11 | +import "crypto/internal/fips140/mlkem" |
| 12 | + |
| 13 | +const ( |
| 14 | + // SharedKeySize is the size of a shared key produced by ML-KEM. |
| 15 | + SharedKeySize = 32 |
| 16 | + |
| 17 | + // SeedSize is the size of a seed used to generate a decapsulation key. |
| 18 | + SeedSize = 64 |
| 19 | + |
| 20 | + // CiphertextSize768 is the size of a ciphertext produced by the 768-bit |
| 21 | + // variant of ML-KEM. |
| 22 | + CiphertextSize768 = 1088 |
| 23 | + |
| 24 | + // EncapsulationKeySize768 is the size of an encapsulation key for the |
| 25 | + // 768-bit variant of ML-KEM. |
| 26 | + EncapsulationKeySize768 = 1184 |
| 27 | +) |
| 28 | + |
| 29 | +// DecapsulationKey768 is the secret key used to decapsulate a shared key |
| 30 | +// from a ciphertext. It includes various precomputed values. |
| 31 | +type DecapsulationKey768 struct { |
| 32 | + key *mlkem.DecapsulationKey768 |
| 33 | +} |
| 34 | + |
| 35 | +// GenerateKey768 generates a new decapsulation key, drawing random bytes from |
| 36 | +// crypto/rand. The decapsulation key must be kept secret. |
| 37 | +func GenerateKey768() (*DecapsulationKey768, error) { |
| 38 | + key, err := mlkem.GenerateKey768() |
| 39 | + if err != nil { |
| 40 | + return nil, err |
| 41 | + } |
| 42 | + |
| 43 | + return &DecapsulationKey768{key}, nil |
| 44 | +} |
| 45 | + |
| 46 | +// NewDecapsulationKey768 parses a decapsulation key from a 64-byte seed in the |
| 47 | +// "d || z" form. The seed must be uniformly random. |
| 48 | +func NewDecapsulationKey768(seed []byte) (*DecapsulationKey768, error) { |
| 49 | + key, err := mlkem.NewDecapsulationKey768(seed) |
| 50 | + if err != nil { |
| 51 | + return nil, err |
| 52 | + } |
| 53 | + |
| 54 | + return &DecapsulationKey768{key}, nil |
| 55 | +} |
| 56 | + |
| 57 | +// Bytes returns the decapsulation key as a 64-byte seed in the "d || z" form. |
| 58 | +// |
| 59 | +// The decapsulation key must be kept secret. |
| 60 | +func (dk *DecapsulationKey768) Bytes() []byte { |
| 61 | + return dk.key.Bytes() |
| 62 | +} |
| 63 | + |
| 64 | +// Decapsulate generates a shared key from a ciphertext and a decapsulation |
| 65 | +// key. If the ciphertext is not valid, Decapsulate returns an error. |
| 66 | +// |
| 67 | +// The shared key must be kept secret. |
| 68 | +func (dk *DecapsulationKey768) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) { |
| 69 | + return dk.key.Decapsulate(ciphertext) |
| 70 | +} |
| 71 | + |
| 72 | +// EncapsulationKey returns the public encapsulation key necessary to produce |
| 73 | +// ciphertexts. |
| 74 | +func (dk *DecapsulationKey768) EncapsulationKey() *EncapsulationKey768 { |
| 75 | + return &EncapsulationKey768{dk.key.EncapsulationKey()} |
| 76 | +} |
| 77 | + |
| 78 | +// An EncapsulationKey768 is the public key used to produce ciphertexts to be |
| 79 | +// decapsulated by the corresponding DecapsulationKey768. |
| 80 | +type EncapsulationKey768 struct { |
| 81 | + key *mlkem.EncapsulationKey768 |
| 82 | +} |
| 83 | + |
| 84 | +// NewEncapsulationKey768 parses an encapsulation key from its encoded form. If |
| 85 | +// the encapsulation key is not valid, NewEncapsulationKey768 returns an error. |
| 86 | +func NewEncapsulationKey768(encapsulationKey []byte) (*EncapsulationKey768, error) { |
| 87 | + key, err := mlkem.NewEncapsulationKey768(encapsulationKey) |
| 88 | + if err != nil { |
| 89 | + return nil, err |
| 90 | + } |
| 91 | + |
| 92 | + return &EncapsulationKey768{key}, nil |
| 93 | +} |
| 94 | + |
| 95 | +// Bytes returns the encapsulation key as a byte slice. |
| 96 | +func (ek *EncapsulationKey768) Bytes() []byte { |
| 97 | + return ek.key.Bytes() |
| 98 | +} |
| 99 | + |
| 100 | +// Encapsulate generates a shared key and an associated ciphertext from an |
| 101 | +// encapsulation key, drawing random bytes from crypto/rand. |
| 102 | +// |
| 103 | +// The shared key must be kept secret. |
| 104 | +func (ek *EncapsulationKey768) Encapsulate() (ciphertext, sharedKey []byte) { |
| 105 | + return ek.key.Encapsulate() |
| 106 | +} |
0 commit comments