diff --git a/src/burnchains/bitcoin/keys.rs b/src/burnchains/bitcoin/keys.rs
index 86f4538ec..dd9a56708 100644
--- a/src/burnchains/bitcoin/keys.rs
+++ b/src/burnchains/bitcoin/keys.rs
@@ -17,219 +17,6 @@
along with Blockstack. If not, see .
*/
-use secp256k1;
-use secp256k1::Secp256k1;
-use secp256k1::constants as Secp256k1Constants;
-use secp256k1::PublicKey as Secp256k1PublicKey;
-use secp256k1::Message as Secp256k1Message;
-use secp256k1::Signature as Secp256k1Signature;
-use secp256k1::Error as Secp256k1Error;
-
-use burnchains::PublicKey;
-use util::hash::{hex_bytes, to_hex};
-
-use serde::de::Deserialize;
-use serde::de::Error as de_Error;
-
-// per-thread Secp256k1 context
-thread_local!(static _secp256k1: Secp256k1 = Secp256k1::new());
-
-#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
-pub struct BitcoinPublicKey {
- // serde is broken for secp256k1, so do it ourselves
- #[serde(serialize_with = "serialize_secp256k1_pubkey", deserialize_with = "deserialize_secp256k1_pubkey")]
- key: Secp256k1PublicKey,
- compressed: bool
-}
-
-impl BitcoinPublicKey {
- pub fn from_hex(hex_string: &str) -> Result {
- hex_bytes(hex_string)
- .and_then(|vec_bytes| BitcoinPublicKey::from_slice(&vec_bytes[..]))
- .map_err(|_e| "Invalid hex string")
- }
-
- pub fn from_slice(data: &[u8]) -> Result {
- _secp256k1.with(|ctx| {
- match Secp256k1PublicKey::from_slice(&ctx, data) {
- Ok(pubkey_res) =>
- Ok(BitcoinPublicKey {
- key: pubkey_res,
- compressed: data.len() == Secp256k1Constants::PUBLIC_KEY_SIZE
- }),
- Err(_e) => Err("Invalid public key: failed to load")
- }
- })
- }
-}
-
-impl PublicKey for BitcoinPublicKey {
- fn to_bytes(&self) -> Vec {
- if self.compressed {
- self.key.serialize().to_vec()
- }
- else {
- self.key.serialize_uncompressed().to_vec()
- }
- }
-
- fn verify(&self, data_hash: &[u8], sig_der: &[u8]) -> Result {
- _secp256k1.with(|ctx| {
- let msg = Secp256k1Message::from_slice(data_hash)
- .map_err(|_e| "Invalid message: failed to decode data hash: must be a 32-byte hash")?;
-
- let sig = Secp256k1Signature::from_der(ctx, sig_der)
- .map_err(|_e| "Invalid signature: failed to decode signature: must be DER-encoded")?;
-
- let v = ctx.verify(&msg, &sig, &self.key);
- return match v {
- Ok(()) => Ok(true),
- Err(e) =>
- match e {
- Secp256k1Error::IncorrectSignature => Ok(false),
- _ => Err("Failed to process public key or signature")
- }
- };
- })
- }
-}
-
-fn serialize_secp256k1_pubkey(pubk: &Secp256k1PublicKey, s: S) -> Result {
- let key_hex = to_hex(&pubk.serialize().to_vec());
- s.serialize_str(&key_hex.as_str())
-}
-
-fn deserialize_secp256k1_pubkey<'de, D: serde::Deserializer<'de>>(d: D) -> Result {
- let key_hex = String::deserialize(d)?;
- let key_bytes = hex_bytes(&key_hex)
- .map_err(de_Error::custom)?;
-
- _secp256k1.with(|ctx| {
- Secp256k1PublicKey::from_slice(&ctx, &key_bytes[..])
- .map_err(de_Error::custom)
- })
-}
-
-#[cfg(test)]
-mod tests {
- use util::hash::hex_bytes;
-
- use secp256k1;
- use secp256k1::Secp256k1;
- use secp256k1::PublicKey as Secp256k1PublicKey;
- use burnchains::PublicKey;
- use burnchains::bitcoin::keys::BitcoinPublicKey;
-
- use util::log;
-
- struct KeyFixture {
- input: I,
- result: R
- }
-
- struct VerifyFixture {
- public_key: &'static str,
- data: &'static str,
- signature: &'static str,
- result: R
- }
-
- #[test]
- fn test_parse_serialize() {
- let ctx : Secp256k1 = Secp256k1::new();
- let fixtures = vec![
- KeyFixture {
- input: "0233d78f74de8ef4a1de815b6d5c5c129c073786305c0826c499b1811c9a12cee5",
- result: Some(BitcoinPublicKey {
- key: Secp256k1PublicKey::from_slice(&ctx, &hex_bytes("0233d78f74de8ef4a1de815b6d5c5c129c073786305c0826c499b1811c9a12cee5").unwrap()[..]).unwrap(),
- compressed: true
- })
- },
- KeyFixture {
- input: "044a83ad59dbae1e2335f488dbba5f8604d00f612a43ebaae784b5b7124cc38c3aaf509362787e1a8e25131724d57fec81b87889aabb4edf7bd89f5c4daa4f8aa7",
- result: Some(BitcoinPublicKey {
- key: Secp256k1PublicKey::from_slice(&ctx, &hex_bytes("044a83ad59dbae1e2335f488dbba5f8604d00f612a43ebaae784b5b7124cc38c3aaf509362787e1a8e25131724d57fec81b87889aabb4edf7bd89f5c4daa4f8aa7").unwrap()[..]).unwrap(),
- compressed: false
- })
- },
- KeyFixture {
- input: "0233d78f74de8ef4a1de815b6d5c5c129c073786305c0826c499b1811c9a12ce",
- result: None,
- },
- KeyFixture {
- input: "044a83ad59dbae1e2335f488dbba5f8604d00f612a43ebaae784b5b7124cc38c3aaf509362787e1a8e25131724d57fec81b87889aabb4edf7bd89f5c4daa4f8a",
- result: None,
- }
- ];
-
- for fixture in fixtures {
- let key_res = BitcoinPublicKey::from_hex(fixture.input);
- match (key_res, fixture.result) {
- (Ok(key), Some(key_result)) => {
- assert_eq!(key, key_result);
-
- let key_from_slice = BitcoinPublicKey::from_slice(&hex_bytes(fixture.input).unwrap()[..]).unwrap();
- assert_eq!(key_from_slice, key_result);
-
- let key_bytes = key.to_bytes();
- assert_eq!(key_bytes, hex_bytes(fixture.input).unwrap());
- },
- (Err(_e), None) => {},
- (_, _) => {
- // either got a key when we didn't expect one, or didn't get a key when we did
- // expect one.
- assert!(false);
- }
- }
- }
- }
-
- #[test]
- fn test_verify() {
- let _ctx : Secp256k1 = Secp256k1::new();
- let fixtures : Vec>> = vec![
- VerifyFixture {
- public_key: "034c35b09b758678165d6ed84a50b329900c99986cf8e9a358ceae0d03af91f5b6",
- signature: "3045022100853ae0bca72d59aaa335ff967f062952348baf7cc03cd1cb60db21eda6c1fecc0220551afcbcfb81a3f2adba18608d474bf296cccc82d8fca9f2bbd1fea96b4b71dc",
- data: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", // sha256 hash of "hello world"
- result: Ok(true)
- },
- VerifyFixture {
- public_key: "034c35b09b758678165d6ed84a50b329900c99986cf8e9a358ceae0d03af91f5b6",
- signature: "3045022100853ae0bca72d59aaa335ff967f062952348baf7cc03cd1cb60db21eda6c1fecc0220551afcbcfb81a3f2adba18608d474bf296cccc82d8fca9f2bbd1fea96b4b71dc",
- data: "ca3704aa0b06f5954c79ee837faa152d84d6b2d42838f0637a15eda8337dbdce", // sha256 hash of "nope"
- result: Ok(false)
- },
- VerifyFixture {
- public_key: "034c35b09b758678165d6ed84a50b329900c99986cf8e9a358ceae0d03af91f5b6", // wrong key
- signature: "3045022100be57031bf2c095945ba2876e97b3f86ee051643a29b908f22ed45ccf58620103022061e056e5f48c5a51c66604a1ca28e4bfaabab1478424c9bbb396cc6afe5c222e",
- data: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", // sha256 hash of "hello world"
- result: Ok(false)
- },
- VerifyFixture {
- public_key: "02ade4d69dc5f11ab372e10c2fa5ea6a2c6c118dc4ae71cbdf1001292411a05457",
- signature: "3045022100853ae0bca72d59aaa335ff967f062952348baf7cc03cd1cb60db21eda6c1fecc0220551afcbcfb81a3f2adba18608d474bf296cccc82d8fca9f2bbd1fea96b4b71dc", // wrong signature
- data: "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9", // sha256 hash of "hello world"
- result: Ok(false)
- }
- ];
-
- for fixture in fixtures {
- let key = BitcoinPublicKey::from_hex(fixture.public_key).unwrap();
- let ver_res = key.verify(&hex_bytes(fixture.data).unwrap(), &hex_bytes(fixture.signature).unwrap());
- match (ver_res, fixture.result) {
- (Ok(true), Ok(true)) => {},
- (Ok(false), Ok(false)) => {},
- (Err(e1), Err(e2)) => assert_eq!(e1, e2),
- (Err(e1), _) => {
- test_debug!("Failed to verify signature: {}", e1);
- assert!(false);
- }
- (_, _) => {
- assert!(false);
- }
- }
- }
- }
-}
+use util::secp256k1;
+pub type BitcoinPublicKey = secp256k1::Secp256k1PublicKey;