1use super::{Error, Public, Secret, SECP256K1};
18use cfx_types::{BigEndianHash as _, H256, U256};
19use secp256k1::{
20 constants::{CURVE_ORDER, GENERATOR_X, GENERATOR_Y},
21 key,
22};
23
24pub fn public_is_valid(public: &Public) -> bool {
26 to_secp256k1_public(public)
27 .ok()
28 .map_or(false, |p| p.is_valid())
29}
30
31pub fn public_mul_secret(
33 public: &mut Public, secret: &Secret,
34) -> Result<(), Error> {
35 let key_secret = secret.to_secp256k1_secret()?;
36 let mut key_public = to_secp256k1_public(public)?;
37 key_public.mul_assign(&SECP256K1, &key_secret)?;
38 set_public(public, &key_public);
39 Ok(())
40}
41
42pub fn public_add(public: &mut Public, other: &Public) -> Result<(), Error> {
44 let mut key_public = to_secp256k1_public(public)?;
45 let other_public = to_secp256k1_public(other)?;
46 key_public.add_assign(&SECP256K1, &other_public)?;
47 set_public(public, &key_public);
48 Ok(())
49}
50
51pub fn public_sub(public: &mut Public, other: &Public) -> Result<(), Error> {
53 let mut key_neg_other = to_secp256k1_public(other)?;
54 key_neg_other.mul_assign(&SECP256K1, &key::MINUS_ONE_KEY)?;
55
56 let mut key_public = to_secp256k1_public(public)?;
57 key_public.add_assign(&SECP256K1, &key_neg_other)?;
58 set_public(public, &key_public);
59 Ok(())
60}
61
62pub fn public_negate(public: &mut Public) -> Result<(), Error> {
64 let mut key_public = to_secp256k1_public(public)?;
65 key_public.mul_assign(&SECP256K1, &key::MINUS_ONE_KEY)?;
66 set_public(public, &key_public);
67 Ok(())
68}
69
70pub fn generation_point() -> Public {
72 let mut public_sec_raw = [0u8; 65];
73 public_sec_raw[0] = 4;
74 public_sec_raw[1..33].copy_from_slice(&GENERATOR_X);
75 public_sec_raw[33..65].copy_from_slice(&GENERATOR_Y);
76
77 let public_key = key::PublicKey::from_slice(&SECP256K1, &public_sec_raw)
78 .expect("constructing using predefined constants; qed");
79 let mut public = Public::default();
80 set_public(&mut public, &public_key);
81 public
82}
83
84pub fn curve_order() -> U256 { H256::from_slice(&CURVE_ORDER).into_uint() }
86
87fn to_secp256k1_public(public: &Public) -> Result<key::PublicKey, Error> {
88 let public_data = {
89 let mut temp = [4u8; 65];
90 (&mut temp[1..65]).copy_from_slice(&public[0..64]);
91 temp
92 };
93
94 Ok(key::PublicKey::from_slice(&SECP256K1, &public_data)?)
95}
96
97fn set_public(public: &mut Public, key_public: &key::PublicKey) {
98 let key_public_serialized = key_public.serialize_vec(&SECP256K1, false);
99 public
100 .as_bytes_mut()
101 .copy_from_slice(&key_public_serialized[1..65]);
102}
103
104#[cfg(test)]
105mod tests {
106 use super::{
107 super::{KeyPairGenerator, Random},
108 public_add, public_sub,
109 };
110
111 #[test]
112 fn public_addition_is_commutative() {
113 let public1 = Random.generate().unwrap().public().clone();
114 let public2 = Random.generate().unwrap().public().clone();
115
116 let mut left = public1.clone();
117 public_add(&mut left, &public2).unwrap();
118
119 let mut right = public2.clone();
120 public_add(&mut right, &public1).unwrap();
121
122 assert_eq!(left, right);
123 }
124
125 #[test]
126 fn public_addition_is_reversible_with_subtraction() {
127 let public1 = Random.generate().unwrap().public().clone();
128 let public2 = Random.generate().unwrap().public().clone();
129
130 let mut sum = public1.clone();
131 public_add(&mut sum, &public2).unwrap();
132 public_sub(&mut sum, &public2).unwrap();
133
134 assert_eq!(sum, public1);
135 }
136}