-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SIMD-0129: Alt_BN128 Syscalls - Simplified Error Code (#129)
* SIMD-0129: Alt_BN128 Syscalls - Simplified Error Code * rephrase backward compatibility * Update proposals/0129-alt-bn128-simplified-error-code.md Co-authored-by: samkim-crypto <skim13@cs.stanford.edu> * Update proposals/0129-alt-bn128-simplified-error-code.md Co-authored-by: samkim-crypto <skim13@cs.stanford.edu> * Update proposals/0129-alt-bn128-simplified-error-code.md Co-authored-by: samkim-crypto <skim13@cs.stanford.edu> * Update proposals/0129-alt-bn128-simplified-error-code.md Co-authored-by: samkim-crypto <skim13@cs.stanford.edu> --------- Co-authored-by: samkim-crypto <skim13@cs.stanford.edu>
- Loading branch information
1 parent
63053f1
commit 7eb5f99
Showing
1 changed file
with
211 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
--- | ||
simd: '0129' | ||
title: Alt_BN128 Syscalls - Simplified Error Code | ||
authors: | ||
- Emanuele Cesena | ||
category: Standard | ||
type: Core | ||
status: Draft | ||
created: 2024-03-19 | ||
feature: | ||
supersedes: | ||
superseded-by: | ||
extends: | ||
--- | ||
|
||
## Summary | ||
|
||
Simplify the return error code for the family of Alt_BN128 syscalls: | ||
`sol_alt_bn128_group_op`, `sol_alt_bn128_compression` and `sol_poseidon`. | ||
|
||
A single error code is sufficient, in line with all other syscalls. | ||
|
||
## Motivation | ||
|
||
Syscalls in Solana can return: | ||
|
||
- Success, e.g. represented in Rust as `Ok(0)` or `Ok(SUCCESS)` | ||
- Error to the program, e.g. represented in Rust as `Ok(1)` | ||
- Fatal error to the VM, aborting the transaction, e.g. represented in Rust | ||
as `Err(<something>)` | ||
|
||
Most syscalls only have a single error code returned to the program, i.e. `Ok(1)`. | ||
The family of Alt_BN128 syscalls, vice versa, has a richer set of error codes. | ||
|
||
This proposal aims to simplify the error value for these syscalls, in line with | ||
all the other syscalls, and simply return `Ok(1)` (in addition to fatal errors, | ||
that are left unchanged). | ||
|
||
We stress that multiple error codes cause a maintenance burden for the validators. | ||
Moreover, if two different implementation were to return different error codes, | ||
an attacker could exploit the different behavior to cause consensus failure. | ||
|
||
## Alternatives Considered | ||
|
||
Leave as is. | ||
|
||
## New Terminology | ||
|
||
n/a | ||
|
||
## Detailed Design | ||
|
||
### Syscall `sol_alt_bn128_group_op` | ||
|
||
The syscall [`sol_alt_bn128_group_op`](https://github.com/solana-labs/solana/pull/27961) | ||
computes operations on the Alt_BN128 curve, including point addition | ||
in G1, scalar multiplication in G1, and pairing. | ||
|
||
The syscall accepts the following inputs: | ||
|
||
- `group_op`: the operation to perform: | ||
|
||
- `0`: point add in G1 | ||
- `1`: (reserved for) point sub in G1 | ||
- `2`: scalar multiplication in G1 | ||
- `3`: pairing | ||
|
||
- `input`: the serialized inputs to the operation. | ||
|
||
Notes: | ||
|
||
- Input and output depend on the operation. In all cases they are serialized | ||
in standard big endian format. | ||
- Points and scalars must be validated. | ||
- Point sub in G1 is not implemented. The `group_op` value `1` is reserved. | ||
|
||
**Point add in G1** | ||
|
||
Inputs: 2 points in G1. | ||
|
||
Output: 1 point in G1. | ||
|
||
**Scalar multiplication in G1** | ||
|
||
Inputs: 1 point in G1, 1 scalar. | ||
|
||
Output: 1 point in G1. | ||
|
||
**Pairing** | ||
|
||
Inputs: 1 point in G1, 1 point in G2 | ||
|
||
Output: `1` if the pairing is 1, `0` otherwise. | ||
The output is serialized as a 256-bit big integer. | ||
|
||
**Fatal Errors.** | ||
|
||
- Validate `group_op` is `0`, `2`, or `3` (known operation). | ||
- Compute units | ||
- Memory mapping for input/output | ||
|
||
**Error Code(s).** | ||
|
||
Any error caused while computing the operation | ||
is returned as error code `1`, i.e. `Ok(1)` in Rust. | ||
|
||
This includes validating that the input has the valid length, | ||
the input points and scalars are valid, and the operation is successful. | ||
|
||
|
||
### Syscall `sol_alt_bn128_compression` | ||
|
||
The syscall [`sol_alt_bn128_compression`](https://github.com/solana-labs/solana/pull/32870) | ||
allows to compress or decompress points in G1 or G2 groups over the Alt_BN128 | ||
curve. | ||
|
||
The syscall accepts the following inputs: | ||
|
||
- `op`: the operation to perform: | ||
|
||
- `0`: G1 compress | ||
- `1`: G1 decompress | ||
- `2`: G2 compress | ||
- `3`: G2 decompress | ||
|
||
- `input`: the input point to compress / decompress, serialized in standard | ||
big endian format. | ||
|
||
The output is a point, serialized in standard big endian format. | ||
|
||
Note: for performance reasons, this syscall does NOT validate whether the | ||
input is actually an element of G1 or G2. | ||
The intent is to use this syscall in combination with `sol_alt_bn128_group_op`, | ||
that performs validation, and therefore not duplicate the expensive check. | ||
|
||
**Fatal Errors.** | ||
|
||
- Validate `op` is `0`, `1`, `2`, or `3` (known operation). | ||
- Compute units | ||
- Memory mapping for input/output | ||
|
||
**Error Code(s).** | ||
|
||
Any error caused while computing the compress or decompress operation | ||
is returned as error code `1`, i.e. `Ok(1)` in Rust. | ||
|
||
This includes validating that the input has the valid length, | ||
and decompression is successful. | ||
|
||
### Syscall `sol_poseidon` | ||
|
||
The syscall [`sol_poseidon`](https://github.com/solana-labs/solana/pull/32680) | ||
computes the Poseidon hash on an array of input values. | ||
|
||
The syscall accepts the following inputs: | ||
|
||
- `parameters`: `0` to represent the choice of the Alt_BN128 curve. | ||
- `endianness`: `0` for big endian input/output, `1` for little endian. | ||
- `vals_len`: number of input values to hash. Max supported 12 values. | ||
- `vals`: the input values to hash. In line with other hash syscalls, | ||
this is an array of buffers. For Poseidon, each buffer represents an element | ||
in the curve scalar field, encoded as 32 bytes, with the specified | ||
endianness. | ||
|
||
The output is an element of the curve scalar field, encoded as 32 bytes, | ||
with the specified endianness. | ||
|
||
**Fatal Errors.** | ||
|
||
- Validate `parameters` is `0` (known curve). | ||
- Validate `endianness` is `0` or `1` (known endianness). | ||
- Validate `vals_len` is less or equal to 12. | ||
- Compute units | ||
- Memory mapping for input/output | ||
|
||
**Error Code(s).** | ||
|
||
Any error caused while computing the Poseidon hash function is returned | ||
as error code `1`, i.e. `Ok(1)` in Rust. | ||
|
||
This includes validating that the input buffers are valid field elements, | ||
and other errors that may occur while calculating the Poseidon hash. | ||
|
||
## Impact | ||
|
||
Implementing the error logic inside validators will be much easier and less | ||
error prone. | ||
|
||
Dapp developers will have less fine-grained errors, but this is in line with all | ||
the other syscalls. | ||
|
||
## Security Considerations | ||
|
||
Simplifying to one single error code reduces the risk of two different validator | ||
implementations returining different error codes, which could be exploited | ||
to cause a consensus failure. | ||
|
||
This change will also hide some internal implementation details, for example | ||
the err code `TryIntoVecError`, which is a plus from a security perspective. | ||
|
||
The implementation should be straightforward: change the return from `Ok(err_num)` | ||
to `Ok(1)`, so low risk. | ||
|
||
## Backwards Compatibility | ||
|
||
The syscall `sol_alt_bn128_group_op` is enabled in testnet, therefore we'll | ||
feature gate the change. Programs using this syscall may need to adapt to the | ||
simplified error code, but this isn't expected to be an issue in practice. | ||
|
||
For simplicity, we'll keep the change to all 3 syscalls under the same | ||
feature gate. |