mirror of
https://github.com/arnaucube/miden-crypto.git
synced 2026-01-09 15:41:30 +01:00
feat: derandomize RPO-STARK DSA (#358)
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
- [BREAKING] Updated Winterfell dependency to v0.11 (#346).
|
- [BREAKING] Updated Winterfell dependency to v0.11 (#346).
|
||||||
- Added RPO-STARK based DSA (#349).
|
- Added RPO-STARK based DSA (#349).
|
||||||
- Added benchmarks for DSA implementations (#354).
|
- Added benchmarks for DSA implementations (#354).
|
||||||
|
- Implemented deterministic RPO-STARK based DSA (#358).
|
||||||
|
|
||||||
## 0.12.0 (2024-10-30)
|
## 0.12.0 (2024-10-30)
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
|
use alloc::vec::Vec;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use prover::RpoSignatureProver;
|
use prover::RpoSignatureProver;
|
||||||
use rand::{distributions::Standard, prelude::Distribution, thread_rng, RngCore, SeedableRng};
|
|
||||||
use rand_chacha::ChaCha20Rng;
|
use rand_chacha::ChaCha20Rng;
|
||||||
use winter_crypto::{ElementHasher, Hasher, SaltedMerkleTree};
|
use winter_crypto::{ElementHasher, SaltedMerkleTree};
|
||||||
use winter_math::fields::f64::BaseElement;
|
use winter_math::fields::f64::BaseElement;
|
||||||
use winter_prover::{Proof, ProofOptions, Prover};
|
use winter_prover::{Proof, ProofOptions, Prover};
|
||||||
|
use winter_utils::Serializable;
|
||||||
use winter_verifier::{verify, AcceptableOptions, VerifierError};
|
use winter_verifier::{verify, AcceptableOptions, VerifierError};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -24,10 +25,7 @@ pub struct RpoSignatureScheme<H: ElementHasher> {
|
|||||||
_h: PhantomData<H>,
|
_h: PhantomData<H>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: ElementHasher<BaseField = BaseElement> + Sync> RpoSignatureScheme<H>
|
impl<H: ElementHasher<BaseField = BaseElement> + Sync> RpoSignatureScheme<H> {
|
||||||
where
|
|
||||||
Standard: Distribution<<H as Hasher>::Digest>,
|
|
||||||
{
|
|
||||||
pub fn new(options: ProofOptions) -> Self {
|
pub fn new(options: ProofOptions) -> Self {
|
||||||
RpoSignatureScheme { options, _h: PhantomData }
|
RpoSignatureScheme { options, _h: PhantomData }
|
||||||
}
|
}
|
||||||
@@ -40,9 +38,7 @@ where
|
|||||||
let trace = prover.build_trace(sk);
|
let trace = prover.build_trace(sk);
|
||||||
|
|
||||||
// generate the initial seed for the PRNG used for zero-knowledge
|
// generate the initial seed for the PRNG used for zero-knowledge
|
||||||
let mut seed = <ChaCha20Rng as SeedableRng>::Seed::default();
|
let seed: [u8; 32] = generate_seed(sk, msg);
|
||||||
let mut rng = thread_rng();
|
|
||||||
rng.fill_bytes(&mut seed);
|
|
||||||
|
|
||||||
// generate the proof
|
// generate the proof
|
||||||
prover.prove(trace, Some(seed)).expect("failed to generate the signature")
|
prover.prove(trace, Some(seed)).expect("failed to generate the signature")
|
||||||
@@ -67,3 +63,36 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deterministically generates a seed for seeding the PRNG used for zero-knowledge.
|
||||||
|
///
|
||||||
|
/// This uses the argument described in [RFC 6979](https://datatracker.ietf.org/doc/html/rfc6979#section-3.5)
|
||||||
|
/// § 3.5 where the concatenation of the private key and the hashed message, i.e., sk || H(m), is
|
||||||
|
/// used in order to construct the initial seed of a PRNG.
|
||||||
|
///
|
||||||
|
/// Note that we hash in also a context string in order to domain separate between different
|
||||||
|
/// instantiations of the signature scheme.
|
||||||
|
#[inline]
|
||||||
|
pub fn generate_seed(sk: [BaseElement; DIGEST_SIZE], msg: [BaseElement; DIGEST_SIZE]) -> [u8; 32] {
|
||||||
|
let context_bytes = "
|
||||||
|
Seed for PRNG used for Zero-knowledge in RPO-STARK signature scheme:
|
||||||
|
1. Version: Conjectured security
|
||||||
|
2. FRI queries: 30
|
||||||
|
3. Blowup factor: 8
|
||||||
|
4. Grinding bits: 12
|
||||||
|
5. Field extension degree: 2
|
||||||
|
6. FRI folding factor: 4
|
||||||
|
7. FRI remainder polynomial max degree: 7
|
||||||
|
"
|
||||||
|
.to_bytes();
|
||||||
|
let sk_bytes = sk.to_bytes();
|
||||||
|
let msg_bytes = msg.to_bytes();
|
||||||
|
|
||||||
|
let total_length = context_bytes.len() + sk_bytes.len() + msg_bytes.len();
|
||||||
|
let mut buffer = Vec::with_capacity(total_length);
|
||||||
|
buffer.extend_from_slice(&context_bytes);
|
||||||
|
buffer.extend_from_slice(&sk_bytes);
|
||||||
|
buffer.extend_from_slice(&msg_bytes);
|
||||||
|
|
||||||
|
blake3::hash(&buffer).into()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user