fluence_keypair/
signature.rs

1/*
2 * Copyright 2020 Fluence Labs Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16use crate::ed25519;
17use crate::error::DecodingError;
18use crate::key_pair::KeyFormat;
19#[cfg(not(target_arch = "wasm32"))]
20use crate::rsa;
21use crate::secp256k1;
22use serde::{Deserialize, Serialize};
23use std::convert::TryFrom;
24
25#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
26pub enum Signature {
27    Ed25519(ed25519::Signature),
28    #[cfg(not(target_arch = "wasm32"))]
29    Rsa(rsa::Signature),
30    Secp256k1(secp256k1::Signature),
31}
32
33pub struct RawSignature {
34    pub bytes: Vec<u8>,
35    pub sig_type: KeyFormat,
36}
37
38impl Signature {
39    fn get_prefix(&self) -> u8 {
40        use Signature::*;
41        match self {
42            Ed25519(_) => KeyFormat::Ed25519.into(),
43            #[cfg(not(target_arch = "wasm32"))]
44            Rsa(_) => KeyFormat::Rsa.into(),
45            Secp256k1(_) => KeyFormat::Secp256k1.into(),
46        }
47    }
48
49    /// encode keypair type in first byte and signature as byte array
50    pub fn encode(&self) -> Vec<u8> {
51        use Signature::*;
52
53        let mut result: Vec<u8> = vec![self.get_prefix()];
54
55        match self {
56            Ed25519(sig) => result.extend(sig.0.clone()),
57            #[cfg(not(target_arch = "wasm32"))]
58            Rsa(sig) => result.extend(sig.0.clone()),
59            Secp256k1(sig) => result.extend(sig.0.clone()),
60        }
61
62        result
63    }
64
65    /// decode with first byte set as keypair type
66    pub fn decode(bytes: Vec<u8>) -> Result<Self, DecodingError> {
67        match KeyFormat::try_from(bytes[0])? {
68            KeyFormat::Ed25519 => Ok(Signature::Ed25519(ed25519::Signature(bytes[1..].to_vec()))),
69            #[cfg(not(target_arch = "wasm32"))]
70            KeyFormat::Rsa => Ok(Signature::Rsa(rsa::Signature(bytes[1..].to_vec()))),
71            KeyFormat::Secp256k1 => Ok(Signature::Secp256k1(secp256k1::Signature(
72                bytes[1..].to_vec(),
73            ))),
74        }
75    }
76
77    pub fn to_vec(&self) -> &[u8] {
78        use Signature::*;
79
80        match self {
81            Ed25519(sig) => &sig.0,
82            #[cfg(not(target_arch = "wasm32"))]
83            Rsa(sig) => &sig.0,
84            Secp256k1(sig) => &sig.0,
85        }
86    }
87
88    pub fn get_signature_type(&self) -> KeyFormat {
89        use Signature::*;
90
91        match self {
92            Ed25519(_) => KeyFormat::Ed25519,
93            #[cfg(not(target_arch = "wasm32"))]
94            Rsa(_) => KeyFormat::Rsa,
95            Secp256k1(_) => KeyFormat::Secp256k1,
96        }
97    }
98
99    pub fn get_raw_signature(&self) -> RawSignature {
100        RawSignature {
101            bytes: self.to_vec().to_vec(),
102            sig_type: self.get_signature_type(),
103        }
104    }
105
106    pub fn from_bytes(key_format: KeyFormat, bytes: Vec<u8>) -> Self {
107        match key_format {
108            KeyFormat::Ed25519 => Signature::Ed25519(ed25519::Signature(bytes)),
109            #[cfg(not(target_arch = "wasm32"))]
110            KeyFormat::Rsa => Signature::Rsa(rsa::Signature(bytes)),
111            KeyFormat::Secp256k1 => Signature::Secp256k1(secp256k1::Signature(bytes)),
112        }
113    }
114}
115
116#[cfg(test)]
117mod tests {
118    use crate::*;
119
120    #[test]
121    fn signature_encode_decode() {
122        let bytes: Vec<u8> = (0..10).collect();
123        let ed25519_sig = Signature::Ed25519(crate::ed25519::Signature(bytes.clone()));
124        let secp256k1_sig = Signature::Secp256k1(crate::secp256k1::Signature(bytes.clone()));
125        #[cfg(not(target_arch = "wasm32"))]
126        let rsa_sig = Signature::Rsa(crate::rsa::Signature(bytes.clone()));
127
128        assert_eq!(
129            Signature::decode(ed25519_sig.encode()).unwrap(),
130            ed25519_sig
131        );
132        assert_eq!(
133            Signature::decode(secp256k1_sig.encode()).unwrap(),
134            secp256k1_sig
135        );
136        #[cfg(not(target_arch = "wasm32"))]
137        assert_eq!(Signature::decode(rsa_sig.encode()).unwrap(), rsa_sig);
138    }
139}