Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: remove default Schnorr functionality #180

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions benches/signatures.rs
Expand Up @@ -6,10 +6,13 @@ use std::time::Duration;
use criterion::{criterion_group, BatchSize, Criterion};
use rand::{thread_rng, RngCore};
use tari_crypto::{
hash_domain,
keys::{PublicKey, SecretKey},
ristretto::{RistrettoPublicKey, RistrettoSchnorr, RistrettoSecretKey},
};

hash_domain!(BenchDomain, "com.example.bench");

fn generate_secret_key(c: &mut Criterion) {
c.bench_function("Generate secret key", |b| {
let mut rng = thread_rng();
Expand Down Expand Up @@ -45,7 +48,7 @@ fn sign_message(c: &mut Criterion) {
b.iter_batched(
gen_keypair,
|d| {
let _sig = RistrettoSchnorr::sign_message(&d.k, d.m).unwrap();
let _sig: RistrettoSchnorr<BenchDomain> = RistrettoSchnorr::sign_message(&d.k, d.m).unwrap();
},
BatchSize::SmallInput,
);
Expand All @@ -59,7 +62,7 @@ fn verify_message(c: &mut Criterion) {
b.iter_batched(
|| {
let d = gen_keypair();
let s = RistrettoSchnorr::sign_message(&d.k, d.m).unwrap();
let s: RistrettoSchnorr<BenchDomain> = RistrettoSchnorr::sign_message(&d.k, d.m).unwrap();
(d, s)
},
|(d, s)| assert!(s.verify_message(&d.p, d.m)),
Expand Down
180 changes: 0 additions & 180 deletions src/ffi/keys.rs
Expand Up @@ -20,7 +20,6 @@ use crate::{
RistrettoComAndPubSig,
RistrettoComSig,
RistrettoPublicKey,
RistrettoSchnorr,
RistrettoSecretKey,
},
};
Expand Down Expand Up @@ -51,87 +50,6 @@ pub unsafe extern "C" fn random_keypair(priv_key: *mut KeyArray, pub_key: *mut K
OK
}

/// Generate a Schnorr signature (s, R) using the provided private key and message (k, m).
///
/// # Safety
/// The caller MUST ensure that the string is null terminated e.g. "msg\0".
/// If any args are null then the function returns -1
///
/// The public nonce and signature are returned in the provided mutable arrays.
#[no_mangle]
pub unsafe extern "C" fn sign(
priv_key: *const KeyArray,
msg: *const c_char,
public_nonce: *mut KeyArray,
signature: *mut KeyArray,
) -> c_int {
if public_nonce.is_null() || signature.is_null() || priv_key.is_null() || msg.is_null() {
return NULL_POINTER;
}
let k = match RistrettoSecretKey::from_bytes(&(*priv_key)) {
Ok(k) => k,
_ => return INVALID_SECRET_KEY_SER,
};
let pubkey = RistrettoPublicKey::from_secret_key(&k);
let r = RistrettoSecretKey::random(&mut OsRng);
let pub_r = RistrettoPublicKey::from_secret_key(&r);
let msg = match CStr::from_ptr(msg).to_str() {
Ok(s) => s,
_ => return STR_CONV_ERR,
};
let e = RistrettoSchnorr::construct_domain_separated_challenge::<_, Blake256>(&pub_r, &pubkey, msg.as_bytes());
let sig = match RistrettoSchnorr::sign_raw(&k, r, e.as_ref()) {
Ok(sig) => sig,
_ => return SIGNING_ERROR,
};
(*public_nonce).copy_from_slice(sig.get_public_nonce().as_bytes());
(*signature).copy_from_slice(sig.get_signature().as_bytes());
OK
}

/// Verify that a Schnorr signature (s, R) is valid for the provided public key and message (P, m).
///
/// # Safety
/// The caller MUST ensure that the string is null terminated e.g. "msg\0".
/// If any args are null then the function returns false, and sets `err_code` to -1
#[no_mangle]
pub unsafe extern "C" fn verify(
pub_key: *const KeyArray,
msg: *const c_char,
pub_nonce: *const KeyArray,
signature: *const KeyArray,
err_code: *mut c_int,
) -> bool {
if pub_key.is_null() || msg.is_null() || pub_nonce.is_null() || signature.is_null() || err_code.is_null() {
if !err_code.is_null() {
*err_code = NULL_POINTER;
}
return false;
}
let pk = match RistrettoPublicKey::from_bytes(&(*pub_key)) {
Ok(k) => k,
_ => {
*err_code = INVALID_SECRET_KEY_SER;
return false;
},
};
let r_pub = match RistrettoPublicKey::from_bytes(&(*pub_nonce)) {
Ok(r) => r,
_ => return false,
};
let sig = match RistrettoSecretKey::from_bytes(&(*signature)) {
Ok(s) => s,
_ => return false,
};
let msg = match CStr::from_ptr(msg).to_str() {
Ok(s) => s,
_ => return false,
};

let sig = RistrettoSchnorr::new(r_pub, sig);
sig.verify_message(&pk, msg.as_bytes())
}

/// Generate a Pedersen commitment (C) using the provided value and spending key (a, x).
///
/// # Safety
Expand Down Expand Up @@ -442,102 +360,4 @@ mod test {
pub_key
);
}

#[test]
pub fn test_sign_invalid_params() {
unsafe {
let priv_key = [0; KEY_LENGTH];
let msg = "msg\0";
let mut nonce = [0; KEY_LENGTH];
let mut signature = [0; KEY_LENGTH];
assert_eq!(
sign(null_mut(), msg.as_ptr() as *const c_char, &mut nonce, &mut signature),
NULL_POINTER
);
assert_eq!(sign(&priv_key, null_mut(), &mut nonce, &mut signature), NULL_POINTER);
assert_eq!(
sign(&priv_key, msg.as_ptr() as *const c_char, null_mut(), &mut signature),
NULL_POINTER
);
assert_eq!(
sign(&priv_key, msg.as_ptr() as *const c_char, &mut nonce, null_mut()),
NULL_POINTER
);
}
}

#[test]
pub fn test_sign_valid_params() {
let priv_key = [1; KEY_LENGTH];
let msg = "msg\0";
let mut nonce = [0; KEY_LENGTH];
let mut signature = [0; KEY_LENGTH];
unsafe {
assert_eq!(
sign(&priv_key, msg.as_ptr() as *const c_char, &mut nonce, &mut signature),
OK
);
}
}

#[test]
pub fn test_verify_invalid_params() {
let pub_key = [1; KEY_LENGTH];
let msg = "msg\0";
let pub_nonce = [0; KEY_LENGTH];
let signature = [0; KEY_LENGTH];
let mut err_code = 0i32;
unsafe {
assert!(!verify(
null_mut(),
msg.as_ptr() as *const c_char,
&pub_nonce,
&signature,
&mut err_code
),);
assert!(!verify(&pub_key, null_mut(), &pub_nonce, &signature, &mut err_code),);
assert!(!verify(
&pub_key,
msg.as_ptr() as *const c_char,
null_mut(),
&signature,
&mut err_code
),);
assert!(!verify(
&pub_key,
msg.as_ptr() as *const c_char,
&pub_nonce,
null_mut(),
&mut err_code
),);
assert!(!verify(
&pub_key,
msg.as_ptr() as *const c_char,
&pub_nonce,
&signature,
null_mut()
),);
}
}

#[test]
pub fn test_verify_success() {
let mut priv_key: KeyArray = [0; KEY_LENGTH];
let mut pub_key: KeyArray = [0; KEY_LENGTH];
let mut pub_nonce: KeyArray = [0; KEY_LENGTH];
let mut signature: KeyArray = [0; KEY_LENGTH];
let msg = "msg\0";
let mut err_code = 0i32;
unsafe {
random_keypair(&mut priv_key, &mut pub_key);
sign(&priv_key, msg.as_ptr() as *const c_char, &mut pub_nonce, &mut signature);
assert!(verify(
&pub_key,
msg.as_ptr() as *const c_char,
&pub_nonce,
&signature,
&mut err_code
));
}
}
}
11 changes: 1 addition & 10 deletions src/ffi/mod.rs
Expand Up @@ -9,16 +9,7 @@ mod error;
mod keys;

pub use error::lookup_error_message;
pub use keys::{
commitment,
random_keypair,
sign,
sign_comandpubsig,
sign_comsig,
verify,
verify_comandpubsig,
verify_comsig,
};
pub use keys::{commitment, random_keypair, sign_comandpubsig, sign_comsig, verify_comandpubsig, verify_comsig};

const VERSION: &str = concat!(env!("CARGO_PKG_VERSION"), "\u{00}");

Expand Down
3 changes: 1 addition & 2 deletions src/ristretto/mod.rs
Expand Up @@ -12,7 +12,6 @@ mod ristretto_com_sig;
pub mod ristretto_keys;
mod ristretto_sig;
pub mod serialize;
pub mod utils;

// Re-export
pub use dalek_range_proof::DalekRangeProofService;
Expand All @@ -21,7 +20,7 @@ pub use self::{
ristretto_com_and_pub_sig::RistrettoComAndPubSig,
ristretto_com_sig::RistrettoComSig,
ristretto_keys::{RistrettoPublicKey, RistrettoSecretKey},
ristretto_sig::{RistrettoSchnorr, RistrettoSchnorrWithDomain},
ristretto_sig::RistrettoSchnorr,
};

// test modules
Expand Down