Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/nullifier #99

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/rust/src/bolos/zemu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ extern "C" {
}

#[cfg(not(test))]
pub fn c_zemu_log_stack(s: &[u8]) {
pub fn c_zemu_log_stack(s: &str) {
unsafe { zemu_log_stack(s.as_ptr()) }
}

#[cfg(test)]
pub fn c_zemu_log_stack(_s: &[u8]) {}
pub fn c_zemu_log_stack(_s: &str) {}
116 changes: 85 additions & 31 deletions app/rust/src/commitments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,50 +94,48 @@ pub fn value_commitment_step2(rcm: &[u8; 32]) -> ExtendedPoint {
VALUE_COMMITMENT_RANDOM_BASE.multiply_bits(rcm)
}

#[inline(never)]
pub fn note_commitment(v: u64, g_d: &[u8; 32], pk_d: &[u8; 32], rcm: &[u8; 32]) -> ExtendedPoint {
c_zemu_log_stack("notecommit\x00");
let mut input_hash = [0u8; 73];

// Convert the value to bytes and reverse the bits as per protocol
let vbytes = utils::write_u64_tobytes(v);
input_hash[0..8].copy_from_slice(&vbytes);

// Reverse bits for g_d and pk_d and place them into the input hash
utils::reverse_bits(g_d, &mut input_hash[8..40]);
utils::reverse_bits(pk_d, &mut input_hash[40..72]);

// Perform a bit shift operation on the entire array
shiftsixbits(&mut input_hash);

// Compute the Pedersen hash to point
let mut p = pedersen_hash_to_point(&input_hash, 582);

// Multiply the randomness base by rcm and add to the point
let s = PEDERSEN_RANDOMNESS_BASE.multiply_bits(rcm);
p += s;

p
}

//////////////////////////////
//////////////////////////////

#[cfg(test)]
mod tests {
use crate::bolos::seed::with_device_seed_context;
use crate::commitments_extern::{compute_note_commitment, compute_nullifier};
use crate::constants::{ZIP32_COIN_TYPE, ZIP32_PURPOSE};
use crate::sapling::*;
use crate::types::{diversifier_zero, NskBytes};
use crate::utils::into_fixed_array;
use crate::zip32::*;
use crate::zip32_extern::zip32_nsk;

use super::*;

#[inline(never)]
pub fn note_commitment(
v: u64,
g_d: &[u8; 32],
pk_d: &[u8; 32],
rcm: &[u8; 32],
) -> ExtendedPoint {
c_zemu_log_stack(b"notecommit\x00".as_ref());
let mut input_hash = [0u8; 73];

// Convert the value to bytes and reverse the bits as per protocol
let vbytes = utils::write_u64_tobytes(v);
input_hash[0..8].copy_from_slice(&vbytes);

// Reverse bits for g_d and pk_d and place them into the input hash
utils::reverse_bits(g_d, &mut input_hash[8..40]);
utils::reverse_bits(pk_d, &mut input_hash[40..72]);

// Perform a bit shift operation on the entire array
shiftsixbits(&mut input_hash);

// Compute the Pedersen hash to point
let mut p = pedersen_hash_to_point(&input_hash, 582);

// Multiply the randomness base by rcm and add to the point
let s = PEDERSEN_RANDOMNESS_BASE.multiply_bits(rcm);
p += s;

p
}

#[inline(never)]
pub fn value_commitment(value: u64, rcm: &[u8; 32]) -> [u8; 32] {
let scalar = into_fixed_array(value);
Expand Down Expand Up @@ -272,6 +270,62 @@ mod tests {
})
}

#[test]
fn check_nf_with_seed() {
let pos: u64 = 2578461368;
let path = [ZIP32_PURPOSE, ZIP32_COIN_TYPE, 0];
let rcm: [u8; 32] = [
0x6e, 0xbb, 0xed, 0x74, 0x36, 0x19, 0xa2, 0x56, 0xf9, 0xad, 0x2e, 0x85, 0x88, 0x0c,
0xfa, 0xa9, 0x09, 0x8a, 0x5f, 0xdb, 0x16, 0x29, 0x99, 0x0d, 0x9a, 0x7d, 0x3b, 0xb9,
0x3f, 0xc9, 0x00, 0x03,
];
let value: u64 = 17811330145809239872;

let key_bundle = zip32_sapling_derive(&path);
let mut nsk: NskBytes = [0u8; 32];

zip32_nsk(0, &mut nsk);

let ak = sapling_ask_to_ak(&key_bundle.ask());
let nsk = key_bundle.nsk();
let nk = sapling_nsk_to_nk(&key_bundle.nsk());
let ivk = sapling_aknk_to_ivk(&ak, &nk);
let diversifier = diversifier_find_valid(&key_bundle.dk(), &diversifier_zero());
let pk_d = pkd_default(&ivk, &diversifier);

let g_d = compute_g_d(&diversifier);
let h = note_commitment(value, &g_d, &pk_d, &rcm);

let cm1 = group::GroupEncoding::to_bytes(&h);

let mp = mixed_pedersen(&h, Fr::from_bytes(&into_fixed_array(pos)).unwrap());
let nf = prf_nf(&nk, &mp);

assert_eq!(
hex::encode(nf),
"a9f8bb1b242c5fef6d8f81cc4c5ce32d296fd69b27138c104ff8a652b00682a2"
);

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Bellow to check that both note_commitment and compute_note_commitment are working and
// gives the same note commitment

let mut cm2 = [0u8; 32];
compute_note_commitment(&rcm, value, &diversifier, &pk_d, &mut cm2);
println!("cm1: {}", hex::encode(cm1));
println!("cm2: {}", hex::encode(cm2));
assert_eq!(cm1, cm2);

let mut nf = [0u8; 32];

compute_nullifier(&cm2, pos, &nsk, &mut nf);

assert_eq!(
hex::encode(nf),
"a9f8bb1b242c5fef6d8f81cc4c5ce32d296fd69b27138c104ff8a652b00682a2"
);
}

#[test]
fn test_mixed_pedersen() {
let v = 312354353u32;
Expand Down
32 changes: 24 additions & 8 deletions app/rust/src/commitments_extern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub extern "C" fn compute_nullifier(
nsk_ptr: *const NskBytes,
out_ptr: *mut NfBytes,
) {
c_zemu_log_stack(b"compute_nullifier\x00".as_ref());
c_zemu_log_stack("compute_nullifier\x00");
let ncm = unsafe { *ncm_ptr };
let nsk = unsafe { &*nsk_ptr };
let out = unsafe { &mut *out_ptr };
Expand Down Expand Up @@ -43,20 +43,36 @@ pub extern "C" fn compute_note_commitment(
pkd_ptr: *const [u8; 32],
out_ptr: *mut [u8; 32],
) {
c_zemu_log_stack("----[compute_note_commitment]\x00");

let rcm = unsafe { &*rcm_ptr };
let diversifier = unsafe { &*diversifier_ptr };
let pkd = unsafe { &*pkd_ptr };
let out = unsafe { &mut *out_ptr };

let mut gd = [0u8; 32];
commitments::group_hash_from_diversifier(diversifier, &mut gd);
commitments::prepare_and_hash_input_commitment(value, &gd, pkd, out);
// commented code was previous implementation
// and was given an invalid commitment. code is left here
// for further investigation

let mut e = cryptoops::bytes_to_extended(*out);
let s = multiply_with_pedersen_base(rcm);
add_to_point(&mut e, &s);
// let mut gd = [0u8; 32];

let gd = crate::zip32::compute_g_d(diversifier);

// commitments::group_hash_from_diversifier(diversifier, &mut gd);
// commitments::prepare_and_hash_input_commitment(value, &gd, pkd, out);
// let mut e = cryptoops::bytes_to_extended(*out);
// let s = multiply_with_pedersen_base(rcm);
// add_to_point(&mut e, &s);

// TODO: We need to test note_commitment function at runtime
// to discard any stack/pic issues
let commitment_point = crate::commitments::note_commitment(value, &gd, pkd, rcm);

// Convert the commitment point to bytes
let cm_bytes = group::GroupEncoding::to_bytes(&commitment_point);

out.copy_from_slice(&extended_to_u_bytes(&e));
// out.copy_from_slice(&extended_to_u_bytes(&e));
out.copy_from_slice(cm_bytes.as_ref());
}

//////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion app/rust/src/redjubjub_extern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub extern "C" fn sign_redjubjub(
msg_ptr: *const [u8; 64],
out_ptr: *mut [u8; 64],
) {
c_zemu_log_stack(b"sign_redjubjub\x00".as_ref());
c_zemu_log_stack("sign_redjubjub\x00");
let key = unsafe { *key_ptr };
let msg = unsafe { *msg_ptr };
let output = unsafe { &mut *out_ptr };
Expand Down
7 changes: 7 additions & 0 deletions app/rust/src/zip32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ pub fn diversifier_find_valid(dk: &DkBytes, start: &Diversifier) -> Diversifier
div_out
}

pub fn compute_g_d(d: &[u8; 11]) -> [u8; 32] {
let h = blake2b::blake2s_diversification(d);
let v = AffinePoint::from_bytes(h).unwrap();
let g_d = v.mul_by_cofactor();
group::GroupEncoding::to_bytes(&g_d)
}

#[inline(never)]
pub fn diversifier_get_list(
dk: &DkBytes,
Expand Down
Loading