1use crate::{
4 env::internal::{self, BytesObject},
5 unwrap::UnwrapInfallible,
6 Bytes, BytesN, ConversionError, Env, IntoVal, Symbol, TryFromVal, TryIntoVal, Val, Vec, U256,
7};
8
9pub mod bls12_381;
10pub mod bn254;
11pub(crate) mod utils;
12pub use bn254::Fr as BnScalar;
13
14#[derive(Clone)]
28#[repr(transparent)]
29pub struct Hash<const N: usize>(BytesN<N>);
30
31impl<const N: usize> Hash<N> {
32 #[cfg(test)]
37 pub(crate) fn from_bytes(bytes: BytesN<N>) -> Self {
38 Self(bytes)
39 }
40
41 #[inline(always)]
43 pub fn to_bytes(&self) -> BytesN<N> {
44 self.0.clone()
45 }
46
47 #[inline(always)]
49 pub fn to_array(&self) -> [u8; N] {
50 self.0.to_array()
51 }
52
53 pub fn as_val(&self) -> &Val {
54 self.0.as_val()
55 }
56
57 pub fn to_val(&self) -> Val {
58 self.0.to_val()
59 }
60
61 pub fn as_object(&self) -> &BytesObject {
62 self.0.as_object()
63 }
64
65 pub fn to_object(&self) -> BytesObject {
66 self.0.to_object()
67 }
68}
69
70impl<const N: usize> IntoVal<Env, Val> for Hash<N> {
71 fn into_val(&self, e: &Env) -> Val {
72 self.0.into_val(e)
73 }
74}
75
76impl<const N: usize> IntoVal<Env, BytesN<N>> for Hash<N> {
77 fn into_val(&self, _e: &Env) -> BytesN<N> {
78 self.0.clone()
79 }
80}
81
82impl<const N: usize> From<Hash<N>> for Bytes {
83 fn from(v: Hash<N>) -> Self {
84 v.0.into()
85 }
86}
87
88impl<const N: usize> From<Hash<N>> for BytesN<N> {
89 fn from(v: Hash<N>) -> Self {
90 v.0
91 }
92}
93
94impl<const N: usize> Into<[u8; N]> for Hash<N> {
95 fn into(self) -> [u8; N] {
96 self.0.into()
97 }
98}
99
100#[allow(deprecated)]
101impl<const N: usize> crate::TryFromValForContractFn<Env, Val> for Hash<N> {
102 type Error = ConversionError;
103
104 fn try_from_val_for_contract_fn(env: &Env, v: &Val) -> Result<Self, Self::Error> {
105 Ok(Hash(BytesN::<N>::try_from_val(env, v)?))
106 }
107}
108
109pub struct Crypto {
111 env: Env,
112}
113
114impl Crypto {
115 pub(crate) fn new(env: &Env) -> Crypto {
116 Crypto { env: env.clone() }
117 }
118
119 pub fn env(&self) -> &Env {
120 &self.env
121 }
122
123 pub fn sha256(&self, data: &Bytes) -> Hash<32> {
125 let env = self.env();
126 let bin = internal::Env::compute_hash_sha256(env, data.into()).unwrap_infallible();
127 unsafe { Hash(BytesN::unchecked_new(env.clone(), bin)) }
128 }
129
130 pub fn keccak256(&self, data: &Bytes) -> Hash<32> {
132 let env = self.env();
133 let bin = internal::Env::compute_hash_keccak256(env, data.into()).unwrap_infallible();
134 unsafe { Hash(BytesN::unchecked_new(env.clone(), bin)) }
135 }
136
137 pub fn ed25519_verify(&self, public_key: &BytesN<32>, message: &Bytes, signature: &BytesN<64>) {
146 let env = self.env();
147 let _ = internal::Env::verify_sig_ed25519(
148 env,
149 public_key.to_object(),
150 message.to_object(),
151 signature.to_object(),
152 );
153 }
154
155 pub fn secp256k1_recover(
161 &self,
162 message_digest: &Hash<32>,
163 signature: &BytesN<64>,
164 recorvery_id: u32,
165 ) -> BytesN<65> {
166 let env = self.env();
167 CryptoHazmat::new(env).secp256k1_recover(&message_digest.0, signature, recorvery_id)
168 }
169
170 pub fn secp256r1_verify(
175 &self,
176 public_key: &BytesN<65>,
177 message_digest: &Hash<32>,
178 signature: &BytesN<64>,
179 ) {
180 let env = self.env();
181 CryptoHazmat::new(env).secp256r1_verify(public_key, &message_digest.0, signature)
182 }
183
184 pub fn bls12_381(&self) -> bls12_381::Bls12_381 {
187 bls12_381::Bls12_381::new(self.env())
188 }
189
190 pub fn bn254(&self) -> bn254::Bn254 {
193 bn254::Bn254::new(self.env())
194 }
195}
196
197#[cfg_attr(any(test, feature = "hazmat-crypto"), visibility::make(pub))]
204#[cfg_attr(feature = "docs", doc(cfg(feature = "hazmat-crypto")))]
205pub(crate) struct CryptoHazmat {
206 env: Env,
207}
208
209impl CryptoHazmat {
210 pub(crate) fn new(env: &Env) -> CryptoHazmat {
211 CryptoHazmat { env: env.clone() }
212 }
213
214 pub fn env(&self) -> &Env {
215 &self.env
216 }
217
218 pub fn secp256k1_recover(
228 &self,
229 message_digest: &BytesN<32>,
230 signature: &BytesN<64>,
231 recorvery_id: u32,
232 ) -> BytesN<65> {
233 let env = self.env();
234 let bytes = internal::Env::recover_key_ecdsa_secp256k1(
235 env,
236 message_digest.to_object(),
237 signature.to_object(),
238 recorvery_id.into(),
239 )
240 .unwrap_infallible();
241 unsafe { BytesN::unchecked_new(env.clone(), bytes) }
242 }
243
244 pub fn secp256r1_verify(
253 &self,
254 public_key: &BytesN<65>,
255 message_digest: &BytesN<32>,
256 signature: &BytesN<64>,
257 ) {
258 let env = self.env();
259 let _ = internal::Env::verify_sig_ecdsa_secp256r1(
260 env,
261 public_key.to_object(),
262 message_digest.to_object(),
263 signature.to_object(),
264 )
265 .unwrap_infallible();
266 }
267
268 pub fn poseidon_permutation(
273 &self,
274 input: &Vec<U256>,
275 field: Symbol,
276 t: u32,
277 d: u32,
278 rounds_f: u32,
279 rounds_p: u32,
280 mds: &Vec<Vec<U256>>,
281 round_constants: &Vec<Vec<U256>>,
282 ) -> Vec<U256> {
283 let env = self.env();
284 let result = internal::Env::poseidon_permutation(
285 env,
286 input.to_object(),
287 field.to_symbol_val(),
288 t.into(),
289 d.into(),
290 rounds_f.into(),
291 rounds_p.into(),
292 mds.to_object(),
293 round_constants.to_object(),
294 )
295 .unwrap_infallible();
296
297 result.try_into_val(env).unwrap_infallible()
298 }
299
300 pub fn poseidon2_permutation(
305 &self,
306 input: &Vec<U256>,
307 field: Symbol,
308 t: u32,
309 d: u32,
310 rounds_f: u32,
311 rounds_p: u32,
312 mat_internal_diag_m_1: &Vec<U256>,
313 round_constants: &Vec<Vec<U256>>,
314 ) -> Vec<U256> {
315 let env = self.env();
316 let result = internal::Env::poseidon2_permutation(
317 env,
318 input.to_object(),
319 field.to_symbol_val(),
320 t.into(),
321 d.into(),
322 rounds_f.into(),
323 rounds_p.into(),
324 mat_internal_diag_m_1.to_object(),
325 round_constants.to_object(),
326 )
327 .unwrap_infallible();
328
329 result.try_into_val(env).unwrap_infallible()
330 }
331}