"crypto/internal/fips140"
_ "crypto/internal/fips140/check"
"errors"
+ "sync"
)
-func init() {
+var fipsSelfTest = sync.OnceFunc(func() {
fips140.CAST("ML-KEM-768", func() error {
var d = &[32]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
dk := &DecapsulationKey768{}
kemKeyGen(dk, d, z)
ek := dk.EncapsulationKey()
- Ke, c := ek.EncapsulateInternal(m)
- Kd, err := dk.Decapsulate(c)
- if err != nil {
- return err
- }
+ var cc [CiphertextSize768]byte
+ Ke, _ := kemEncaps(&cc, ek, m)
+ Kd := kemDecaps(dk, &cc)
if !bytes.Equal(Ke, K) || !bytes.Equal(Kd, K) {
return errors.New("unexpected result")
}
return nil
})
-}
+})
}
func generateKey1024(dk *DecapsulationKey1024) (*DecapsulationKey1024, error) {
+ fipsSelfTest()
var d [32]byte
drbg.Read(d[:])
var z [32]byte
// GenerateKeyInternal1024 is a derandomized version of GenerateKey1024,
// exclusively for use in tests.
func GenerateKeyInternal1024(d, z *[32]byte) *DecapsulationKey1024 {
+ fipsSelfTest()
dk := &DecapsulationKey1024{}
kemKeyGen1024(dk, d, z)
return dk
}
func (ek *EncapsulationKey1024) encapsulate(cc *[CiphertextSize1024]byte) (sharedKey, ciphertext []byte) {
+ fipsSelfTest()
var m [messageSize]byte
drbg.Read(m[:])
// Note that the modulus check (step 2 of the encapsulation key check from
// EncapsulateInternal is a derandomized version of Encapsulate, exclusively for
// use in tests.
func (ek *EncapsulationKey1024) EncapsulateInternal(m *[32]byte) (sharedKey, ciphertext []byte) {
+ fipsSelfTest()
cc := &[CiphertextSize1024]byte{}
return kemEncaps1024(cc, ek, m)
}
//
// The shared key must be kept secret.
func (dk *DecapsulationKey1024) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) {
+ fipsSelfTest()
if len(ciphertext) != CiphertextSize1024 {
return nil, errors.New("mlkem: invalid ciphertext length")
}
}
func generateKey(dk *DecapsulationKey768) (*DecapsulationKey768, error) {
+ fipsSelfTest()
var d [32]byte
drbg.Read(d[:])
var z [32]byte
// GenerateKeyInternal768 is a derandomized version of GenerateKey768,
// exclusively for use in tests.
func GenerateKeyInternal768(d, z *[32]byte) *DecapsulationKey768 {
+ fipsSelfTest()
dk := &DecapsulationKey768{}
kemKeyGen(dk, d, z)
return dk
}
func (ek *EncapsulationKey768) encapsulate(cc *[CiphertextSize768]byte) (sharedKey, ciphertext []byte) {
+ fipsSelfTest()
var m [messageSize]byte
drbg.Read(m[:])
// Note that the modulus check (step 2 of the encapsulation key check from
// EncapsulateInternal is a derandomized version of Encapsulate, exclusively for
// use in tests.
func (ek *EncapsulationKey768) EncapsulateInternal(m *[32]byte) (sharedKey, ciphertext []byte) {
+ fipsSelfTest()
cc := &[CiphertextSize768]byte{}
return kemEncaps(cc, ek, m)
}
//
// The shared key must be kept secret.
func (dk *DecapsulationKey768) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) {
+ fipsSelfTest()
if len(ciphertext) != CiphertextSize768 {
return nil, errors.New("mlkem: invalid ciphertext length")
}
"HKDF-SHA2-256",
"HMAC-SHA2-256",
"KAS-ECC-SSC P-256",
- "ML-KEM PCT",
- "ML-KEM PCT",
+ "ML-KEM PCT", // -768
+ "ML-KEM PCT", // -1024
"ML-KEM-768",
"PBKDF2",
"RSA sign and verify PCT",
// TestConditionals causes the conditional CASTs and PCTs to be invoked.
func TestConditionals(t *testing.T) {
- mlkem.GenerateKey768()
+ // ML-KEM PCT
+ kMLKEM, err := mlkem.GenerateKey768()
+ if err != nil {
+ t.Error(err)
+ } else {
+ // ML-KEM-768
+ kMLKEM.EncapsulationKey().Encapsulate()
+ }
+ // ECDH PCT
kDH, err := ecdh.GenerateKey(ecdh.P256(), rand.Reader)
if err != nil {
t.Error(err)
} else {
+ // KAS-ECC-SSC P-256
ecdh.ECDH(ecdh.P256(), kDH, kDH.PublicKey())
}
+ // ECDSA PCT
kDSA, err := ecdsa.GenerateKey(ecdsa.P256(), rand.Reader)
if err != nil {
t.Error(err)
} else {
+ // ECDSA P-256 SHA2-512 sign and verify
ecdsa.SignDeterministic(ecdsa.P256(), sha256.New, kDSA, make([]byte, 32))
}
+ // Ed25519 sign and verify PCT
k25519, err := ed25519.GenerateKey()
if err != nil {
t.Error(err)
} else {
+ // Ed25519 sign and verify
ed25519.Sign(k25519, make([]byte, 32))
}
+ // RSA sign and verify PCT
kRSA, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Error(err)
} else {
+ // RSASSA-PKCS-v1.5 2048-bit sign and verify
rsa.SignPKCS1v15(kRSA, crypto.SHA256.String(), make([]byte, 32))
}
t.Log("completed successfully")