polysig_node_bindings/signers/
eddsa.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//! EdDSA signatures compatible with Solana.
use anyhow::Error;
use polysig_driver::signers::eddsa::{self, Signature};
use napi::JsError;
use napi_derive::napi;
use std::borrow::Cow;

/// Signer for EdDSA.
#[napi]
pub struct EddsaSigner {
    inner: eddsa::EddsaSigner<'static>,
}

#[napi]
impl EddsaSigner {
    /// Create a new signer.
    #[napi(constructor)]
    pub fn new(signing_key: Vec<u8>) -> Result<EddsaSigner, JsError> {
        let signing_key: [u8; 32] =
            signing_key.as_slice().try_into().map_err(Error::new)?;
        let signing_key =
            eddsa::EddsaSigner::from_bytes(&signing_key);
        Ok(Self {
            inner: eddsa::EddsaSigner::new(Cow::Owned(signing_key)),
        })
    }

    /// Generate a random signing key.
    #[napi]
    pub fn random() -> Vec<u8> {
        eddsa::EddsaSigner::random().to_bytes().as_slice().to_vec()
    }

    /// Sign a message.
    #[napi]
    pub fn sign(&self, message: Vec<u8>) -> Vec<u8> {
        let result = self.inner.sign(&message);
        result.to_bytes().as_slice().to_vec()
    }

    /// Verifying key for this signer.
    #[napi(js_name = "verifyingKey")]
    pub fn verifying_key(&self) -> Vec<u8> {
        self.inner.verifying_key().to_bytes().to_vec()
    }

    /// Verify a message.
    #[napi]
    pub fn verify(
        &self,
        message: Vec<u8>,
        signature: Vec<u8>,
    ) -> Result<(), JsError> {
        let signature: Signature =
            signature.as_slice().try_into().map_err(Error::new)?;
        Ok(self
            .inner
            .verify(&message, &signature)
            .map_err(Error::new)?)
    }
}