Skip to content

Commit

Permalink
feat: add sum for schnorr signature and capk signature (#231)
Browse files Browse the repository at this point in the history
Adds sum for schnorr signature and capk signature as a features
new version
  • Loading branch information
SWvheerden authored Jul 2, 2024
1 parent 494bb73 commit bdf1d83
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ categories = ["cryptography"]
homepage = "https://tari.com"
readme = "README.md"
license = "BSD-3-Clause"
version = "0.20.2"
version = "0.20.3"
edition = "2018"

[dependencies]
Expand Down
11 changes: 9 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.21.2](https://github.com/tari-project/tari-crypto/compare/v0.21.1...v0.21.2) (2024-06-28)
### [0.20.3](https://github.com/tari-project/tari-crypto/compare/v0.20.1...v0.20.3) (2024-07-02)


### Features

* Include Add CAPK and Schnorr signatures together

### [0.20.2](https://github.com/tari-project/tari-crypto/compare/v0.20.1...v0.20.2) (2024-06-28)


### Features

* Adds public constructor for DHKE


### [0.21.1](https://github.com/tari-project/tari-crypto/compare/v0.20.0...v0.21.1) (2024-05-09)
### [0.20.1](https://github.com/tari-project/tari-crypto/compare/v0.20.0...v0.20.1) (2024-05-09)


### Features
Expand Down
57 changes: 57 additions & 0 deletions src/ristretto/ristretto_com_and_pub_sig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ mod test {
pedersen::{commitment_factory::PedersenCommitmentFactory, PedersenCommitment},
RistrettoComAndPubSig,
RistrettoPublicKey,
RistrettoSchnorr,
RistrettoSecretKey,
},
};
Expand Down Expand Up @@ -265,6 +266,62 @@ mod test {
assert!(sig_p_total.verify_challenge(&commitment, &pubkey, &challenge, &factory, &mut rng));
}

/// Create a schnorr and RistrettoComAndPubSig adding them together and testing if they still valid.
#[test]
fn sign_and_verify_combined_schnorr() {
let mut rng = rand::thread_rng();

// Challenge; doesn't use proper Fiat-Shamir, so it's for testing only!
let challenge = Blake2b::<U64>::new().chain_update(b"Small Gods").finalize();

// Witness data
let a_value = RistrettoSecretKey::random(&mut rng);
let x_value = RistrettoSecretKey::random(&mut rng);
let y_value = RistrettoSecretKey::random(&mut rng);

// Statement data
let factory = PedersenCommitmentFactory::default();
let commitment = factory.commit(&x_value, &a_value);
let pubkey = RistrettoPublicKey::from_secret_key(&y_value);

// Nonce data
let r_a = RistrettoSecretKey::random(&mut rng);
let r_x = RistrettoSecretKey::random(&mut rng);
let r_y = RistrettoSecretKey::random(&mut rng);

let sig_capk =
RistrettoComAndPubSig::sign(&a_value, &x_value, &y_value, &r_a, &r_x, &r_y, &challenge, &factory).unwrap();
assert!(sig_capk.verify_challenge(&commitment, &pubkey, &challenge, &factory, &mut rng));

let (k, pub_k) = RistrettoPublicKey::random_keypair(&mut rng);
let r = RistrettoSecretKey::random(&mut rng);

let total_y_value = &y_value + &k;
let total_r_y = &r_y + &r;

let sig = RistrettoSchnorr::sign_raw_uniform(&k, r, &challenge).unwrap();
assert!(sig.verify_raw_uniform(&pub_k, &challenge));

let total_pubkey = RistrettoPublicKey::from_secret_key(&total_y_value);

let total_sig_capk = RistrettoComAndPubSig::sign(
&a_value,
&x_value,
&total_y_value,
&r_a,
&r_x,
&total_r_y,
&challenge,
&factory,
)
.unwrap();
assert!(total_sig_capk.verify_challenge(&commitment, &total_pubkey, &challenge, &factory, &mut rng));

let agg_sig = &sig_capk + &sig;
assert!(agg_sig.verify_challenge(&commitment, &total_pubkey, &challenge, &factory, &mut rng));
assert_eq!(agg_sig, total_sig_capk);
}

/// Test that commitment signatures are linear, as in a multisignature construction
#[test]
fn test_signature_addition() {
Expand Down
55 changes: 55 additions & 0 deletions src/signatures/commitment_and_public_key_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
alloc::borrow::ToOwned,
commitment::{HomomorphicCommitment, HomomorphicCommitmentFactory},
keys::{PublicKey, SecretKey},
signatures::SchnorrSignature,
};

/// An error when creating a commitment signature
Expand Down Expand Up @@ -305,6 +306,60 @@ where
}
}

impl<'a, 'b, P, K> Add<&'b SchnorrSignature<P, K>> for &'a CommitmentAndPublicKeySignature<P, K>
where
P: PublicKey<K = K>,
&'a HomomorphicCommitment<P>: Add<&'b HomomorphicCommitment<P>, Output = HomomorphicCommitment<P>>,
&'a P: Add<&'b P, Output = P>,
K: SecretKey,
&'a K: Add<&'b K, Output = K>,
{
type Output = CommitmentAndPublicKeySignature<P, K>;

fn add(self, rhs: &'b SchnorrSignature<P, K>) -> CommitmentAndPublicKeySignature<P, K> {
let ephemeral_commitment_sum = self.ephemeral_commitment().clone();
let ephemeral_pubkey_sum_sum = self.ephemeral_pubkey() + rhs.get_public_nonce();
let u_a_sum = self.u_a().clone();
let u_x_sum = self.u_x().clone();
let u_y_sum = self.u_y() + rhs.get_signature();

CommitmentAndPublicKeySignature::new(
ephemeral_commitment_sum,
ephemeral_pubkey_sum_sum,
u_a_sum,
u_x_sum,
u_y_sum,
)
}
}

impl<'a, P, K> Add<SchnorrSignature<P, K>> for &'a CommitmentAndPublicKeySignature<P, K>
where
P: PublicKey<K = K>,
for<'b> &'a HomomorphicCommitment<P>: Add<&'b HomomorphicCommitment<P>, Output = HomomorphicCommitment<P>>,
for<'b> &'a P: Add<&'b P, Output = P>,
K: SecretKey,
for<'b> &'a K: Add<&'b K, Output = K>,
{
type Output = CommitmentAndPublicKeySignature<P, K>;

fn add(self, rhs: SchnorrSignature<P, K>) -> CommitmentAndPublicKeySignature<P, K> {
let ephemeral_commitment_sum = self.ephemeral_commitment().clone();
let ephemeral_pubkey_sum_sum = self.ephemeral_pubkey() + rhs.get_public_nonce();
let u_a_sum = self.u_a().clone();
let u_x_sum = self.u_x().clone();
let u_y_sum = self.u_y() + rhs.get_signature();

CommitmentAndPublicKeySignature::new(
ephemeral_commitment_sum,
ephemeral_pubkey_sum_sum,
u_a_sum,
u_x_sum,
u_y_sum,
)
}
}

impl<P, K> Default for CommitmentAndPublicKeySignature<P, K>
where
P: PublicKey<K = K>,
Expand Down

0 comments on commit bdf1d83

Please sign in to comment.