// Package verify implements signature verification for Mithril certificates. // // Two layers of verification exist in Mithril: // // 1. The genesis certificate is signed by a static Ed25519 key baked into // the client (per-network). This bootstraps trust into the STM protocol. // 2. Subsequent certificates carry an STM (Stake-based Threshold Multi- // signature) aggregate signature over BLS12-381. Verification requires // the stake distribution snapshot plus the signers' verification keys // and their individual signature shares. // // v1 scope: genesis Ed25519 verification only. STM/BLS verification is a // separate follow-on milestone — it is the bulk of the cryptographic work // in this project. package verify import ( "crypto/ed25519" "encoding/hex" "errors" "fmt" ) var ( ErrNotGenesis = errors.New("certificate is not a genesis certificate") ErrBadSignature = errors.New("genesis signature verification failed") ErrSTMNotImplemented = errors.New("STM signature verification not implemented yet") ) // Genesis verifies that the certificate was signed by the network's genesis // verification key. signedPayload is the exact bytes the aggregator stated // were signed (derived from the certificate's protocol_message, not this // function's job to construct). func Genesis(verifyKeyHex, genesisSignatureHex string, signedPayload []byte) error { pkHex, err := hex.DecodeString(verifyKeyHex) if err != nil { return fmt.Errorf("decode verify key: %w", err) } // Mithril genesis keys are serialized as hex(ascii-of-byte-array-literal), // e.g. "[191,66,140,...]" → outer hex → inner ASCII → parse. The real decoder // will unpack this; for now accept a raw 32-byte hex as well. pk := ed25519.PublicKey(pkHex) if len(pk) != ed25519.PublicKeySize { return fmt.Errorf("verify key wrong size: got %d, want %d", len(pk), ed25519.PublicKeySize) } sig, err := hex.DecodeString(genesisSignatureHex) if err != nil { return fmt.Errorf("decode signature: %w", err) } if !ed25519.Verify(pk, signedPayload, sig) { return ErrBadSignature } return nil } // STM verifies a non-genesis certificate's aggregate BLS signature against // the stake distribution. Stub — implementation target: Mithril STM paper // §5 (signing protocol) + §6 (aggregation) using a BLS12-381 library. func STM(protocolMessage, multiSignature []byte, stakeDistribution any) error { return ErrSTMNotImplemented }