1use crate::{
4 env::internal::{self, BytesObject},
5 unwrap::UnwrapInfallible,
6 Bytes, BytesN, ConversionError, Env, IntoVal, TryFromVal, Val,
7};
8
9pub mod bls12_381;
10#[derive(Clone)]
24#[repr(transparent)]
25pub struct Hash<const N: usize>(BytesN<N>);
26
27impl<const N: usize> Hash<N> {
28 #[cfg(test)]
33 pub(crate) fn from_bytes(bytes: BytesN<N>) -> Self {
34 Self(bytes)
35 }
36
37 #[inline(always)]
39 pub fn to_bytes(&self) -> BytesN<N> {
40 self.0.clone()
41 }
42
43 #[inline(always)]
45 pub fn to_array(&self) -> [u8; N] {
46 self.0.to_array()
47 }
48
49 pub fn as_val(&self) -> &Val {
50 self.0.as_val()
51 }
52
53 pub fn to_val(&self) -> Val {
54 self.0.to_val()
55 }
56
57 pub fn as_object(&self) -> &BytesObject {
58 self.0.as_object()
59 }
60
61 pub fn to_object(&self) -> BytesObject {
62 self.0.to_object()
63 }
64}
65
66impl<const N: usize> IntoVal<Env, Val> for Hash<N> {
67 fn into_val(&self, e: &Env) -> Val {
68 self.0.into_val(e)
69 }
70}
71
72impl<const N: usize> IntoVal<Env, BytesN<N>> for Hash<N> {
73 fn into_val(&self, _e: &Env) -> BytesN<N> {
74 self.0.clone()
75 }
76}
77
78impl<const N: usize> From<Hash<N>> for Bytes {
79 fn from(v: Hash<N>) -> Self {
80 v.0.into()
81 }
82}
83
84impl<const N: usize> From<Hash<N>> for BytesN<N> {
85 fn from(v: Hash<N>) -> Self {
86 v.0
87 }
88}
89
90impl<const N: usize> Into<[u8; N]> for Hash<N> {
91 fn into(self) -> [u8; N] {
92 self.0.into()
93 }
94}
95
96#[allow(deprecated)]
97impl<const N: usize> crate::TryFromValForContractFn<Env, Val> for Hash<N> {
98 type Error = ConversionError;
99
100 fn try_from_val_for_contract_fn(env: &Env, v: &Val) -> Result<Self, Self::Error> {
101 Ok(Hash(BytesN::<N>::try_from_val(env, v)?))
102 }
103}
104
105pub struct Crypto {
107 env: Env,
108}
109
110impl Crypto {
111 pub(crate) fn new(env: &Env) -> Crypto {
112 Crypto { env: env.clone() }
113 }
114
115 pub fn env(&self) -> &Env {
116 &self.env
117 }
118
119 pub fn sha256(&self, data: &Bytes) -> Hash<32> {
121 let env = self.env();
122 let bin = internal::Env::compute_hash_sha256(env, data.into()).unwrap_infallible();
123 unsafe { Hash(BytesN::unchecked_new(env.clone(), bin)) }
124 }
125
126 pub fn keccak256(&self, data: &Bytes) -> Hash<32> {
128 let env = self.env();
129 let bin = internal::Env::compute_hash_keccak256(env, data.into()).unwrap_infallible();
130 unsafe { Hash(BytesN::unchecked_new(env.clone(), bin)) }
131 }
132
133 pub fn ed25519_verify(&self, public_key: &BytesN<32>, message: &Bytes, signature: &BytesN<64>) {
142 let env = self.env();
143 let _ = internal::Env::verify_sig_ed25519(
144 env,
145 public_key.to_object(),
146 message.to_object(),
147 signature.to_object(),
148 );
149 }
150
151 pub fn secp256k1_recover(
157 &self,
158 message_digest: &Hash<32>,
159 signature: &BytesN<64>,
160 recorvery_id: u32,
161 ) -> BytesN<65> {
162 let env = self.env();
163 CryptoHazmat::new(env).secp256k1_recover(&message_digest.0, signature, recorvery_id)
164 }
165
166 pub fn secp256r1_verify(
171 &self,
172 public_key: &BytesN<65>,
173 message_digest: &Hash<32>,
174 signature: &BytesN<64>,
175 ) {
176 let env = self.env();
177 CryptoHazmat::new(env).secp256r1_verify(public_key, &message_digest.0, signature)
178 }
179
180 pub fn bls12_381(&self) -> bls12_381::Bls12_381 {
183 bls12_381::Bls12_381::new(self.env())
184 }
185}
186
187#[cfg(any(test, feature = "hazmat"))]
194#[cfg_attr(feature = "docs", doc(cfg(feature = "hazmat")))]
195pub struct CryptoHazmat {
196 env: Env,
197}
198#[cfg(not(any(test, feature = "hazmat")))]
199pub(crate) struct CryptoHazmat {
200 env: Env,
201}
202
203impl CryptoHazmat {
204 pub(crate) fn new(env: &Env) -> CryptoHazmat {
205 CryptoHazmat { env: env.clone() }
206 }
207
208 pub fn env(&self) -> &Env {
209 &self.env
210 }
211
212 pub fn secp256k1_recover(
222 &self,
223 message_digest: &BytesN<32>,
224 signature: &BytesN<64>,
225 recorvery_id: u32,
226 ) -> BytesN<65> {
227 let env = self.env();
228 let bytes = internal::Env::recover_key_ecdsa_secp256k1(
229 env,
230 message_digest.to_object(),
231 signature.to_object(),
232 recorvery_id.into(),
233 )
234 .unwrap_infallible();
235 unsafe { BytesN::unchecked_new(env.clone(), bytes) }
236 }
237
238 pub fn secp256r1_verify(
247 &self,
248 public_key: &BytesN<65>,
249 message_digest: &BytesN<32>,
250 signature: &BytesN<64>,
251 ) {
252 let env = self.env();
253 let _ = internal::Env::verify_sig_ecdsa_secp256r1(
254 env,
255 public_key.to_object(),
256 message_digest.to_object(),
257 signature.to_object(),
258 )
259 .unwrap_infallible();
260 }
261}