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}