mina_tree/util/
mod.rs

1use std::ops::Neg;
2
3use ark_ff::{BigInteger, PrimeField};
4use mina_curves::pasta::{Fp, Fq};
5use mina_signer::{CompressedPubKey, CurvePoint, Keypair, PubKey};
6
7mod backtrace;
8mod pubkey;
9
10pub use pubkey::compressed_pubkey_from_address_maybe_with_error;
11
12use crate::proofs::{field::FieldWitness, to_field_elements::ToFieldElements};
13pub use crate::util::backtrace::*;
14
15#[cfg(not(target_family = "wasm"))]
16pub fn pid() -> u32 {
17    std::process::id()
18}
19
20#[cfg(target_family = "wasm")]
21pub fn pid() -> u32 {
22    0
23}
24
25pub trait FpExt {
26    fn to_decimal(&self) -> String;
27}
28
29impl FpExt for Fp {
30    fn to_decimal(&self) -> String {
31        let r = self.into_repr();
32        let bigint: num_bigint::BigUint = r.into();
33        bigint.to_string()
34    }
35}
36
37impl FpExt for Fq {
38    fn to_decimal(&self) -> String {
39        let r = self.into_repr();
40        let bigint: num_bigint::BigUint = r.into();
41        bigint.to_string()
42    }
43}
44
45pub fn gen_keypair() -> Keypair {
46    let mut rng = rand::thread_rng();
47    Keypair::rand(&mut rng).unwrap()
48}
49
50pub fn gen_compressed() -> CompressedPubKey {
51    gen_keypair().public.into_compressed()
52}
53
54/// Not sure if it's correct
55/// I used the same code as there:
56/// <https://github.com/o1-labs/proof-systems/blob/226de4aeb11b8814327ab832e4fccdce5585f473/signer/src/pubkey.rs#L95-L106>
57pub fn decompress_pk(pk: &CompressedPubKey) -> Option<PubKey> {
58    let y_parity = pk.is_odd;
59    let x = pk.x;
60
61    let mut pt = CurvePoint::get_point_from_x(x, y_parity)?;
62
63    if pt.y.into_repr().is_even() == y_parity {
64        pt.y = pt.y.neg();
65    }
66
67    if !pt.is_on_curve() {
68        return None;
69    }
70
71    // Safe now because we checked point pt is on curve
72    Some(PubKey::from_point_unsafe(pt))
73}
74
75pub fn take<T>(slice: &[T], n: usize) -> &[T] {
76    slice.get(..n).unwrap_or(slice)
77}
78
79pub fn drop<T>(slice: &[T], n: usize) -> &[T] {
80    slice.get(n..).unwrap_or(&[])
81}
82
83pub fn take_at<T>(slice: &[T], skip: usize, n: usize) -> &[T] {
84    slice.get(skip..).map(|s| take(s, n)).unwrap_or(&[])
85}
86
87pub fn split_at<T>(slice: &[T], at: usize) -> (&[T], &[T]) {
88    if at <= slice.len() {
89        slice.split_at(at)
90    } else {
91        (slice, &[])
92    }
93}
94
95pub fn split_at_vec<T>(mut vec: Vec<T>, at: usize) -> (Vec<T>, Vec<T>) {
96    if at <= vec.len() {
97        let vec2 = vec.split_off(at);
98        (vec, vec2)
99    } else {
100        (vec, Vec::new())
101    }
102}
103
104// `std::borrow::Cow` has a `ToOwned` constraints
105pub enum MyCow<'a, T> {
106    Borrow(&'a T),
107    Own(T),
108}
109
110impl<'a, T> MyCow<'a, T> {
111    pub fn borrow_or_default(v: &'a Option<T>) -> Self
112    where
113        T: Default,
114    {
115        match v.as_ref() {
116            Some(v) => Self::Borrow(v),
117            None => Self::Own(T::default()),
118        }
119    }
120
121    pub fn borrow_or_else<F>(v: &'a Option<T>, default: F) -> Self
122    where
123        F: FnOnce() -> T,
124    {
125        match v.as_ref() {
126            Some(v) => Self::Borrow(v),
127            None => Self::Own(default()),
128        }
129    }
130}
131
132impl<T> MyCow<'_, T>
133where
134    T: ToOwned<Owned = T>,
135{
136    pub fn to_owned(self) -> T {
137        match self {
138            MyCow::Borrow(v) => v.to_owned(),
139            MyCow::Own(v) => v,
140        }
141    }
142}
143
144impl<T> std::ops::Deref for MyCow<'_, T> {
145    type Target = T;
146
147    fn deref(&self) -> &Self::Target {
148        self.as_ref()
149    }
150}
151
152impl<T> AsRef<T> for MyCow<'_, T> {
153    fn as_ref(&self) -> &T {
154        match self {
155            MyCow::Borrow(v) => v,
156            MyCow::Own(v) => v,
157        }
158    }
159}
160
161impl<F, T> ToFieldElements<F> for MyCow<'_, T>
162where
163    F: FieldWitness,
164    T: ToFieldElements<F>,
165{
166    fn to_field_elements(&self, fields: &mut Vec<F>) {
167        let this: &T = self;
168        this.to_field_elements(fields);
169    }
170}
171
172// `std::borrow::Cow` has a `ToOwned` constraints
173pub enum MyCowMut<'a, T> {
174    Borrow(&'a mut T),
175    Own(T),
176}
177
178impl<T> std::ops::Deref for MyCowMut<'_, T> {
179    type Target = T;
180
181    fn deref(&self) -> &Self::Target {
182        match self {
183            MyCowMut::Borrow(v) => v,
184            MyCowMut::Own(v) => v,
185        }
186    }
187}
188
189impl<T> std::ops::DerefMut for MyCowMut<'_, T> {
190    fn deref_mut(&mut self) -> &mut Self::Target {
191        match self {
192            MyCowMut::Borrow(v) => v,
193            MyCowMut::Own(v) => v,
194        }
195    }
196}