SIMD-0359

Poseidon Syscall - Enforce Input Length

Author: Michal Rostecki · Category: Core Protocol GitHub →

TL;DR

Require all Poseidon hash inputs to have a fixed length determined by the number of bytes used by the modulus of a prime field. For the (currently the only supported) prime field BN254, the modulus is: $$ p = 21888242871839275222246405745257275088548364400416034343698204186575808495617 $$ The byte representation of that modulus takes 32 bytes: ``` [ 1, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48 ] ``` That means there is no element in BN254 prime field that has byte representation larger than 32 bytes. As of today, Poseidon syscall accepts byte slices with length $$n$$, where: $$ 0 \leq n \leq bytelen(p) $$ The goal of this change is to restrict it to: $$ n = bytelen(p) $$ In case of inputs with byte representations having fewer bytes than modulus, that means a necessity to add explicit padding. For example, the following big number: ``` 115792089237316195423570985008687907853269984665640564039439137263839420088320 ``` Which can be represented by these 24 bytes: ``` [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ] ``` When used as a little-endian input for Poseidon on BN254 prime field, will have to be extended to the following 32 byte representation: ``` [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0 ] ```

Summary

Require all Poseidon hash inputs to have a fixed length determined by the number of bytes used by the modulus of a prime field. For the (currently the only supported) prime field BN254, the modulus is: $$ p = 21888242871839275222246405745257275088548364400416034343698204186575808495617 $$ The byte representation of that modulus takes 32 bytes: ``` [ 1, 0, 0, 240, 147, 245, 225, 67, 145, 112, 185, 121, 72, 232, 51, 40, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48 ] ``` That means there is no element in BN254 prime field that has byte representation larger than 32 bytes. As of today, Poseidon syscall accepts byte slices with length $$n$$, where: $$ 0 \leq n \leq bytelen(p) $$ The goal of this change is to restrict it to: $$ n = bytelen(p) $$ In case of inputs with byte representations having fewer bytes than modulus, that means a necessity to add explicit padding. For example, the following big number: ``` 115792089237316195423570985008687907853269984665640564039439137263839420088320 ``` Which can be represented by these 24 bytes: ``` [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ] ``` When used as a little-endian input for Poseidon on BN254 prime field, will have to be extended to the following 32 byte representation: ``` [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0 ] ```

Motivation

The current behavior allowing people to submit slices of different lengths is confusing and makes the implementation of the hasher less straightforward.

Impact

It's a consensus breaking change, therefore it needs to be guarded with a feature flag, implemented by all validator implementations and activated once all of them are ready.

Backwards Compatibility

The feature breaks backward compatibility, therefore it needs to be introduced with a feature gate. Without the feature enabled, validators must honor the old behavior, where smaller inputs are accepted and still correctly serialized as big integers.

Security Considerations

n/a