mirror of
https://github.com/arnaucube/miden-crypto.git
synced 2026-01-08 23:21: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).
|
||||
- Added RPO-STARK based DSA (#349).
|
||||
- Added benchmarks for DSA implementations (#354).
|
||||
- Implemented deterministic RPO-STARK based DSA (#358).
|
||||
|
||||
## 0.12.0 (2024-10-30)
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use prover::RpoSignatureProver;
|
||||
use rand::{distributions::Standard, prelude::Distribution, thread_rng, RngCore, SeedableRng};
|
||||
use rand_chacha::ChaCha20Rng;
|
||||
use winter_crypto::{ElementHasher, Hasher, SaltedMerkleTree};
|
||||
use winter_crypto::{ElementHasher, SaltedMerkleTree};
|
||||
use winter_math::fields::f64::BaseElement;
|
||||
use winter_prover::{Proof, ProofOptions, Prover};
|
||||
use winter_utils::Serializable;
|
||||
use winter_verifier::{verify, AcceptableOptions, VerifierError};
|
||||
|
||||
use crate::{
|
||||
@@ -24,10 +25,7 @@ pub struct RpoSignatureScheme<H: ElementHasher> {
|
||||
_h: PhantomData<H>,
|
||||
}
|
||||
|
||||
impl<H: ElementHasher<BaseField = BaseElement> + Sync> RpoSignatureScheme<H>
|
||||
where
|
||||
Standard: Distribution<<H as Hasher>::Digest>,
|
||||
{
|
||||
impl<H: ElementHasher<BaseField = BaseElement> + Sync> RpoSignatureScheme<H> {
|
||||
pub fn new(options: ProofOptions) -> Self {
|
||||
RpoSignatureScheme { options, _h: PhantomData }
|
||||
}
|
||||
@@ -40,9 +38,7 @@ where
|
||||
let trace = prover.build_trace(sk);
|
||||
|
||||
// generate the initial seed for the PRNG used for zero-knowledge
|
||||
let mut seed = <ChaCha20Rng as SeedableRng>::Seed::default();
|
||||
let mut rng = thread_rng();
|
||||
rng.fill_bytes(&mut seed);
|
||||
let seed: [u8; 32] = generate_seed(sk, msg);
|
||||
|
||||
// generate the proof
|
||||
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