Skip to content

Commit db4fade

Browse files
FiloSottilegopherbot
authored andcommitted
crypto/internal/fips140/mlkem: make CAST conditional
It taks north of 130µs on my machine, which is enough to be worth shaving off at init time. Change-Id: I6a6a696463de228bc3e7b9ca10c12ddbaabdf384 Reviewed-on: https://go-review.googlesource.com/c/go/+/707695 Auto-Submit: Filippo Valsorda <[email protected]> Reviewed-by: Daniel McCarney <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Carlos Amedee <[email protected]>
1 parent db3cb3f commit db4fade

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

src/crypto/internal/fips140/mlkem/cast.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import (
99
"crypto/internal/fips140"
1010
_ "crypto/internal/fips140/check"
1111
"errors"
12+
"sync"
1213
)
1314

14-
func init() {
15+
var fipsSelfTest = sync.OnceFunc(func() {
1516
fips140.CAST("ML-KEM-768", func() error {
1617
var d = &[32]byte{
1718
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
@@ -40,14 +41,12 @@ func init() {
4041
dk := &DecapsulationKey768{}
4142
kemKeyGen(dk, d, z)
4243
ek := dk.EncapsulationKey()
43-
Ke, c := ek.EncapsulateInternal(m)
44-
Kd, err := dk.Decapsulate(c)
45-
if err != nil {
46-
return err
47-
}
44+
var cc [CiphertextSize768]byte
45+
Ke, _ := kemEncaps(&cc, ek, m)
46+
Kd := kemDecaps(dk, &cc)
4847
if !bytes.Equal(Ke, K) || !bytes.Equal(Kd, K) {
4948
return errors.New("unexpected result")
5049
}
5150
return nil
5251
})
53-
}
52+
})

src/crypto/internal/fips140/mlkem/mlkem1024.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/crypto/internal/fips140/mlkem/mlkem768.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ func GenerateKey768() (*DecapsulationKey768, error) {
172172
}
173173

174174
func generateKey(dk *DecapsulationKey768) (*DecapsulationKey768, error) {
175+
fipsSelfTest()
175176
var d [32]byte
176177
drbg.Read(d[:])
177178
var z [32]byte
@@ -185,6 +186,7 @@ func generateKey(dk *DecapsulationKey768) (*DecapsulationKey768, error) {
185186
// GenerateKeyInternal768 is a derandomized version of GenerateKey768,
186187
// exclusively for use in tests.
187188
func GenerateKeyInternal768(d, z *[32]byte) *DecapsulationKey768 {
189+
fipsSelfTest()
188190
dk := &DecapsulationKey768{}
189191
kemKeyGen(dk, d, z)
190192
return dk
@@ -337,6 +339,7 @@ func (ek *EncapsulationKey768) Encapsulate() (sharedKey, ciphertext []byte) {
337339
}
338340

339341
func (ek *EncapsulationKey768) encapsulate(cc *[CiphertextSize768]byte) (sharedKey, ciphertext []byte) {
342+
fipsSelfTest()
340343
var m [messageSize]byte
341344
drbg.Read(m[:])
342345
// Note that the modulus check (step 2 of the encapsulation key check from
@@ -348,6 +351,7 @@ func (ek *EncapsulationKey768) encapsulate(cc *[CiphertextSize768]byte) (sharedK
348351
// EncapsulateInternal is a derandomized version of Encapsulate, exclusively for
349352
// use in tests.
350353
func (ek *EncapsulationKey768) EncapsulateInternal(m *[32]byte) (sharedKey, ciphertext []byte) {
354+
fipsSelfTest()
351355
cc := &[CiphertextSize768]byte{}
352356
return kemEncaps(cc, ek, m)
353357
}
@@ -453,6 +457,7 @@ func pkeEncrypt(cc *[CiphertextSize768]byte, ex *encryptionKey, m *[messageSize]
453457
//
454458
// The shared key must be kept secret.
455459
func (dk *DecapsulationKey768) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) {
460+
fipsSelfTest()
456461
if len(ciphertext) != CiphertextSize768 {
457462
return nil, errors.New("mlkem: invalid ciphertext length")
458463
}

src/crypto/internal/fips140test/cast_test.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ var allCASTs = []string{
4848
"HKDF-SHA2-256",
4949
"HMAC-SHA2-256",
5050
"KAS-ECC-SSC P-256",
51-
"ML-KEM PCT",
52-
"ML-KEM PCT",
51+
"ML-KEM PCT", // -768
52+
"ML-KEM PCT", // -1024
5353
"ML-KEM-768",
5454
"PBKDF2",
5555
"RSA sign and verify PCT",
@@ -104,29 +104,44 @@ func TestAllCASTs(t *testing.T) {
104104

105105
// TestConditionals causes the conditional CASTs and PCTs to be invoked.
106106
func TestConditionals(t *testing.T) {
107-
mlkem.GenerateKey768()
107+
// ML-KEM PCT
108+
kMLKEM, err := mlkem.GenerateKey768()
109+
if err != nil {
110+
t.Error(err)
111+
} else {
112+
// ML-KEM-768
113+
kMLKEM.EncapsulationKey().Encapsulate()
114+
}
115+
// ECDH PCT
108116
kDH, err := ecdh.GenerateKey(ecdh.P256(), rand.Reader)
109117
if err != nil {
110118
t.Error(err)
111119
} else {
120+
// KAS-ECC-SSC P-256
112121
ecdh.ECDH(ecdh.P256(), kDH, kDH.PublicKey())
113122
}
123+
// ECDSA PCT
114124
kDSA, err := ecdsa.GenerateKey(ecdsa.P256(), rand.Reader)
115125
if err != nil {
116126
t.Error(err)
117127
} else {
128+
// ECDSA P-256 SHA2-512 sign and verify
118129
ecdsa.SignDeterministic(ecdsa.P256(), sha256.New, kDSA, make([]byte, 32))
119130
}
131+
// Ed25519 sign and verify PCT
120132
k25519, err := ed25519.GenerateKey()
121133
if err != nil {
122134
t.Error(err)
123135
} else {
136+
// Ed25519 sign and verify
124137
ed25519.Sign(k25519, make([]byte, 32))
125138
}
139+
// RSA sign and verify PCT
126140
kRSA, err := rsa.GenerateKey(rand.Reader, 2048)
127141
if err != nil {
128142
t.Error(err)
129143
} else {
144+
// RSASSA-PKCS-v1.5 2048-bit sign and verify
130145
rsa.SignPKCS1v15(kRSA, crypto.SHA256.String(), make([]byte, 32))
131146
}
132147
t.Log("completed successfully")

0 commit comments

Comments
 (0)