mimblewimble / secp256k1-zkp

Fork of secp256k1-zkp for the Grin/MimbleWimble project
MIT License
32 stars 42 forks source link

bulletproof requires nonce == blind #12

Closed mschneiderwng closed 6 years ago

mschneiderwng commented 6 years ago

If I understand it correctly, then the blind and nonce can be chosen independently (even if the rust api sets nonce = blind) when creating and unwinding bulletproofs. However, if nonce != blind, then only the first 32 bytes of the message can be unwinded as in the following test which can be inserted into perdersen.rs.

    #[test]
    fn test_bullet_nonce_neq_blind() {
        use std;
        use super::*;
        let secp = Secp256k1::with_caps(ContextFlag::Commit);
        let mut rng = OsRng::new().unwrap();
        let value = 1234567;
        let blind = SecretKey::new(&secp, &mut rng);
        let nonce = SecretKey::new(&secp, &mut rng);
        //let nonce = blind; // this works
        let mut msg = [0u8; 64];
        rng.fill_bytes(&mut msg);

        // ffi structures
        let n_bits = 64;
        let mut proof = [0; constants::MAX_PROOF_SIZE];
        let mut plen = constants::MAX_PROOF_SIZE as size_t;
        let extra_data = vec![];

        // create proof
        let success = unsafe {
            ffi::secp256k1_bulletproof_rangeproof_prove_single_w_scratch(
                secp.ctx,
                proof.as_mut_ptr(),
                &mut plen,
                value,
                blind.as_ptr(),
                constants::GENERATOR_H.as_ptr(),
                n_bits as size_t,
                nonce.as_ptr(),
                extra_data.as_ptr(),
                extra_data.len() as size_t,
                msg.as_ptr()
            ) == 1
        };
        assert!(success);

        // unwind proof
        let mut unwinded_msg = [0u8; 64];
        let commit = secp.commit(value, blind).unwrap();
        let success = unsafe {
            ffi::secp256k1_bulletproof_rangeproof_unwind_message(
                secp.ctx,
                proof.as_ptr(),
                plen as size_t,
                commit.as_ptr(),
                n_bits as size_t,
                constants::GENERATOR_H.as_ptr(),
                extra_data.as_ptr(),
                extra_data.len() as size_t,
                nonce.as_ptr(),
                unwinded_msg.as_mut_ptr(),
            ) == 1
        };
        assert!(success);

        println!("msg:     {:?}", msg.to_vec());
        println!("unwinded:{:?}", unwinded_msg.to_vec());

        for i in 0..msg.len() {
            assert_eq!(msg[i], unwinded_msg[i]);
        }
    }
mschneiderwng commented 6 years ago

I think this should be moved to rust-secp256k1-zkp