Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,147 changes: 625 additions & 522 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,15 @@ console = "0.15.10"
console_error_panic_hook = "0.1.7"
console_log = "0.2.2"
criterion = "0.5.1"
curve25519-dalek = { version = "4.1.3", features = ["digest", "rand_core"] }
# TODO: switch back to crates.io version when "hEAA" is merged
# curve25519-dalek = { version = "4.1.3", features = ["digest", "rand_core"] }
curve25519-dalek = { git = "https://github.com/zz-sol/curve25519-dalek.git", branch = "zz/impl_ches25", default-features = false, features = ["digest", "zeroize", "precomputed-tables"] }
dashmap = { version = "5.5.3", features = ["serde"] }
derivation-path = { version = "0.2.0", default-features = false }
digest = "0.10.7"
ed25519-dalek = "2.1.1"
ed25519-dalek-bip32 = "0.3.0"
# ed25519-dalek = "2.1.1"
ed25519-zebra = { git = "https://github.com/zz-sol/ed25519-zebra.git", branch = "zz/impl_size_halving_verify" }
ff = "0.13.1"
five8 = "1.0.0"
five8_const = "1.0.0"
Expand Down Expand Up @@ -343,3 +346,6 @@ opt-level = 1
# Enable optimizations for procmacros for faster recompile
[profile.dev.build-override]
opt-level = 1

[patch.crates-io]
curve25519-dalek = { git = "https://github.com/zz-sol/curve25519-dalek.git", branch = "zz/impl_ches25", default-features = false, features = ["digest", "zeroize", "precomputed-tables"] }
2 changes: 1 addition & 1 deletion account-view/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-account-view"
description = "Lightweight representation of a runtime account"
documentation = "https://docs.rs/solana-account-view"
version = "1.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion address-lookup-table-interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-address-lookup-table-interface"
description = "Solana address lookup table interface."
documentation = "https://docs.rs/solana-address-lookup-table-interface"
version = "3.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions address/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-address"
description = "Solana account addresses"
documentation = "https://docs.rs/solana-address"
version = "2.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand All @@ -20,7 +20,7 @@ atomic = ["dep:solana-atomic-u64"]
borsh = ["dep:borsh", "alloc"]
bytemuck = ["copy", "dep:bytemuck", "dep:bytemuck_derive"]
copy = []
curve25519 = ["dep:curve25519-dalek", "sha2", "syscalls"]
curve25519 = ["dep:curve25519-dalek", "sha2", "syscalls", "alloc"]
decode = ["dep:five8", "dep:five8_const", "error"]
dev-context-only-utils = ["dep:arbitrary", "rand"]
error = ["dep:solana-program-error"]
Expand Down
2 changes: 1 addition & 1 deletion bls-signatures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-bls-signatures"
description = "Solana BLS Signatures"
documentation = "https://docs.rs/solana-bls-signatures"
version = "1.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion commitment-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-commitment-config"
description = "Solana commitment config."
documentation = "https://docs.rs/solana-commitment-config"
version = "3.1.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion derivation-path/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-derivation-path"
description = "Solana BIP44 derivation paths."
documentation = "https://docs.rs/solana-derivation-path"
version = "3.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion feature-gate-interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repository = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = "1.81.0"
rust-version = "1.85.0"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
Expand Down
2 changes: 1 addition & 1 deletion hash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-hash"
description = "Solana wrapper for the 32-byte output of a hashing algorithm."
documentation = "https://docs.rs/solana-hash"
version = "4.0.1"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion instruction-error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-instruction-error"
description = "Solana InstructionError type."
documentation = "https://docs.rs/solana-instruction-error"
version = "2.1.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion instruction-view/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-instruction-view"
description = "Lightweight instruction representation"
documentation = "https://docs.rs/solana-instruction-view"
version = "1.0.0"
rust-version = "1.82.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions keypair/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-keypair"
description = "Concrete implementation of a Solana `Signer`."
documentation = "https://docs.rs/solana-keypair"
version = "3.1.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand All @@ -23,8 +23,8 @@ seed-derivable = [
]

