Skip to content

Commit

Permalink
Add create commit from pubkey function (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeastplume authored Mar 25, 2020
1 parent 0683a3d commit 69adbfc
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,11 @@ extern "C" {
cx: *const Context, pk: *mut PublicKey,
commit: *const c_uchar) -> c_int;

// Get a pedersen commitment from a pubkey
pub fn secp256k1_pubkey_to_pedersen_commitment(
cx: *const Context, commit: *mut c_uchar,
pk: *const PublicKey) -> c_int;

// Takes a list of n pointers to 32 byte blinding values, the first negs
// of which are treated with positive sign and the rest negative, then
// calculates an additional blinding value that adds to zero.
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,8 @@ pub enum Error {
InvalidMessage,
/// Bad public key
InvalidPublicKey,
/// Bad commit
InvalidCommit,
/// Bad signature
InvalidSignature,
/// Bad secret key
Expand Down Expand Up @@ -493,6 +495,7 @@ impl error::Error for Error {
Error::IncorrectSignature => "secp: signature failed verification",
Error::InvalidMessage => "secp: message was not 32 bytes (do you need to hash?)",
Error::InvalidPublicKey => "secp: malformed public key",
Error::InvalidCommit => "secp: malformed commit",
Error::InvalidSignature => "secp: malformed signature",
Error::InvalidSecretKey => "secp: malformed or out-of-range secret key",
Error::InvalidRecoveryId => "secp: bad recovery id",
Expand Down
49 changes: 48 additions & 1 deletion src/pedersen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use std::ptr;
use std::u64;

use crate::ContextFlag;
use crate::Error::{self, InvalidPublicKey};
use crate::Error::{self, InvalidPublicKey, InvalidCommit};
use crate::Secp256k1;

use super::{Message, Signature};
Expand Down Expand Up @@ -95,6 +95,18 @@ impl Commitment {
mem::uninitialized()
}

/// Creates from a pubkey
pub fn from_pubkey(secp: &Secp256k1, pk: &key::PublicKey) -> Result<Self, Error> {
unsafe {
let mut commit = Self::blank();
if ffi::secp256k1_pubkey_to_pedersen_commitment(secp.ctx, commit.as_mut_ptr(), &pk.0) == 1 {
Ok(commit)
} else {
Err(InvalidCommit)
}
}
}

/// Converts a commitment to a public key
pub fn to_pubkey(&self, secp: &Secp256k1) -> Result<key::PublicKey, Error> {
let mut pk = unsafe { ffi::PublicKey::blank() };
Expand All @@ -107,6 +119,7 @@ impl Commitment {
}
}
}

}

/// A range proof. Typically much larger in memory that the above (~5k).
Expand Down Expand Up @@ -1276,6 +1289,40 @@ mod tests {
}
}

#[test]
fn test_from_pubkey() {
for _ in 0..100 {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let blinding = SecretKey::new(&secp, &mut thread_rng());
let commit = secp.commit(1, blinding).unwrap();
let pubkey = commit.to_pubkey(&secp);
let p = match pubkey {
Ok(p) => {
// this is good
p
}
Err(e) => {
panic!("Creating pubkey: {}", e);
}
};
//println!("Pre Commit is: {:?}", commit);
//println!("Pre Pubkey is: {:?}", p);
let new_commit = Commitment::from_pubkey(&secp, &p);
let commit2 = match new_commit {
Ok(c) => {
// this is good
c
}
Err(e) => {
panic!("Creating commit from Pubkey: {}", e);
}
};
//println!("Post Commit is: {:?}", commit2);
//println!("Post Pubkey is: {:?}", p);
assert_eq!(commit, commit2);
}
}

#[test]
fn test_sign_with_pubkey_from_commitment() {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
Expand Down

0 comments on commit 69adbfc

Please sign in to comment.