Explanation of the publicID and privatedID trait in PARSEC...

I’m not entirely sure, if I get the logic of the PublicId and SecretId traits. Lets assume we use a standard public key cryptographic scheme like RSA or EdDSA… We have a private_key and a public_key…

In the trait PublicID, we have the type Signature… Shouldn’t it be “type pub_key” instead? Every peer that implements this trait has a public key (obviously) that doesn’t change, so here is a good place to store it. Signatures depend on data too and are different for different events.

And the function verify needs the pubkey, a signature and the data. Why is it different in the trait?

A structure that implements the privateID, the should store a private key, too…

So the general idea is to have to structures, say our_peer and other_peer, the former implements both publicID and privateID, while the latter implements only publicID. Something like that?

3 Likes

Hi Andre,

The idea is indeed that the PublicId represents a public key. The Signature is just the type associated with that specific public key. A type which implements PublicId wouldn’t be expected to hold a specific instance of such an associated Signature - rather we’re saying this is the type which will be returned when the key signs some data.

The SecretId trait would be expected to hold both a public and secret key - i.e. a keypair. If for example you wanted to create types using rust_sodium which implement these traits, you could do something like this:

use rust_sodium::crypto::sign;

#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Debug)]
pub struct MyPublicKey(sign::PublicKey);

impl PublicId for MyPublicKey {
    type Signature = sign::Signature;

    fn verify_signature(&self, signature: &Self::Signature, data: &[u8]) -> bool {
        sign::verify_detached(signature, data, &self.0)
    }
}

pub struct MyKeyPair {
    secret: sign::SecretKey,
    public: MyPublicKey,
}

impl SecretId for MyKeyPair {
    type PublicId = MyPublicKey;

    fn public_id(&self) -> &Self::PublicId {
        &self.public
    }

    fn sign_detached(&self, data: &[u8]) -> <Self::PublicId as PublicId>::Signature {
        sign::sign_detached(data, &self.secret)
    }
}

So although we’d anticipated these really just representing asymmetric keys, as you suggest these could be more than just keys. You could indeed have a struct OurPeer which implements SecretId and will hold the full keypair, and another struct OtherPeer which only holds a public key and implements PublicId.

6 Likes