-
Notifications
You must be signed in to change notification settings - Fork 118
Description
NEP: XXX
Title: Standard for Offline Message Signing and Verification
Author: Adrian (atlazor)
Discussions-To: https://github.com/neo-project/proposals/issues
Status: Draft
Type: Standards Track
Category: Core
Created: 2025-11-10
Simple Summary
Define a standardized JSON format and signing algorithm specification for offline message signing in Neo N3 CLI and compatible wallets, ensuring consistent and verifiable results across implementations.
Abstract
This NEP introduces a standard for offline message signing and verification. It defines:
- A canonical JSON structure for the signed message output.
- A versioning convention for signing standards (e.g.,
NEP-XXX.1). - The
algoproperty to identify the algorithm used for message payload construction. - The
curveproperty to define the elliptic curve used for signing.
The initial algorithm, nep33_safe_message_v1, provides a secure method of signing arbitrary messages without risk of the resulting signature being interpreted as a valid Neo transaction.
Motivation
Governance candidates, node operators, and automated agents often need to sign arbitrary messages securely and verifiably using Neo wallets or CLI tools. Currently, there is no standard output format or canonical signing algorithm for this process.
Different wallets have implemented ad-hoc approaches for signing messages, leading to verification inconsistencies and interoperability issues.
The goal of NEP-33 is to unify how offline messages are signed, serialized, and verified across the Neo ecosystem.
Specification
The standard defines both the output format and the algorithmic method for constructing the payload to be signed.
JSON Output Format
The standardized JSON object MUST include the following fields:
{
"version": "NEP-XXX.1",
"algo": "nepXXX_safe_message_v1",
"curve": "secp256r1",
"signedPayloadBase64": "AQAB8MmMZCPvdYfAA7ScAZZiw8NLil8isWvxfs5Q...AA==",
"signatures": [
{
"address": "NZf33mJcBxW6ZjYGRcbvV2eiVigFD3g2Ak",
"publicKey": "03a9321588342aaecca1f4983a5bca1b16e460ed3d07e40a5d9f76ae7077d9779d",
"signature": "b8170ac6c93a0b79...",
"salt": "42a0df62e01367f430842f2f551d46a4"
}
]
}Field Descriptions
-
version — NEP reference and sub-version (e.g.,
NEP-XXX.1). -
algo — The algorithm used to construct the signed payload.
-
curve — Elliptic curve used for signing (
secp256r1,secp256k1, etc.). -
signedPayloadBase64 — MUST be the exact byte sequence that was signed, encoded in base64 (no
0xprefix or hex). This enables unambiguous reconstruction and verification across languages and platforms. -
signatures — List of signature entries, one for each signing account.
- address — Neo N3 address of the signer.
- publicKey — Compressed public key of the signer.
- signature — Hex-encoded signature.
- salt — Random 16-byte hex string used in payload construction.
Encoding Rules:
- Implementations MUST base64-encode the raw payload bytes as
signedPayloadBase64. - Implementations SHOULD NOT include a duplicate hex-encoded payload field; hex can be ambiguous across environments (e.g.,
0xprefixes). - If a hex form is exposed for debugging, it MUST be named
signedPayloadHexand is OPTIONAL.
Algorithm Definitions
nepXXX_safe_message_v1
The nepXXX_safe_message_v1 aims to prevent message signatures from being valid Neo transactions by embedding the message inside a non-transactional payload.
Payload Construction:
010001f0 + VarBytes(Salt + Message) + 0000
Verification Steps:
- Rebuild the payload using the provided
saltand message data according to the defined algorithm. - Apply the chosen elliptic curve (
curve) and signature scheme. - Verify using the provided
publicKeyandsignature.
Security Rationale:
The prefix 010001f0 and suffix 0000 ensure the signed payload cannot be interpreted as a valid Neo transaction, mitigating the risk of transaction replay or signature misuse.
Rationale
A common, machine-readable format for offline message signing simplifies cross-tool verification, governance audits, and automated attestation mechanisms. It also ensures that node operators and wallets can independently verify message authenticity without requiring a running Neo node.
Backward Compatibility
This proposal introduces new functionality and does not break any existing behavior. Future wallet or CLI implementations can adopt NEP-XXX incrementally.
Reference Implementation
The Neo CLI implementation added by Adrian (atlazor) in November 2025:
https://github.com/neo-project/neo/blob/master/src/Neo.CLI/CLI/MainService.Wallet.cs
[ConsoleCommand("sign message", Category = "Wallet Commands")]
private void OnSignMessageCommand(string message)Payload construction follows:
010001f0 + VarBytes(Salt + Message) + 0000