Skip to content

Commit 78ecbb1

Browse files
authored
Merge pull request #21 from ZencashOfficial/issue#19/return_constant
Issue#19/return constant
2 parents dc509ba + 1304438 commit 78ecbb1

File tree

12 files changed

+242
-206
lines changed

12 files changed

+242
-206
lines changed

api/src/ginger_calls.rs

+42-53
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,6 @@ pub fn create_naive_threshold_sig_proof(
251251
//Compute b as v-t and convert it to field element
252252
let b = read_field_element_from_u64(valid_signatures - threshold);
253253

254-
//Compute wcert_sysdata_hash
255-
let wcert_sysdata_hash = compute_wcert_sysdata_hash(valid_signatures, &mr_bt, &prev_end_epoch_mc_b_hash, &end_epoch_mc_b_hash)?;
256-
257-
//Compute pks_threshold_hash
258-
let pks_threshold_hash = compute_pks_threshold_hash(pks, threshold)?;
259-
260254
//Convert affine pks to projective
261255
let pks = pks.iter().map(|&pk| pk.into_projective()).collect::<Vec<_>>();
262256

@@ -265,8 +259,7 @@ pub fn create_naive_threshold_sig_proof(
265259

266260
let c = NaiveTresholdSignature::<FieldElement>::new(
267261
pks, sigs, threshold, b, end_epoch_mc_b_hash,
268-
prev_end_epoch_mc_b_hash, mr_bt, pks_threshold_hash,
269-
wcert_sysdata_hash, max_pks,
262+
prev_end_epoch_mc_b_hash, mr_bt, max_pks,
270263
);
271264

272265
//Read proving key
@@ -278,48 +271,27 @@ pub fn create_naive_threshold_sig_proof(
278271
Ok((proof, valid_signatures))
279272
}
280273

281-
//Return (wcert_sysdata_hash, pk_threshold_hash)
282-
pub fn get_public_inputs_for_naive_threshold_sig_proof(
283-
pks: &[SchnorrPk],
284-
threshold: u64,
274+
pub fn verify_naive_threshold_sig_proof(
275+
constant: &FieldElement,
285276
end_epoch_mc_b_hash: &[u8; 32],
286277
prev_end_epoch_mc_b_hash: &[u8; 32],
287278
bt_list: &[BackwardTransfer],
288279
valid_sigs: u64,
289-
) -> Result<(FieldElement, FieldElement), Error> {
290-
280+
proof: &SCProof,
281+
vk_path: &str,
282+
) -> Result<bool, Error>
283+
{
284+
//Compute wcert_sysdata_hash
291285
let end_epoch_mc_b_hash = read_field_element_from_buffer_with_padding(&end_epoch_mc_b_hash[..])?;
292286
let prev_end_epoch_mc_b_hash = read_field_element_from_buffer_with_padding(&prev_end_epoch_mc_b_hash[..])?;
293287
let (mr_bt, _) = compute_msg_to_sign(&end_epoch_mc_b_hash, &prev_end_epoch_mc_b_hash, bt_list)?;
294288
let wcert_sysdata_hash = compute_wcert_sysdata_hash(valid_sigs, &mr_bt, &prev_end_epoch_mc_b_hash, &end_epoch_mc_b_hash)?;
295-
let pks_threshold_hash = compute_pks_threshold_hash(pks, threshold)?;
289+
let aggregated_input = compute_poseidon_hash(&[*constant, wcert_sysdata_hash])?;
296290

297-
Ok((wcert_sysdata_hash, pks_threshold_hash))
298-
}
299-
300-
pub fn verify_naive_threshold_sig_proof(
301-
pks: &[SchnorrPk],
302-
threshold: u64,
303-
end_epoch_mc_b_hash: &[u8; 32],
304-
prev_end_epoch_mc_b_hash: &[u8; 32],
305-
bt_list: &[BackwardTransfer],
306-
valid_sigs: u64,
307-
proof: SCProof,
308-
vk_path: &str,
309-
) -> Result<bool, Error>
310-
{
311291
//Verify proof
312-
let (wcert_sysdata_hash, pks_threshold_hash) = get_public_inputs_for_naive_threshold_sig_proof(
313-
&pks,
314-
threshold,
315-
&end_epoch_mc_b_hash,
316-
&prev_end_epoch_mc_b_hash,
317-
bt_list,
318-
valid_sigs
319-
)?;
320292
let vk = read_from_file(vk_path)?;
321293
let pvk = prepare_verifying_key(&vk); //Get verifying key
322-
let is_verified = verify_proof(&pvk, &proof, &[pks_threshold_hash, wcert_sysdata_hash])?;
294+
let is_verified = verify_proof(&pvk, &proof, &[aggregated_input])?;
323295

324296
Ok(is_verified)
325297
}
@@ -387,7 +359,7 @@ pub fn vrf_proof_to_hash(msg: &FieldElement, pk: &VRFPk, proof: &VRFProof) -> Re
387359
pub struct FieldBasedMerkleTreeParams;
388360

389361
impl FieldBasedMerkleTreeConfig for FieldBasedMerkleTreeParams {
390-
const HEIGHT: usize = 9;
362+
const HEIGHT: usize = 13;
391363
type H = MNT4PoseidonHash;
392364
}
393365

@@ -429,6 +401,21 @@ mod test {
429401
Ok(())
430402
}
431403

404+
#[allow(dead_code)]
405+
fn into_i8(v: Vec<u8>) -> Vec<i8> {
406+
// first, make sure v's destructor doesn't free the data
407+
// it thinks it owns when it goes out of scope
408+
let mut v = std::mem::ManuallyDrop::new(v);
409+
410+
// then, pick apart the existing Vec
411+
let p = v.as_mut_ptr();
412+
let len = v.len();
413+
let cap = v.capacity();
414+
415+
// finally, adopt the data into a new Vec
416+
unsafe { Vec::from_raw_parts(p as *mut i8, len, cap) }
417+
}
418+
432419
#[test]
433420
fn create_sample_naive_threshold_sig_circuit() {
434421
//assume to have 3 pks, threshold = 2
@@ -478,6 +465,8 @@ mod test {
478465
sigs.push(None);
479466
sigs.push(Some(schnorr_sign(&msg, &sks[2], &pks[2]).unwrap()));
480467

468+
let constant = compute_pks_threshold_hash(pks.as_slice(), threshold).unwrap();
469+
481470
//Create and serialize proof
482471
let (proof, quality) = create_naive_threshold_sig_proof(
483472
pks.as_slice(),
@@ -492,27 +481,27 @@ mod test {
492481
write_to_file(&proof, proof_path).unwrap();
493482

494483
//Verify proof
495-
let (wcert_sysdata_hash, pks_threshold_hash) = get_public_inputs_for_naive_threshold_sig_proof(
496-
&pks,
497-
threshold,
484+
assert!(verify_naive_threshold_sig_proof(
485+
&constant,
498486
&end_epoch_mc_b_hash,
499487
&prev_end_epoch_mc_b_hash,
500488
bt_list.as_slice(),
501-
quality
502-
).unwrap();
503-
let pvk = prepare_verifying_key(&params.vk); //Get verifying key
504-
assert!(verify_proof(&pvk, &proof, &[pks_threshold_hash, wcert_sysdata_hash]).unwrap()); //Assert proof verification passes
489+
quality,
490+
&proof,
491+
"./sample_vk",
492+
).unwrap());
505493

506-
//Generate wrong public inputs by changing threshold and valid sigs and assert proof verification doesn't pass
507-
let (wrong_wcert_sysdata_hash, wrong_pks_threshold_hash) = get_public_inputs_for_naive_threshold_sig_proof(
508-
&pks,
509-
1,
494+
495+
//Generate wrong public inputs by changing quality and assert proof verification doesn't pass
496+
assert!(!verify_naive_threshold_sig_proof(
497+
&constant,
510498
&end_epoch_mc_b_hash,
511499
&prev_end_epoch_mc_b_hash,
512500
bt_list.as_slice(),
513-
quality - 1
514-
).unwrap();
515-
assert!(!verify_proof(&pvk, &proof, &[wrong_pks_threshold_hash, wrong_wcert_sysdata_hash]).unwrap()); //Assert proof verification passes
501+
quality - 1,
502+
&proof,
503+
"./sample_vk",
504+
).unwrap());
516505
}
517506

518507
#[test]

api/src/lib.rs

+65-25
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,58 @@ pub extern "system" fn Java_com_horizen_vrfnative_VRFPublicKey_nativeProofToHash
10071007
*result
10081008
}
10091009

1010+
//Naive threshold signature proof functions
1011+
#[no_mangle]
1012+
pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_nativeGetConstant(
1013+
_env: JNIEnv,
1014+
// this is the class that owns our
1015+
// static method. Not going to be
1016+
// used, but still needs to have
1017+
// an argument slot
1018+
_class: JClass,
1019+
_schnorr_pks_list: jobjectArray,
1020+
_threshold: jlong,
1021+
) -> jobject
1022+
{
1023+
//Extract Schnorr pks
1024+
let mut pks = vec![];
1025+
1026+
let pks_list_size = _env.get_array_length(_schnorr_pks_list)
1027+
.expect("Should be able to get schnorr_pks_list size");
1028+
1029+
for i in 0..pks_list_size {
1030+
1031+
let pk_object = _env.get_object_array_element(_schnorr_pks_list, i)
1032+
.expect(format!("Should be able to get elem {} of schnorr_pks_list", i).as_str());
1033+
1034+
let pk = _env.get_field(pk_object, "publicKeyPointer", "J")
1035+
.expect("Should be able to get field publicKeyPointer");
1036+
1037+
pks.push(*read_raw_pointer(pk.j().unwrap() as *const SchnorrPk));
1038+
}
1039+
1040+
//Extract threshold
1041+
let threshold = _threshold as u64;
1042+
1043+
//Compute constant
1044+
let constant = match compute_pks_threshold_hash(pks.as_slice(), threshold){
1045+
Ok(constant) => constant,
1046+
Err(_) => return std::ptr::null::<jobject>() as jobject //CRYPTO_ERROR
1047+
};
1048+
1049+
//Return constant
1050+
let field_ptr: jlong = jlong::from(Box::into_raw(Box::new(constant)) as i64);
1051+
1052+
let field_class = _env.find_class("com/horizen/librustsidechains/FieldElement")
1053+
.expect("Should be able to find FieldElement class");
1054+
1055+
let result = _env.new_object(field_class, "(J)V", &[
1056+
JValue::Long(field_ptr)]).expect("Should be able to create new long for FieldElement");
1057+
1058+
*result
1059+
}
1060+
1061+
10101062
#[no_mangle]
10111063
pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_nativeCreateMsgToSign(
10121064
_env: JNIEnv,
@@ -1101,7 +1153,6 @@ pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_na
11011153
*result
11021154
}
11031155

1104-
//Naive threshold signature proof functions
11051156
#[no_mangle]
11061157
pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_nativeCreateProof(
11071158
_env: JNIEnv,
@@ -1270,10 +1321,9 @@ pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_na
12701321
// an argument slot
12711322
_class: JClass,
12721323
_bt_list: jobjectArray,
1273-
_schnorr_pks_list: jobjectArray,
12741324
_end_epoch_block_hash: jbyteArray,
12751325
_prev_end_epoch_block_hash: jbyteArray,
1276-
_threshold: jlong,
1326+
_constant: JObject,
12771327
_quality: jlong,
12781328
_sc_proof_bytes: jbyteArray,
12791329
_verification_key_path: JString
@@ -1310,23 +1360,6 @@ pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_na
13101360
bt_list.push(BackwardTransfer::new(pk, a));
13111361
}
13121362

1313-
//Extract Schnorr pks
1314-
let mut pks = vec![];
1315-
1316-
let pks_list_size = _env.get_array_length(_schnorr_pks_list)
1317-
.expect("Should be able to get schnorr_pks_list size");
1318-
1319-
for i in 0..pks_list_size {
1320-
1321-
let pk_object = _env.get_object_array_element(_schnorr_pks_list, i)
1322-
.expect(format!("Should be able to get elem {} of schnorr_pks_list", i).as_str());
1323-
1324-
let pk = _env.get_field(pk_object, "publicKeyPointer", "J")
1325-
.expect("Should be able to get field publicKeyPointer");
1326-
1327-
pks.push(*read_raw_pointer(pk.j().unwrap() as *const SchnorrPk));
1328-
}
1329-
13301363
//Extract block hashes
13311364
let end_epoch_block_hash = {
13321365
let t = _env.convert_byte_array(_end_epoch_block_hash)
@@ -1352,8 +1385,16 @@ pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_na
13521385
prev_end_epoch_block_hash_bytes
13531386
};
13541387

1355-
//Extract threshold and quality
1356-
let threshold = _threshold as u64;
1388+
//Extract constant
1389+
let constant = {
1390+
1391+
let c =_env.get_field(_constant, "fieldElementPointer", "J")
1392+
.expect("Should be able to get field fieldElementPointer");
1393+
1394+
read_raw_pointer(c.j().unwrap() as *const FieldElement)
1395+
};
1396+
1397+
//Extract quality
13571398
let quality = _quality as u64;
13581399

13591400
//Extract proof
@@ -1370,13 +1411,12 @@ pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_na
13701411

13711412
//Verify proof
13721413
match verify_naive_threshold_sig_proof(
1373-
pks.as_slice(),
1374-
threshold,
1414+
constant,
13751415
&end_epoch_block_hash,
13761416
&prev_end_epoch_block_hash,
13771417
bt_list.as_slice(),
13781418
quality,
1379-
proof,
1419+
&proof,
13801420
vk_path.to_str().unwrap()
13811421
) {
13821422
Ok(result) => if result { JNI_TRUE } else { JNI_FALSE },

build_jar.sh

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
cargo clean
2+
3+
cargo build --release --target=x86_64-pc-windows-gnu
4+
cargo build --release --target=x86_64-unknown-linux-gnu
5+
6+
7+
mkdir -p jni/src/main/resources/native/linux64
8+
cp target/x86_64-unknown-linux-gnu/release/libzendoo_sc.so jni/src/main/resources/native/linux64/libzendoo_sc.so
9+
10+
mkdir -p jni/src/main/resources/native/windows64
11+
cp target/x86_64-pc-windows-gnu/release/zendoo_sc.dll jni/src/main/resources/native/windows64/zendoo_sc.dll
12+
13+
cd jni
14+
mvn clean package

0 commit comments

Comments
 (0)