Skip to content

Commit

Permalink
Merge pull request #91 from koute/master_dalek4
Browse files Browse the repository at this point in the history
Update to `curve25519-dalek` 4.1.0
  • Loading branch information
burdges authored Sep 6, 2023
2 parents ab3e3d6 + 8dc6b99 commit d42c00e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 21 deletions.
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ aead = { version = "0.5.2", default-features = false, optional = true }
arrayref = { version = "0.3.6", default-features = false }
# needs to match parity-scale-code which is "=0.7.0"
arrayvec = { version = "0.7.0", default-features = false }
curve25519-dalek = { version = "4.0.0-rc.2", default-features = false, features = ["digest", "zeroize"] }
curve25519-dalek = { version = "4.1.0", default-features = false, features = ["digest", "zeroize", "precomputed-tables", "legacy_compatibility"] }
subtle = { version = "2.5.0", default-features = false }
merlin = { version = "3.0.0", default-features = false }
rand_core = { version = "0.6.2", default-features = false }
Expand All @@ -42,13 +42,12 @@ name = "schnorr_benchmarks"
harness = false

[features]
default = ["std", "getrandom", "precomputed-tables"]
default = ["std", "getrandom"]
preaudit_deprecated = []
nightly = []
alloc = ["curve25519-dalek/alloc", "rand_core/alloc", "serde_bytes/alloc"]
std = ["alloc", "getrandom", "serde_bytes/std"]
asm = ["sha2/asm"]
precomputed-tables = ["curve25519-dalek/precomputed-tables"]
serde = ["serde_crate", "serde_bytes", "cfg-if"]
# We cannot make getrandom a direct dependency because rand_core makes
# getrandom a feature name, which requires forwarding.
Expand Down
17 changes: 5 additions & 12 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ pub enum SignatureError {
PointDecompressionError,
/// Invalid scalar provided, usually to `Signature::from_bytes`.
ScalarFormatError,
/// The provided key is not valid.
InvalidKey,
/// An error in the length of bytes handed to a constructor.
///
/// To use this, pass a string specifying the `name` of the type
Expand Down Expand Up @@ -120,6 +122,8 @@ impl Display for SignatureError {
write!(f, "Cannot decompress Ristretto point"),
ScalarFormatError =>
write!(f, "Cannot use scalar with high-bit set"),
InvalidKey =>
write!(f, "The provided key is not valid"),
BytesLengthError { name, length, .. } =>
write!(f, "{name} must be {length} bytes in length"),
NotMarkedSchnorrkel =>
Expand Down Expand Up @@ -147,16 +151,5 @@ impl failure::Fail for SignatureError {}
pub fn serde_error_from_signature_error<E>(err: SignatureError) -> E
where E: serde_crate::de::Error
{
use self::SignatureError::*;
match err {
PointDecompressionError
=> E::custom("Ristretto point decompression failed"),
ScalarFormatError
=> E::custom("improper scalar has high-bit set"), // TODO ed25519 v high 3 bits?
BytesLengthError{ description, length, .. }
=> E::invalid_length(length, &description),
NotMarkedSchnorrkel
=> E::custom("Signature bytes not marked as a schnorrkel signature"),
_ => panic!("Non-serialisation error encountered by serde!"),
}
E::custom(err)
}
30 changes: 26 additions & 4 deletions src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ impl MiniSecretKey {
// We then divide by the cofactor to internally keep a clean
// representation mod l.
scalars::divide_scalar_bytes_by_cofactor(&mut key);

#[allow(deprecated)] // Scalar's always reduced here, so this is OK.
let key = Scalar::from_bits(key);

let mut nonce = [0u8; 32];
Expand Down Expand Up @@ -518,14 +520,17 @@ impl SecretKey {

let mut key: [u8; 32] = [0u8; 32];
key.copy_from_slice(&bytes[00..32]);
// TODO: We should consider making sure the scalar is valid,
// maybe by zeroing the high bit, or preferably by checking < l.
// key[31] &= 0b0111_1111;
// We divide by the cofactor to internally keep a clean
// representation mod l.
scalars::divide_scalar_bytes_by_cofactor(&mut key);
let key = Scalar::from_bits(key);

let key = Scalar::from_canonical_bytes(key);
if bool::from(key.is_none()) {
// This should never trigger for keys which come from `to_ed25519_bytes`.
return Err(SignatureError::InvalidKey);
}

let key = key.unwrap();
let mut nonce: [u8; 32] = [0u8; 32];
nonce.copy_from_slice(&bytes[32..64]);

Expand Down Expand Up @@ -974,4 +979,21 @@ mod test {
let public_from_secret: PublicKey = secret.to_public();
assert!(public_from_mini_secret == public_from_secret);
}

#[cfg(feature = "getrandom")]
#[test]
fn secret_key_can_be_converted_to_ed25519_bytes_and_back() {
let count = if cfg!(debug_assertions) {
200000
} else {
2000000
};

for _ in 0..count {
let key = SecretKey::generate();
let bytes = key.to_ed25519_bytes();
let key_deserialized = SecretKey::from_ed25519_bytes(&bytes).unwrap();
assert_eq!(key_deserialized, key);
}
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@
#![deny(missing_docs)] // refuse to compile if documentation is missing
#![allow(clippy::needless_lifetimes)]

#[cfg(any(feature = "std"))]
#[cfg(feature = "std")]
#[macro_use]
extern crate std;

Expand Down
3 changes: 2 additions & 1 deletion src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ pub(crate) fn check_scalar(bytes: [u8; 32]) -> SignatureResult<Scalar> {
// as the order of the basepoint is roughly a 2^(252.5) bit number.
//
// This succeed-fast trick should succeed for roughly half of all scalars.
if bytes[31] & 240 == 0 {
if bytes[31] & 0b11110000 == 0 {
#[allow(deprecated)] // Scalar's always reduced here, so this is OK.
return Ok(Scalar::from_bits(bytes))
}

Expand Down

0 comments on commit d42c00e

Please sign in to comment.