The trait bound ed25519_dalek::SecretKey: Eq is not satisfied
required because of the requirements on the impl of Eq for Option<ed25519_dalek::SecretKey>
use secp256k1::{PublicKey, Secp256k1, SecretKey, SignOnly, VerifyOnly};
use ed25519_dalek::{SecretKey as EdDsaSecretKey};
lazy_static! {
static ref SECP256K1_SIGN_ONLY: Secp256k1<SignOnly> = Secp256k1::signing_only();
static ref SECP256K1_VERIFY_ONLY: Secp256k1<VerifyOnly> = Secp256k1::verification_only();
}
type ChainCode = Vec<u8>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExtendedPrivKey {
pub private_key: Option<SecretKey>,
pub chain_code: ChainCode,
pub ed_dsa_private_key: Option<EdDsaSecretKey> <- Here
}
derive(PartialEq, Eq) will automatically generate code that should run when you compare two values x: ExtendPrivKey and y: ExtendPrivKey via x == y operation. The generated code will check equality on all fields, e.g. x.private_key == y.private_key && x.chain_code == y.chain_code && x.ed_dsa_private_key == y.ed_dsa_private_key. For this to work, the types of these fields need to support ==-comparison, too.
The (PartialEq and) Eq trait is the way Rust codifies the notion of whether or not values of a type can be compared using ==. Looking at the documentation ( ed25519_dalek::SecretKey - Rust ) you can see that the trait implementations section does not feature PartialEq/Eq, which means values of type ed25519_dalek::SecretKeycannot be compared using ==.
Now, it’s up to you to decide whether comparing such values for whether or not they’re “equal” might make sense anyway; or whether ExtendedPrivKey should be considered equal under some different condition that doesn’t involve comparing their ed_dsa_private_key fields; or whether ==-operator support for ExtendedPrivKey is not needed after all. In the first two cases, you can write a manual PartialEq implementation for ExtendedPrivKey(you can still derive Eq because it itself doesn’t actually feature any methods), in the last case, you simply remove the two traits PartialEq and Eq from the derive list alltogether.
A manual implementation of PartialEq would look like
impl PartialEq for ExtendedPrivKey {
fn eq(&self, other: &Self) -> bool {
todo!() // <- your code here, comparing `self` and `other`
}
}
Note that ed25519_dalek::SecretKey values can be compared with key1.as_bytes() == key2.as_bytes(), so you could implement PartialEq manually using that. However, there could be an important cryptographic reason why ed25519_dalek::SecretKey doesn't implement PartialEq; I'm not an expert, but it could enable timing attacks to guess the value of the private key in certain circumstances.
Thanks, @LegionMammal978, for your response, I tried that, but it didn't work.
the trait bound `ed25519_dalek::SecretKey: Eq` is not satisfied
required because of the requirements on the impl of `Eq` for `Option<ed25519_dalek::SecretKey>`
todo!() // <- your code here, comparing `self` and `other`
was meant to be filled in in order to handle the fact that
either by somehow arguing that
in which case you must invent your own notion of “equality” between ed25519_dalek::SecretKey values,
or in case
I also pointed out that
And the whole point of not using the automatically genereted implementation in this case would be because the generated one doesn’t work. Using the same code nonetheless results in the same error message, unsurprisingly.
In case this wasn’t clear, my explanations cited above mean that
ed25519_dalek::SecretKeydoes not support==, and neither does Option<ed25519_dalek::SecretKey> so you cannot write x.ed_dsa_private_key == y.ed_dsa_private_key
in case you know some way of comparing two values of type ed25519_dalek::SecretKey for equality that makes sense, you might use that anyways, e.g. the one @LegionMammal978 suggested, but of course, it might be the case that comparing SecretKeys like this might be undesirable or meaningless for whatever reason; I don’t know, but ed25519_dalek::SecretKey might not implement PartialEq/Eq for a reason
otherwise, you could use some implementation that doesn’t involve comparing the ed_dsa_private_key at all, in case that makes sense for your use case
Side note, try to learn posting full error messages, as reported by cargo check in the terminal. Those tend to be way easier to read than what you are posting.
With regards to
I’d assume that error appears on the derive(Eq) part, and I must say that I was incorrect on my observation that
because it turns out derive(Eq) does conservatively check if all the fields implement Eq as well (and it does have a hidden method in order for the generated code to be able to check this).
So I’ll correct myself, and you will have to also implement Eq manually after all, but that’s easy because it’s simply
impl Eq for ExtendedPrivKey {}
In case a as_bytes-based approach makes sense for your implementation, you might want to change .ed_dsa_private_key.unwrap().as_bytes() to something along the lines of .ed_dsa_private_key().as_ref().map(EdDsaSecretKey::as_bytes).