-
Notifications
You must be signed in to change notification settings - Fork 90
Add VRF support and update documentation #719
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ thiserror = "1.0" | |
| rand_core = "0.9" | ||
| serde = { version = "1.0.143", features = ["derive"] } | ||
| pallas-codec = { version = "=1.0.0-alpha.3", path = "../pallas-codec" } | ||
| cardano-crypto = { version = "=1.0.6", optional = true, features = ["vrf"] } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check cardano-crypto versions on crates.io
curl -s https://crates.io/api/v1/crates/cardano-crypto | jq '.versions[] | select(.num | test("1\\.0")) | {num, created_at, yanked}' | head -50Repository: txpipe/pallas Length of output: 665 🏁 Script executed: #!/bin/bash
# Get summary info about cardano-crypto crate
curl -s https://crates.io/api/v1/crates/cardano-crypto | jq '.crate | {name, max_version, documentation}'Repository: txpipe/pallas Length of output: 166 🏁 Script executed: #!/bin/bash
# Search for any security advisories or issues with cardano-crypto
curl -s https://rustsec.org/advisory.json | jq '.[] | select(.crate.name == "cardano-crypto") | {id, crate, title, date}'Repository: txpipe/pallas Length of output: 114 🌐 Web query:
💡 Result: I couldn't find any published security advisory or CVE specifically for cardano-crypto 1.0.6. The package pages I checked (Hackage and docs.rs) show the cardano-crypto project but contain no vulnerability advisory for 1.0.6. [1][2] If you want, I can:
Sources:
Review the rationale for exact version pinning on cardano-crypto. Version 1.0.6 exists, is the latest available, and has no known security advisories. However, the exact version constraint 🤖 Prompt for AI Agents |
||
|
|
||
| # kes dependencies | ||
| rand = { version = "0.9", optional = true } | ||
|
|
@@ -42,6 +43,7 @@ default = [] | |
| sk_clone_enabled = [] | ||
| kes = ["rand", "rand_chacha", "serde_with", "ed25519-dalek", "zeroize"] | ||
| relaxed = [] | ||
| vrf = ["cardano-crypto/vrf"] | ||
|
|
||
| [[bench]] | ||
| harness = false | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Seeds for failure cases proptest has generated in the past. It is | ||
| # automatically read and these particular cases re-run before any | ||
| # novel cases are generated. | ||
| # | ||
| # It is recommended to check this file in to source control so that | ||
| # everyone who runs the test benefits from these saved cases. | ||
| cc a80811a55e353e6c0a9e2fb8bcc9331942c135baf17fea40c45b258aaa926c09 # shrinks to ((mut sk_bytes,pk),msg1,msg2) = (([118, 121, 140, 51, 101, 51, 163, 103, 235, 28, 143, 46, 23, 39, 102, 159, 3, 166, 178, 183, 145, 159, 199, 149, 221, 188, 177, 156, 251, 0, 120, 48, 26, 41, 81, 47, 50, 158, 95, 189, 47, 46, 196, 91, 131, 108, 2, 69, 219, 255, 46, 128, 103, 108, 82, 236, 55, 105, 210, 57, 189, 70, 145, 169, 196, 71, 254, 141, 70, 197, 189, 242, 7, 216, 170, 28, 166, 128, 195, 49, 110, 62, 186, 177, 58, 103, 6, 164, 62, 56, 83, 82, 19, 166, 0, 156, 51, 17, 32, 79, 87, 94, 90, 106, 181, 195, 124, 188, 72, 148, 114, 132, 89, 83, 191, 241, 63, 78, 85, 37, 245, 98, 65, 169, 129, 108, 136, 138, 227, 102, 43, 118, 77, 163, 227, 112, 111, 204, 101, 26, 132, 181, 91, 131, 95, 211, 240, 225, 115, 131, 210, 195, 222, 146, 15, 227, 58, 62, 69, 23, 92, 184, 60, 255, 172, 115, 30, 174, 92, 25, 25, 10, 40, 23, 228, 203, 28, 162, 69, 142, 77, 128, 68, 70, 134, 253, 221, 13, 45, 94, 115, 0, 166, 116, 181, 77, 120, 117, 36, 43, 166, 150, 140, 27, 108, 4, 184, 88, 27, 66, 119, 83, 102, 46, 190, 150, 165, 223, 56, 55, 50, 237, 91, 240, 137, 156, 122, 26, 49, 15, 29, 121, 240, 215, 65, 111, 191, 183, 200, 195, 53, 46, 187, 218, 178, 24, 56, 96, 21, 143, 122, 149, 50, 193, 122, 142, 192, 181, 155, 199, 52, 67, 29, 6, 215, 250, 215, 137, 227, 42, 248, 102, 118, 247, 59, 254, 229, 1, 134, 60, 234, 80, 210, 235, 252, 36, 99, 68, 101, 170, 146, 97, 6, 6, 6, 8, 71, 251, 64, 179, 144, 98, 170, 131, 152, 111, 252, 127, 150, 161, 80, 99, 224, 46, 25, 173, 170, 30, 13, 146, 50, 51, 155, 190, 232, 53, 157, 79, 209, 109, 188, 2, 37, 8, 75, 19, 46, 248, 55, 97, 19, 212, 93, 101, 5, 41, 197, 211, 117, 220, 28, 10, 230, 84, 248, 143, 30, 254, 217, 46, 235, 222, 52, 72, 247, 200, 114, 220, 48, 96, 222, 97, 126, 187, 52, 197, 89, 159, 105, 244, 8, 31, 121, 106, 94, 182, 48, 63, 193, 12, 250, 28, 93, 73, 235, 141, 218, 11, 190, 114, 29, 94, 16, 184, 88, 218, 174, 195, 109, 171, 3, 198, 76, 215, 3, 193, 74, 212, 49, 128, 2, 99, 132, 165, 11, 107, 152, 165, 64, 4, 248, 95, 122, 88, 142, 35, 184, 216, 181, 92, 188, 74, 42, 2, 116, 113, 168, 155, 246, 221, 110, 206, 41, 26, 247, 173, 26, 154, 132, 215, 31, 96, 184, 163, 125, 27, 100, 7, 205, 65, 160, 111, 123, 166, 4, 10, 112, 94, 185, 249, 201, 76, 248, 194, 123, 81, 226, 130, 128, 139, 72, 235, 214, 229, 222, 86, 247, 76, 249, 76, 108, 243, 242, 249, 136, 25, 130, 65, 102, 240, 24, 89, 118, 111, 138, 76, 90, 115, 25, 128, 20, 233, 207, 172, 30, 210, 124, 94, 254, 143, 172, 205, 186, 45, 228, 77, 247, 91, 171, 180, 204, 201, 221, 214, 119, 144, 27, 239, 128, 22, 52, 169, 231, 58, 209, 94, 15, 76, 65, 213, 60, 253, 166, 101, 7, 83, 225, 251, 95, 198, 184, 65, 33, 52, 106, 110, 190, 165, 83, 46, 152, 181, 18, 232, 101, 90, 154, 191, 9, 3, 213, 99, 48, 208, 136, 233, 142, 21, 72, 14, 124, 213, 191, 4, 13, 140, 19, 71, 0, 0, 0, 0], PublicKey([220, 226, 205, 176, 140, 133, 89, 107, 176, 150, 130, 165, 8, 119, 148, 63, 96, 138, 43, 31, 154, 151, 32, 236, 113, 152, 197, 198, 142, 158, 38, 162])), [], []) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,3 +5,5 @@ pub mod kes; | |
| pub mod key; | ||
| pub mod memsec; | ||
| pub mod nonce; | ||
| #[cfg(feature = "vrf")] | ||
| pub mod vrf; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,101 @@ | ||||||||||||||||||||||||||||
| //! Verifiable Random Functions (VRF) bindings | ||||||||||||||||||||||||||||
| //! | ||||||||||||||||||||||||||||
| //! This module re-exports Cardano-compatible VRF primitives from the `cardano-crypto` | ||||||||||||||||||||||||||||
| //! crate so downstream users can generate proofs and verify outputs for both | ||||||||||||||||||||||||||||
| //! draft-03 (Cardano standard) and draft-13 variants. | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| use cardano_crypto::common::{CryptoError, CryptoResult}; | ||||||||||||||||||||||||||||
| use cardano_crypto::vrf::CertifiedVrf; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| pub use cardano_crypto::vrf::{ | ||||||||||||||||||||||||||||
| cardano_compat::cardano_vrf_prove as prove_cardano, | ||||||||||||||||||||||||||||
| cardano_compat::cardano_vrf_verify as verify_cardano, CertifiedVrf as CertifiedOutput, | ||||||||||||||||||||||||||||
| OutputVrf as Output, VrfDraft03, VrfDraft13, VrfKeyPair, VrfProof, VrfSigningKey, | ||||||||||||||||||||||||||||
| VrfVerificationKey, DRAFT03_PROOF_SIZE, DRAFT13_PROOF_SIZE, OUTPUT_SIZE, PUBLIC_KEY_SIZE, | ||||||||||||||||||||||||||||
| SECRET_KEY_SIZE, SEED_SIZE, | ||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /// Generate a draft-03 keypair from a 32-byte seed. | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| /// Generate a draft-03 keypair from a 32-byte seed. | |
| /// Generate a VRF keypair from a 32-byte seed. | |
| /// | |
| /// The generated keypair is compatible with both draft-03 (Cardano standard) and draft-13 VRF variants. |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function name 'keypair_from_seed' is specific to draft-03. Consider renaming to 'keypair_from_seed_draft03' or documenting that it specifically generates draft-03 keypairs, especially since this module supports both draft-03 and draft-13 variants.
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test coverage for convenience wrapper functions. The module includes certify_draft03 and verify_certified functions that lack test coverage. Consider adding tests for these functions to ensure they work correctly, especially since they're part of the public API.
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent return types between draft-03 and draft-13 prove functions. The prove_draft03 function returns a VrfProof, while prove_draft13 returns a raw array [u8; PROOF_SIZE]. Consider making these consistent by either having both return typed wrappers (like VrfProof) or both return raw arrays for consistency in the API.
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type aliases lack documentation comments. The Error and Result type aliases should include doc comments explaining that they're aliases for CryptoError and CryptoResult from the cardano-crypto crate, to help users understand the error types they'll encounter when using this API.
| /// Error type alias for VRF operations. | |
| pub type Error = CryptoError; | |
| /// Result type alias for VRF operations. | |
| /// Error type alias for VRF operations. | |
| /// | |
| /// This is an alias for [`CryptoError`] from the [`cardano-crypto`] crate, | |
| /// representing errors that can occur during VRF operations in this API. | |
| pub type Error = CryptoError; | |
| /// Result type alias for VRF operations. | |
| /// | |
| /// This is an alias for [`CryptoResult`] from the [`cardano-crypto`] crate, | |
| /// representing the result of VRF operations in this API. |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type aliases should be declared near the top of the module, not at the end. According to Rust conventions, type aliases should appear early in the module, typically after imports and before function definitions, to improve readability and discoverability.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,68 @@ | ||||||||||||||||||||||||||
| #![cfg(feature = "kes")] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| use pallas_crypto::kes::summed_kes::Sum6Kes; | ||||||||||||||||||||||||||
| use pallas_crypto::kes::traits::{KesSig, KesSk}; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||
| fn sum6_total_periods_and_roundtrip() { | ||||||||||||||||||||||||||
| let mut key_bytes = [0u8; Sum6Kes::SIZE + 4]; | ||||||||||||||||||||||||||
| let mut seed = [0x46u8; 32]; | ||||||||||||||||||||||||||
| let (mut sk, vk) = Sum6Kes::keygen(&mut key_bytes, &mut seed); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // sign at period 0 | ||||||||||||||||||||||||||
| let msg0 = b"Sum6 period 0"; | ||||||||||||||||||||||||||
| let sig0 = sk.sign(msg0); | ||||||||||||||||||||||||||
| sig0.verify(sk.get_period(), &vk, msg0).expect("verify p0"); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // evolve to final period and sign | ||||||||||||||||||||||||||
| for _ in 0..63 { | ||||||||||||||||||||||||||
| sk.update().expect("evolve"); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| assert_eq!(sk.get_period(), 63); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| let msg_last = b"Sum6 period 63"; | ||||||||||||||||||||||||||
| let sig_last = sk.sign(msg_last); | ||||||||||||||||||||||||||
| sig_last.verify(63, &vk, msg_last).expect("verify p63"); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // adjacent periods should fail | ||||||||||||||||||||||||||
| assert!(sig_last.verify(62, &vk, msg_last).is_err()); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||
| fn sum6_verification_key_stability() { | ||||||||||||||||||||||||||
| let mut key_bytes = [0u8; Sum6Kes::SIZE + 4]; | ||||||||||||||||||||||||||
| let mut seed = [0x99u8; 32]; | ||||||||||||||||||||||||||
| let (mut sk, vk0) = Sum6Kes::keygen(&mut key_bytes, &mut seed); | ||||||||||||||||||||||||||
| let vk0_bytes = vk0.as_bytes().to_vec(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| for period in 0..10 { | ||||||||||||||||||||||||||
| let vk_bytes = sk.to_pk().as_bytes().to_vec(); | ||||||||||||||||||||||||||
| assert_eq!( | ||||||||||||||||||||||||||
| vk0_bytes, vk_bytes, | ||||||||||||||||||||||||||
| "vkey must stay stable at period {period}" | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| if period < 9 { | ||||||||||||||||||||||||||
| sk.update().expect("evolve"); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| #[test] | ||||||||||||||||||||||||||
| fn sum6_deterministic_from_seed() { | ||||||||||||||||||||||||||
| let seed = [0xCCu8; 32]; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| let mut key_bytes1 = [0u8; Sum6Kes::SIZE + 4]; | ||||||||||||||||||||||||||
| let mut seed1 = seed.clone(); | ||||||||||||||||||||||||||
| let (sk1, vk1) = Sum6Kes::keygen(&mut key_bytes1, &mut seed1); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| let mut key_bytes2 = [0u8; Sum6Kes::SIZE + 4]; | ||||||||||||||||||||||||||
| let mut seed2 = seed.clone(); | ||||||||||||||||||||||||||
|
Comment on lines
+55
to
+59
|
||||||||||||||||||||||||||
| let mut seed1 = seed.clone(); | |
| let (sk1, vk1) = Sum6Kes::keygen(&mut key_bytes1, &mut seed1); | |
| let mut key_bytes2 = [0u8; Sum6Kes::SIZE + 4]; | |
| let mut seed2 = seed.clone(); | |
| let mut seed1 = seed; | |
| let (sk1, vk1) = Sum6Kes::keygen(&mut key_bytes1, &mut seed1); | |
| let mut key_bytes2 = [0u8; Sum6Kes::SIZE + 4]; | |
| let mut seed2 = seed; |
Copilot
AI
Dec 13, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary clone of a Copy type. Arrays implement Copy, so cloning is not needed. Simply assign the value directly.
| let mut seed2 = seed.clone(); | |
| let mut seed2 = seed; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| #![cfg(feature = "vrf")] | ||
|
|
||
| use pallas_crypto::vrf::{keypair_from_seed, verify_draft03, VrfDraft03}; | ||
|
|
||
| fn hex_decode(s: &str) -> Vec<u8> { | ||
| (0..s.len()) | ||
| .step_by(2) | ||
| .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap()) | ||
| .collect() | ||
| } | ||
|
|
||
| #[test] | ||
| fn draft03_ietf_vector_10() { | ||
| // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-03#appendix-A.1 | ||
| let sk_seed = hex_decode("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"); | ||
| let expected_pk = | ||
| hex_decode("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"); | ||
| let expected_pi = hex_decode(concat!( | ||
| "b6b4699f87d56126c9117a7da55bd0085246f4c56dbc95d20172612e9d38e8d7", | ||
| "ca65e573a126ed88d4e30a46f80a666854d675cf3ba81de0de043c3774f06156", | ||
| "0f55edc256a787afe701677c0f602900", | ||
| )); | ||
| let expected_beta = hex_decode(concat!( | ||
| "5b49b554d05c0cd5a5325376b3387de59d924fd1e13ded44648ab33c21349a60", | ||
| "3f25b84ec5ed887995b33da5e3bfcb87cd2f64521c4c62cf825cffabbe5d31cc", | ||
| )); | ||
|
|
||
| let seed: [u8; 32] = sk_seed.try_into().unwrap(); | ||
| let (sk, pk) = VrfDraft03::keypair_from_seed(&seed); | ||
|
|
||
| assert_eq!(pk.as_slice(), expected_pk.as_slice()); | ||
|
|
||
| let proof = VrfDraft03::prove(&sk, &[]).expect("prove"); | ||
| assert_eq!(proof.as_slice(), expected_pi.as_slice()); | ||
|
|
||
| let beta = VrfDraft03::verify(&pk, &proof, &[]).expect("verify"); | ||
| assert_eq!(beta.as_slice(), expected_beta.as_slice()); | ||
|
|
||
| let beta2 = VrfDraft03::proof_to_hash(&proof).expect("proof_to_hash"); | ||
| assert_eq!(beta, beta2); | ||
| } | ||
|
|
||
| #[test] | ||
| fn draft03_ietf_vector_11() { | ||
| let sk_seed = hex_decode("4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb"); | ||
| let expected_pk = | ||
| hex_decode("3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"); | ||
| let alpha = hex_decode("72"); | ||
| let expected_pi = hex_decode("ae5b66bdf04b4c010bfe32b2fc126ead2107b697634f6f7337b9bff8785ee111200095ece87dde4dbe87343f6df3b107d91798c8a7eb1245d3bb9c5aafb093358c13e6ae1111a55717e895fd15f99f07"); | ||
| let expected_beta = hex_decode(concat!( | ||
| "94f4487e1b2fec954309ef1289ecb2e15043a2461ecc7b2ae7d4470607ef82eb", | ||
| "1cfa97d84991fe4a7bfdfd715606bc27e2967a6c557cfb5875879b671740b7d8", | ||
| )); | ||
|
|
||
| let seed: [u8; 32] = sk_seed.try_into().unwrap(); | ||
| let (sk, pk) = VrfDraft03::keypair_from_seed(&seed); | ||
|
|
||
| assert_eq!(pk.as_slice(), expected_pk.as_slice()); | ||
|
|
||
| let proof = VrfDraft03::prove(&sk, &alpha).expect("prove"); | ||
| assert_eq!( | ||
| proof.as_slice().len(), | ||
| pallas_crypto::vrf::DRAFT03_PROOF_SIZE | ||
| ); | ||
| assert_eq!(proof.as_slice(), expected_pi.as_slice()); | ||
|
|
||
| let beta = VrfDraft03::verify(&pk, &proof, &alpha).expect("verify"); | ||
| assert_eq!(beta.as_slice().len(), pallas_crypto::vrf::OUTPUT_SIZE); | ||
| assert_eq!(beta.as_slice(), expected_beta.as_slice()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn draft03_ietf_vector_12() { | ||
| let sk_seed = hex_decode("c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"); | ||
| let expected_pk = | ||
| hex_decode("fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"); | ||
| let alpha = hex_decode("af82"); | ||
| let expected_pi = hex_decode(concat!( | ||
| "dfa2cba34b611cc8c833a6ea83b8eb1bb5e2ef2dd1b0c481bc42ff36ae7847f6", | ||
| "ab52b976cfd5def172fa412defde270c8b8bdfbaae1c7ece17d9833b1bcf3106", | ||
| "4fff78ef493f820055b561ece45e1009", | ||
| )); | ||
| let expected_beta = hex_decode(concat!( | ||
| "2031837f582cd17a9af9e0c7ef5a6540e3453ed894b62c293686ca3c1e319dde", | ||
| "9d0aa489a4b59a9594fc2328bc3deff3c8a0929a369a72b1180a596e016b5ded", | ||
| )); | ||
|
|
||
| let seed: [u8; 32] = sk_seed.try_into().unwrap(); | ||
| let (sk, pk) = VrfDraft03::keypair_from_seed(&seed); | ||
|
|
||
| assert_eq!(pk.as_slice(), expected_pk.as_slice()); | ||
|
|
||
| let proof = VrfDraft03::prove(&sk, &alpha).expect("prove"); | ||
| assert_eq!(proof.as_slice(), expected_pi.as_slice()); | ||
|
|
||
| let beta = VrfDraft03::verify(&pk, &proof, &alpha).expect("verify"); | ||
| assert_eq!(beta.as_slice(), expected_beta.as_slice()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn draft03_cardano_messages() { | ||
| let seed = [0x42u8; 32]; | ||
| let kp = keypair_from_seed(&seed); | ||
| let messages: &[&[u8]] = &[ | ||
| b"Block header hash", | ||
| b"Epoch nonce derivation", | ||
| b"Leader election slot 12345", | ||
| &[0u8; 64], | ||
| &[], | ||
| ]; | ||
|
|
||
| for msg in messages { | ||
| let (proof, out1) = pallas_crypto::vrf::prove_draft03(&kp.signing_key, msg).expect("prove"); | ||
| let out2 = verify_draft03(&kp.verification_key, &proof, msg).expect("verify"); | ||
| assert_eq!(out1.as_bytes(), out2.as_bytes()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using exact version match for dependency. The cardano-crypto dependency uses '=1.0.6' which requires an exact version match. While this ensures reproducibility, it may cause issues when other crates in the dependency tree need a different patch version of the same major.minor version. Consider using '^1.0.6' (caret requirements) or '~1.0.6' (tilde requirements) to allow compatible patch updates while maintaining stability.