1pub mod evm;
8
9use std::{
10 borrow::Cow,
11 fmt,
12 hash::{Hash, Hasher},
13 str::FromStr,
14};
15
16use allocative::{Allocative, Visitor};
17use k256::{
18 ecdsa::{Signature, SigningKey, VerifyingKey},
19 elliptic_curve::sec1::FromEncodedPoint,
20 EncodedPoint,
21};
22use linera_witty::{
23 GuestPointer, HList, InstanceWithMemory, Layout, Memory, Runtime, RuntimeError, RuntimeMemory,
24 WitLoad, WitStore, WitType,
25};
26use serde::{Deserialize, Serialize};
27
28use super::{BcsHashable, BcsSignable, CryptoError, CryptoHash, HasTypeName};
29use crate::doc_scalar;
30
31const SECP256K1_SCHEME_LABEL: &str = "secp256k1";
33
34const SECP256K1_PUBLIC_KEY_SIZE: usize = 65;
36
37const SECP256K1_SIGNATURE_SIZE: usize = 64;
39
40#[derive(Eq, PartialEq)]
42pub struct Secp256k1SecretKey(pub SigningKey);
43
44#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
46pub struct Secp256k1PublicKey(pub VerifyingKey);
47
48impl Allocative for Secp256k1PublicKey {
49 fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
50 visitor.visit_simple_sized::<Self>();
51 }
52}
53
54impl Hash for Secp256k1PublicKey {
55 fn hash<H: Hasher>(&self, state: &mut H) {
56 self.as_bytes().hash(state);
57 }
58}
59
60#[derive(Debug, PartialEq, Eq)]
62pub struct Secp256k1KeyPair {
63 pub secret_key: Secp256k1SecretKey,
65 pub public_key: Secp256k1PublicKey,
67}
68
69#[derive(Eq, PartialEq, Copy, Clone)]
71pub struct Secp256k1Signature(pub Signature);
72
73impl Allocative for Secp256k1Signature {
74 fn visit<'a, 'b: 'a>(&self, visitor: &'a mut Visitor<'b>) {
75 visitor.visit_simple_sized::<Self>();
76 }
77}
78
79impl Secp256k1PublicKey {
80 #[cfg(all(with_testing, not(target_arch = "wasm32")))]
82 pub fn test_key(seed: u8) -> Self {
83 use rand::SeedableRng;
84 let mut rng = rand::rngs::StdRng::seed_from_u64(seed as u64);
85 let sk = k256::SecretKey::random(&mut rng);
86 Self(sk.public_key().into())
87 }
88
89 pub fn as_bytes(&self) -> [u8; SECP256K1_PUBLIC_KEY_SIZE] {
91 self.0
93 .to_encoded_point(false)
94 .as_bytes()
95 .try_into()
96 .unwrap()
97 }
98
99 pub fn from_bytes(bytes: &[u8]) -> Result<Self, CryptoError> {
104 let encoded_point =
105 EncodedPoint::from_bytes(bytes).map_err(|_| CryptoError::IncorrectPublicKeySize {
106 scheme: SECP256K1_SCHEME_LABEL,
107 len: bytes.len(),
108 expected: SECP256K1_PUBLIC_KEY_SIZE,
109 })?;
110
111 match k256::PublicKey::from_encoded_point(&encoded_point).into_option() {
112 Some(public_key) => Ok(Self(public_key.into())),
113 None => {
114 let error = CryptoError::Secp256k1PointAtInfinity(hex::encode(bytes));
115 Err(error)
116 }
117 }
118 }
119}
120
121impl fmt::Debug for Secp256k1SecretKey {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 write!(f, "<redacted for Secp256k1 secret key>")
124 }
125}
126
127impl Serialize for Secp256k1SecretKey {
128 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
129 where
130 S: serde::ser::Serializer,
131 {
132 assert!(serializer.is_human_readable());
134 serializer.serialize_str(&hex::encode(self.0.to_bytes()))
135 }
136}
137
138impl<'de> Deserialize<'de> for Secp256k1SecretKey {
139 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
140 where
141 D: serde::de::Deserializer<'de>,
142 {
143 assert!(deserializer.is_human_readable());
145 let str = String::deserialize(deserializer)?;
146 let bytes = hex::decode(&str).map_err(serde::de::Error::custom)?;
147 let sk = k256::ecdsa::SigningKey::from_slice(&bytes).map_err(serde::de::Error::custom)?;
148 Ok(Secp256k1SecretKey(sk))
149 }
150}
151
152impl Serialize for Secp256k1PublicKey {
153 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
154 where
155 S: serde::ser::Serializer,
156 {
157 if serializer.is_human_readable() {
158 serializer.serialize_str(&hex::encode(self.as_bytes()))
159 } else {
160 let compact_pk = serde_utils::UncompressedPublicKey(self.as_bytes());
161 serializer.serialize_newtype_struct("Secp256k1PublicKey", &compact_pk)
162 }
163 }
164}
165
166impl<'de> Deserialize<'de> for Secp256k1PublicKey {
167 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
168 where
169 D: serde::de::Deserializer<'de>,
170 {
171 if deserializer.is_human_readable() {
172 let s = String::deserialize(deserializer)?;
173 let value = hex::decode(s).map_err(serde::de::Error::custom)?;
174 Ok(Secp256k1PublicKey::from_bytes(&value).map_err(serde::de::Error::custom)?)
175 } else {
176 #[derive(Deserialize)]
177 #[serde(rename = "Secp256k1PublicKey")]
178 struct PublicKey(serde_utils::UncompressedPublicKey);
179 let compact = PublicKey::deserialize(deserializer)?;
180 Ok(Secp256k1PublicKey::from_bytes(&compact.0 .0).map_err(serde::de::Error::custom)?)
181 }
182 }
183}
184
185impl FromStr for Secp256k1PublicKey {
186 type Err = CryptoError;
187
188 fn from_str(s: &str) -> Result<Self, Self::Err> {
189 hex::decode(s)?.as_slice().try_into()
190 }
191}
192
193impl TryFrom<&[u8]> for Secp256k1PublicKey {
194 type Error = CryptoError;
195
196 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
197 Self::from_bytes(value)
198 }
199}
200
201impl fmt::Display for Secp256k1PublicKey {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 let str = hex::encode(self.as_bytes());
204 write!(f, "{str}")
205 }
206}
207
208impl fmt::Debug for Secp256k1PublicKey {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 write!(f, "{}..", hex::encode(&self.as_bytes()[0..9]))
211 }
212}
213
214impl BcsHashable<'_> for Secp256k1PublicKey {}
215
216impl WitType for Secp256k1PublicKey {
217 const SIZE: u32 = <(u64, u64, u64, u64, u64, u64, u64, u64, u8) as WitType>::SIZE;
218 type Layout = <(u64, u64, u64, u64, u64, u64, u64, u64, u8) as WitType>::Layout;
219 type Dependencies = HList![];
220
221 fn wit_type_name() -> Cow<'static, str> {
222 "secp256k1-public-key".into()
223 }
224
225 fn wit_type_declaration() -> Cow<'static, str> {
226 concat!(
227 " record secp256k1-public-key {\n",
228 " part1: u64,\n",
229 " part2: u64,\n",
230 " part3: u64,\n",
231 " part4: u64,\n",
232 " part5: u64,\n",
233 " part6: u64,\n",
234 " part7: u64,\n",
235 " part8: u64,\n",
236 " part9: u8\n",
237 " }\n",
238 )
239 .into()
240 }
241}
242
243impl WitLoad for Secp256k1PublicKey {
244 fn load<Instance>(
245 memory: &Memory<'_, Instance>,
246 location: GuestPointer,
247 ) -> Result<Self, RuntimeError>
248 where
249 Instance: InstanceWithMemory,
250 <Instance::Runtime as Runtime>::Memory: RuntimeMemory<Instance>,
251 {
252 let parts = WitLoad::load(memory, location)?;
253 Ok(Self::from_parts(parts))
254 }
255
256 fn lift_from<Instance>(
257 flat_layout: <Self::Layout as Layout>::Flat,
258 memory: &Memory<'_, Instance>,
259 ) -> Result<Self, RuntimeError>
260 where
261 Instance: InstanceWithMemory,
262 <Instance::Runtime as Runtime>::Memory: RuntimeMemory<Instance>,
263 {
264 let parts = WitLoad::lift_from(flat_layout, memory)?;
265 Ok(Self::from_parts(parts))
266 }
267}
268
269impl WitStore for Secp256k1PublicKey {
270 fn store<Instance>(
271 &self,
272 memory: &mut Memory<'_, Instance>,
273 location: GuestPointer,
274 ) -> Result<(), RuntimeError>
275 where
276 Instance: InstanceWithMemory,
277 <Instance::Runtime as Runtime>::Memory: RuntimeMemory<Instance>,
278 {
279 self.into_parts().store(memory, location)
280 }
281
282 fn lower<Instance>(
283 &self,
284 memory: &mut Memory<'_, Instance>,
285 ) -> Result<<Self::Layout as Layout>::Flat, RuntimeError>
286 where
287 Instance: InstanceWithMemory,
288 <Instance::Runtime as Runtime>::Memory: RuntimeMemory<Instance>,
289 {
290 self.into_parts().lower(memory)
291 }
292}
293
294type PublicKeyParts = (u64, u64, u64, u64, u64, u64, u64, u64, u8);
296
297impl Secp256k1PublicKey {
298 fn from_parts(parts: PublicKeyParts) -> Self {
299 let (part1, part2, part3, part4, part5, part6, part7, part8, part9) = parts;
300 let mut bytes = [0u8; SECP256K1_PUBLIC_KEY_SIZE];
301 bytes[0..8].copy_from_slice(&part1.to_be_bytes());
302 bytes[8..16].copy_from_slice(&part2.to_be_bytes());
303 bytes[16..24].copy_from_slice(&part3.to_be_bytes());
304 bytes[24..32].copy_from_slice(&part4.to_be_bytes());
305 bytes[32..40].copy_from_slice(&part5.to_be_bytes());
306 bytes[40..48].copy_from_slice(&part6.to_be_bytes());
307 bytes[48..56].copy_from_slice(&part7.to_be_bytes());
308 bytes[56..64].copy_from_slice(&part8.to_be_bytes());
309 bytes[64] = part9;
310 Self::from_bytes(&bytes).unwrap()
311 }
312
313 fn into_parts(self) -> PublicKeyParts {
314 let bytes = self.as_bytes();
315 let part1 = u64::from_be_bytes(bytes[0..8].try_into().unwrap());
316 let part2 = u64::from_be_bytes(bytes[8..16].try_into().unwrap());
317 let part3 = u64::from_be_bytes(bytes[16..24].try_into().unwrap());
318 let part4 = u64::from_be_bytes(bytes[24..32].try_into().unwrap());
319 let part5 = u64::from_be_bytes(bytes[32..40].try_into().unwrap());
320 let part6 = u64::from_be_bytes(bytes[40..48].try_into().unwrap());
321 let part7 = u64::from_be_bytes(bytes[48..56].try_into().unwrap());
322 let part8 = u64::from_be_bytes(bytes[56..64].try_into().unwrap());
323 let part9 = bytes[64];
324 (
325 part1, part2, part3, part4, part5, part6, part7, part8, part9,
326 )
327 }
328}
329
330impl Secp256k1KeyPair {
331 #[cfg(all(with_getrandom, with_testing))]
333 pub fn generate() -> Self {
334 let mut rng = rand::rngs::OsRng;
335 Self::generate_from(&mut rng)
336 }
337
338 #[cfg(with_getrandom)]
340 pub fn generate_from<R: super::CryptoRng>(rng: &mut R) -> Self {
341 let secret_key = Secp256k1SecretKey(SigningKey::random(rng));
342 let public_key = secret_key.public();
343 Secp256k1KeyPair {
344 secret_key,
345 public_key,
346 }
347 }
348}
349
350impl Secp256k1SecretKey {
351 pub fn public(&self) -> Secp256k1PublicKey {
353 Secp256k1PublicKey(*self.0.verifying_key())
354 }
355
356 pub fn copy(&self) -> Self {
361 Self(self.0.clone())
362 }
363
364 #[cfg(all(with_getrandom, with_testing))]
366 pub fn generate() -> Self {
367 let mut rng = rand::rngs::OsRng;
368 Self::generate_from(&mut rng)
369 }
370
371 #[cfg(with_getrandom)]
373 pub fn generate_from<R: super::CryptoRng>(rng: &mut R) -> Self {
374 Secp256k1SecretKey(SigningKey::random(rng))
375 }
376}
377
378impl Secp256k1Signature {
379 pub fn new<'de, T>(value: &T, secret: &Secp256k1SecretKey) -> Self
382 where
383 T: BcsSignable<'de>,
384 {
385 Self::sign_prehash(secret, CryptoHash::new(value))
386 }
387
388 pub fn sign_prehash(secret: &Secp256k1SecretKey, prehash: CryptoHash) -> Self {
390 use k256::ecdsa::signature::hazmat::PrehashSigner;
391
392 let (signature, _rid) = secret
393 .0
394 .sign_prehash(&prehash.as_bytes().0)
395 .expect("Failed to sign prehashed data"); Secp256k1Signature(signature)
397 }
398
399 pub fn check<'de, T>(&self, value: &T, author: Secp256k1PublicKey) -> Result<(), CryptoError>
401 where
402 T: BcsSignable<'de> + fmt::Debug,
403 {
404 let prehash = CryptoHash::new(value).as_bytes().0;
405 self.verify_inner::<T>(prehash, author)
406 }
407
408 pub fn verify_batch<'a, 'de, T, I>(value: &'a T, votes: I) -> Result<(), CryptoError>
412 where
413 T: BcsSignable<'de> + fmt::Debug,
414 I: IntoIterator<Item = &'a (Secp256k1PublicKey, Secp256k1Signature)>,
415 {
416 let prehash = CryptoHash::new(value).as_bytes().0;
417 for (author, signature) in votes {
418 signature.verify_inner::<T>(prehash, *author)?;
419 }
420 Ok(())
421 }
422
423 pub fn as_bytes(&self) -> [u8; SECP256K1_SIGNATURE_SIZE] {
425 self.0.to_bytes().into()
426 }
427
428 fn verify_inner<'de, T>(
429 &self,
430 prehash: [u8; 32],
431 author: Secp256k1PublicKey,
432 ) -> Result<(), CryptoError>
433 where
434 T: BcsSignable<'de> + fmt::Debug,
435 {
436 use k256::ecdsa::signature::hazmat::PrehashVerifier;
437
438 author
439 .0
440 .verify_prehash(&prehash, &self.0)
441 .map_err(|error| CryptoError::InvalidSignature {
442 error: error.to_string(),
443 type_name: T::type_name().to_string(),
444 })
445 }
446
447 pub fn from_slice<A: AsRef<[u8]>>(bytes: A) -> Result<Self, CryptoError> {
450 let sig = k256::ecdsa::Signature::from_slice(bytes.as_ref())
451 .map_err(CryptoError::Secp256k1Error)?;
452 Ok(Secp256k1Signature(sig))
453 }
454}
455
456impl Serialize for Secp256k1Signature {
457 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
458 where
459 S: serde::ser::Serializer,
460 {
461 if serializer.is_human_readable() {
462 serializer.serialize_str(&hex::encode(self.as_bytes()))
463 } else {
464 let compact = serde_utils::CompactSignature(self.as_bytes());
465 serializer.serialize_newtype_struct("Secp256k1Signature", &compact)
466 }
467 }
468}
469
470impl<'de> Deserialize<'de> for Secp256k1Signature {
471 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
472 where
473 D: serde::de::Deserializer<'de>,
474 {
475 if deserializer.is_human_readable() {
476 let s = String::deserialize(deserializer)?;
477 let value = hex::decode(s).map_err(serde::de::Error::custom)?;
478 Self::from_slice(&value).map_err(serde::de::Error::custom)
479 } else {
480 #[derive(Deserialize)]
481 #[serde(rename = "Secp256k1Signature")]
482 struct Signature(serde_utils::CompactSignature);
483
484 let value = Signature::deserialize(deserializer)?;
485 Self::from_slice(value.0 .0.as_ref()).map_err(serde::de::Error::custom)
486 }
487 }
488}
489
490impl fmt::Display for Secp256k1Signature {
491 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
492 let s = hex::encode(self.as_bytes());
493 write!(f, "{s}")
494 }
495}
496
497impl fmt::Debug for Secp256k1Signature {
498 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499 write!(f, "{}..", hex::encode(&self.as_bytes()[0..9]))
500 }
501}
502
503doc_scalar!(Secp256k1Signature, "A secp256k1 signature value");
504doc_scalar!(Secp256k1PublicKey, "A secp256k1 public key value");
505
506mod serde_utils {
507 use serde::{Deserialize, Serialize};
508 use serde_with::serde_as;
509
510 use super::{SECP256K1_PUBLIC_KEY_SIZE, SECP256K1_SIGNATURE_SIZE};
511
512 #[serde_as]
517 #[derive(Serialize, Deserialize)]
518 #[serde(transparent)]
519 pub struct CompactSignature(#[serde_as(as = "[_; 64]")] pub [u8; SECP256K1_SIGNATURE_SIZE]);
520
521 #[serde_as]
522 #[derive(Serialize, Deserialize)]
523 #[serde(transparent)]
524 pub struct UncompressedPublicKey(
525 #[serde_as(as = "[_; 65]")] pub [u8; SECP256K1_PUBLIC_KEY_SIZE],
526 );
527}
528
529#[cfg(with_testing)]
530mod tests {
531 #[test]
532 fn test_signatures() {
533 use serde::{Deserialize, Serialize};
534
535 use crate::crypto::{
536 secp256k1::{Secp256k1KeyPair, Secp256k1Signature},
537 BcsSignable, TestString,
538 };
539
540 #[derive(Debug, Serialize, Deserialize)]
541 struct Foo(String);
542
543 impl BcsSignable<'_> for Foo {}
544
545 let keypair1 = Secp256k1KeyPair::generate();
546 let keypair2 = Secp256k1KeyPair::generate();
547
548 let ts = TestString("hello".into());
549 let tsx = TestString("hellox".into());
550 let foo = Foo("hello".into());
551
552 let s = Secp256k1Signature::new(&ts, &keypair1.secret_key);
553 assert!(s.check(&ts, keypair1.public_key).is_ok());
554 assert!(s.check(&ts, keypair2.public_key).is_err());
555 assert!(s.check(&tsx, keypair1.public_key).is_err());
556 assert!(s.check(&foo, keypair1.public_key).is_err());
557 }
558
559 #[test]
560 fn test_public_key_serialization() {
561 use crate::crypto::secp256k1::Secp256k1PublicKey;
562 let key_in = Secp256k1PublicKey::test_key(0);
563 let s = serde_json::to_string(&key_in).unwrap();
564 let key_out: Secp256k1PublicKey = serde_json::from_str(&s).unwrap();
565 assert_eq!(key_out, key_in);
566
567 let s = bcs::to_bytes(&key_in).unwrap();
568 let key_out: Secp256k1PublicKey = bcs::from_bytes(&s).unwrap();
569 assert_eq!(key_out, key_in);
570 }
571
572 #[test]
573 fn test_secret_key_serialization() {
574 use crate::crypto::secp256k1::{Secp256k1KeyPair, Secp256k1SecretKey};
575 let key_in = Secp256k1KeyPair::generate().secret_key;
576 let s = serde_json::to_string(&key_in).unwrap();
577 let key_out: Secp256k1SecretKey = serde_json::from_str(&s).unwrap();
578 assert_eq!(key_out, key_in);
579 }
580
581 #[test]
582 fn test_signature_serialization() {
583 use crate::crypto::{
584 secp256k1::{Secp256k1KeyPair, Secp256k1Signature},
585 TestString,
586 };
587 let keypair = Secp256k1KeyPair::generate();
588 let sig = Secp256k1Signature::new(&TestString("hello".into()), &keypair.secret_key);
589 let s = serde_json::to_string(&sig).unwrap();
590 let sig2: Secp256k1Signature = serde_json::from_str(&s).unwrap();
591 assert_eq!(sig, sig2);
592
593 let s = bcs::to_bytes(&sig).unwrap();
594 let sig2: Secp256k1Signature = bcs::from_bytes(&s).unwrap();
595 assert_eq!(sig, sig2);
596 }
597
598 #[test]
599 fn public_key_from_str() {
600 use std::str::FromStr;
601
602 use crate::crypto::secp256k1::Secp256k1PublicKey;
603 let key = Secp256k1PublicKey::test_key(0);
604 let s = key.to_string();
605 let key2 = Secp256k1PublicKey::from_str(s.as_str()).unwrap();
606 assert_eq!(key, key2);
607 }
608
609 #[test]
610 fn bytes_repr_compact_public_key() {
611 use crate::crypto::secp256k1::{Secp256k1PublicKey, SECP256K1_PUBLIC_KEY_SIZE};
612 let key_in: Secp256k1PublicKey = Secp256k1PublicKey::test_key(0);
613 let bytes = key_in.as_bytes();
614 assert!(
615 bytes.len() == SECP256K1_PUBLIC_KEY_SIZE,
616 "::to_bytes() should return uncompressed representation"
617 );
618 let key_out = Secp256k1PublicKey::from_bytes(&bytes).unwrap();
619 assert_eq!(key_in, key_out);
620 }
621
622 #[test]
623 fn human_readable_ser() {
624 use crate::crypto::{
625 secp256k1::{Secp256k1KeyPair, Secp256k1Signature},
626 TestString,
627 };
628 let key_pair = Secp256k1KeyPair::generate();
629 let sig = Secp256k1Signature::new(&TestString("hello".into()), &key_pair.secret_key);
630 let s = serde_json::to_string(&sig).unwrap();
631 let sig2: Secp256k1Signature = serde_json::from_str(&s).unwrap();
632 assert_eq!(sig, sig2);
633 }
634}