mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
InitiateKEMSession took a transcript, hashed six kilobytes of it into the session, and the handshake then overwrote that hash with its own — so the argument's only effects were a non-empty check and a cSHAKE nobody read, once per handshake. The doc comment said the derived key was bound to the bytes passed there, which it was not. The KEM establishes a shared secret. The commitment is made where the whole handshake is known, which is the only place it can be made correctly. Co-authored-by: Hanzo Dev <[email protected]>
96 lines
3.2 KiB
Go
96 lines
3.2 KiB
Go
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package kem
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestDKGChannel_ForcesMLKEM1024 asserts the DKG channel adapter refuses
|
|
// any KEM other than ML-KEM-1024. This closes the cross-axis drift where
|
|
// a profile pins HighValueKEM=ML-KEM-1024 but a DKG attempt under
|
|
// ML-KEM-768 would otherwise succeed silently.
|
|
func TestDKGChannel_ForcesMLKEM1024(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
// DKGChannelScheme is the canonical constant; assert its byte value
|
|
// is ML-KEM-1024 so a future refactor can't silently flip it.
|
|
require.Equal(KeyExchangeMLKEM1024, DKGChannelScheme,
|
|
"DKGChannelScheme MUST be ML-KEM-1024")
|
|
|
|
pub1024, priv1024, err := GenerateKEMKeypair(KeyExchangeMLKEM1024, rand.Reader)
|
|
require.NoError(err)
|
|
|
|
transcript := []byte("dkg-channel-transcript")
|
|
|
|
// Happy path: ML-KEM-1024 succeeds end-to-end.
|
|
initSess, ct, err := InitiateDKGKEMSession(KeyExchangeMLKEM1024, pub1024)
|
|
require.NoError(err)
|
|
initSess.TranscriptHash = HashTranscript(transcript)
|
|
require.Equal(KeyExchangeMLKEM1024, initSess.SchemeID)
|
|
|
|
respSess, err := RespondDKGKEMSession(KeyExchangeMLKEM1024, priv1024, ct)
|
|
require.NoError(err)
|
|
respSess.TranscriptHash = HashTranscript(transcript)
|
|
require.Equal(initSess.SharedSecret, respSess.SharedSecret)
|
|
|
|
// DKG-flavour AEAD key MUST derive cleanly.
|
|
initKey, err := initSess.DeriveDKGAEADKey()
|
|
require.NoError(err)
|
|
respKey, err := respSess.DeriveDKGAEADKey()
|
|
require.NoError(err)
|
|
require.Equal(initKey, respKey)
|
|
|
|
// Bad path 1: caller passes ML-KEM-768 to the DKG adapter.
|
|
pub768, priv768, err := GenerateKEMKeypair(KeyExchangeMLKEM768, rand.Reader)
|
|
require.NoError(err)
|
|
|
|
_, _, err = InitiateDKGKEMSession(KeyExchangeMLKEM768, pub768)
|
|
require.ErrorIs(err, ErrDKGSchemeMismatch,
|
|
"DKG adapter MUST refuse ML-KEM-768")
|
|
|
|
_, err = RespondDKGKEMSession(KeyExchangeMLKEM768, priv768, make([]byte, 1088))
|
|
require.ErrorIs(err, ErrDKGSchemeMismatch)
|
|
|
|
// Bad path 2: caller passes a classical marker.
|
|
_, _, err = InitiateDKGKEMSession(KeyExchangeX25519Unsafe, pub1024)
|
|
require.ErrorIs(err, ErrDKGSchemeMismatch)
|
|
|
|
// Bad path 3: caller passes None.
|
|
_, _, err = InitiateDKGKEMSession(KeyExchangeNone, pub1024)
|
|
require.ErrorIs(err, ErrDKGSchemeMismatch)
|
|
}
|
|
|
|
// TestAssertDKGCompliance exercises the boot-time cross-axis check that
|
|
// a pulsar / pulsar-m DKG session's scheme byte agrees with the strict-PQ
|
|
// profile's HighValueKEM byte. Both must be ML-KEM-1024; anything else is
|
|
// a configuration drift.
|
|
func TestAssertDKGCompliance(t *testing.T) {
|
|
require := require.New(t)
|
|
|
|
// Happy path: both ML-KEM-1024.
|
|
require.NoError(AssertDKGCompliance(KeyExchangeMLKEM1024, KeyExchangeMLKEM1024))
|
|
|
|
// Profile high-value byte wrong.
|
|
require.ErrorIs(
|
|
AssertDKGCompliance(KeyExchangeMLKEM1024, KeyExchangeMLKEM768),
|
|
ErrDKGSchemeMismatch,
|
|
)
|
|
|
|
// Session byte wrong (profile correct).
|
|
require.ErrorIs(
|
|
AssertDKGCompliance(KeyExchangeMLKEM768, KeyExchangeMLKEM1024),
|
|
ErrDKGSchemeMismatch,
|
|
)
|
|
|
|
// Both wrong.
|
|
require.ErrorIs(
|
|
AssertDKGCompliance(KeyExchangeX25519Unsafe, KeyExchangeMLKEM768),
|
|
ErrDKGSchemeMismatch,
|
|
)
|
|
}
|