1use crate::ffi::{self, CPtr};
2use crate::{constants, from_hex, Error, Secp256k1, Signing, Tag};
3use core::{fmt, str};
4#[cfg(feature = "actual-rand")]
5use rand::Rng;
6
7#[derive(Default, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
12pub struct Tweak([u8; constants::SECRET_KEY_SIZE]);
13secp256k1_zkp_sys::impl_array_newtype!(Tweak, u8, constants::SECRET_KEY_SIZE);
14
15pub const ZERO_TWEAK: Tweak = Tweak([
17 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
18]);
19
20impl fmt::Debug for Tweak {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 write!(f, "Tweak(")?;
23 for i in self[..].iter() {
24 write!(f, "{:02x}", i)?;
25 }
26 write!(f, ")")
27 }
28}
29
30impl fmt::LowerHex for Tweak {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 for ch in &self.0[..] {
33 write!(f, "{:02x}", *ch)?;
34 }
35 Ok(())
36 }
37}
38
39impl fmt::Display for Tweak {
40 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41 fmt::LowerHex::fmt(self, f)
42 }
43}
44
45impl str::FromStr for Tweak {
46 type Err = Error;
47 fn from_str(s: &str) -> Result<Tweak, Error> {
48 let mut res = [0; constants::SECRET_KEY_SIZE];
49 match from_hex(s, &mut res) {
50 Ok(constants::SECRET_KEY_SIZE) => Tweak::from_inner(res),
51 _ => Err(Error::InvalidTweakLength),
52 }
53 }
54}
55
56impl Tweak {
57 #[cfg(feature = "actual-rand")]
59 pub fn new<R: Rng + ?Sized>(rng: &mut R) -> Tweak {
60 let mut ret = [0u8; constants::SECRET_KEY_SIZE];
61 rng.fill_bytes(&mut ret);
62 Tweak(ret)
63 }
64
65 #[inline]
68 pub fn from_slice(data: &[u8]) -> Result<Tweak, Error> {
69 match data.len() {
70 constants::SECRET_KEY_SIZE => {
71 let mut ret = [0; constants::SECRET_KEY_SIZE];
72 unsafe {
73 if ffi::secp256k1_ec_seckey_verify(
74 ffi::secp256k1_context_no_precomp,
75 data.as_ref().as_c_ptr(),
76 ) == 0
77 {
78 if data.iter().all(|x| *x == 0) {
79 return Ok(Tweak(ret));
80 }
81 return Err(Error::TweakOutOfBounds);
82 }
83 }
84 ret[..].copy_from_slice(data);
85 Ok(Tweak(ret))
86 }
87 _ => Err(Error::InvalidTweakLength),
88 }
89 }
90
91 #[inline]
93 pub fn from_inner(data: [u8; 32]) -> Result<Tweak, Error> {
94 unsafe {
95 if ffi::secp256k1_ec_seckey_verify(
96 ffi::secp256k1_context_no_precomp,
97 data.as_ref().as_c_ptr(),
98 ) == 0
99 {
100 if data.iter().all(|x| *x == 0) {
101 return Ok(Tweak(data));
102 }
103 return Err(Error::TweakOutOfBounds);
104 }
105 }
106 Ok(Tweak(data))
107 }
108}
109#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
113pub struct Generator(ffi::PublicKey);
114
115impl Generator {
116 pub fn serialize(&self) -> [u8; 33] {
118 let mut output = [0u8; 33];
119
120 let ret = unsafe {
121 ffi::secp256k1_generator_serialize(
122 ffi::secp256k1_context_no_precomp,
123 output.as_mut_ptr(),
124 &self.0,
125 )
126 };
127 assert_eq!(ret, 1);
129
130 output
131 }
132
133 pub fn from_slice(bytes: &[u8]) -> Result<Self, Error> {
135 let mut public_key = unsafe { ffi::PublicKey::new() };
136
137 let ret = unsafe {
138 ffi::secp256k1_generator_parse(
139 ffi::secp256k1_context_no_precomp,
140 &mut public_key,
141 bytes.as_ptr(),
142 )
143 };
144
145 if ret == 0 {
146 return Err(Error::InvalidGenerator);
147 }
148
149 Ok(Generator(public_key))
150 }
151
152 pub fn new_blinded<C: Signing>(secp: &Secp256k1<C>, tag: Tag, blinding_factor: Tweak) -> Self {
155 let mut generator = unsafe { ffi::PublicKey::new() };
156
157 let ret = unsafe {
158 ffi::secp256k1_generator_generate_blinded(
159 secp.ctx().as_ptr(),
160 &mut generator,
161 tag.into_inner().as_c_ptr(),
162 blinding_factor.as_c_ptr(),
163 )
164 };
165 assert_eq!(ret, 1);
166
167 Generator(generator)
168 }
169
170 pub fn new_unblinded<C: Signing>(secp: &Secp256k1<C>, tag: Tag) -> Self {
173 Generator::new_blinded(secp, tag, ZERO_TWEAK)
174 }
175
176 #[cfg(feature = "std")] pub(crate) fn as_inner(&self) -> &ffi::PublicKey {
182 &self.0
183 }
184}
185
186impl fmt::LowerHex for Generator {
187 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
188 let ser = self.serialize();
189 for ch in &ser[..] {
190 write!(f, "{:02x}", *ch)?;
191 }
192 Ok(())
193 }
194}
195
196impl fmt::Display for Generator {
197 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
198 fmt::LowerHex::fmt(self, f)
199 }
200}
201
202impl str::FromStr for Generator {
203 type Err = Error;
204 fn from_str(s: &str) -> Result<Self, Error> {
205 let mut res = [0; constants::PUBLIC_KEY_SIZE];
206 match from_hex(s, &mut res) {
207 Ok(constants::PUBLIC_KEY_SIZE) => Self::from_slice(&res[0..constants::PUBLIC_KEY_SIZE]),
208 _ => Err(Error::InvalidGenerator),
209 }
210 }
211}
212
213#[cfg(feature = "serde")]
214impl ::serde::Serialize for Generator {
215 fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
216 if s.is_human_readable() {
217 s.collect_str(self)
218 } else {
219 s.serialize_bytes(&self.serialize())
220 }
221 }
222}
223
224#[cfg(feature = "serde")]
225impl<'de> ::serde::Deserialize<'de> for Generator {
226 fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
227 use crate::serde_util;
228
229 if d.is_human_readable() {
230 d.deserialize_str(serde_util::FromStrVisitor::new("an ASCII hex string"))
231 } else {
232 d.deserialize_bytes(serde_util::BytesVisitor::new(
233 "a bytestring",
234 Generator::from_slice,
235 ))
236 }
237 }
238}
239
240#[cfg(feature = "serde")]
241impl ::serde::Serialize for Tweak {
242 fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
243 if s.is_human_readable() {
244 s.collect_str(self)
245 } else {
246 s.serialize_bytes(self.as_ref())
247 }
248 }
249}
250
251#[cfg(feature = "serde")]
252impl<'de> ::serde::Deserialize<'de> for Tweak {
253 fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
254 use crate::serde_util;
255
256 if d.is_human_readable() {
257 d.deserialize_str(serde_util::FromStrVisitor::new("an ASCII hex string"))
258 } else {
259 d.deserialize_bytes(serde_util::BytesVisitor::new(
260 "a bytestring",
261 Tweak::from_slice,
262 ))
263 }
264 }
265}
266
267#[cfg(test)]
268mod tests {
269 }