mirror of
https://github.com/luxfi/chains.git
synced 2026-09-24 00:26:00 +00:00
LP-134 was renumbered LP-1340 (lp-1340-lux-chain-topology); 21 citations across 16 files still named the old number, which resolves to nothing. Corona rests on Module-LWE, not Ring-LWE — LP-4805 says so in three places and b17e086 already corrected one file, leaving evm/main.go and schain/SECURITY_review.md claiming the wrong hardness assumption. The two-family argument in LP-4900 depends on which lattice problem this is. P3Q at 0x012205 is kind-byte signature dispatch; STARK/FRI is starkfri at 0x012220 (LP-7050). Naming P3Q for a scheme at another slot describes a precompile that is not the one being imported. Carries the substance of 2f22fa2, the one commit the parallel line held that this history did not.
78 lines
2.5 KiB
Go
78 lines
2.5 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package cert
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"errors"
|
|
)
|
|
|
|
// Roots is the set of upstream roots a Quasar 3.0 certificate_subject
|
|
// binds, mirroring the QuasarRoundDescriptor in LP-1340.
|
|
//
|
|
// All ten roots are required, including both MChain and FChain —
|
|
// this is the structural property that makes cross-chain replay
|
|
// impossible. The substrate does not let a caller skip a root: a zero
|
|
// value is still a value, and the chain that owns the root is
|
|
// expected to provide its current root on every round.
|
|
type Roots struct {
|
|
ParentBlock [32]byte
|
|
StateRoot [32]byte
|
|
ExecRoot [32]byte
|
|
PChainValidator [32]byte
|
|
QChainCeremony [32]byte
|
|
ZChainVK [32]byte
|
|
AChainAttestation [32]byte
|
|
BChainBridge [32]byte
|
|
MChainCeremony [32]byte
|
|
FChainFHE [32]byte
|
|
}
|
|
|
|
// BindSubject computes certificate_subject = H(... all roots ...).
|
|
// The hash domain is sha256 with a 1-byte version tag (0x01 for
|
|
// LP-1340 v3.1) so future descriptor extensions can change the input
|
|
// set without colliding.
|
|
func BindSubject(r Roots) [32]byte {
|
|
h := sha256.New()
|
|
h.Write([]byte{0x01}) // LP-1340 v3.1 descriptor version
|
|
h.Write(r.ParentBlock[:])
|
|
h.Write(r.StateRoot[:])
|
|
h.Write(r.ExecRoot[:])
|
|
h.Write(r.PChainValidator[:])
|
|
h.Write(r.QChainCeremony[:])
|
|
h.Write(r.ZChainVK[:])
|
|
h.Write(r.AChainAttestation[:])
|
|
h.Write(r.BChainBridge[:])
|
|
h.Write(r.MChainCeremony[:])
|
|
h.Write(r.FChainFHE[:])
|
|
var out [32]byte
|
|
copy(out[:], h.Sum(nil))
|
|
return out
|
|
}
|
|
|
|
// VerifySubject re-computes the subject from its inputs and checks it
|
|
// matches the value carried on the wire. Used by both M-Chain and
|
|
// F-Chain at certificate-ingress time.
|
|
func VerifySubject(claimed [32]byte, r Roots) error {
|
|
if BindSubject(r) != claimed {
|
|
return errors.New("subject: claimed certificate_subject does not match descriptor roots")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RequireBothChains reports an error if either MChainCeremony or
|
|
// FChainFHE is zero — the LP-1340 invariant that every round binds
|
|
// **both** chain roots, even on rounds where one chain does not
|
|
// finalize a ceremony (the unchanged root from the previous round
|
|
// satisfies the binding).
|
|
func (r Roots) RequireBothChains() error {
|
|
if r.MChainCeremony == ([32]byte{}) {
|
|
return errors.New("subject: mchain_ceremony_root is zero — boot-time root not yet wired")
|
|
}
|
|
if r.FChainFHE == ([32]byte{}) {
|
|
return errors.New("subject: fchain_fhe_root is zero — boot-time root not yet wired")
|
|
}
|
|
return nil
|
|
}
|