Skip to main content

crypto_dispatch/algorithms/
p256.rs

1// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
2//
3// SPDX-License-Identifier: Apache-2.0
4
5#![allow(clippy::needless_return)]
6use crate::traits::SignatureAlgorithm;
7use crate::AlgorithmError;
8use crypto_core::Algorithm;
9use zeroize::Zeroizing;
10
11/// NIST P-256 (secp256r1) signature adapter.
12pub struct P256Algo;
13
14impl SignatureAlgorithm for P256Algo {
15    const ALG: Algorithm = Algorithm::P256;
16
17    fn generate_keypair() -> Result<(Vec<u8>, Zeroizing<Vec<u8>>), AlgorithmError> {
18        #[cfg(any(feature = "native", all(feature = "wasm", target_arch = "wasm32")))]
19        {
20            return crate::algorithms::KeypairResultExt::into_algorithm_keypair(
21                crypto_p256::generate_p256_keypair(),
22                Self::ALG,
23            );
24        }
25
26        #[cfg(not(any(feature = "native", all(feature = "wasm", target_arch = "wasm32"))))]
27        {
28            Err(AlgorithmError::UnsupportedAlgorithm(Self::ALG))
29        }
30    }
31
32    fn sign(secret: &[u8], msg: &[u8]) -> Result<Vec<u8>, AlgorithmError> {
33        #[cfg(any(feature = "native", all(feature = "wasm", target_arch = "wasm32")))]
34        {
35            return crypto_p256::sign_p256_der_prehash(secret, msg).map_err(AlgorithmError::from);
36        }
37
38        #[cfg(not(any(feature = "native", all(feature = "wasm", target_arch = "wasm32"))))]
39        {
40            let _ = (secret, msg);
41            Err(AlgorithmError::UnsupportedAlgorithm(Self::ALG))
42        }
43    }
44
45    fn verify(public: &[u8], msg: &[u8], sig: &[u8]) -> Result<(), AlgorithmError> {
46        #[cfg(any(feature = "native", all(feature = "wasm", target_arch = "wasm32")))]
47        {
48            return crypto_p256::verify_p256_der_prehash(sig, msg, public)
49                .map_err(|error| crate::algorithms::map_verify_error(Self::ALG, error));
50        }
51
52        #[cfg(not(any(feature = "native", all(feature = "wasm", target_arch = "wasm32"))))]
53        {
54            let _ = (public, msg, sig);
55            Err(AlgorithmError::UnsupportedAlgorithm(Self::ALG))
56        }
57    }
58}
59
60impl P256Algo {
61    /// Derive the P-256 ECDH shared secret; the returned value zeroizes on
62    /// drop and must be passed through a protocol KDF before key use.
63    pub fn derive_shared_secret(
64        secret_key: &[u8],
65        public_key: &[u8],
66    ) -> Result<Zeroizing<Vec<u8>>, AlgorithmError> {
67        #[cfg(any(feature = "native", all(feature = "wasm", target_arch = "wasm32")))]
68        {
69            return crypto_p256::derive_p256_shared_secret(secret_key, public_key)
70                .map_err(AlgorithmError::from);
71        }
72
73        #[cfg(not(any(feature = "native", all(feature = "wasm", target_arch = "wasm32"))))]
74        {
75            let _ = (secret_key, public_key);
76            Err(AlgorithmError::UnsupportedAlgorithm(Self::ALG))
77        }
78    }
79}