mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-08-02 00:31:32 +00:00
Refactor Sapling verification checks
This commit is contained in:
@@ -690,10 +690,39 @@ pub extern "system" fn librustzcash_sapling_check_spend(
|
|||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Deserialize the anchor, which should be an element
|
||||||
|
// of Fr.
|
||||||
|
let anchor = match Fr::from_repr(read_le(&(unsafe { &*anchor })[..])) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Deserialize rk
|
||||||
|
let rk = match redjubjub::PublicKey::<Bls12>::read(&(unsafe { &*rk })[..], &JUBJUB) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Deserialize the signature
|
||||||
|
let spend_auth_sig = match Signature::read(&(unsafe { &*spend_auth_sig })[..]) {
|
||||||
|
Ok(sig) => sig,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Deserialize the proof
|
||||||
|
let zkproof = match Proof::<Bls12>::read(&(unsafe { &*zkproof })[..]) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
if is_small_order(&cv) {
|
if is_small_order(&cv) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if is_small_order(&rk.0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Accumulate the value commitment in the context
|
// Accumulate the value commitment in the context
|
||||||
{
|
{
|
||||||
let mut tmp = cv.clone();
|
let mut tmp = cv.clone();
|
||||||
@@ -703,37 +732,15 @@ pub extern "system" fn librustzcash_sapling_check_spend(
|
|||||||
unsafe { &mut *ctx }.bvk = tmp;
|
unsafe { &mut *ctx }.bvk = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deserialize the anchor, which should be an element
|
|
||||||
// of Fr.
|
|
||||||
let anchor = match Fr::from_repr(read_le(&(unsafe { &*anchor })[..])) {
|
|
||||||
Ok(a) => a,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Grab the nullifier as a sequence of bytes
|
// Grab the nullifier as a sequence of bytes
|
||||||
let nullifier = &unsafe { &*nullifier }[..];
|
let nullifier = &unsafe { &*nullifier }[..];
|
||||||
|
|
||||||
// Compute the signature's message for rk/spend_auth_sig
|
// Compute the signature's message for rk/spend_auth_sig
|
||||||
let mut data_to_be_signed = [0u8; 64];
|
let mut data_to_be_signed = [0u8; 64];
|
||||||
(&mut data_to_be_signed[0..32]).copy_from_slice(&(unsafe { &*rk })[..]);
|
rk.0.write(&mut data_to_be_signed[0..32])
|
||||||
|
.expect("message buffer should be 32 bytes");
|
||||||
(&mut data_to_be_signed[32..64]).copy_from_slice(&(unsafe { &*sighash_value })[..]);
|
(&mut data_to_be_signed[32..64]).copy_from_slice(&(unsafe { &*sighash_value })[..]);
|
||||||
|
|
||||||
// Deserialize rk
|
|
||||||
let rk = match redjubjub::PublicKey::<Bls12>::read(&(unsafe { &*rk })[..], &JUBJUB) {
|
|
||||||
Ok(p) => p,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
if is_small_order(&rk.0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deserialize the signature
|
|
||||||
let spend_auth_sig = match Signature::read(&(unsafe { &*spend_auth_sig })[..]) {
|
|
||||||
Ok(sig) => sig,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify the spend_auth_sig
|
// Verify the spend_auth_sig
|
||||||
if !rk.verify(
|
if !rk.verify(
|
||||||
&data_to_be_signed,
|
&data_to_be_signed,
|
||||||
@@ -769,12 +776,6 @@ pub extern "system" fn librustzcash_sapling_check_spend(
|
|||||||
public_input[6] = nullifier[1];
|
public_input[6] = nullifier[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deserialize the proof
|
|
||||||
let zkproof = match Proof::<Bls12>::read(&(unsafe { &*zkproof })[..]) {
|
|
||||||
Ok(p) => p,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify the proof
|
// Verify the proof
|
||||||
match verify_proof(
|
match verify_proof(
|
||||||
unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap(),
|
unsafe { SAPLING_SPEND_VK.as_ref() }.unwrap(),
|
||||||
@@ -803,20 +804,6 @@ pub extern "system" fn librustzcash_sapling_check_output(
|
|||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_small_order(&cv) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accumulate the value commitment in the context
|
|
||||||
{
|
|
||||||
let mut tmp = cv.clone();
|
|
||||||
tmp = tmp.negate(); // Outputs subtract from the total.
|
|
||||||
tmp = tmp.add(&unsafe { &*ctx }.bvk, &JUBJUB);
|
|
||||||
|
|
||||||
// Update the context
|
|
||||||
unsafe { &mut *ctx }.bvk = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deserialize the commitment, which should be an element
|
// Deserialize the commitment, which should be an element
|
||||||
// of Fr.
|
// of Fr.
|
||||||
let cm = match Fr::from_repr(read_le(&(unsafe { &*cm })[..])) {
|
let cm = match Fr::from_repr(read_le(&(unsafe { &*cm })[..])) {
|
||||||
@@ -830,10 +817,30 @@ pub extern "system" fn librustzcash_sapling_check_output(
|
|||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Deserialize the proof
|
||||||
|
let zkproof = match Proof::<Bls12>::read(&(unsafe { &*zkproof })[..]) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if is_small_order(&cv) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if is_small_order(&epk) {
|
if is_small_order(&epk) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accumulate the value commitment in the context
|
||||||
|
{
|
||||||
|
let mut tmp = cv.clone();
|
||||||
|
tmp = tmp.negate(); // Outputs subtract from the total.
|
||||||
|
tmp = tmp.add(&unsafe { &*ctx }.bvk, &JUBJUB);
|
||||||
|
|
||||||
|
// Update the context
|
||||||
|
unsafe { &mut *ctx }.bvk = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
// Construct public input for circuit
|
// Construct public input for circuit
|
||||||
let mut public_input = [Fr::zero(); 5];
|
let mut public_input = [Fr::zero(); 5];
|
||||||
{
|
{
|
||||||
@@ -848,12 +855,6 @@ pub extern "system" fn librustzcash_sapling_check_output(
|
|||||||
}
|
}
|
||||||
public_input[4] = cm;
|
public_input[4] = cm;
|
||||||
|
|
||||||
// Deserialize the proof
|
|
||||||
let zkproof = match Proof::<Bls12>::read(&(unsafe { &*zkproof })[..]) {
|
|
||||||
Ok(p) => p,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify the proof
|
// Verify the proof
|
||||||
match verify_proof(
|
match verify_proof(
|
||||||
unsafe { SAPLING_OUTPUT_VK.as_ref() }.unwrap(),
|
unsafe { SAPLING_OUTPUT_VK.as_ref() }.unwrap(),
|
||||||
@@ -901,6 +902,12 @@ pub extern "system" fn librustzcash_sapling_final_check(
|
|||||||
binding_sig: *const [c_uchar; 64],
|
binding_sig: *const [c_uchar; 64],
|
||||||
sighash_value: *const [c_uchar; 32],
|
sighash_value: *const [c_uchar; 32],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
// Deserialize the signature
|
||||||
|
let binding_sig = match Signature::read(&(unsafe { &*binding_sig })[..]) {
|
||||||
|
Ok(sig) => sig,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
// Obtain current bvk from the context
|
// Obtain current bvk from the context
|
||||||
let mut bvk = redjubjub::PublicKey(unsafe { &*ctx }.bvk.clone());
|
let mut bvk = redjubjub::PublicKey(unsafe { &*ctx }.bvk.clone());
|
||||||
|
|
||||||
@@ -921,12 +928,6 @@ pub extern "system" fn librustzcash_sapling_final_check(
|
|||||||
.expect("bvk is 32 bytes");
|
.expect("bvk is 32 bytes");
|
||||||
(&mut data_to_be_signed[32..64]).copy_from_slice(&(unsafe { &*sighash_value })[..]);
|
(&mut data_to_be_signed[32..64]).copy_from_slice(&(unsafe { &*sighash_value })[..]);
|
||||||
|
|
||||||
// Deserialize the signature
|
|
||||||
let binding_sig = match Signature::read(&(unsafe { &*binding_sig })[..]) {
|
|
||||||
Ok(sig) => sig,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verify the binding_sig
|
// Verify the binding_sig
|
||||||
if !bvk.verify(
|
if !bvk.verify(
|
||||||
&data_to_be_signed,
|
&data_to_be_signed,
|
||||||
|
Reference in New Issue
Block a user