dharitri_sc/types/managed/basic/
elliptic_curve.rs

1use crate::{
2    abi::{TypeAbi, TypeAbiFrom, TypeName},
3    api::{use_raw_handle, BigIntApiImpl, EllipticCurveApiImpl, ManagedTypeApi},
4    types::{BigUint, ManagedType},
5};
6
7use crate::{api::StaticVarApiImpl, types::ManagedBuffer};
8
9use crate::codec::*;
10
11pub const ELLIPTIC_CURVE_P224_INT: u32 = 224;
12pub const ELLIPTIC_CURVE_P224_NAME: &str = "p224";
13pub const ELLIPTIC_CURVE_P256_INT: u32 = 256;
14pub const ELLIPTIC_CURVE_P256_NAME: &str = "p256";
15pub const ELLIPTIC_CURVE_P384_INT: u32 = 384;
16pub const ELLIPTIC_CURVE_P384_NAME: &str = "p384";
17pub const ELLIPTIC_CURVE_P521_INT: u32 = 521;
18pub const ELLIPTIC_CURVE_P521_NAME: &str = "p521";
19
20pub type EllipticCurveComponents<M> = (
21    BigUint<M>,
22    BigUint<M>,
23    BigUint<M>,
24    BigUint<M>,
25    BigUint<M>,
26    u32,
27);
28
29#[repr(transparent)]
30#[derive(Debug)]
31pub struct EllipticCurve<M: ManagedTypeApi> {
32    pub(super) handle: M::EllipticCurveHandle,
33}
34
35impl<M: ManagedTypeApi> ManagedType<M> for EllipticCurve<M> {
36    type OwnHandle = M::EllipticCurveHandle;
37
38    unsafe fn from_handle(handle: M::EllipticCurveHandle) -> Self {
39        EllipticCurve { handle }
40    }
41
42    fn get_handle(&self) -> M::EllipticCurveHandle {
43        self.handle.clone()
44    }
45
46    unsafe fn forget_into_handle(self) -> Self::OwnHandle {
47        unsafe {
48            let handle = core::ptr::read(&self.handle);
49            core::mem::forget(self);
50            handle
51        }
52    }
53
54    fn transmute_from_handle_ref(handle_ref: &M::EllipticCurveHandle) -> &Self {
55        unsafe { core::mem::transmute(handle_ref) }
56    }
57
58    fn transmute_from_handle_ref_mut(handle_ref: &mut M::EllipticCurveHandle) -> &mut Self {
59        unsafe { core::mem::transmute(handle_ref) }
60    }
61}
62
63impl<M: ManagedTypeApi> EllipticCurve<M> {
64    pub fn from_name(name: &ManagedBuffer<M>) -> Self {
65        let handle = M::managed_type_impl().ec_create_from_name_mb(name.get_handle());
66        unsafe { EllipticCurve::from_handle(handle) }
67    }
68
69    pub fn from_name_str(name: &str) -> Self {
70        let handle = M::managed_type_impl().ec_create_from_name_bytes(name.as_bytes());
71        unsafe { EllipticCurve::from_handle(handle) }
72    }
73
74    pub fn from_bitsize(bitsize: u32) -> Option<Self> {
75        match bitsize {
76            ELLIPTIC_CURVE_P224_INT => Some(Self::from_name_str(ELLIPTIC_CURVE_P224_NAME)),
77            ELLIPTIC_CURVE_P256_INT => Some(Self::from_name_str(ELLIPTIC_CURVE_P256_NAME)),
78            ELLIPTIC_CURVE_P384_INT => Some(Self::from_name_str(ELLIPTIC_CURVE_P384_NAME)),
79            ELLIPTIC_CURVE_P521_INT => Some(Self::from_name_str(ELLIPTIC_CURVE_P521_NAME)),
80            _ => None,
81        }
82    }
83
84    pub fn get_values(&self) -> EllipticCurveComponents<M> {
85        let api = M::managed_type_impl();
86        let field_order_handle = api.bi_new_zero();
87        let base_point_order_handle = api.bi_new_zero();
88        let eq_constant_handle = api.bi_new_zero();
89        let x_base_point_handle = api.bi_new_zero();
90        let y_base_point_handle = api.bi_new_zero();
91        api.ec_get_values(
92            self.handle.clone(),
93            field_order_handle.clone(),
94            base_point_order_handle.clone(),
95            eq_constant_handle.clone(),
96            x_base_point_handle.clone(),
97            y_base_point_handle.clone(),
98        );
99        unsafe {
100            (
101                BigUint::from_handle(field_order_handle),
102                BigUint::from_handle(base_point_order_handle),
103                BigUint::from_handle(eq_constant_handle),
104                BigUint::from_handle(x_base_point_handle),
105                BigUint::from_handle(y_base_point_handle),
106                api.ec_curve_length(self.handle.clone()),
107            )
108        }
109    }
110
111    pub fn get_curve_length(&self) -> u32 {
112        let api = M::managed_type_impl();
113        api.ec_curve_length(self.handle.clone())
114    }
115
116    pub fn get_priv_key_byte_length(&self) -> u32 {
117        let api = M::managed_type_impl();
118        api.ec_private_key_byte_length(self.handle.clone())
119    }
120
121    pub fn add(
122        &self,
123        x_first_point: BigUint<M>,
124        y_first_point: BigUint<M>,
125        x_second_point: BigUint<M>,
126        y_second_point: BigUint<M>,
127    ) -> (BigUint<M>, BigUint<M>) {
128        let api = M::managed_type_impl();
129        let x_result_handle = api.bi_new_zero();
130        let y_result_handle = api.bi_new_zero();
131        api.ec_add(
132            x_result_handle.clone(),
133            y_result_handle.clone(),
134            self.handle.clone(),
135            x_first_point.value.handle,
136            y_first_point.value.handle,
137            x_second_point.value.handle,
138            y_second_point.value.handle,
139        );
140        unsafe {
141            (
142                BigUint::from_handle(x_result_handle),
143                BigUint::from_handle(y_result_handle),
144            )
145        }
146    }
147
148    pub fn double(&self, x_point: BigUint<M>, y_point: BigUint<M>) -> (BigUint<M>, BigUint<M>) {
149        let api = M::managed_type_impl();
150        let x_result_handle = api.bi_new_zero();
151        let y_result_handle = api.bi_new_zero();
152        api.ec_double(
153            x_result_handle.clone(),
154            y_result_handle.clone(),
155            self.handle.clone(),
156            x_point.value.handle,
157            y_point.value.handle,
158        );
159        unsafe {
160            (
161                BigUint::from_handle(x_result_handle),
162                BigUint::from_handle(y_result_handle),
163            )
164        }
165    }
166
167    pub fn is_on_curve(&self, x_point: BigUint<M>, y_point: BigUint<M>) -> bool {
168        let api = M::managed_type_impl();
169        api.ec_is_on_curve(
170            self.handle.clone(),
171            x_point.value.handle,
172            y_point.value.handle,
173        )
174    }
175
176    #[deprecated(since = "0.41.0", note = "Please use method `scalar_mult` instead.")]
177    pub fn scalar_mult_legacy(
178        &self,
179        x_point: BigUint<M>,
180        y_point: BigUint<M>,
181        data: &[u8],
182    ) -> (BigUint<M>, BigUint<M>) {
183        let api = M::managed_type_impl();
184        let x_result_handle = api.bi_new_zero();
185        let y_result_handle = api.bi_new_zero();
186        api.ec_scalar_mult_legacy(
187            x_result_handle.clone(),
188            y_result_handle.clone(),
189            self.handle.clone(),
190            x_point.value.handle,
191            y_point.value.handle,
192            data,
193        );
194        unsafe {
195            (
196                BigUint::from_handle(x_result_handle),
197                BigUint::from_handle(y_result_handle),
198            )
199        }
200    }
201
202    pub fn scalar_mult(
203        &self,
204        x_point: BigUint<M>,
205        y_point: BigUint<M>,
206        data: &ManagedBuffer<M>,
207    ) -> (BigUint<M>, BigUint<M>) {
208        let api = M::managed_type_impl();
209        let x_result_handle = api.bi_new_zero();
210        let y_result_handle = api.bi_new_zero();
211        api.ec_scalar_mult(
212            x_result_handle.clone(),
213            y_result_handle.clone(),
214            self.handle.clone(),
215            x_point.value.handle,
216            y_point.value.handle,
217            data.get_handle(),
218        );
219        unsafe {
220            (
221                BigUint::from_handle(x_result_handle),
222                BigUint::from_handle(y_result_handle),
223            )
224        }
225    }
226
227    #[deprecated(
228        since = "0.41.0",
229        note = "Please use method `scalar_base_mult` instead."
230    )]
231    pub fn scalar_base_mult_legacy(&self, data: &[u8]) -> (BigUint<M>, BigUint<M>) {
232        let api = M::managed_type_impl();
233        let x_result_handle = api.bi_new_zero();
234        let y_result_handle = api.bi_new_zero();
235        api.ec_scalar_base_mult_legacy(
236            x_result_handle.clone(),
237            y_result_handle.clone(),
238            self.handle.clone(),
239            data,
240        );
241        unsafe {
242            (
243                BigUint::from_handle(x_result_handle),
244                BigUint::from_handle(y_result_handle),
245            )
246        }
247    }
248
249    pub fn scalar_base_mult(&self, data: &ManagedBuffer<M>) -> (BigUint<M>, BigUint<M>) {
250        let api = M::managed_type_impl();
251        let x_result_handle = api.bi_new_zero();
252        let y_result_handle = api.bi_new_zero();
253        api.ec_scalar_base_mult(
254            x_result_handle.clone(),
255            y_result_handle.clone(),
256            self.handle.clone(),
257            data.get_handle(),
258        );
259        unsafe {
260            (
261                BigUint::from_handle(x_result_handle),
262                BigUint::from_handle(y_result_handle),
263            )
264        }
265    }
266
267    #[deprecated(since = "0.41.0", note = "Please use method `marshal` instead.")]
268    #[cfg(feature = "alloc")]
269    pub fn marshal_legacy(
270        &self,
271        x_pair: BigUint<M>,
272        y_pair: BigUint<M>,
273    ) -> crate::types::heap::BoxedBytes {
274        let api = M::managed_type_impl();
275        api.ec_marshal_legacy(
276            self.handle.clone(),
277            x_pair.value.handle,
278            y_pair.value.handle,
279        )
280    }
281
282    pub fn marshal(&self, x_pair: BigUint<M>, y_pair: BigUint<M>) -> ManagedBuffer<M> {
283        let result_handle: M::ManagedBufferHandle =
284            use_raw_handle(M::static_var_api_impl().next_handle());
285        M::managed_type_impl().ec_marshal(
286            self.handle.clone(),
287            x_pair.value.handle,
288            y_pair.value.handle,
289            result_handle.clone(),
290        );
291        unsafe { ManagedBuffer::from_handle(result_handle) }
292    }
293
294    #[deprecated(
295        since = "0.41.0",
296        note = "Please use method `marshal_compressed` instead."
297    )]
298    #[cfg(feature = "alloc")]
299    pub fn marshal_compressed_legacy(
300        &self,
301        x_pair: BigUint<M>,
302        y_pair: BigUint<M>,
303    ) -> crate::types::heap::BoxedBytes {
304        let api = M::managed_type_impl();
305        api.ec_marshal_compressed_legacy(
306            self.handle.clone(),
307            x_pair.value.handle,
308            y_pair.value.handle,
309        )
310    }
311
312    pub fn marshal_compressed(&self, x_pair: BigUint<M>, y_pair: BigUint<M>) -> ManagedBuffer<M> {
313        let result_handle: M::ManagedBufferHandle =
314            use_raw_handle(M::static_var_api_impl().next_handle());
315        M::managed_type_impl().ec_marshal_compressed(
316            self.handle.clone(),
317            x_pair.value.handle,
318            y_pair.value.handle,
319            result_handle.clone(),
320        );
321        unsafe { ManagedBuffer::from_handle(result_handle) }
322    }
323
324    #[deprecated(since = "0.41.0", note = "Please use method `unmarshal` instead.")]
325    pub fn unmarshal_legacy(&self, data: &[u8]) -> (BigUint<M>, BigUint<M>) {
326        let api = M::managed_type_impl();
327        let x_pair_handle = api.bi_new_zero();
328        let y_pair_handle = api.bi_new_zero();
329        api.ec_unmarshal_legacy(
330            x_pair_handle.clone(),
331            y_pair_handle.clone(),
332            self.handle.clone(),
333            data,
334        );
335        unsafe {
336            (
337                BigUint::from_handle(x_pair_handle),
338                BigUint::from_handle(y_pair_handle),
339            )
340        }
341    }
342
343    pub fn unmarshal(&self, data: &ManagedBuffer<M>) -> (BigUint<M>, BigUint<M>) {
344        let api = M::managed_type_impl();
345        let x_pair_handle = api.bi_new_zero();
346        let y_pair_handle = api.bi_new_zero();
347        api.ec_unmarshal(
348            x_pair_handle.clone(),
349            y_pair_handle.clone(),
350            self.handle.clone(),
351            data.get_handle(),
352        );
353        unsafe {
354            (
355                BigUint::from_handle(x_pair_handle),
356                BigUint::from_handle(y_pair_handle),
357            )
358        }
359    }
360
361    #[deprecated(
362        since = "0.41.0",
363        note = "Please use method `unmarshal_compressed` instead."
364    )]
365    pub fn unmarshal_compressed_legacy(&self, data: &[u8]) -> (BigUint<M>, BigUint<M>) {
366        let api = M::managed_type_impl();
367        let x_pair_handle = api.bi_new_zero();
368        let y_pair_handle = api.bi_new_zero();
369        api.ec_unmarshal_compressed_legacy(
370            x_pair_handle.clone(),
371            y_pair_handle.clone(),
372            self.handle.clone(),
373            data,
374        );
375        unsafe {
376            (
377                BigUint::from_handle(x_pair_handle),
378                BigUint::from_handle(y_pair_handle),
379            )
380        }
381    }
382
383    pub fn unmarshal_compressed(&self, data: &ManagedBuffer<M>) -> (BigUint<M>, BigUint<M>) {
384        let api = M::managed_type_impl();
385        let x_pair_handle = api.bi_new_zero();
386        let y_pair_handle = api.bi_new_zero();
387        api.ec_unmarshal_compressed(
388            x_pair_handle.clone(),
389            y_pair_handle.clone(),
390            self.handle.clone(),
391            data.get_handle(),
392        );
393        unsafe {
394            (
395                BigUint::from_handle(x_pair_handle),
396                BigUint::from_handle(y_pair_handle),
397            )
398        }
399    }
400
401    #[deprecated(since = "0.41.0", note = "Please use method `generate_key` instead.")]
402    #[cfg(feature = "alloc")]
403    pub fn generate_key_legacy(&self) -> (BigUint<M>, BigUint<M>, crate::types::heap::BoxedBytes) {
404        let api = M::managed_type_impl();
405        let x_pub_key_handle = api.bi_new_zero();
406        let y_pub_key_handle = api.bi_new_zero();
407        let private_key = api.ec_generate_key_legacy(
408            x_pub_key_handle.clone(),
409            y_pub_key_handle.clone(),
410            self.handle.clone(),
411        );
412        unsafe {
413            (
414                BigUint::from_handle(x_pub_key_handle),
415                BigUint::from_handle(y_pub_key_handle),
416                private_key,
417            )
418        }
419    }
420
421    pub fn generate_key(&self) -> (BigUint<M>, BigUint<M>, ManagedBuffer<M>) {
422        let api = M::managed_type_impl();
423        let x_pub_key_handle = api.bi_new_zero();
424        let y_pub_key_handle = api.bi_new_zero();
425        let private_key_handle: M::ManagedBufferHandle =
426            use_raw_handle(M::static_var_api_impl().next_handle());
427        api.ec_generate_key(
428            x_pub_key_handle.clone(),
429            y_pub_key_handle.clone(),
430            self.handle.clone(),
431            private_key_handle.clone(),
432        );
433        unsafe {
434            (
435                BigUint::from_handle(x_pub_key_handle),
436                BigUint::from_handle(y_pub_key_handle),
437                ManagedBuffer::from_handle(private_key_handle),
438            )
439        }
440    }
441}
442
443impl<M: ManagedTypeApi> NestedEncode for EllipticCurve<M> {
444    fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
445    where
446        O: NestedEncodeOutput,
447        H: EncodeErrorHandler,
448    {
449        let (field_order, base_point_order, eq_constant, x_base_point, y_base_point, size_of_field) =
450            self.get_values();
451        NestedEncode::dep_encode_or_handle_err(&field_order, dest, h)?;
452        NestedEncode::dep_encode_or_handle_err(&base_point_order, dest, h)?;
453        NestedEncode::dep_encode_or_handle_err(&eq_constant, dest, h)?;
454        NestedEncode::dep_encode_or_handle_err(&x_base_point, dest, h)?;
455        NestedEncode::dep_encode_or_handle_err(&y_base_point, dest, h)?;
456        NestedEncode::dep_encode_or_handle_err(&size_of_field, dest, h)?;
457        Ok(())
458    }
459}
460
461impl<M: ManagedTypeApi> TopEncode for EllipticCurve<M> {
462    fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
463    where
464        O: TopEncodeOutput,
465        H: EncodeErrorHandler,
466    {
467        top_encode_from_nested(self, output, h)
468    }
469}
470
471impl<M> TypeAbiFrom<Self> for EllipticCurve<M> where M: ManagedTypeApi {}
472
473impl<M: ManagedTypeApi> TypeAbi for EllipticCurve<M> {
474    type Unmanaged = Self;
475
476    fn type_name() -> TypeName {
477        TypeName::from("EllipticCurve")
478    }
479
480    fn type_name_rust() -> TypeName {
481        TypeName::from("EllipticCurve<$API>")
482    }
483}