mina_signer/
lib.rs

1#![deny(missing_docs)]
2#![doc = include_str!("../README.md")]
3#![no_std]
4
5extern crate alloc;
6use alloc::{vec, vec::Vec};
7use ark_ec::AffineRepr;
8pub use keypair::Keypair;
9pub use mina_curves::pasta::Pallas as CurvePoint;
10use mina_hasher::{DomainParameter, Hashable};
11pub use pubkey::{CompressedPubKey, PubKey};
12pub use schnorr::Schnorr;
13pub use seckey::SecKey;
14pub use signature::Signature;
15
16pub mod keypair;
17pub mod pubkey;
18pub mod schnorr;
19pub mod seckey;
20pub mod signature;
21
22/// Base field element type
23pub type BaseField = <CurvePoint as AffineRepr>::BaseField;
24
25/// Scalar field element type
26pub type ScalarField = <CurvePoint as AffineRepr>::ScalarField;
27
28/// Mina network (or blockchain) identifier
29#[derive(Debug, Clone)]
30pub enum NetworkId {
31    /// Id for all testnets
32    TESTNET = 0x00,
33
34    /// Id for mainnet
35    MAINNET = 0x01,
36}
37
38impl From<NetworkId> for u8 {
39    fn from(id: NetworkId) -> u8 {
40        id as u8
41    }
42}
43
44impl DomainParameter for NetworkId {
45    fn into_bytes(self) -> Vec<u8> {
46        vec![self as u8]
47    }
48}
49
50/// Interface for signed objects
51///
52/// Signer interface for signing [`Hashable`] inputs and verifying
53/// [`Signatures`](Signature) using [`Keypairs`](Keypair) and
54/// [`PubKeys`](PubKey)
55pub trait Signer<H: Hashable> {
56    /// Sign `input` (see [`Hashable`]) using keypair `kp` and return the
57    /// corresponding signature.
58    ///
59    /// # Parameters
60    ///
61    /// * `kp` - The keypair to use for signing
62    /// * `input` - The message to sign (must implement [`Hashable`])
63    /// * `packed` - Controls nonce derivation method:
64    ///   - `true`: Use OCaml/TypeScript compatible nonce derivation with field
65    ///     packing
66    ///   - `false`: Use standard Rust nonce derivation
67    ///
68    /// # Returns
69    ///
70    /// A [`Signature`] over the input message.
71    ///
72    /// # Compatibility
73    ///
74    /// Use `packed: true` when compatibility with OCaml and TypeScript
75    /// implementations is required. Use `packed: false` for standard Rust-only
76    /// usage.
77    ///
78    /// **Note**: The standard nonce derivation (`packed: false`) will be
79    /// deprecated in future versions. Use `packed: true` for new code to ensure
80    /// forward compatibility.
81    fn sign(&mut self, kp: &Keypair, input: &H, packed: bool) -> Signature;
82
83    /// Verify that the signature `sig` on `input` (see [`Hashable`]) is signed
84    /// with the secret key corresponding to `pub_key`.
85    /// Return `true` if the signature is valid and `false` otherwise.
86    fn verify(&mut self, sig: &Signature, pub_key: &PubKey, input: &H) -> bool;
87}
88
89/// Create a legacy signer context with domain parameters initialized with
90/// `domain_param`
91///
92/// **Example**
93///
94/// ```
95/// #[path = "../tests/transaction.rs"]
96/// mod transaction;
97/// use mina_signer::{NetworkId, self, Signer};
98/// use transaction::Transaction;
99///
100/// let mut ctx = mina_signer::create_legacy::<Transaction>(NetworkId::TESTNET);
101/// ```
102pub fn create_legacy<H: 'static + Hashable>(domain_param: H::D) -> impl Signer<H> {
103    schnorr::create_legacy::<H>(domain_param)
104}
105
106/// Create an experimental kimchi signer context with domain parameters
107/// initialized with `domain_param`
108///
109/// **Example**
110///
111/// ```
112/// #[path = "../tests/transaction.rs"]
113/// mod transaction;
114/// use mina_signer::{NetworkId, self, Signer};
115/// use transaction::Transaction;
116///
117/// let mut ctx = mina_signer::create_kimchi::<Transaction>(NetworkId::TESTNET);
118/// ```
119pub fn create_kimchi<H: 'static + Hashable>(domain_param: H::D) -> impl Signer<H> {
120    schnorr::create_kimchi::<H>(domain_param)
121}