Skip to main content

rune_ring/
keys.rs

1//! Key generation for Rune.
2
3use rand_core::{CryptoRng, RngCore};
4use zeroize::ZeroizeOnDrop;
5
6use crate::error::RuneError;
7use crate::math::{
8    poly_add, poly_is_well_formed, poly_mul_schoolbook, sample_cbd, sample_uniform_poly, Poly,
9    ZeroizingPoly,
10};
11use crate::params::Params;
12
13/// Rune public key.
14#[derive(Clone, Debug, PartialEq, Eq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub struct PublicKey {
17    /// Common public ring element shared by every member of a ring.
18    pub a: Poly,
19    /// Individual public value `t = a * s + e`.
20    pub t: Poly,
21}
22
23/// Rune secret key.
24#[derive(ZeroizeOnDrop)]
25pub struct SecretKey {
26    s: Poly,
27    e: Poly,
28    t: Poly,
29}
30
31impl SecretKey {
32    fn new(s: Poly, e: Poly, t: Poly) -> Self {
33        Self { s, e, t }
34    }
35
36    pub(crate) fn s(&self) -> &Poly {
37        &self.s
38    }
39
40    pub(crate) fn e(&self) -> &Poly {
41        &self.e
42    }
43
44    pub(crate) fn t(&self) -> &Poly {
45        &self.t
46    }
47}
48
49// Redact secret material; show only the public component t.
50impl std::fmt::Debug for SecretKey {
51    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52        f.debug_struct("SecretKey")
53            .field("s", &"[REDACTED]")
54            .field("e", &"[REDACTED]")
55            .field("t", &"<public>")
56            .finish()
57    }
58}
59
60/// Generates the common public ring element from a CSPRNG.
61pub fn generate_shared_a(params: &Params, rng: &mut (impl CryptoRng + RngCore)) -> Poly {
62    sample_uniform_poly(params, rng)
63}
64
65/// Generates a Rune keypair.
66///
67/// # Errors
68///
69/// Returns [`RuneError::MalformedPublicKey`] if `a` is not a canonical
70/// polynomial for `params`.
71pub fn keygen(
72    a: &Poly,
73    params: &Params,
74    rng: &mut (impl CryptoRng + RngCore),
75) -> Result<(PublicKey, SecretKey), RuneError> {
76    if !poly_is_well_formed(a, params) {
77        return Err(RuneError::MalformedPublicKey);
78    }
79
80    let s = ZeroizingPoly(sample_cbd(params, rng));
81    let e = ZeroizingPoly(sample_cbd(params, rng));
82    let t = poly_add(&poly_mul_schoolbook(a, &s.0, params), &e.0, params);
83
84    let pk = PublicKey {
85        a: a.clone(),
86        t: t.clone(),
87    };
88    let sk = SecretKey::new(s.0.clone(), e.0.clone(), t);
89
90    Ok((pk, sk))
91}