Browse Source

feat: derandomize RPO-STARK DSA (#358)

rpo-dsa
Al-Kindi-0 3 months ago
committed by GitHub
parent
commit
d2a6739605
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 9 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +38
    -9
      src/dsa/rpo_stark/stark/mod.rs

+ 1
- 0
CHANGELOG.md

@ -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)

+ 38
- 9
src/dsa/rpo_stark/stark/mod.rs

@ -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: PhantomData<H>, _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 { 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 mut rng = thread_rng();
rng.fill_bytes(&mut seed);
let seed: [u8; 32] = generate_seed(sk, msg);
// 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()
}

Loading…
Cancel
Save