Skip to content

Commit 638ffc7

Browse files
committed
feat: add sign and verify of single message
Signed-off-by: pedro bufulin <pedro@semiotic.ai>
1 parent 1bead82 commit 638ffc7

File tree

1 file changed

+98
-8
lines changed

1 file changed

+98
-8
lines changed

h2s2/src/nc1.rs

Lines changed: 98 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,20 @@ use ark_ff::{BigInteger, UniformRand, Zero};
1010
use ark_std::rand::Rng;
1111
use digest::Digest;
1212

13+
fn hash_to_g1<P: Pairing, D: Digest>(message_data: Vec<u8>) -> P::G1Affine {
14+
let mut g1_point: Option<P::G1Affine> = None;
15+
let mut counter = 0;
16+
while g1_point.is_some() == false {
17+
let mut tmp_message = message_data.clone();
18+
tmp_message.push(counter);
19+
let hash_out = D::digest(&tmp_message);
20+
g1_point = P::G1Affine::from_random_bytes(&hash_out);
21+
counter += 1;
22+
}
23+
g1_point.unwrap()
24+
}
25+
1326
pub struct NC1<P: Pairing, D: Digest> {
14-
parameters: Option<H2S2Parameters<P>>,
1527
_pairing: PhantomData<P>,
1628
_hash: PhantomData<D>,
1729
}
@@ -23,7 +35,7 @@ pub struct H2S2Parameters<P: Pairing> {
2335
// both the indexer and verifier need it. The secret key
2436
// remains with the gateway
2537
pub public_key: P::G2,
26-
pub secret_key: P::ScalarField,
38+
pub secret_key: Option<P::ScalarField>,
2739
pub max_lanes: usize,
2840
}
2941

@@ -46,16 +58,16 @@ impl<P: Pairing, D: Digest + Send + Sync> HolographicHomomorphicSignatureScheme<
4658
let mut pp = H2S2Parameters {
4759
g1_generators,
4860
g2_generator,
49-
secret_key: P::ScalarField::zero(), // Temporary placeholder
50-
public_key: P::G2::zero(), // Temporary placeholder
61+
secret_key: Some(P::ScalarField::zero()), // Temporary placeholder
62+
public_key: P::G2::zero(), // Temporary placeholder
5163
max_lanes: n,
5264
};
5365

5466
// Use the keygen function to generate the secret/public key pair
5567
let (public_key, secret_key) = Self::keygen(&pp, rng)?;
5668

5769
// Update the parameters with the generated keys
58-
pp.secret_key = secret_key;
70+
pp.secret_key = Some(secret_key);
5971
pp.public_key = public_key;
6072

6173
Ok(pp)
@@ -113,7 +125,32 @@ impl<P: Pairing, D: Digest + Send + Sync> HolographicHomomorphicSignatureScheme<
113125
index: &[u8],
114126
message: &[Self::Message],
115127
) -> Result<Self::Signature, Box<dyn Error>> {
116-
Ok(P::G1::default())
128+
use ark_std::vec::Vec;
129+
130+
// Concatenate the allocation ID (tag) with the index
131+
let mut input = Vec::from(tag);
132+
input.extend_from_slice(index);
133+
134+
// Hash the concatenated input to map it to a G1 element
135+
let lane_point = hash_to_g1::<P, D>(input);
136+
137+
// Compute the message commitment
138+
let mut message_commitment = P::G1::zero();
139+
for (i, m) in message.iter().enumerate() {
140+
// Multiply each message part with its respective generator
141+
let mut message_point = pp.g1_generators[i].clone();
142+
message_point = message_point.mul(*m);
143+
message_commitment += message_point;
144+
}
145+
146+
// Combine lane_point and message_commitment
147+
let combined_point = lane_point.into_group() + message_commitment;
148+
149+
// Sign the combined point using the secret key
150+
let mut signature = combined_point.clone();
151+
signature = signature.mul(*sk);
152+
153+
Ok(signature)
117154
}
118155

119156
fn verify(
@@ -124,7 +161,31 @@ impl<P: Pairing, D: Digest + Send + Sync> HolographicHomomorphicSignatureScheme<
124161
message: &[Self::Message],
125162
signature: &Self::Signature,
126163
) -> Result<bool, Box<dyn Error>> {
127-
Ok(true)
164+
// Concatenate the allocation ID (tag) with the index
165+
let mut input = Vec::from(tag);
166+
input.extend_from_slice(index);
167+
168+
// Hash the concatenated input to map it to a G1 element
169+
let lane_point = hash_to_g1::<P, D>(input);
170+
171+
// Compute the message commitment
172+
let mut message_commitment = P::G1::zero();
173+
for (i, m) in message.iter().enumerate() {
174+
// Multiply each message part with its respective generator
175+
let mut message_point = pp.g1_generators[i].clone();
176+
message_point = message_point.mul(*m);
177+
message_commitment += message_point;
178+
}
179+
180+
// Combine lane_point and message_commitment
181+
let combined_point = lane_point.into_group() + message_commitment;
182+
183+
// Compute the pairings for verification
184+
let lhs_pairing = P::pairing(*signature, pp.g2_generator);
185+
let rhs_pairing = P::pairing(combined_point, *pk);
186+
187+
// Verify that the pairings match
188+
Ok(lhs_pairing == rhs_pairing)
128189
}
129190

130191
fn verify_aggregate(
@@ -169,7 +230,7 @@ mod tests {
169230
assert_eq!(params.max_lanes, 10);
170231

171232
let expected_public_key = params.public_key;
172-
let calculated_public_key = params.g2_generator.mul(params.secret_key);
233+
let calculated_public_key = params.g2_generator.mul(params.secret_key.unwrap());
173234

174235
assert_eq!(
175236
calculated_public_key, expected_public_key,
@@ -187,4 +248,33 @@ mod tests {
187248

188249
println!("Precomputed Hash Aggregate: {:?}", hash_aggregate);
189250
}
251+
#[test]
252+
fn test_sign_and_verify() {
253+
let params = &*PARAMS;
254+
let allocation_id = b"example_allocation_id";
255+
let index = b"lane_1";
256+
let message = vec![ark_bn254::Fr::from(42u64), ark_bn254::Fr::from(7u64)];
257+
258+
let sk = params.secret_key.unwrap();
259+
let pk = params.public_key;
260+
261+
// Sign the message
262+
let signature =
263+
NC1::<Bn254, Blake2b512>::sign(&params, &sk, allocation_id, index, &message)
264+
.expect("Sign failed");
265+
266+
// Verify the signature
267+
let is_valid = NC1::<Bn254, Blake2b512>::verify(
268+
&params,
269+
&pk,
270+
allocation_id,
271+
index,
272+
&message,
273+
&signature,
274+
)
275+
.expect("Verify failed");
276+
277+
assert!(is_valid, "Signature verification failed!");
278+
println!("Signature successfully verified!");
279+
}
190280
}

0 commit comments

Comments
 (0)