confium_tc_frost_p256/
keys.rs1use crate::scalar;
4use p256::{
5 AffinePoint, ProjectivePoint, Scalar,
6 ecdsa::{SigningKey, VerifyingKey},
7 elliptic_curve::sec1::ToSec1Point,
8};
9
10#[derive(Debug, Clone)]
12pub struct Keypair {
13 pub secret_scalar: Scalar,
15 pub public_key: AffinePoint,
17}
18
19impl Keypair {
20 pub fn to_signing_key(&self) -> SigningKey {
22 let bytes = scalar::scalar_to_bytes(&self.secret_scalar);
23 SigningKey::from_bytes((&bytes).into()).expect("scalar is in valid range")
24 }
25
26 pub fn to_verifying_key(&self) -> VerifyingKey {
28 VerifyingKey::from_affine(self.public_key).expect("public key is valid")
29 }
30}
31
32pub fn generate_keypair() -> Keypair {
34 let secret = loop {
35 let s = scalar::random_scalar();
36 if s != Scalar::ZERO {
37 break s;
38 }
39 };
40 let public = public_key_for(&secret);
41 Keypair {
42 secret_scalar: secret,
43 public_key: public,
44 }
45}
46
47pub fn public_key_for(secret: &Scalar) -> AffinePoint {
49 let g = ProjectivePoint::GENERATOR;
50 let p = g * secret;
51 p.to_affine()
52}
53
54pub fn public_key_sec1(affine: &AffinePoint) -> Vec<u8> {
56 affine.to_sec1_point(false).as_bytes().to_vec()
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn keypair_generation_is_unique() {
65 let k1 = generate_keypair();
66 let k2 = generate_keypair();
67 assert_ne!(k1.secret_scalar, k2.secret_scalar);
68 assert_ne!(k1.public_key, k2.public_key);
69 }
70
71 #[test]
72 fn secret_to_public_is_deterministic() {
73 let k = generate_keypair();
74 let pk_again = public_key_for(&k.secret_scalar);
75 assert_eq!(pk_again, k.public_key);
76 }
77
78 #[test]
79 fn public_key_sec1_is_65_bytes_uncompressed() {
80 let k = generate_keypair();
81 let bytes = public_key_sec1(&k.public_key);
82 assert_eq!(bytes.len(), 65);
83 assert_eq!(bytes[0], 0x04);
84 }
85}