Skip to content
This repository was archived by the owner on Feb 6, 2025. It is now read-only.

Commit da04bc9

Browse files
chore: Move VRF and KES wrappers to ouroboros-crypto
1 parent f9b81ae commit da04bc9

File tree

9 files changed

+342
-17
lines changed

9 files changed

+342
-17
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
resolver = "2"
33
members = [
44
"ouroboros",
5+
"ouroboros-crypto",
56
"ouroboros-praos",
67
]

ouroboros-crypto/Cargo.toml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "ouroboros-crypto"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
hex = "0.4"
8+
cryptoxide = { version = "0.4.4" }
9+
thiserror = "2.0"
10+
rand_core = "0.6"
11+
pallas-codec = "0.31.0"
12+
pallas-crypto = "0.31.0"
13+
serde = "1.0.143"
14+
kes-summed-ed25519 = { git = "https://github.com/txpipe/kes", rev = "f69fb357d46f6a18925543d785850059569d7e78" }
15+
zeroize = "1.8.1"
16+
17+
# The vrf crate has not been fully tested in production environments and still has several upstream issues that
18+
# are open PRs but not merged yet.
19+
vrf_dalek = { git = "https://github.com/txpipe/vrf", rev = "044b45a1a919ba9d9c2471fc5c4d441f13086676" }
20+
21+
[dev-dependencies]
22+
#itertools = "0.13"
23+
#quickcheck = "1.0"
24+
#quickcheck_macros = "1.0"
25+
rand = "0.8"

