**[1]** Daniel J. Bernstein, *Curve25519: New Diffie--Hellman Speed Records* (2006), in: M. Yung, Ye. Dodis, A. Kiayas et al, *Public Key Cryptography*, Lecture Notes in Computer Science 3958, pp. 207--228. Available at https://cr.yp.to/ecdh/curve25519-20060209.pdf. +[1] Daniel J. Bernstein, *Curve25519: New Diffie--Hellman Speed Records*... -**[2]** Daniel J. Bernstein, Niels Duif, Tanja Lange et al., *High-speed high-security signatures* (2012), *Journal of Cryptographic Engineering* 2 (2), pp. 77--89. Available at https://ed25519.cr.yp.to/ed25519-20110926.pdf. +[2] Daniel J. Bernstein, Niels Duif, Tanja Lange et al., *High-speed high-security signatures*... -**[3]** N. Durov, *Telegram Open Network*, 2017. +[3] N. Durov, *Telegram Open Network*, 2017. -**[4]** N. Durov, *Telegram Open Network Virtual Machine*, 2018. +[4] N. Durov, *Telegram Open Network Virtual Machine*, 2018. ## Footnotes -**1** As of August 2018, this document does not include a detailed description of serialized invalidity proofs, because they are likely to change significantly during the development of the validator software. Only the general design principles for consistency conditions and serialized invalidity proofs are discussed. [Back ↑](#introduction) +**1** As of August 2018, this document does not include a detailed description of serialized invalidity proofs, because they are likely to change significantly during the development of the validator software. Only the general design principles for consistency conditions and serialized invalidity proofs are discussed. [Back ↑](#ref-fn1) -**2** This is not included in the present version of this document, but will be provided in a separate appendix to a future revision. [Back ↑](#introduction) +**2** This is not included in the present version of this document, but will be provided in a separate appendix to a future revision. [Back ↑](#ref-fn2) -**3** Completely identical cells are often identified in memory and in disk storage; this is the reason why trees of cells are transparently transformed into DAGs of cells. From this perspective, a DAG is just a storage optimization of the underlying tree of cells, irrelevant for most considerations. [Back ↑](#1-1-1-tvm-cells) +**3** Completely identical cells are often identified in memory and in disk storage; this is the reason why trees of cells are transparently transformed into DAGs of cells. From this perspective, a DAG is just a storage optimization of the underlying tree of cells, irrelevant for most considerations. [Back ↑](#ref-fn3) -**4** Cf. [[4](#ref-4)], 3.3.3-4], where an example is given and explained, pending a more complete reference. [Back ↑](#1-1-1-tvm-cells) +**4** [[4](#ref-4), 3.3.3–4], where an example is given and explained, pending a more complete reference. [Back ↑](#ref-fn4) -**5** If there are no transactions related to an account, the corresponding virtual block is empty and is omitted in the shardchain block. [Back ↑](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state) +**5** If there are no transactions related to an account, the corresponding virtual block is empty and is omitted in the shardchain block. [Back ↑](#ref-fn5) -**6** Recall that TON Blockchain supports *dynamic* sharding, so the shard configuration may change from block to block because of shard merge and split events. Therefore, we cannot simply say that each shardchain corresponds to a fixed set of accountchains. [Back ↑](#1-2-1-the-infinite-sharding-paradigm-isp-applied-to-blockchain-block-and-state) +**6** Recall that TON Blockchain supports *dynamic* sharding, so the shard configuration may change from block to block because of shard merge and split events. Therefore, we cannot simply say that each shardchain corresponds to a fixed set of accountchains. [Back ↑](#ref-fn6) -**7** This condition applies if there is exactly one immediate antecessor (i.e., if a shardchain merge event did not occur immediately before the block in question); otherwise, this condition becomes more convoluted. [Back ↑](#1-2-3-interaction-with-other-blocks-and-the-outside-world-global-and-local-consistency-conditions) +**7** This condition applies if there is exactly one immediate antecessor (i.e., if a shardchain merge event did not occur immediately before the block in question); otherwise, this condition becomes more convoluted. [Back ↑](#ref-fn7) -**8** This example is a bit simplified since it does not take into account the presence of transit messages in InMsgDescr, which are not processed by any explicit transaction. [Back ↑](#1-3-8-example%3A-consistency-condition-for-inmsgdescr) +**8** This example is a bit simplified since it does not take into account the presence of transit messages in InMsgDescr, which are not processed by any explicit transaction. [Back ↑](#ref-fn8) -**9** It is interesting to note that this part of the work can be done almost automatically. [Back ↑](#1-3-12-witnesses-of-the-invalidity-of-a-block) +**9** It is interesting to note that this part of the work can be done almost automatically. [Back ↑](#ref-fn9) -**10** In order to express this condition correctly in the presence of dynamic sharding, one should fix some account $\xi$, and consider the latest blocks $S$ and $S'$ of the shardchains containing $\xi$ in the shard configurations of both $B$ and $B'$, since the shards containing $\xi$ might be different in $B$ and $B'$. [Back ↑](#1-5-1-total-state-defined-by-a-masterchain-block) +**10** In order to express this condition correctly in the presence of dynamic sharding, one should fix some account $\xi$, and consider the latest blocks $S$ and $S'$ of the shardchains containing $\xi$ in the shard configurations of both $B$ and $B'$, since the shards containing $\xi$ might be different in $B$ and $B'$. [Back ↑](#ref-fn10) -**11** Value-bearing messages with the `bounce` flag set will not be accepted by an uninitialized account, but will be "bounced" back. [Back ↑](#1-7-2-transferring-cryptocurrency-to-uninitialized-accounts) +**11** Value-bearing messages with the `bounce` flag set will not be accepted by an uninitialized account, but will be "bounced" back. [Back ↑](#ref-fn11) -**12** "Messages to nowhere" may have some special fields in their body indicating their destination outside the TON Blockchain—for instance, an account in some other blockchain, or an IP address and port—which may be interpreted by the third-party software appropriately. Such fields are ignored by the TON Blockchain. [Back ↑](#2-1-3-external-messages-with-no-source-or-destination-address) +**12** "Messages to nowhere" may have some special fields in their body indicating their destination outside the TON Blockchain—for instance, an account in some other blockchain, or an IP address and port—which may be interpreted by the third-party software appropriately. Such fields are ignored by the TON Blockchain. [Back ↑](#ref-fn12) -**13** The problem of bypassing possible validator censorship—which could happen, for instance, if all validators conspire not to include external messages sent to accounts belonging to some set of blacklisted accounts—is dealt with separately elsewhere. The main idea is that the validators may be forced to promise to include a message with a known hash in a future block, without knowing anything about the identity of the sender or the receiver; they will have to keep this promise afterwards when the message itself with pre-agreed hash is presented. [Back ↑](#2-1-3-external-messages-with-no-source-or-destination-address) +**13** The problem of bypassing possible validator censorship—which could happen, for instance, if all validators conspire not to include external messages sent to accounts belonging to some set of blacklisted accounts—is dealt with separately elsewhere. The main idea is that the validators may be forced to promise to include a message with a known hash in a future block, without knowing anything about the identity of the sender or the receiver; they will have to keep this promise afterwards when the message itself with pre-agreed hash is presented. [Back ↑](#ref-fn13) -**14** However, the internal routing process described in [2.1.11](#sp-hr-int-route) is applied immediately after that, which may further modify the transit address. [Back ↑](#2-1-4-transit-and-next-hop-addresses) +**14** However, the internal routing process described in [Internal routing](#2-1-11-internal-routing) is applied immediately after that, which may further modify the transit address. [Back ↑](#ref-fn14) -**15** When the addresses involved are of different lengths (e.g., because they belong to different workchains), one should consider only the first 96 bits of the addresses in the above formula. [Back ↑](#2-1-8-hamming-optimality-of-the-next-hop-address-algorithm) +**15** When the addresses involved are of different lengths (e.g., because they belong to different workchains), one should consider only the first 96 bits of the addresses in the above formula. [Back ↑](#ref-fn15) -**16** Instead of Hamming optimality, we might have considered the equivalent property of Kademlia optimality, written for the Kademlia (or weighted $L_1$) distance as given by $\|\xi-\eta\|_K:=\sum_i2^{-i}|\xi_i-\eta_i|$ instead of the Hamming distance. [Back ↑](#2-1-8-hamming-optimality-of-the-next-hop-address-algorithm) +**16** Instead of Hamming optimality, we might have considered the equivalent property of Kademlia optimality, written for the Kademlia (or weighted $L_1$) distance as given by $\|\xi-\eta\|_K:=\sum_i2^{-i}|\xi_i-\eta_i|$ instead of the Hamming distance. [Back ↑](#ref-fn16) -**17** Notice that the next-hop and internal-routing computations are still applied to such messages, since the current shardchain may be split before the message is processed. In this case, the new sub-shardchain containing the destination address will inherit the message. [Back ↑](#2-1-13-any-shard-is-a-neighbor-of-itself) +**17** Notice that the next-hop and internal-routing computations are still applied to such messages, since the current shardchain may be split before the message is processed. In this case, the new sub-shardchain containing the destination address will inherit the message. [Back ↑](#ref-fn17) -**18** We may define the (virtual) output queue of an account(chain) as the subset of the OutMsgQueue of the shard currently containing that account that consists of messages with transit addresses equal to the address of the account. [Back ↑](#2-1-14-hypercube-routing-and-the-isp) +**18** We may define the (virtual) output queue of an account(chain) as the subset of the OutMsgQueue of the shard currently containing that account that consists of messages with transit addresses equal to the address of the account. [Back ↑](#ref-fn18) -**19** In particular, if the hash of a recent block of a neighboring shardchain is not yet reflected in the latest masterchain block, its modifications to OutMsgQueue must not be taken into account. [Back ↑](#2-2-5-logical-time-monotonicity-importing-the-oldest-message-from-the-neighbors) +**19** In particular, if the hash of a recent block of a neighboring shardchain is not yet reflected in the latest masterchain block, its modifications to OutMsgQueue must not be taken into account. [Back ↑](#ref-fn19) -**20** This statement is not as trivial as it seems at first, because some of the shardchains involved may split or merge during the routing. A correct proof may be obtained by adopting the ISP perspective to HR as explained in [2.1.14](#2-1-14-hypercube-routing-and-the-isp) and observing that $m'$ will always be behind $m$, either in terms of the intermediate accountchain reached or, if they happen to be in the same accountchain, in terms of logical creation time. +**20** This statement is not as trivial as it seems at first, because some of the shardchains involved may split or merge during the routing. A correct proof may be obtained by adopting the ISP perspective to HR as explained in [Hypercube Routing and the ISP](#2-1-14-hypercube-routing-and-the-isp) and observing that $m'$ will always be behind $m$, either in terms of the intermediate accountchain reached or, if they happen to be in the same accountchain, in terms of logical creation time. [Back ↑](#ref-fn20) -**21** One must not only look up the key $\text{Hash}(m)$ in the InMsgDescr of these blocks, but also check the intermediate addresses in the envelope of the corresponding entry, if found. [Back ↑](#2-3-6-checking-whether-an-hr-message-has-already-been-delivered-via-hr-to-its-final-destination-or-an-intermediate-shardchain) +**21** One must not only look up the key $\text{Hash}(m)$ in the InMsgDescr of these blocks, but also check the intermediate addresses in the envelope of the corresponding entry, if found. [Back ↑](#ref-fn21) -**22** A description of an older version of TL may be found at https://core.telegram.org/mtproto/TL. Alternatively, an informal introduction to TL-B schemes may be found in [[4](#ref-4)]. [Back ↑](#3-1-1-some-standard-definitions) +**22** A description of an older version of TL may be found at https://core.telegram.org/mtproto/TL. Alternatively, an informal introduction to TL-B schemes may be found in [[4]](#references). [Back ↑](#ref-fn22) -**23** Address rewriting is a feature used to implement "anycast addresses" employed by the so-called large or global smart contracts (cf. [[3](#ref-3)]), which can have instances in several shardchains. When address rewriting is enabled, a message may be routed to and processed by a smart contract with an address coinciding with the destination address up to the first $d$ bits, where $d\leq 32$ is the "splitting depth" of the smart contract indicated in the `anycast.depth` field (cf. [2.1.6](#2-1-6-support-for-anycast-addresses)). Otherwise, the addresses must match exactly. [Back ↑](#3-1-4-internal-addresses) +**23** Address rewriting is a feature used to implement "anycast addresses" employed by the so-called large or global smart contracts (see [[3]](#references)), which can have instances in several shardchains. When address rewriting is enabled, a message may be routed to and processed by a smart contract with an address coinciding with the destination address up to the first $d$ bits, where $d\leq 32$ is the "splitting depth" of the smart contract indicated in the `anycast.depth` field ([Support for anycast addresses](#2-1-6-support-for-anycast-addresses)). Otherwise, the addresses must match exactly. [Back ↑](#ref-fn23) -**24** More precisely, the information from the `init` field of an inbound message is used either when the receiving account is uninitialized or frozen with the hash of StateInit equal to the one expected by the account, or when the receiving account is active, and its code or data is an external hash reference matching the hash of the code or data received in the StateInit of the message. [Back ↑](#3-1-9-code-and-data-portions-contained-in-a-message) +**24** More precisely, the information from the `init` field of an inbound message is used either when the receiving account is uninitialized or frozen with the hash of StateInit equal to the one expected by the account, or when the receiving account is active, and its code or data is an external hash reference matching the hash of the code or data received in the StateInit of the message. [Back ↑](#ref-fn24) -**25** Strictly speaking, InMsgDescr is the type of this structure; we deliberately use the same notation to describe the only instance of this type in a block. [Back ↑](#3-2-inbound-message-descriptors) +**25** Strictly speaking, InMsgDescr is the type of this structure; we deliberately use the same notation to describe the only instance of this type in a block. [Back ↑](#ref-fn25) -**26** Recall that a shardchain is considered a neighbor of itself. [Back ↑](#3-2-1-types-and-sources-of-inbound-messages) +**26** Recall that a shardchain is considered a neighbor of itself. [Back ↑](#ref-fn26) -**27** This situation is rare and occurs only after shardchain merge events. Normally the messages imported from the OutMsgQueue of the same shardchain have destinations inside this shardchain, and are processed accordingly instead of being re-queued. [Back ↑](#3-3-2-message-dequeueing-records) +**27** This situation is rare and occurs only after shardchain merge events. Normally the messages imported from the OutMsgQueue of the same shardchain have destinations inside this shardchain, and are processed accordingly instead of being re-queued. [Back ↑](#ref-fn27) -**28** For simplicity, we sometimes treat the masterchain as just another workchain with $\mathit{workchain\_id}=-1$. [Back ↑](#4-1-1-account-addresses) +**28** For simplicity, we sometimes treat the masterchain as just another workchain with $\mathit{workchain\_id}=-1$. [Back ↑](#ref-fn28) -**29** In fact, up to the first $d$ bits are replaced in such a way that each shard contains at most one instance of the large smart contract, and that shards $(w,s)$ with prefix $s$ of length $|s|\leq d$ contain exactly one instance. [Back ↑](#4-1-3-small-and-large-smart-contracts) +**29** In fact, up to the first $d$ bits are replaced in such a way that each shard contains at most one instance of the large smart contract, and that shards $(w,s)$ with prefix $s$ of length $|s|\leq d$ contain exactly one instance. [Back ↑](#ref-fn29) -**30** This scheme uses anonymous constructors and anonymous fields, both represented by an underscore `_`. [Back ↑](#4-1-6-account-description) +**30** This scheme uses anonymous constructors and anonymous fields, both represented by an underscore `_`. [Back ↑](#ref-fn30) -**31** In particular, if a user mistakenly sends some funds to a non-existent address in a bounceable message, the funds will not be wasted, but rather will be returned (bounced) back. Therefore, a user wallet application should set the bounce flag in all generated messages by default unless explicitly instructed otherwise. However, non-bounceable messages are indispensable in some situations (cf. 1.7.6). [Back ↑](#4-2-6-bouncing-inbound-messages-to-non-existent-accounts) +**31** In particular, if a user mistakenly sends some funds to a non-existent address in a bounceable message, the funds will not be wasted, but rather will be returned (bounced) back. Therefore, a user wallet application should set the bounce flag in all generated messages by default unless explicitly instructed otherwise. However, non-bounceable messages are indispensable in some situations ([Using non-bounceable messages](#1-7-6-using-non-bounceable-messages)). [Back ↑](#ref-fn31) -**32** A reference implementation of a TVM emulator running in a stripped-down version of TVM may be committed into the masterchain to be used when a disagreement between the validators on a specific run of TVM arises. In this way, flawed implementations of TVM may be detected. The reference implementation then serves as an authoritative source on the operational semantics of TVM. (Cf. [[2](#ref-2)] B.2) [Back ↑](#4-2-8-reasons-for-splitting-the-processing-into-computation-and-action-phases) +**32** A reference implementation of a TVM emulator running in a stripped-down version of TVM may be committed into the masterchain to be used when a disagreement between the validators on a specific run of TVM arises. In this way, flawed implementations of TVM may be detected. The reference implementation then serves as an authoritative source on the operational semantics of TVM. ([[2]](#references) B.2) [Back ↑](#ref-fn32) -**33** Notice that this record does not represent a change in the state of the account, because the transaction may still be aborted during the action phase. In that case, the new persistent data indirectly referenced by vm_final_state_hash will be discarded. [Back ↑](#4-3-7-valid-computing-phase) +**33** Notice that this record does not represent a change in the state of the account, because the transaction may still be aborted during the action phase. In that case, the new persistent data indirectly referenced by vm_final_state_hash will be discarded. [Back ↑](#ref-fn33) -**34** The most common way of creating shared libraries for TVM is to publish a reference to the root cell of the library in the masterchain. [Back ↑](#4-4-3-smart-contract-library-environment) +**34** The most common way of creating shared libraries for TVM is to publish a reference to the root cell of the library in the masterchain. [Back ↑](#ref-fn34) -**35** The persistent data of the smart contract need not be loaded in its entirety for this to occur. Instead the root is loaded, and TVM may load other cells by their references from the root only when they are accessed, thus providing a form of virtual memory. [Back ↑](#4-4-4-the-initial-state-of-tvm) +**35** The persistent data of the smart contract need not be loaded in its entirety for this to occur. Instead the root is loaded, and TVM may load other cells by their references from the root only when they are accessed, thus providing a form of virtual memory. [Back ↑](#ref-fn35) -**36** Both the global gas limit and the gas price are configurable parameters determined by the current state of the masterchain. [Back ↑](#4-4-4-the-initial-state-of-tvm) +**36** Both the global gas limit and the gas price are configurable parameters determined by the current state of the masterchain. [Back ↑](#ref-fn36) -**37** In principle, an experimental version of TON Blockchain might choose to keep only the hashes of the initial and final states of the shardchain. The Merkle update increases the block size, but it is handy for full nodes that want to keep and update their copy of the shardchain state. Otherwise, the full nodes would have to repeat all the computations contained in a block to compute the updated state of the shardchain by themselves. [Back ↑](#5-1-2-components-of-a-shardchain-block) +**37** In principle, an experimental version of TON Blockchain might choose to keep only the hashes of the initial and final states of the shardchain. The Merkle update increases the block size, but it is handy for full nodes that want to keep and update their copy of the shardchain state. Otherwise, the full nodes would have to repeat all the computations contained in a block to compute the updated state of the shardchain by themselves. [Back ↑](#ref-fn37) -**38** Notice that these "absent cells" are different from the library reference and external reference cells, which are kinds of exotic cells (cf. [[4, 3.1.7](#ref-4)]). Absent cells, by contrast, are introduced only for the purpose of serializing incomplete bags of cells, and can never be processed by TVM. [Back ↑](#5-3-6-serialization-of-one-cell-from-a-bag-of-cells) +**38** Notice that these "absent cells" are different from the library reference and external reference cells, which are kinds of exotic cells ([[4]](#references), 3.1.7). Absent cells, by contrast, are introduced only for the purpose of serializing incomplete bags of cells, and can never be processed by TVM. [Back ↑](#ref-fn38) -**39** Notice that exotic cells (with $s=1$) always have $b\geq8$, with the cell type encoded in the first eight data bits (cf. [[4, 3.1.7](#ref-4)]). [Back ↑](#5-3-6-serialization-of-one-cell-from-a-bag-of-cells) +**39** Notice that exotic cells (with $s=1$) always have $b\geq8$, with the cell type encoded in the first eight data bits ([[4]](#references), 3.1.7). [Back ↑](#ref-fn39) -**40** If the bag of cells is not complete, some of these cell references may refer to cells $c'$ absent from the bag of cells. In that case, special "absent cells" with $r=7$ are included into the bag of cells and are assigned some indices $j$. These indices are then used to represent references to absent cells. [Back ↑](#5-3-6-serialization-of-one-cell-from-a-bag-of-cells) +**40** If the bag of cells is not complete, some of these cell references may refer to cells $c'$ absent from the bag of cells. In that case, special "absent cells" with $r=7$ are included into the bag of cells and are assigned some indices $j$. These indices are then used to represent references to absent cells. [Back ↑](#ref-fn40) -**41** Arithmetic modulo $p$ for a modulus $p$ near a power of two can be implemented very efficiently. On the other hand, residues modulo $2^{255}-19$ can be represented by 255-bit integers. This is the reason this particular value of $p$ has been chosen by D. Bernstein. [Back ↑](#a-1-1-finite-fields) +**41** Arithmetic modulo $p$ for a modulus $p$ near a power of two can be implemented very efficiently. On the other hand, residues modulo $2^{255}-19$ can be represented by 255-bit integers. This is the reason this particular value of $p$ has been chosen by D. Bernstein. [Back ↑](#ref-fn41) -**42** Actually, D. Bernstein chose $A=486662$ because it is the smallest positive integer $A\equiv 2\pmod 4$ such that both the corresponding Montgomery curve ([31](#a-2-1-curve25519)) over $\mathbb{F}_p$ for $p=2^{255}-19$ and the quadratic twist of this curve have small cofactors. Such an arrangement avoids the necessity to check whether an $x$-coordinate $x_P\in\mathbb{F}_p$ of a point $P$ defines a point $(x_P,y_P)\in\mathbb{F}_p^2$ lying on the Montgomery curve itself or on its quadratic twist. [Back ↑](#a-2-1-curve25519) \ No newline at end of file +**42** Actually, D. Bernstein chose $A=486662$ because it is the smallest positive integer $A\equiv 2\pmod 4$ such that both the corresponding Montgomery curve ([31](#a-2-1-curve25519)) over $\mathbb{F}_p$ for $p=2^{255}-19$ and the quadratic twist of this curve have small cofactors. Such an arrangement avoids the necessity to check whether an $x$-coordinate $x_P\in\mathbb{F}_p$ of a point $P$ defines a point $(x_P,y_P)\in\mathbb{F}_p^2$ lying on the Montgomery curve itself or on its quadratic twist. [Back ↑](#ref-fn42) \ No newline at end of file