1use secp256k1::{self, Secp256k1};
22use secp256k1::key::{PublicKey, SecretKey};
23use bitcoin_hashes::{hash160, sha256, Hash, HashEngine, Hmac, HmacEngine};
24use blockdata::{opcodes, script};
25
26use std::{error, fmt};
27
28use network::constants::Network;
29use util::address;
30
31static PUBKEY: u8 = 0xFE;
33
34#[derive(Debug, PartialEq, Eq, Clone)]
36pub enum Error {
37 BadTweak(secp256k1::Error),
40 Secp(secp256k1::Error),
42 Script(script::Error),
44 UncompressedKey,
48 ExpectedKey,
50 ExpectedChecksig,
53 TooFewKeys(usize),
55 TooManyKeys(usize)
57}
58
59impl fmt::Display for Error {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 match *self {
62 Error::BadTweak(ref e) |
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<&error::Error> {
76 match *self {
77 Error::BadTweak(ref e) |
78 Error::Secp(ref e) => Some(e),
79 Error::Script(ref e) => Some(e),
80 _ => None
81 }
82 }
83
84 fn description(&self) -> &'static str {
85 match *self {
86 Error::BadTweak(_) => "bad public key tweak",
87 Error::Secp(_) => "libsecp256k1 error",
88 Error::Script(_) => "script error",
89 Error::UncompressedKey => "encountered uncompressed secp public key",
90 Error::ExpectedKey => "expected key when deserializing script",
91 Error::ExpectedChecksig => "expected OP_*CHECKSIG* when deserializing script",
92 Error::TooFewKeys(_) => "too few keys for template",
93 Error::TooManyKeys(_) => "too many keys for template"
94 }
95 }
96}
97
98#[derive(Copy, Clone, PartialEq, Eq, Debug)]
100enum TemplateElement {
101 Op(opcodes::All),
102 Key
103}
104
105#[derive(Clone, PartialEq, Eq, Debug)]
107pub struct Template(Vec<TemplateElement>);
108
109impl Template {
110 pub fn to_script(&self, keys: &[PublicKey]) -> Result<script::Script, Error> {
112 let mut key_index = 0;
113 let mut ret = script::Builder::new();
114 for elem in &self.0 {
115 ret = match *elem {
116 TemplateElement::Op(opcode) => ret.push_opcode(opcode),
117 TemplateElement::Key => {
118 if key_index == keys.len() {
119 return Err(Error::TooFewKeys(key_index));
120 }
121 key_index += 1;
122 ret.push_slice(&keys[key_index - 1].serialize()[..])
123 }
124 }
125 }
126 if key_index == keys.len() {
127 Ok(ret.into_script())
128 } else {
129 Err(Error::TooManyKeys(keys.len()))
130 }
131 }
132
133 pub fn required_keys(&self) -> usize {
135 self.0.iter().filter(|e| **e == TemplateElement::Key).count()
136 }
137
138 pub fn first_push_as_number(&self) -> Option<usize> {
143 if !self.0.is_empty() {
144 if let TemplateElement::Op(op) = self.0[0] {
145 if let opcodes::Class::PushNum(n) = op.classify() {
146 if n >= 0 {
147 return Some(n as usize);
148 }
149 }
150 }
151 }
152 None
153 }
154}
155
156impl<'a> From<&'a [u8]> for Template {
157 fn from(slice: &'a [u8]) -> Template {
158 Template(slice.iter().map(|&byte| {
159 if byte == PUBKEY {
160 TemplateElement::Key
161 } else {
162 TemplateElement::Op(opcodes::All::from(byte))
163 }
164 }).collect())
165 }
166}
167
168pub fn tweak_keys<C: secp256k1::Verification>(secp: &Secp256k1<C>, keys: &[PublicKey], contract: &[u8]) -> Result<Vec<PublicKey>, Error> {
170 let mut ret = Vec::with_capacity(keys.len());
171 for mut key in keys.iter().cloned() {
172 let mut hmac_engine: HmacEngine<sha256::Hash> = HmacEngine::new(&key.serialize());
173 hmac_engine.input(contract);
174 let hmac_result: Hmac<sha256::Hash> = Hmac::from_engine(hmac_engine);
175 let hmac_sk = SecretKey::from_slice(&hmac_result[..]).map_err(Error::BadTweak)?;
176 key.add_exp_assign(secp, &hmac_sk[..]).map_err(Error::Secp)?;
177 ret.push(key);
178 }
179 Ok(ret)
180}
181
182pub fn compute_tweak(pk: &PublicKey, contract: &[u8]) -> Result<SecretKey, Error> {
184 let mut hmac_engine: HmacEngine<sha256::Hash> = HmacEngine::new(&pk.serialize());
185 hmac_engine.input(contract);
186 let hmac_result: Hmac<sha256::Hash> = Hmac::from_engine(hmac_engine);
187 SecretKey::from_slice(&hmac_result[..]).map_err(Error::BadTweak)
188}
189
190pub fn tweak_secret_key<C: secp256k1::Signing>(secp: &Secp256k1<C>, key: &SecretKey, contract: &[u8]) -> Result<SecretKey, Error> {
192 let pk = PublicKey::from_secret_key(secp, &key);
194 let hmac_sk = compute_tweak(&pk, contract)?;
196 let mut key = *key;
198 key.add_assign(&hmac_sk[..]).map_err(Error::Secp)?;
199 Ok(key)
201}
202
203pub fn create_address<C: secp256k1::Verification>(secp: &Secp256k1<C>,
205 network: Network,
206 contract: &[u8],
207 keys: &[PublicKey],
208 template: &Template)
209 -> Result<address::Address, Error> {
210 let keys = tweak_keys(secp, keys, contract)?;
211 let script = template.to_script(&keys)?;
212 Ok(address::Address {
213 network: network,
214 payload: address::Payload::ScriptHash(
215 hash160::Hash::hash(&script[..])
216 )
217 })
218}
219
220pub fn untemplate(script: &script::Script) -> Result<(Template, Vec<PublicKey>), Error> {
222 let mut ret = script::Builder::new();
223 let mut retkeys = vec![];
224
225 #[derive(Copy, Clone, PartialEq, Eq)]
226 enum Mode {
227 SeekingKeys,
228 CopyingKeys,
229 SeekingCheckMulti
230 }
231
232 let mut mode = Mode::SeekingKeys;
233 for instruction in script.iter(false) {
234 match instruction {
235 script::Instruction::PushBytes(data) => {
236 let n = data.len();
237 ret = match PublicKey::from_slice(data) {
238 Ok(key) => {
239 if n == 65 { return Err(Error::UncompressedKey); }
240 if mode == Mode::SeekingCheckMulti { return Err(Error::ExpectedChecksig); }
241 retkeys.push(key);
242 mode = Mode::CopyingKeys;
243 ret.push_opcode(opcodes::All::from(PUBKEY))
244 }
245 Err(_) => {
246 match mode {
249 Mode::SeekingKeys => { ret.push_slice(data) }
250 Mode::CopyingKeys => { return Err(Error::ExpectedKey); },
251 Mode::SeekingCheckMulti => { return Err(Error::ExpectedChecksig); }
252 }
253 }
254 }
255 }
256 script::Instruction::Op(op) => {
257 match op.classify() {
258 opcodes::Class::Ordinary(opcodes::Ordinary::OP_CHECKSIG) |
260 opcodes::Class::Ordinary(opcodes::Ordinary::OP_CHECKSIGVERIFY) => {
261 if mode == Mode::SeekingKeys { return Err(Error::ExpectedKey); }
262 mode = Mode::SeekingKeys;
263 }
264 opcodes::Class::Ordinary(opcodes::Ordinary::OP_CHECKMULTISIG) |
266 opcodes::Class::Ordinary(opcodes::Ordinary::OP_CHECKMULTISIGVERIFY) => {
267 if mode == Mode::SeekingKeys { return Err(Error::ExpectedKey); }
268 if mode == Mode::CopyingKeys { return Err(Error::ExpectedKey); }
269 mode = Mode::SeekingKeys;
270 }
271 opcodes::Class::PushNum(_) => {
273 if mode == Mode::SeekingCheckMulti { return Err(Error::ExpectedChecksig); }
274 if mode == Mode::CopyingKeys { mode = Mode::SeekingCheckMulti; }
275 }
276 _ => {}
278 }
279 ret = ret.push_opcode(op);
280 }
281 script::Instruction::Error(e) => { return Err(Error::Script(e)); }
282 }
283 }
284 Ok((Template::from(&ret[..]), retkeys))
285}
286
287#[cfg(test)]
288mod tests {
289 use secp256k1::Secp256k1;
290 use secp256k1::key::PublicKey;
291 use hex::decode as hex_decode;
292 use rand::thread_rng;
293
294 use blockdata::script::Script;
295 use network::constants::Network;
296
297 use super::*;
298
299 macro_rules! hex (($hex:expr) => (hex_decode($hex).unwrap()));
300 macro_rules! hex_key (($hex:expr) => (PublicKey::from_slice(&hex!($hex)).unwrap()));
301 macro_rules! alpha_template(() => (Template::from(&hex!("55fefefefefefefe57AE")[..])));
302 macro_rules! alpha_keys(() => (
303 &[hex_key!("0269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d933"),
304 hex_key!("021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a"),
305 hex_key!("02174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea1"),
306 hex_key!("033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a"),
307 hex_key!("0313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c2"),
308 hex_key!("030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab0"),
309 hex_key!("02fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce")]
310 ));
311
312 #[test]
313 fn sanity() {
314 let secp = Secp256k1::new();
315 let keys = alpha_keys!();
316 let contract = hex!("5032534894ffbf32c1f1c0d3089b27c98fd991d5d7329ebd7d711223e2cde5a9417a1fa3e852c576");
318
319 let addr = create_address(&secp, Network::Testnet, &contract, keys, &alpha_template!()).unwrap();
320 assert_eq!(addr.to_string(), "2N3zXjbwdTcPsJiy8sUK9FhWJhqQCxA8Jjr".to_owned());
321 }
322
323 #[test]
324 fn script() {
325 let alpha_keys = alpha_keys!();
326 let alpha_template = alpha_template!();
327
328 let alpha_redeem = Script::from(hex!("55210269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d93321021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a2102174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea121033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a210313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c221030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab02102fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce57ae"));
329 let (template, keys) = untemplate(&alpha_redeem).unwrap();
330
331 assert_eq!(keys, alpha_keys);
332 assert_eq!(template, alpha_template);
333 }
334
335 #[test]
336 fn tweak_secret() {
337 let secp = Secp256k1::new();
338 let (sk1, pk1) = secp.generate_keypair(&mut thread_rng());
339 let (sk2, pk2) = secp.generate_keypair(&mut thread_rng());
340 let (sk3, pk3) = secp.generate_keypair(&mut thread_rng());
341
342 let pks = [pk1, pk2, pk3];
343 let contract = b"if bottle mt dont remembr drink wont pay";
344
345 let tweaked_pks = tweak_keys(&secp, &pks, &contract[..]).unwrap();
347 let tweaked_pk1 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk1, &contract[..]).unwrap());
349 let tweaked_pk2 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk2, &contract[..]).unwrap());
350 let tweaked_pk3 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk3, &contract[..]).unwrap());
351 assert_eq!(tweaked_pks[0], tweaked_pk1);
353 assert_eq!(tweaked_pks[1], tweaked_pk2);
354 assert_eq!(tweaked_pks[2], tweaked_pk3);
355 }
356
357 #[test]
358 fn bad_key_number() {
359 let alpha_keys = alpha_keys!();
360 let template_short = Template::from(&hex!("55fefefefefefe57AE")[..]);
361 let template_long = Template::from(&hex!("55fefefefefefefefe57AE")[..]);
362 let template = Template::from(&hex!("55fefefefefefefe57AE")[..]);
363
364 assert_eq!(template_short.required_keys(), 6);
365 assert_eq!(template_long.required_keys(), 8);
366 assert_eq!(template.required_keys(), 7);
367 assert_eq!(template_short.to_script(alpha_keys), Err(Error::TooManyKeys(7)));
368 assert_eq!(template_long.to_script(alpha_keys), Err(Error::TooFewKeys(7)));
369 assert!(template.to_script(alpha_keys).is_ok());
370 }
371}
372
373