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