-
Notifications
You must be signed in to change notification settings - Fork 30
YNU-827: Nitrolite Protocol Documentation #619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1176de1
0ceab74
7dc2535
ac4f34b
c41da7d
8a46259
ee41834
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| # Cross-Chain and Asset Model | ||
|
|
||
| Previous: [Enforcement and Settlement](enforcement.md) | Next: [Interactions](interactions.md) | ||
|
|
||
| --- | ||
|
|
||
| This document describes the unified asset model and cross-chain functionality. | ||
|
|
||
| ## Purpose | ||
|
|
||
| The unified asset model allows participants to operate on assets from multiple blockchains within a single channel. This eliminates the need for separate channels per blockchain and enables cross-chain interactions. | ||
|
|
||
| ## Unified Asset Concept | ||
|
|
||
| Assets in the Nitrolite protocol are identified independently of any specific blockchain. | ||
|
|
||
| A unified asset is defined by: | ||
|
|
||
| | Field | Description | | ||
| | -------- | -------------------------------------------------- | | ||
| | Symbol | Human-readable canonical asset identifier (e.g. "USDC") | | ||
| | Decimals | Decimal precision of the asset | | ||
|
|
||
| ### Canonical Asset Identification | ||
|
|
||
| The protocol identifies a unified asset by its symbol. Within channel metadata, the symbol is represented as the first 8 bytes of its Keccak-256 hash, providing a compact canonical identifier. Two chain-specific tokens are recognized as the same unified asset if they share the same symbol-derived identifier and are configured as such by the node. | ||
|
|
||
| Symbol collisions are prevented by the node's asset configuration. The protocol does not maintain a global on-chain registry of unified assets. | ||
|
|
||
| ### Amount Normalization | ||
|
|
||
| Assets on different blockchains MAY have different decimal precisions (e.g. USDC has 6 decimals on Ethereum but may have different precision on other chains). The protocol normalizes amounts for cross-chain comparisons using WAD normalization, which scales chain-specific amounts as if a token had 18 decimals: | ||
|
|
||
| ``` | ||
| NormalizedAmount = Amount * 10^(18 - ChainDecimals) | ||
| ``` | ||
|
|
||
| Each unified asset defines a canonical decimal precision (e.g. 6 for USDC) that is used during User <> Clearnode interactions (e.g. on-chain deposit, on-chain state submission requests, transfers, app session operations etc.). | ||
|
|
||
| Rules: | ||
|
|
||
| - Normalization is used **only for cross-chain comparisons** (e.g. validating that escrow amounts match across chains). It is not used for storage or accounting — stored values remain in their chain-native precision. | ||
| - The asset's configured decimal precision acts as the base, whereas 18 is the target of the upscaling. The maximum supported decimal precision is 18. | ||
| - Normalization is exact and lossless when scaling up. No rounding or remainder occurs. | ||
| - The blockchain layer validates that declared decimals match the actual token decimals on the current chain. | ||
|
|
||
| ## Home Chain | ||
|
|
||
| The home chain is the blockchain against which a given channel state is enforced. It is identified by the chain identifier in the home ledger of that state. | ||
|
|
||
| The home chain determines: | ||
|
|
||
| - where enforcement operations for that state are executed | ||
| - which blockchain holds the locked funds for the channel | ||
| - the authoritative source for state validation | ||
|
|
||
| The home chain MAY change over the lifetime of a channel through a migration operation. After migration, the new home chain becomes the authoritative enforcement target. | ||
|
|
||
| ## Home and Non-Home Ledger Roles | ||
|
|
||
| **Home Ledger** | ||
| The home ledger is the primary record of asset allocations. It is associated with the home chain and is directly enforceable through the blockchain layer. | ||
|
|
||
| Responsibilities: | ||
|
|
||
| - tracks the authoritative asset allocations | ||
| - receives checkpoints for enforcement | ||
| - holds deposited assets in the enforcement contract | ||
|
|
||
| **Non-Home Ledger** | ||
| The non-home ledger tracks asset allocations on a blockchain other than the home chain. When no cross-chain operation is in progress, the non-home ledger MUST be empty (see [Empty Non-Home Ledger](state-model.md#empty-non-home-ledger)). | ||
|
|
||
| Responsibilities: | ||
|
|
||
| - tracks assets involved in cross-chain escrow operations | ||
| - reflects cross-chain deposit and withdrawal allocations | ||
| - coordinates with the home ledger for consistency | ||
|
|
||
| ## Escrow Model | ||
|
|
||
| Cross-chain operations use an **escrow** mechanism to coordinate fund movements across two independent blockchains. | ||
|
|
||
| An escrow is a temporary on-chain record that locks funds on one chain while a corresponding state update is being finalized on the other chain. Each escrow is identified by an **escrow channel identifier**, derived deterministically from the home channel identifier and the state version at initiation. | ||
|
|
||
| | Property | Description | | ||
| | -------------- | --------------------------------------------------------------- | | ||
| | Identifier | 32-byte hash derived from the home channel identifier and state version | | ||
| | Hosting chain | The non-home chain (for deposits: where the user's funds are locked; for withdrawals: where the node's funds are locked) | | ||
| | Tracked amount | The amount locked in escrow, corresponding to the non-home ledger allocations | | ||
| | Unlock delay | Escrow deposits include an unlock delay after which funds are automatically unlocked to the node if not challenged | | ||
| | ChallengeDuration | A period after a challenge was initiated that allows resolution. If no finalization state was supplied, the initiate state is finalized, and funds are returned | | ||
|
|
||
| An escrow is not a separate protocol entity with its own state — it is an on-chain record derived from a channel state transition. The escrow exists only between initiation and finalization (or timeout). | ||
|
|
||
| ## Cross-Chain Deposit | ||
|
|
||
| To deposit assets from a non-home chain into a channel, the protocol uses a two-phase escrow process: | ||
|
|
||
| 1. **Initiate (Escrow Deposit Initiate)** — participants sign a state that creates an escrow. On the home chain, the node's allocation increases to reserve funds. On the non-home chain, the user's deposit is locked in an escrow record with an unlock delay. | ||
| 2. **Finalize (Escrow Deposit Finalize)** — after the escrow is created, participants sign a state that completes the deposit. On the home chain, the user's allocation increases by the deposited amount. On the non-home chain, the escrowed funds are released to the node's vault. | ||
|
|
||
| If the escrow is not finalized within the unlock delay, the escrowed funds on the non-home chain are automatically unlocked to the Node. Either participant MAY challenge the escrow during the challenge period. Note that it is NOT possible to challenge a deposit escrow after unlock delay has passed as the funds were already unlocked to the Node. | ||
|
|
||
| Cross-chain amounts are validated using WAD normalization to ensure the home-chain node allocation matches the non-home-chain user deposit. | ||
|
|
||
| ## Cross-Chain Withdrawal | ||
|
|
||
| To withdraw assets to a non-home chain, the protocol uses a similar two-phase escrow process: | ||
|
|
||
| 1. **Initiate (Escrow Withdrawal Initiate)** — participants sign a state that creates an escrow. On the non-home chain, the node locks funds from its vault into the escrow record. | ||
| 2. **Finalize (Escrow Withdrawal Finalize)** — participants sign a state that completes the withdrawal. On the home chain, the user's allocation decreases. On the non-home chain, the escrowed funds are released to the user. | ||
|
|
||
| If the escrow is not finalized cooperatively, either participant MAY challenge the escrow. | ||
|
|
||
| ## Home Chain Migration | ||
|
|
||
| The home chain of a channel MAY be changed through a two-phase migration process: | ||
|
|
||
| 1. **Initiate (Migration Initiate)** — participants sign a state that begins the migration. On the current home chain, the state records the target chain allocation. On the target chain, a new channel record is created with status "migrating in" and the node locks funds equal to the user's allocation (validated via WAD normalization). | ||
| 2. **Finalize (Migration Finalize)** — participants sign a state that completes the migration. On the new home chain, the channel transitions to operating status. On the old home chain, all locked funds are released to the node and the channel is marked as migrated out. | ||
|
|
||
| After migration, the following changes take effect: | ||
|
|
||
| - **Home chain identifier** is updated to reflect the migration | ||
| - **Home token address** is updated to reflect the migration | ||
| - **Ledger roles** — the former non-home ledger becomes the home ledger; the former home ledger becomes the non-home ledger (and its allocations are zeroed out on finalization) | ||
| - **Enforcement target** — all subsequent enforcement operations execute against the new home chain | ||
| - **Balances** — the user's allocation is preserved (normalized by decimal precision); the node's allocation is recalculated for the new chain | ||
|
|
||
| VERSION NOTE: Migration transitions are functional but may be refined in future protocol versions. | ||
|
|
||
| ## Cross-Chain Replay Protection | ||
|
|
||
| The protocol prevents cross-chain replay through multiple binding mechanisms: | ||
|
|
||
| - **Chain identifier binding** — each ledger is bound to a specific chain identifier. The blockchain layer validates that the home ledger chain identifier matches the current blockchain. This prevents a state signed for one chain from being enforced on another. | ||
| - **Channel identifier scoping** — channel identifiers incorporate a protocol version byte, preventing replay across smart contract deployments. The same channel definition on a different protocol version produces a different channel identifier. | ||
| - **Escrow identifier uniqueness** — escrow channel identifiers are derived from the home channel identifier and the state version at initiation. This ensures that each escrow operation produces a unique identifier, preventing a completed escrow from being replayed. | ||
| - **Ledger validation** — on-chain enforcement validates that both home and non-home ledger's declared decimals match the actual token decimals on the current execution chain, preventing states crafted for a different token from being accepted. Additionally, a specific set of invariants is enforced for security purposes. | ||
|
|
||
| ## Current Version Notes | ||
|
|
||
| In the current protocol version: | ||
|
|
||
| - Cross-chain operations require trust in the node to relay state correctly between chains. The node is responsible for submitting escrow initiation and finalization transactions on the appropriate chains. | ||
| - Full cross-chain enforcement (trustless bridging) is a planned future improvement. | ||
| - Each channel state supports exactly two ledgers: one home ledger and one non-home ledger. This is a V1-specific design constraint; future protocol versions MAY support additional ledger configurations. | ||
|
|
||
| --- | ||
|
|
||
| Previous: [Enforcement and Settlement](enforcement.md) | Next: [Interactions](interactions.md) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| # Cryptography | ||
|
|
||
| Previous: [Terminology](terminology.md) | Next: [State Model](state-model.md) | ||
|
|
||
| --- | ||
|
|
||
| This document defines how protocol objects are encoded, hashed, and signed. | ||
|
|
||
| All rules are described as algorithms and canonical procedures, independent of any specific programming language. | ||
|
|
||
| ## Purpose | ||
|
|
||
| Cryptography in the Nitrolite protocol serves three functions: | ||
|
|
||
| 1. **Authentication** — proving that a specific participant authorized a state update | ||
| 2. **Integrity** — ensuring that signed data has not been modified | ||
| 3. **Replay protection** — preventing previously signed states from being reused in unintended contexts | ||
|
|
||
| ## Cryptographic Algorithms | ||
|
|
||
| The protocol uses the following cryptographic primitives. | ||
|
|
||
| **Signature Algorithm** | ||
| ECDSA over the secp256k1 curve, producing a 65-byte signature (r, s, v). | ||
|
|
||
| **Hash Function** | ||
| Keccak-256, producing a 32-byte digest. | ||
|
|
||
| ## Canonical Encoding | ||
|
|
||
| Protocol objects that require signing MUST be encoded into a canonical binary representation before hashing. | ||
|
|
||
| The canonical encoding uses RLP encoding (`abi.encode` in Solidity) as defined in [this paper](https://doi.org/10.48550/arXiv.2009.13769) and by [Ethereum documentation](https://ethereum.org/developers/docs/data-structures-and-encoding/rlp/). This ensures deterministic byte sequences regardless of implementation language. | ||
|
|
||
|
dimast-x marked this conversation as resolved.
|
||
| ## Message Digest Construction | ||
|
|
||
| The digest of a signable payload is constructed as follows: | ||
|
|
||
| 1. Encode the object using canonical encoding | ||
| 2. Prepend the EIP-191 personal message prefix: the ASCII string `"\x19Ethereum Signed Message:\n"` followed by the decimal length of the encoded bytes, then the encoded bytes themselves | ||
| 3. Compute the Keccak-256 hash of the prefixed message | ||
|
|
||
| The resulting 32-byte digest is the value that is signed. | ||
|
Comment on lines
+35
to
+43
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a matter of fact, this is not the only supported format. The contract currently also supports raw ECDSA signatures. |
||
|
|
||
| ## ECDSA Signature Format | ||
|
|
||
| The raw ECDSA signature consists of: | ||
|
|
||
| | Field | Size | Description | | ||
| | ----- | -------- | ------------------------ | | ||
| | R | 32 bytes | ECDSA r component | | ||
| | S | 32 bytes | ECDSA s component | | ||
| | V | 1 byte | Recovery identifier | | ||
|
|
||
| The signer's address is recovered from the signature and the message digest. The protocol does not transmit the signer's public key or address alongside the signature. | ||
|
|
||
| ## Protocol Signature Envelope | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, this is not true for ALL signatures that ChannelHub validates. In fact, However, I am not sure whether this should be mentioned. |
||
|
|
||
| A protocol signature is a wrapper around the raw ECDSA signature that includes a validation mode prefix: | ||
|
|
||
| ``` | ||
| ProtocolSignature = ValidationMode || SignatureData | ||
| ``` | ||
|
|
||
| The first byte (`ValidationMode`) determines the validation method, which must map to a signature validator registered by the Node on the Smart Contract infrastructure. The remaining bytes (`SignatureData`) contain mode-specific data including the raw signature. | ||
|
|
||
| ## Signature Validation Modes | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should also be noted that this is extensible and NOT OWNER-ful (we as protocol developers do NOT have ability to change this), but rather Nodes control which validators are supported. Moreover, we should mention that both user and node agree on which validators they will use BEFORE creating a channel, and that the Node can NOT invalidate any validator. |
||
|
|
||
| The protocol supports multiple signature validation modes to allow different key types and authorization schemes. | ||
|
|
||
| **Default Mode (0x00)** | ||
| Standard ECDSA signature validation. SignatureData contains the raw ECDSA signature (R, S, V). The signer's address is recovered from the signature. The recovered address MUST match the expected participant address. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Signature can be either raw ECDSA or EIP-191 signature. |
||
|
|
||
| **Session Key Mode (0x01)** | ||
| Delegated signature validation. SignatureData contains a session key authorization and the session key's ECDSA signature over the state data, ABI-encoded as a tuple. The validator first verifies that the participant authorized the session key, then verifies that the session key produced a valid signature over the state. The session key authorization MUST be associated with the same address as the channel's user or node participant. The recovered session key address MUST match the address authorized by the participant. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ChannelHub also supports both raw ECDSA and EIP-191 signatures from Session Keys. |
||
|
|
||
| Session-key signatures are valid for both off-chain state advancement and on-chain enforcement, provided the session key validation mode is among the channel's approved signature validators. | ||
|
|
||
| ## Signable Object Classes | ||
|
dimast-x marked this conversation as resolved.
|
||
|
|
||
| The protocol defines a general signing framework that accommodates multiple classes of signable objects: | ||
|
|
||
| - **Channel Objects**: primarily, the state of a channel, but also a session key registration and challenger signature | ||
| - **Extension Objects**: primarily, the state of an extension entity (such as an application session), signed by the relevant session participants | ||
|
|
||
| Please note that channel and extension states are identified by a unique entity identifier and follows the same canonical encoding and digest construction rules. | ||
|
|
||
| This framework is extensible: future protocol extensions MAY introduce additional signable object classes without requiring changes to the core signing rules. | ||
|
|
||
| ## Session Key Authorization | ||
|
|
||
| A participant MAY delegate signing authority to a session key. | ||
|
|
||
| The authorization is constructed as follows: | ||
|
|
||
| 1. The participant signs a message containing: | ||
| - the session key address | ||
| - authorization metadata hash (`keccak256` over scope, expiration and possible other data) | ||
| 2. The authorization signature is produced using the participant's primary key | ||
| 3. The session key MAY then produce signatures on behalf of the participant within the authorized scope | ||
|
|
||
| Session key signatures MUST include the authorization proof alongside the session key signature. The authorization proof is canonically encoded as a tuple containing the session key authorization and the raw signature bytes. | ||
|
|
||
| ## Replay Protection | ||
|
|
||
| The protocol prevents replay attacks through the following mechanisms: | ||
|
|
||
| **Entity Identifier** | ||
| Each signable entity has a unique identifier derived from its definition. Signed states are bound to a specific entity, preventing a signature over one entity's state from being replayed against another. | ||
|
|
||
| **State Version** | ||
| Each state includes a monotonically increasing version number. The blockchain layer MUST reject states with a version less than or equal to the currently enforced version. | ||
|
|
||
| **Blockchain Identifier** | ||
| States include blockchain-specific identifiers preventing cross-chain replay. | ||
|
|
||
| **Smart Contract Version** | ||
| The channel entity identifier incorporates a contract version (currently as the first byte), preventing replay across different deployments. | ||
|
|
||
| --- | ||
|
|
||
| Previous: [Terminology](terminology.md) | Next: [State Model](state-model.md) | ||
Uh oh!
There was an error while loading. Please reload this page.