Skip to content

Commit

Permalink
Return shared secret as PublicKey rather than byte array
Browse files Browse the repository at this point in the history
Using the `PublicKey` struct makes more sense for an api like this I
think. If people want to access the internaly byte array, they can use
the `PublicKey` serialize functions.
  • Loading branch information
cygnet3 committed Jun 2, 2024
1 parent e60e32c commit 98244fc
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 16 deletions.
7 changes: 3 additions & 4 deletions examples/find_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use bitcoin_hashes::hex::FromHex;

use silentpayments::receiving::{Label, Receiver};
use silentpayments::utils::receiving::{
calculate_shared_point, calculate_tweak_data, get_pubkey_from_input,
calculate_ecdh_shared_secret, calculate_tweak_data, get_pubkey_from_input,
};

fn main() -> Result<(), Box<dyn Error>> {
Expand Down Expand Up @@ -70,8 +70,7 @@ fn main() -> Result<(), Box<dyn Error>> {

let pubkeys_ref: Vec<&PublicKey> = input_pubkeys.iter().collect();
let tweak_data = calculate_tweak_data(&pubkeys_ref, &outpoints)?;
let ecdh_shared_point = calculate_shared_point(&tweak_data, &scan_privkey);
let shared_public_key = PublicKey::from_slice(&ecdh_shared_point)?;
let ecdh_shared_secret = calculate_ecdh_shared_secret(&tweak_data, &scan_privkey)?;

let pubkeys_to_check: Vec<_> = tx
.output
Expand All @@ -83,7 +82,7 @@ fn main() -> Result<(), Box<dyn Error>> {
})
.collect();

let my_outputs = receiver.scan_transaction(&shared_public_key, pubkeys_to_check)?;
let my_outputs = receiver.scan_transaction(&ecdh_shared_secret, pubkeys_to_check)?;

println!("Found {} outputs", my_outputs.len());

Expand Down
5 changes: 2 additions & 3 deletions src/sending.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use core::fmt;
use secp256k1::{PublicKey, Secp256k1, SecretKey, XOnlyPublicKey};
use std::collections::HashMap;

use crate::utils::sending::calculate_shared_point;
use crate::utils::sending::calculate_ecdh_shared_secret;
use crate::{common::calculate_t_n, error::Error, Network, Result};

#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
Expand Down Expand Up @@ -162,8 +162,7 @@ pub fn generate_recipient_pubkeys(
if let Some((_, payments)) = silent_payment_groups.get_mut(&B_scan) {
payments.push(address);
} else {
let shared_point = calculate_shared_point(&B_scan, &partial_secret);
let ecdh_shared_secret = PublicKey::from_slice(&shared_point)?;
let ecdh_shared_secret = calculate_ecdh_shared_secret(&B_scan, &partial_secret)?;

silent_payment_groups.insert(B_scan, (ecdh_shared_secret, vec![address]));
}
Expand Down
8 changes: 6 additions & 2 deletions src/utils/receiving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,17 @@ pub fn calculate_tweak_data(
/// This function will error if:
///
/// * Elliptic curve computation results in an invalid public key.
pub fn calculate_shared_point(tweak_data: &PublicKey, b_scan: &SecretKey) -> [u8; 65] {
pub fn calculate_ecdh_shared_secret(
tweak_data: &PublicKey,
b_scan: &SecretKey,
) -> Result<PublicKey> {
let mut ss_bytes = [0u8; 65];
ss_bytes[0] = 0x04;

// Using `shared_secret_point` to ensure the multiplication is constant time
ss_bytes[1..].copy_from_slice(&shared_secret_point(&tweak_data, &b_scan));
ss_bytes

Ok(PublicKey::from_slice(&ss_bytes)?)
}

/// Get the public keys from a set of input data.
Expand Down
12 changes: 9 additions & 3 deletions src/utils/sending.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,33 @@ pub fn calculate_partial_secret(

/// Calculate the shared secret of a transaction.
///
/// Since [`crate::sending::generate_recipient_pubkeys`] calls this function internally, it is not needed for the default sending flow.
///
/// # Arguments
///
/// * `B_scan` - The scan public key used by the wallet.
/// * `partial_secret` - the sum of all (eligible) input keys multiplied with the input hash, see `calculate_partial_secret`.
///
/// # Returns
///
/// This function returns the shared secret point of this transaction. This shared secret can be used to generate output keys for the recipient, see `sending::generate_recipient_pubkeys`
/// This function returns the shared secret of this transaction. This shared secret can be used to generate output keys for the recipient.
///
/// # Errors
///
/// This function will error if:
///
/// * Elliptic curve computation results in an invalid public key.
pub fn calculate_shared_point(B_scan: &PublicKey, partial_secret: &SecretKey) -> [u8; 65] {
pub fn calculate_ecdh_shared_secret(
B_scan: &PublicKey,
partial_secret: &SecretKey,
) -> Result<PublicKey> {
let mut ss_bytes = [0u8; 65];
ss_bytes[0] = 0x04;

// Using `shared_secret_point` to ensure the multiplication is constant time
ss_bytes[1..].copy_from_slice(&shared_secret_point(B_scan, partial_secret));
ss_bytes

Ok(PublicKey::from_slice(&ss_bytes)?)
}

fn get_a_sum_secret_keys(input: &[(SecretKey, bool)]) -> Result<SecretKey> {
Expand Down
7 changes: 3 additions & 4 deletions tests/vector_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod tests {
receiving::Label,
utils::{
receiving::{
calculate_shared_point, calculate_tweak_data, get_pubkey_from_input, is_p2tr,
calculate_ecdh_shared_secret, calculate_tweak_data, get_pubkey_from_input, is_p2tr,
},
sending::calculate_partial_secret,
},
Expand Down Expand Up @@ -161,11 +161,10 @@ mod tests {
assert_eq!(set1, set2);

let tweak_data = calculate_tweak_data(&input_pub_keys, &outpoints).unwrap();
let shared_point = calculate_shared_point(&tweak_data, &b_scan);
let shared_public_key = PublicKey::from_slice(&shared_point).unwrap();
let ecdh_shared_secret = calculate_ecdh_shared_secret(&tweak_data, &b_scan).unwrap();

let scanned_outputs_received = sp_receiver
.scan_transaction(&shared_public_key, outputs_to_check)
.scan_transaction(&ecdh_shared_secret, outputs_to_check)
.unwrap();

let key_tweaks: Vec<Scalar> = scanned_outputs_received
Expand Down

0 comments on commit 98244fc

Please sign in to comment.