LIP: 0009 Title: Mitigate transaction replay on different chains Author: Manu Nelamane Siddalingegowda <email@example.com> Iker Alustiza <firstname.lastname@example.org> Discussions-To: https://research.lisk.io/t/mitigate-transaction-replay-on-different-chains/ Status: Draft Type: Standards Track Created: 2018-10-16 Updated: 2019-10-08
This LIP proposes to mitigate transaction replay on different chains by introducing a network identifier as a constitutive component of the signature of a transaction.
This LIP is licensed under the Creative Commons Zero 1.0 Universal.
Currently, transactions included in a blockchain on the Lisk platform can be replayed on other chains. For example, transactions sent on Testnet can be replayed on Mainnet, and the problem is likely to be exacerbated by the introduction of sidechains into this system. Current mitigation methods include (1) discouraging passphrase reuse across blockchains, and (2) encouraging registration of distinct second passphrases on distinct blockchains in situations where (1) is not feasible. However, one of the touted advantages of the Lisk platform is the ability to reuse passphrases on multiple blockchains, including the mainchain and sidechains, which conflicts with this strategy.
This LIP proposes to include a network identifier as a constitutive component of the signature of a transaction. This network identifier will be a hash of the concatenation of the blockchain’s nethash and a community identifier. The combination of these two components is intended to be unique and honest actors should conform to that requirement.
This proposal avoids transaction replay attacks from any existing blockchain to Lisk Mainnet or Testnet (and between each other). Adding the network identifier in the signature function will make the signature only valid for the specific network.
Moreover, in an ecosystem with sidechains implemented, each sidechain will have a unique network identifier to mitigate transaction replays across different chains. However, the situation will be more complex in this case since a malicious sidechain developer could copy the unique identifier from Mainnet or another sidechain and try to replay a transaction from its own sidechain on that original chain. The sidechain user, who calls the signature function, should check what will be exactly signed in the transaction object, including the network identifier. Note that the question of which properties are present on the serialized object that is used as the input for this function is different to the question of what information is transmitted over a network or stored in a database, where this identifier may be omitted for reasons of efficiency/scalability.
With a general and well defined signature process for the whole Lisk ecosystem, we could (strongly) recommend that sidechains use the functions implemented in Lisk Elements (or at least functions that meet this specification), removing the opportunity for a sidechain developer to provide a malicious signature function. Users (or third party clients) would be free to use Lisk Elements (or equivalent third-party tools) directly when signing transaction objects, and their suspicions should be raised if the sidechain protocol does not allow this.
As introduced in the previous section, the network identifier will be constructed as follows:
network identifier = H(nethash + community identifier)
H()- The cryptographic hash function SHA-256.
nethash- The UTF-8 encoded string containing the hexadecimal representation of the SHA-256 hash of the genesis block of the relevant blockchain. For Lisk Mainnet and Testnet, the
nethashvalues are stored in the source code. In the case of sidechains’ nethash, we assume that Lisk Elements will provide a standard nethash calculating function. This way, sidechain users can generate this value by themselves and verify that the sidechain network identifier is the right one.
community identifier- The name of the relevant community as a string encoded in UTF-8 format. This identifier uniquely specifies the community supporting the relevant network. The community identifier associated with the Lisk Foundation and its supporters will be
Lisk. If a subset of the community decided to split the network, they could, for example, choose
LiskCashas their community identifier. In general, the community identifier field should be well documented and defined in the Lisk ecosystem (for example as in SLIP-0044) for every chain within it.
Note that the sum symbol “+” in the formula above stands for the string concatenation operator. In Appendix B below, one can find a simple example of the construction of a network identifier.
In order to implement the proposed change, the network identifier has to be included in first position of the byte array used as the input of the transaction signing process (note that the byte array used to generate the transaction ID remains unchanged). This will impact the following functions according to the current implementation:
Below, there are two illustrative examples of Testnet and Mainnet depicting how the network identifier will be generated at the point of various hard forks in the network according to what was proposed before.
TG0 = Testnet genesis nethash NI1 = H(TG0 + ‘Lisk’) NI2 = H(TG0 + ‘LiskCash’) TG0-------|----T1--------------------Lisk------------> NI1 | |--------------T2---------Liskcash---------> NI2
The above illustration shows a possible scenario of hard forks and how the proposal will mitigate transaction replay attacks. As one can observe, we start with a single network which eventually splits into two networks with two different network identifiers (
NI2). Assume we have a hard fork since a minority of the community decided to fork the network identified by
NI1 resulting in
NI2. The network identifiers of the example were generated using the same nethash (
TG0). When a minority of the community decided to split the network with a hard fork (i.e.,
NI2), they defined a new community identifier (e.g.
LiskCash) for their fork. Since the new network shares history with the old network, the network identifier for the new network should be derived from the original nethash.
Assume now we have a transaction
NI1. An attacker tries to replay the transaction
T1 from network
NI1 over network
NI2. This transaction will be rejected as the signature of the transaction is unique to network
NI1. More precisely, the distinct community identifier for
NI2 yield a distinct network identifier, resulting in distinct data being signed as part of the transaction-signing process. The same would happen if the attacker tried to replay a transaction
T2 from network
NI2 over network
MG0 = Mainnet genesis nethash TG0 = Testnet genesis nethash MNI = H(MG0 + 'Lisk') TNI = H(TG0 + 'Lisk') TG0-------------T1------------------------------> TNI MG0------------------------------T2-------------> MNI
The above illustration demonstrates how the proposal will avoid transaction replay attacks across networks with different genesis blocks (Testnet, Mainnet). As it can be observed, we have two networks, Testnet and Mainnet, with different nethashes (
MG0) resulting in two different network identifiers (
Assume we have a transaction
T1 from network
TNI and a transaction
MNI. When an attacker tries to replay transaction
T1 from network
TNI over network
MNI, the transaction will be rejected as the signature of
T1 is unique to the network
TNI. The same would happen if the user tried to replay transaction
T2 from network
MNI over network
This change will introduce a hard fork. After the change is implemented, transaction signatures will be fundamentally different. This means that transactions will be verified in a different way, and thus, nodes on the old protocol version will reject transactions that have been signed using the new protocol, and vice versa.
Example of the construction of a new network identifier in the original Lisk Mainnet supported by the Lisk Foundation:
- Community identifier =
- Hash function
With these parameters, the network identifier will be calculated as:
network_ID = SHA-256(NH + ‘Lisk’)= '9ee11e9df416b18bf69dbd1a920442e08c6ca319e69926bc843a561782ca17ee'.