1 unstable release
new 0.1.0 | Mar 14, 2025 |
---|
#486 in Magic Beans
24KB
371 lines
Solana Secp256k1 ECDSA
A no_std
compatible ECDSA implementation for the Secp256k1 curve, designed for use within the Solana ecosystem.
Overview
This library provides a lightweight implementation of ECDSA signatures using the Secp256k1 curve. It's designed to be compatible with no_std
environments, making it suitable for embedded systems, WebAssembly modules, and other constrained environments without standard library support.
Features
- no_std compatible: Works in environments without the Rust standard library
- Signature creation: Generate ECDSA signatures with various methods:
- RFC6979 deterministic nonce generation
- Custom ephemeral key (k) support
- Pre-hashed message support
- Signature verification: Verify ECDSA signatures against public keys
- Signature normalization: Handles signature malleability with optional s-value normalization (low-S)
- Minimal dependencies: Built on top of
solana_secp256k1
primitives
Usage
Add this to your Cargo.toml
:
[dependencies]
solana-secp256k1-ecdsa = "0.1.0"
Creating Signatures
Enable the sign
feature flag to use signature creation functionality:
[dependencies]
solana-secp256k1-ecdsa = { version = "0.1.0", features = ["sign"] }
Basic Signing
use solana_secp256k1_ecdsa::{Secp256k1EcdsaSignature, hash::Sha256};
// Your message and private key
let message = b"Hello, Solana!";
let private_key: [u8; 32] = [/* your private key */];
// Sign the message
let signature = Secp256k1EcdsaSignature::sign::<Sha256>(message, &private_key)?;
Signing with a Custom Ephemeral Key
use solana_secp256k1_ecdsa::{Secp256k1EcdsaSignature, hash::Sha256};
// Your message, ephemeral key, and private key
let message = b"Hello, Solana!";
let ephemeral_key: [u8; 32] = [/* your ephemeral key */];
let private_key: [u8; 32] = [/* your private key */];
// Sign with custom k
let signature = Secp256k1EcdsaSignature::sign_with_k::<Sha256>(
message,
&ephemeral_key,
&private_key
)?;
Verifying Signatures
use solana_secp256k1_ecdsa::{Secp256k1EcdsaSignature, hash::Sha256};
use solana_secp256k1::Pubkey;
// Your message, signature, and public key
let message = b"Hello, Solana!";
let signature: Secp256k1EcdsaSignature = /* your signature */;
let public_key: Pubkey = /* your public key */;
// Verify the signature
signature.verify::<Sha256, _>(message, public_key)?;
Security Notes
- When using
sign_with_k
, ensure your ephemeral key is truly random and never reused. Reusing or using predictable ephemeral keys can compromise your private key. - The library provides
normalize_s
to handle signature malleability concerns. This is important for blockchain applications where transaction malleability could be an issue.
Hash Implementations
Implement the Secp256k1EcdsaHash
trait for custom hash algorithms:
use solana_secp256k1_ecdsa::hash::Secp256k1EcdsaHash;
struct MyCustomHash;
impl Secp256k1EcdsaHash for MyCustomHash {
fn hash(message: &[u8]) -> [u8; 32] {
// Your custom hash implementation
}
}
Disclaimer
Use this library at your own risk.
License
MIT
Dependencies
~4.5MB
~97K SLoC