Skip to content
Open
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
2 changes: 1 addition & 1 deletion fastcrypto-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repository = "https://github.com/MystenLabs/fastcrypto"

[dependencies]
clap = { version = "4.1.8", features = ["derive"] }
fastcrypto = { path = "../fastcrypto", features = ["copy_key"] }
fastcrypto = { path = "../fastcrypto" }
fastcrypto-vdf = { path = "../fastcrypto-vdf", features = ["experimental"] }
hex = "0.4.3"
rand.workspace = true
Expand Down
40 changes: 20 additions & 20 deletions fastcrypto-cli/src/sigs_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,38 +126,38 @@ fn execute(cmd: Command) -> Result<(), FastCryptoError> {
let (sk, pk) = match SignatureScheme::from_str(&arg.scheme) {
Ok(SignatureScheme::Ed25519) => {
let kp = Ed25519KeyPair::generate(rng);
(
Hex::encode(kp.copy().private().as_ref()),
Hex::encode(kp.public().as_ref()),
)
{
let pk = Hex::encode(kp.public().as_ref());
(Hex::encode(kp.private().as_ref()), pk)
}
}
Ok(SignatureScheme::Secp256k1) | Ok(SignatureScheme::Secp256k1Recoverable) => {
let kp = Secp256k1KeyPair::generate(rng);
(
Hex::encode(kp.copy().private().as_ref()),
Hex::encode(kp.public().as_ref()),
)
{
let pk = Hex::encode(kp.public().as_ref());
(Hex::encode(kp.private().as_ref()), pk)
}
}
Ok(SignatureScheme::Secp256r1) | Ok(SignatureScheme::Secp256r1Recoverable) => {
let kp = Secp256r1KeyPair::generate(rng);
(
Hex::encode(kp.copy().private().as_ref()),
Hex::encode(kp.public().as_ref()),
)
{
let pk = Hex::encode(kp.public().as_ref());
(Hex::encode(kp.private().as_ref()), pk)
}
}
Ok(SignatureScheme::BLS12381MinSig) => {
let kp = fastcrypto::bls12381::min_sig::BLS12381KeyPair::generate(rng);
(
Hex::encode(kp.copy().private().as_ref()),
Hex::encode(kp.public().as_ref()),
)
{
let pk = Hex::encode(kp.public().as_ref());
(Hex::encode(kp.private().as_ref()), pk)
}
}
Ok(SignatureScheme::BLS12381MinPk) => {
let kp = fastcrypto::bls12381::min_pk::BLS12381KeyPair::generate(rng);
(
Hex::encode(kp.copy().private().as_ref()),
Hex::encode(kp.public().as_ref()),
)
{
let pk = Hex::encode(kp.public().as_ref());
(Hex::encode(kp.private().as_ref()), pk)
}
}
Err(_) => return Err(FastCryptoError::InvalidInput),
};
Expand Down
8 changes: 6 additions & 2 deletions fastcrypto-pq/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ repository = "https://github.com/MystenLabs/fastcrypto"
publish = false

[dependencies]
# copy_key is not optional here
fastcrypto = { path = "../fastcrypto", features = ["copy_key"] }
fastcrypto = { path = "../fastcrypto" }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cargo check --workspace fails on

impl KeyPair for MLDSA65KeyPair {

with error:

error[E0046]: not all trait items implemented, missing: `copy`
   --> fastcrypto-pq/src/mldsa65/mod.rs:179:1

the core issue I think is:

fastcrypto = { path = "../fastcrypto", features = ["copy_key"] }

hardcodes features = ["copy_key"], so feature unification turns it on for the shared fastcrypto build.

fastcrypto-derive = { path = "../fastcrypto-derive", version = "0.1.4" }
# The C backend (mldsa-native, pinned as a submodule inside the wrapper)
mysten-mldsa-native-rs = { git = "https://github.com/MystenLabs/mysten-mldsa-native-rs.git", rev = "ea1a9794c7ad0c68b9410121964b7439540826bc", version = "0.1.0" }
Expand All @@ -23,6 +22,11 @@ bincode.workspace = true
zeroize.workspace = true

[features]
# Forwards to fastcrypto's copy_key, which gates KeyPair::copy for every scheme. Optional
# here so that depending on this crate does not turn private key copying on for the rest of
# the dependency graph through feature unification.
copy_key = ["fastcrypto/copy_key"]

# Forwards to the wrapper's verified assembly backends: NEON on aarch64, AVX2 on x86_64
# behind a runtime CPU probe. Identical signatures either way, roughly 2.5x faster.
native = ["mysten-mldsa-native-rs/native"]
Expand Down
2 changes: 1 addition & 1 deletion fastcrypto-pq/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ smart-contract vaults rather than the native transaction path.

```bash
# everything, both schemes
cargo test -p fastcrypto-pq --features native
cargo test -p fastcrypto-pq --all-features

# only the SLH-DSA building blocks
cargo test -p fastcrypto-pq sphincs
Expand Down
2 changes: 1 addition & 1 deletion fastcrypto-pq/src/mldsa65/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl KeyPair for MLDSA65KeyPair {
self.private
}

// Not cfg-gated on copy_key; this crate always enables fastcrypto/copy_key
#[cfg(feature = "copy_key")]
fn copy(&self) -> Self {
MLDSA65KeyPair {
public: self.public.clone(),
Expand Down
5 changes: 3 additions & 2 deletions fastcrypto-pq/src/tests/mldsa65_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ fn serialize_deserialize() {
verify_serialization(&signature, Some(signature.as_ref()));

// The secret side serializes as the 32-byte seed
let private = keypair.copy().private();
let private = MLDSA65PrivateKey::from_bytes(keypair.as_ref()).unwrap();
verify_serialization(&private, Some(private.as_ref()));
let kp_bytes = bincode::serialize(&keypair).unwrap();
assert_eq!(kp_bytes, keypair.as_ref());
Expand Down Expand Up @@ -241,6 +241,7 @@ fn keypair_from_str_roundtrip() {
}

#[test]
#[cfg(feature = "copy_key")]
fn copy_key_pair_preserves_identity() {
let keypair = keys().pop().unwrap();
let copied = keypair.copy();
Expand Down Expand Up @@ -290,7 +291,7 @@ fn debug_output_is_redacted_for_secrets() {
let keypair = keys().pop().unwrap();

// Secret material must never appear in formatted output.
let private = keypair.copy().private();
let private = MLDSA65PrivateKey::from_bytes(keypair.as_ref()).unwrap();
assert!(!format!("{private:?}").contains(&Base64::encode(keypair.as_ref())));

// Public types print their base64 form, which assertion failures rely on.
Expand Down
Loading