From 0699c3b08fe1e908966b4a3fa1e2c83aecc54576 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Sun, 6 Nov 2022 22:00:30 -0800 Subject: crypto: fix 'multibase' pubkey serialization for DID documents See: https://medium.com/asecuritysite-when-bob-met-alice/02-03-or-04-so-what-are-compressed-and-uncompressed-public-keys-6abcb57efeb6 Thanks to folks in bluesky matrix dev channel for the tip. --- adenosine-pds/src/crypto.rs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/adenosine-pds/src/crypto.rs b/adenosine-pds/src/crypto.rs index ba69dc6..07119b1 100644 --- a/adenosine-pds/src/crypto.rs +++ b/adenosine-pds/src/crypto.rs @@ -119,13 +119,16 @@ impl PubKey { .to_string() } - /// This public verification key encoded as base58btc multibase string + /// This public verification key encoded as base58btc multibase string, not 'compressed', as + /// included in DID documents ('publicKeyMultibase'). + /// + /// Note that the did:key serialization does 'compress' the key into a smaller size. pub fn to_multibase(&self) -> String { let mut bytes: Vec = vec![]; match self { PubKey::P256(key) => { bytes.extend_from_slice(&MULTICODE_P256_BYTES); - bytes.extend_from_slice(&key.to_encoded_point(true).to_bytes()); + bytes.extend_from_slice(&key.to_encoded_point(false).to_bytes()); } PubKey::K256(key) => { bytes.extend_from_slice(&MULTICODE_K256_BYTES); @@ -135,8 +138,23 @@ impl PubKey { format!("{}", multibase::encode(multibase::Base::Base58Btc, &bytes)) } + /// Serializes as a 'did:key' string. pub fn to_did_key(&self) -> String { - format!("did:key:{}", self.to_multibase()) + let mut bytes: Vec = vec![]; + match self { + PubKey::P256(key) => { + bytes.extend_from_slice(&MULTICODE_P256_BYTES); + bytes.extend_from_slice(&key.to_encoded_point(true).to_bytes()); + } + PubKey::K256(key) => { + bytes.extend_from_slice(&MULTICODE_K256_BYTES); + bytes.extend_from_slice(&key.to_bytes()); + } + } + format!( + "did:key:{}", + multibase::encode(multibase::Base::Base58Btc, &bytes) + ) } pub fn from_did_key(did_key: &str) -> Result { @@ -180,9 +198,8 @@ impl PubKey { } impl std::fmt::Display for PubKey { - // TODO: what should this actually be, instead of multibase? the did:key representation? fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.to_multibase()) + write!(f, "{}", self.to_did_key()) } } -- cgit v1.2.3