1#![cfg_attr(not(test), deprecated)]
22
23use secp256k1::{self, Secp256k1, SecretKey};
24use PrivateKey;
25use PublicKey;
26use hashes::{sha256, Hash, HashEngine, Hmac, HmacEngine};
27use blockdata::{opcodes, script};
28
29use std::{error, fmt};
30
31use hash_types::ScriptHash;
32use network::constants::Network;
33use util::address;
34
35static PUBKEY: u8 = 0xFE;
37
38#[derive(Debug, PartialEq, Eq, Clone)]
40pub enum Error {
41 Secp(secp256k1::Error),
43 Script(script::Error),
45 UncompressedKey,
49 ExpectedKey,
51 ExpectedChecksig,
54 TooFewKeys(usize),
56 TooManyKeys(usize)
58}
59
60impl fmt::Display for Error {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 match *self {
63 Error::Secp(ref e) => fmt::Display::fmt(&e, f),
64 Error::Script(ref e) => fmt::Display::fmt(&e, f),
65 Error::UncompressedKey => f.write_str("encountered uncompressed secp public key"),
66 Error::ExpectedKey => f.write_str("expected key when deserializing script"),
67 Error::ExpectedChecksig => f.write_str("expected OP_*CHECKSIG* when deserializing script"),
68 Error::TooFewKeys(n) => write!(f, "got {} keys, which was not enough", n),
69 Error::TooManyKeys(n) => write!(f, "got {} keys, which was too many", n)
70 }
71 }
72}
73
74impl error::Error for Error {
75 fn cause(&self) -> Option<&dyn error::Error> {
76 match *self {
77 Error::Secp(ref e) => Some(e),
78 Error::Script(ref e) => Some(e),
79 _ => None
80 }
81 }
82}
83
84#[derive(Copy, Clone, PartialEq, Eq, Debug)]
86enum TemplateElement {
87 Op(opcodes::All),
88 Key
89}
90
91#[derive(Clone, PartialEq, Eq, Debug)]
93pub struct Template(Vec<TemplateElement>);
94
95impl Template {
96 pub fn to_script(&self, secp: &Secp256k1, keys: &[PublicKey]) -> Result<script::Script, Error> {
98 let mut key_index = 0;
99 let mut ret = script::Builder::new();
100 for elem in &self.0 {
101 ret = match *elem {
102 TemplateElement::Op(opcode) => ret.push_opcode(opcode),
103 TemplateElement::Key => {
104 if key_index == keys.len() {
105 return Err(Error::TooFewKeys(key_index));
106 }
107 key_index += 1;
108 ret.push_key(secp, &keys[key_index - 1])
109 }
110 }
111 }
112 if key_index == keys.len() {
113 Ok(ret.into_script())
114 } else {
115 Err(Error::TooManyKeys(keys.len()))
116 }
117 }
118
119 pub fn required_keys(&self) -> usize {
121 self.0.iter().filter(|e| **e == TemplateElement::Key).count()
122 }
123
124 pub fn first_push_as_number(&self) -> Option<usize> {
129 if !self.0.is_empty() {
130 if let TemplateElement::Op(op) = self.0[0] {
131 if let opcodes::Class::PushNum(n) = op.classify() {
132 if n >= 0 {
133 return Some(n as usize);
134 }
135 }
136 }
137 }
138 None
139 }
140}
141
142impl<'a> From<&'a [u8]> for Template {
143 fn from(slice: &'a [u8]) -> Template {
144 Template(slice.iter().map(|&byte| {
145 if byte == PUBKEY {
146 TemplateElement::Key
147 } else {
148 TemplateElement::Op(opcodes::All::from(byte))
149 }
150 }).collect())
151 }
152}
153
154pub fn tweak_key(secp: &Secp256k1, mut key: PublicKey, contract: &[u8]) -> PublicKey {
156 let hmac_result = compute_tweak(secp, &key, contract);
157 key.key.add_exp_assign(
158 secp, &SecretKey::from_slice(secp, &hmac_result[..]).expect("HMAC cannot produce invalid tweak")
159 ).expect("HMAC cannot produce invalid tweak");
160 key
161}
162
163pub fn tweak_keys(secp: &Secp256k1, keys: &[PublicKey], contract: &[u8]) -> Vec<PublicKey> {
165 keys.iter().cloned().map(|key| tweak_key(secp, key, contract)).collect()
166}
167
168pub fn compute_tweak(secp: &Secp256k1, pk: &PublicKey, contract: &[u8]) -> Hmac<sha256::Hash> {
170 let mut hmac_engine: HmacEngine<sha256::Hash> = if pk.compressed {
171 HmacEngine::new(&pk.key.serialize_vec(secp, true)[..])
172 } else {
173 HmacEngine::new(&pk.key.serialize_vec(secp, false)[..])
174 };
175 hmac_engine.input(contract);
176 Hmac::from_engine(hmac_engine)
177}
178
179pub fn tweak_secret_key(secp: &Secp256k1, key: &PrivateKey, contract: &[u8]) -> Result<PrivateKey, Error> {
181 let pk = PublicKey::from_private_key(secp, &key);
183 let hmac_sk = compute_tweak(secp, &pk, contract);
185 let mut key = key.clone();
187 key.key.add_assign(secp,
188 &SecretKey::from_slice(secp, &hmac_sk[..]).map_err(Error::Secp)?
189 ).map_err(Error::Secp)?;
190 Ok(key)
192}
193
194pub fn create_address(secp: &Secp256k1,
196 network: Network,
197 contract: &[u8],
198 keys: &[PublicKey],
199 template: &Template)
200 -> Result<address::Address, Error> {
201 let keys = tweak_keys(secp, keys, contract);
202 let script = template.to_script(secp, &keys)?;
203
204 let mut address = address::Address::new_btc();
205 address.network = network;
206 address.payload = address::Payload::ScriptHash(
207 ScriptHash::hash(&script[..])
208 );
209
210 Ok(address)
211}
212
213pub fn untemplate(secp: &Secp256k1, script: &script::Script) -> Result<(Template, Vec<PublicKey>), Error> {
215 let mut ret = script::Builder::new();
216 let mut retkeys = vec![];
217
218 #[derive(Copy, Clone, PartialEq, Eq)]
219 enum Mode {
220 SeekingKeys,
221 CopyingKeys,
222 SeekingCheckMulti
223 }
224
225 let mut mode = Mode::SeekingKeys;
226 for instruction in script.instructions() {
227 if let Err(e) = instruction {
228 return Err(Error::Script(e));
229 }
230 match instruction.unwrap() {
231 script::Instruction::PushBytes(data) => {
232 let n = data.len();
233 ret = match PublicKey::from_slice(secp, data) {
234 Ok(key) => {
235 if n == 65 { return Err(Error::UncompressedKey); }
236 if mode == Mode::SeekingCheckMulti { return Err(Error::ExpectedChecksig); }
237 retkeys.push(key);
238 mode = Mode::CopyingKeys;
239 ret.push_opcode(opcodes::All::from(PUBKEY))
240 }
241 Err(_) => {
242 match mode {
245 Mode::SeekingKeys => { ret.push_slice(data) }
246 Mode::CopyingKeys => { return Err(Error::ExpectedKey); },
247 Mode::SeekingCheckMulti => { return Err(Error::ExpectedChecksig); }
248 }
249 }
250 }
251 }
252 script::Instruction::Op(op) => {
253 match op.classify() {
254 opcodes::Class::Ordinary(opcodes::Ordinary::OP_CHECKSIG) |
256 opcodes::Class::Ordinary(opcodes::Ordinary::OP_CHECKSIGVERIFY) => {
257 if mode == Mode::SeekingKeys { return Err(Error::ExpectedKey); }
258 mode = Mode::SeekingKeys;
259 }
260 opcodes::Class::Ordinary(opcodes::Ordinary::OP_CHECKMULTISIG) |
262 opcodes::Class::Ordinary(opcodes::Ordinary::OP_CHECKMULTISIGVERIFY) => {
263 if mode == Mode::SeekingKeys { return Err(Error::ExpectedKey); }
264 if mode == Mode::CopyingKeys { return Err(Error::ExpectedKey); }
265 mode = Mode::SeekingKeys;
266 }
267 opcodes::Class::PushNum(_) => {
269 if mode == Mode::SeekingCheckMulti { return Err(Error::ExpectedChecksig); }
270 if mode == Mode::CopyingKeys { mode = Mode::SeekingCheckMulti; }
271 }
272 _ => {}
274 }
275 ret = ret.push_opcode(op);
276 }
277 }
278 }
279 Ok((Template::from(&ret[..]), retkeys))
280}
281
282#[cfg(test)]
283mod tests {
284 use secp256k1::Secp256k1;
285 use hashes::hex::FromHex;
286 use secp256k1::rand::thread_rng;
287 use std::str::FromStr;
288
289 use blockdata::script::Script;
290 use network::constants::Network;
291
292 use super::*;
293 use PublicKey;
294
295 macro_rules! hex (($hex:expr) => (Vec::from_hex($hex).unwrap()));
296 macro_rules! hex_key (($secp:expr, $hex:expr) => (PublicKey::from_slice($secp, &hex!($hex)).unwrap()));
297 macro_rules! alpha_template(() => (Template::from(&hex!("55fefefefefefefe57AE")[..])));
298 macro_rules! alpha_keys(($secp:expr) => (
299 &[hex_key!($secp, "0269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d933"),
300 hex_key!($secp, "021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a"),
301 hex_key!($secp, "02174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea1"),
302 hex_key!($secp, "033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a"),
303 hex_key!($secp, "0313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c2"),
304 hex_key!($secp, "030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab0"),
305 hex_key!($secp, "02fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce")]
306 ));
307
308 #[test]
309 fn sanity() {
310 let secp = Secp256k1::new();
311 let keys = alpha_keys!(&secp);
312 let contract = hex!("5032534894ffbf32c1f1c0d3089b27c98fd991d5d7329ebd7d711223e2cde5a9417a1fa3e852c576");
314
315 let addr = create_address(&secp, Network::Testnet, &contract, keys, &alpha_template!()).unwrap();
316 assert_eq!(addr.to_string(), "2N3zXjbwdTcPsJiy8sUK9FhWJhqQCxA8Jjr".to_owned());
317 }
318
319 #[test]
320 fn script() {
321 let secp = Secp256k1::new();
322 let alpha_keys = alpha_keys!(&secp);
323 let alpha_template = alpha_template!();
324
325 let alpha_redeem = Script::from(hex!("55210269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d93321021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a2102174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea121033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a210313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c221030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab02102fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce57ae"));
326 let (template, keys) = untemplate(&secp, &alpha_redeem).unwrap();
327
328 assert_eq!(keys, alpha_keys);
329 assert_eq!(template, alpha_template);
330 }
331
332 #[test]
333 fn tweak_secret() {
334 let secp = Secp256k1::new();
335 let (sk1, pk1) = secp.generate_keypair(&mut thread_rng()).unwrap();
336 let (sk2, pk2) = secp.generate_keypair(&mut thread_rng()).unwrap();
337 let (sk3, pk3) = secp.generate_keypair(&mut thread_rng()).unwrap();
338
339 let sk1 = PrivateKey {
340 key: sk1,
341 compressed: true,
342 network: Network::Bitcoin,
343 };
344 let sk2 = PrivateKey {
345 key: sk2,
346 compressed: false,
347 network: Network::Bitcoin,
348 };
349 let sk3 = PrivateKey {
350 key: sk3,
351 compressed: true,
352 network: Network::Bitcoin,
353 };
354 let pks = [
355 PublicKey { key: pk1, compressed: true },
356 PublicKey { key: pk2, compressed: false },
357 PublicKey { key: pk3, compressed: true },
358 ];
359 let contract = b"if bottle mt dont remembr drink wont pay";
360
361 let tweaked_pks = tweak_keys(&secp, &pks, &contract[..]);
363 let tweaked_pk1 = PublicKey::from_private_key(&secp, &tweak_secret_key(&secp, &sk1, &contract[..]).unwrap());
365 let tweaked_pk2 = PublicKey::from_private_key(&secp, &tweak_secret_key(&secp, &sk2, &contract[..]).unwrap());
366 let tweaked_pk3 = PublicKey::from_private_key(&secp, &tweak_secret_key(&secp, &sk3, &contract[..]).unwrap());
367 assert_eq!(tweaked_pks[0], tweaked_pk1);
369 assert_eq!(tweaked_pks[1], tweaked_pk2);
370 assert_eq!(tweaked_pks[2], tweaked_pk3);
371 }
372
373 #[test]
374 fn tweak_fixed_vector() {
375 let secp = Secp256k1::new();
376
377 let pks = [
378 PublicKey::from_str("02ba604e6ad9d3864eda8dc41c62668514ef7d5417d3b6db46e45cc4533bff001c").unwrap(),
379 PublicKey::from_str("0365c0755ea55ce85d8a1900c68a524dbfd1c0db45ac3b3840dbb10071fe55e7a8").unwrap(),
380 PublicKey::from_str("0202313ca315889b2e69c94cf86901119321c7288139ba53ac022b7af3dc250054").unwrap(),
381 ];
382 let tweaked_pks = [
383 PublicKey::from_str("03b3597221b5982a3f1a77aed50f0015d1b6edfc69023ef7f25cfac0e8af1b2041").unwrap(),
384 PublicKey::from_str("0296ece1fd954f7ae94f8d6bad19fd6d583f5b36335cf13135a3053a22f3c1fb05").unwrap(),
385 PublicKey::from_str("0230bb1ca5dbc7fcf49294c2c3e582e5582eabf7c87e885735dc774da45d610e51").unwrap(),
386 ];
387 let contract = b"if bottle mt dont remembr drink wont pay";
388
389 assert_eq!(
391 tweak_keys(&secp, &pks, &contract[..]),
392 tweaked_pks
393 );
394 }
395
396 #[test]
397 fn bad_key_number() {
398 let secp = Secp256k1::new();
399 let alpha_keys = alpha_keys!(&secp);
400 let template_short = Template::from(&hex!("55fefefefefefe57AE")[..]);
401 let template_long = Template::from(&hex!("55fefefefefefefefe57AE")[..]);
402 let template = Template::from(&hex!("55fefefefefefefe57AE")[..]);
403
404 assert_eq!(template_short.required_keys(), 6);
405 assert_eq!(template_long.required_keys(), 8);
406 assert_eq!(template.required_keys(), 7);
407 assert_eq!(template_short.to_script(&secp, alpha_keys), Err(Error::TooManyKeys(7)));
408 assert_eq!(template_long.to_script(&secp, alpha_keys), Err(Error::TooFewKeys(7)));
409 assert!(template.to_script(&secp, alpha_keys).is_ok());
410 }
411}
412
413