1use crate::common::elgamal::Encoding as _;
2use anyhow::Result;
3
4#[derive(clap::Args, Debug)]
5pub struct ToolsArgs {
6 #[command(subcommand)]
7 command: Commands,
8}
9
10impl ToolsArgs {
11 pub fn run(self, _spec: &mut clap::Command) -> Result<()> {
12 match self.command {
13 Commands::Generate(args) => args.run(),
14 Commands::YiviEpoch(args) => args.run(),
15 }
16 }
17}
18
19#[derive(clap::Subcommand, Debug)]
20enum Commands {
21 Generate(generate::Args),
23
24 YiviEpoch(YiviEpochArgs),
26}
27
28#[derive(clap::Args, Debug)]
29struct YiviEpochArgs {
30 #[arg(long, value_name = "NUMBER", conflicts_with = "at")]
32 nr: Option<u64>,
33
34 #[arg(
36 long,
37 value_name = "TIMESTAMP",
38 value_parser = humantime::parse_rfc3339_weak,
39 conflicts_with = "nr"
40 )]
41 at: Option<std::time::SystemTime>,
42}
43
44impl YiviEpochArgs {
45 fn run(self) -> Result<()> {
46 let epoch = if let Some(nr) = self.nr {
47 crate::servers::yivi::Epoch::with_seqnr(nr)
48 } else if let Some(at) = self.at {
49 let nd: crate::api::NumericDate = at.into();
50 crate::servers::yivi::Epoch::from(nd)
51 } else {
52 crate::servers::yivi::Epoch::current()
53 };
54
55 print!("{}", epoch);
56
57 Ok(())
58 }
59}
60
61mod generate {
63 use super::*;
64
65 #[derive(clap::Args, Debug)]
66 pub(super) struct Args {
67 #[command(subcommand)]
68 command: Commands,
69 }
70
71 impl Args {
72 pub(super) fn run(self) -> Result<()> {
73 match self.command {
74 Commands::Id(args) => args.run(),
75 Commands::Scalar(args) => args.run(),
76 Commands::SigningKey(args) => args.run(),
77 }
78 }
79 }
80
81 #[derive(clap::Subcommand, Debug)]
82 enum Commands {
83 Id(IdArgs),
85
86 Scalar(ScalarArgs),
88
89 SigningKey(SigningKeyArgs),
91 }
92
93 #[derive(clap::Args, Debug)]
94 struct IdArgs {}
95
96 impl IdArgs {
97 fn run(self) -> Result<()> {
98 println!("{}", crate::id::Id::random());
99
100 Ok(())
101 }
102 }
103
104 #[derive(clap::Args, Debug)]
105 struct ScalarArgs {}
106
107 impl ScalarArgs {
108 fn run(self) -> Result<()> {
109 let pk = crate::common::elgamal::PrivateKey::random();
110
111 println!("x (private key): {}", pk.to_hex());
112 println!("xB (public key): {}", pk.public_key().to_hex());
113
114 Ok(())
115 }
116 }
117
118 #[derive(clap::Args, Debug)]
119
120 struct SigningKeyArgs {}
121
122 impl SigningKeyArgs {
123 fn run(self) -> Result<()> {
124 let sk = crate::api::SigningKey::generate();
125 let vk: crate::api::VerifyingKey = sk.verifying_key().into();
126
127 println!(" signing key: {sk}");
128 println!("verifying key: {vk}");
129
130 Ok(())
131 }
132 }
133}