From aacbf3e0dd86932e1192e0b6d7b5cfc7d45b7afc Mon Sep 17 00:00:00 2001 From: EmelyanenkoK Date: Wed, 25 Oct 2023 15:14:19 +0300 Subject: [PATCH] Improve TVM Upgrade Documentation --- .../tvm-instructions/tvm-upgrade-2023-07.md | 184 ++++++++++-------- 1 file changed, 106 insertions(+), 78 deletions(-) diff --git a/docs/learn/tvm-instructions/tvm-upgrade-2023-07.md b/docs/learn/tvm-instructions/tvm-upgrade-2023-07.md index 84b6fd4e02..b06f6f17e8 100644 --- a/docs/learn/tvm-instructions/tvm-upgrade-2023-07.md +++ b/docs/learn/tvm-instructions/tvm-upgrade-2023-07.md @@ -4,7 +4,8 @@ Some operation codes may be removed, some gas prices are likely to be changed. It is expected that no new opcodes will be added to the list. ::: -This upgrade expected to be shipped in testnet by the end of the May and in mainnet by the end of the June. +This upgrade is in testnet and expected to be shipped to mainnet in 2023 Q4. + # c7 @@ -47,28 +48,35 @@ Inclusion of data on shardblocks may cause some data availability issues (due to it is not necessarily required (since any event/data can by proven using masterchain blocks) and thus we decided not to include it. # New opcodes -Rule of thumb when choosing gas cost on new opcodes is that it should not be less than normal (calculated from opcode length) and should spend no more than 20 ns per gas unit. +Rule of thumb when choosing gas cost on new opcodes is that it should not be less than normal (calculated from opcode length) and should take no more than 20 ns per gas unit. ## Opcodes to work with new c7 values -26 gas for each - -| xxxxxxxxxxxxxxxxxxxxxx
Fift syntax | xxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | -|:-|:-|:-| -| `MYCODE` | _`- c`_ | Retrieve code of smart-contract from c7 | -| `INCOMINGVALUE` | _`- t`_ | Retrieve value of incoming message from c7 | -| `STORAGEFEES` | _`- i`_ | Retrieve value of storage phase fees from c7 | -| `PREVBLOCKSINFOTUPLE` | _`- t`_ | Retrive PrevBlocksInfo: `[last_mc_blocks, prev_key_block]` from c7 | -| `PREVMCBLOCKS` | _`- t`_ | Retrive only `last_mc_blocks` | -| `PREVKEYBLOCK` | _`- t`_ | Retrieve only `prev_key_block` | -| `GLOBALID` | _`- i`_ | Retrieve `global_id` from 19 network config | +26 gas for each, except for `PREVMCBLOCKS` and `PREVKEYBLOCK` (34 gas). + +| xxxxxxxxxxxxxxxxxxxxxx
Fift syntax | xxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | +|:-|:-|:--------------------------------------------------------------------| +| `MYCODE` | _`- c`_ | Retrieves code of smart-contract from c7 | +| `INCOMINGVALUE` | _`- t`_ | Retrieves value of incoming message from c7 | +| `STORAGEFEES` | _`- i`_ | Retrieves value of storage phase fees from c7 | +| `PREVBLOCKSINFOTUPLE` | _`- t`_ | Retrives PrevBlocksInfo: `[last_mc_blocks, prev_key_block]` from c7 | +| `PREVMCBLOCKS` | _`- t`_ | Retrieves only `last_mc_blocks` | +| `PREVKEYBLOCK` | _`- t`_ | Retrieves only `prev_key_block` | +| `GLOBALID` | _`- i`_ | Retrieves `global_id` from 19 network config | ## Gas -| xxxxxxxxxxxxxx
Fift syntax | xxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | -|:-|:-|:-| -| `GASCONSUMED` | _`- g_c`_ | Returns gas consumed by VM so far
_26 gas_ | +| xxxxxxxxxxxxxx
Fift syntax | xxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | +|:-|:-|:-----------------------------------------------------------------------------| +| `GASCONSUMED` | _`- g_c`_ | Returns gas consumed by VM so far (including this instruction).
_26 gas_ | ## Arithmetics +New variants of [the division opcode](https://docs.ton.org/learn/tvm-instructions/instructions#52-division) (`A9mscdf`) are added: +`d=0` takes one additional integer from stack and adds it to the intermediate value before division/rshift. These operations return both the quotient and the remainder (just like `d=3`). + +Quiet variants are also available (e.g. `QMULADDDIVMOD` or `QUIET MULADDDIVMOD`). + +If return values don't fit into 257-bit integers or the divider is zero, non-quiet operation throws an integer overflow exception. Quiet operations return `NaN` instead of the value that doesn't fit (two `NaN`s if the divider is zero). + Gas cost is equal to 10 plus opcode length: 26 for most opcodes, +8 for `LSHIFT#`/`RSHIFT#`, +8 for quiet. | xxxxxxxxxxxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Stack | @@ -98,8 +106,6 @@ Gas cost is equal to 10 plus opcode length: 26 for most opcodes, +8 for `LSHIFT# | `y LSHIFT#ADDDIVMODR` | _`x w z - q=round((x*2^y+w)/z) r=(x*2^y+w)-zq`_ | | `y LSHIFT#ADDDIVMODC` | _`x w z - q=ceil((x*2^y+w)/z) r=(x*2^y+w)-zq`_ | -Quiet versions of these instructions are available: `QUIET ADDDIVMOD`, `QUIET 1 MULADDRSHIFTR#MOD` etc. - ## Stack operations Currently arguments of all stack operations are bounded by 256. That means that if stack become deeper than 256 it becomes difficult to manage deep stack elements. @@ -114,15 +120,18 @@ Currently only two hash operations are available in TVM: calculation of represen `HASHEXT[A][R]_(HASH)` family of operations is added: -| xxxxxxxxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | -|:-|:-|:-| -| `HASHEXT_(HASH)` | _`s_1 ... s_n n - h`_ | Calculate and return hash of the concatenation of slices (or builders) `s_1...s_n`. | -| `HASHEXTR_(HASH)` | _`s_n ... s_1 n - h`_ | Same thing, but arguments are given in reverse order. | -| `HASHEXTA_(HASH)` | _`b s_1 ... s_n n - b'`_ | Append the resulting hash to a builder `b` instead of pushing it to the stack. | -| `HASHEXTAR_(HASH)` | _`b s_n ... s_1 n - b'`_ | Arguments in reverse order, append hash to builder. | +| xxxxxxxxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | +|:-|:-|:--------------------------------------------------------------------------------------| +| `HASHEXT_(HASH)` | _`s_1 ... s_n n - h`_ | Calculates and returns hash of the concatenation of slices (or builders) `s_1...s_n`. | +| `HASHEXTR_(HASH)` | _`s_n ... s_1 n - h`_ | Same thing, but arguments are given in reverse order. | +| `HASHEXTA_(HASH)` | _`b s_1 ... s_n n - b'`_ | Appends the resulting hash to a builder `b` instead of pushing it to the stack. | +| `HASHEXTAR_(HASH)` | _`b s_n ... s_1 n - b'`_ | Arguments are given in reverse order, appends hash to builder. | Only the bits from root cells of `s_i` are used. -Note that each chunk `s_i` may contain non-integer number of bytes. However, the sum of bits of all chunks should be divisible by 8. + +Each chunk `s_i` may contain non-integer number of bytes. However, the sum of bits of all chunks should be divisible by 8. +Note that TON uses most-significant bit ordering, so when two slices with non-integer number of bytes are concatenated, bits from the first slice become most-significant bits. + Gas consumption depends on the number of hashed bytes and the chosen algorithm. Additional 1 gas unit is consumed per chunk. If `[A]` is not enabled, the result of hashing will be returned as an unsigned integer if fits 256 bits or tuple of ints otherwise. @@ -131,19 +140,21 @@ The following algorithms are available: - `SHA256` - openssl implementation, 1/33 gas per byte, hash is 256 bits. - `SHA512` - openssl implementation, 1/16 gas per byte, hash is 512 bits. - `BLAKE2B` - openssl implementation, 1/19 gas per byte, hash is 512 bits. -- `KECCAK256` - [ethereum compatible implementation](http://keccak.noekeon.org/) , 1/11 gas per byte, hash is 256 bits. -- `KECCAK512` - [ethereum compatible implementation](http://keccak.noekeon.org/) , 1/6 gas per byte, hash is 512 bits. +- `KECCAK256` - [ethereum compatible implementation](http://keccak.noekeon.org/), 1/11 gas per byte, hash is 256 bits. +- `KECCAK512` - [ethereum compatible implementation](http://keccak.noekeon.org/), 1/6 gas per byte, hash is 512 bits. + +Gas usage is rounded down. ## Crypto Currently the only cryptographic algorithm available is `CHKSIGN`: check the Ed25519-signature of a hash `h` for a public key `k`. -For compatibility with prev generation blockchains such as Bitcoin and Ethereum we need `secp256k1` signature checking algo. -For modern cryptographic algorithms the bare minimum is curve addition and multiplication. -For compatibility with Ethereum 2.0 PoS and some other modern cryptography we need BLS-signature scheme on bls12-381 curve. -For some secure hardware secp256r1 == P256 == prime256v1 is needed. +- For compatibility with prev generation blockchains such as Bitcoin and Ethereum we also need checking `secp256k1` signatures. +- For modern cryptographic algorithms the bare minimum is curve addition and multiplication. +- For compatibility with Ethereum 2.0 PoS and some other modern cryptography we need BLS-signature scheme on bls12-381 curve. +- For some secure hardware secp256r1 == P256 == prime256v1 is needed. ### secp256k1 -Bitcoin/ethereum signatures. Uses libsecp256k1 implementation (https://github.com/bitcoin-core/secp256k1). +Bitcoin/ethereum signatures. Uses [libsecp256k1 implementation](https://github.com/bitcoin-core/secp256k1). | xxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | |:-|:-|:-| @@ -161,7 +172,7 @@ Uses OpenSSL implementation. Interface is similar to `CHKSIGNS`/`CHKSIGNU`. Comp ### Ristretto Extended docs are [here](https://ristretto.group/). In short, Curve25519 was developed with performance in mind, however it exhibits symmetry due to which group elements have multiple representations. Simpler protocols such as Schnorr signatures or Diffie-Hellman apply tricks at the protocol level to mitigate some issues, but break key derivation and key blinding schemes. And those tricks do not scale to more complex protocols such as Bulletproofs. Ristretto is an arithmetic abstraction over Curve25519 such that each group element corresponds to a unique point, which is the requirement for most cryptographic protocols. Ristretto is essentially a compression/decompression protocol for Curve25519 that offers the required arithmetic abstraction. As a result, crypto protocols are easy to write correctly, while benefiting from the high performance of Curve25519. -Ristretto operation allow calculating curve operations on Curve25519 (the reverse is not true), thus we can consider that we add both Ristretto and Curve25519 curve operation in one step. +Ristretto operations allow calculating curve operations on Curve25519 (the reverse is not true), thus we can consider that we add both Ristretto and Curve25519 curve operation in one step. [libsodium](https://github.com/jedisct1/libsodium/) implementation is used. @@ -169,20 +180,20 @@ All ristretto-255 points are represented in TVM as 256-bit unsigned integers. Non-quiet operations throw `range_chk` if arguments are not valid encoded points. Zero point is represented as integer `0`. -| xxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | -|:-|:-|:-| -| `RIST255_FROMHASH` | _`h1 h2 - x`_ | Deterministically generate a valid point `x` from a 512-bit hash (given as two 256-bit integers)
_626 gas_ | -| `RIST255_VALIDATE` | _`x -`_ | Check that integer `x` is a valid representation of some curve point. Throw `range_chk` on error.
_226 gas_ | -| `RIST255_ADD` | _`x y - x+y`_ | Addition of two points on a curve
_626 gas_ | -| `RIST255_SUB` | _`x y - x-y`_ | Subtraction of two points on curve
_626 gas_ | -| `RIST255_MUL` | _`x n - x*n`_ | Multiply point `x` by a scalar `n`.
_2026 gas_ | -| `RIST255_MULBASE` | _`n - g*n`_ | Multiply the generator point `g` by a scalar `n`.
_776 gas_ | -| `RIST255_PUSHL` | _`- l`_ | Push integer `l=2^252+27742317777372353535851937790883648493`, which is the order of the group.
_26 gas_ | -| `RIST255_QVALIDATE` | _`x - 0 or -1`_ | Quiet version of `RIST255_VALIDATE`.
_234 gas_ | -| `RIST255_QADD` | _`x y - 0 or x+y -1`_ | Quiet version of `RIST255_ADD`.
_634 gas_ | -| `RIST255_QSUB` | _`x y - 0 or x-y -1`_ | Quiet version of `RIST255_SUB`.
_634 gas_ | -| `RIST255_QMUL` | _`x n - 0 or x*n -1`_ | Quiet version of `RIST255_MUL`.
_2034 gas_ | -| `RIST255_QMULBASE` | _`n - 0 or g*n -1`_ | Quiet version of `RIST255_MULBASE`.
_784 gas_ | +| xxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | +|:-|:-|:------------------------------------------------------------------------------------------------------------------| +| `RIST255_FROMHASH` | _`h1 h2 - x`_ | Deterministically generates a valid point `x` from a 512-bit hash (given as two 256-bit integers).
_626 gas_ | +| `RIST255_VALIDATE` | _`x -`_ | Checks that integer `x` is a valid representation of some curve point. Throws `range_chk` on error.
_226 gas_ | +| `RIST255_ADD` | _`x y - x+y`_ | Addition of two points on a curve.
_626 gas_ | +| `RIST255_SUB` | _`x y - x-y`_ | Subtraction of two points on curve.
_626 gas_ | +| `RIST255_MUL` | _`x n - x*n`_ | Multiplies point `x` by a scalar `n`.
Any `n` is valid, including negative.
_2026 gas_ | +| `RIST255_MULBASE` | _`n - g*n`_ | Multiplies the generator point `g` by a scalar `n`.
Any `n` is valid, including negative.
_776 gas_ | +| `RIST255_PUSHL` | _`- l`_ | Pushes integer `l=2^252+27742317777372353535851937790883648493`, which is the order of the group.
_26 gas_ | +| `RIST255_QVALIDATE` | _`x - 0 or -1`_ | Quiet version of `RIST255_VALIDATE`.
_234 gas_ | +| `RIST255_QADD` | _`x y - 0 or x+y -1`_ | Quiet version of `RIST255_ADD`.
_634 gas_ | +| `RIST255_QSUB` | _`x y - 0 or x-y -1`_ | Quiet version of `RIST255_SUB`.
_634 gas_ | +| `RIST255_QMUL` | _`x n - 0 or x*n -1`_ | Quiet version of `RIST255_MUL`.
_2034 gas_ | +| `RIST255_QMULBASE` | _`n - 0 or g*n -1`_ | Quiet version of `RIST255_MULBASE`.
_784 gas_ | ### BLS12-381 Operations on a pairing friendly BLS12-381 curve. [BLST](https://github.com/supranational/blst) implementation is used. Also, ops for BLS signature scheme which is based on this curve. @@ -194,41 +205,58 @@ BLS values are represented in TVM in the following way: - Elements of field FP2: 96-byte slice. - Messages: slice. Number of bits should be divisible by 8. -| xxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | -|:-|:-|:-| -| `BLS_VERIFY` | _`pk msg sgn - bool`_ | Check BLS signature, return true on success.
_61000 gas_ | -| `BLS_AGGREGATE` | _`sig_1 ... sig_n n - sig`_ | Aggregate signatures. `n>0`.
_`gas=n*4350-2650`_ | -| `BLS_FASTAGGREGATEVERIFY`- | _`pk_1 ... pk_n msg sig - bool`_ | Check aggregated BLS signature for keys `pk_1...pk_n` and message `msg`. `n>0`.
_`gas=58000+n*3000`_ | -| `BLS_AGGREGATEVERIFY` | _`pk_1 msg_1 ... pk_n msg_n n sgn - bool`_ | Check aggregated BLS signature for kay-message pairs `pk_1 msg_1...pk_n msg_n`. `n>0`.
_`gas=38500+n*22500`_ | -| `BLS_G1_ADD` | _`x y - x+y`_ | Addition on G1.
_3900 gas_ | -| `BLS_G1_SUB` | _`x y - x-y`_ | Subtraction on G1.
_3900 gas_ | -| `BLS_G1_NEG` | _`x - -x`_ | Negation on G1.
_750 gas_ | -| `BLS_G1_MUL` | _`x s - x*s`_ | Multiply G1 point `x` by scalar `s`.
_5200 gas_ | -| `BLS_G1_MULTIEXP` | _`x_1 s_1 ... x_n s_n - x_1*s_1+...+x_n*s_n`_ | Calculate `x_1*s_1+...+x_n*s_n` for G1 points `x_i` and scalars `n_i`.
_`gas=11409+n*630+n/floor(max(log2(n),4))*8820`_ | -| `BLS_G1_ZERO` | _`- zero`_ | Push zero point in G1.
_34 gas_ | -| `BLS_MAP_TO_G1` | _`f - x`_ | Convert FP element `f` to a G1 point.
_2350 gas_ | -| `BLS_G1_INGROUP` | _`x - bool`_ | Check that slice `x` represents a valid element of G1.
_2950 gas_ | -| `BLS_G1_ISZERO` | _`x - bool`_ | Check that G1 point `x` is equal to zero.
_34 gas_ | -| `BLS_G2_ADD` | _`x y - x+y`_ | Addition on G2.
_6134 gas_ | -| `BLS_G2_SUB` | _`x y - x-y`_ | Subtraction on G2.
_6134 gas_ | -| `BLS_G2_NEG` | _`x - -x`_ | Negation on G2.
_1584 gas_ | -| `BLS_G2_MUL` | _`x s - x*s`_ | Multiply G2 point `x` by scalar `s`.
_10550 gas_ | -| `BLS_G2_MULTIEXP` | _`x_1 s_1 ... x_n s_n - x_1*s_1+...+x_n*s_n`_ | Calculate `x_1*s_1+...+x_n*s_n` for G2 points `x_i` and scalars `n_i`.
_`gas=30422+n*1280+n/floor(max(log2(n),4))*22840`_ | -| `BLS_G2_ZERO` | _`- zero`_ | Push zero point in G2.
_34 gas_ | -| `BLS_MAP_TO_G2` | _`f - x`_ | Convert FP2 element `f` to a G2 point.
_7950 gas_ | -| `BLS_G2_INGROUP` | _`x - bool`_ | Check that slice `x` represents a valid element of G2.
_4250 gas_ | -| `BLS_G2_ISZERO` | _`x - bool`_ | Check that G2 point `x` is equal to zero.
_34 gas_ | -| `BLS_PAIRING` | _`x_1 y_1 ... x_n y_n n - bool`_ | Given G1 points `x_i` and G2 points `y_i`, calculate and multiply pairings of `x_i,y_i`. Return true if the result is the multiplicative identity in FP12.
_`gas=20034+n*11800`_ | -| `BLS_PUSHR` | _`- r`_ | Push the order of G1 and G2 (approx. `2^255`).
_`gas=34`_ | +When input value is a point or a field element, the slice may have more than 48/96 bytes. In this case only the first 48/96 bytes are taken. If the slice has less bytes (or if message size is not divisible by 8), cell underflow exception is thrown. + +#### High-level operations +These are high-level operations for verifying BLS signatures. + +| xxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | +|:-|:-|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `BLS_VERIFY` | _`pk msg sgn - bool`_ | Checks BLS signature, return true on success, false otherwise.
_61034 gas_ | +| `BLS_AGGREGATE` | _`sig_1 ... sig_n n - sig`_ | Aggregates signatures. `n>0`. Throw exception if `n=0` or if some `sig_i` is not a valid signature.
_`gas=n*4350-2616`_ | +| `BLS_FASTAGGREGATEVERIFY`- | _`pk_1 ... pk_n n msg sig - bool`_ | Checks aggregated BLS signature for keys `pk_1...pk_n` and message `msg`. Return true on success, false otherwise. Return false if `n=0`.
_`gas=58034+n*3000`_ | +| `BLS_AGGREGATEVERIFY` | _`pk_1 msg_1 ... pk_n msg_n n sgn - bool`_ | Checks aggregated BLS signature for key-message pairs `pk_1 msg_1...pk_n msg_n`. Return true on success, false otherwise. Return false if `n=0`.
_`gas=38534+n*22500`_ | + +`VERIFY` instructions don't throw exception on invalid signatures and public keys (except for cell underflow exceptions), they return false instead. + +#### Low-level operations +These are arithmetic operations on group elements. + +| xxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | +|:-|:-|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `BLS_G1_ADD` | _`x y - x+y`_ | Addition on G1.
_3934 gas_ | +| `BLS_G1_SUB` | _`x y - x-y`_ | Subtraction on G1.
_3934 gas_ | +| `BLS_G1_NEG` | _`x - -x`_ | Negation on G1.
_784 gas_ | +| `BLS_G1_MUL` | _`x s - x*s`_ | Multiplies G1 point `x` by scalar `s`.
Any `s` is valid, including negative.
_5234 gas_ | +| `BLS_G1_MULTIEXP` | _`x_1 s_1 ... x_n s_n n - x_1*s_1+...+x_n*s_n`_ | Calculates `x_1*s_1+...+x_n*s_n` for G1 points `x_i` and scalars `s_i`. Returns zero point if `n=0`.
Any `s_i` is valid, including negative.
_`gas=11409+n*630+n/floor(max(log2(n),4))*8820`_ | +| `BLS_G1_ZERO` | _`- zero`_ | Pushes zero point in G1.
_34 gas_ | +| `BLS_MAP_TO_G1` | _`f - x`_ | Converts FP element `f` to a G1 point.
_2384 gas_ | +| `BLS_G1_INGROUP` | _`x - bool`_ | Checks that slice `x` represents a valid element of G1.
_2984 gas_ | +| `BLS_G1_ISZERO` | _`x - bool`_ | Checks that G1 point `x` is equal to zero.
_34 gas_ | +| `BLS_G2_ADD` | _`x y - x+y`_ | Addition on G2.
_6134 gas_ | +| `BLS_G2_SUB` | _`x y - x-y`_ | Subtraction on G2.
_6134 gas_ | +| `BLS_G2_NEG` | _`x - -x`_ | Negation on G2.
_1584 gas_ | +| `BLS_G2_MUL` | _`x s - x*s`_ | Multiplies G2 point `x` by scalar `s`.
Any `s` is valid, including negative.
_10584 gas_ | +| `BLS_G2_MULTIEXP` | _`x_1 s_1 ... x_n s_n n - x_1*s_1+...+x_n*s_n`_ | Calculates `x_1*s_1+...+x_n*s_n` for G2 points `x_i` and scalars `s_i`. Returns zero point if `n=0`.
Any `s_i` is valid, including negative.
_`gas=30422+n*1280+n/floor(max(log2(n),4))*22840`_ | +| `BLS_G2_ZERO` | _`- zero`_ | Pushes zero point in G2.
_34 gas_ | +| `BLS_MAP_TO_G2` | _`f - x`_ | Converts FP2 element `f` to a G2 point.
_7984 gas_ | +| `BLS_G2_INGROUP` | _`x - bool`_ | Checks that slice `x` represents a valid element of G2.
_4284 gas_ | +| `BLS_G2_ISZERO` | _`x - bool`_ | Checks that G2 point `x` is equal to zero.
_34 gas_ | +| `BLS_PAIRING` | _`x_1 y_1 ... x_n y_n n - bool`_ | Given G1 points `x_i` and G2 points `y_i`, calculates and multiply pairings of `x_i,y_i`. Returns true if the result is the multiplicative identity in FP12, false otherwise. Returns false if `n=0`.
_`gas=20034+n*11800`_ | +| `BLS_PUSHR` | _`- r`_ | Pushes the order of G1 and G2 (approx. `2^255`).
_34 gas_ | + +`INGROUP`, `ISZERO` don't throw exception on invalid points (except for cell underflow exceptions), they return false instead. + +Other arithmetic operations throw exception on invalid curve points. Note that they don't check whether given curve points belong to group G1/G2. Use `INGROUP` instruction to check this. ## RUNVM Currently there is no way for code in TVM to call external untrusted code "in sandbox". In other words, external code always can irreversibly update code, data of contract, or set actions (such as sending all money). `RUNVM` instruction allows to spawn an independent VM instance, run desired code and get needed data (stack, registers, gas consumption etc) without risks of polluting caller's state. Running arbitrary code in a safe way may be useful for [v4-style plugins](/participate/wallets/contracts#wallet-v4), Tact's `init` style subcontract calculation etc. -| xxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | -|:-|:-|:-| -| `flags RUNVM` | _`x_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c]`_ | Run child VM with code `code` and stack `x_1...x_n`. Return the resulting stack `x'_1...x'_m` and exitcode.
Other arguments and return values are enabled by flags, see below. | -| `RUNVMX` | _`x_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] flags - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c]`_ | Same thing. but pop flags from stack. | +| xxxxxxxxxxxxx
Fift syntax | xxxxxxxxxxxxxxxxx
Stack | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Description | +|:-|:-|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `flags RUNVM` | _`x_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c]`_ | Runs child VM with code `code` and stack `x_1...x_n`. Returns the resulting stack `x'_1...x'_m` and exitcode.
Other arguments and return values are enabled by flags, see below. | +| `RUNVMX` | _`x_1 ... x_n n code [r] [c4] [c7] [g_l] [g_m] flags - x'_1 ... x'_m exitcode [data'] [c4'] [c5] [g_c]`_ | Same thing, but pops flags from stack. | Flags are similar to `runvmx` in fift: - `+1`: set c3 to code @@ -250,4 +278,4 @@ Gas cost: Currently it is difficult to calculate cost of sending message in contract (which leads to some approximations like in [jettons](https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-wallet.fc#L94)) and impossible to bounce request back if action phase is incorrect. It is also impossible to accurately subtract from incoming message sum of "constant fee for contract logic" and "gas expenses". - `SENDMSG` takes a cell and mode as input. Creates an output action and returns a fee for creating a message. Mode has the same effect as in the case of SENDRAWMSG. Additionally `+1024` means - do not create an action, only estimate fee. Other modes affect the fee calculation as follows: `+64` substitutes the entire balance of the incoming message as an outcoming value (slightly inaccurate, gas expenses that cannot be estimated before the computation is completed are not taken into account), `+128` substitutes the value of the entire balance of the contract before the start of the computation phase (slightly inaccurate, since gas expenses that cannot be estimated before the completion of the computation phase are not taken into account). -- `SENDRAWMSG`,`RAWRESERVE`,`SETLIBRARY` - `+16` flag is added, that means in the case of action fail - bounce transaction. Won't work if `+2` is used +- `SENDRAWMSG`, `RAWRESERVE`, `SETLIBCODE`, `CHANGELIB` - `+16` flag is added, that means in the case of action fail - bounce transaction. No effect if `+2` is used.