Skip to content

Commit 8702698

Browse files
authored
Merge branch 'main' into debug-assert-in-contract
2 parents 1af8c7f + 0b4bb28 commit 8702698

File tree

216 files changed

+2682
-694
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

216 files changed

+2682
-694
lines changed

Cargo.lock

Lines changed: 126 additions & 295 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,42 @@ members = [
1515
]
1616

1717
[workspace.package]
18-
version = "25.3.0"
18+
version = "26.0.0-rc.1"
1919
rust-version = "1.91.0"
2020

2121
[workspace.dependencies]
22-
soroban-sdk = { version = "25.3.0", path = "soroban-sdk" }
23-
soroban-sdk-macros = { version = "25.3.0", path = "soroban-sdk-macros" }
24-
soroban-meta = { version = "25.3.0", path = "soroban-meta" }
25-
soroban-spec = { version = "25.3.0", path = "soroban-spec" }
26-
soroban-spec-rust = { version = "25.3.0", path = "soroban-spec-rust" }
27-
soroban-ledger-snapshot = { version = "25.3.0", path = "soroban-ledger-snapshot" }
28-
soroban-token-sdk = { version = "25.3.0", path = "soroban-token-sdk" }
29-
soroban-token-spec = { version = "25.3.0", path = "soroban-token-spec" }
30-
stellar-asset-spec = { version = "25.3.0", path = "stellar-asset-spec" }
22+
soroban-sdk = { version = "26.0.0-rc.1", path = "soroban-sdk" }
23+
soroban-sdk-macros = { version = "26.0.0-rc.1", path = "soroban-sdk-macros" }
24+
soroban-meta = { version = "26.0.0-rc.1", path = "soroban-meta" }
25+
soroban-spec = { version = "26.0.0-rc.1", path = "soroban-spec" }
26+
soroban-spec-rust = { version = "26.0.0-rc.1", path = "soroban-spec-rust" }
27+
soroban-ledger-snapshot = { version = "26.0.0-rc.1", path = "soroban-ledger-snapshot" }
28+
soroban-token-sdk = { version = "26.0.0-rc.1", path = "soroban-token-sdk" }
29+
soroban-token-spec = { version = "26.0.0-rc.1", path = "soroban-token-spec" }
30+
stellar-asset-spec = { version = "26.0.0-rc.1", path = "stellar-asset-spec" }
3131

3232
[workspace.dependencies.soroban-env-common]
33-
version = "=25.0.1"
33+
version = "=26.0.1"
3434
# git = "https://github.com/stellar/rs-soroban-env"
35-
# rev = "cf58d535ab05d02802a5e804a95524650f8c62c7"
35+
# rev = "f4d7b3299df8fc19e92769d0a26be2d032b78ccb"
3636

3737
[workspace.dependencies.soroban-env-guest]
38-
version = "=25.0.1"
38+
version = "=26.0.1"
3939
# git = "https://github.com/stellar/rs-soroban-env"
40-
# rev = "cf58d535ab05d02802a5e804a95524650f8c62c7"
40+
# rev = "f4d7b3299df8fc19e92769d0a26be2d032b78ccb"
4141

4242
[workspace.dependencies.soroban-env-host]
43-
version = "=25.0.1"
43+
version = "=26.0.1"
4444
# git = "https://github.com/stellar/rs-soroban-env"
45-
# rev = "cf58d535ab05d02802a5e804a95524650f8c62c7"
45+
# rev = "f4d7b3299df8fc19e92769d0a26be2d032b78ccb"
4646

4747
[workspace.dependencies.stellar-strkey]
4848
version = "=0.0.16"
4949

5050
[workspace.dependencies.stellar-xdr]
51-
version = "=25.0.0"
51+
version = "=26.0.0"
52+
# git = "https://github.com/stellar/rs-stellar-xdr"
53+
# rev = "dd7a165a193126fd37a751d867bee1cb8f3b55a6"
5254
default-features = false
5355
features = ["curr"]
5456

