k256/
coord.rs

1use alloc::vec::Vec;
2
3use elliptic_curve::subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
4use openvm_algebra_guest::IntMod;
5
6use crate::internal::Secp256k1Coord;
7
8// --- Implement elliptic_curve traits on Secp256k1Coord ---
9
10impl Copy for Secp256k1Coord {}
11
12impl Default for Secp256k1Coord {
13    fn default() -> Self {
14        <Self as IntMod>::ZERO
15    }
16}
17
18impl ConditionallySelectable for Secp256k1Coord {
19    fn conditional_select(
20        a: &Secp256k1Coord,
21        b: &Secp256k1Coord,
22        choice: Choice,
23    ) -> Secp256k1Coord {
24        Secp256k1Coord::from_le_bytes_unchecked(
25            &a.as_le_bytes()
26                .iter()
27                .zip(b.as_le_bytes().iter())
28                .map(|(a, b)| u8::conditional_select(a, b, choice))
29                .collect::<Vec<_>>(),
30        )
31    }
32}
33
34impl ConstantTimeEq for Secp256k1Coord {
35    fn ct_eq(&self, other: &Secp256k1Coord) -> Choice {
36        #[cfg(not(target_os = "zkvm"))]
37        {
38            // Requires canonical form
39            self.as_le_bytes().ct_eq(other.as_le_bytes())
40        }
41        #[cfg(target_os = "zkvm")]
42        {
43            // The zkVM implementation calls iseqmod opcode so it is constant time, _except_ a check
44            // of whether the setup opcode has been called already
45            Choice::from((self == other) as u8)
46        }
47    }
48}