secp256k1_zkp/zkp/
generator.rs

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/// Represents a blinding factor/Tweak on secp256k1 curve
8///
9/// Contrary to a [`crate::SecretKey`], the value 0 is also a valid tweak.
10/// Values outside secp curve order are invalid tweaks.
11#[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
15/// The zero Tweak
16pub 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    /// Generate a new random Tweak
58    #[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    /// Converts a byte slice to a Tweak
66    /// Fails if tweak is not 32 bytes or if tweak is outside secp curve order
67    #[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    /// Converts a `SECRET_KEY_SIZE`(32)- array to a tweak
92    #[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/// Represents a generator on the secp256k1 curve.
110///
111/// A generator is a public key internally but has a slightly different serialization with the first byte being tweaked.
112#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
113pub struct Generator(ffi::PublicKey);
114
115impl Generator {
116    /// Serialize the generator to a byte array.
117    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        // TODO: Replace most assert_eq with debug_assert_eq
128        assert_eq!(ret, 1);
129
130        output
131    }
132
133    /// Parse a generator from a slice of bytes.
134    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    /// Creates a new [`Generator`] by blinding a [`Tag`] using the given blinding factor.
153    /// Use [Generator::new_unblinded] for creating a [`Generator`] with zero blinding factor
154    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    /// Creates a new unblinded [`Generator`] by from [`Tag`]
171    /// Same as using zero [`Tweak`] with [`Generator::new_blinded`]
172    pub fn new_unblinded<C: Signing>(secp: &Secp256k1<C>, tag: Tag) -> Self {
173        Generator::new_blinded(secp, tag, ZERO_TWEAK)
174    }
175
176    /// Extracts the internal representation of this generator.
177    ///
178    /// This is `pub(crate)` because generators have a different serialization from regular public keys.
179    /// As such, certain invariants need to be upheld which is easier if we don't allow users to access the internal representation of generators.
180    #[cfg(feature = "std")] // for un-used warnings
181    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    // TODO: Test prefix of serialization
270}