Skip to content

Commit

Permalink
Merge pull request #25 from ZencashOfficial/handle_no_bwt
Browse files Browse the repository at this point in the history
Support to proof creation/verification with no bwt
  • Loading branch information
albertog78 authored Jun 9, 2020
2 parents 78ecbb1 + e58ef0f commit 985c95e
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 66 deletions.
40 changes: 23 additions & 17 deletions api/src/ginger_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ use primitives::{
BoweHopwoodPedersenCRH, BoweHopwoodPedersenParameters
},
},
merkle_tree::field_based_mht::{FieldBasedMerkleHashTree, FieldBasedMerkleTreeConfig, FieldBasedMerkleTreePath},
merkle_tree::field_based_mht::{
FieldBasedMerkleHashTree, FieldBasedMerkleTreeConfig,
FieldBasedMerkleTreePath, MNT4753_PHANTOM_MERKLE_ROOT,
},
signature::{
FieldBasedSignatureScheme, schnorr::field_based_schnorr::{
FieldBasedSchnorrSignatureScheme, FieldBasedSchnorrSignature
Expand Down Expand Up @@ -178,20 +181,19 @@ pub fn compute_msg_to_sign(
bt_list: &[BackwardTransfer],
) -> Result<(FieldElement, FieldElement), Error> {

let mut bt_field_list = vec![];
for bt in bt_list.iter() {
let bt_f = bt.to_field_element()?;
bt_field_list.push(bt_f);
}

//Compute bt_list merkle_root
let bt_mt = new_ginger_merkle_tree(bt_field_list.as_slice())?;

drop(bt_field_list);

let mr_bt = get_ginger_merkle_root(&bt_mt);
let mr_bt = if bt_list.is_empty() {
MNT4753_PHANTOM_MERKLE_ROOT
} else {
let mut bt_field_list = vec![];
for bt in bt_list.iter() {
let bt_f = bt.to_field_element()?;
bt_field_list.push(bt_f);
}

drop(bt_mt);
//Compute bt_list merkle_root
let bt_mt = new_ginger_merkle_tree(bt_field_list.as_slice())?;
get_ginger_merkle_root(&bt_mt)
};

//Compute message to be verified
let msg = compute_poseidon_hash(&[mr_bt, *prev_end_epoch_mc_b_hash, *end_epoch_mc_b_hash])?;
Expand Down Expand Up @@ -416,8 +418,7 @@ mod test {
unsafe { Vec::from_raw_parts(p as *mut i8, len, cap) }
}

#[test]
fn create_sample_naive_threshold_sig_circuit() {
fn create_sample_naive_threshold_sig_circuit(bt_num: usize) {
//assume to have 3 pks, threshold = 2
let mut rng = OsRng;

Expand All @@ -429,7 +430,6 @@ mod test {
let end_epoch_mc_b_hash_f = read_field_element_from_buffer_with_padding(&end_epoch_mc_b_hash[..]).unwrap();
let prev_end_epoch_mc_b_hash_f = read_field_element_from_buffer_with_padding(&prev_end_epoch_mc_b_hash[..]).unwrap();

let bt_num = 10;
let mut bt_list = vec![];
for _ in 0..bt_num {
bt_list.push(BackwardTransfer::default());
Expand Down Expand Up @@ -504,6 +504,12 @@ mod test {
).unwrap());
}

#[test]
fn naive_threshold_sig_circuit_test() {
create_sample_naive_threshold_sig_circuit(10);
create_sample_naive_threshold_sig_circuit(0);
}

#[test]
fn sample_schnorr_sig_prove_verify(){
let mut rng = OsRng;
Expand Down
104 changes: 55 additions & 49 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,29 +1078,31 @@ pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_na
let bt_list_size = _env.get_array_length(_bt_list)
.expect("Should be able to get bt_list size");

for i in 0..bt_list_size {
let o = _env.get_object_array_element(_bt_list, i)
.expect(format!("Should be able to get elem {} of bt_list array", i).as_str());
if bt_list_size > 0
{
for i in 0..bt_list_size {
let o = _env.get_object_array_element(_bt_list, i)
.expect(format!("Should be able to get elem {} of bt_list array", i).as_str());

let pk: [u8; 20] = {
let p = _env.call_method(o, "getPublicKeyHash", "()[B", &[])
.expect("Should be able to call getPublicKeyHash method").l().unwrap().cast();

let pk: [u8; 20] = {
let p = _env.call_method(o, "getPublicKeyHash", "()[B", &[])
.expect("Should be able to call getPublicKeyHash method").l().unwrap().cast();
let mut pk_bytes = [0u8; 20];

let mut pk_bytes = [0u8; 20];
_env.convert_byte_array(p)
.expect("Should be able to convert to Rust byte array")
.write(&mut pk_bytes[..])
.expect("Should be able to write into byte array of fixed size");

_env.convert_byte_array(p)
.expect("Should be able to convert to Rust byte array")
.write(&mut pk_bytes[..])
.expect("Should be able to write into byte array of fixed size");
pk_bytes
};

pk_bytes
};

let a = _env.call_method(o, "getAmount", "()J", &[])
.expect("Should be able to call getAmount method").j().unwrap() as u64;
let a = _env.call_method(o, "getAmount", "()J", &[])
.expect("Should be able to call getAmount method").j().unwrap() as u64;

bt_list.push(BackwardTransfer::new(pk, a));
bt_list.push(BackwardTransfer::new(pk, a));
}
}

//Extract block hashes
Expand Down Expand Up @@ -1176,29 +1178,31 @@ pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_na
let bt_list_size = _env.get_array_length(_bt_list)
.expect("Should be able to get bt_list size");

for i in 0..bt_list_size {
let o = _env.get_object_array_element(_bt_list, i)
.expect(format!("Should be able to get elem {} of bt_list array", i).as_str());
if bt_list_size > 0 {
for i in 0..bt_list_size {
let o = _env.get_object_array_element(_bt_list, i)
.expect(format!("Should be able to get elem {} of bt_list array", i).as_str());


let pk: [u8; 20] = {
let p = _env.call_method(o, "getPublicKeyHash", "()[B", &[])
.expect("Should be able to call getPublicKeyHash method").l().unwrap().cast();
let pk: [u8; 20] = {
let p = _env.call_method(o, "getPublicKeyHash", "()[B", &[])
.expect("Should be able to call getPublicKeyHash method").l().unwrap().cast();

let mut pk_bytes = [0u8; 20];
let mut pk_bytes = [0u8; 20];

_env.convert_byte_array(p)
.expect("Should be able to convert to Rust byte array")
.write(&mut pk_bytes[..])
.expect("Should be able to write into byte array of fixed size");
_env.convert_byte_array(p)
.expect("Should be able to convert to Rust byte array")
.write(&mut pk_bytes[..])
.expect("Should be able to write into byte array of fixed size");

pk_bytes
};
pk_bytes
};

let a = _env.call_method(o, "getAmount", "()J", &[])
.expect("Should be able to call getAmount method").j().unwrap() as u64;
let a = _env.call_method(o, "getAmount", "()J", &[])
.expect("Should be able to call getAmount method").j().unwrap() as u64;

bt_list.push(BackwardTransfer::new(pk, a));
bt_list.push(BackwardTransfer::new(pk, a));
}
}

//Extract Schnorr signatures and the corresponding Schnorr pks
Expand Down Expand Up @@ -1335,29 +1339,31 @@ pub extern "system" fn Java_com_horizen_sigproofnative_NaiveThresholdSigProof_na
let bt_list_size = _env.get_array_length(_bt_list)
.expect("Should be able to get bt_list size");

for i in 0..bt_list_size {
let o = _env.get_object_array_element(_bt_list, i)
.expect(format!("Should be able to get elem {} of bt_list array", i).as_str());
if bt_list_size > 0 {
for i in 0..bt_list_size {
let o = _env.get_object_array_element(_bt_list, i)
.expect(format!("Should be able to get elem {} of bt_list array", i).as_str());


let pk: [u8; 20] = {
let p = _env.call_method(o, "getPublicKeyHash", "()[B", &[])
.expect("Should be able to call getPublicKeyHash method").l().unwrap().cast();
let pk: [u8; 20] = {
let p = _env.call_method(o, "getPublicKeyHash", "()[B", &[])
.expect("Should be able to call getPublicKeyHash method").l().unwrap().cast();

let mut pk_bytes = [0u8; 20];
let mut pk_bytes = [0u8; 20];

_env.convert_byte_array(p)
.expect("Should be able to convert to Rust byte array")
.write(&mut pk_bytes[..])
.expect("Should be able to write into byte array of fixed size");
_env.convert_byte_array(p)
.expect("Should be able to convert to Rust byte array")
.write(&mut pk_bytes[..])
.expect("Should be able to write into byte array of fixed size");

pk_bytes
};
pk_bytes
};

let a = _env.call_method(o, "getAmount", "()J", &[])
.expect("Should be able to call getAmount method").j().unwrap() as u64;
let a = _env.call_method(o, "getAmount", "()J", &[])
.expect("Should be able to call getAmount method").j().unwrap() as u64;

bt_list.push(BackwardTransfer::new(pk, a));
bt_list.push(BackwardTransfer::new(pk, a));
}
}

//Extract block hashes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,96 @@ public void testcreateProof() {
createAndVerifyProof();
}

@Test
public void testcreateProofWithoutBWT() {

endEpochBlockHash = new byte[] {
61, -127, 80, -103, 117, -119, -44, -90, 52, -56, 79, -18, -64, -92, -42, -61, -89, 8, -107, 114, -6, -58,
87, 123, 54, 3, 100, 121, -26, -80, -122, -90
};

prevEndEpochBlockHash = new byte[] {
95, 99, 89, 78, -113, 46, 99, -61, -11, -11, -24, 104, -51, -109, -48, 11, 119, 94, 104, -104, 38, -84,
126, 22, -119, -96, -57, -67, 38, 109, 73, -22
};

byte[][] secretKeyList = {
{
-63, 75, 3, -102, -107, 40, -92, 126, -93, 78, -33, -110, 98, -23, 115, -111, 39, -37, -88, 56, -25, 44,
-59, 15, 106, -95, 105, 73, 14, 38, 81, -94, -36, -41, 57, -7, -104, 96, -38, -30, 15, -61, 36, -109,
-74, -38, 70, -97, 67, -19, 74, -122, 98, -95, 27, -33, -44, 83, -20, 12, -44, -107, -81, -7, 24, -73,
118, 70, 5, -41, 13, 109, -106, -8, 39, 79, 24, 94, -5, -61, 47, 124, -107, -99, -25, -81, -3, -104,
-78, -76, 62, -45, -66, 74, 0, 0
},
{
4, 80, -48, 29, 28, 54, -89, 82, 40, -76, -78, -111, 30, 51, 82, -64, -97, -33, 46, 91, 25, -20, 72,
117, 84, 38, -53, 40, 26, 125, 77, -22, -16, -83, -23, 0, 52, -27, 57, -17, 83, -60, 59, 125, 97, 94,
-118, -10, 33, -5, -79, 15, 105, -119, -99, 125, 107, -123, -27, 89, -56, -99, -114, 62, 31, 82, -80,
108, 104, -114, -60, -70, 34, 118, 97, -90, 15, -92, 2, -65, -82, 78, 119, -119, 107, 103, 3, 115, 15,
-76, -30, -98, -91, 14, 1, 0
},
{
16, -108, 42, -111, 35, -85, 34, -91, -83, -68, -36, 89, -39, 2, -67, -15, -48, -64, -109, 2, -22, 87,
127, 16, 72, -116, -39, -13, 76, -100, 83, -103, -32, 78, 6, -13, -127, -2, -10, -33, -9, 32, 67, 17,
12, -77, 70, 112, 101, -28, 76, 42, -93, 31, -108, -42, -26, -45, 96, -45, 119, -56, 118, 68, -61, -27,
94, 22, -30, -120, -111, -115, -99, -86, 97, -98, -49, 23, 8, -9, 88, 50, -46, 48, -83, 65, -88, 120,
-25, -92, 76, -112, -76, 82, 1, 0
}
};

byte[][] serializedSignatureList = {
{
25, -17, 9, 92, -67, -25, 113, 99, -75, 110, -63, -63, 23, -107, -107, 8, 83, -94, 43, 55, 96, 71,
-7, 37, -103, -28, -74, 125, -115, 125, 66, 33, -62, 54, 34, -6, 38, 26, -86, 62, 37, 26, -90, -46, -21,
-47, 101, -105, 48, 62, 23, -64, -49, 20, -45, 41, -116, 21, -112, -79, -5, -56, -4, -33, -65, 76, -31,
89, 15, 3, -41, -88, 48, -105, -98, -115, -49, -23, 98, -69, 105, 2, 13, 76, -107, 88, -61, 15, -122,
73, 19, -117, -124, -16, 0, 0, 124, -66, 28, -41, -12, -12, 108, 19, 88, 107, 106, -5, 52, 122, 101,
-59, -73, -99, 24, 43, -81, -93, 72, -83, -126, 24, 102, -125, -115, -27, 75, 92, 17, -61, -14, -58, 46,
-104, 101, 94, -124, 117, 1, -66, 48, -127, -103, 32, -3, -81, 115, -21, 67, 126, 36, -74, 56, 113, 31,
-123, 30, 8, -82, -115, 100, -89, 93, -105, -35, -82, 98, 34, 58, 77, 79, 56, 94, -111, -124, 17, 4,
-13, -108, -121, 30, -89, 96, 43, 67, -55, 38, -61, -123, -119, 0, 0
},
{
-72, 57, 95, -103, 95, 18, -39, -31, 116, 33, -76, -46, -121, 79, -123, 45, 119, 104, 1, -50, -95, 14,
-93, 41, -63, 82, -61, 22, 65, -103, 115, -106, 69, -4, -40, -80, 45, -66, 105, 30, -55, 9, -86, -60,
48, 100, -81, -1, 45, 111, -55, -93, 5, 33, -101, -56, 56, 10, 110, 22, -66, -57, 21, -102, -44, 54,
-119, 121, -32, 51, -4, 70, -74, -26, 91, -20, 8, -43, -5, 75, -73, 12, -43, 46, -4, 98, 49, -20, 97, 8,
87, 53, -65, 119, 0, 0, -16, 35, -123, 124, -6, 10, 61, -27, 123, 4, -66, 71, -92, -125, 108, -76, 104,
79, -74, 42, 125, -59, 89, 126, 124, -21, 67, -56, 22, -109, -39, -30, 4, 53, 5, 111, -96, 82, 123, 77,
86, 103, -75, 28, -79, -98, 108, -73, 55, 117, -22, -126, -7, 103, -10, 28, -73, 14, -37, -47, 56, -49,
-34, 52, -117, 18, -99, -49, -73, -61, -114, -59, 43, -28, -30, 39, 29, -111, -98, -119, -40, 15, -75,
24, 35, 118, 38, 85, -53, 8, 70, 80, 74, -117, 0, 0
}
};

// Deserialize secret keys and get the corresponding public keys
for (int i = 0; i<keyCount; i++) {

SchnorrSecretKey sk = SchnorrSecretKey.deserialize(secretKeyList[i]);
assertNotNull("sk" + i + "deserialization must not fail", sk);

SchnorrPublicKey pk = new SchnorrKeyPair(sk).getPublicKey();
assertTrue("Public key verification failed.", pk.verifyKey());

publicKeyList.add(pk);
sk.freeSecretKey();
}

// Deserialize Schnorr Signatures
for (int i = 0; i<keyCount; i++) {
if (i < threshold) {
SchnorrSignature sig = SchnorrSignature.deserialize(serializedSignatureList[i]);
assertNotNull("sig" + i + "deserialization must not fail", sig);
signatureList.add(sig);
} else {
SchnorrSignature sig = new SchnorrSignature();
signatureList.add(sig);
}
}

createAndVerifyProof();
}

@Test
public void testCreateRandomProof(){
Random r = new Random();
Expand All @@ -140,6 +230,7 @@ public void testCreateRandomProof(){

r.nextBytes(prevEndEpochBlockHash);

backwardTransferCout = r.nextInt(backwardTransferCout + 1);
// Create dummy Backward Transfers
for(int i = 0; i < backwardTransferCout; i++) {

Expand Down

0 comments on commit 985c95e

Please sign in to comment.