schnorrkel/
keys.rs

1// -*- mode: rust; -*-
2//
3// This file is part of schnorrkel.
4// Copyright (c) 2019 isis lovecruft and Web 3 Foundation
5// See LICENSE for licensing information.
6//
7// Authors:
8// - isis agora lovecruft <isis@patternsinthevoid.net>
9// - Jeff Burdges <jeff@web3.foundation>
10
11//! ### Schnorr signatures on the 2-torsion free subgroup of ed25519, as provided by the Ristretto point compression.
12
13use core::convert::AsRef;
14use core::fmt::{Debug};
15
16use rand_core::{RngCore,CryptoRng};
17
18use curve25519_dalek::constants;
19use curve25519_dalek::ristretto::{CompressedRistretto,RistrettoPoint};
20use curve25519_dalek::scalar::Scalar;
21
22use subtle::{Choice,ConstantTimeEq};
23use zeroize::Zeroize;
24
25use crate::scalars;
26use crate::points::RistrettoBoth;
27use crate::errors::{SignatureError,SignatureResult};
28
29
30/// The length of a Ristretto Schnorr `MiniSecretKey`, in bytes.
31pub const MINI_SECRET_KEY_LENGTH: usize = 32;
32
33/// The length of a Ristretto Schnorr `PublicKey`, in bytes.
34pub const PUBLIC_KEY_LENGTH: usize = 32;
35
36/// The length of the "key" portion of a Ristretto Schnorr secret key, in bytes.
37const SECRET_KEY_KEY_LENGTH: usize = 32;
38
39/// The length of the "nonce" portion of a Ristretto Schnorr secret key, in bytes.
40const SECRET_KEY_NONCE_LENGTH: usize = 32;
41
42/// The length of a Ristretto Schnorr key, `SecretKey`, in bytes.
43pub const SECRET_KEY_LENGTH: usize = SECRET_KEY_KEY_LENGTH + SECRET_KEY_NONCE_LENGTH;
44
45/// The length of an Ristretto Schnorr `Keypair`, in bytes.
46pub const KEYPAIR_LENGTH: usize = SECRET_KEY_LENGTH + PUBLIC_KEY_LENGTH;
47
48
49/// Methods for expanding a `MiniSecretKey` into a `SecretKey`.
50///
51/// Our `SecretKey`s consist of a scalar and nonce seed, both 32 bytes,
52/// what EdDSA/Ed25519 calls an extended secret key.  We normally create
53/// `SecretKey`s by expanding a `MiniSecretKey`, what Esd25519 calls
54/// a `SecretKey`.  We provide two such methods, our suggested approach
55/// produces uniformly distribted secret key scalars, but another
56/// approach retains the bit clamping form Ed25519.
57pub enum ExpansionMode {
58    /// Expand the `MiniSecretKey` into a uniformly distributed
59    /// `SecretKey`.
60    ///
61    /// We produce the `SecretKey` using merlin and far more uniform
62    /// sampling, which might benefits some future protocols, and
63    /// might reduce binary size if used throughout.
64    ///
65    /// We slightly prefer this method, but some existing code uses
66    /// `Ed25519` mode, so users cannot necessarily use this mode
67    /// if they require compatability with existing systems.
68    Uniform,
69
70    /// Expand this `MiniSecretKey` into a `SecretKey` using
71    /// ed25519-style bit clamping.
72    ///
73    /// Ristretto points are represented by Ed25519 points internally
74    /// so conceivably some future standard might expose a mapping
75    /// from Ristretto to Ed25519, which makes this mode useful.
76    /// At present, there is no such exposed mapping however because
77    /// two such mappings actually exist, depending upon the branch of
78    /// the inverse square root chosen by a Ristretto implementation.
79    /// There is however a concern that such a mapping would remain
80    /// a second class citizen, meaning implementations differ and
81    /// create incompatibility.
82    ///
83    /// We weakly recommend against employing this method.  We include
84    /// it primarily because early Ristretto documentation touted the
85    /// relationship with Ed25519, which led to some deployments adopting
86    /// this expansion method.
87    Ed25519,
88}
89
90/// An EdDSA-like "secret" key seed.
91///
92/// These are seeds from which we produce a real `SecretKey`, which
93/// EdDSA itself calls an extended secret key by hashing.  We require
94/// homomorphic properties unavailable from these seeds, so we renamed
95/// these and reserve `SecretKey` for what EdDSA calls an extended
96/// secret key.
97#[derive(Clone,Zeroize)]
98#[zeroize(drop)]
99pub struct MiniSecretKey(pub (crate) [u8; MINI_SECRET_KEY_LENGTH]);
100
101impl Debug for MiniSecretKey {
102    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
103        write!(f, "MiniSecretKey: {:?}", &self.0[..])
104    }
105}
106
107impl Eq for MiniSecretKey {}
108impl PartialEq for MiniSecretKey {
109    fn eq(&self, other: &Self) -> bool {
110        self.ct_eq(other).unwrap_u8() == 1u8
111    }
112}
113impl ConstantTimeEq for MiniSecretKey {
114    fn ct_eq(&self, other: &Self) -> Choice {
115        self.0.ct_eq(&other.0)
116    }
117}
118
119impl MiniSecretKey {
120    const DESCRIPTION : &'static str = "Analogous to ed25519 secret key as 32 bytes, see RFC8032.";
121
122    /// Avoids importing `ExpansionMode`
123    pub const UNIFORM_MODE : ExpansionMode = ExpansionMode::Uniform;
124
125    /// Avoids importing `ExpansionMode`
126    pub const ED25519_MODE : ExpansionMode = ExpansionMode::Ed25519;
127
128    /// Expand this `MiniSecretKey` into a `SecretKey`
129    ///
130    /// We produce a secret keys using merlin and more uniformly
131    /// with this method, which reduces binary size and benefits
132    /// some future protocols.
133    ///
134    /// # Examples
135    ///
136    /// ```compile_fail
137    /// # fn main() {
138    /// use rand::{Rng, rngs::OsRng};
139    /// use schnorrkel::{MiniSecretKey, SecretKey};
140    ///
141    /// let mini_secret_key: MiniSecretKey = MiniSecretKey::generate_with(OsRng);
142    /// let secret_key: SecretKey = mini_secret_key.expand_uniform();
143    /// # }
144    /// ```
145    fn expand_uniform(&self) -> SecretKey {
146        let mut t = merlin::Transcript::new(b"ExpandSecretKeys");
147        t.append_message(b"mini", &self.0[..]);
148
149        let mut scalar_bytes = [0u8; 64];
150        t.challenge_bytes(b"sk", &mut scalar_bytes);
151        let key = Scalar::from_bytes_mod_order_wide(&scalar_bytes);
152
153        let mut nonce = [0u8; 32];
154        t.challenge_bytes(b"no", &mut nonce);
155
156        SecretKey { key, nonce }
157    }
158
159    /// Expand this `MiniSecretKey` into a `SecretKey` using
160    /// ed25519-style bit clamping.
161    ///
162    /// At present, there is no exposed mapping from Ristretto
163    /// to the underlying Edwards curve because Ristretto involves
164    /// an inverse square root, and thus two such mappings exist.
165    /// Ristretto could be made usable with Ed25519 keys by choosing
166    /// one mapping as standard, but doing so makes the standard more
167    /// complex, and possibly harder to implement.  If anyone does
168    /// standardize the mapping to the curve then this method permits
169    /// compatible schnorrkel and ed25519 keys.
170    ///
171    /// # Examples
172    ///
173    /// ```compile_fail
174    /// # #[cfg(feature = "getrandom")]
175    /// # fn main() {
176    /// use rand::{Rng, rngs::OsRng};
177    /// use schnorrkel::{MiniSecretKey, SecretKey};
178    ///
179    /// let mini_secret_key: MiniSecretKey = MiniSecretKey::generate_with(OsRng);
180    /// let secret_key: SecretKey = mini_secret_key.expand_ed25519();
181    /// # }
182    /// ```
183    fn expand_ed25519(&self) -> SecretKey {
184        use sha2::{Sha512, digest::{Update,FixedOutput}};
185
186        let mut h = Sha512::default();
187        h.update(self.as_bytes());
188        let r = h.finalize_fixed();
189
190        // We need not clamp in a Schnorr group like Ristretto, but here
191        // we do so to improve Ed25519 comparability.
192        let mut key = [0u8; 32];
193        key.copy_from_slice(&r.as_slice()[0..32]);
194        key[0]  &= 248;
195        key[31] &=  63;
196        key[31] |=  64;
197        // We then divide by the cofactor to internally keep a clean
198        // representation mod l.
199        scalars::divide_scalar_bytes_by_cofactor(&mut key);
200
201        #[allow(deprecated)] // Scalar's always reduced here, so this is OK.
202        let key = Scalar::from_bits(key);
203
204        let mut nonce = [0u8; 32];
205        nonce.copy_from_slice(&r.as_slice()[32..64]);
206
207        SecretKey{ key, nonce }
208    }
209
210    /// Derive the `SecretKey` corresponding to this `MiniSecretKey`.
211    ///
212    /// We caution that `mode` must always be chosen consistently.
213    /// We slightly prefer `ExpansionMode::Uniform` here, but both
214    /// remain secure under almost all situations.  There exists
215    /// deployed code using `ExpansionMode::Ed25519`, so you might
216    /// require that for compatability.
217    ///
218    /// ```
219    /// # fn main() {
220    /// use rand::{Rng, rngs::OsRng};
221    /// # #[cfg(feature = "getrandom")]
222    /// # {
223    /// use schnorrkel::{MiniSecretKey, SecretKey, ExpansionMode};
224    ///
225    /// let mini_secret_key: MiniSecretKey = MiniSecretKey::generate_with(OsRng);
226    /// let secret_key: SecretKey = mini_secret_key.expand(ExpansionMode::Uniform);
227    /// # }
228    /// # }
229    /// ```
230    pub fn expand(&self, mode: ExpansionMode) -> SecretKey {
231        match mode {
232            ExpansionMode::Uniform => self.expand_uniform(),
233            ExpansionMode::Ed25519 => self.expand_ed25519(),
234        }
235    }
236
237    /// Derive the `Keypair` corresponding to this `MiniSecretKey`.
238    pub fn expand_to_keypair(&self, mode: ExpansionMode) -> Keypair {
239        self.expand(mode).into()
240    }
241
242    /// Derive the `PublicKey` corresponding to this `MiniSecretKey`.
243    pub fn expand_to_public(&self, mode: ExpansionMode) -> PublicKey {
244        self.expand(mode).to_public()
245    }
246
247    /// Convert this secret key to a byte array.
248    #[inline]
249    pub fn to_bytes(&self) -> [u8; MINI_SECRET_KEY_LENGTH] {
250        self.0
251    }
252
253    /// View this secret key as a byte array.
254    #[inline]
255    pub fn as_bytes(&self) -> &[u8; MINI_SECRET_KEY_LENGTH] {
256        &self.0
257    }
258
259    /// Construct a `MiniSecretKey` from a slice of bytes.
260    ///
261    /// # Example
262    ///
263    /// ```
264    /// use schnorrkel::{MiniSecretKey, MINI_SECRET_KEY_LENGTH};
265    ///
266    /// let secret_key_bytes: [u8; MINI_SECRET_KEY_LENGTH] = [
267    ///    157, 097, 177, 157, 239, 253, 090, 096,
268    ///    186, 132, 074, 244, 146, 236, 044, 196,
269    ///    068, 073, 197, 105, 123, 050, 105, 025,
270    ///    112, 059, 172, 003, 028, 174, 127, 096, ];
271    ///
272    /// let secret_key: MiniSecretKey = MiniSecretKey::from_bytes(&secret_key_bytes).unwrap();
273    /// ```
274    ///
275    /// # Returns
276    ///
277    /// A `Result` whose okay value is an EdDSA `MiniSecretKey` or whose error value
278    /// is an `SignatureError` wrapping the internal error that occurred.
279    #[inline]
280    pub fn from_bytes(bytes: &[u8]) -> SignatureResult<MiniSecretKey> {
281        if bytes.len() != MINI_SECRET_KEY_LENGTH {
282            return Err(SignatureError::BytesLengthError {
283                name: "MiniSecretKey",
284                description: MiniSecretKey::DESCRIPTION,
285                length: MINI_SECRET_KEY_LENGTH
286            });
287        }
288        let mut bits: [u8; 32] = [0u8; 32];
289        bits.copy_from_slice(&bytes[..32]);
290        Ok(MiniSecretKey(bits))
291    }
292
293    /// Generate a `MiniSecretKey` from a `csprng`.
294    ///
295    /// # Example
296    ///
297    /// ```
298    /// use rand::{Rng, rngs::OsRng};
299    /// use schnorrkel::{PublicKey, MiniSecretKey, Signature};
300    ///
301    /// let secret_key: MiniSecretKey = MiniSecretKey::generate_with(OsRng);
302    /// ```
303    ///
304    /// # Input
305    ///
306    /// A CSPRNG with a `fill_bytes()` method, e.g. `rand_chacha::ChaChaRng`
307    pub fn generate_with<R>(mut csprng: R) -> MiniSecretKey
308    where R: CryptoRng + RngCore,
309    {
310        let mut sk: MiniSecretKey = MiniSecretKey([0u8; 32]);
311        csprng.fill_bytes(&mut sk.0);
312        sk
313    }
314
315    /// Generate a `MiniSecretKey` from rand's `thread_rng`.
316    ///
317    /// # Example
318    ///
319    /// ```
320    /// use schnorrkel::{PublicKey, MiniSecretKey, Signature};
321    ///
322    /// let secret_key: MiniSecretKey = MiniSecretKey::generate();
323    /// ```
324    ///
325    /// Afterwards, you can generate the corresponding public key.
326    ///
327    /// ```
328    /// # use rand::{Rng, SeedableRng};
329    /// # use rand_chacha::ChaChaRng;
330    /// # use schnorrkel::{PublicKey, MiniSecretKey, ExpansionMode, Signature};
331    /// #
332    /// # let mut csprng: ChaChaRng = ChaChaRng::from_seed([0u8; 32]);
333    /// # let secret_key: MiniSecretKey = MiniSecretKey::generate_with(&mut csprng);
334    ///
335    /// let public_key: PublicKey = secret_key.expand_to_public(ExpansionMode::Ed25519);
336    /// ```
337    #[cfg(feature = "getrandom")]
338    pub fn generate() -> MiniSecretKey {
339        Self::generate_with(super::getrandom_or_panic())
340    }
341}
342
343serde_boilerplate!(MiniSecretKey);
344
345
346/// A secret key for use with Ristretto Schnorr signatures.
347///
348/// Internally, these consist of a scalar mod l along with a seed for
349/// nonce generation.  In this way, we ensure all scalar arithmetic
350/// works smoothly in operations like threshold or multi-signatures,
351/// or hierarchical deterministic key derivations.
352///
353/// We keep our secret key serializaion "almost" compatable with EdDSA
354/// "expanded" secret key serializaion by multiplying the scalar by the
355/// cofactor 8, as integers, and dividing on deserializaion.
356/// We do not however attempt to keep the scalar's high bit set, especially
357/// not during hierarchical deterministic key derivations, so some Ed25519
358/// libraries might compute the public key incorrectly from our secret key.
359#[derive(Clone,Zeroize)]
360#[zeroize(drop)]
361pub struct SecretKey {
362    /// Actual public key represented as a scalar.
363    pub (crate) key: Scalar,
364    /// Seed for deriving the nonces used in signing.
365    ///
366    /// We require this be random and secret or else key compromise attacks will ensue.
367    /// Any modification here may disrupt some non-public key derivation techniques.
368    pub (crate) nonce: [u8; 32],
369}
370
371impl Debug for SecretKey {
372    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
373        write!(f, "SecretKey {{ key: {:?} nonce: {:?} }}", &self.key, &self.nonce)
374    }
375}
376
377impl Eq for SecretKey {}
378impl PartialEq for SecretKey {
379    fn eq(&self, other: &Self) -> bool {
380        self.ct_eq(other).unwrap_u8() == 1u8
381    }
382}
383impl ConstantTimeEq for SecretKey {
384    fn ct_eq(&self, other: &Self) -> Choice {
385        self.key.ct_eq(&other.key)
386    }
387}
388
389/*
390impl From<&MiniSecretKey> for SecretKey {
391    /// Construct an `SecretKey` from a `MiniSecretKey`.
392    ///
393    /// # Examples
394    ///
395    /// ```
396    /// # #[cfg(feature = "getrandom")
397    /// # fn main() {
398    /// use rand::{Rng, rngs::OsRng};
399    /// use schnorrkel::{MiniSecretKey, SecretKey};
400    ///
401    /// let mini_secret_key: MiniSecretKey = MiniSecretKey::generate_with(OsRng);
402    /// let secret_key: SecretKey = SecretKey::from(&mini_secret_key);
403    /// # }
404    /// ```
405    fn from(msk: &MiniSecretKey) -> SecretKey {
406        msk.expand(ExpansionMode::Ed25519)
407    }
408}
409*/
410
411impl SecretKey {
412    const DESCRIPTION : &'static str = "An ed25519-like expanded secret key as 64 bytes, as specified in RFC8032.";
413
414    /// Convert this `SecretKey` into an array of 64 bytes with.
415    ///
416    /// Returns an array of 64 bytes, with the first 32 bytes being
417    /// the secret scalar represented canonically, and the last
418    /// 32 bytes being the seed for nonces.
419    ///
420    /// # Examples
421    ///
422    /// ```
423    /// # #[cfg(feature = "getrandom")]
424    /// # {
425    /// use schnorrkel::{MiniSecretKey, SecretKey};
426    ///
427    /// let mini_secret_key: MiniSecretKey = MiniSecretKey::generate();
428    /// let secret_key: SecretKey = mini_secret_key.expand(MiniSecretKey::UNIFORM_MODE);
429    /// # // was SecretKey::from(&mini_secret_key);
430    /// let secret_key_bytes: [u8; 64] = secret_key.to_bytes();
431    /// let bytes: [u8; 64] = secret_key.to_bytes();
432    /// let secret_key_again: SecretKey = SecretKey::from_bytes(&bytes[..]).unwrap();
433    /// assert_eq!(&bytes[..], & secret_key_again.to_bytes()[..]);
434    /// # }
435    /// ```
436    #[inline]
437    pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
438        let mut bytes: [u8; 64] = [0u8; 64];
439        bytes[..32].copy_from_slice(&self.key.to_bytes()[..]);
440        bytes[32..].copy_from_slice(&self.nonce[..]);
441        bytes
442    }
443
444    /// Construct an `SecretKey` from a slice of bytes.
445    ///
446    /// # Examples
447    ///
448    /// ```
449    /// use schnorrkel::{MiniSecretKey, SecretKey, ExpansionMode, SignatureError};
450    ///
451    /// # #[cfg(feature = "getrandom")]
452    /// # {
453    /// let mini_secret_key: MiniSecretKey = MiniSecretKey::generate();
454    /// let secret_key: SecretKey = mini_secret_key.expand(MiniSecretKey::ED25519_MODE);
455    /// # // was SecretKey::from(&mini_secret_key);
456    /// let bytes: [u8; 64] = secret_key.to_bytes();
457    /// let secret_key_again: SecretKey = SecretKey::from_bytes(&bytes[..]).unwrap();
458    /// assert_eq!(secret_key_again, secret_key);
459    /// # }
460    /// ```
461    #[inline]
462    pub fn from_bytes(bytes: &[u8]) -> SignatureResult<SecretKey> {
463        if bytes.len() != SECRET_KEY_LENGTH {
464            return Err(SignatureError::BytesLengthError{
465                name: "SecretKey",
466                description: SecretKey::DESCRIPTION,
467                length: SECRET_KEY_LENGTH,
468            });
469        }
470
471        let mut key: [u8; 32] = [0u8; 32];
472        key.copy_from_slice(&bytes[00..32]);
473        let key = crate::scalar_from_canonical_bytes(key).ok_or(SignatureError::ScalarFormatError) ?;
474
475        let mut nonce: [u8; 32] = [0u8; 32];
476        nonce.copy_from_slice(&bytes[32..64]);
477
478        Ok(SecretKey{ key, nonce })
479    }
480
481    /// Convert this `SecretKey` into an array of 64 bytes, corresponding to
482    /// an Ed25519 expanded secret key.
483    ///
484    /// Returns an array of 64 bytes, with the first 32 bytes being
485    /// the secret scalar shifted ed25519 style, and the last 32 bytes
486    /// being the seed for nonces.
487    #[inline]
488    pub fn to_ed25519_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
489        let mut bytes: [u8; 64] = [0u8; 64];
490        let mut key = self.key.to_bytes();
491        // We multiply by the cofactor to improve ed25519 compatability,
492        // while our internally using a scalar mod l.
493        scalars::multiply_scalar_bytes_by_cofactor(&mut key);
494        bytes[..32].copy_from_slice(&key[..]);
495        bytes[32..].copy_from_slice(&self.nonce[..]);
496        bytes
497    }
498
499    /* Unused tooling removed to reduce dependencies. 
500    /// Convert this `SecretKey` into an Ed25519 expanded secret key.
501    #[cfg(feature = "ed25519_dalek")]
502    pub fn to_ed25519_expanded_secret_key(&self) -> ed25519_dalek::ExpandedSecretKey {
503        ed25519_dalek::ExpandedSecretKey::from_bytes(&self.to_ed25519_bytes()[..])
504        .expect("Improper serialisation of Ed25519 secret key!")
505    }
506    */
507
508    /// Construct an `SecretKey` from a slice of bytes, corresponding to
509    /// an Ed25519 expanded secret key.
510    ///
511    /// # Example
512    ///
513    /// ```
514    /// use schnorrkel::{SecretKey, SECRET_KEY_LENGTH};
515    /// use hex_literal::hex;
516    ///
517    /// let secret = hex!("28b0ae221c6bb06856b287f60d7ea0d98552ea5a16db16956849aa371db3eb51fd190cce74df356432b410bd64682309d6dedb27c76845daf388557cbac3ca34");
518    /// let public = hex!("46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a");
519    /// let secret_key = SecretKey::from_ed25519_bytes(&secret[..]).unwrap();
520    /// assert_eq!(secret_key.to_public().to_bytes(), public);
521    /// ```
522    #[inline]
523    pub fn from_ed25519_bytes(bytes: &[u8]) -> SignatureResult<SecretKey> {
524        if bytes.len() != SECRET_KEY_LENGTH {
525            return Err(SignatureError::BytesLengthError{
526                name: "SecretKey",
527                description: SecretKey::DESCRIPTION,
528                length: SECRET_KEY_LENGTH,
529            });
530        }
531
532        let mut key: [u8; 32] = [0u8; 32];
533        key.copy_from_slice(&bytes[00..32]);
534        // We divide by the cofactor to internally keep a clean
535        // representation mod l.
536        scalars::divide_scalar_bytes_by_cofactor(&mut key);
537
538        let key = Scalar::from_canonical_bytes(key);
539        if bool::from(key.is_none()) {
540            // This should never trigger for keys which come from `to_ed25519_bytes`.
541            return Err(SignatureError::InvalidKey);
542        }
543
544        let key = key.unwrap();
545        let mut nonce: [u8; 32] = [0u8; 32];
546        nonce.copy_from_slice(&bytes[32..64]);
547
548        Ok(SecretKey{ key, nonce })
549    }
550
551    /// Generate an "unbiased" `SecretKey` directly from a user
552    /// suplied `csprng` uniformly, bypassing the `MiniSecretKey`
553    /// layer.
554    pub fn generate_with<R>(mut csprng: R) -> SecretKey
555    where R: CryptoRng + RngCore,
556    {
557        let mut key: [u8; 64] = [0u8; 64];
558        csprng.fill_bytes(&mut key);
559        let mut nonce: [u8; 32] = [0u8; 32];
560        csprng.fill_bytes(&mut nonce);
561        SecretKey { key: Scalar::from_bytes_mod_order_wide(&key), nonce }
562    }
563
564    /// Generate an "unbiased" `SecretKey` directly,
565    /// bypassing the `MiniSecretKey` layer.
566    #[cfg(feature = "getrandom")]
567    pub fn generate() -> SecretKey {
568        Self::generate_with(super::getrandom_or_panic())
569    }
570
571    /// Derive the `PublicKey` corresponding to this `SecretKey`.
572    pub fn to_public(&self) -> PublicKey {
573        // No clamping necessary in the ristretto255 group
574        PublicKey::from_point(&self.key * constants::RISTRETTO_BASEPOINT_TABLE)
575    }
576
577    /// Derive the `PublicKey` corresponding to this `SecretKey`.
578    pub fn to_keypair(self) -> Keypair {
579        let public = self.to_public();
580        Keypair { secret: self, public }
581    }
582}
583
584serde_boilerplate!(SecretKey);
585
586
587/// A Ristretto Schnorr public key.
588///
589/// Internally, these are represented as a `RistrettoPoint`, meaning
590/// an Edwards point with a static guarantee to be 2-torsion free.
591///
592/// At present, we decompress `PublicKey`s into this representation
593/// during deserialization, which improves error handling, but costs
594/// a compression during signing and verification.
595#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
596pub struct PublicKey(pub (crate) RistrettoBoth);
597
598impl Debug for PublicKey {
599    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
600        write!(f, "PublicKey( {:?} )", self.0)
601    }
602}
603
604impl ConstantTimeEq for PublicKey {
605    fn ct_eq(&self, other: &PublicKey) -> Choice {
606        self.0.ct_eq(&other.0)
607    }
608}
609
610/*
611impl Zeroize for PublicKey {
612    fn zeroize(&mut self) {
613        self.0.zeroize()
614    }
615}
616*/
617
618// We should imho drop this impl but it benifits users who start with ring.
619impl AsRef<[u8]> for PublicKey {
620    fn as_ref(&self) -> &[u8] {
621        self.as_compressed().as_bytes()
622    }
623}
624
625impl PublicKey {
626    const DESCRIPTION : &'static str = "A Ristretto Schnorr public key represented as a 32-byte Ristretto compressed point";
627
628    /// Access the compressed Ristretto form
629    pub fn as_compressed(&self) -> &CompressedRistretto { self.0.as_compressed() }
630
631    /// Extract the compressed Ristretto form
632    pub fn into_compressed(self) -> CompressedRistretto { self.0.into_compressed() }
633
634    /// Access the point form
635    pub fn as_point(&self) -> &RistrettoPoint { self.0.as_point() }
636
637    /// Extract the point form
638    pub fn into_point(self) -> RistrettoPoint { self.0.into_point() }
639
640    /// Decompress into the `PublicKey` format that also retains the
641    /// compressed form.
642    pub fn from_compressed(compressed: CompressedRistretto) -> SignatureResult<PublicKey> {
643        Ok(PublicKey(RistrettoBoth::from_compressed(compressed) ?))
644    }
645
646    /// Compress into the `PublicKey` format that also retains the
647    /// uncompressed form.
648    pub fn from_point(point: RistrettoPoint) -> PublicKey {
649        PublicKey(RistrettoBoth::from_point(point))
650    }
651
652    /// Convert this public key to a byte array.
653    /// # Example
654    ///
655    /// ```
656    /// # #[cfg(feature = "getrandom")]
657    /// # {
658    /// use schnorrkel::{SecretKey, PublicKey, PUBLIC_KEY_LENGTH, SignatureError};
659    ///
660    /// let public_key: PublicKey = SecretKey::generate().to_public();
661    /// let public_key_bytes = public_key.to_bytes();
662    /// let public_key_again: PublicKey = PublicKey::from_bytes(&public_key_bytes[..]).unwrap();
663    /// assert_eq!(public_key_bytes, public_key_again.to_bytes());
664    /// # }
665    /// ```
666    #[inline]
667    pub fn to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH] {
668        self.as_compressed().to_bytes()
669    }
670
671    /// Construct a `PublicKey` from a slice of bytes.
672    ///
673    /// # Example
674    ///
675    /// ```
676    /// use schnorrkel::{PublicKey, PUBLIC_KEY_LENGTH, SignatureError};
677    ///
678    /// let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = [
679    ///     208, 120, 140, 129, 177, 179, 237, 159,
680    ///     252, 160, 028, 013, 206, 005, 211, 241,
681    ///     192, 218, 001, 097, 130, 241, 020, 169,
682    ///     119, 046, 246, 029, 079, 080, 077, 084];
683    ///
684    /// let public_key = PublicKey::from_bytes(&public_key_bytes).unwrap();
685    /// assert_eq!(public_key.to_bytes(), public_key_bytes);
686    /// ```
687    ///
688    /// # Returns
689    ///
690    /// A `Result` whose okay value is an EdDSA `PublicKey` or whose error value
691    /// is an `SignatureError` describing the error that occurred.
692    #[inline]
693    pub fn from_bytes(bytes: &[u8]) -> SignatureResult<PublicKey> {
694        Ok(PublicKey(RistrettoBoth::from_bytes_ser("PublicKey",PublicKey::DESCRIPTION,bytes) ?))
695    }
696}
697
698impl From<SecretKey> for PublicKey {
699    fn from(source: SecretKey) -> PublicKey {
700        source.to_public()
701    }
702}
703
704serde_boilerplate!(PublicKey);
705
706
707/// A Ristretto Schnorr keypair.
708#[derive(Clone,Debug)]
709// #[derive(Clone,Zeroize)]
710// #[zeroize(drop)]
711pub struct Keypair {
712    /// The secret half of this keypair.
713    pub secret: SecretKey,
714    /// The public half of this keypair.
715    pub public: PublicKey,
716}
717
718impl Zeroize for Keypair {
719    fn zeroize(&mut self) {
720        self.secret.zeroize();
721    }
722}
723impl Drop for Keypair {
724    fn drop(&mut self) {
725        self.zeroize();
726    }
727}
728
729impl From<SecretKey> for Keypair {
730    fn from(secret: SecretKey) -> Keypair {
731        let public = secret.to_public();
732        Keypair{ secret, public }
733    }
734}
735
736impl Keypair {
737    const DESCRIPTION : &'static str = "A 96 bytes Ristretto Schnorr keypair";
738    /*
739    const DESCRIPTION_LONG : &'static str =
740        "An ristretto schnorr keypair, 96 bytes in total, where the \
741        first 64 bytes contains the secret key represented as an \
742        ed25519 expanded secret key, as specified in RFC8032, and \
743        the subsequent 32 bytes gives the public key as a compressed \
744        ristretto point.";
745    */
746
747    /// Serialize `Keypair` to bytes.
748    ///
749    /// # Returns
750    ///
751    /// A byte array `[u8; KEYPAIR_LENGTH]` consisting of first a
752    /// `SecretKey` serialized canonically, and next the Ristterro
753    /// `PublicKey`
754    ///
755    /// # Examples
756    ///
757    /// ```
758    /// # #[cfg(feature = "getrandom")]
759    /// # {
760    /// use schnorrkel::{Keypair, KEYPAIR_LENGTH};
761    ///
762    /// let keypair: Keypair = Keypair::generate();
763    /// let bytes: [u8; KEYPAIR_LENGTH] = keypair.to_bytes();
764    /// let keypair_too = Keypair::from_bytes(&bytes[..]).unwrap();
765    /// assert_eq!(&bytes[..], & keypair_too.to_bytes()[..]);
766    /// # }
767    /// ```
768    pub fn to_bytes(&self) -> [u8; KEYPAIR_LENGTH] {
769        let mut bytes: [u8; KEYPAIR_LENGTH] = [0u8; KEYPAIR_LENGTH];
770
771        bytes[..SECRET_KEY_LENGTH].copy_from_slice(& self.secret.to_bytes());
772        bytes[SECRET_KEY_LENGTH..].copy_from_slice(& self.public.to_bytes());
773        bytes
774    }
775
776    /// Deserialize a `Keypair` from bytes.
777    ///
778    /// # Inputs
779    ///
780    /// * `bytes`: an `&[u8]` consisting of byte representations of
781    /// first a `SecretKey` and then the corresponding ristretto
782    /// `PublicKey`.
783    ///
784    /// # Examples
785    ///
786    /// ```
787    /// use schnorrkel::{Keypair, KEYPAIR_LENGTH};
788    /// use hex_literal::hex;
789    ///
790    /// // TODO: Fix test vector
791    /// // let keypair_bytes = hex!("28b0ae221c6bb06856b287f60d7ea0d98552ea5a16db16956849aa371db3eb51fd190cce74df356432b410bd64682309d6dedb27c76845daf388557cbac3ca3446ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a");
792    /// // let keypair: Keypair = Keypair::from_bytes(&keypair_bytes[..]).unwrap();
793    /// // assert_eq!(&keypair_bytes[..], & keypair.to_bytes()[..]);
794    /// ```
795    ///
796    /// # Returns
797    ///
798    /// A `Result` whose okay value is an EdDSA `Keypair` or whose error value
799    /// is an `SignatureError` describing the error that occurred.
800    pub fn from_bytes(bytes: &[u8]) -> SignatureResult<Keypair> {
801        if bytes.len() != KEYPAIR_LENGTH {
802            return Err(SignatureError::BytesLengthError {
803                name: "Keypair",
804                description: Keypair::DESCRIPTION,
805                length: KEYPAIR_LENGTH
806            });
807        }
808        let secret = SecretKey::from_bytes(&bytes[..SECRET_KEY_LENGTH]) ?;
809        let public = PublicKey::from_bytes(&bytes[SECRET_KEY_LENGTH..]) ?;
810
811        Ok(Keypair{ secret, public })
812    }
813
814    /// Serialize `Keypair` to bytes with Ed25519 secret key format.
815    ///
816    /// # Returns
817    ///
818    /// A byte array `[u8; KEYPAIR_LENGTH]` consisting of first a
819    /// `SecretKey` serialized like Ed25519, and next the Ristterro
820    /// `PublicKey`
821    ///
822    ///
823    pub fn to_half_ed25519_bytes(&self) -> [u8; KEYPAIR_LENGTH] {
824        let mut bytes: [u8; KEYPAIR_LENGTH] = [0u8; KEYPAIR_LENGTH];
825
826        bytes[..SECRET_KEY_LENGTH].copy_from_slice(& self.secret.to_ed25519_bytes());
827        bytes[SECRET_KEY_LENGTH..].copy_from_slice(& self.public.to_bytes());
828        bytes
829    }
830
831    /// Deserialize a `Keypair` from bytes with Ed25519 style `SecretKey` format.
832    ///
833    /// # Inputs
834    ///
835    /// * `bytes`: an `&[u8]` representing the scalar for the secret key, and a
836    ///   compressed Ristretto point, both as bytes.
837    ///
838    /// # Examples
839    ///
840    /// ```
841    /// use schnorrkel::{Keypair, KEYPAIR_LENGTH};
842    /// use hex_literal::hex;
843    ///
844    /// let keypair_bytes = hex!("28b0ae221c6bb06856b287f60d7ea0d98552ea5a16db16956849aa371db3eb51fd190cce74df356432b410bd64682309d6dedb27c76845daf388557cbac3ca3446ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a");
845    /// let keypair: Keypair = Keypair::from_half_ed25519_bytes(&keypair_bytes[..]).unwrap();
846    /// assert_eq!(&keypair_bytes[..], & keypair.to_half_ed25519_bytes()[..]);
847    /// ```
848    ///
849    /// # Returns
850    ///
851    /// A `Result` whose okay value is an EdDSA `Keypair` or whose error value
852    /// is an `SignatureError` describing the error that occurred.
853    pub fn from_half_ed25519_bytes(bytes: &[u8]) -> SignatureResult<Keypair> {
854        if bytes.len() != KEYPAIR_LENGTH {
855            return Err(SignatureError::BytesLengthError {
856                name: "Keypair",
857                description: Keypair::DESCRIPTION,
858                length: KEYPAIR_LENGTH
859            });
860        }
861        let secret = SecretKey::from_ed25519_bytes(&bytes[..SECRET_KEY_LENGTH]) ?;
862        let public = PublicKey::from_bytes(&bytes[SECRET_KEY_LENGTH..]) ?;
863
864        Ok(Keypair{ secret, public })
865    }
866
867    /// Generate a Ristretto Schnorr `Keypair` directly,
868    /// bypassing the `MiniSecretKey` layer.
869    ///
870    /// # Example
871    ///
872    /// ```
873    /// # fn main() {
874    ///
875    /// use rand::{Rng, rngs::OsRng};
876    /// # #[cfg(feature = "getrandom")]
877    /// use schnorrkel::Keypair;
878    /// use schnorrkel::Signature;
879    ///
880    /// # #[cfg(feature = "getrandom")]
881    /// let keypair: Keypair = Keypair::generate_with(OsRng);
882    ///
883    /// # }
884    /// ```
885    ///
886    /// # Input
887    ///
888    /// A CSPRNG with a `fill_bytes()` method, e.g. `rand_chacha::ChaChaRng`.
889    ///
890    /// We generate a `SecretKey` directly bypassing `MiniSecretKey`,
891    /// so our secret keys do not satisfy the high bit "clamping"
892    /// imposed on Ed25519 keys.
893    pub fn generate_with<R>(csprng: R) -> Keypair
894    where R: CryptoRng + RngCore,
895    {
896        let secret: SecretKey = SecretKey::generate_with(csprng);
897        let public: PublicKey = secret.to_public();
898
899        Keypair{ public, secret }
900    }
901
902    /// Generate a Ristretto Schnorr `Keypair` directly, from a user
903    /// suplied `csprng`, bypassing the `MiniSecretKey` layer.
904    #[cfg(feature = "getrandom")]
905    pub fn generate() -> Keypair {
906        Self::generate_with(super::getrandom_or_panic())
907    }
908}
909
910serde_boilerplate!(Keypair);
911
912
913#[cfg(test)]
914mod test {
915    // use std::vec::Vec;
916    use super::*;
917
918    /*
919    TODO: Use some Ristretto point to do this test correctly.
920    use curve25519_dalek::edwards::{CompressedEdwardsY};  // EdwardsPoint
921    #[test]
922    fn public_key_from_bytes() {
923        static ED25519_PUBLIC_KEY : CompressedEdwardsY = CompressedEdwardsY([
924            215, 090, 152, 001, 130, 177, 010, 183,
925            213, 075, 254, 211, 201, 100, 007, 058,
926            014, 225, 114, 243, 218, 166, 035, 037,
927            175, 002, 026, 104, 247, 007, 081, 026, ]);
928        let pk = ED25519_PUBLIC_KEY.decompress().unwrap();
929        // let pk = unsafe { std::mem::transmute::<EdwardsPoint,RistrettoPoint>(pk) };
930        let point = super::super::ed25519::edwards_to_ristretto(pk).unwrap();
931        let ristretto_public_key = PublicKey::from_point(point);
932
933        assert_eq!(
934            ristretto_public_key.to_ed25519_public_key_bytes(),
935            pk.mul_by_cofactor().compress().0
936        );
937
938        // Make another function so that we can test the ? operator.
939        fn do_the_test(s: &[u8]) -> Result<PublicKey, SignatureError> {
940            let public_key = PublicKey::from_bytes(s) ?;
941            Ok(public_key)
942        }
943        assert_eq!(
944            do_the_test(ristretto_public_key.as_ref()),
945            Ok(ristretto_public_key)
946        );
947        assert_eq!(
948            do_the_test(&ED25519_PUBLIC_KEY.0),  // Not a Ristretto public key
949            Err(SignatureError::PointDecompressionError)
950        );
951    }
952    */
953
954    #[test]
955    fn derives_from_core() {
956        let pk_d = PublicKey::default();
957        debug_assert_eq!(
958            pk_d.as_point().compress(),
959            CompressedRistretto::default()
960        );
961        debug_assert_eq!(
962            pk_d.as_compressed().decompress().unwrap(),
963            RistrettoPoint::default()
964        );
965    }
966
967    #[cfg(feature = "getrandom")]
968    #[test]
969    fn keypair_zeroize() {
970        let mut csprng = rand_core::OsRng;
971
972        let mut keypair = Keypair::generate_with(&mut csprng);
973
974        keypair.zeroize();
975
976        fn as_bytes<T>(x: &T) -> &[u8] {
977            use core::mem;
978            use core::slice;
979
980            unsafe {
981                slice::from_raw_parts(x as *const T as *const u8, mem::size_of_val(x))
982            }
983        }
984
985        assert!(!as_bytes(&keypair).iter().all(|x| *x == 0u8));
986    }
987
988    #[cfg(feature = "getrandom")]
989    #[test]
990    fn pubkey_from_mini_secret_and_expanded_secret() {
991        let mut csprng = rand_core::OsRng;
992
993        let mini_secret: MiniSecretKey = MiniSecretKey::generate_with(&mut csprng);
994        let secret: SecretKey = mini_secret.expand(ExpansionMode::Ed25519);
995        let public_from_mini_secret: PublicKey = mini_secret.expand_to_public(ExpansionMode::Ed25519);
996        let public_from_secret: PublicKey = secret.to_public();
997        assert!(public_from_mini_secret == public_from_secret);
998        let secret: SecretKey = mini_secret.expand(ExpansionMode::Uniform);
999        let public_from_mini_secret: PublicKey = mini_secret.expand_to_public(ExpansionMode::Uniform);
1000        let public_from_secret: PublicKey = secret.to_public();
1001        assert!(public_from_mini_secret == public_from_secret);
1002    }
1003
1004    #[cfg(feature = "getrandom")]
1005    #[test]
1006    fn secret_key_can_be_converted_to_ed25519_bytes_and_back() {
1007        let count = if cfg!(debug_assertions) {
1008            200000
1009        } else {
1010            2000000
1011        };
1012
1013        for _ in 0..count {
1014            let key = SecretKey::generate();
1015            let bytes = key.to_ed25519_bytes();
1016            let key_deserialized = SecretKey::from_ed25519_bytes(&bytes).unwrap();
1017            assert_eq!(key_deserialized, key);
1018        }
1019    }
1020}