Skip to content

Commit

Permalink
fix(comms)!: commit to public key and nonce in identity sig (#3928)
Browse files Browse the repository at this point in the history
Description
---

- commit to public nonce and public key on identity signature 

Motivation and Context
---
Schnorr signatures are not secure unless public nonce and public key are committed to

How Has This Been Tested?
---
Existing tests (internal to identity signature)
  • Loading branch information
sdbondi committed May 24, 2022
1 parent 1e96d45 commit 5ac6133
Showing 1 changed file with 26 additions and 6 deletions.
32 changes: 26 additions & 6 deletions comms/core/src/peer_manager/identity_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use digest::Digest;
use prost::Message;
use rand::rngs::OsRng;
use serde::{Deserialize, Serialize};
use tari_crypto::keys::SecretKey;
use tari_crypto::keys::PublicKey as PublicKeyTrait;
use tari_utilities::ByteArray;

use crate::{
Expand Down Expand Up @@ -64,9 +64,17 @@ impl IdentitySignature {
addresses: I,
updated_at: DateTime<Utc>,
) -> Self {
let challenge = Self::construct_challenge(Self::LATEST_VERSION, features, addresses, updated_at);
let nonce = CommsSecretKey::random(&mut OsRng);
let signature = Signature::sign(secret_key.clone(), nonce, &challenge.finalize())
let public_key = CommsPublicKey::from_secret_key(secret_key);
let (secret_nonce, public_nonce) = CommsPublicKey::random_keypair(&mut OsRng);
let challenge = Self::construct_challenge(
&public_key,
&public_nonce,
Self::LATEST_VERSION,
features,
addresses,
updated_at,
);
let signature = Signature::sign(secret_key.clone(), secret_nonce, &challenge.finalize())
.expect("unreachable panic: challenge hash digest is the correct length");
Self {
version: Self::LATEST_VERSION,
Expand Down Expand Up @@ -110,17 +118,29 @@ impl IdentitySignature {
return false;
}

let challenge = Self::construct_challenge(self.version, features, addresses, self.updated_at);
let challenge = Self::construct_challenge(
public_key,
self.signature.get_public_nonce(),
self.version,
features,
addresses,
self.updated_at,
);
self.signature.verify_challenge(public_key, &challenge.finalize())
}

fn construct_challenge<'a, I: IntoIterator<Item = &'a Multiaddr>>(
public_key: &CommsPublicKey,
public_nonce: &CommsPublicKey,
version: u8,
features: PeerFeatures,
addresses: I,
updated_at: DateTime<Utc>,
) -> Challenge {
// e = H(P||R||m)
let challenge = Challenge::new()
.chain(public_key.as_bytes())
.chain(public_nonce.as_bytes())
.chain(version.to_le_bytes())
.chain(u64::try_from(updated_at.timestamp()).unwrap().to_le_bytes())
.chain(features.bits().to_le_bytes());
Expand Down Expand Up @@ -177,7 +197,7 @@ impl From<&IdentitySignature> for proto::identity::IdentitySignature {
mod test {
use std::str::FromStr;

use tari_crypto::keys::PublicKey;
use tari_crypto::keys::{PublicKey, SecretKey};

use super::*;
use crate::peer_manager::{NodeId, PeerFlags};
Expand Down

0 comments on commit 5ac6133

Please sign in to comment.