// Section 5.2 · Protocol
Node Authentication
Every message a node emits is signed.
// 5.2 · node authentication · the actor binding primitive
Nodes register an RSA public key when they join the network. Every message the node emits afterward is signed with the corresponding private key. The coordinator verifies the signature against the registry on receipt. Anything unsigned, anything with an invalid signature, anything that does not bind to a registered node is discarded at the coordinator boundary.
The verification flow
// three checks · before the result is admitted
Coordinator extracts the signature header from the message envelope. Messages without a signature header drop immediately.
Resolve node_id → registered RSA public key from the node registry. Unknown node_id drops the message.
rsa_verify(pubkey, message_body, signature). A failed verification drops the message and increments a fingerprinting counter against the source IP.
The signing primitive
// rsa-2048 · sha-256 hash inside · standard scheme
def sign_result(node_key: PrivateKey, request_id: bytes, result: bytes, poe: bytes) -> bytes:
"""Sign the (request_id, result, poe) tuple before returning to the coordinator."""
message = request_id + result + poe
return rsa_sign_pkcs1v15(node_key, sha256(message))
# Node returns:
# { request_id, result, poe, sig }def verify_return(returned: RequestReturn) -> bool:
pubkey = node_registry.get(returned.node_id)
if pubkey is None:
return False # unknown node
message = returned.request_id + returned.result + returned.poe
return rsa_verify_pkcs1v15(pubkey, sha256(message), returned.sig)Actor binding
Proves the specific node holding node.key produced and submitted the message. The signature is unforgeable without that key.
Result correctness
Says nothing about whether the result is honest. A node can sign a fabricated result with a valid signature. Honesty is enforced by §5.5 redundancy.