Files
oracle/vm/observation_fuzz_test.go
zeekay c3951dda56 vm: wire Observation + OracleRecord signing through profile gate
- Observation and OracleRecord now carry an explicit Scheme tag
  (wire-stable enum 0x01=ml-dsa-65, 0x02=ed25519) so verifiers
  dispatch deterministically.
- RegisterOperatorKey(nodeID, scheme, pub) registers an operator's
  signing key. Registration accepts both schemes; verification is the
  gate (single call to profile.Verify).
- VerifyObservationSignature and VerifyRecordSignature each call
  profile.Verify exactly once over a canonical message string
  ("LUX:OracleObservation:v1" / "LUX:OracleRecord:v1" tagged inputs).
  No primitive-specific code remains in the VM.
- vm.Config.LegacyClassicalEnabled wires the chain-level toggle into
  vm.policy.

5 e2e tests: PQ-default Observation, PQ-default Record, strict-PQ
classical refusal, legacy opt-in, unregistered-operator refuse. 2
fuzz targets (FuzzObservationDecode, FuzzOracleRecordDecode) survive
~50k execs with no panics.
2026-05-19 08:37:15 -07:00

53 lines
1.3 KiB
Go

// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package vm
import (
"encoding/json"
"testing"
)
// FuzzObservationDecode feeds the JSON observation decoder arbitrary bytes
// to confirm it never panics — the decoder is at the trust boundary between
// O-Chain RPC callers and the operator key registry.
func FuzzObservationDecode(f *testing.F) {
good := &Observation{
Value: []byte("100.0"),
Scheme: 0x01,
Signature: []byte("seed-sig"),
}
if b, err := json.Marshal(good); err == nil {
f.Add(b)
}
f.Add([]byte(`{}`))
f.Add([]byte(`null`))
f.Add([]byte(`{"scheme":255}`))
f.Add([]byte(`{"signature":null}`))
f.Fuzz(func(t *testing.T, data []byte) {
var o Observation
_ = json.Unmarshal(data, &o) // must not panic
})
}
// FuzzOracleRecordDecode does the same for executor records.
func FuzzOracleRecordDecode(f *testing.F) {
good := &OracleRecord{
Endpoint: "https://x.test/v1",
ResultCode: 200,
Scheme: 0x01,
}
if b, err := json.Marshal(good); err == nil {
f.Add(b)
}
f.Add([]byte(`{}`))
f.Add([]byte(`null`))
f.Add([]byte(`{"resultCode":-1}`))
f.Fuzz(func(t *testing.T, data []byte) {
var r OracleRecord
_ = json.Unmarshal(data, &r) // must not panic
})
}