[dependencies]
ed25519-dalek = { workspace = true, features = ["rand_core"] }
ed25519-dalek-bip32 = { workspace = true, optional = true }
ed25519-zebra = { workspace = true }
five8 = { workspace = true }
rand = { workspace = true }
solana-address = { workspace = true, features = ["decode"] }
Expand Down
88 changes: 50 additions & 38 deletions keypair/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Concrete implementation of a Solana `Signer` from raw bytes
#![cfg_attr(docsrs, feature(doc_cfg))]
use {
ed25519_dalek::Signer as DalekSigner,
rand::rngs::OsRng,
solana_seed_phrase::generate_seed_from_seed_phrase_and_passphrase,
solana_signer::SignerError,
Expand All @@ -23,8 +22,10 @@ pub mod signable;

/// A vanilla Ed25519 key pair
#[derive(Debug)]
pub struct Keypair(ed25519_dalek::SigningKey);
pub struct Keypair(ed25519_zebra::SigningKey);

// ed25519_zebra's signing_key module is private, so we define this constant ourselves
pub const SECRET_KEY_LENGTH: usize = 32;
pub const KEYPAIR_LENGTH: usize = 64;

impl Keypair {
Expand All @@ -34,23 +35,33 @@ impl Keypair {
/// Constructs a new, random `Keypair` using `OsRng`
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
let mut rng = OsRng;
Self(ed25519_dalek::SigningKey::generate(&mut rng))
let rng = OsRng;
Self(ed25519_zebra::SigningKey::new(rng))
}

/// Constructs a new `Keypair` using secret key bytes
pub fn new_from_array(secret_key: [u8; 32]) -> Self {
Self(ed25519_dalek::SigningKey::from(secret_key))
Self(ed25519_zebra::SigningKey::from(secret_key))
}

/// Returns this `Keypair` as a byte array
pub fn to_bytes(&self) -> [u8; KEYPAIR_LENGTH] {
self.0.to_keypair_bytes()
// Zebra simplified dalek and removed the struct `Keypair`.
// For this lib to be backwards compatible while using zebra,
// we manually write the to_bytes() function, which is
// [ sk | vk ]
[
self.0.to_bytes().as_ref(),
self.0.verification_key().as_ref(),
]
.concat()
.try_into()
.expect("fail to convert keypair to byte array")
}

/// Recovers a `Keypair` from a base58-encoded string
pub fn from_base58_string(s: &str) -> Self {
let mut buf = [0u8; ed25519_dalek::KEYPAIR_LENGTH];
let mut buf = [0u8; KEYPAIR_LENGTH];
five8::decode_64(s, &mut buf).unwrap();
Self::try_from(&buf[..]).unwrap()
}
Expand All @@ -75,37 +86,43 @@ impl Keypair {
/// Only use this in tests or when strictly required. Consider using [`std::sync::Arc<Keypair>`]
/// instead.
pub fn insecure_clone(&self) -> Self {
Self(self.0.clone())
Self(self.0)
}
}

impl TryFrom<&[u8]> for Keypair {
type Error = SignatureError;

fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
let keypair_bytes: &[u8; ed25519_dalek::KEYPAIR_LENGTH] =
bytes.try_into().map_err(|_| {
SignatureError::from_source(String::from(
"candidate keypair byte array is the wrong length",
))
})?;
ed25519_dalek::SigningKey::from_keypair_bytes(keypair_bytes)
.map_err(|_| {
SignatureError::from_source(String::from(
"keypair bytes do not specify same pubkey as derived from their secret key",
))
})
.map(Self)
let keypair_bytes: &[u8; KEYPAIR_LENGTH] = bytes.try_into().map_err(|_| {
SignatureError::from_source(String::from(
"candidate keypair byte array is the wrong length",
))
})?;
let (secret_key, verifying_key) = keypair_bytes.split_at(SECRET_KEY_LENGTH);
let signing_key = ed25519_zebra::SigningKey::try_from(secret_key)
.map_err(|e| SignatureError::from_source(format!("invalid secret key: {e}")))?;
let verifying_key = ed25519_zebra::VerificationKey::try_from(verifying_key)
.map_err(|e| SignatureError::from_source(format!("invalid verification key: {e}")))?;

if signing_key.verification_key() != verifying_key {
return Err(SignatureError::from_source(String::from(
"deserialized keypair's public key does not match the secret key",
)));
}

Ok(Self(signing_key))
}
}

#[cfg(test)]
static_assertions::const_assert_eq!(Keypair::SECRET_KEY_LENGTH, ed25519_dalek::SECRET_KEY_LENGTH);
static_assertions::const_assert_eq!(Keypair::SECRET_KEY_LENGTH, SECRET_KEY_LENGTH);

impl Signer for Keypair {
#[inline]
fn pubkey(&self) -> Address {
Address::from(self.0.verifying_key().to_bytes())
let vk_bytes: [u8; 32] = self.0.verification_key().into();
Address::from(vk_bytes)
}

fn try_pubkey(&self) -> Result<Address, SignerError> {
Expand Down Expand Up @@ -172,18 +189,13 @@ pub fn read_keypair<R: Read>(reader: &mut R) -> Result<Keypair, Box<dyn error::E
let contents = &trimmed[1..trimmed.len() - 1];
let elements_vec: Vec<&str> = contents.split(',').map(|s| s.trim()).collect();
let len = elements_vec.len();
let elements: [&str; ed25519_dalek::KEYPAIR_LENGTH] =
elements_vec.try_into().map_err(|_| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Expected {} elements, found {}",
ed25519_dalek::KEYPAIR_LENGTH,
len
),
)
})?;
let mut out = [0u8; ed25519_dalek::KEYPAIR_LENGTH];
let elements: [&str; KEYPAIR_LENGTH] = elements_vec.try_into().map_err(|_| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Expected {KEYPAIR_LENGTH} elements, found {len}"),
)
})?;
let mut out = [0u8; KEYPAIR_LENGTH];
for (idx, element) in elements.into_iter().enumerate() {
let parsed: u8 = element.parse()?;
out[idx] = parsed;
Expand Down Expand Up @@ -232,12 +244,12 @@ pub fn write_keypair_file<F: AsRef<Path>>(

/// Constructs a `Keypair` from caller-provided seed entropy
pub fn keypair_from_seed(seed: &[u8]) -> Result<Keypair, Box<dyn error::Error>> {
if seed.len() < ed25519_dalek::SECRET_KEY_LENGTH {
if seed.len() < SECRET_KEY_LENGTH {
return Err("Seed is too short".into());
}
// this won't fail as we've already checked the length
let secret_key = ed25519_dalek::SecretKey::try_from(&seed[..ed25519_dalek::SECRET_KEY_LENGTH])?;
Ok(Keypair(ed25519_dalek::SigningKey::from(secret_key)))
let secret_key: &[u8; SECRET_KEY_LENGTH] = seed[..SECRET_KEY_LENGTH].try_into()?;
Ok(Keypair(ed25519_zebra::SigningKey::from_bytes(secret_key)))
}

pub fn keypair_from_seed_phrase_and_passphrase(
Expand Down
6 changes: 5 additions & 1 deletion keypair/src/seed_derivable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,9 @@ fn bip32_derived_keypair(
) -> Result<Keypair, Bip32Error> {
let extended = ed25519_dalek_bip32::ExtendedSigningKey::from_seed(seed)
.and_then(|extended| extended.derive(&derivation_path))?;
Ok(Keypair(extended.signing_key))
// Convert ed25519_dalek SigningKey to ed25519_zebra SigningKey
let secret_bytes = extended.signing_key.to_bytes();
Ok(Keypair(ed25519_zebra::SigningKey::from_bytes(
&secret_bytes,
)))
}
2 changes: 1 addition & 1 deletion message/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-message"
description = "Solana transaction message types."
documentation = "https://docs.rs/solana-message"
version = "3.0.1"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion precompile-error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-precompile-error"
description = "Solana PrecompileError type"
documentation = "https://docs.rs/solana-precompile-error"
version = "3.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion program-entrypoint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }

rust-version = "1.81.0"
rust-version = "1.85.0"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
Expand Down
2 changes: 1 addition & 1 deletion program-error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-program-error"
description = "Solana ProgramError type and related definitions."
documentation = "https://docs.rs/solana-program-error"
version = "3.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repository = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = "1.81.0" # solana platform-tools rust version
rust-version = "1.85.0" # solana platform-tools rust version
include = ["src/**/*", "README.md"]

[package.metadata.docs.rs]
Expand Down
2 changes: 1 addition & 1 deletion pubkey/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-pubkey"
description = "Solana account addresses"
documentation = "https://docs.rs/solana-pubkey"
version = "4.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion quic-definitions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-quic-definitions"
description = "Definitions related to Solana over QUIC."
documentation = "https://docs.rs/solana-quic-definitions"
version = "3.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion sanitize/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "solana-sanitize"
description = "Solana Message Sanitization"
documentation = "https://docs.rs/solana-sanitize"
rust-version = "1.81.0"
rust-version = "1.85.0"
version = "3.0.1"
authors = { workspace = true }
repository = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion secp256r1-program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "solana-secp256r1-program"
description = "Precompile implementation for the secp256r1 elliptic curve."
documentation = "https://docs.rs/solana-secp256r1"
version = "3.0.0"
rust-version = "1.81.0"
rust-version = "1.85.0"
authors = { workspace = true }
repository = { workspace = true }
homepage = { workspace = true }
Expand Down
Loading