ouroboros-crypto/src/kes/mod.rs

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
use kes_summed_ed25519::kes::{Sum6Kes, Sum6KesSig};
2+
use kes_summed_ed25519::traits::{KesSig, KesSk};
3+
use kes_summed_ed25519::PublicKey;
4+
use thiserror::Error;
5+
6+
/// KES error
7+
#[derive(Error, Debug)]
8+
pub enum Error {
9+
#[error("KES error: {0}")]
10+
Kes(#[from] kes_summed_ed25519::errors::Error),
11+
}
12+
13+
/// KES secret key
14+
pub struct KesSecretKey<'a> {
15+
sum_6_kes: Sum6Kes<'a>,
16+
}
17+
18+
impl KesSecretKey<'_> {
19+
/// Create a new KES secret key
20+
pub fn from_bytes(sk_bytes: &mut Vec<u8>) -> Result<KesSecretKey, Error> {
21+
// TODO: extend() could potentially re-allocate memory to a new location and copy the sk_bytes.
22+
// This would leave the original memory containing the secret key without being wiped.
23+
sk_bytes.extend([0u8; 4]); // default to period = 0
24+
let sum_6_kes = Sum6Kes::from_bytes(sk_bytes.as_mut_slice())?;
25+
Ok(KesSecretKey { sum_6_kes })
26+
}
27+
28+
/// Get the internal representation of the KES secret key at the current period
29+
/// This value will include the period as the last 4 bytes in big-endian format
30+
///
31+
/// # Safety
32+
/// This function is marked unsafe because we wished to highlight the
33+
/// importance of keeping the content of the secret key private.
34+
/// However there are reasons that may be valid to _leak_ the private
35+
/// key: to encrypt it and store securely.
36+
pub unsafe fn leak_into_bytes(&self) -> &[u8] {
37+
self.sum_6_kes.as_bytes()
38+
}
39+
40+
/// Get the KesPublicKey from the KesSecretKey
41+
pub fn to_pk(&self) -> KesPublicKey {
42+
KesPublicKey {
43+
kes_pk: self.sum_6_kes.to_pk(),
44+
}
45+
}
46+
47+
/// Get the current period of the KES secret key
48+
pub fn get_period(&self) -> u32 {
49+
self.sum_6_kes.get_period()
50+
}
51+
52+
/// Update the KES secret key to the next period
53+
pub fn update(&mut self) -> Result<(), Error> {
54+
Ok(self.sum_6_kes.update()?)
55+
}
56+
}
57+
58+
/// KES public key
59+
pub struct KesPublicKey {
60+
kes_pk: PublicKey,
61+
}
62+
63+
impl KesPublicKey {
64+
/// Create a new KES public key
65+
pub fn from_bytes(pk_bytes: &[u8]) -> Result<KesPublicKey, Error> {
66+
let kes_pk = PublicKey::from_bytes(pk_bytes)?;
67+
Ok(KesPublicKey { kes_pk })
68+
}
69+
70+
/// Get the internal representation of the KES public key
71+
pub fn as_bytes(&self) -> &[u8] {
72+
self.kes_pk.as_bytes()
73+
}
74+
}
75+
76+
/// KES signature
77+
pub struct KesSignature {
78+
sum_6_kes_sig: Sum6KesSig,
79+
}
80+
81+
impl KesSignature {
82+
/// Create a new KES signature
83+
pub fn from_bytes(sig_bytes: &[u8]) -> Result<KesSignature, Error> {
84+
let sum_6_kes_sig = Sum6KesSig::from_bytes(sig_bytes)?;
85+
Ok(KesSignature { sum_6_kes_sig })
86+
}
87+
88+
/// Get the internal representation of the KES signature
89+
pub fn to_bytes(&self) -> [u8; 448] {
90+
self.sum_6_kes_sig.to_bytes()
91+
}
92+
93+
/// Verify the KES signature
94+
pub fn verify(&self, kes_period: u32, kes_pk: &KesPublicKey, msg: &[u8]) -> Result<(), Error> {
95+
Ok(self.sum_6_kes_sig.verify(kes_period, &kes_pk.kes_pk, msg)?)
96+
}
97+
}
98+
99+
#[cfg(test)]
100+
mod tests {
101+
use crate::kes::{KesPublicKey, KesSecretKey, KesSignature};
102+
103+
#[test]
104+
fn kes_key_evolution() {
105+
let mut kes_sk_bytes = hex::decode("68b77b6e61925be0499d1445fd9210cec5bdfd5dd92662802eb2720ff70bc68fd8964580ff18bd2b232eb716dfbbeef82e2844b466ddd5dacaad9f15d3c753b348354141e973d039b1147c48e71e5b7cadc6deb28c86e4ae4fc26e8bbe1695c3374d4eb1094a7a698722894301546466c750947778b18ac3270397efd2eced4d25ced55d2bd2c09e7c0fa7b849d41787ca11defc91609d930a9870881a56a587bff20b2c5c59f63ccb008be495917da3fcae536d05401b6771bb1f9356f031b3ddadbffbc426a9a23e34274b187f7e93892e990644f6273772a02d3e38bee7459ed6a9bb5760fe012e47a2e75880125e7fb072b2b7a626a5375e2039d8d748cb8ad4dd02697250d3155eee39308ecc2925405a8c15e1cbe556cc4315d43ee5101003639bcb33bd6e27da3885888d7cca20b05cadbaa53941ef5282cde8f377c3bd0bf732cfac6b5d4d5597a1f72d81bc0d8af634a4c760b309fe8959bbde666ff10310377b313860bd52d56fd7cb149633beb1eb2e0076111df61e570a042f7cebae74a8de298a6f114938946230db42651ea4eddf5df2d7d2f3016464073da8a9dc715817b43586a61874e576da7b47a2bb6c2e19d4cbd5b1b39a24427e89b812cce6d30e0506e207f1eaab313c45a236068ea319958474237a5ffe02736e1c51c02a05999816c9253a557f09375c83acf5d7250f3bbc638e10c58fb274e2002eed841ecef6a9cbc57c3157a7c3cf47e66b1741e8173b6676ac973bc9715027a3225087cabad45407b891416330485891dc9a3875488a26428d20d581b629a8f4f42e3aa00cbcaae6c8e2b8f3fe033b874d1de6a3f8c321c92b77643f00d28e").unwrap();
106+
let mut kes_sk = KesSecretKey::from_bytes(&mut kes_sk_bytes).unwrap();
107+
let kes_pk = kes_sk.to_pk();
108+
assert_eq!(kes_sk.get_period(), 0);
109+
assert_eq!(hex::encode(unsafe { kes_sk.leak_into_bytes() }), "68b77b6e61925be0499d1445fd9210cec5bdfd5dd92662802eb2720ff70bc68fd8964580ff18bd2b232eb716dfbbeef82e2844b466ddd5dacaad9f15d3c753b348354141e973d039b1147c48e71e5b7cadc6deb28c86e4ae4fc26e8bbe1695c3374d4eb1094a7a698722894301546466c750947778b18ac3270397efd2eced4d25ced55d2bd2c09e7c0fa7b849d41787ca11defc91609d930a9870881a56a587bff20b2c5c59f63ccb008be495917da3fcae536d05401b6771bb1f9356f031b3ddadbffbc426a9a23e34274b187f7e93892e990644f6273772a02d3e38bee7459ed6a9bb5760fe012e47a2e75880125e7fb072b2b7a626a5375e2039d8d748cb8ad4dd02697250d3155eee39308ecc2925405a8c15e1cbe556cc4315d43ee5101003639bcb33bd6e27da3885888d7cca20b05cadbaa53941ef5282cde8f377c3bd0bf732cfac6b5d4d5597a1f72d81bc0d8af634a4c760b309fe8959bbde666ff10310377b313860bd52d56fd7cb149633beb1eb2e0076111df61e570a042f7cebae74a8de298a6f114938946230db42651ea4eddf5df2d7d2f3016464073da8a9dc715817b43586a61874e576da7b47a2bb6c2e19d4cbd5b1b39a24427e89b812cce6d30e0506e207f1eaab313c45a236068ea319958474237a5ffe02736e1c51c02a05999816c9253a557f09375c83acf5d7250f3bbc638e10c58fb274e2002eed841ecef6a9cbc57c3157a7c3cf47e66b1741e8173b6676ac973bc9715027a3225087cabad45407b891416330485891dc9a3875488a26428d20d581b629a8f4f42e3aa00cbcaae6c8e2b8f3fe033b874d1de6a3f8c321c92b77643f00d28e00000000");
110+
assert_eq!(
111+
hex::encode(kes_pk.as_bytes()),
112+
"2e5823037de29647e495b97d9dd7bf739f7ebc11d3701c8d0720f55618e1b292"
113+
);
114+
kes_sk.update().unwrap();
115+
assert_eq!(kes_sk.get_period(), 1);
116+
assert_eq!(hex::encode(unsafe { kes_sk.leak_into_bytes() }), "d8964580ff18bd2b232eb716dfbbeef82e2844b466ddd5dacaad9f15d3c753b3000000000000000000000000000000000000000000000000000000000000000048354141e973d039b1147c48e71e5b7cadc6deb28c86e4ae4fc26e8bbe1695c3374d4eb1094a7a698722894301546466c750947778b18ac3270397efd2eced4d25ced55d2bd2c09e7c0fa7b849d41787ca11defc91609d930a9870881a56a587bff20b2c5c59f63ccb008be495917da3fcae536d05401b6771bb1f9356f031b3ddadbffbc426a9a23e34274b187f7e93892e990644f6273772a02d3e38bee7459ed6a9bb5760fe012e47a2e75880125e7fb072b2b7a626a5375e2039d8d748cb8ad4dd02697250d3155eee39308ecc2925405a8c15e1cbe556cc4315d43ee5101003639bcb33bd6e27da3885888d7cca20b05cadbaa53941ef5282cde8f377c3bd0bf732cfac6b5d4d5597a1f72d81bc0d8af634a4c760b309fe8959bbde666ff10310377b313860bd52d56fd7cb149633beb1eb2e0076111df61e570a042f7cebae74a8de298a6f114938946230db42651ea4eddf5df2d7d2f3016464073da8a9dc715817b43586a61874e576da7b47a2bb6c2e19d4cbd5b1b39a24427e89b812cce6d30e0506e207f1eaab313c45a236068ea319958474237a5ffe02736e1c51c02a05999816c9253a557f09375c83acf5d7250f3bbc638e10c58fb274e2002eed841ecef6a9cbc57c3157a7c3cf47e66b1741e8173b6676ac973bc9715027a3225087cabad45407b891416330485891dc9a3875488a26428d20d581b629a8f4f42e3aa00cbcaae6c8e2b8f3fe033b874d1de6a3f8c321c92b77643f00d28e00000001");
117+
kes_sk.update().unwrap();
118+
assert_eq!(kes_sk.get_period(), 2);
119+
assert_eq!(hex::encode(unsafe { kes_sk.leak_into_bytes() }), "ba1aacc52e63e6121c2a205ecb5ae8f34a6e49bcc24254ca495a4affcd27fd869dd961c480648623218bf9b5f69d557547586a4fca8391092c59e27ef6a0584f7bc8e482396722f2a0a36fc2ac660eb44d8f5a5cf6916bba31afda77ef53364ea5ea39cc7e01d4ec1fce69c4b1f359781f460f373b9a81e7d3034b5baa3853840000000000000000000000000000000000000000000000000000000000000000bff20b2c5c59f63ccb008be495917da3fcae536d05401b6771bb1f9356f031b3ddadbffbc426a9a23e34274b187f7e93892e990644f6273772a02d3e38bee7459ed6a9bb5760fe012e47a2e75880125e7fb072b2b7a626a5375e2039d8d748cb8ad4dd02697250d3155eee39308ecc2925405a8c15e1cbe556cc4315d43ee5101003639bcb33bd6e27da3885888d7cca20b05cadbaa53941ef5282cde8f377c3bd0bf732cfac6b5d4d5597a1f72d81bc0d8af634a4c760b309fe8959bbde666ff10310377b313860bd52d56fd7cb149633beb1eb2e0076111df61e570a042f7cebae74a8de298a6f114938946230db42651ea4eddf5df2d7d2f3016464073da8a9dc715817b43586a61874e576da7b47a2bb6c2e19d4cbd5b1b39a24427e89b812cce6d30e0506e207f1eaab313c45a236068ea319958474237a5ffe02736e1c51c02a05999816c9253a557f09375c83acf5d7250f3bbc638e10c58fb274e2002eed841ecef6a9cbc57c3157a7c3cf47e66b1741e8173b6676ac973bc9715027a3225087cabad45407b891416330485891dc9a3875488a26428d20d581b629a8f4f42e3aa00cbcaae6c8e2b8f3fe033b874d1de6a3f8c321c92b77643f00d28e00000002");
120+
}
121+
122+
#[test]
123+
fn kes_signature_verify() {
124+
let kes_pk_bytes =
125+
hex::decode("2e5823037de29647e495b97d9dd7bf739f7ebc11d3701c8d0720f55618e1b292")
126+
.unwrap();
127+
let kes_pk = KesPublicKey::from_bytes(&kes_pk_bytes).unwrap();
128+
let kes_signature_bytes = hex::decode("20f1c8f9ae672e6ec75b0aa63a85e7ab7865b95f6b2907a26b54c14f49184ab52cf98ef441bb71de50380325b34f16d84fc78d137467a1b49846747cf8ee4701c56f08f198b94c468d46b67b271f5bc30ab2ad14b1bdbf2be0695a00fe4b02b3060fa52128f4cce9c5759df0ba8d71fe99456bd2e333671e45110908d03a2ec3b38599d26adf182ba63f79900fdb2732947cf8e940a4cf1e8db9b4cf4c001dbd37c60d0e38851de4910807896153be455e13161342d4c6f7bb3e4d2d35dbbbba0ebcd161be2f1ec030d2f5a6059ac89dfa70dc6b3d0bc2da179c62ae95c4f9c7ad9c0387b35bf2b45b325d1e0a18c0c783a0779003bf23e7a6b00cc126c5e3d51a57d41ff1707a76fb2c306a67c21473b41f1d9a7f64a670ec172a2421da03d796fa97086de8812304f4f96bd45243d0a2ad6c48a69d9e2c0afbb1333acee607d18eb3a33818c3c9d5bb72cade889379008bf60d436298cb0cfc6159332cb1af1de4f1d64e79c399d058ac4993704eed67917093f89db6cde830383e69aa400ba3225087cabad45407b891416330485891dc9a3875488a26428d20d581b629a8f4f42e3aa00cbcaae6c8e2b8f3fe033b874d1de6a3f8c321c92b77643f00d28e").unwrap();
129+
let kes_signature = KesSignature::from_bytes(&kes_signature_bytes).unwrap();
130+
let kes_period = 36u32;
131+
let kes_msg = hex::decode("8a1a00a50f121a0802d24458203deea82abe788d260b8987a522aadec86c9f098e88a57d7cfcdb24f474a7afb65820cad3c900ca6baee9e65bf61073d900bfbca458eeca6d0b9f9931f5b1017a8cd65820576d49e98adfab65623dc16f9fff2edd210e8dd1d4588bfaf8af250beda9d3c7825840d944b8c81000fc1182ec02194ca9eca510fd84995d22bfe1842190b39d468e5ecbd863969e0c717b0071a371f748d44c895fa9233094cefcd3107410baabb19a5850f2a29f985d37ca8eb671c2847fab9cc45c93738a430b4e43837e7f33028b190a7e55152b0e901548961a66d56eebe72d616f9e68fd13e9955ccd8611c201a5b422ac8ef56af74cb657b5b868ce9d850f1945d15820639d4986d17de3cac8079a3b25d671f339467aa3a9948e29992dafebf90f719f8458202e5823037de29647e495b97d9dd7bf739f7ebc11d3701c8d0720f55618e1b292171903e958401feeeabc7460b19370f4050e986b558b149fdc8724b4a4805af8fe45c8e7a7c6753894ad7a1b9c313da269ddc5922e150da3b378977f1dfea79fc52fd2c12f08820901").unwrap();
132+
assert!(kes_signature.verify(kes_period, &kes_pk, &kes_msg).is_ok());
133+
}
134+
}

