Skip to content

Commit dae729b

Browse files
committed
RingVerifier fromm VerifierKey
1 parent c99ee40 commit dae729b

File tree

3 files changed

+63
-24
lines changed

3 files changed

+63
-24
lines changed

Cargo.toml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,25 @@ serde_json = "1.0"
3434
indexmap = { version = "2.2.6", features = ["serde"] }
3535

3636
[features]
37-
default = [ "std" ]
37+
default = [ "std", "ring" ]
3838
std = [
3939
"ark-std/std",
4040
"ark-ec/std",
4141
"ring-proof?/std",
4242
]
43+
full = [
44+
"secp256r1",
45+
"ed25519",
46+
"bandersnatch",
47+
"ring",
48+
]
4349
# Curves
4450
ed25519 = [ "ark-ed25519" ]
4551
bandersnatch = [ "ark-ed-on-bls12-381-bandersnatch", "ark-bls12-381/curve" ]
4652
secp256r1 = [ "ark-secp256r1", "rfc-6979" ]
4753
# Miscellanea
4854
ring = [ "ring-proof" ]
4955
rfc-6979 = [ "hmac" ]
50-
full = [
51-
"secp256r1",
52-
"ed25519",
53-
"bandersnatch",
54-
"ring",
55-
]
5656
# Optimizations
5757
parallel = [
5858
"ark-ec/parallel",
@@ -64,3 +64,6 @@ parallel = [
6464
asm = [ "ark-ff/asm", "ring-proof?/asm" ]
6565
# Deterministic, no-zk, ring-proof (unsafe)
6666
test-vectors = [ "ring-proof?/test-vectors" ]
67+
68+
[package.metadata.docs.rs]
69+
features = [ "full" ]

src/ring.rs

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,11 @@ where
175175
piop_params: PiopParams<S>,
176176
}
177177

178-
// Evaluation domain size required for the given ring size.
178+
/// Evaluation domain size required for the given ring size.
179+
///
180+
/// This determines the size of the [PcsParams] required to construct.
179181
#[inline(always)]
180-
fn domain_size<S: RingSuite>(ring_size: usize) -> usize
182+
pub fn domain_size<S: RingSuite>(ring_size: usize) -> usize
181183
where
182184
BaseField<S>: ark_ff::PrimeField,
183185
CurveConfig<S>: TECurveConfig + Clone,
@@ -186,6 +188,20 @@ where
186188
1 << ark_std::log2(ring_size + ScalarField::<S>::MODULUS_BIT_SIZE as usize + 4)
187189
}
188190

191+
fn piop_params<S: RingSuite>(domain_size: usize) -> PiopParams<S>
192+
where
193+
BaseField<S>: ark_ff::PrimeField,
194+
CurveConfig<S>: TECurveConfig + Clone,
195+
AffinePoint<S>: TEMapping<CurveConfig<S>>,
196+
{
197+
PiopParams::<S>::setup(
198+
ring_proof::Domain::new(domain_size, true),
199+
S::BLINDING_BASE.into_te(),
200+
S::ACCUMULATOR_BASE.into_te(),
201+
S::PADDING.into_te(),
202+
)
203+
}
204+
189205
#[allow(private_bounds)]
190206
impl<S: RingSuite> RingContext<S>
191207
where
@@ -194,40 +210,39 @@ where
194210
AffinePoint<S>: TEMapping<CurveConfig<S>>,
195211
{
196212
/// Construct a new ring context suitable to manage the given ring size.
213+
///
214+
/// Calls into [`RingContext::from_rand`] with a `ChaCha20Rng` seeded with `seed`.
197215
pub fn from_seed(ring_size: usize, seed: [u8; 32]) -> Self {
198216
use ark_std::rand::SeedableRng;
199217
let mut rng = rand_chacha::ChaCha20Rng::from_seed(seed);
200218
Self::from_rand(ring_size, &mut rng)
201219
}
202220

203221
/// Construct a new random ring context suitable for the given ring size.
222+
///
223+
/// Calls into [`RingContext::from_srs`] with a randomly generated [`PcsParams`]
224+
/// large enough to be used with the given `ring_size`.
204225
pub fn from_rand(ring_size: usize, rng: &mut impl ark_std::rand::RngCore) -> Self {
205226
use ring_proof::pcs::PCS;
206227
let domain_size = domain_size::<S>(ring_size);
207228
let pcs_params = Pcs::<S>::setup(3 * domain_size, rng);
208229
Self::from_srs(ring_size, pcs_params).expect("PCS params is correct")
209230
}
210231

232+
/// Construct a new random ring context suitable for the given [`PcsParams`].
233+
///
234+
/// Fails if `PcsParams` are not
211235
pub fn from_srs(ring_size: usize, mut pcs_params: PcsParams<S>) -> Result<Self, Error> {
212236
let domain_size = domain_size::<S>(ring_size);
213-
if pcs_params.powers_in_g1.len() < 3 * domain_size + 1 || pcs_params.powers_in_g2.len() < 2
214-
{
237+
if pcs_params.powers_in_g1.len() <= 3 * domain_size || pcs_params.powers_in_g2.len() < 2 {
215238
return Err(Error::InvalidData);
216239
}
217240
// Keep only the required powers of tau.
218241
pcs_params.powers_in_g1.truncate(3 * domain_size + 1);
219242
pcs_params.powers_in_g2.truncate(2);
220-
221-
let piop_params = PiopParams::<S>::setup(
222-
ring_proof::Domain::new(domain_size, true),
223-
S::BLINDING_BASE.into_te(),
224-
S::ACCUMULATOR_BASE.into_te(),
225-
S::PADDING.into_te(),
226-
);
227-
228243
Ok(Self {
229244
pcs_params,
230-
piop_params,
245+
piop_params: piop_params::<S>(domain_size),
231246
})
232247
}
233248

@@ -286,7 +301,25 @@ where
286301
)
287302
}
288303

