spark-cryptography 0.1.11

Cryptography module for Spark Rust SDK
Documentation
use bitcoin::secp256k1::{All, Error as Secp256k1Error, PublicKey, Secp256k1, SecretKey};
use rand::rngs::OsRng;

use crate::error::SparkCryptographyError;

/// Subtracts the rhs public key from the lhs public key
///
/// Input keys must be 33-byte compressed secp256k1 public keys
///
/// # Arguments
///
/// * `pk1` - The first public key
/// * `pk2` - The second public key
///
/// # Returns
/// The result of subtracting the second public key from the first
///
/// # Errors
/// - [`SparkCryptographyError::SecpError`] if the keys are not valid.
///
/// # Examples
/// ```
/// use bitcoin::secp256k1::{PublicKey, Secp256k1};
/// use spark_cryptography::secp::subtract_public_keys;
/// use bitcoin::secp256k1::rand::rngs::OsRng;
///
/// let secp = Secp256k1::new();
/// let (_, pk1) = secp.generate_keypair(&mut OsRng);
/// let (_, pk2) = secp.generate_keypair(&mut OsRng);
/// let result = subtract_public_keys(&pk1, &pk2).unwrap();
/// ```
#[cfg_attr(feature = "telemetry", tracing::instrument(skip_all))]
pub fn subtract_public_keys(
    pk1: &PublicKey,
    pk2: &PublicKey,
) -> Result<PublicKey, SparkCryptographyError> {
    let secp = Secp256k1::new();

    // Negate the second key and add
    let negated = pk2.negate(&secp);
    Ok(pk1.combine(&negated)?)
}

/// Subtracts the rhs secret key from the lhs secret key
///
/// Input keys must be 32 bytes
///
/// # Arguments
///
/// * `sk1` - The first secret key
/// * `sk2` - The second secret key
///
/// # Returns
/// The result of subtracting the second secret key from the first
///
/// # Errors
/// - [`Secp256k1Error`] if the keys are not valid.
///
/// # Examples
/// ```
/// use bitcoin::secp256k1::{SecretKey, Secp256k1};
/// use spark_cryptography::secp::subtract_secret_keys;
/// use bitcoin::secp256k1::rand::rngs::OsRng;
///
/// let secp = Secp256k1::new();
/// let (sk1, _) = secp.generate_keypair(&mut OsRng);
/// let (sk2, _) = secp.generate_keypair(&mut OsRng);
/// let result = subtract_secret_keys(&sk1, &sk2).unwrap();
/// ```
#[cfg_attr(feature = "telemetry", tracing::instrument(skip_all))]
pub fn subtract_secret_keys(sk1: &SecretKey, sk2: &SecretKey) -> Result<SecretKey, Secp256k1Error> {
    // Negate the second key and add
    let negated = sk2.negate();
    sk1.add_tweak(&negated.into())
}

/// Generates a new keypair
///
/// # Arguments
///
/// * `secp` - The secp256k1 context
///
/// # Returns
/// A tuple of the secret key and public key
///
/// # Errors
/// - [`Secp256k1Error`] if the keys are not valid.
///
/// # Examples
/// ```
/// use bitcoin::secp256k1::{Secp256k1, All};
/// use spark_cryptography::secp::generate_keypair;
///
/// let secp = Secp256k1::new();
/// let (sk, pk) = generate_keypair(&secp);
/// ```
#[cfg_attr(feature = "telemetry", tracing::instrument(skip_all))]
pub fn generate_keypair(secp: &Secp256k1<All>) -> (SecretKey, PublicKey) {
    secp.generate_keypair(&mut OsRng)
}