Files
zeekay 2646382620 chore: initial commit — p3q-prover
This tree had a .git directory but ZERO commits, no branch and no remote: the
source existed only as loose files on one disk, where an rm -rf would have
destroyed it with nothing to recover from.

Commits the working tree as-is so the work is in git history. No source was
modified.

NOTE: still has no remote. luxfi/p3q-prover does not exist on GitHub, so this
is one copy in one place until somebody creates it.
2026-07-26 02:53:27 -07:00

86 lines
2.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package p3qprover
// proofPayload is the decoded P3QRoot.Proof for the reference (BackendDirect)
// backend. It carries the witness (the verified subset's signatures) plus the
// bound public-input digest and attested weight. For BackendStarkFRI this
// payload is replaced by a FRI proof; the surrounding P3QRoot fields (Root,
// SignerSetID, EraHandle, Threshold, SuiteID) are unchanged.
type proofPayload struct {
backend Backend
pi [32]byte
attestedWeight uint64
entries []CertEntry
}
// encodeProof serializes the reference proof envelope.
//
// Layout:
//
// [4] magic "P3QR"
// [1] version
// [1] backend
// [1] mode (0x65)
// [32] PI digest
// [8] attestedWeight (BE)
// [4] N (BE uint32)
// N × entry{ [20] nodeID | [4] sigLen (BE) | [sigLen] sig }
func encodeProof(p proofPayload) []byte {
out := make([]byte, 0, 4+1+1+1+32+8+4+len(p.entries)*(nodeIDLen+4+mldsaSigSize))
out = append(out, []byte(proofMagic)...)
out = append(out, wireVersion, byte(p.backend), modeMLDSA65)
out = append(out, p.pi[:]...)
out = append(out, be64(p.attestedWeight)...)
out = appendU32(out, uint32(len(p.entries)))
return appendEntries(out, p.entries)
}
// decodeProof parses the reference proof envelope. It validates the structural
// frame only; the cryptographic checks (signatures, root, PI) are the
// verifier's job (verify.go).
func decodeProof(b []byte) (proofPayload, error) {
var p proofPayload
r := newReader(b)
magic, ok := r.take(4)
if !ok || string(magic) != proofMagic {
return p, ErrMalformedProof
}
ver, ok := r.byteAt()
if !ok || ver != wireVersion {
return p, ErrMalformedProof
}
backend, ok := r.byteAt()
if !ok {
return p, ErrMalformedProof
}
p.backend = Backend(backend)
mode, ok := r.byteAt()
if !ok {
return p, ErrMalformedProof
}
if mode != modeMLDSA65 {
return p, ErrUnsupportedMode
}
pi, ok := r.take(32)
if !ok {
return p, ErrMalformedProof
}
copy(p.pi[:], pi)
aw, ok := r.u64()
if !ok {
return p, ErrMalformedProof
}
p.attestedWeight = aw
entries, err := readEntries(&r)
if err != nil {
return p, err
}
if !r.done() {
return p, ErrMalformedProof
}
p.entries = entries
return p, nil
}