secp256k1_test/
schnorr.rs1use ContextFlag;
19use Error;
20use Message;
21use Secp256k1;
22
23use constants;
24use ffi;
25use key::{SecretKey, PublicKey};
26
27use std::{mem, ptr};
28use std::convert::From;
29
30pub struct Signature([u8; constants::SCHNORR_SIGNATURE_SIZE]);
32impl_array_newtype!(Signature, u8, constants::SCHNORR_SIGNATURE_SIZE);
33impl_pretty_debug!(Signature);
34
35impl Signature {
36 pub fn deserialize(data: &[u8]) -> Signature {
38 assert_eq!(data.len(), constants::SCHNORR_SIGNATURE_SIZE);
39 let mut ret = [0; constants::SCHNORR_SIGNATURE_SIZE];
40 ret[..].copy_from_slice(data);
41 Signature(ret)
42 }
43
44 pub fn serialize(&self) -> Vec<u8> {
46 Vec::from(&self.0[..])
47 }
48}
49
50impl Secp256k1 {
51 pub fn sign_schnorr(&self, msg: &Message, sk: &SecretKey) -> Result<Signature, Error> {
53 if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None {
54 return Err(Error::IncapableContext);
55 }
56
57 let mut ret: Signature = unsafe { mem::uninitialized() };
58 unsafe {
59 let err = ffi::secp256k1_schnorr_sign(self.ctx, ret.as_mut_ptr(), msg.as_ptr(),
62 sk.as_ptr(), ffi::secp256k1_nonce_function_rfc6979,
63 ptr::null());
64 debug_assert_eq!(err, 1);
65 }
66 Ok(ret)
67 }
68
69 pub fn verify_schnorr(&self, msg: &Message, sig: &Signature, pk: &PublicKey) -> Result<(), Error> {
71 if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None {
72 return Err(Error::IncapableContext);
73 }
74
75 if !pk.is_valid() {
76 Err(Error::InvalidPublicKey)
77 } else if unsafe { ffi::secp256k1_schnorr_verify(self.ctx, sig.as_ptr(), msg.as_ptr(),
78 pk.as_ptr()) } == 0 {
79 Err(Error::IncorrectSignature)
80 } else {
81 Ok(())
82 }
83 }
84
85 pub fn recover_schnorr(&self, msg: &Message, sig: &Signature)
88 -> Result<PublicKey, Error> {
89 if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None {
90 return Err(Error::IncapableContext);
91 }
92
93 let mut pk = unsafe { ffi::PublicKey::blank() };
94 unsafe {
95 if ffi::secp256k1_schnorr_recover(self.ctx, &mut pk,
96 sig.as_ptr(), msg.as_ptr()) != 1 {
97 return Err(Error::InvalidSignature);
98 }
99 };
100 Ok(PublicKey::from(pk))
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use rand::{Rng, thread_rng};
107 use ContextFlag;
108 use Message;
109 use Secp256k1;
110 use Error::IncapableContext;
111 use super::Signature;
112
113 #[test]
114 fn capabilities() {
115 let none = Secp256k1::with_caps(ContextFlag::None);
116 let sign = Secp256k1::with_caps(ContextFlag::SignOnly);
117 let vrfy = Secp256k1::with_caps(ContextFlag::VerifyOnly);
118 let full = Secp256k1::with_caps(ContextFlag::Full);
119
120 let mut msg = [0u8; 32];
121 thread_rng().fill_bytes(&mut msg);
122 let msg = Message::from_slice(&msg).unwrap();
123
124 let (sk, pk) = full.generate_keypair(&mut thread_rng()).unwrap();
125
126 assert_eq!(none.sign_schnorr(&msg, &sk), Err(IncapableContext));
128 assert_eq!(vrfy.sign_schnorr(&msg, &sk), Err(IncapableContext));
129 assert!(sign.sign_schnorr(&msg, &sk).is_ok());
130 assert!(full.sign_schnorr(&msg, &sk).is_ok());
131 assert_eq!(sign.sign_schnorr(&msg, &sk), full.sign_schnorr(&msg, &sk));
132 let sig = full.sign_schnorr(&msg, &sk).unwrap();
133
134 assert_eq!(none.verify_schnorr(&msg, &sig, &pk), Err(IncapableContext));
136 assert_eq!(sign.verify_schnorr(&msg, &sig, &pk), Err(IncapableContext));
137 assert!(vrfy.verify_schnorr(&msg, &sig, &pk).is_ok());
138 assert!(full.verify_schnorr(&msg, &sig, &pk).is_ok());
139
140 assert_eq!(none.recover_schnorr(&msg, &sig), Err(IncapableContext));
142 assert_eq!(sign.recover_schnorr(&msg, &sig), Err(IncapableContext));
143 assert!(vrfy.recover_schnorr(&msg, &sig).is_ok());
144 assert!(full.recover_schnorr(&msg, &sig).is_ok());
145
146 assert_eq!(vrfy.recover_schnorr(&msg, &sig),
147 full.recover_schnorr(&msg, &sig));
148 assert_eq!(full.recover_schnorr(&msg, &sig), Ok(pk));
149 }
150
151 #[test]
152 fn sign_verify() {
153 let mut s = Secp256k1::new();
154 s.randomize(&mut thread_rng());
155
156 let mut msg = [0u8; 32];
157 thread_rng().fill_bytes(&mut msg);
158 let msg = Message::from_slice(&msg).unwrap();
159
160 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
161
162 let sig = s.sign_schnorr(&msg, &sk).unwrap();
163 assert!(s.verify_schnorr(&msg, &sig, &pk).is_ok());
164 }
165
166 #[test]
167 fn deserialize() {
168 let mut s = Secp256k1::new();
169 s.randomize(&mut thread_rng());
170
171 let mut msg = [0u8; 32];
172 thread_rng().fill_bytes(&mut msg);
173 let msg = Message::from_slice(&msg).unwrap();
174
175 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
176
177 let sig1 = s.sign_schnorr(&msg, &sk).unwrap();
178 let sig2 = Signature::deserialize(&sig1.serialize());
179 assert_eq!(sig1, sig2);
180 }
181}
182