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}