deny.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,8 @@ deny = [
219219

220220
# Certain crates/versions that will be skipped when doing duplicate detection.
221221
skip = [
222-
{ name = "hashbrown", version = "=0.13.2" },
222+
{ name = "hashbrown", version = "=0.14.5" },
223223
{ name = "stellar-strkey", version = "=0.0.13" },
224-
{ name = "syn", version = "=1.0.109" },
225224
]
226225
# Similarly to `skip` allows you to skip certain crates during duplicate
227226
# detection. Unlike skip, it also includes the entire tree of transitive

soroban-ledger-snapshot/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl LedgerSnapshot {
260260
impl Default for LedgerSnapshot {
261261
fn default() -> Self {
262262
Self {
263-
protocol_version: 25,
263+
protocol_version: 26,
264264
sequence_number: Default::default(),
265265
timestamp: Default::default(),
266266
network_id: Default::default(),

soroban-sdk-macros/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ stellar-xdr = { workspace = true, features = ["curr", "std"] }
2222
syn = {version="2.0.77",features=["full"]}
2323
quote = "1.0"
2424
proc-macro2 = "1.0"
25-
itertools = "0.10.5"
25+
itertools = "0.13.0"
2626
darling = "0.20.10"
2727
macro-string = "0.1.4"
2828
sha2 = "0.10.7"

soroban-sdk/src/_migrating.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,40 @@
1+
//! # Migrating from v25 to v26
2+
//!
3+
//! 1. Add support for [CAP-78: Host functions for performing limited TTL extensions](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0078.md).
4+
//! New `extend_ttl_with_limits` methods on [`Persistent`], [`Instance`], and
5+
//! [`Deployer`] provide bounded control over TTL extensions with `min_extension` and
6+
//! `max_extension` parameters.
7+
//!
8+
//! 2. Add support for [CAP-82: Checked 256-bit integer arithmetic host functions](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0082.md).
9+
//! New `checked_*` methods on [`U256`] and [`I256`] (`checked_add`, `checked_sub`,
10+
//! `checked_mul`, `checked_div`, `checked_pow`, `checked_rem_euclid`, `checked_shl`,
11+
//! `checked_shr`) return `Option` instead of panicking on overflow. Also adds
12+
//! `min_value` and `max_value` methods on [`U256`] and [`I256`] to fetch the
13+
//! value bounds of each type.
14+
//!
15+
//! 3. Add support for [CAP-80: Host functions for efficient ZK BN254 use cases](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0080.md).
16+
//! [`BN254`] gains scalar field arithmetic (`Fr` `Add`/`Sub`/`Mul` traits, `pow`, `inv`),
17+
//! multi-scalar multiplication (`g1_msm`), and curve validation (`g1_is_on_curve`).
18+
//! [`BLS12381`] gains `g1_is_on_curve` and `g2_is_on_curve`.
19+
//!
20+
//! 4. Add support for [CAP-79: Host functions for muxed address strkey conversions](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0079.md).
21+
//! New method [`MuxedAddress::to_strkey`] converts muxed addresses to Stellar strkey format.
22+
//!
23+
//! 5. Add support for [CAP-73: Allow SAC to create G-account balances](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0073.md).
24+
//! Update the [`StellarAssetInterface`] to include the new method [`StellarAssetInterface::trust`]. This method creates
25+
//! an unlimited trustline for the contract's asset, if applicable.
26+
//!
27+
//! [`Persistent`]: crate::storage::Persistent
28+
//! [`Instance`]: crate::storage::Instance
29+
//! [`Deployer`]: crate::deploy::Deployer
30+
//! [`U256`]: crate::U256
31+
//! [`I256`]: crate::I256
32+
//! [`MuxedAddress::to_strkey`]: crate::MuxedAddress::to_strkey
33+
//! [`StellarAssetInterface`]: crate::token::StellarAssetInterface
34+
//! [`StellarAssetInterface::trust`]: crate::token::StellarAssetInterface::trust
35+
//! [`BN254`]: crate::crypto::bn254
36+
//! [`BLS12381`]: crate::crypto::bls12_381
37+
//!
138
//! # Migrating from v23 to v25
239
//!
340
//! 1. [`Events::all()` return type changed from `Vec<(Address, Vec<Val>, Val)>` to `ContractEvents`][v25_event_testing].

soroban-sdk/src/crypto.rs

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,36 @@ impl CryptoHazmat {
267267

268268
/// Performs a Poseidon permutation on the input state vector.
269269
///
270-
/// WARNING: This is a low-level permutation function. Most users should use
271-
/// the higher-level `poseidon_hash` function instead.
270+
/// This is a **low-level** permutation primitive. For safe, user-friendly
271+
/// hash functions, use
272+
/// [`rs-soroban-poseidon`](https://github.com/stellar/rs-soroban-poseidon)
273+
/// instead, which provides input validation and standard hash constructions.
274+
///
275+
/// # Field elements and `U256`
276+
///
277+
/// All `U256` values (`input`, `mds`, `round_constants`) are generic
278+
/// representations of field elements in the prime field specified by
279+
/// `field`. If a `U256` value exceeds the field modulus, it is **silently
280+
/// reduced mod the field order**. Two distinct `U256` inputs that reduce
281+
/// to the same field element will produce the same output, leading to
282+
/// unintended collisions. Callers must ensure inputs are already in the
283+
/// valid field range.
284+
///
285+
/// # Parameters
286+
///
287+
/// - `input`: state vector of `t` field elements.
288+
/// - `field`: the prime field (`"BLS12_381"` or `"BN254"`).
289+
/// - `t`: state size (number of field elements).
290+
/// - `d`: S-box degree (5 for BLS12-381 and BN254).
291+
/// - `rounds_f`: number of full rounds (must be even).
292+
/// - `rounds_p`: number of partial rounds.
293+
/// - `mds`: `t`-by-`t` MDS matrix as `Vec<Vec<U256>>`.
294+
/// - `round_constants`: `(rounds_f + rounds_p)`-by-`t` matrix of round
295+
/// constants as `Vec<Vec<U256>>`.
296+
///
297+
/// # Panics
298+
///
299+
/// If any dimension is inconsistent or if `field` is unsupported.
272300
pub fn poseidon_permutation(
273301
&self,
274302
input: &Vec<U256>,
@@ -299,8 +327,38 @@ impl CryptoHazmat {
299327

300328
/// Performs a Poseidon2 permutation on the input state vector.
301329
///
302-
/// WARNING: This is a low-level permutation function. Most users should use
303-
/// the higher-level `poseidon2_hash` function instead.
330+
/// This is a **low-level** permutation primitive. For safe, user-friendly
331+
/// hash functions, use
332+
/// [`rs-soroban-poseidon`](https://github.com/stellar/rs-soroban-poseidon)
333+
/// instead, which provides input validation and standard hash constructions.
334+
///
335+
/// # Field elements and `U256`
336+
///
337+
/// All `U256` values (`input`, `mat_internal_diag_m_1`, `round_constants`)
338+
/// are generic representations of field elements in the prime field
339+
/// specified by `field`. If a `U256` value exceeds the field modulus, it
340+
/// is **silently reduced mod the field order**. Two distinct `U256` inputs
341+
/// that reduce to the same field element will produce the same output,
342+
/// leading to unintended collisions. Callers must ensure inputs are
343+
/// already in the valid field range.
344+
///
345+
/// # Parameters
346+
///
347+
/// - `input`: state vector of `t` field elements.
348+
/// - `field`: the prime field (`"BLS12_381"` or `"BN254"`).
349+
/// - `t`: state size (number of field elements). Only
350+
/// `t` ∈ {2, 3, 4, 8, 12, 16, 20, 24} are supported.
351+
/// - `d`: S-box degree (5 for BLS12-381 and BN254).
352+
/// - `rounds_f`: number of full rounds (must be even).
353+
/// - `rounds_p`: number of partial rounds.
354+
/// - `mat_internal_diag_m_1`: diagonal of the internal matrix minus the
355+
/// identity, as `Vec<U256>` of length `t`.
356+
/// - `round_constants`: `(rounds_f + rounds_p)`-by-`t` matrix of round
357+
/// constants as `Vec<Vec<U256>>`.
358+
///
359+
/// # Panics
360+
///
361+
/// If any dimension is inconsistent or if `field` is unsupported.
304362
pub fn poseidon2_permutation(
305363
&self,
306364
input: &Vec<U256>,

soroban-sdk/src/crypto/bls12_381.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,14 @@ impl Bls12_381 {
603603
res.into()
604604
}
605605

606+
/// Checks if a G1 point is on the BLS12-381 curve (no subgroup check).
607+
pub fn g1_is_on_curve(&self, point: &G1Affine) -> bool {
608+
let env = self.env();
609+
internal::Env::bls12_381_g1_is_on_curve(env, point.to_object())
610+
.unwrap_infallible()
611+
.into()
612+
}
613+
606614
/// Adds two points `p0` and `p1` in G1.
607615
pub fn g1_add(&self, p0: &G1Affine, p1: &G1Affine) -> G1Affine {
608616
let env = self.env();
@@ -671,6 +679,14 @@ impl Bls12_381 {
671679
res.into()
672680
}
673681

682+
/// Checks if a G2 point is on the BLS12-381 curve (no subgroup check).
683+
pub fn g2_is_on_curve(&self, point: &G2Affine) -> bool {
684+
let env = self.env();
685+
internal::Env::bls12_381_g2_is_on_curve(env, point.to_object())
686+
.unwrap_infallible()
687+
.into()
688+
}
689+
674690
/// Adds two points `p0` and `p1` in G2.
675691
pub fn g2_add(&self, p0: &G2Affine, p1: &G2Affine) -> G2Affine {
676692
let env = self.env();

soroban-sdk/src/crypto/bn254.rs

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
use crate::xdr::ScVal;
33
use crate::{
44
crypto::utils::BigInt,
5-
env::internal::{self, BytesObject, U256Val},
5+
env::internal::{self, BytesObject, U256Val, U64Val},
66
impl_bytesn_repr_without_from_bytes,
77
unwrap::{UnwrapInfallible, UnwrapOptimized},
88
Bytes, BytesN, ConversionError, Env, IntoVal, TryFromVal, Val, Vec, U256,
99
};
1010
use core::{
1111
cmp::Ordering,
1212
fmt::Debug,
13-
ops::{Add, Mul, Neg},
13+
ops::{Add, Mul, Neg, Sub},
1414
};
1515

1616
pub const BN254_FP_SERIALIZED_SIZE: usize = 32; // Size in bytes of a serialized Bn254Fp element in BN254. The field modulus is 254 bits, requiring 32 bytes (256 bits).
@@ -254,6 +254,38 @@ impl Fr {
254254
pub fn to_val(&self) -> Val {
255255
self.0.to_val()
256256
}
257+
258+
pub fn pow(&self, rhs: u64) -> Self {
259+
self.env().crypto().bn254().fr_pow(self, rhs)
260+
}
261+
262+
pub fn inv(&self) -> Self {
263+
self.env().crypto().bn254().fr_inv(self)
264+
}
265+
}
266+
267+
impl Add for Fr {
268+
type Output = Fr;
269+
270+
fn add(self, rhs: Self) -> Self::Output {
271+
self.env().crypto().bn254().fr_add(&self, &rhs)
272+
}
273+
}
274+
275+
impl Sub for Fr {
276+
type Output = Fr;
277+
278+
fn sub(self, rhs: Self) -> Self::Output {
279+
self.env().crypto().bn254().fr_sub(&self, &rhs)
280+
}
281+
}
282+
283+
impl Mul for Fr {
284+
type Output = Fr;
285+
286+
fn mul(self, rhs: Self) -> Self::Output {
287+
self.env().crypto().bn254().fr_mul(&self, &rhs)
288+
}
257289
}
258290

259291
// BN254 scalar field modulus r in big-endian bytes.
@@ -386,6 +418,59 @@ impl Bn254 {
386418
.unwrap_infallible()
387419
.into()
388420
}
421+
422+
/// Performs a multi-scalar multiplication (MSM) operation in G1.
423+
pub fn g1_msm(&self, vp: Vec<Bn254G1Affine>, vs: Vec<Fr>) -> Bn254G1Affine {
424+
let env = self.env();
425+
let bin = internal::Env::bn254_g1_msm(env, vp.into(), vs.into()).unwrap_infallible();
426+
unsafe { Bn254G1Affine::from_bytes(BytesN::unchecked_new(env.clone(), bin)) }
427+
}
428+
429+
/// Checks if a G1 point is on the BN254 curve.
430+
pub fn g1_is_on_curve(&self, point: &Bn254G1Affine) -> bool {
431+
let env = self.env();
432+
internal::Env::bn254_g1_is_on_curve(env, point.to_object())
433+
.unwrap_infallible()
434+
.into()
435+
}
436+
437+
// scalar arithmetic
438+
439+
/// Adds two scalars in the BN254 scalar field `Fr`.
440+
pub fn fr_add(&self, lhs: &Fr, rhs: &Fr) -> Fr {
441+
let env = self.env();
442+
let v = internal::Env::bn254_fr_add(env, lhs.into(), rhs.into()).unwrap_infallible();
443+
U256::try_from_val(env, &v).unwrap_infallible().into()
444+
}
445+
446+
/// Subtracts one scalar from another in the BN254 scalar field `Fr`.
447+
pub fn fr_sub(&self, lhs: &Fr, rhs: &Fr) -> Fr {
448+
let env = self.env();
449+
let v = internal::Env::bn254_fr_sub(env, lhs.into(), rhs.into()).unwrap_infallible();
450+
U256::try_from_val(env, &v).unwrap_infallible().into()
451+
}
452+
453+
/// Multiplies two scalars in the BN254 scalar field `Fr`.
454+
pub fn fr_mul(&self, lhs: &Fr, rhs: &Fr) -> Fr {
455+
let env = self.env();
456+
let v = internal::Env::bn254_fr_mul(env, lhs.into(), rhs.into()).unwrap_infallible();
457+
U256::try_from_val(env, &v).unwrap_infallible().into()
458+
}
459+
460+
/// Raises a scalar to the power of a given exponent in the BN254 scalar field `Fr`.
461+
pub fn fr_pow(&self, lhs: &Fr, rhs: u64) -> Fr {
462+
let env = self.env();
463+
let rhs = U64Val::try_from_val(env, &rhs).unwrap_optimized();
464+
let v = internal::Env::bn254_fr_pow(env, lhs.into(), rhs).unwrap_infallible();
465+
U256::try_from_val(env, &v).unwrap_infallible().into()
466+
}
467+
468+
/// Computes the multiplicative inverse of a scalar in the BN254 scalar field `Fr`.
469+
pub fn fr_inv(&self, lhs: &Fr) -> Fr {
470+
let env = self.env();
471+
let v = internal::Env::bn254_fr_inv(env, lhs.into()).unwrap_infallible();
472+
U256::try_from_val(env, &v).unwrap_infallible().into()
473+
}
389474
}
390475

391476
#[cfg(test)]

0 commit comments

Comments
 (0)