Skip to content

Commit

Permalink
Add linking to documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
cygnet3 committed Jun 3, 2024
1 parent f7eafdd commit f0bde33
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 36 deletions.
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! A rust implementation of BIP352: Silent Payments. This library
//! A rust implementation of BIP352: Silent Payments. This library
//! can be used to add silent payment support to wallets.
//!
//! This library is split up in two parts: sending and receiving.
Expand All @@ -11,8 +11,8 @@
//! In the meantime, have a look at the [test vectors from the BIP](https://github.com/cygnet3/rust-silentpayments/blob/master/tests/vector_tests.rs)
//! to see how to do a simple implementation.
//!
//! Alternatively, have a look at [Donation wallet](https://github.com/cygnet3/sp-backend/tree/master),
//! which is a WIP 'silent payments native' wallet.
//! Alternatively, have a look at [Sp client](https://github.com/cygnet3/sp-client/tree/master),
//! which is a WIP wallet client for building silent payment wallets.
#![allow(dead_code, non_snake_case)]
mod common;
mod error;
Expand Down
36 changes: 19 additions & 17 deletions src/receiving.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//! The receiving component of silent payments.
//!
//! For receiving, we use the `Receiver` struct.
//! For receiving, we use the [`Receiver`] struct.
//! This struct does not contain any private key information,
//! so as to avoid having access to secret data.
//!
//! After creating a `Receiver` object, you can call `scan_transaction`,
//! After creating a [`Receiver`] object, you can call [`scan_transaction`](Receiver::scan_transaction),
//! to scan a specific transaction for outputs belonging to this receiver.
//! For this, you need to have calculated the `ecdh_shared_secret` beforehand.
//! To do so, you can use `utils::receiving::calculate_shared_secret`.
//! To do so, you can use [`calculate_ecdh_shared_secret`](`crate::utils::receiving::calculate_ecdh_shared_secret`) from the `utils` module.
//!
//! For a concrete example, you can have a look at the [vector tests](https://github.com/cygnet3/rust-silentpayments/blob/master/tests/vector_tests.rs).
//! For a concrete example, have a look at the [test vectors](https://github.com/cygnet3/rust-silentpayments/blob/master/tests/vector_tests.rs).
use std::{
collections::{HashMap, HashSet},
fmt,
Expand All @@ -29,6 +29,7 @@ use serde::{
Deserialize, Deserializer, Serialize,
};

/// A Silent payment receiving label.
#[derive(Eq, PartialEq, Clone)]
pub struct Label {
s: Scalar,
Expand Down Expand Up @@ -103,9 +104,10 @@ impl From<Label> for Scalar {
}

/// A struct representing a silent payment recipient.
/// It can be used to scan for transaction outputs belonging to us by using the scan_transaction function.
///
/// It can be used to scan for transaction outputs belonging to us by using the [`scan_transaction`](Receiver::scan_transaction) function.
/// It optionally supports labels, which it manages internally.
/// Labels can be added with the add_label function.
/// Labels can be added with [`add_label`](Receiver::add_label).
#[derive(Debug, Clone, PartialEq)]
pub struct Receiver {
version: u8,
Expand Down Expand Up @@ -281,8 +283,8 @@ impl Receiver {
Ok(receiver)
}

/// Takes a Label and adds it to the list of labels that this recipient uses.
/// Returns a bool on success, `true` if the label was new, `false` if it already existed in our list.
/// Takes a [Label] and adds it to the list of labels that this recipient uses.
/// Returns a bool on success, [true] if the label was new, [false] if it already existed in our list.
pub fn add_label(&mut self, label: Label) -> Result<bool> {
let secp = Secp256k1::signing_only();

Expand All @@ -306,11 +308,11 @@ impl Receiver {
///
/// # Arguments
///
/// * `label` - A reference to a Label.
/// * `label` - A reference to a [Label].
///
/// # Returns
///
/// If successful, the function returns a `Result` wrapping a String, which is the bech32m encoded silent payment address.
/// If successful, the function returns a [Result] wrapping a [String], which is the bech32m encoded silent payment address.
///
/// # Errors
///
Expand Down Expand Up @@ -348,7 +350,7 @@ impl Receiver {
///
/// # Returns
///
/// If successful, the function returns a `String`, which is the bech32m encoded silent payment address.
/// If successful, the function returns a [String], which is the bech32m encoded silent payment address.
pub fn get_receiving_address(&self) -> String {
self.encode_silent_payment_address(self.spend_pubkey)
}
Expand All @@ -357,19 +359,19 @@ impl Receiver {
///
/// # Arguments
///
/// * `ecdh_shared_secret` - The ECDH shared secret between sender and recipient as a PublicKey, the result of elliptic-curve multiplication of `(input_hash * sum_inputs_pubkeys) * scan_private_key`.
/// * `pubkeys_to_check` - A `HashSet` of public keys of all (unspent) taproot output of the transaction.
/// * `ecdh_shared_secret` - The ECDH shared secret between sender and recipient as a [PublicKey], the result of elliptic-curve multiplication of `(input_hash * sum_inputs_pubkeys) * scan_private_key`.
/// * `pubkeys_to_check` - A [HashSet] of public keys of all (unspent) taproot output of the transaction.
///
/// # Returns
///
/// If successful, the function returns a `Result` wrapping a `HashMap` of labels to a map of outputs to key tweaks (since the same label may have been paid multiple times in one transaction). The key tweaks can be added to the wallet's spending private key to produce a key that can spend the utxo. A resulting `HashMap` of length 0 implies none of the outputs are owned by us.
/// If successful, the function returns a [Result] wrapping a [HashMap] of labels to a map of outputs to key tweaks (since the same label may have been paid multiple times in one transaction). The key tweaks can be added to the wallet's spending private key to produce a key that can spend the utxo. A resulting [HashMap] of length 0 implies none of the outputs are owned by us.
///
/// # Errors
///
/// This function will return an error if:
///
/// * One of the public keys to scan can't be parsed into a valid x-only public key.
/// * An error occurs during elliptic curve computation. This may happen if a sender is being malicious. (?)
/// * An error occurs during elliptic curve computation. This may happen if a sender is being malicious.
pub fn scan_transaction(
&self,
ecdh_shared_secret: &PublicKey,
Expand Down Expand Up @@ -423,13 +425,13 @@ impl Receiver {
///
/// # Returns
///
/// If successful, the function returns a `Result` wrapping a HashMap that maps an optional Label to a Script as a 34-byte vector. The script has the following format: `OP_PUSHNUM_1 OP_PUSHBYTES_32 taproot_output`
/// If successful, the function returns a [Result] wrapping a [HashMap] that maps an optional [Label] to a Script as a 34-byte vector. The script has the following format: `OP_PUSHNUM_1 OP_PUSHBYTES_32 taproot_output`
///
/// # Errors
///
/// This function will return an error if:
///
/// * An error occurs during elliptic curve computation. This may happen if a sender is being malicious. (?)
/// * An error occurs during elliptic curve computation. This may happen if a sender is being malicious.
pub fn get_spks_from_shared_secret(
&self,
ecdh_shared_secret: &PublicKey,
Expand Down
20 changes: 11 additions & 9 deletions src/sending.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//! The sending component of silent payments.
//!
//! The most relevant function is `generate_recipient_pubkeys`,
//! which can be used to create outputs for a list of silent payment receipients.
//! The [`generate_recipient_pubkeys`] function can be used to create outputs for a list of silent payment recipients.
//!
//! Using `generate_recipient_pubkeys` will require calculating a
//! Using [`generate_recipient_pubkeys`] will require calculating a
//! `partial_secret` beforehand.
//! To do this, you can use the function from `utils::sending::calculate_partial_secret`.
//! To do this, you can use [`calculate_partial_secret`](crate::utils::sending::calculate_partial_secret) from the `utils` module.
//! See the [tests on github](https://github.com/cygnet3/rust-silentpayments/blob/master/tests/vector_tests.rs)
//! for a concrete example.
use bech32::{FromBase32, ToBase32};
Expand All @@ -17,6 +16,7 @@ use std::collections::HashMap;
use crate::utils::sending::calculate_ecdh_shared_secret;
use crate::{common::calculate_t_n, error::Error, Network, Result};

/// A silent payment address struct.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub struct SilentPaymentAddress {
version: u8,
Expand Down Expand Up @@ -128,24 +128,26 @@ impl From<SilentPaymentAddress> for String {
}

/// Create outputs for a given set of silent payment recipients and their corresponding shared secrets.
///
/// When creating the outputs for a transaction, this function should be used to generate the output keys.
///
/// This function should only be used once per transaction! If used multiple times, address reuse may occur.
///
/// # Arguments
///
/// * `recipients` - A `Vec` of silent payment addresses to be paid.
/// * `partial_secret` - A `SecretKey` that represents the sum of the private keys of eligible inputs of the transaction multiplied by the input hash.
/// * `recipients` - A [Vec] of silent payment addresses strings to be paid.
/// * `partial_secret` - A [SecretKey] that represents the sum of the private keys of eligible inputs of the transaction multiplied by the input hash.
///
/// # Returns
///
/// If successful, the function returns a `Result` wrapping a `HashMap` of silent payment addresses to a `Vec`.
/// The `Vec` contains all the outputs that are associated with the silent payment address.
/// If successful, the function returns a [Result] wrapping a [HashMap] of silent payment addresses to a [Vec].
/// The [Vec] contains all the outputs that are associated with the silent payment address.
///
/// # Errors
///
/// This function will return an error if:
///
/// * The recipients Vec contains a silent payment address with an incorrect format.
/// * The recipients [Vec] contains a silent payment address with an incorrect format.
/// * Edge cases are hit during elliptic curve computation (extremely unlikely).
pub fn generate_recipient_pubkeys(
recipients: Vec<String>,
Expand Down
2 changes: 1 addition & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub mod receiving;
#[cfg(feature = "sending")]
pub mod sending;

// NUMS_H (defined in BIP340)
/// [BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki)-defined 'Nothing Up My Sleeve' point.
pub const NUMS_H: [u8; 32] = [
0x50, 0x92, 0x9b, 0x74, 0xc1, 0xa0, 0x49, 0x54, 0xb7, 0x8b, 0x4b, 0x60, 0x35, 0xe9, 0x7a, 0x5e,
0x07, 0x8a, 0x5a, 0x0f, 0x28, 0xec, 0x96, 0xd5, 0x47, 0xbf, 0xee, 0x9a, 0xce, 0x80, 0x3a, 0xc0,
Expand Down
6 changes: 4 additions & 2 deletions src/utils/receiving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use secp256k1::{PublicKey, SecretKey};
use super::{hash::calculate_input_hash, COMPRESSED_PUBKEY_SIZE, NUMS_H};

/// Calculate the tweak data of a transaction.
/// This is useful in combination with the `calculate_shared_secret` function, but can also be used
///
/// This is useful in combination with the [calculate_ecdh_shared_secret] function, but can also be used
/// by indexing servers that don't have access to the recipient scan key.
///
/// # Arguments
Expand Down Expand Up @@ -53,6 +54,7 @@ pub fn calculate_tweak_data(
/// # Returns
///
/// This function returns the shared secret of this transaction. This shared secret can be used to scan the transaction of outputs that are for the current user. See `receiving::scan_transaction`.
/// This function returns the shared secret of this transaction. This shared secret can be used to scan the transaction of outputs that are for the current user. See [`Receiver::scan_transaction`](crate::receiving::Receiver::scan_transaction).
pub fn calculate_ecdh_shared_secret(tweak_data: &PublicKey, b_scan: &SecretKey) -> PublicKey {
let mut ss_bytes = [0u8; 65];
ss_bytes[0] = 0x04;
Expand All @@ -73,7 +75,7 @@ pub fn calculate_ecdh_shared_secret(tweak_data: &PublicKey, b_scan: &SecretKey)
///
/// # Returns
///
/// If no errors occur, this function will optionally return a PublicKey if this input is silent payment-eligible.
/// If no errors occur, this function will optionally return a [PublicKey] if this input is silent payment-eligible.
///
/// # Errors
///
Expand Down
8 changes: 4 additions & 4 deletions src/utils/sending.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use super::hash::calculate_input_hash;
///
/// # Arguments
///
/// * `input_keys` - A reference to a list of tuples, each tuple containing a `SecretKey` and `bool`. The `SecretKey` is the private key used in the input, and the `bool` indicates whether this was from a taproot address.
/// * `outpoints_data` - The prevout outpoints used as input for this transaction. Note that the txid is given in String format, which is displayed in reverse order from the inner byte array.
/// * `input_keys` - A reference to a list of tuples, each tuple containing a [SecretKey] and [bool]. The [SecretKey] is the private key used in the input, and the [bool] indicates whether this was from a taproot address.
/// * `outpoints_data` - The prevout outpoints used as input for this transaction. Note that the txid is given in [String] format, which is displayed in reverse order from the inner byte array.
///
/// # Returns
///
Expand Down Expand Up @@ -37,12 +37,12 @@ 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.
/// Since [generate_recipient_pubkeys](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`.
/// * `partial_secret` - the sum of all (eligible) input keys multiplied with the input hash, see [calculate_partial_secret].
///
/// # Returns
///
Expand Down

0 comments on commit f0bde33

Please sign in to comment.