Skip to content

Commit 144da97

Browse files
olegnnlovesh
authored andcommitted
Refactor PoKOfSignatureG1Protocol::init
1 parent fc97fb9 commit 144da97

File tree

15 files changed

+284
-202
lines changed

15 files changed

+284
-202
lines changed

bbs_plus/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bbs_plus"
3-
version = "0.11.0"
3+
version = "0.12.0"
44
edition.workspace = true
55
authors.workspace = true
66
license.workspace = true
@@ -18,6 +18,7 @@ ark-ec.workspace = true
1818
ark-std.workspace = true
1919
digest.workspace = true
2020
rayon = {workspace = true, optional = true}
21+
itertools = "0.10.5"
2122
schnorr_pok = { version = "0.9.0", default-features = false, path = "../schnorr_pok" }
2223
dock_crypto_utils = { version = "0.9.0", default-features = false, path = "../utils" }
2324
serde.workspace = true

bbs_plus/src/error.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
use ark_serialize::SerializationError;
44
use ark_std::fmt::Debug;
5-
use dock_crypto_utils::serde_utils::ArkSerializationError;
5+
use dock_crypto_utils::{
6+
serde_utils::ArkSerializationError,
7+
try_iter::{IndexIsOutOfBounds, InvalidPair},
8+
};
69
use schnorr_pok::error::SchnorrError;
710
use serde::Serialize;
811

