# Affinidi Secrets Manager

## 13th June 2026 (0.5.8)

Semver wave (W7 — release W11). `SecretsResolverError` is now `#[non_exhaustive]`
(match with a wildcard arm). Patch bump preserves the `didwebvh-rs`
`[patch.crates-io]` coupling — see ADR 0003 and the migration guide.

## 6th June 2026 (0.5.7)

- **Full P-521 secret support (#357).** Added `Secret::generate_p521`
  (load/generate P-521 key-agreement secrets) and wired P-521 into
  `from_multibase` decoding (`P521_PRIV`) — previously a P-521 private key
  could be *written* but not *loaded*. Also unblocked P-521 public-key
  multibase encoding, which had been hard-erroring with "P-521 is not
  supported". This lets a sender/recipient actually use a P-521
  key-agreement key end-to-end. New `p521` feature (on by default).

## 28th May 2026 (0.5.6)

- **SECURITY (HIGH):** Redact private key material in `Debug` output for
  both `Secret` and `SecretMaterial`. `Secret` derived `Debug` while
  holding `private_bytes` (raw key) and `secret_material` (the JWK
  including `d`), so any `{:?}` in a tracing span, error context, panic
  message, or stray `dbg!()` would dump the key to logs. `SecretMaterial`
  is `pub` and every variant (`JWK` with `d`, `PrivateKeyMultibase`,
  `Base58`, `Multibase`) carries the raw private key, so a direct `{:?}`
  on a value would leak there too. Manual `Debug` impls now print
  identifying metadata (id / type / key_type / variant name) and render
  the key bytes as `[REDACTED]`. `ZeroizeOnDrop` continues to cover heap
  lifetime; this closes the print-side leak.

## 18th April 2026 (0.5.5)

- **FEATURE:** `post-quantum` Cargo feature (off by default) with
  `ml-dsa` and `slh-dsa` sub-flags. Adds `Secret::generate_ml_dsa_44`,
  `generate_ml_dsa_65`, `generate_ml_dsa_87`, and
  `generate_slh_dsa_sha2_128s` methods.
- **FEATURE:** Multikey (multibase + multicodec) round-trip for
  ML-DSA-{44,65,67} using the registered `-priv-seed` codecs
  (`0x131a`–`0x131c`). SLH-DSA has no registered private-key codec;
  `get_private_keymultibase` returns a descriptive error so callers
  must persist raw private bytes themselves.
- **SAFETY:** `get_public_keymultibase` for P-256 / P-384 / secp256k1
  now bounds-checks `public_bytes` instead of panicking on out-of-range
  indexing. Pre-existing latent issue surfaced by the PQC review.
- **TESTS:** New varint-prefix pinning tests assert that emitted
  multikeys use the exact official multicodec codes (guards against
  drift toward invented codec values).

## 15th April 2026 (0.5.3)

- **CHANGE:** Removed `multihash` crate dependency (yanked `core2` transitive dep)
  - Multihash encoding now uses inline varint encoding via existing `unsigned-varint`
    dependency — output is byte-identical

## 3rd November October 2025 (0.5.2)

- **BREAKING:** Now uses the affinidi-crypto library for all cryptographic operations
- **FEATURE:** Added ability to deserialize `Secret` from a privateKeyMultiBase
  string

## 3rd November October 2025 (0.4.0)

- **BREAKING:** `Secret::from_multibase()` API changed to just need a private string

## 22nd October 2025 (0.3.5)

- **FIX:** ed25519 --> x25519 bit swap was inverted

## 21st October 2025 (0.3.4)

- **FEATURE:** Ability to convert Ed25519 secret to X25519 secret is now public
  - `ed25519_private_to_x25519_private_key()`

## 12th October 2025 (0.3.3)

- **IMPROVEMENT:** Implemented stronger and more consistent zeroize on drop for
  `Secret`
  - This may cause breaking changes for apps where they were not using references
    to `Secret`

## 9th October 2025 (0.3.2)

- **FIX:** secp256k1 Public point compression was off by a byte causing decrypt
  failures.
  - No loss of security as it hard failed to decrypt

## 8th October 2025 (0.3.1)

- **FIX:** P-256 and P-384 Public point compression was off by a byte causing decrypt
  failures.
  - No loss of security as it hard failed to decrypt
- **FIX:** Incorrect Curve String in JWK representation of public-keys for P-256
  and P-384
  - Changed `P256` to `P-256` and `P384` to `P-384`
- **CHORE:** Additional Unit Tests added (50.77% Coverage)

## 3rd October 2025 (0.3.0)

- **FEATURE:** `Secret::generate_ed25519()` now allows for creation from optional
  seed
- **FEATURE:** `Secret::generate_x25519()` now allows for creation from optional
  seed
- **NOTE:** The above changes causes a breaking API change

## 1st October 2025 (0.2.1, 0.2.2)

- **FIX:** Secret struct deserialization was not correct
  - Added a unit test to check deserialization of Secret
  - serde now correctly names the SecretMaterial fields
- **FIX:** JWK conversions from bytes were not correct for Ecliptic Curves

## 30th September 2025 (0.2.0)

- **IMPROVEMENT:** SSI Crate dependency removed from this library
- **IMPROVEMENT:** Crypto methods added directly to this library for easier 3rd
  party usage

## 13th September 2025 (0.1.18)

- **IMPROVEMENT:** Crate can now be compiled to a WASM compatible library
- **FIX:** Incorrect encoding on multikey public_keys for P-256, P384 and secp256k1

## 10th September 2025 (0.1.16)

- **IMPROVEMENT:** Removing SSI crate as a dependency
- **IMPROVEMENT:** Added ability to create ED25519 keys directly

## 8th September 2025 (0.1.14)

- **FIX:** X25519 Secrets had type set to Ed25519

## 2nd September 2025 (0.1.13)

- **FEATURE:** Ability to convert a ED25519 Secret to a X25519 Secret added
- **MAINTENANCE:** Dependencies updated

## 9th June 2025 (0.1.12)

- **MAINTENANCE:** Dependencies updated
- **MAINTENANCE:** Addressing Rust linting warnings
- **CHANGE:** Hashing of publickeys returns base58 only not multiencode

## 14th June 2025 (0.1.11)

- **MAINTENANCE:** Updated SSI crate from 0.11 to 0.12
- **FEATURE:** Loading JWK format keys will support public/private byte methods
  - This has been implemented using a Inner Shadow struct for Secret `Deseralization`

## 6th June 2025 (0.1.10)

- **FIX:** Generating a hash of the public key `multibase` was incorrect
- **FEATURE:** Added `get_hash()` to `Secrets` allowing for easier hashing of keys
  without converting to a secret
- **TESTS:** Added more unit tests to test functionality of `get_hash()`

## 29th May 2025 (0.1.9)

- **MAINTENANCE:** Crate dependencies updated
- **FEATURE:** `get_public_bytes()` and `get_private_bytes()` methods added
- **FEATURE:** `get_public_multibase()` and `get_private_multibase()` methods added
  - Returns a MultiKey format String
- **FEATURE:** `get_public_multibase_hash()` method added
  - Returns a Base58btc encoded Multihash of the MultiKey Public Key
  - Useful for checks against pre-shared keys without disclosing the key itself

## Release 0.1.7

- Removed drop() trait implementation as was causing the SecretsTask to close early

## Release 0.1.0

- Initial release of crate
