oasis_runtime_sdk/crypto/signature/
secp256r1.rs1use base64::prelude::*;
3use digest::{consts::U32, core_api::BlockSizeUser, Digest, FixedOutput, FixedOutputReset};
4use k256::sha2::Sha512_256;
5use p256::{
6 self,
7 ecdsa::{
8 self,
9 signature::{DigestSigner as _, DigestVerifier, Signer as _, Verifier as _},
10 },
11};
12use rand_core::{CryptoRng, RngCore};
13
14use crate::crypto::signature::{Error, Signature};
15
16#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
18pub struct PublicKey(p256::EncodedPoint);
19
20impl PublicKey {
21 pub fn as_bytes(&self) -> &[u8] {
23 self.0.as_bytes()
24 }
25
26 pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
28 p256::EncodedPoint::from_bytes(bytes)
29 .map_err(|_| Error::MalformedPublicKey)
30 .map(PublicKey)
31 }
32
33 pub fn verify(
35 &self,
36 context: &[u8],
37 message: &[u8],
38 signature: &Signature,
39 ) -> Result<(), Error> {
40 let digest = Sha512_256::new()
41 .chain_update(context)
42 .chain_update(message);
43 self.verify_digest(digest, signature)
44 }
45
46 pub fn verify_raw(&self, message: &[u8], signature: &Signature) -> Result<(), Error> {
48 let sig = ecdsa::Signature::from_der(signature.0.as_ref())
49 .map_err(|_| Error::MalformedSignature)?;
50 let verify_key = ecdsa::VerifyingKey::from_encoded_point(&self.0)
51 .map_err(|_| Error::MalformedPublicKey)?;
52 verify_key
53 .verify(message, &sig)
54 .map_err(|_| Error::VerificationFailed)
55 }
56
57 pub fn verify_digest<D>(&self, digest: D, signature: &Signature) -> Result<(), Error>
59 where
60 D: Digest + FixedOutput<OutputSize = U32>,
61 {
62 let sig = ecdsa::Signature::from_der(signature.as_ref())
63 .map_err(|_| Error::MalformedSignature)?;
64 let verify_key = ecdsa::VerifyingKey::from_encoded_point(&self.0)
65 .map_err(|_| Error::MalformedPublicKey)?;
66 verify_key
67 .verify_digest(digest, &sig)
68 .map_err(|_| Error::VerificationFailed)
69 }
70}
71
72impl From<&'static str> for PublicKey {
73 fn from(s: &'static str) -> PublicKey {
74 PublicKey::from_bytes(&BASE64_STANDARD.decode(s).unwrap()).unwrap()
75 }
76}
77
78impl cbor::Encode for PublicKey {
79 fn into_cbor_value(self) -> cbor::Value {
80 cbor::Value::ByteString(self.as_bytes().to_vec())
81 }
82}
83
84impl cbor::Decode for PublicKey {
85 fn try_from_cbor_value(value: cbor::Value) -> Result<Self, cbor::DecodeError> {
86 match value {
87 cbor::Value::ByteString(data) => {
88 Self::from_bytes(&data).map_err(|_| cbor::DecodeError::UnexpectedType)
89 }
90 _ => Err(cbor::DecodeError::UnexpectedType),
91 }
92 }
93}
94
95pub struct MemorySigner {
97 sk: ecdsa::SigningKey,
98}
99
100impl MemorySigner {
101 pub fn sign_digest<D>(&self, digest: D) -> Result<Signature, Error>
102 where
103 D: Digest + FixedOutput<OutputSize = U32> + BlockSizeUser + FixedOutputReset,
104 {
105 let signature: ecdsa::Signature = self.sk.sign_digest(digest);
106 Ok(signature.to_der().as_bytes().to_vec().into())
107 }
108}
109
110impl super::Signer for MemorySigner {
111 fn random(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error> {
112 let mut seed = [0u8; 32];
113 rng.fill_bytes(&mut seed);
114 Self::new_from_seed(&seed)
115 }
116
117 fn new_from_seed(seed: &[u8]) -> Result<Self, Error> {
118 let sk = ecdsa::SigningKey::from_slice(seed).map_err(|_| Error::InvalidArgument)?;
119 Ok(Self { sk })
120 }
121
122 fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
123 Ok(Self {
124 sk: ecdsa::SigningKey::from_slice(bytes).map_err(|_| Error::MalformedPrivateKey)?,
125 })
126 }
127
128 fn to_bytes(&self) -> Vec<u8> {
129 self.sk.to_bytes().to_vec()
130 }
131
132 fn public_key(&self) -> super::PublicKey {
133 super::PublicKey::Secp256r1(PublicKey(self.sk.verifying_key().to_encoded_point(true)))
134 }
135
136 fn sign(&self, context: &[u8], message: &[u8]) -> Result<Signature, Error> {
137 let digest = sha2::Sha256::new()
138 .chain_update(context)
139 .chain_update(message);
140 let signature: ecdsa::Signature = self.sk.sign_digest(digest);
141 Ok(signature.to_der().as_bytes().to_vec().into())
142 }
143
144 fn sign_raw(&self, message: &[u8]) -> Result<Signature, Error> {
145 let signature: ecdsa::Signature = self.sk.sign(message);
146 Ok(signature.to_der().as_bytes().to_vec().into())
147 }
148}