ouroboros-crypto/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod kes;
2+
pub mod vrf;

ouroboros-crypto/src/vrf/mod.rs

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
use pallas_crypto::hash::Hash;
2+
use thiserror::Error;
3+
use vrf_dalek::vrf03::{PublicKey03, SecretKey03, VrfProof03};
4+
5+
/// error that can be returned if the verification of a [`VrfProof`] fails
6+
/// see [`VrfProof::verify`]
7+
///
8+
#[derive(Error, Debug)]
9+
#[error("VRF Proof Verification failed.")]
10+
pub struct VerificationError(
11+
#[from]
12+
#[source]
13+
vrf_dalek::errors::VrfError,
14+
);
15+
16+
pub const VRF_SEED_SIZE: usize = 32;
17+
pub const VRF_PROOF_SIZE: usize = 80;
18+
pub const VRF_PUBLIC_KEY_SIZE: usize = 32;
19+
pub const VRF_SECRET_KEY_SIZE: usize = 32;
20+
pub const VRF_PROOF_HASH_SIZE: usize = 64;
21+
22+
pub type VrfSeedBytes = [u8; VRF_SEED_SIZE];
23+
pub type VrfProofBytes = [u8; VRF_PROOF_SIZE];
24+
pub type VrfPublicKeyBytes = [u8; VRF_PUBLIC_KEY_SIZE];
25+
pub type VrfSecretKeyBytes = [u8; VRF_SECRET_KEY_SIZE];
26+
pub type VrfProofHashBytes = [u8; VRF_PROOF_HASH_SIZE];
27+
28+
// Wrapper for VRF secret key
29+
pub struct VrfSecretKey {
30+
secret_key_03: SecretKey03,
31+
}
32+
33+
// Wrapper for VRF public key
34+
pub struct VrfPublicKey {
35+
public_key_03: PublicKey03,
36+
}
37+
38+
// Wrapper for VRF proof
39+
pub struct VrfProof {
40+
proof_03: VrfProof03,
41+
}
42+
43+
// Create a VrfSecretKey from a slice
44+
impl From<&VrfSecretKeyBytes> for VrfSecretKey {
45+
fn from(slice: &VrfSecretKeyBytes) -> Self {
46+
VrfSecretKey {
47+
secret_key_03: SecretKey03::from_bytes(slice),
48+
}
49+
}
50+
}
51+
52+
// Create a VrfPublicKey from a slice
53+
impl From<&VrfPublicKeyBytes> for VrfPublicKey {
54+
fn from(slice: &VrfPublicKeyBytes) -> Self {
55+
VrfPublicKey {
56+
public_key_03: PublicKey03::from_bytes(slice),
57+
}
58+
}
59+
}
60+
61+
// Create a VrfProof from a slice
62+
impl From<&VrfProofBytes> for VrfProof {
63+
fn from(slice: &VrfProofBytes) -> Self {
64+
VrfProof {
65+
proof_03: VrfProof03::from_bytes(slice).expect("Infallible"),
66+
}
67+
}
68+
}
69+
70+
// Create a VrfPublicKey from a VrfSecretKey
71+
impl From<&VrfSecretKey> for VrfPublicKey {
72+
fn from(secret_key: &VrfSecretKey) -> Self {
73+
VrfPublicKey {
74+
public_key_03: PublicKey03::from(&secret_key.secret_key_03),
75+
}
76+
}
77+
}
78+
79+
impl VrfSecretKey {
80+
/// Sign a challenge message value with a vrf secret key and produce a proof signature
81+
pub fn prove(&self, challenge: &[u8]) -> VrfProof {
82+
let pk = PublicKey03::from(&self.secret_key_03);
83+
let proof = VrfProof03::generate(&pk, &self.secret_key_03, challenge);
84+
VrfProof { proof_03: proof }
85+
}
86+
}
87+
88+
impl VrfProof {
89+
/// Return the created proof signature
90+
pub fn signature(&self) -> [u8; VRF_PROOF_SIZE] {
91+
self.proof_03.to_bytes()
92+
}
93+
94+
/// Convert a proof signature to a hash
95+
pub fn to_hash(&self) -> Hash<VRF_PROOF_HASH_SIZE> {
96+
Hash::from(self.proof_03.proof_to_hash())
97+
}
98+
99+
/// Verify a proof signature with a vrf public key. This will return a hash to compare with the original
100+
/// signature hash, but any non-error result is considered a successful verification without needing
101+
/// to do the extra comparison check.
102+
pub fn verify(
103+
&self,
104+
public_key: &VrfPublicKey,
105+
seed: &[u8],
106+
) -> Result<Hash<VRF_PROOF_HASH_SIZE>, VerificationError> {
107+
Ok(Hash::from(
108+
self.proof_03.verify(&public_key.public_key_03, seed)?,
109+
))
110+
}
111+
}
112+
113+
#[cfg(test)]
114+
mod tests {
115+
use super::*;
116+
use rand::{thread_rng, Rng};
117+
118+
#[test]
119+
fn vrf_prove_and_verify() {
120+
// Node operational VRF-Verification-Key: pool.vrf.vkey
121+
// {
122+
// "type": "VrfVerificationKey_PraosVRF",
123+
// "description": "VRF Verification Key",
124+
// "cborHex": "5820e0ff2371508ac339431b50af7d69cde0f120d952bb876806d3136f9a7fda4381"
125+
// }
126+
//
127+
// Node operational VRF-Signing-Key: pool.vrf.skey
128+
// {
129+
// "type": "VrfSigningKey_PraosVRF",
130+
// "description": "VRF Signing Key",
131+
// "cborHex": "5840adb9c97bec60189aa90d01d113e3ef405f03477d82a94f81da926c90cd46a374e0ff2371508ac339431b50af7d69cde0f120d952bb876806d3136f9a7fda4381"
132+
// }
133+
let raw_vrf_skey: Vec<u8> = hex::decode("adb9c97bec60189aa90d01d113e3ef405f03477d82a94f81da926c90cd46a374e0ff2371508ac339431b50af7d69cde0f120d952bb876806d3136f9a7fda4381").unwrap();
134+
let raw_vrf_vkey: Vec<u8> =
135+
hex::decode("e0ff2371508ac339431b50af7d69cde0f120d952bb876806d3136f9a7fda4381")
136+
.unwrap();
137+
138+
let vrf_skey = VrfSecretKey::from(&raw_vrf_skey[..VRF_SECRET_KEY_SIZE].try_into().unwrap());
139+
let vrf_vkey =
140+
VrfPublicKey::from(&raw_vrf_vkey[..VRF_PUBLIC_KEY_SIZE].try_into().unwrap()
141+
as &[u8; VRF_PUBLIC_KEY_SIZE]);
142+
143+
let calculated_vrf_vkey = VrfPublicKey::from(&vrf_skey);
144+
assert_eq!(
145+
vrf_vkey.public_key_03.as_bytes(),
146+
calculated_vrf_vkey.public_key_03.as_bytes()
147+
);
148+
149+
// random challenge to sign with vrf_skey
150+
let mut challenge = [0u8; 64];
151+
thread_rng().fill(&mut challenge);
152+
153+
// create a proof signature and hash of the seed
154+
let proof = vrf_skey.prove(&challenge);
155+
let proof_hash = proof.to_hash();
156+
157+
// verify the proof signature with the public vrf public key
158+
let verified_hash = proof.verify(&vrf_vkey, &challenge).unwrap();
159+
assert_eq!(proof_hash, verified_hash);
160+
}
161+
}

