-
Notifications
You must be signed in to change notification settings - Fork 17.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit exposes the crypto/internal/mlkem package as a public crypto package based on the linked proposal. Since we've already implemented this internal to the FIPS boundary this largely defers to that implementation. Updates #70122 Change-Id: I5ec9c2783c4d44583244c6d16597704a51e9b738 Reviewed-on: https://go-review.googlesource.com/c/go/+/630240 Reviewed-by: Filippo Valsorda <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]> Auto-Submit: Filippo Valsorda <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
- Loading branch information
Showing
7 changed files
with
272 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
pkg crypto/mlkem, const CiphertextSize1024 = 1568 #70122 | ||
pkg crypto/mlkem, const CiphertextSize1024 ideal-int #70122 | ||
pkg crypto/mlkem, const CiphertextSize768 = 1088 #70122 | ||
pkg crypto/mlkem, const CiphertextSize768 ideal-int #70122 | ||
pkg crypto/mlkem, const EncapsulationKeySize1024 = 1568 #70122 | ||
pkg crypto/mlkem, const EncapsulationKeySize1024 ideal-int #70122 | ||
pkg crypto/mlkem, const EncapsulationKeySize768 = 1184 #70122 | ||
pkg crypto/mlkem, const EncapsulationKeySize768 ideal-int #70122 | ||
pkg crypto/mlkem, const SeedSize = 64 #70122 | ||
pkg crypto/mlkem, const SeedSize ideal-int #70122 | ||
pkg crypto/mlkem, const SharedKeySize = 32 #70122 | ||
pkg crypto/mlkem, const SharedKeySize ideal-int #70122 | ||
pkg crypto/mlkem, func GenerateKey1024() (*DecapsulationKey1024, error) #70122 | ||
pkg crypto/mlkem, func GenerateKey768() (*DecapsulationKey768, error) #70122 | ||
pkg crypto/mlkem, func NewDecapsulationKey1024([]uint8) (*DecapsulationKey1024, error) #70122 | ||
pkg crypto/mlkem, func NewDecapsulationKey768([]uint8) (*DecapsulationKey768, error) #70122 | ||
pkg crypto/mlkem, func NewEncapsulationKey1024([]uint8) (*EncapsulationKey1024, error) #70122 | ||
pkg crypto/mlkem, func NewEncapsulationKey768([]uint8) (*EncapsulationKey768, error) #70122 | ||
pkg crypto/mlkem, method (*DecapsulationKey1024) Bytes() []uint8 #70122 | ||
pkg crypto/mlkem, method (*DecapsulationKey1024) Decapsulate([]uint8) ([]uint8, error) #70122 | ||
pkg crypto/mlkem, method (*DecapsulationKey1024) EncapsulationKey() *EncapsulationKey1024 #70122 | ||
pkg crypto/mlkem, method (*DecapsulationKey768) Bytes() []uint8 #70122 | ||
pkg crypto/mlkem, method (*DecapsulationKey768) Decapsulate([]uint8) ([]uint8, error) #70122 | ||
pkg crypto/mlkem, method (*DecapsulationKey768) EncapsulationKey() *EncapsulationKey768 #70122 | ||
pkg crypto/mlkem, method (*EncapsulationKey1024) Bytes() []uint8 #70122 | ||
pkg crypto/mlkem, method (*EncapsulationKey1024) Encapsulate() ([]uint8, []uint8) #70122 | ||
pkg crypto/mlkem, method (*EncapsulationKey768) Bytes() []uint8 #70122 | ||
pkg crypto/mlkem, method (*EncapsulationKey768) Encapsulate() ([]uint8, []uint8) #70122 | ||
pkg crypto/mlkem, type DecapsulationKey1024 struct #70122 | ||
pkg crypto/mlkem, type DecapsulationKey768 struct #70122 | ||
pkg crypto/mlkem, type EncapsulationKey1024 struct #70122 | ||
pkg crypto/mlkem, type EncapsulationKey768 struct #70122 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
A new `crypto/mlkem` package was added, implementing ML-KEM (formerly known as | ||
Kyber), as specified in [NIST FIPS 203](https://doi.org/10.6028/NIST.FIPS.203). | ||
<!-- go.dev/issue/70122 --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<!-- This is a new package; covered in 6-stdlib/4-mlkem.md. --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright 2023 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package mlkem | ||
|
||
import "crypto/internal/fips140/mlkem" | ||
|
||
const ( | ||
// CiphertextSize1024 is the size of a ciphertext produced by the 1024-bit | ||
// variant of ML-KEM. | ||
CiphertextSize1024 = 1568 | ||
|
||
// EncapsulationKeySize1024 is the size of an encapsulation key for the | ||
// 1024-bit variant of ML-KEM. | ||
EncapsulationKeySize1024 = 1568 | ||
) | ||
|
||
// DecapsulationKey1024 is the secret key used to decapsulate a shared key | ||
// from a ciphertext. It includes various precomputed values. | ||
type DecapsulationKey1024 struct { | ||
key *mlkem.DecapsulationKey1024 | ||
} | ||
|
||
// GenerateKey1024 generates a new decapsulation key, drawing random bytes from | ||
// crypto/rand. The decapsulation key must be kept secret. | ||
func GenerateKey1024() (*DecapsulationKey1024, error) { | ||
key, err := mlkem.GenerateKey1024() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &DecapsulationKey1024{key}, nil | ||
} | ||
|
||
// NewDecapsulationKey1024 parses a decapsulation key from a 64-byte seed in the | ||
// "d || z" form. The seed must be uniformly random. | ||
func NewDecapsulationKey1024(seed []byte) (*DecapsulationKey1024, error) { | ||
key, err := mlkem.NewDecapsulationKey1024(seed) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &DecapsulationKey1024{key}, nil | ||
} | ||
|
||
// Bytes returns the decapsulation key as a 64-byte seed in the "d || z" form. | ||
// | ||
// The decapsulation key must be kept secret. | ||
func (dk *DecapsulationKey1024) Bytes() []byte { | ||
return dk.key.Bytes() | ||
} | ||
|
||
// Decapsulate generates a shared key from a ciphertext and a decapsulation | ||
// key. If the ciphertext is not valid, Decapsulate returns an error. | ||
// | ||
// The shared key must be kept secret. | ||
func (dk *DecapsulationKey1024) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) { | ||
return dk.key.Decapsulate(ciphertext) | ||
} | ||
|
||
// EncapsulationKey returns the public encapsulation key necessary to produce | ||
// ciphertexts. | ||
func (dk *DecapsulationKey1024) EncapsulationKey() *EncapsulationKey1024 { | ||
return &EncapsulationKey1024{dk.key.EncapsulationKey()} | ||
} | ||
|
||
// An EncapsulationKey1024 is the public key used to produce ciphertexts to be | ||
// decapsulated by the corresponding DecapsulationKey1024. | ||
type EncapsulationKey1024 struct { | ||
key *mlkem.EncapsulationKey1024 | ||
} | ||
|
||
// NewEncapsulationKey1024 parses an encapsulation key from its encoded form. If | ||
// the encapsulation key is not valid, NewEncapsulationKey1024 returns an error. | ||
func NewEncapsulationKey1024(encapsulationKey []byte) (*EncapsulationKey1024, error) { | ||
key, err := mlkem.NewEncapsulationKey1024(encapsulationKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &EncapsulationKey1024{key}, nil | ||
} | ||
|
||
// Bytes returns the encapsulation key as a byte slice. | ||
func (ek *EncapsulationKey1024) Bytes() []byte { | ||
return ek.key.Bytes() | ||
} | ||
|
||
// Encapsulate generates a shared key and an associated ciphertext from an | ||
// encapsulation key, drawing random bytes from crypto/rand. | ||
// | ||
// The shared key must be kept secret. | ||
func (ek *EncapsulationKey1024) Encapsulate() (ciphertext, sharedKey []byte) { | ||
return ek.key.Encapsulate() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// Copyright 2023 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package mlkem implements the quantum-resistant key encapsulation method | ||
// ML-KEM (formerly known as Kyber), as specified in [NIST FIPS 203]. | ||
// | ||
// [NIST FIPS 203]: https://doi.org/10.6028/NIST.FIPS.203 | ||
package mlkem | ||
|
||
import "crypto/internal/fips140/mlkem" | ||
|
||
const ( | ||
// SharedKeySize is the size of a shared key produced by ML-KEM. | ||
SharedKeySize = 32 | ||
|
||
// SeedSize is the size of a seed used to generate a decapsulation key. | ||
SeedSize = 64 | ||
|
||
// CiphertextSize768 is the size of a ciphertext produced by the 768-bit | ||
// variant of ML-KEM. | ||
CiphertextSize768 = 1088 | ||
|
||
// EncapsulationKeySize768 is the size of an encapsulation key for the | ||
// 768-bit variant of ML-KEM. | ||
EncapsulationKeySize768 = 1184 | ||
) | ||
|
||
// DecapsulationKey768 is the secret key used to decapsulate a shared key | ||
// from a ciphertext. It includes various precomputed values. | ||
type DecapsulationKey768 struct { | ||
key *mlkem.DecapsulationKey768 | ||
} | ||
|
||
// GenerateKey768 generates a new decapsulation key, drawing random bytes from | ||
// crypto/rand. The decapsulation key must be kept secret. | ||
func GenerateKey768() (*DecapsulationKey768, error) { | ||
key, err := mlkem.GenerateKey768() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &DecapsulationKey768{key}, nil | ||
} | ||
|
||
// NewDecapsulationKey768 parses a decapsulation key from a 64-byte seed in the | ||
// "d || z" form. The seed must be uniformly random. | ||
func NewDecapsulationKey768(seed []byte) (*DecapsulationKey768, error) { | ||
key, err := mlkem.NewDecapsulationKey768(seed) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &DecapsulationKey768{key}, nil | ||
} | ||
|
||
// Bytes returns the decapsulation key as a 64-byte seed in the "d || z" form. | ||
// | ||
// The decapsulation key must be kept secret. | ||
func (dk *DecapsulationKey768) Bytes() []byte { | ||
return dk.key.Bytes() | ||
} | ||
|
||
// Decapsulate generates a shared key from a ciphertext and a decapsulation | ||
// key. If the ciphertext is not valid, Decapsulate returns an error. | ||
// | ||
// The shared key must be kept secret. | ||
func (dk *DecapsulationKey768) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) { | ||
return dk.key.Decapsulate(ciphertext) | ||
} | ||
|
||
// EncapsulationKey returns the public encapsulation key necessary to produce | ||
// ciphertexts. | ||
func (dk *DecapsulationKey768) EncapsulationKey() *EncapsulationKey768 { | ||
return &EncapsulationKey768{dk.key.EncapsulationKey()} | ||
} | ||
|
||
// An EncapsulationKey768 is the public key used to produce ciphertexts to be | ||
// decapsulated by the corresponding DecapsulationKey768. | ||
type EncapsulationKey768 struct { | ||
key *mlkem.EncapsulationKey768 | ||
} | ||
|
||
// NewEncapsulationKey768 parses an encapsulation key from its encoded form. If | ||
// the encapsulation key is not valid, NewEncapsulationKey768 returns an error. | ||
func NewEncapsulationKey768(encapsulationKey []byte) (*EncapsulationKey768, error) { | ||
key, err := mlkem.NewEncapsulationKey768(encapsulationKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &EncapsulationKey768{key}, nil | ||
} | ||
|
||
// Bytes returns the encapsulation key as a byte slice. | ||
func (ek *EncapsulationKey768) Bytes() []byte { | ||
return ek.key.Bytes() | ||
} | ||
|
||
// Encapsulate generates a shared key and an associated ciphertext from an | ||
// encapsulation key, drawing random bytes from crypto/rand. | ||
// | ||
// The shared key must be kept secret. | ||
func (ek *EncapsulationKey768) Encapsulate() (ciphertext, sharedKey []byte) { | ||
return ek.key.Encapsulate() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters