github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/docs/spec/_ics/ics-030-signed-messages.md (about)

     1  # ICS 030: Cosmos Signed Messages
     2  
     3  >TODO: Replace with valid ICS number and possibly move to new location.
     4  
     5  * [Changelog](#changelog)
     6  * [Abstract](#abstract)
     7  * [Preliminary](#preliminary)
     8  * [Specification](#specification)
     9  * [Future Adaptations](#future-adaptations)
    10  * [API](#api)
    11  * [References](#references)
    12  
    13  ## Status
    14  
    15  Proposed.
    16  
    17  ## Changelog
    18  
    19  ## Abstract
    20  
    21  Having the ability to sign messages off-chain has proven to be a fundamental aspect
    22  of nearly any blockchain. The notion of signing messages off-chain has many 
    23  added benefits such as saving on computational costs and reducing transaction
    24  throughput and overhead. Within the context of the Cosmos, some of the major
    25  applications of signing such data includes, but is not limited to, providing a
    26  cryptographic secure and verifiable means of proving validator identity and
    27  possibly associating it with some other framework or organization. In addition,
    28  having the ability to sign Cosmos messages with a Ledger or similar HSM device.
    29  
    30  A standardized protocol for hashing, signing, and verifying messages that can be
    31  implemented by the Cosmos SDK and other third-party organizations is needed. Such a
    32  standardized protocol subscribes to the following:
    33  
    34  * Contains a specification of human-readable and machine-verifiable typed structured data
    35  * Contains a framework for deterministic and injective encoding of structured data
    36  * Utilizes cryptographic secure hashing and signing algorithms
    37  * A framework for supporting extensions and domain separation
    38  * Is invulnerable to chosen ciphertext attacks
    39  * Has protection against potentially signing transactions a user did not intend to
    40  
    41  This specification is only concerned with the rationale and the standardized
    42  implementation of Cosmos signed messages. It does **not** concern itself with the
    43  concept of replay attacks as that will be left up to the higher-level application
    44  implementation. If you view signed messages in the means of authorizing some
    45  action or data, then such an application would have to either treat this as 
    46  idempotent or have mechanisms in place to reject known signed messages.
    47  
    48  ## Preliminary
    49  
    50  The Cosmos message signing protocol will be parameterized with a cryptographic
    51  secure hashing algorithm `SHA-256` and a signing algorithm `S` that contains 
    52  the operations `sign` and `verify` which provide a digital signature over a set
    53  of bytes and verification of a signature respectively.
    54  
    55  Note, our goal here is not to provide context and reasoning about why necessarily
    56  these algorithms were chosen apart from the fact they are the defacto algorithms
    57  used in Tendermint and the Cosmos SDK and that they satisfy our needs for such
    58  cryptographic algorithms such as having resistance to collision and second
    59  pre-image attacks, as well as being [deterministic](https://en.wikipedia.org/wiki/Hash_function#Determinism) and [uniform](https://en.wikipedia.org/wiki/Hash_function#Uniformity).
    60  
    61  ## Specification
    62  
    63  Tendermint has a well established protocol for signing messages using a canonical
    64  JSON representation as defined [here](https://github.com/tendermint/tendermint/blob/master/types/canonical.go).
    65  
    66  An example of such a canonical JSON structure is Tendermint's vote structure:
    67  
    68  ```go
    69  type CanonicalJSONVote struct {
    70      ChainID   string               `json:"@chain_id"`
    71      Type      string               `json:"@type"`
    72      BlockID   CanonicalJSONBlockID `json:"block_id"`
    73      Height    int64                `json:"height"`
    74      Round     int                  `json:"round"`
    75      Timestamp string               `json:"timestamp"`
    76      VoteType  byte                 `json:"type"`
    77  }
    78  ```
    79  
    80  With such canonical JSON structures, the specification requires that they include
    81  meta fields: `@chain_id` and `@type`. These meta fields are reserved and must be
    82  included. They are both of type `string`. In addition, fields must be ordered
    83  in lexicographically ascending order.
    84  
    85  For the purposes of signing Cosmos messages, the `@chain_id` field must correspond
    86  to the Cosmos chain identifier. The user-agent should **refuse** signing if the
    87  `@chain_id` field does not match the currently active chain! The `@type` field
    88  must equal the constant `"message"`. The `@type` field corresponds to the type of 
    89  structure the user will be signing in an application. For now, a user is only
    90  allowed to sign bytes of valid ASCII text ([see here](https://github.com/tendermint/tendermint/blob/master/libs/common/string.go#L61-L74)).
    91  However, this will change and evolve to support additional application-specific
    92  structures that are human-readable and machine-verifiable ([see Future Adaptations](#futureadaptations)).
    93  
    94  Thus, we can have a canonical JSON structure for signing Cosmos messages using
    95  the [JSON schema](http://json-schema.org/) specification as such:
    96  
    97  ```json
    98  {
    99    "$schema": "http://json-schema.org/draft-04/schema#",
   100    "$id": "cosmos/signing/typeData/schema",
   101    "title": "The Cosmos signed message typed data schema.",
   102    "type": "object",
   103    "properties": {
   104      "@chain_id": {
   105        "type": "string",
   106        "description": "The corresponding Cosmos chain identifier.",
   107        "minLength": 1
   108      },
   109      "@type": {
   110        "type": "string",
   111        "description": "The message type. It must be 'message'.",
   112        "enum": [
   113          "message"
   114        ]
   115      },
   116      "text": {
   117        "type": "string",
   118        "description": "The valid ASCII text to sign.",
   119        "pattern": "^[\\x20-\\x7E]+$",
   120        "minLength": 1
   121      }
   122    },
   123    "required": [
   124      "@chain_id",
   125      "@type",
   126      "text"
   127    ]
   128  }
   129  ```
   130  
   131  e.g.
   132  
   133  ```json
   134  {
   135    "@chain_id": "1",
   136    "@type": "message",
   137    "text": "Hello, you can identify me as XYZ on keybase."
   138  }
   139  ```
   140  
   141  ## Future Adaptations
   142  
   143  As applications can vary greatly in domain, it will be vital to support both
   144  domain separation and human-readable and machine-verifiable structures.
   145  
   146  Domain separation will allow for application developers to prevent collisions of
   147  otherwise identical structures. It should be designed to be unique per application
   148  use and should directly be used in the signature encoding itself.
   149  
   150  Human-readable and machine-verifiable structures will allow end users to sign
   151  more complex structures, apart from just string messages, and still be able to
   152  know exactly what they are signing (opposed to signing a bunch of arbitrary bytes).
   153  
   154  Thus, in the future, the Cosmos signing message specification will be expected
   155  to expand upon it's canonical JSON structure to include such functionality.
   156  
   157  
   158  ## API
   159  
   160  Application developers and designers should formalize a standard set of APIs that
   161  adhere to the following specification:
   162  
   163  -----
   164  
   165  ### **cosmosSignBytes**
   166  
   167  Params:
   168  
   169  * `data`: the Cosmos signed message canonical JSON structure
   170  * `address`: the Bech32 Cosmos account address to sign data with
   171  
   172  Returns:
   173  
   174  * `signature`: the Cosmos signature derived using signing algorithm `S`
   175  
   176  -----
   177  
   178  ### Examples
   179  
   180  Using the `secp256k1` as the DSA, `S`:
   181  
   182  ```javascript
   183  data = {
   184    "@chain_id": "1",
   185    "@type": "message",
   186    "text": "I hereby claim I am ABC on Keybase!"
   187  }
   188  
   189  cosmosSignBytes(data, "cosmos1pvsch6cddahhrn5e8ekw0us50dpnugwnlfngt3")
   190  > "0x7fc4a495473045022100dec81a9820df0102381cdbf7e8b0f1e2cb64c58e0ecda1324543742e0388e41a02200df37905a6505c1b56a404e23b7473d2c0bc5bcda96771d2dda59df6ed2b98f8"
   191  ```
   192  
   193  ## References