Bladeren bron

SIMD-0359: Enforce padding in Poseidon hash inputs (#8534)

light-poseidon 0.4.0 introduced a more rigid hash input check
(Lightprotocol/light-poseidon@92ce32a6513b), where every input needs
to have a length matching the byte length of the prime field modulus.
In case of the `Fr` field, it's 32 bytes.

Previously it was possible to pass smaller byte inputs, which still
have the same value as a scalar, e.g. (little-endian):

```
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 1]
[0, 1]
[1]
```

From now on, the only accepted way of passing a scalar `1` will be:

```
[
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 1
]
```

Upgrade of light-poseidon requires upgrade of ark-bn254 from 0.4.0 to
0.5.0

This behavior is guarded by the new feature flag
`poseidon_enforce_padding`. If the feature flag is disabled, the old
versions of light-poseidon and ark-bn254 are used to ensure the old
behavior.
Michal R 3 weken geleden
bovenliggende
commit
3da465153b
10 gewijzigde bestanden met toevoegingen van 1046 en 81 verwijderingen
  1. 205 26
      Cargo.lock
  2. 4 2
      Cargo.toml
  3. 196 26
      dev-bins/Cargo.lock
  4. 9 0
      feature-set/src/lib.rs
  5. 2 0
      poseidon/Cargo.toml
  6. 401 0
      poseidon/src/legacy.rs
  7. 16 0
      poseidon/src/lib.rs
  8. 205 26
      programs/sbf/Cargo.lock
  9. 2 0
      svm-feature-set/src/lib.rs
  10. 6 1
      syscalls/src/lib.rs

+ 205 - 26
Cargo.lock

@@ -800,9 +800,20 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f"
 dependencies = [
- "ark-ec",
- "ark-ff",
- "ark-std",
+ "ark-ec 0.4.2",
+ "ark-ff 0.4.2",
+ "ark-std 0.4.0",
+]
+
+[[package]]
+name = "ark-bn254"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc"
+dependencies = [
+ "ark-ec 0.5.0",
+ "ark-ff 0.5.0",
+ "ark-std 0.5.0",
 ]
 
 [[package]]
@@ -811,10 +822,10 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba"
 dependencies = [
- "ark-ff",
- "ark-poly",
- "ark-serialize",
- "ark-std",
+ "ark-ff 0.4.2",
+ "ark-poly 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "hashbrown 0.13.2",
  "itertools 0.10.5",
@@ -822,16 +833,37 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "ark-ec"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce"
+dependencies = [
+ "ahash 0.8.11",
+ "ark-ff 0.5.0",
+ "ark-poly 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "educe 0.6.0",
+ "fnv",
+ "hashbrown 0.15.1",
+ "itertools 0.13.0",
+ "num-bigint 0.4.6",
+ "num-integer",
+ "num-traits",
+ "zeroize",
+]
+
 [[package]]
 name = "ark-ff"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba"
 dependencies = [
- "ark-ff-asm",
- "ark-ff-macros",
- "ark-serialize",
- "ark-std",
+ "ark-ff-asm 0.4.2",
+ "ark-ff-macros 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "digest 0.10.7",
  "itertools 0.10.5",
@@ -842,6 +874,26 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "ark-ff"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70"
+dependencies = [
+ "ark-ff-asm 0.5.0",
+ "ark-ff-macros 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "arrayvec",
+ "digest 0.10.7",
+ "educe 0.6.0",
+ "itertools 0.13.0",
+ "num-bigint 0.4.6",
+ "num-traits",
+ "paste",
+ "zeroize",
+]
+
 [[package]]
 name = "ark-ff-asm"
 version = "0.4.2"
@@ -852,6 +904,16 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-ff-asm"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60"
+dependencies = [
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-ff-macros"
 version = "0.4.2"
@@ -865,27 +927,68 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-ff-macros"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3"
+dependencies = [
+ "num-bigint 0.4.6",
+ "num-traits",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-poly"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf"
 dependencies = [
- "ark-ff",
- "ark-serialize",
- "ark-std",
+ "ark-ff 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "hashbrown 0.13.2",
 ]
 
+[[package]]
+name = "ark-poly"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27"
+dependencies = [
+ "ahash 0.8.11",
+ "ark-ff 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "educe 0.6.0",
+ "fnv",
+ "hashbrown 0.15.1",
+]
+
 [[package]]
 name = "ark-serialize"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5"
 dependencies = [
- "ark-serialize-derive",
- "ark-std",
+ "ark-serialize-derive 0.4.2",
+ "ark-std 0.4.0",
+ "digest 0.10.7",
+ "num-bigint 0.4.6",
+]
+
+[[package]]
+name = "ark-serialize"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7"
+dependencies = [
+ "ark-serialize-derive 0.5.0",
+ "ark-std 0.5.0",
+ "arrayvec",
  "digest 0.10.7",
  "num-bigint 0.4.6",
 ]
@@ -901,6 +1004,17 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-serialize-derive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-std"
 version = "0.4.0"
@@ -911,6 +1025,16 @@ dependencies = [
  "rand 0.8.5",
 ]
 
+[[package]]
+name = "ark-std"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a"
+dependencies = [
+ "num-traits",
+ "rand 0.8.5",
+]
+
 [[package]]
 name = "arrayref"
 version = "0.3.9"
@@ -2684,12 +2808,24 @@ version = "0.4.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f86b50932a01e7ec5c06160492ab660fb19b6bb2a7878030dd6cd68d21df9d4d"
 dependencies = [
- "enum-ordinalize",
+ "enum-ordinalize 3.1.10",
  "proc-macro2",
  "quote",
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "educe"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417"
+dependencies = [
+ "enum-ordinalize 4.3.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "either"
 version = "1.11.0"
@@ -2763,6 +2899,26 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "enum-ordinalize"
+version = "4.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5"
+dependencies = [
+ "enum-ordinalize-derive",
+]
+
+[[package]]
+name = "enum-ordinalize-derive"
+version = "4.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "env_filter"
 version = "0.1.3"
@@ -4050,6 +4206,15 @@ dependencies = [
  "either",
 ]
 
+[[package]]
+name = "itertools"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
+dependencies = [
+ "either",
+]
+
 [[package]]
 name = "itoa"
 version = "1.0.9"
@@ -4407,8 +4572,20 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee"
 dependencies = [
- "ark-bn254",
- "ark-ff",
+ "ark-bn254 0.4.0",
+ "ark-ff 0.4.2",
+ "num-bigint 0.4.6",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "light-poseidon"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862"
+dependencies = [
+ "ark-bn254 0.5.0",
+ "ark-ff 0.5.0",
  "num-bigint 0.4.6",
  "thiserror 1.0.69",
 ]
@@ -7349,10 +7526,10 @@ version = "3.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d08583be08d2d5f19aa21efbb6fbdb968ba7fd0de74562441437a7d776772bf"
 dependencies = [
- "ark-bn254",
- "ark-ec",
- "ark-ff",
- "ark-serialize",
+ "ark-bn254 0.4.0",
+ "ark-ec 0.4.2",
+ "ark-ff 0.4.2",
+ "ark-serialize 0.4.2",
  "bytemuck",
  "solana-define-syscall 3.0.0",
  "thiserror 2.0.17",
@@ -9470,8 +9647,10 @@ dependencies = [
 name = "solana-poseidon"
 version = "3.1.0"
 dependencies = [
- "ark-bn254",
- "light-poseidon",
+ "ark-bn254 0.4.0",
+ "ark-bn254 0.5.0",
+ "light-poseidon 0.2.0",
+ "light-poseidon 0.4.0",
  "solana-define-syscall 3.0.0",
  "thiserror 2.0.17",
 ]
@@ -12745,7 +12924,7 @@ checksum = "911a61637386b789af998ee23f50aa30d5fd7edcec8d6d3dedae5e5815205466"
 dependencies = [
  "bincode",
  "bytes",
- "educe",
+ "educe 0.4.18",
  "futures-core",
  "futures-sink",
  "pin-project",

+ 4 - 2
Cargo.toml

@@ -207,7 +207,8 @@ anyhow = "1.0.100"
 aquamarine = "0.6.0"
 arbitrary = "1.4.2"
 arc-swap = "1.7.1"
-ark-bn254 = "0.4.0"
+ark-bn254 = "0.5.0"
+ark-bn254-0-4 = { package = "ark-bn254", version = "0.4.0" }
 array-bytes = "=1.4.1"
 arrayref = "0.3.9"
 arrayvec = "0.7.6"
@@ -311,7 +312,8 @@ libsecp256k1 = { version = "0.6.0", default-features = false, features = [
     "std",
     "static-context",
 ] }
-light-poseidon = "0.2.0"
+light-poseidon = "0.4.0"
+light-poseidon-0-2 = { package = "light-poseidon", version = "0.2.0" }
 log = "0.4.28"
 lru = "0.7.7"
 lz4 = "1.28.1"

+ 196 - 26
dev-bins/Cargo.lock

@@ -596,9 +596,20 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f"
 dependencies = [
- "ark-ec",
- "ark-ff",
- "ark-std",
+ "ark-ec 0.4.2",
+ "ark-ff 0.4.2",
+ "ark-std 0.4.0",
+]
+
+[[package]]
+name = "ark-bn254"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc"
+dependencies = [
+ "ark-ec 0.5.0",
+ "ark-ff 0.5.0",
+ "ark-std 0.5.0",
 ]
 
 [[package]]
@@ -607,10 +618,10 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba"
 dependencies = [
- "ark-ff",
- "ark-poly",
- "ark-serialize",
- "ark-std",
+ "ark-ff 0.4.2",
+ "ark-poly 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "hashbrown 0.13.2",
  "itertools 0.10.5",
@@ -618,16 +629,37 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "ark-ec"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce"
+dependencies = [
+ "ahash 0.8.12",
+ "ark-ff 0.5.0",
+ "ark-poly 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "educe 0.6.0",
+ "fnv",
+ "hashbrown 0.15.5",
+ "itertools 0.13.0",
+ "num-bigint 0.4.6",
+ "num-integer",
+ "num-traits",
+ "zeroize",
+]
+
 [[package]]
 name = "ark-ff"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba"
 dependencies = [
- "ark-ff-asm",
- "ark-ff-macros",
- "ark-serialize",
- "ark-std",
+ "ark-ff-asm 0.4.2",
+ "ark-ff-macros 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "digest 0.10.7",
  "itertools 0.10.5",
@@ -638,6 +670,26 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "ark-ff"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70"
+dependencies = [
+ "ark-ff-asm 0.5.0",
+ "ark-ff-macros 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "arrayvec",
+ "digest 0.10.7",
+ "educe 0.6.0",
+ "itertools 0.13.0",
+ "num-bigint 0.4.6",
+ "num-traits",
+ "paste",
+ "zeroize",
+]
+
 [[package]]
 name = "ark-ff-asm"
 version = "0.4.2"
@@ -648,6 +700,16 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-ff-asm"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60"
+dependencies = [
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-ff-macros"
 version = "0.4.2"
@@ -661,27 +723,68 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-ff-macros"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3"
+dependencies = [
+ "num-bigint 0.4.6",
+ "num-traits",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-poly"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf"
 dependencies = [
- "ark-ff",
- "ark-serialize",
- "ark-std",
+ "ark-ff 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "hashbrown 0.13.2",
 ]
 
+[[package]]
+name = "ark-poly"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27"
+dependencies = [
+ "ahash 0.8.12",
+ "ark-ff 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "educe 0.6.0",
+ "fnv",
+ "hashbrown 0.15.5",
+]
+
 [[package]]
 name = "ark-serialize"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5"
 dependencies = [
- "ark-serialize-derive",
- "ark-std",
+ "ark-serialize-derive 0.4.2",
+ "ark-std 0.4.0",
+ "digest 0.10.7",
+ "num-bigint 0.4.6",
+]
+
+[[package]]
+name = "ark-serialize"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7"
+dependencies = [
+ "ark-serialize-derive 0.5.0",
+ "ark-std 0.5.0",
+ "arrayvec",
  "digest 0.10.7",
  "num-bigint 0.4.6",
 ]
@@ -697,6 +800,17 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-serialize-derive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-std"
 version = "0.4.0"
@@ -707,6 +821,16 @@ dependencies = [
  "rand 0.8.5",
 ]
 
+[[package]]
+name = "ark-std"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a"
+dependencies = [
+ "num-traits",
+ "rand 0.8.5",
+]
+
 [[package]]
 name = "arrayref"
 version = "0.3.9"
@@ -2146,12 +2270,24 @@ version = "0.4.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f"
 dependencies = [
- "enum-ordinalize",
+ "enum-ordinalize 3.1.15",
  "proc-macro2",
  "quote",
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "educe"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417"
+dependencies = [
+ "enum-ordinalize 4.3.2",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "either"
 version = "1.15.0"
@@ -2225,6 +2361,26 @@ dependencies = [
  "syn 2.0.106",
 ]
 
+[[package]]
+name = "enum-ordinalize"
+version = "4.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0"
+dependencies = [
+ "enum-ordinalize-derive",
+]
+
+[[package]]
+name = "enum-ordinalize-derive"
+version = "4.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "env_filter"
 version = "0.1.3"
@@ -3738,8 +3894,20 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee"
 dependencies = [
- "ark-bn254",
- "ark-ff",
+ "ark-bn254 0.4.0",
+ "ark-ff 0.4.2",
+ "num-bigint 0.4.6",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "light-poseidon"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862"
+dependencies = [
+ "ark-bn254 0.5.0",
+ "ark-ff 0.5.0",
  "num-bigint 0.4.6",
  "thiserror 1.0.69",
 ]
@@ -6352,10 +6520,10 @@ version = "3.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d08583be08d2d5f19aa21efbb6fbdb968ba7fd0de74562441437a7d776772bf"
 dependencies = [
- "ark-bn254",
- "ark-ec",
- "ark-ff",
- "ark-serialize",
+ "ark-bn254 0.4.0",
+ "ark-ec 0.4.2",
+ "ark-ff 0.4.2",
+ "ark-serialize 0.4.2",
  "bytemuck",
  "solana-define-syscall 3.0.0",
  "thiserror 2.0.17",
@@ -7947,8 +8115,10 @@ dependencies = [
 name = "solana-poseidon"
 version = "3.1.0"
 dependencies = [
- "ark-bn254",
- "light-poseidon",
+ "ark-bn254 0.4.0",
+ "ark-bn254 0.5.0",
+ "light-poseidon 0.2.0",
+ "light-poseidon 0.4.0",
  "solana-define-syscall 3.0.0",
  "thiserror 2.0.17",
 ]
@@ -10582,7 +10752,7 @@ checksum = "911a61637386b789af998ee23f50aa30d5fd7edcec8d6d3dedae5e5815205466"
 dependencies = [
  "bincode",
  "bytes",
- "educe",
+ "educe 0.4.23",
  "futures-core",
  "futures-sink",
  "pin-project",

+ 9 - 0
feature-set/src/lib.rs

@@ -170,6 +170,7 @@ impl FeatureSet {
                 .is_active(&provide_instruction_data_offset_in_vm_r2::id()),
             increase_cpi_account_info_limit: self.is_active(&increase_cpi_account_info_limit::id()),
             vote_state_v4: self.is_active(&vote_state_v4::id()),
+            poseidon_enforce_padding: self.is_active(&poseidon_enforce_padding::id()),
         }
     }
 }
@@ -1176,6 +1177,10 @@ pub mod deprecate_rent_exemption_threshold {
     solana_pubkey::declare_id!("rent6iVy6PDoViPBeJ6k5EJQrkj62h7DPyLbWGHwjrC");
 }
 
+pub mod poseidon_enforce_padding {
+    solana_pubkey::declare_id!("poUdAqRXXsNmfqAZ6UqpjbeYgwBygbfQLEvWSqVhSnb");
+}
+
 pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::new(|| {
     [
         (secp256k1_program_enabled::id(), "secp256k1 program"),
@@ -2115,6 +2120,10 @@ pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::n
             deprecate_rent_exemption_threshold::id(),
             "SIMD-0194: Deprecate rent exemption threshold",
         ),
+        (
+            poseidon_enforce_padding::id(),
+            "SIMD-0359: Enforce padding in Poseidon hash inputs",
+        ),
         /*************** ADD NEW FEATURES HERE ***************/
     ]
     .iter()

+ 2 - 0
poseidon/Cargo.toml

@@ -20,7 +20,9 @@ thiserror = { workspace = true }
 
 [target.'cfg(not(target_os = "solana"))'.dependencies]
 ark-bn254 = { workspace = true }
+ark-bn254-0-4 = { workspace = true }
 light-poseidon = { workspace = true }
+light-poseidon-0-2 = { workspace = true }
 
 [target.'cfg(target_os = "solana")'.dependencies]
 solana-define-syscall = { workspace = true }

+ 401 - 0
poseidon/src/legacy.rs

@@ -0,0 +1,401 @@
+//! Legacy Poseidon hash implementation using older crate versions and not
+//! enforcing the explicit padding.
+//!
+//! This module mirrors the logic from `lib.rs` but imports `ark_bn254_0_4` and
+//! `light_poseidon_0_2`.
+
+use crate::{Endianness, Parameters, PoseidonHash, PoseidonSyscallError};
+#[cfg(target_os = "solana")]
+use {crate::HASH_BYTES, solana_define_syscall::definitions::sol_poseidon};
+
+/// Return a Poseidon hash for the given data with the given elliptic curve and
+/// endianness.
+///
+/// # Examples
+///
+/// ```rust
+/// use solana_poseidon::{hashv, Endianness, Parameters};
+///
+/// # fn test() {
+/// let input1 = [1u8; 32];
+/// let input2 = [2u8; 32];
+///
+/// let hash = hashv(Parameters::Bn254X5, Endianness::BigEndian, &[&input1, &input2]).unwrap();
+/// assert_eq!(hash.to_bytes().len(), 32);
+/// # }
+/// ```
+#[allow(unused_variables)]
+pub fn hashv(
+    // This parameter is not used currently, because we support only one curve
+    // (BN254). It should be used in case we add more curves in the future.
+    parameters: Parameters,
+    endianness: Endianness,
+    vals: &[&[u8]],
+) -> Result<PoseidonHash, PoseidonSyscallError> {
+    // Perform the calculation inline, calling this from within a program is
+    // not supported.
+    #[cfg(not(target_os = "solana"))]
+    {
+        use {
+            ark_bn254_0_4::Fr,
+            light_poseidon_0_2::{Poseidon, PoseidonBytesHasher, PoseidonError},
+        };
+
+        #[allow(non_local_definitions)]
+        impl From<PoseidonError> for PoseidonSyscallError {
+            fn from(error: PoseidonError) -> Self {
+                match error {
+                    PoseidonError::InvalidNumberOfInputs { .. } => {
+                        PoseidonSyscallError::InvalidNumberOfInputs
+                    }
+                    PoseidonError::EmptyInput => PoseidonSyscallError::EmptyInput,
+                    PoseidonError::InvalidInputLength { .. } => {
+                        PoseidonSyscallError::InvalidInputLength
+                    }
+                    PoseidonError::BytesToPrimeFieldElement { .. } => {
+                        PoseidonSyscallError::BytesToPrimeFieldElement
+                    }
+                    PoseidonError::InputLargerThanModulus => {
+                        PoseidonSyscallError::InputLargerThanModulus
+                    }
+                    PoseidonError::VecToArray => PoseidonSyscallError::VecToArray,
+                    PoseidonError::U64Tou8 => PoseidonSyscallError::U64Tou8,
+                    PoseidonError::BytesToBigInt => PoseidonSyscallError::BytesToBigInt,
+                    PoseidonError::InvalidWidthCircom { .. } => {
+                        PoseidonSyscallError::InvalidWidthCircom
+                    }
+                }
+            }
+        }
+
+        let mut hasher =
+            Poseidon::<Fr>::new_circom(vals.len()).map_err(PoseidonSyscallError::from)?;
+        let res = match endianness {
+            Endianness::BigEndian => hasher.hash_bytes_be(vals),
+            Endianness::LittleEndian => hasher.hash_bytes_le(vals),
+        }
+        .map_err(PoseidonSyscallError::from)?;
+
+        Ok(PoseidonHash(res))
+    }
+    #[cfg(target_os = "solana")]
+    {
+        let mut hash_result = [0; HASH_BYTES];
+        let result = unsafe {
+            sol_poseidon(
+                parameters.into(),
+                endianness.into(),
+                vals as *const _ as *const u8,
+                vals.len() as u64,
+                &mut hash_result as *mut _ as *mut u8,
+            )
+        };
+
+        match result {
+            0 => Ok(PoseidonHash::new(hash_result)),
+            _ => Err(PoseidonSyscallError::Unexpected),
+        }
+    }
+}
+
+/// Return a Poseidon hash for the given data with the given elliptic curve and
+/// endianness.
+///
+/// # Examples
+///
+/// ```rust
+/// use solana_poseidon::{hash, Endianness, Parameters};
+///
+/// # fn test() {
+/// let input = [1u8; 32];
+///
+/// let result = hash(Parameters::Bn254X5, Endianness::BigEndian, &input).unwrap();
+/// assert_eq!(
+///     result.to_bytes(),
+///     [
+///         5, 191, 172, 229, 129, 238, 97, 119, 204, 25, 198, 197, 99, 99, 166, 136, 130, 241,
+///         30, 132, 7, 172, 99, 157, 185, 145, 224, 210, 127, 27, 117, 230
+///     ],
+/// );
+///
+/// let hash = hash(Parameters::Bn254X5, Endianness::LittleEndian, &input).unwrap();
+/// assert_eq!(
+///     hash.to_bytes(),
+///     [
+///         230, 117, 27, 127, 210, 224, 145, 185, 157, 99, 172, 7, 132, 30, 241, 130, 136,
+///         166, 99, 99, 197, 198, 25, 204, 119, 97, 238, 129, 229, 172, 191, 5
+///     ],
+/// );
+/// # }
+/// ```
+pub fn hash(
+    parameters: Parameters,
+    endianness: Endianness,
+    val: &[u8],
+) -> Result<PoseidonHash, PoseidonSyscallError> {
+    hashv(parameters, endianness, &[val])
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_poseidon_input_ones_be() {
+        let input = [1u8; 32];
+
+        let hash = hash(Parameters::Bn254X5, Endianness::BigEndian, &input).unwrap();
+        assert_eq!(
+            hash.to_bytes(),
+            [
+                5, 191, 172, 229, 129, 238, 97, 119, 204, 25, 198, 197, 99, 99, 166, 136, 130, 241,
+                30, 132, 7, 172, 99, 157, 185, 145, 224, 210, 127, 27, 117, 230
+            ]
+        );
+    }
+
+    #[test]
+    fn test_poseidon_input_ones_le() {
+        let input = [1u8; 32];
+
+        let hash = hash(Parameters::Bn254X5, Endianness::LittleEndian, &input).unwrap();
+        assert_eq!(
+            hash.to_bytes(),
+            [
+                230, 117, 27, 127, 210, 224, 145, 185, 157, 99, 172, 7, 132, 30, 241, 130, 136,
+                166, 99, 99, 197, 198, 25, 204, 119, 97, 238, 129, 229, 172, 191, 5
+            ],
+        );
+    }
+
+    #[test]
+    fn test_poseidon_input_ones_twos_be() {
+        let input1 = [1u8; 32];
+        let input2 = [2u8; 32];
+
+        let hash = hashv(
+            Parameters::Bn254X5,
+            Endianness::BigEndian,
+            &[&input1, &input2],
+        )
+        .unwrap();
+        assert_eq!(
+            hash.to_bytes(),
+            [
+                13, 84, 225, 147, 143, 138, 140, 28, 125, 235, 94, 3, 85, 242, 99, 25, 32, 123,
+                132, 254, 156, 162, 206, 27, 38, 231, 53, 200, 41, 130, 25, 144
+            ]
+        );
+    }
+
+    #[test]
+    fn test_poseidon_input_ones_twos_le() {
+        let input1 = [1u8; 32];
+        let input2 = [2u8; 32];
+
+        let hash = hashv(
+            Parameters::Bn254X5,
+            Endianness::LittleEndian,
+            &[&input1, &input2],
+        )
+        .unwrap();
+        assert_eq!(
+            hash.to_bytes(),
+            [
+                144, 25, 130, 41, 200, 53, 231, 38, 27, 206, 162, 156, 254, 132, 123, 32, 25, 99,
+                242, 85, 3, 94, 235, 125, 28, 140, 138, 143, 147, 225, 84, 13
+            ]
+        );
+    }
+
+    #[test]
+    fn test_poseidon_input_one() {
+        let input = [
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 1,
+        ];
+
+        let expected_hashes = [
+            [
+                41, 23, 97, 0, 234, 169, 98, 189, 193, 254, 108, 101, 77, 106, 60, 19, 14, 150,
+                164, 209, 22, 139, 51, 132, 139, 137, 125, 197, 2, 130, 1, 51,
+            ],
+            [
+                0, 122, 243, 70, 226, 211, 4, 39, 158, 121, 224, 169, 243, 2, 63, 119, 18, 148,
+                167, 138, 203, 112, 231, 63, 144, 175, 226, 124, 173, 64, 30, 129,
+            ],
+            [
+                2, 192, 6, 110, 16, 167, 42, 189, 43, 51, 195, 178, 20, 203, 62, 129, 188, 177,
+                182, 227, 9, 97, 205, 35, 194, 2, 177, 134, 115, 191, 37, 67,
+            ],
+            [
+                8, 44, 156, 55, 10, 13, 36, 244, 65, 111, 188, 65, 74, 55, 104, 31, 120, 68, 45,
+                39, 216, 99, 133, 153, 28, 23, 214, 252, 12, 75, 125, 113,
+            ],
+            [
+                16, 56, 150, 5, 174, 104, 141, 79, 20, 219, 133, 49, 34, 196, 125, 102, 168, 3,
+                199, 43, 65, 88, 156, 177, 191, 134, 135, 65, 178, 6, 185, 187,
+            ],
+            [
+                42, 115, 246, 121, 50, 140, 62, 171, 114, 74, 163, 229, 189, 191, 80, 179, 144, 53,
+                215, 114, 159, 19, 91, 151, 9, 137, 15, 133, 197, 220, 94, 118,
+            ],
+            [
+                34, 118, 49, 10, 167, 243, 52, 58, 40, 66, 20, 19, 157, 157, 169, 89, 190, 42, 49,
+                178, 199, 8, 165, 248, 25, 84, 178, 101, 229, 58, 48, 184,
+            ],
+            [
+                23, 126, 20, 83, 196, 70, 225, 176, 125, 43, 66, 51, 66, 81, 71, 9, 92, 79, 202,
+                187, 35, 61, 35, 11, 109, 70, 162, 20, 217, 91, 40, 132,
+            ],
+            [
+                14, 143, 238, 47, 228, 157, 163, 15, 222, 235, 72, 196, 46, 187, 68, 204, 110, 231,
+                5, 95, 97, 251, 202, 94, 49, 59, 138, 95, 202, 131, 76, 71,
+            ],
+            [
+                46, 196, 198, 94, 99, 120, 171, 140, 115, 48, 133, 79, 74, 112, 119, 193, 255, 146,
+                96, 228, 72, 133, 196, 184, 29, 209, 49, 173, 58, 134, 205, 150,
+            ],
+            [
+                0, 113, 61, 65, 236, 166, 53, 241, 23, 212, 236, 188, 235, 95, 58, 102, 220, 65,
+                66, 235, 112, 181, 103, 101, 188, 53, 143, 27, 236, 64, 187, 155,
+            ],
+            [
+                20, 57, 11, 224, 186, 239, 36, 155, 212, 124, 101, 221, 172, 101, 194, 229, 46,
+                133, 19, 192, 129, 193, 205, 114, 201, 128, 6, 9, 142, 154, 143, 190,
+            ],
+        ];
+
+        for (i, expected_hash) in expected_hashes.into_iter().enumerate() {
+            let inputs = vec![&input[..]; i + 1];
+            let hash = hashv(Parameters::Bn254X5, Endianness::BigEndian, &inputs).unwrap();
+            assert_eq!(hash.to_bytes(), expected_hash);
+        }
+    }
+
+    // This is one of the cases that differentiates the legacy module from the
+    // main one.
+    #[test]
+    fn test_poseidon_input_without_padding_be() {
+        let input = [1];
+
+        let expected_hashes = [
+            [
+                41, 23, 97, 0, 234, 169, 98, 189, 193, 254, 108, 101, 77, 106, 60, 19, 14, 150,
+                164, 209, 22, 139, 51, 132, 139, 137, 125, 197, 2, 130, 1, 51,
+            ],
+            [
+                0, 122, 243, 70, 226, 211, 4, 39, 158, 121, 224, 169, 243, 2, 63, 119, 18, 148,
+                167, 138, 203, 112, 231, 63, 144, 175, 226, 124, 173, 64, 30, 129,
+            ],
+            [
+                2, 192, 6, 110, 16, 167, 42, 189, 43, 51, 195, 178, 20, 203, 62, 129, 188, 177,
+                182, 227, 9, 97, 205, 35, 194, 2, 177, 134, 115, 191, 37, 67,
+            ],
+            [
+                8, 44, 156, 55, 10, 13, 36, 244, 65, 111, 188, 65, 74, 55, 104, 31, 120, 68, 45,
+                39, 216, 99, 133, 153, 28, 23, 214, 252, 12, 75, 125, 113,
+            ],
+            [
+                16, 56, 150, 5, 174, 104, 141, 79, 20, 219, 133, 49, 34, 196, 125, 102, 168, 3,
+                199, 43, 65, 88, 156, 177, 191, 134, 135, 65, 178, 6, 185, 187,
+            ],
+            [
+                42, 115, 246, 121, 50, 140, 62, 171, 114, 74, 163, 229, 189, 191, 80, 179, 144, 53,
+                215, 114, 159, 19, 91, 151, 9, 137, 15, 133, 197, 220, 94, 118,
+            ],
+            [
+                34, 118, 49, 10, 167, 243, 52, 58, 40, 66, 20, 19, 157, 157, 169, 89, 190, 42, 49,
+                178, 199, 8, 165, 248, 25, 84, 178, 101, 229, 58, 48, 184,
+            ],
+            [
+                23, 126, 20, 83, 196, 70, 225, 176, 125, 43, 66, 51, 66, 81, 71, 9, 92, 79, 202,
+                187, 35, 61, 35, 11, 109, 70, 162, 20, 217, 91, 40, 132,
+            ],
+            [
+                14, 143, 238, 47, 228, 157, 163, 15, 222, 235, 72, 196, 46, 187, 68, 204, 110, 231,
+                5, 95, 97, 251, 202, 94, 49, 59, 138, 95, 202, 131, 76, 71,
+            ],
+            [
+                46, 196, 198, 94, 99, 120, 171, 140, 115, 48, 133, 79, 74, 112, 119, 193, 255, 146,
+                96, 228, 72, 133, 196, 184, 29, 209, 49, 173, 58, 134, 205, 150,
+            ],
+            [
+                0, 113, 61, 65, 236, 166, 53, 241, 23, 212, 236, 188, 235, 95, 58, 102, 220, 65,
+                66, 235, 112, 181, 103, 101, 188, 53, 143, 27, 236, 64, 187, 155,
+            ],
+            [
+                20, 57, 11, 224, 186, 239, 36, 155, 212, 124, 101, 221, 172, 101, 194, 229, 46,
+                133, 19, 192, 129, 193, 205, 114, 201, 128, 6, 9, 142, 154, 143, 190,
+            ],
+        ];
+
+        for (i, expected_hash) in expected_hashes.into_iter().enumerate() {
+            let inputs = vec![&input[..]; i + 1];
+            let hash = hashv(Parameters::Bn254X5, Endianness::BigEndian, &inputs).unwrap();
+            assert_eq!(hash.to_bytes(), expected_hash);
+        }
+    }
+
+    #[test]
+    fn test_poseidon_input_without_padding_le() {
+        let input = [1];
+
+        let expected_hashes = [
+            [
+                51, 1, 130, 2, 197, 125, 137, 139, 132, 51, 139, 22, 209, 164, 150, 14, 19, 60,
+                106, 77, 101, 108, 254, 193, 189, 98, 169, 234, 0, 97, 23, 41,
+            ],
+            [
+                129, 30, 64, 173, 124, 226, 175, 144, 63, 231, 112, 203, 138, 167, 148, 18, 119,
+                63, 2, 243, 169, 224, 121, 158, 39, 4, 211, 226, 70, 243, 122, 0,
+            ],
+            [
+                67, 37, 191, 115, 134, 177, 2, 194, 35, 205, 97, 9, 227, 182, 177, 188, 129, 62,
+                203, 20, 178, 195, 51, 43, 189, 42, 167, 16, 110, 6, 192, 2,
+            ],
+            [
+                113, 125, 75, 12, 252, 214, 23, 28, 153, 133, 99, 216, 39, 45, 68, 120, 31, 104,
+                55, 74, 65, 188, 111, 65, 244, 36, 13, 10, 55, 156, 44, 8,
+            ],
+            [
+                187, 185, 6, 178, 65, 135, 134, 191, 177, 156, 88, 65, 43, 199, 3, 168, 102, 125,
+                196, 34, 49, 133, 219, 20, 79, 141, 104, 174, 5, 150, 56, 16,
+            ],
+            [
+                118, 94, 220, 197, 133, 15, 137, 9, 151, 91, 19, 159, 114, 215, 53, 144, 179, 80,
+                191, 189, 229, 163, 74, 114, 171, 62, 140, 50, 121, 246, 115, 42,
+            ],
+            [
+                184, 48, 58, 229, 101, 178, 84, 25, 248, 165, 8, 199, 178, 49, 42, 190, 89, 169,
+                157, 157, 19, 20, 66, 40, 58, 52, 243, 167, 10, 49, 118, 34,
+            ],
+            [
+                132, 40, 91, 217, 20, 162, 70, 109, 11, 35, 61, 35, 187, 202, 79, 92, 9, 71, 81,
+                66, 51, 66, 43, 125, 176, 225, 70, 196, 83, 20, 126, 23,
+            ],
+            [
+                71, 76, 131, 202, 95, 138, 59, 49, 94, 202, 251, 97, 95, 5, 231, 110, 204, 68, 187,
+                46, 196, 72, 235, 222, 15, 163, 157, 228, 47, 238, 143, 14,
+            ],
+            [
+                150, 205, 134, 58, 173, 49, 209, 29, 184, 196, 133, 72, 228, 96, 146, 255, 193,
+                119, 112, 74, 79, 133, 48, 115, 140, 171, 120, 99, 94, 198, 196, 46,
+            ],
+            [
+                155, 187, 64, 236, 27, 143, 53, 188, 101, 103, 181, 112, 235, 66, 65, 220, 102, 58,
+                95, 235, 188, 236, 212, 23, 241, 53, 166, 236, 65, 61, 113, 0,
+            ],
+            [
+                190, 143, 154, 142, 9, 6, 128, 201, 114, 205, 193, 129, 192, 19, 133, 46, 229, 194,
+                101, 172, 221, 101, 124, 212, 155, 36, 239, 186, 224, 11, 57, 20,
+            ],
+        ];
+
+        for (i, expected_hash) in expected_hashes.into_iter().enumerate() {
+            let inputs = vec![&input[..]; i + 1];
+            let hash = hashv(Parameters::Bn254X5, Endianness::LittleEndian, &inputs).unwrap();
+            assert_eq!(hash.to_bytes(), expected_hash);
+        }
+    }
+}

+ 16 - 0
poseidon/src/lib.rs

@@ -13,6 +13,9 @@
 
 use thiserror::Error;
 
+#[doc(hidden)]
+pub mod legacy;
+
 /// Length of Poseidon hash result.
 pub const HASH_BYTES: usize = 32;
 
@@ -461,4 +464,17 @@ mod tests {
             assert_eq!(hash.to_bytes(), expected_hash);
         }
     }
+
+    #[test]
+    fn test_poseidon_input_without_padding() {
+        let input = [1];
+
+        for i in 1..12 {
+            let inputs = vec![&input[..]; i + 1];
+            let res = hashv(Parameters::Bn254X5, Endianness::BigEndian, &inputs);
+            assert!(res.is_err());
+            let res = hashv(Parameters::Bn254X5, Endianness::LittleEndian, &inputs);
+            assert!(res.is_err());
+        }
+    }
 }

+ 205 - 26
programs/sbf/Cargo.lock

@@ -588,9 +588,20 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f"
 dependencies = [
- "ark-ec",
- "ark-ff",
- "ark-std",
+ "ark-ec 0.4.2",
+ "ark-ff 0.4.2",
+ "ark-std 0.4.0",
+]
+
+[[package]]
+name = "ark-bn254"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc"
+dependencies = [
+ "ark-ec 0.5.0",
+ "ark-ff 0.5.0",
+ "ark-std 0.5.0",
 ]
 
 [[package]]
@@ -599,10 +610,10 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba"
 dependencies = [
- "ark-ff",
- "ark-poly",
- "ark-serialize",
- "ark-std",
+ "ark-ff 0.4.2",
+ "ark-poly 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "hashbrown 0.13.2",
  "itertools 0.10.5",
@@ -610,16 +621,37 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "ark-ec"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce"
+dependencies = [
+ "ahash 0.8.11",
+ "ark-ff 0.5.0",
+ "ark-poly 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "educe 0.6.0",
+ "fnv",
+ "hashbrown 0.15.1",
+ "itertools 0.13.0",
+ "num-bigint 0.4.6",
+ "num-integer",
+ "num-traits",
+ "zeroize",
+]
+
 [[package]]
 name = "ark-ff"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba"
 dependencies = [
- "ark-ff-asm",
- "ark-ff-macros",
- "ark-serialize",
- "ark-std",
+ "ark-ff-asm 0.4.2",
+ "ark-ff-macros 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "digest 0.10.7",
  "itertools 0.10.5",
@@ -630,6 +662,26 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "ark-ff"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70"
+dependencies = [
+ "ark-ff-asm 0.5.0",
+ "ark-ff-macros 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "arrayvec",
+ "digest 0.10.7",
+ "educe 0.6.0",
+ "itertools 0.13.0",
+ "num-bigint 0.4.6",
+ "num-traits",
+ "paste",
+ "zeroize",
+]
+
 [[package]]
 name = "ark-ff-asm"
 version = "0.4.2"
@@ -640,6 +692,16 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-ff-asm"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60"
+dependencies = [
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-ff-macros"
 version = "0.4.2"
@@ -653,27 +715,68 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-ff-macros"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3"
+dependencies = [
+ "num-bigint 0.4.6",
+ "num-traits",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-poly"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf"
 dependencies = [
- "ark-ff",
- "ark-serialize",
- "ark-std",
+ "ark-ff 0.4.2",
+ "ark-serialize 0.4.2",
+ "ark-std 0.4.0",
  "derivative",
  "hashbrown 0.13.2",
 ]
 
+[[package]]
+name = "ark-poly"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27"
+dependencies = [
+ "ahash 0.8.11",
+ "ark-ff 0.5.0",
+ "ark-serialize 0.5.0",
+ "ark-std 0.5.0",
+ "educe 0.6.0",
+ "fnv",
+ "hashbrown 0.15.1",
+]
+
 [[package]]
 name = "ark-serialize"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5"
 dependencies = [
- "ark-serialize-derive",
- "ark-std",
+ "ark-serialize-derive 0.4.2",
+ "ark-std 0.4.0",
+ "digest 0.10.7",
+ "num-bigint 0.4.6",
+]
+
+[[package]]
+name = "ark-serialize"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7"
+dependencies = [
+ "ark-serialize-derive 0.5.0",
+ "ark-std 0.5.0",
+ "arrayvec",
  "digest 0.10.7",
  "num-bigint 0.4.6",
 ]
@@ -689,6 +792,17 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "ark-serialize-derive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "ark-std"
 version = "0.4.0"
@@ -699,6 +813,16 @@ dependencies = [
  "rand 0.8.5",
 ]
 
+[[package]]
+name = "ark-std"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a"
+dependencies = [
+ "num-traits",
+ "rand 0.8.5",
+]
+
 [[package]]
 name = "array-bytes"
 version = "1.4.1"
@@ -2054,12 +2178,24 @@ version = "0.4.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f"
 dependencies = [
- "enum-ordinalize",
+ "enum-ordinalize 3.1.15",
  "proc-macro2",
  "quote",
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "educe"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417"
+dependencies = [
+ "enum-ordinalize 4.3.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "either"
 version = "1.11.0"
@@ -2142,6 +2278,26 @@ dependencies = [
  "syn 2.0.106",
 ]
 
+[[package]]
+name = "enum-ordinalize"
+version = "4.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5"
+dependencies = [
+ "enum-ordinalize-derive",
+]
+
+[[package]]
+name = "enum-ordinalize-derive"
+version = "4.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
 [[package]]
 name = "env_filter"
 version = "0.1.3"
@@ -3301,6 +3457,15 @@ dependencies = [
  "either",
 ]
 
+[[package]]
+name = "itertools"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
+dependencies = [
+ "either",
+]
+
 [[package]]
 name = "itoa"
 version = "1.0.9"
@@ -3703,8 +3868,20 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee"
 dependencies = [
- "ark-bn254",
- "ark-ff",
+ "ark-bn254 0.4.0",
+ "ark-ff 0.4.2",
+ "num-bigint 0.4.6",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "light-poseidon"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862"
+dependencies = [
+ "ark-bn254 0.5.0",
+ "ark-ff 0.5.0",
  "num-bigint 0.4.6",
  "thiserror 1.0.69",
 ]
@@ -6179,10 +6356,10 @@ version = "3.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d08583be08d2d5f19aa21efbb6fbdb968ba7fd0de74562441437a7d776772bf"
 dependencies = [
- "ark-bn254",
- "ark-ec",
- "ark-ff",
- "ark-serialize",
+ "ark-bn254 0.4.0",
+ "ark-ec 0.4.2",
+ "ark-ff 0.4.2",
+ "ark-serialize 0.4.2",
  "bytemuck",
  "solana-define-syscall 3.0.0",
  "thiserror 2.0.17",
@@ -7644,8 +7821,10 @@ dependencies = [
 name = "solana-poseidon"
 version = "3.1.0"
 dependencies = [
- "ark-bn254",
- "light-poseidon",
+ "ark-bn254 0.4.0",
+ "ark-bn254 0.5.0",
+ "light-poseidon 0.2.0",
+ "light-poseidon 0.4.0",
  "solana-define-syscall 3.0.0",
  "thiserror 2.0.17",
 ]
@@ -11061,7 +11240,7 @@ checksum = "911a61637386b789af998ee23f50aa30d5fd7edcec8d6d3dedae5e5815205466"
 dependencies = [
  "bincode",
  "bytes",
- "educe",
+ "educe 0.4.23",
  "futures-core",
  "futures-sink",
  "pin-project",

+ 2 - 0
svm-feature-set/src/lib.rs

@@ -49,6 +49,7 @@ pub struct SVMFeatureSet {
     pub provide_instruction_data_offset_in_vm_r2: bool,
     pub increase_cpi_account_info_limit: bool,
     pub vote_state_v4: bool,
+    pub poseidon_enforce_padding: bool,
 }
 
 impl SVMFeatureSet {
@@ -94,6 +95,7 @@ impl SVMFeatureSet {
             provide_instruction_data_offset_in_vm_r2: true,
             increase_cpi_account_info_limit: true,
             vote_state_v4: true,
+            poseidon_enforce_padding: true,
         }
     }
 }

+ 6 - 1
syscalls/src/lib.rs

@@ -1779,7 +1779,12 @@ declare_builtin_function!(
             })
             .collect::<Result<Vec<_>, Error>>()?;
 
-        let Ok(hash) = poseidon::hashv(parameters, endianness, inputs.as_slice()) else {
+        let result = if invoke_context.get_feature_set().poseidon_enforce_padding {
+            poseidon::hashv(parameters, endianness, inputs.as_slice())
+        } else {
+            poseidon::legacy::hashv(parameters, endianness, inputs.as_slice())
+        };
+        let Ok(hash) = result else {
             return Ok(1);
         };
         hash_result.copy_from_slice(&hash.to_bytes());