# Migration: RustCrypto `p256` -> `rscrypto`
Replace RustCrypto P-256 ECDSA signing and verification call sites with
`EcdsaP256SecretKey`, `EcdsaP256PublicKey`, and `EcdsaP256Signature`.
rscrypto supports the fixed P-256/SHA-256 ECDSA profile, raw `r || s`
signatures, DER signature import, SEC1/SPKI public-key import, deterministic
signing, and caller-blinded signing.
Verified against RustCrypto `p256 0.13.2`.
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 | `p256 = { version = "0.13", features = ["ecdsa"] }` | `rscrypto = { version = "0.4.0", default-features = false, features = ["ecdsa-p256"] }` |
| Import | `use p256::ecdsa::{SigningKey, Signature};` | `use rscrypto::{EcdsaP256SecretKey, EcdsaP256PublicKey, EcdsaP256Signature};` |
| Sign | `signing_key.sign(msg)` | `secret.try_sign(msg)?` |
| Verify | `verifying_key.verify(msg, &sig)?` | `public.verify(msg, &sig)?` |
## Cargo.toml
```toml
# Before
p256 = { version = "0.13", features = ["ecdsa"] }
# After
rscrypto = { version = "0.4.0", default-features = false, features = ["ecdsa-p256"] }
```
The `ecdsa-p256` feature implies `hmac`, which is used for deterministic nonce
derivation.
## Type Map
| `ecdsa::SigningKey` | `EcdsaP256SecretKey` | 32-byte scalar |
| `ecdsa::VerifyingKey` | `EcdsaP256PublicKey` | uncompressed SEC1 65B |
| `ecdsa::Signature` | `EcdsaP256Signature` | raw `r || s` 64B |
| `EncodedPoint` public key | `EcdsaP256PublicKey::from_sec1_bytes` | uncompressed SEC1 only |
## Sign
```rust
// Before
use p256::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::EcdsaP256SecretKey;
let secret = EcdsaP256SecretKey::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 p256::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::{EcdsaP256PublicKey, EcdsaP256Signature};
let public = EcdsaP256PublicKey::from_sec1_bytes(public_sec1)?;
let signature = EcdsaP256Signature::from_bytes(*signature_raw)?;
public.verify(message, &signature)?;
```
## Verify DER Signatures
```rust
// Before
use p256::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::{EcdsaP256PublicKey, EcdsaP256Signature};
let public = EcdsaP256PublicKey::from_sec1_bytes(public_sec1)?;
let signature = EcdsaP256Signature::from_der(signature_der)?;
public.verify(message, &signature)?;
```
If the public key is SubjectPublicKeyInfo DER, use
`EcdsaP256PublicKey::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-256 ECDH is not part of this migration. rscrypto currently exposes ECDSA
P-256, not P-256 key agreement.