ouroboros-praos/Cargo.toml

+7-6
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ edition = "2021"
66
[dependencies]
77
hex = "0.4"
88
ouroboros = { path = "../ouroboros" }
9-
pallas-crypto = { git = "https://github.com/txpipe/pallas", rev = "4871342a8deffaceafb5e0f771e1623dfe57e25f" }
10-
pallas-math = { git = "https://github.com/txpipe/pallas", rev = "4871342a8deffaceafb5e0f771e1623dfe57e25f" }
11-
pallas-primitives = { git = "https://github.com/txpipe/pallas", rev = "4871342a8deffaceafb5e0f771e1623dfe57e25f" }
9+
ouroboros-crypto = { path = "../ouroboros-crypto" }
10+
pallas-crypto = "0.31.0"
11+
pallas-math = "0.31.0"
12+
pallas-primitives = "0.31.0"
1213
tracing = "0.1"
13-
rayon = "1.10.0"
14+
rayon = "1.10"
1415

1516
[dev-dependencies]
1617
ctor = "0.2"
17-
insta = { version = "1.40.0", features = ["yaml"] }
18+
insta = { version = "1.41", features = ["yaml"] }
1819
mockall = "0.13"
19-
pallas-traverse = { git = "https://github.com/txpipe/pallas", rev = "4871342a8deffaceafb5e0f771e1623dfe57e25f" }
20+
pallas-traverse = "0.31.0"
2021
tracing-subscriber = "0.3"
2122
criterion = "0.5.1"
2223

