chore: update ed25519-dalek and rand libraries, use workspace versioning

This commit is contained in:
Aaron Blankstein
2024-02-15 10:23:23 -06:00
parent 2dca32f984
commit 41df072c8d
14 changed files with 1091 additions and 984 deletions

1874
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,10 @@ members = [
# Dependencies we want to keep the same between workspace members
[workspace.dependencies]
wsts = { version = "8.0", default-features = false }
ed25519-dalek = { version = "2.1.1", features = ["serde", "rand_core"] }
rand_core = "0.6"
rand = "0.8"
rand_chacha = "0.3.1"
# Use a bit more than default optimization for
# dev builds to speed up test execution

View File

@@ -18,8 +18,8 @@ name = "clarity"
path = "./src/libclarity.rs"
[dependencies]
rand = "0.7.3"
rand_chacha = "=0.2.2"
rand = { workspace = true }
rand_chacha = { workspace = true }
serde = "1"
serde_derive = "1"
serde_stacker = "0.1"

View File

@@ -18,7 +18,7 @@ name = "stacks_common"
path = "./src/libcommon.rs"
[dependencies]
rand = "0.7.3"
rand = { workspace = true }
serde = "1"
serde_derive = "1"
serde_stacker = "0.1"
@@ -55,8 +55,7 @@ version = "=0.24.2"
features = ["blob", "serde_json", "i128_blob", "bundled", "trace"]
[dependencies.ed25519-dalek]
version = "=1.0.0-pre.3"
features = ["serde"]
workspace = true
[dependencies.curve25519-dalek]
version = "=2.0.0"
@@ -70,7 +69,7 @@ features = ["std"]
rstest = "0.11.0"
rstest_reuse = "0.1.3"
assert-json-diff = "1.0.0"
rand_core = "0.6"
rand_core = { workspace = true }
[features]
default = ["developer-mode"]

View File

@@ -381,7 +381,7 @@ mod test {
fn old_c32_validation() {
for n in 0..5000 {
// random version
let random_version: u8 = rand::thread_rng().gen_range(0, 31);
let random_version: u8 = rand::thread_rng().gen_range(0..31);
// random 20 bytes
let random_bytes = rand::thread_rng().gen::<[u8; 20]>();

View File

@@ -31,7 +31,7 @@ use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint};
use curve25519_dalek::scalar::Scalar as ed25519_Scalar;
use ed25519_dalek::{
Keypair as VRFKeypair, PublicKey as ed25519_PublicKey, SecretKey as ed25519_PrivateKey,
SecretKey as EdDalekSecretKeyBytes, SigningKey as EdPrivateKey, VerifyingKey as EdPublicKey,
};
use rand;
use sha2::{Digest, Sha512};
@@ -39,9 +39,10 @@ use sha2::{Digest, Sha512};
use crate::util::hash::{hex_bytes, to_hex};
#[derive(Clone)]
pub struct VRFPublicKey(pub ed25519_PublicKey);
pub struct VRFPublicKey(pub ed25519_dalek::VerifyingKey);
pub struct VRFPrivateKey(pub ed25519_PrivateKey);
#[derive(Clone)]
pub struct VRFPrivateKey(pub ed25519_dalek::SigningKey);
impl serde::Serialize for VRFPublicKey {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
@@ -58,29 +59,6 @@ impl<'de> serde::Deserialize<'de> for VRFPublicKey {
}
}
// have to do Clone separately since ed25519_PrivateKey doesn't implement Clone
impl Clone for VRFPrivateKey {
fn clone(&self) -> VRFPrivateKey {
let bytes = self.to_bytes();
let pk = ed25519_PrivateKey::from_bytes(&bytes)
.expect("FATAL: could not do VRFPrivateKey round-trip");
VRFPrivateKey(pk)
}
}
impl Deref for VRFPublicKey {
type Target = ed25519_PublicKey;
fn deref(&self) -> &ed25519_PublicKey {
&self.0
}
}
impl DerefMut for VRFPublicKey {
fn deref_mut(&mut self) -> &mut ed25519_PublicKey {
&mut self.0
}
}
impl Debug for VRFPublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", &self.to_hex())
@@ -113,19 +91,6 @@ impl Hash for VRFPublicKey {
}
}
impl Deref for VRFPrivateKey {
type Target = ed25519_PrivateKey;
fn deref(&self) -> &ed25519_PrivateKey {
&self.0
}
}
impl DerefMut for VRFPrivateKey {
fn deref_mut(&mut self) -> &mut ed25519_PrivateKey {
&mut self.0
}
}
impl Debug for VRFPrivateKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", &self.to_hex())
@@ -149,71 +114,76 @@ impl Default for VRFPrivateKey {
impl VRFPrivateKey {
pub fn new() -> VRFPrivateKey {
let mut rng = rand::thread_rng();
let keypair: VRFKeypair = VRFKeypair::generate(&mut rng);
VRFPrivateKey(keypair.secret)
let signing_key = ed25519_dalek::SigningKey::generate(&mut rng);
VRFPrivateKey(signing_key)
}
pub fn from_hex(h: &str) -> Option<VRFPrivateKey> {
match hex_bytes(h) {
Ok(b) => match ed25519_PrivateKey::from_bytes(&b[..]) {
Ok(pk) => Some(VRFPrivateKey(pk)),
Err(_) => None,
},
Err(_) => None,
}
let bytes = hex_bytes(h).ok()?;
Self::from_bytes(bytes.as_slice())
}
pub fn from_bytes(b: &[u8]) -> Option<VRFPrivateKey> {
match ed25519_PrivateKey::from_bytes(b) {
Ok(pk) => Some(VRFPrivateKey(pk)),
Err(_) => None,
}
let signing_key = ed25519_dalek::SigningKey::try_from(b).ok()?;
Some(VRFPrivateKey(signing_key))
}
pub fn to_hex(&self) -> String {
to_hex(self.as_bytes())
}
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
}
impl VRFPublicKey {
pub fn from_private(pk: &VRFPrivateKey) -> VRFPublicKey {
VRFPublicKey(ed25519_PublicKey::from(&pk.0))
pub fn from_private(sk: &VRFPrivateKey) -> VRFPublicKey {
VRFPublicKey(sk.0.verifying_key())
}
/// Verify that a given byte string is a well-formed EdDSA public
/// key (i.e. it's a compressed Edwards point that is valid), and return
/// a VRFPublicKey if so
pub fn from_bytes(pubkey_bytes: &[u8]) -> Option<VRFPublicKey> {
match pubkey_bytes.len() {
32 => {
let mut pubkey_slice = [0; 32];
pubkey_slice.copy_from_slice(&pubkey_bytes[0..32]);
let pubkey_slice = pubkey_bytes.try_into().ok()?;
let checked_pubkey = CompressedEdwardsY(pubkey_slice);
match checked_pubkey.decompress() {
Some(_) => {}
None => {
// invalid
return None;
}
}
// NOTE: `ed25519_dalek::VerifyingKey::from_bytes` docs say
// that this check must be performed by the caller, but as of
// latest, it actually performs the check as well. However,
// we do this check out of an abundance of caution because
// that's what the docs say to do!
match ed25519_PublicKey::from_bytes(&pubkey_slice) {
Ok(key) => Some(VRFPublicKey(key)),
Err(_) => None,
}
}
_ => None,
let checked_pubkey = CompressedEdwardsY(pubkey_slice);
if checked_pubkey.decompress().is_none() {
// invalid
return None;
}
let key = ed25519_dalek::VerifyingKey::from_bytes(&pubkey_slice).ok()?;
Some(VRFPublicKey(key))
}
pub fn from_hex(h: &str) -> Option<VRFPublicKey> {
match hex_bytes(h) {
Ok(b) => VRF::check_public_key(&b),
Err(_) => None,
}
let bytes = hex_bytes(h).ok()?;
Self::from_bytes(bytes.as_slice())
}
pub fn to_hex(&self) -> String {
to_hex(self.as_bytes())
}
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
}
#[derive(Debug)]
@@ -565,15 +535,6 @@ impl VRF {
// NOTE: this leverages constant-time comparison inherited from the Scalar impl
Ok(c_prime == *(proof.c()))
}
/// Verify that a given byte string is a well-formed EdDSA public key (i.e. it's a compressed
/// Edwards point that is valid).
pub fn check_public_key(pubkey_bytes: &Vec<u8>) -> Option<VRFPublicKey> {
match pubkey_bytes.len() {
32 => VRFPublicKey::from_bytes(&pubkey_bytes[..]),
_ => None,
}
}
}
#[cfg(test)]
@@ -714,14 +675,14 @@ mod tests {
#[test]
fn check_valid_public_key() {
let res1 = VRF::check_public_key(
let res1 = VRFPublicKey::from_bytes(
&hex_bytes("a366b51292bef4edd64063d9145c617fec373bceb0758e98cd72becd84d54c7a")
.unwrap()
.to_vec(),
);
assert!(res1.is_some());
let res2 = VRF::check_public_key(
let res2 = VRFPublicKey::from_bytes(
&hex_bytes("a366b51292bef4edd64063d9145c617fec373bceb0758e98cd72becd84d54c7b")
.unwrap()
.to_vec(),

View File

@@ -31,8 +31,9 @@ name = "blockstack-cli"
path = "src/blockstack_cli.rs"
[dependencies]
rand = "0.7.3"
rand_chacha = "=0.2.2"
rand = { workspace = true }
rand_core = { workspace = true }
rand_chacha = { workspace = true }
serde = "1"
serde_derive = "1"
serde_stacker = "0.1"
@@ -56,7 +57,6 @@ pox-locking = { path = "../pox-locking" }
libstackerdb = { path = "../libstackerdb" }
siphasher = "0.3.7"
wsts = {workspace = true}
rand_core = {workspace = true}
hashbrown = "0.14"
[target.'cfg(unix)'.dependencies]
@@ -81,8 +81,7 @@ version = "=0.24.2"
features = ["blob", "serde_json", "i128_blob", "bundled", "trace"]
[dependencies.ed25519-dalek]
version = "=1.0.0-pre.3"
features = ["serde"]
workspace = true
[dependencies.curve25519-dalek]
version = "=2.0.0"

View File

@@ -187,7 +187,7 @@ impl BitcoinIndexer {
}
Err(btc_error::ConnectionBroken) => {
// need to try again
backoff = 2.0 * backoff + (backoff * rng.gen_range(0.0, 1.0));
backoff = 2.0 * backoff + (backoff * rng.gen_range(0.0..1.0));
}
Err(e) => {
// propagate other network error
@@ -204,7 +204,7 @@ impl BitcoinIndexer {
"Failed to connect to peer {}:{}: {}",
&self.config.peer_host, self.config.peer_port, err_msg
);
backoff = 2.0 * backoff + (backoff * rng.gen_range(0.0, 1.0));
backoff = 2.0 * backoff + (backoff * rng.gen_range(0.0..1.0));
}
}

View File

@@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
use ed25519_dalek::Keypair as VRFKeypair;
use rand::rngs::ThreadRng;
use rand::thread_rng;
use serde::Serialize;
@@ -867,12 +866,13 @@ fn test_burn_snapshot_sequence() {
for i in 0..32 {
let mut csprng: ThreadRng = thread_rng();
let keypair: VRFKeypair = VRFKeypair::generate(&mut csprng);
let vrf_privkey = VRFPrivateKey(ed25519_dalek::SigningKey::generate(&mut csprng));
let vrf_pubkey = VRFPublicKey::from_private(&vrf_privkey);
let privkey_hex = to_hex(&keypair.secret.to_bytes());
let privkey_hex = vrf_privkey.to_hex();
leader_private_keys.push(privkey_hex);
let pubkey_hex = to_hex(&keypair.public.to_bytes());
let pubkey_hex = vrf_pubkey.to_hex();
leader_public_keys.push(pubkey_hex);
let bitcoin_privkey = Secp256k1PrivateKey::new();

View File

@@ -150,8 +150,8 @@ impl SortitionHash {
if max < 2 {
return (0..max).collect();
}
let first = rng.gen_range(0, max);
let try_second = rng.gen_range(0, max - 1);
let first = rng.gen_range(0..max);
let try_second = rng.gen_range(0..(max - 1));
let second = if first == try_second {
// "swap" try_second with max
max - 1

View File

@@ -53,9 +53,9 @@ fn test_fuzzing_seed1() {
.get_rate_estimates()
.expect("Estimate should exist."),
FeeRateEstimate {
high: 96.20545857700169f64,
middle: 50.63445188263247f64,
low: 5.0634451882632465f64
high: 91.73244187536466f64,
middle: 48.28023256598139f64,
low: 4.82802325659814f64
}
);
}
@@ -77,9 +77,9 @@ fn test_fuzzing_seed2() {
.get_rate_estimates()
.expect("Estimate should exist."),
FeeRateEstimate {
high: 100.08112623179122f64,
middle: 52.67427696410064f64,
low: 5.267427696410064f64
high: 88.82921297592677f64,
middle: 46.75221735575093f64,
low: 4.675221735575093f64
}
);
}
@@ -136,9 +136,9 @@ fn test_notify_pass_through() {
.get_rate_estimates()
.expect("Estimate should exist."),
FeeRateEstimate {
high: 2.1069710785640257f64,
middle: 2.1069710785640257f64,
low: 2.1069710785640257f64
},
high: 1.8700886942300372f64,
middle: 1.8700886942300372f64,
low: 1.8700886942300372f64
}
);
}

View File

@@ -134,7 +134,7 @@ impl Neighbor {
let mut rng = thread_rng();
let min = cmp::min(self.in_degree, self.out_degree);
let max = cmp::max(self.in_degree, self.out_degree);
let res = rng.gen_range(min, max + 1) as u64;
let res = rng.gen_range(min..(max + 1)) as u64;
if res == 0 {
1
} else {

View File

@@ -1375,7 +1375,7 @@ impl<DB: NeighborWalkDB, NC: NeighborComms> NeighborWalk<DB, NC> {
}
// select a random neighbor index, if exclude is set, and matches this
// neighbor, then use the next index (modulo the frontier length).
let mut neighbor_index = rnd.gen_range(0, frontier.len());
let mut neighbor_index = rnd.gen_range(0..frontier.len());
for _ in 0..2 {
// two attempts, in case our first attempt lands on `exclude`
for (cnt, (nk, n)) in frontier.iter().enumerate() {

View File

@@ -153,7 +153,7 @@ impl PeerNetwork {
total += count;
}
let sample = rng.gen_range(0, total);
let sample = rng.gen_range(0..total);
let mut offset = 0;
for (org, count) in org_weights.iter() {
if *count == 0 {