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
54pub 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 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
104pub 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
172pub 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}