ouroboros-praos/src/consensus/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use ouroboros::ledger::{issuer_vkey_to_pool_id, LedgerState, PoolId};
22
use ouroboros::validator::{ValidationError, Validator};
3-
use pallas_crypto::hash::{Hash, Hasher};
4-
use pallas_crypto::kes::{KesPublicKey, KesSignature};
5-
use pallas_crypto::key::ed25519::{PublicKey, Signature};
6-
use pallas_crypto::vrf::{
3+
use ouroboros_crypto::kes::{KesPublicKey, KesSignature};
4+
use ouroboros_crypto::vrf::{
75
VrfProof, VrfProofBytes, VrfProofHashBytes, VrfPublicKey, VrfPublicKeyBytes,
86
};
7+
use pallas_crypto::hash::{Hash, Hasher};
8+
use pallas_crypto::key::ed25519::{PublicKey, Signature};
99
use pallas_math::math::{ExpOrdering, FixedDecimal, FixedPrecision};
1010
use pallas_primitives::babbage;
1111
use pallas_primitives::babbage::{derive_tagged_vrf_output, VrfDerivation};

ouroboros/Cargo.toml

+7-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ edition = "2021"
66
[dependencies]
77
hex = "0.4.3"
88
mockall = "0.13"
9-
pallas-codec = { git = "https://github.com/txpipe/pallas", rev = "4871342a8deffaceafb5e0f771e1623dfe57e25f" }
10-
pallas-crypto = { git = "https://github.com/txpipe/pallas", rev = "4871342a8deffaceafb5e0f771e1623dfe57e25f" }
11-
thiserror = "1.0"
12-
serde = { version = "1.0.210", features = ["derive"] }
13-
async-trait = "0.1.83"
9+
pallas-codec = "0.31.0"
10+
pallas-crypto = "0.31.0"
11+
ouroboros-crypto = { path = "../ouroboros-crypto" }
12+
thiserror = "2.0"
13+
serde = { version = "1.0", features = ["derive"] }
14+
async-trait = "0.1"
1415

1516
[dev-dependencies]
16-
insta = { version = "1.40.0", features = ["yaml"] }
17+
insta = { version = "1.41", features = ["yaml"] }

0 commit comments

Comments
 (0)