304+
/// Constructs a `RingVerifier` from a `VerifierKey` without a `RingContext` instance.
305+
///
306+
/// While this approach is slightly less efficient than using a pre-constructed `RingContext`,
307+
/// as some parameters need to be computed on-the-fly, it is beneficial in memory or
308+
/// storage constrained environments. This avoids the need to retain the full `RingContext` for
309+
/// ring signature verification. Instead, the `VerifierKey` contains only the essential information
310+
/// needed to verify ring proofs.
311+
pub fn verifier_no_context(verifier_key: VerifierKey<S>, ring_size: usize) -> RingVerifier<S> {
312+
RingVerifier::<S>::init(
313+
verifier_key,
314+
piop_params::<S>(domain_size::<S>(ring_size)),
315+
ring_proof::ArkTranscript::new(S::SUITE_ID),
316+
)
317+
}
318+
289319
/// Get the padding point.
320+
///
321+
/// This is a point of unknown dlog that can be used to replace of any key during
322+
/// ring construciton.
290323
#[inline(always)]
291324
pub const fn padding_point() -> AffinePoint<S> {
292325
S::PADDING
@@ -304,8 +337,7 @@ where
304337
mut writer: W,
305338
compress: ark_serialize::Compress,
306339
) -> Result<(), ark_serialize::SerializationError> {
307-
self.pcs_params.serialize_with_mode(&mut writer, compress)?;
308-
Ok(())
340+
self.pcs_params.serialize_with_mode(&mut writer, compress)
309341
}
310342

311343
fn serialized_size(&self, compress: ark_serialize::Compress) -> usize {
@@ -330,8 +362,10 @@ where
330362
validate,
331363
)?;
332364
let domain_size = (pcs_params.powers_in_g1.len() - 1) / 3;
333-
Self::from_srs(domain_size, pcs_params)
334-
.map_err(|_| ark_serialize::SerializationError::InvalidData)
365+
Ok(Self {
366+
pcs_params,
367+
piop_params: piop_params::<S>(domain_size),
368+
})
335369
}
336370
}
337371

src/suites/bandersnatch.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,13 @@ pub mod te {
164164
};
165165
}
166166

167+
// TODO @davxy: make module public and rename to just `ring`
167168
#[cfg(feature = "ring")]
168169
mod ring_defs {
169170
use super::*;
170171
use crate::ring as ring_suite;
171172

173+
// TODO @davxy : introduce `ring_suite_types!` macro
172174
pub type PcsParams = ring_suite::PcsParams<BandersnatchSha512Ell2>;
173175
pub type RingContext = ring_suite::RingContext<BandersnatchSha512Ell2>;
174176
pub type RingCommitment = ring_suite::RingCommitment<BandersnatchSha512Ell2>;

0 commit comments

Comments
 (0)