@@ -11,7 +14,6 @@ pub enum BBSPlusError {
1114
CannotInvert0,
1215
NoMessageToSign,
1316
MessageCountIncompatibleWithSigParams(usize, usize),
14-
InvalidMessageIdx(usize),
1517
/// Signature's `A` is 0
1618
ZeroSignature,
1719
InvalidSignature,
@@ -25,6 +27,8 @@ pub enum BBSPlusError {
2527
#[serde(with = "ArkSerializationError")]
2628
Serialization(SerializationError),
2729
SchnorrError(SchnorrError),
30+
MessageIndicesMustBeUniqueAndSorted(InvalidPair<usize>),
31+
MessageIndexIsOutOfBounds(IndexIsOutOfBounds),
2832
}
2933

3034
impl From<SchnorrError> for BBSPlusError {
@@ -33,6 +37,18 @@ impl From<SchnorrError> for BBSPlusError {
3337
}
3438
}
3539

40+
impl<T> From<InvalidPair<(usize, T)>> for BBSPlusError {
41+
fn from(err: InvalidPair<(usize, T)>) -> Self {
42+
Self::MessageIndicesMustBeUniqueAndSorted(err.map(|(idx, _)| idx))
43+
}
44+
}
45+
46+
impl From<IndexIsOutOfBounds> for BBSPlusError {
47+
fn from(err: IndexIsOutOfBounds) -> Self {
48+
Self::MessageIndexIsOutOfBounds(err)
49+
}
50+
}
51+
3652
impl From<SerializationError> for BBSPlusError {
3753
fn from(e: SerializationError) -> Self {
3854
Self::Serialization(e)

bbs_plus/src/proof.rs

Lines changed: 106 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ use ark_std::{
7171
vec::Vec,
7272
One, UniformRand,
7373
};
74+
use dock_crypto_utils::extend_some::ExtendSome;
7475
use dock_crypto_utils::randomized_pairing_check::RandomizedPairingChecker;
75-
use dock_crypto_utils::serde_utils::*;
76+
use dock_crypto_utils::{misc::rand, serde_utils::*};
77+
use itertools::multiunzip;
7678
use schnorr_pok::{error::SchnorrError, SchnorrCommitment, SchnorrResponse};
7779
use serde::{Deserialize, Serialize};
7880
use serde_with::serde_as;
@@ -131,58 +133,57 @@ pub struct PoKOfSignatureG1Proof<E: Pairing> {
131133
pub sc_resp_2: SchnorrResponse<E::G1Affine>,
132134
}
133135

136+
/// Each message can be either randomly blinded, unblinded, or blinded using supplied blinding.
137+
/// By default, a message is blinded with random blinding.
138+
pub enum MessageOrBlinding<'a, P: PrimeField> {
139+
/// Message will be blinded using random blinding.
140+
BlindMessageRandomly(&'a P),
141+
/// Message will be revealed, and thus won't be included in PoK.
142+
RevealMessage(&'a P),
143+
/// Message will be blinded using the supplied blinding.
144+
BlindMessageWithConcreteBlinding { message: &'a P, blinding: P },
145+
}
146+
134147
impl<E: Pairing> PoKOfSignatureG1Protocol<E> {
135148
/// Initiate the protocol, i.e. pre-challenge phase. This will generate the randomized signature and execute
136-
/// the commit-to-randomness step (Step 1) of both Schnorr protocols. Accepts the indices of the
137-
/// multi-message which are revealed to the verifier and thus their knowledge is not proven.
138-
/// Accepts blindings (randomness) to be used for any messages in the multi-message. This is useful
139-
/// when some messages need to be proven to be the same as they will generate the same response (step 3 in
140-
/// Schnorr protocol). If extra blindings are passed, or passed for revealed messages, they are ignored.
141-
/// eg. If the multi-message is `[m_0, m_1, m_2, m_3, m_4]` and the user provides blindings for messages
142-
/// `m_0` and `m_2` and revealing messages `m_1`, `m_3` and `m_4`, `blindings` is `(0 -> m_0), (2 -> m_2)`
143-
/// and `revealed_msg_indices` is `(1 -> m_1), (3 -> m_3), (4 -> m_4)`
144-
pub fn init<R: RngCore>(
149+
/// the commit-to-randomness step (Step 1) of both Schnorr protocols.
150+
/// Accepts an iterator of messages. Each message can be either randomly blinded, revealed, or blinded using supplied blinding.
151+
pub fn init<'a, MBI, R: RngCore>(
145152
rng: &mut R,
146153
signature: &SignatureG1<E>,
147154
params: &SignatureParamsG1<E>,
148-
messages: &[E::ScalarField],
149-
mut blindings: BTreeMap<usize, E::ScalarField>,
150-
revealed_msg_indices: BTreeSet<usize>,
151-
) -> Result<Self, BBSPlusError> {
155+
messages_and_blindings: MBI,
156+
) -> Result<Self, BBSPlusError>
157+
where
158+
MBI: IntoIterator<Item = MessageOrBlinding<'a, E::ScalarField>>,
159+
{
160+
let (messages, ExtendSome::<Vec<_>>(indexed_blindings)): (Vec<_>, _) =
161+
messages_and_blindings
162+
.into_iter()
163+
.enumerate()
164+
.map(|(idx, msg_or_blinding)| match msg_or_blinding {
165+
MessageOrBlinding::BlindMessageRandomly(message) => {
166+
(message, (idx, rand(rng)).into())
167+
}
168+
MessageOrBlinding::BlindMessageWithConcreteBlinding { message, blinding } => {
169+
(message, (idx, blinding).into())
170+
}
171+
MessageOrBlinding::RevealMessage(message) => (message, None),
172+
})
173+
.unzip();
152174
if messages.len() != params.supported_message_count() {
153-
return Err(BBSPlusError::MessageCountIncompatibleWithSigParams(
175+
Err(BBSPlusError::MessageCountIncompatibleWithSigParams(
154176
messages.len(),
155177
params.supported_message_count(),
156-
));
157-
}
158-
159-
// No message index should be >= max messages
160-
for idx in &revealed_msg_indices {
161-
if *idx >= messages.len() {
162-
return Err(BBSPlusError::InvalidMessageIdx(*idx));
163-
}
164-
}
165-
166-
// Generate any blindings that are not explicitly passed. At the end of the loop, we should have
167-
// a blinding for every message whose knowledge is to be proven
168-
for i in 0..messages.len() {
169-
if !revealed_msg_indices.contains(&i) && !blindings.contains_key(&i) {
170-
blindings.insert(i, E::ScalarField::rand(rng));
171-
}
178+
))?
172179
}
173180

174181
let r1 = E::ScalarField::rand(rng);
175182
let r2 = E::ScalarField::rand(rng);
176183
let r3 = r1.inverse().ok_or(BBSPlusError::CannotInvert0)?;
177184

178185
// b = (e+x) * A = g1 + h_0*s + sum(h_i*m_i) for all i in I
179-
let b = params.b(
180-
messages
181-
.iter()
182-
.enumerate()
183-
.collect::<BTreeMap<usize, &E::ScalarField>>(),
184-
&signature.s,
185-
)?;
186+
let b = params.b(messages.iter().enumerate(), &signature.s)?;
186187

187188
// A' = A * r1
188189
let A_prime = signature.A.mul_bigint(r1.into_bigint());
@@ -224,31 +225,23 @@ impl<E: Pairing> PoKOfSignatureG1Protocol<E> {
224225
// Knowledge of all unrevealed messages `m_j` need to be proven in addition to knowledge of `-r3` and `s'`. Thus
225226
// all `m_j`, `-r3` and `s'` are the witnesses, while all `h_j`, `d`, `h_0` and `-g1 + \sum_{i \in D}(h_i*{-m_i})` is the instance.
226227

227-
let mut bases_2 = Vec::with_capacity(2 + blindings.len());
228-
let mut randomness_2 = Vec::with_capacity(2 + blindings.len());
229-
let mut wits_2 = Vec::with_capacity(2 + blindings.len());
230-
bases_2.push(d_affine);
231-
randomness_2.push(E::ScalarField::rand(rng));
232-
wits_2.push(-r3);
233-
bases_2.push(h_0);
234-
randomness_2.push(E::ScalarField::rand(rng));
235-
wits_2.push(s_prime);
236-
237-
// Capture all unrevealed messages `m_j` and corresponding `h_j`
238-
for i in 0..messages.len() {
239-
if !revealed_msg_indices.contains(&i) {
240-
bases_2.push(params.h[i]);
241-
randomness_2.push(blindings.remove(&i).unwrap());
242-
wits_2.push(messages[i]);
243-
}
244-
}
228+
let h_blinding_message = indexed_blindings
229+
.into_iter()
230+
.map(|(idx, blinding)| (params.h[idx], blinding, messages[idx]));
231+
232+
let (bases_2, randomness_2, wits_2): (Vec<_>, Vec<_>, Vec<_>) = multiunzip(
233+
[(d_affine, rand(rng), -r3), (h_0, rand(rng), s_prime)]
234+
.into_iter()
235+
.chain(h_blinding_message),
236+
);
245237

246238
// Commit to randomness, i.e. `bases_2[0]*randomness_2[0] + bases_2[1]*randomness_2[1] + .... bases_2[j]*randomness_2[j]`
247239
let sc_comm_2 = SchnorrCommitment::new(&bases_2, randomness_2);
240+
248241
Ok(Self {
249242
A_prime: A_prime_affine,
250243
A_bar: A_bar.into_affine(),
251-
d: bases_2.remove(0),
244+
d: bases_2[0],
252245
sc_comm_1,
253246
sc_wits_1: wits_1,
254247
sc_comm_2,
@@ -588,9 +581,13 @@ mod tests {
588581
&mut rng,
589582
&sig,
590583
&params,
591-
messages.as_slice(),
592-
BTreeMap::new(),
593-
revealed_indices.clone(),
584+
messages.iter().enumerate().map(|(idx, msg)| {
585+
if revealed_indices.contains(&idx) {
586+
MessageOrBlinding::RevealMessage(msg)
587+
} else {
588+
MessageOrBlinding::BlindMessageRandomly(msg)
589+
}
590+
}),
594591
)
595592
.unwrap();
596593
proof_create_duration += start.elapsed();
@@ -720,18 +717,32 @@ mod tests {
720717
&mut rng,
721718
&sig_1,
722719
&params_1,
723-
&messages_1,
724-
blindings_1,
725-
BTreeSet::new(),
720+
messages_1.iter().enumerate().map(|(idx, message)| {
721+
if let Some(blinding) = blindings_1.remove(&idx) {
722+
MessageOrBlinding::BlindMessageWithConcreteBlinding {
723+
message,
724+
blinding: blinding,
725+
}
726+
} else {
727+
MessageOrBlinding::BlindMessageRandomly(message)
728+
}
729+
}),
726730
)
727731
.unwrap();
728732
let pok_2 = PoKOfSignatureG1Protocol::init(
729733
&mut rng,
730734
&sig_2,
731735
&params_2,
732-
&messages_2,
733-
blindings_2,
734-
BTreeSet::new(),
736+
messages_2.iter().enumerate().map(|(idx, message)| {
737+
if let Some(blinding) = blindings_2.remove(&idx) {
738+
MessageOrBlinding::BlindMessageWithConcreteBlinding {
739+
message,
740+
blinding: blinding,
741+
}
742+
} else {
743+
MessageOrBlinding::BlindMessageRandomly(message)
744+
}
745+
}),
735746
)
736747
.unwrap();
737748

@@ -802,9 +813,13 @@ mod tests {
802813
&mut rng,
803814
&sig,
804815
&params,
805-
messages.as_slice(),
806-
BTreeMap::new(),
807-
revealed_indices_1.clone(),
816+
messages.iter().enumerate().map(|(idx, msg)| {
817+
if revealed_indices_1.contains(&idx) {
818+
MessageOrBlinding::RevealMessage(msg)
819+
} else {
820+
MessageOrBlinding::BlindMessageRandomly(msg)
821+
}
822+
}),
808823
)
809824
.unwrap();
810825
let proof_1 = pok_1.gen_proof(&challenge).unwrap();
@@ -826,9 +841,13 @@ mod tests {
826841
&mut rng,
827842
&sig,
828843
&params,
829-
messages.as_slice(),
830-
BTreeMap::new(),
831-
revealed_indices_2.clone(),
844+
messages.iter().enumerate().map(|(idx, msg)| {
845+
if revealed_indices_2.contains(&idx) {
846+
MessageOrBlinding::RevealMessage(msg)
847+
} else {
848+
MessageOrBlinding::BlindMessageRandomly(msg)
849+
}
850+
}),
832851
)
833852
.unwrap();
834853
let proof_2 = pok_2.gen_proof(&challenge).unwrap();
@@ -871,9 +890,13 @@ mod tests {
871890
&mut rng,
872891
&sig,
873892
&params,
874-
messages.as_slice(),
875-
BTreeMap::new(),
876-
revealed_indices_3.clone(),
893+
messages.iter().enumerate().map(|(idx, msg)| {
894+
if revealed_indices_3.contains(&idx) {
895+
MessageOrBlinding::RevealMessage(msg)
896+
} else {
897+
MessageOrBlinding::BlindMessageRandomly(msg)
898+
}
899+
}),
877900
)
878901
.unwrap();
879902
let proof_3 = pok_3.gen_proof(&challenge).unwrap();
@@ -920,9 +943,13 @@ mod tests {
920943
&mut rng,
921944
&sig,
922945
&params,
923-
messages.as_slice(),
924-
BTreeMap::new(),
925-
revealed_indices.clone(),
946+
messages.iter().enumerate().map(|(idx, msg)| {
947+
if revealed_indices.contains(&idx) {
948+
MessageOrBlinding::RevealMessage(msg)
949+
} else {
950+
MessageOrBlinding::BlindMessageRandomly(msg)
951+
}
952+
}),
926953
)
927954
.unwrap();
928955
let proof = pok.gen_proof(&challenge).unwrap();
@@ -978,9 +1005,7 @@ mod tests {
9781005
&mut rng,
9791006
&sigs[i],
9801007
&params,
981-
&msgs[i],
982-
BTreeMap::new(),
983-
BTreeSet::new(),
1008+
msgs[i].iter().map(MessageOrBlinding::BlindMessageRandomly),
9841009
)
9851010
.unwrap();
9861011
pok.challenge_contribution(&BTreeMap::new(), &params, &mut chal_bytes_prover)

0 commit comments

Comments
 (0)