# Migration: RustCrypto `p384` -> `rscrypto`
Replace RustCrypto P-384 ECDSA signing and verification call sites with
`EcdsaP384SecretKey`, `EcdsaP384PublicKey`, and `EcdsaP384Signature`.
rscrypto supports the fixed P-384/SHA-384 ECDSA profile, raw `r || s`
signatures, DER signature import, SEC1/SPKI public-key import, deterministic
signing, and caller-blinded signing.
Verified against RustCrypto `p384 0.13.1`.
Evidence: `tests/ecdsa_oracle.rs`, `src/auth/ecdsa.rs` unit tests, and
`fuzz/target_impls/auth_ecdsa_verify.rs` /
`fuzz/target_impls/auth_ecdsa_sign.rs`.
## TL;DR
| Cargo dep | `p384 = { version = "0.13", features = ["ecdsa"] }` | `rscrypto = { version = "0.5.0", default-features = false, features = ["ecdsa-p384"] }` |
| Import | `use p384::ecdsa::{SigningKey, Signature};` | `use rscrypto::{EcdsaP384SecretKey, EcdsaP384PublicKey, EcdsaP384Signature};` |
| Sign | `signing_key.sign(msg)` | `secret.try_sign(msg)?` |
| Verify | `verifying_key.verify(msg, &sig)?` | `public.verify(msg, &sig)?` |
## Cargo.toml
```toml
# Before
p384 = { version = "0.13", features = ["ecdsa"] }
# After
rscrypto = { version = "0.5.0", default-features = false, features = ["ecdsa-p384"] }
```
The `ecdsa-p384` feature implies `hmac`, which is used for deterministic nonce
derivation.
## Type Map
| `ecdsa::SigningKey` | `EcdsaP384SecretKey` | 48-byte scalar |
| `ecdsa::VerifyingKey` | `EcdsaP384PublicKey` | uncompressed SEC1 97B |
| `ecdsa::Signature` | `EcdsaP384Signature` | raw `r || s` 96B |
| `EncodedPoint` public key | `EcdsaP384PublicKey::from_sec1_bytes` | uncompressed SEC1 only |
## Sign
```rust
// Before
use p384::ecdsa::{SigningKey, Signature, signature::Signer};
let signing_key = SigningKey::from_slice(secret_bytes)?;
let signature: Signature = signing_key.sign(message);
let raw = signature.to_bytes();
```
```rust
// After
use rscrypto::EcdsaP384SecretKey;
let secret = EcdsaP384SecretKey::from_bytes(*secret_bytes)?;
let signature = secret.try_sign(message)?;
let raw = signature.to_bytes();
```
Use `try_sign_blinded(message, fill)` when the deployment requires caller-owned
blinding for the internal `kG` point. The ECDSA nonce remains deterministic;
the closure fills the blinding bytes.
## Verify Raw Signatures
```rust
// Before
use p384::ecdsa::{Signature, VerifyingKey, signature::Verifier};
let public = VerifyingKey::from_sec1_bytes(public_sec1)?;
let signature = Signature::from_slice(signature_raw)?;
public.verify(message, &signature)?;
```
```rust
// After
use rscrypto::{EcdsaP384PublicKey, EcdsaP384Signature};
let public = EcdsaP384PublicKey::from_sec1_bytes(public_sec1)?;
let signature = EcdsaP384Signature::from_bytes(*signature_raw)?;
public.verify(message, &signature)?;
```
## Verify DER Signatures
```rust
// Before
use p384::ecdsa::{DerSignature, VerifyingKey, signature::Verifier};
let public = VerifyingKey::from_sec1_bytes(public_sec1)?;
let signature = DerSignature::from_bytes(signature_der)?;
public.verify(message, &signature)?;
```
```rust
// After
use rscrypto::{EcdsaP384PublicKey, EcdsaP384Signature};
let public = EcdsaP384PublicKey::from_sec1_bytes(public_sec1)?;
let signature = EcdsaP384Signature::from_der(signature_der)?;
public.verify(message, &signature)?;
```
If the public key is SubjectPublicKeyInfo DER, use
`EcdsaP384PublicKey::from_spki_der()`.
## Notes
- rscrypto exposes inherent methods instead of RustCrypto's `Signer` /
`Verifier` trait call shape.
- rscrypto accepts raw fixed-width signatures and imports DER
`Ecdsa-Sig-Value` signatures. It does not export DER signatures today.
- rscrypto public keys import uncompressed SEC1 and SPKI DER. It does not
import compressed SEC1 public keys or PKCS#8/SEC1 private-key DER today.
- Signing normalizes signatures to low-S form. Verification accepts valid raw
or DER signatures after scalar-shape parsing.
- P-384 ECDH is not part of this migration. rscrypto currently exposes ECDSA
P-384, not P-384 key agreement.