Skip to content

Commit 1e2f1be

Browse files
committed
Update the accumulator and the main file
1 parent a979a90 commit 1e2f1be

File tree

3 files changed

+247
-209
lines changed

3 files changed

+247
-209
lines changed

src/acumulator.rs

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
// mod bb_params;
2+
// mod credential;
3+
// mod commitment;
4+
// mod witness;
5+
6+
7+
use ark_bls12_381::{
8+
Bls12_381,
9+
Fr,
10+
g1::{G1_GENERATOR_X, G1_GENERATOR_Y},
11+
g2::{G2_GENERATOR_X, G2_GENERATOR_Y},
12+
G1Affine, G2Affine, G1Projective, G2Projective
13+
};
14+
use ark_serialize::CanonicalSerialize;
15+
use bbs_plus::prelude::SignatureParamsG1;
16+
use bbs_plus::prelude::SecretKey;
17+
use bbs_plus::signature::SignatureG1;
18+
use ark_ec::{pairing::Pairing};
19+
use ark_ec::CurveGroup;
20+
use ark_ff::{PrimeField, UniformRand};
21+
use num_bigint::{BigUint, RandBigInt};
22+
use rand::thread_rng;
23+
use ark_ec::AffineRepr;
24+
use ark_ff::BigInteger;
25+
// use ark_ec::pairing::PairingOutput;
26+
use ark_ff::Field;
27+
use std::ops::Mul;
28+
use sha2::Sha256;
29+
use sha2::Digest;
30+
use std::collections::HashMap; // Added import
31+
32+
33+
use crate::bb_params::*;
34+
use crate::credential::*;
35+
use crate::commitment::*;
36+
use crate::witness::*;
37+
38+
39+
/// Generate bilinear group parameters: (g ∈ G1, g2 ∈ G2, gt = e(g, g2), q = |Fr|)
40+
pub fn bi_linear_generator() -> BBParams {
41+
// MODULUS is a BigInt, convert to BigUint
42+
let q = BigUint::from(Fr::MODULUS);
43+
44+
// G1: Create point from (x, y)
45+
let g1_affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
46+
let g = g1_affine.into_group(); // Into G1Projective
47+
48+
// G2: Create point from (x, y)
49+
let g2_affine = G2Affine::new_unchecked(G2_GENERATOR_X, G2_GENERATOR_Y);
50+
let g2 = g2_affine.into_group(); // Into G2Projective
51+
52+
let gt = Bls12_381::pairing(&g, &g2);
53+
54+
BBParams { q, g, g2, gt }
55+
}
56+
57+
// Implement the Perdersent commitment for hidding data
58+
fn commit_to_x(x: &Fr, h: &G1Projective) -> Commitment {
59+
let mut rng = thread_rng();
60+
let r = Fr::rand(&mut rng);
61+
let g = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y).into_group(); // assumes G is public
62+
let commitment = g.mul(x) + h.mul(r); // g^x * h^r (g, h in G1) <x is the messae, r for the randomess>
63+
64+
Commitment {
65+
value: commitment,
66+
blinding: r,
67+
}
68+
}
69+
70+
71+
/// Accumulator struct
72+
pub struct Accumulator {
73+
pub acc_val: G1Projective,
74+
pub parameter: Option<BBParams>,
75+
pub j_pub: Option<G2Projective>,
76+
pub issued_x: HashMap<String, Fr>, // Maps a credential ID to its x value (in actual this was a database)
77+
}
78+
79+
impl Accumulator {
80+
pub fn new() -> Self { // the constructor - but not for use
81+
let g1_affine = G1Affine::new_unchecked(G1_GENERATOR_X, G1_GENERATOR_Y);
82+
let g = g1_affine.into_group(); // Into G1Projective
83+
Self {
84+
85+
acc_val: g,
86+
parameter: None,
87+
j_pub: None,
88+
issued_x: HashMap::new(),
89+
}
90+
}
91+
92+
pub fn acc_gen(&mut self, sk: Fr, _n: usize) { // Initialize the acc_gen to actual use
93+
let bp_para = bi_linear_generator();
94+
self.parameter = Some(bp_para);
95+
96+
let mut rng = thread_rng();
97+
98+
// j_pub = g2^sk ∈ G2
99+
let g2 = self.parameter.as_ref().unwrap().g2;
100+
let j = g2 * sk;
101+
102+
// Sample u_0 ∈ [0, q)
103+
let u_0 = rng.gen_biguint_below(&self.parameter.as_ref().unwrap().q);
104+
let u_0_fr = Fr::from_le_bytes_mod_order(&u_0.to_bytes_le());
105+
106+
// acc = g^u_0 ∈ G1
107+
let g = self.parameter.as_ref().unwrap().g;
108+
self.acc_val = g * u_0_fr;
109+
110+
self.j_pub = Some(j);
111+
}
112+
113+
pub fn gen_wit(&mut self, sk: &SecretKey<Fr>, credential: Credential, h: &G1Projective)
114+
-> Witness {
115+
// (a) Sample x ∈ D / sk
116+
let mut rng = thread_rng();
117+
let x = loop {
118+
let candidate = Fr::rand(&mut rng);
119+
let sum = candidate + sk.0;
120+
if !sum.0.is_zero() {
121+
break candidate;
122+
}
123+
// else continue looping
124+
};
125+
126+
// (b) Commit to x
127+
let commitment = commit_to_x(&x, h);
128+
let c_x = commitment.value;
129+
130+
// (c) Gen non-membership witness w_{x|t}
131+
let sum = x + sk.0;
132+
let inv = sum.inverse().unwrap();
133+
let w_x_t = self.acc_val.mul(inv);
134+
135+
// // (d) Sign over messages || c_x
136+
let mut combined_msgs = credential.messages.clone(); // Vec<BigUnit>
137+
let c_x_bytes = c_x.into_affine().x.0.to_bytes_be();
138+
let c_x_fr = Fr::from_be_bytes_mod_order(&c_x_bytes);
139+
combined_msgs.push(c_x_fr);
140+
141+
let message_count = combined_msgs.len() as u32;
142+
let params = SignatureParamsG1::<Bls12_381>::generate_using_rng(&mut rng, message_count).try_into().unwrap();
143+
let sig = SignatureG1::new(&mut rng, &combined_msgs, sk, &params).unwrap();
144+
145+
// Example: associate x with a credential ID = hash(sig)
146+
let mut hasher = Sha256::new();
147+
let mut sig_bytes = vec![];
148+
credential.signature.serialize_compressed(&mut sig_bytes).unwrap();
149+
hasher.update(sig_bytes);
150+
let hash = hasher.finalize();
151+
let cred_id = format!(
152+
"cred_{}",
153+
hash[..4].iter().map(|b| format!("{:02x}", b)).collect::<String>()
154+
);
155+
self.issued_x.insert(cred_id, x);
156+
157+
// // (e) Return the witness
158+
let witness = Witness{
159+
x: x,
160+
c_x: commitment,
161+
w_x_t: w_x_t,
162+
sig: sig.clone()
163+
};
164+
165+
return witness
166+
}
167+
168+
169+
// remove an accumulated values - send the updated message for each holder to re-calculate their witness
170+
171+
pub fn del(&mut self, sk: &SecretKey<Fr>, revoke_cred: Credential) -> Fr {
172+
173+
// Serialize the signature
174+
let mut hasher = Sha256::new();
175+
let mut sig_bytes = vec![];
176+
revoke_cred.signature.serialize_compressed(&mut sig_bytes).unwrap();
177+
hasher.update(sig_bytes);
178+
let hash = hasher.finalize();
179+
let cred_id = format!(
180+
"cred_{}",
181+
hash[..4].iter().map(|b| format!("{:02x}", b)).collect::<String>()
182+
);
183+
184+
// Get x associated with this credential
185+
let delta = *self.get_x_by_id(&cred_id).unwrap();
186+
// let delta = self.issued_x.get(&cred_id).unwrap(); // Option<&Fr>
187+
// the delta shall be stored in some-where for all un-update valid holder still work
188+
let sum = delta + sk.0;
189+
let inv = sum.inverse().unwrap();
190+
191+
// Update accumulator
192+
self.acc_val = self.acc_val.mul(inv);
193+
194+
return delta;
195+
}
196+
197+
fn get_x_by_id(&self, cred_id: &str) -> Option<&Fr> {
198+
self.issued_x.get(cred_id)
199+
}
200+
201+
pub fn get_acc_val(&self) -> G1Projective {
202+
self.acc_val
203+
}
204+
205+
pub fn get_j_pub(&self) -> G2Projective {
206+
self.j_pub.expect("j_pub is not initialized")
207+
}
208+
209+
pub fn get_parameter(&self) -> BBParams {
210+
self.parameter.clone().expect("Parameter of accumulator not been setup")
211+
}
212+
213+
214+
}
215+

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub mod bb_params;
2+
pub mod credential;
3+
pub mod commitment;
4+
pub mod witness;
5+
pub mod acumulator;

0 commit comments

Comments
 (0)