Skip to content

Commit 63b478e

Browse files
avi-starkwareclaude
andcommitted
fix StubSyscallHandler secp ops returning identity element
The secp256k1_add / secp256k1_mul / secp256r1_add / secp256r1_mul stub implementations called `p.to_encoded_point(false)` and then assumed the result was Coordinates::Uncompressed. The identity element returns Coordinates::Identity instead, so P + (-P) and k * P (mod ord) panicked with unreachable!(). Pre-existing bug in sierra-emu, surfaced more visibly by the trait alignment in this PR (which added is_infinity to the surface). Add an explicit Coordinates::Identity arm to all four sites, returning the canonical (0, 0) + is_infinity: true point. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 8675039 commit 63b478e

2 files changed

Lines changed: 43 additions & 11 deletions

File tree

debug_utils/sierra-emu/src/starknet.rs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ pub trait StarknetSyscallHandler {
3939

4040
fn get_execution_info_v2(&mut self, remaining_gas: &mut u64) -> SyscallResult<ExecutionInfoV2>;
4141

42-
fn get_execution_info_v3(&mut self, _remaining_gas: &mut u64) -> SyscallResult<ExecutionInfoV3> {
42+
fn get_execution_info_v3(
43+
&mut self,
44+
_remaining_gas: &mut u64,
45+
) -> SyscallResult<ExecutionInfoV3> {
4346
unimplemented!()
4447
}
4548

@@ -500,9 +503,17 @@ impl StarknetSyscallHandler for StubSyscallHandler {
500503
let p = p.to_encoded_point(false);
501504
let (x, y) = match p.coordinates() {
502505
Coordinates::Uncompressed { x, y } => (x, y),
506+
Coordinates::Identity => {
507+
// P + (-P) yields the identity. Return the canonical (0, 0) +
508+
// is_infinity encoding (see Secp256k1Point::into_value).
509+
return Ok(Secp256k1Point {
510+
x: U256 { lo: 0, hi: 0 },
511+
y: U256 { lo: 0, hi: 0 },
512+
is_infinity: true,
513+
});
514+
}
503515
_ => {
504-
// This should be unreachable because we explicitly asked for the uncompressed
505-
// encoding.
516+
// We explicitly asked for the uncompressed encoding.
506517
unreachable!()
507518
}
508519
};
@@ -565,9 +576,16 @@ impl StarknetSyscallHandler for StubSyscallHandler {
565576
let p = p.to_encoded_point(false);
566577
let (x, y) = match p.coordinates() {
567578
Coordinates::Uncompressed { x, y } => (x, y),
579+
Coordinates::Identity => {
580+
// m * P can be the identity (e.g. m = ord(P)).
581+
return Ok(Secp256k1Point {
582+
x: U256 { lo: 0, hi: 0 },
583+
y: U256 { lo: 0, hi: 0 },
584+
is_infinity: true,
585+
});
586+
}
568587
_ => {
569-
// This should be unreachable because we explicitly asked for the uncompressed
570-
// encoding.
588+
// We explicitly asked for the uncompressed encoding.
571589
unreachable!()
572590
}
573591
};
@@ -737,9 +755,17 @@ impl StarknetSyscallHandler for StubSyscallHandler {
737755
let p = p.to_encoded_point(false);
738756
let (x, y) = match p.coordinates() {
739757
Coordinates::Uncompressed { x, y } => (x, y),
758+
Coordinates::Identity => {
759+
// P + (-P) yields the identity. Return the canonical (0, 0) +
760+
// is_infinity encoding (see Secp256r1Point::into_value).
761+
return Ok(Secp256r1Point {
762+
x: U256 { lo: 0, hi: 0 },
763+
y: U256 { lo: 0, hi: 0 },
764+
is_infinity: true,
765+
});
766+
}
740767
_ => {
741-
// This should be unreachable because we explicitly asked for the uncompressed
742-
// encoding.
768+
// We explicitly asked for the uncompressed encoding.
743769
unreachable!()
744770
}
745771
};
@@ -801,9 +827,16 @@ impl StarknetSyscallHandler for StubSyscallHandler {
801827
let p = p.to_encoded_point(false);
802828
let (x, y) = match p.coordinates() {
803829
Coordinates::Uncompressed { x, y } => (x, y),
830+
Coordinates::Identity => {
831+
// m * P can be the identity (e.g. m = ord(P)).
832+
return Ok(Secp256r1Point {
833+
x: U256 { lo: 0, hi: 0 },
834+
y: U256 { lo: 0, hi: 0 },
835+
is_infinity: true,
836+
});
837+
}
804838
_ => {
805-
// This should be unreachable because we explicitly asked for the uncompressed
806-
// encoding.
839+
// We explicitly asked for the uncompressed encoding.
807840
unreachable!()
808841
}
809842
};

debug_utils/sierra-emu/src/vm/starknet.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,7 @@ fn eval_call_contract(
655655
}
656656
};
657657

658-
let result =
659-
syscall_handler.call_contract(address, entry_point_selector, &calldata, &mut gas);
658+
let result = syscall_handler.call_contract(address, entry_point_selector, &calldata, &mut gas);
660659

661660
match result {
662661
Ok(return_values) => EvalAction::NormalBranch(

0 commit comments

Comments
 (0)