1use crate::ec::verification::Signature;
16use crate::elem::{
17 elem_reduced_to_scalar, elem_to_unencoded, scalar_add, scalar_inv_to_mont, scalar_mul,
18 scalar_sub, scalar_to_unencoded, Elem, Scalar, R,
19};
20use crate::err::KeyRejectedError;
21use crate::jacobian::exchange::affine_from_jacobian;
22use crate::key::private::create_private_key;
23use crate::key::public::PublicKey;
24use crate::limb::{LIMB_LENGTH, ONE};
25use crate::norop::parse_big_endian;
26use crate::rand::{DefaultRand, SecureRandom};
27use crate::sm2p256::{base_point_mul, scalar_to_mont};
28use core::marker::PhantomData;
29
30#[derive(Clone)]
31pub struct KeyPair {
32 d: Scalar<R>, pk: PublicKey,
34}
35
36impl KeyPair {
37 pub fn new(private_key: &[u8]) -> Result<Self, KeyRejectedError> {
38 let mut key_limb = [0; LIMB_LENGTH];
39 parse_big_endian(&mut key_limb, private_key)?;
40 let d = Scalar {
41 limbs: scalar_to_mont(&key_limb),
42 m: PhantomData,
43 };
44 let pk = PublicKey::public_from_private(&d)?;
45 Ok(KeyPair { d, pk })
46 }
47
48 pub fn public_key(&self) -> PublicKey {
49 self.pk
50 }
51
52 pub fn sign(&self, message: &[u8]) -> Result<Signature, KeyRejectedError> {
53 let ctx = libsm::sm2::signature::SigCtx::new();
54 let pk_point = ctx
55 .load_pubkey(self.pk.bytes_less_safe())
56 .map_err(|e| KeyRejectedError::LibSmError(format!("{e}")))?;
57 let digest = ctx
58 .hash("1234567812345678", &pk_point, message)
59 .map_err(|e| KeyRejectedError::LibSmError(format!("{e}")))?;
60
61 self.sign_digest(&mut DefaultRand(rand::thread_rng()), &digest)
62 }
63
64 pub fn sign_with_seed(
65 &self,
66 rng: &mut dyn SecureRandom,
67 message: &[u8],
68 ) -> Result<Signature, KeyRejectedError> {
69 let ctx = libsm::sm2::signature::SigCtx::new();
70 let pk_point = ctx
71 .load_pubkey(self.pk.bytes_less_safe())
72 .map_err(|e| KeyRejectedError::LibSmError(format!("{e}")))?;
73 let digest = ctx
74 .hash("1234567812345678", &pk_point, message)
75 .map_err(|e| KeyRejectedError::LibSmError(format!("{e}")))?;
76
77 self.sign_digest(rng, &digest)
78 }
79
80 pub fn sign_digest(
81 &self,
82 rng: &mut dyn SecureRandom,
83 digest: &[u8],
84 ) -> Result<Signature, KeyRejectedError> {
85 for _ in 0..100 {
86 #[allow(unused_variables)]
87 let rk = create_private_key(rng)?;
88
89 #[cfg(test)]
92 let rk = Scalar {
93 limbs: [
94 0xb9670787642a68de,
95 0x3b4a6247824f5d33,
96 0xa280f245f9e93c7f,
97 0x94a1bbb14b906a61,
98 ],
99 m: PhantomData,
100 };
101
102 let rq = base_point_mul(&rk.limbs);
103
104 let r = {
105 let (x, _) = affine_from_jacobian(&rq)?;
106 let x = elem_to_unencoded(&x);
107 elem_reduced_to_scalar(&x)
108 };
109 if r.is_zero() {
110 continue;
111 }
112
113 let mut dl = [0; LIMB_LENGTH];
114 parse_big_endian(&mut dl, digest)?;
115 let edl = Elem {
116 limbs: dl,
117 m: PhantomData,
118 };
119 let e = elem_reduced_to_scalar(&edl);
120
121 static SCALAR_ONE: Scalar = Scalar {
122 limbs: ONE,
123 m: PhantomData,
124 };
125
126 let r = scalar_add(&r, &e);
127
128 let da_ue = scalar_to_unencoded(&self.d);
129 let left = scalar_inv_to_mont(&scalar_add(&da_ue, &SCALAR_ONE));
130 let dr = scalar_mul(&self.d, &r);
131 let right = scalar_sub(&rk, &dr);
132 let s = scalar_mul(&left, &right);
133
134 #[cfg(test)]
137 {
138 assert_eq!(
139 r.limbs,
140 [
141 0x36bbb9347abf074f,
142 0x25b0f810baf864c4,
143 0x1b87443325f3afd4,
144 0xd6297b17c1cdf71a
145 ]
146 );
147 assert_eq!(
148 s.limbs,
149 [
150 0xb4075ea90353bfe1,
151 0xe827e9a226326c4e,
152 0xd768d0b8cf81bc40,
153 0xde7692f608e19f41
154 ]
155 );
156 }
157
158 return Ok(Signature::from_scalars(r, s));
159 }
160 Err(KeyRejectedError::SignDigestFailed)
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167
168 #[test]
169 fn sign_verify_test() {
170 let test_word = hex::decode("5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8").unwrap();
171 let private_key =
172 hex::decode("b8aa2a5bd9a9cf448984a247e63cb3878859d02b886e1bc63cd5c6dd46a744ab")
173 .unwrap();
174 let key_pair = KeyPair::new(&private_key).unwrap();
175
176 let sig = key_pair.sign(&test_word).unwrap();
177
178 println!(
179 "pk: {}, r: {}, s: {}",
180 hex::encode(key_pair.pk.bytes_less_safe()),
181 hex::encode(&sig.r()),
182 hex::encode(&sig.s())
183 );
184
185 sig.verify(&key_pair.public_key(), &test_word).unwrap()
186 }
187
188 #[test]
189 fn free_input_verify() {
190 let msg = b"hello world";
191
192 let pk = PublicKey::new(
193 &hex::decode("B0E4E03D589C97375BBD6EA49483DD976FB88BBB0C07C72827CD8808B5794D5E")
194 .unwrap(),
195 &hex::decode("2881721E8D9BF56E81FC1E0C325F4FFC052E67FC3A31510D66E7B8749B93B636")
196 .unwrap(),
197 );
198
199 let sig = Signature::new(
200 &hex::decode("45FACCE4BDE9B8A34D43E6060210928802878DDD86A6EAE2938313A165F9F100")
201 .unwrap(),
202 &hex::decode("D9656DA4EC90FB2EFA399C0ECC6301882CA3301925281C58C2E29D9FD6F9C221")
203 .unwrap(),
204 )
205 .unwrap();
206
207 assert!(sig.verify(&pk, msg).is_ok());
208
209 let pk = PublicKey::from_slice(
210 &hex::decode("B0E4E03D589C97375BBD6EA49483DD976FB88BBB0C07C72827CD8808B5794D5E2881721E8D9BF56E81FC1E0C325F4FFC052E67FC3A31510D66E7B8749B93B636")
211 .unwrap(),
212 );
213
214 assert!(sig.verify(&pk, msg).is_ok());
215
216 let sig = Signature::from_slice(
217 &hex::decode("45FACCE4BDE9B8A34D43E6060210928802878DDD86A6EAE2938313A165F9F100D9656DA4EC90FB2EFA399C0ECC6301882CA3301925281C58C2E29D9FD6F9C221")
218 .unwrap(),
219 ).unwrap();
220
221 assert!(sig.verify(&pk, msg).is_ok());
222 }
223}
224
225#[cfg(feature = "internal_benches")]
226mod sign_bench {
227 use super::*;
228 use rand::prelude::ThreadRng;
229 use rand::Rng;
230
231 extern crate test;
232
233 #[bench]
234 fn es_sign_bench(bench: &mut test::Bencher) {
235 pub struct EgRand(ThreadRng);
236
237 impl SecureRandom for EgRand {
238 fn fill(&mut self, dest: &mut [u8]) {
239 self.0.fill(dest)
240 }
241 }
242
243 let test_word = hex::decode("5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8").unwrap();
244 let mut rng = EgRand(rand::thread_rng());
245
246 let private_key =
247 hex::decode("b8aa2a5bd9a9cf448984a247e63cb3878859d02b886e1bc63cd5c6dd46a744ab")
248 .unwrap();
249
250 let key_pair = KeyPair::new(&private_key).unwrap();
251
252 bench.iter(|| {
253 let _ = key_pair.sign_with_seed(&mut rng, &test_word).unwrap();
254 });
255 }
256
257 #[bench]
258 fn libsm_sign_bench(bench: &mut test::Bencher) {
259 let test_word = b"hello world";
260 let ctx = libsm::sm2::signature::SigCtx::new();
261 let (pk, sk) = ctx.new_keypair().unwrap();
262
263 bench.iter(|| {
264 let _ = ctx.sign(test_word, &sk, &pk);
265 });
266 }
267
268 #[bench]
269 fn es_sign_without_sm3_bench(bench: &mut test::Bencher) {
270 pub struct EgRand(ThreadRng);
271
272 impl SecureRandom for EgRand {
273 fn fill(&mut self, dest: &mut [u8]) {
274 self.0.fill(dest)
275 }
276 }
277
278 let test_word = hex::decode("5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8").unwrap();
279 let mut rng = EgRand(rand::thread_rng());
280
281 let private_key =
282 hex::decode("b8aa2a5bd9a9cf448984a247e63cb3878859d02b886e1bc63cd5c6dd46a744ab")
283 .unwrap();
284 let key_pair = KeyPair::new(&private_key).unwrap();
285
286 let ctx = libsm::sm2::signature::SigCtx::new();
287 let pk_point = ctx
288 .load_pubkey(key_pair.pk.bytes_less_safe())
289 .map_err(|e| KeyRejectedError::LibSmError(format!("{e}")))
290 .unwrap();
291 let digest = ctx
292 .hash("1234567812345678", &pk_point, &test_word)
293 .map_err(|e| KeyRejectedError::LibSmError(format!("{e}")))
294 .unwrap();
295
296 bench.iter(|| {
297 let _ = key_pair.sign_digest(&mut rng, &digest).unwrap();
298 });
299 }
300
301 #[bench]
302 fn libsm_sign_without_sm3_bench(bench: &mut test::Bencher) {
303 let test_word = b"hello world";
304 let ctx = libsm::sm2::signature::SigCtx::new();
305 let (pk, sk) = ctx.new_keypair().unwrap();
306 let digest = ctx.hash("1234567812345678", &pk, test_word).unwrap();
307
308 bench.iter(|| {
309 let _ = ctx.sign_raw(&digest, &sk);
310 });
311 }
312
313 #[bench]
314 fn es_verify_bench(bench: &mut test::Bencher) {
315 pub struct EgRand(ThreadRng);
316
317 impl SecureRandom for EgRand {
318 fn fill(&mut self, dest: &mut [u8]) {
319 self.0.fill(dest)
320 }
321 }
322
323 let test_word = hex::decode("5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8").unwrap();
324 let mut rng = EgRand(rand::thread_rng());
325
326 let private_key =
327 hex::decode("b8aa2a5bd9a9cf448984a247e63cb3878859d02b886e1bc63cd5c6dd46a744ab")
328 .unwrap();
329 let key_pair = KeyPair::new(&private_key).unwrap();
330 let sig = key_pair.sign_with_seed(&mut rng, &test_word).unwrap();
331 let pk = key_pair.public_key();
332
333 bench.iter(|| {
334 let _ = sig.verify(&pk, &test_word).unwrap();
335 });
336 }
337
338 #[bench]
339 fn libsm_verify_bench(bench: &mut test::Bencher) {
340 let test_word = b"hello world";
341 let ctx = libsm::sm2::signature::SigCtx::new();
342 let (pk, sk) = ctx.new_keypair().unwrap();
343 let sig = ctx.sign(test_word, &sk, &pk).unwrap();
344
345 bench.iter(|| {
346 let _ = ctx.verify(test_word, &pk, &sig);
347 });
348 }
349}