mimblewimble / rust-secp256k1-zkp Goto Github PK
View Code? Open in Web Editor NEWZKP fork for rust-secp256k1, adds wrappers for range proofs, pedersen commitments, etc
License: Creative Commons Zero v1.0 Universal
ZKP fork for rust-secp256k1, adds wrappers for range proofs, pedersen commitments, etc
License: Creative Commons Zero v1.0 Universal
Looking at https://github.com/mimblewimble/secp256k1-zkp/blob/testnet3/src/modules/bulletproofs/main_impl.h#L30, the method secp256k1_bulletproof_generators_create
only has 3 arguments: a context, a blinding generator and a number. However in https://github.com/mimblewimble/rust-secp256k1-zkp/blob/testnet3/src/ffi.rs#L476 (and all places where it is called) there is a 4th argument precomp_n
. I think this argument doesn't do anything and should be removed.
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]);
}
}
I am new to rust.
after I got the repository, I run
cargo build
then I got
error: no such file or directory: 'depend/secp256k1-zkp/contrib/lax_der_parsing.c'
what should I do? Can someone please help.
Is there any support or planned support of Schnorr Blind Signatures that are compatible with bip-schnorr?
After adding this feature, we don't have any tests.
pub fn bullet_proof(
&self,
value: u64,
blind: SecretKey,
nonce: SecretKey,
extra_data: Option<Vec<u8>>,
message: Option<ProofMessage>,
) -> RangeProof {
...
// TODO: expose multi-party support
let tau_x = ptr::null_mut();
let t_one = ptr::null_mut();
let t_two = ptr::null_mut();
let commits = ptr::null_mut();
let private_nonce = ptr::null();
@jaspervdm Could you please give me some examples to use this new feature? so as me to add some tests for it.
Recent changes, namely deriving Serialize
and Deserialize
for Error
are not yet published to crates.io. It would be great if they were.
Grin currently generates commits that look like this -
Commitment(0251fb65e6cd4ae54749b59e139935dd4cfa10f0694aa8a2645c3950fe8785b198)
But rust-secp256k1-zkp generates commits that look like this -
Commitment(08032fc3685013a35124c0275457e97a7ff0046ba763fa45409b95e8b3eae53425)
ffi::secp256k1_ec_pubkey_parse
calls into secp256k1_eckey_pubkey_parse
which checks that
a 33 byte public key starts with 0x02
or 0x03
Q) Why is rust-secp256k1-zkp creating commitments that appear to be invalid?
We're in the middle of some changes to aggsig and bulletproofs in the underlying lib, so the current master will fail hard in tests until the rust side is update. Grin is currently using a particular tag, so shouldn't be an issue. Just noting I'm aware of it here, and will update the Rust side in one go once all the underlying changes are in.
Corresponding to mimblewimble/secp256k1-zkp#29
There're also 2 files in this repo:
I guess there's no any upstream for these 2 source files. Could you please confirm this? @yeastplume
I also suggest to change the header part, currently it's:
// Bitcoin secp256k1 bindings
// Written in 2014 by
// Dawid Ciężarkiewicz
// Andrew Poelstra
//
And one more suggestion: Could we do rustfmt on these 2 files? since there's no upstream for these 2 files and no need to worry merging.
We should be able to recover the message if we use a known nonce.
See ignopeverell/grin#123 for earlier attempt before we pulled rust-secp256k1-zkp
into a separate repo.
The intent is to be able to call something like -
let message = secp::pedersen::ProofMessage::empty();
let rproof = secp.range_proof(0, REWARD, skey, commit, &message);
A lot of functions in this repository don't take pointers in their arguments but somehow also don't take ownership of the argument (due to the usage of unsafe
blocks). We should replace all these instances with pointers, so that it conforms to the regular Rust ownership rules and is clearer to use. Some examples: commit()
, bullet_proof()
, verify_bullet_proof()
Background: when I perform a transaction on iOS wallet (which use grin codebase compiled for iOS), and later on I restore the wallet - each transaction maps to a weird BIP32 account:
____ Wallet Accounts ____
Name | Parent BIP-32 Derivation Path
-----------+-------------------------------
account_0 | m/540140409/3298754560
account_1 | m/543567437/4159635456
Command 'account' completed successfully
I've started to dig in and understood, that we are using a bulletproof message to store the BIP32 path for identifying the account during restore. Then, I observed that when I create a bulletproof with ProofMessage(00000000000000000000000000000000)
as a message to ffi::secp256k1_bulletproof_rangeproof_prove
(passed as the last parameter) and later call rewind_bullet_proof
with the just created bulletproof I got a different message, like ProofMessage(800da21d66b30000c2001b3a29f0c041)
. So, I assume, the message I pass to ffi::secp256k1_bulletproof_rangeproof_prove
for some reason get distorted.
I've tried to run the tests on iPhone using https://github.com/snipsco/dinghy, and they are failing with the following:
thread #2: tid = 0x3cd272, 0x0000000101056e18 Dinghy`secp256k1_fe_set_b32(r=0x000000016f239528, a="") at field_10x26_impl.h:324, name = 'pedersen::tests::test_bullet_proo[15/558]
ig', stop reason = EXC_BAD_ACCESS (code=1, address=0xa7974c91c050)
frame #0: 0x0000000101056e18 Dinghy`secp256k1_fe_set_b32(r=0x000000016f239528, a="") at field_10x26_impl.h:324
frame #1: 0x0000000101057d64 Dinghy`secp256k1_pedersen_commitment_load(ge=0x00000002833180a0, commit=0x0000a7974c91c030) at main_impl.h:31
frame #2: 0x000000010105f110 Dinghy`secp256k1_bulletproof_rangeproof_prove(ctx=0x0000000283b00000, scratch=0x0000000283018120, gens=0x0000000280204060, proof=0x0000000000000000
, plen=0x0000000000000000, tau_x=0x0000000000000000, t_one=0x000000016f23df30, t_two=0x000000016f23df70, value=0x000000016f239b10, min_value=0x0000000000000000, blind=0x000000028
001c020, commits=0x000000028001c030, n_commits=1, value_gen=0x000000010114a3e1, nbits=64, nonce="bdnW\ #\xab\xa342\xb6.(\x93f", private_nonce="𧜒\x8cV5%\xb1K(iVƥ\x02\xa9c;\x19RT\
xb5\\\xba\xb7, extra_commit=0x0000000000000000, extra_commit_len=0, message=0x0000000000000000) at main_impl.h:252
frame #3: 0x000000010101e538 Dinghy`secp256k1zkp::pedersen::_$LT$impl$u20$secp256k1zkp..Secp256k1$GT$::bullet_proof_multisig::h5ef5f4a8d3562320(self=0x000000016f23dce8, value=1
2345678, blind=(__0 = "\n\xbfDL?]K[\vF\x01\x1e\xac$hv\xb0\x1c\x8c\x9foMg\x02\x1f\x86$]bdnW\ #\xab\xa342\xb6.(\x93f"), nonce=(__0 = "bdnW\ #\xab\xa342\xb6.(\x93f"), extra_data_in=
Option<alloc::vec::Vec<u8>> @ 0x000000016f23f410, message=Option<secp256k1zkp::pedersen::ProofMessage> @ 0x000000016f23f428, tau_x=Option<&mut secp256k1zkp::key::SecretKey> @ 0x0
00000016f239b18, t_one=Option<&mut secp256k1zkp::key::PublicKey> @ 0x000000016f239b20, t_two=Option<&mut secp256k1zkp::key::PublicKey> @ 0x000000016f239b28, commits=Vec<secp256k1
zkp::pedersen::Commitment> @ 0x000000016f23f458, private_nonce=Option<&secp256k1zkp::key::SecretKey> @ 0x000000016f239b30, step='\x01') at pedersen.rs:876
frame #4: 0x0000000100fe4bcc Dinghy`secp256k1zkp::pedersen::tests::test_bullet_proof_multisig::_$u7b$$u7b$closure$u7d$$u7d$::hc44612881ad44945((null)=0x000000016f248c8f, v=1234
5678, nonce=(__0 = "bdnW\ #\xab\xa342\xb6.(\x93f\t\xad\x1b3i\t\xa843;TqG\x1bv\x9d}Y\x1b\xa905T\\\x85Y\xb0b\t\x9d\r\x15\x17ۊ\x9ed\\"\x03C\x05\x82Y\x12\"\x19\x94\x15\xa1\xacV\x83Ov
\x1f\xaem\n\\AOAXK\r\xa0ވ\xb5Ǐ"), ca=(__0 = "\t\xad\x1b3i\t\xa843;TqG\x1bv\x9d}Y\x1b\xa905T\\\x85Y\xb0b\t\x9d\r\x15\x17ۊ\x9ed\\"\x03C\x05\x82Y\x12\"\x19\x94\x15\xa1\xacV\x83Ov\x8\x1f\xaem\n\\AOAXK\r\xa0ވ\xb5Ǐ"), cb=(__0 = "\t\x9d\r\x15\x17ۊ\x9ed\\"\x03C\x05\x82Y\x12\"\x19\x94\x15\xa1\xacV\x83Ov\x84\n\xbfDL?]K[\vF\x01\x1e\xac$hv\xb0\x1c\x8c\x9foMg\x02\x1f\x1f\xaem\n\\AOAXK\r\xa0ވ\xb5Ǐ"), msg=Option<secp256k1zkp::pedersen::ProofMessage> @ 0x000000016f24a248, extra=Option<alloc::vec::Vec<u8>> @ 0x000000016f24a308) at pedersen.rs:1497
frame #5: 0x0000000100fcf8e4 Dinghy`secp256k1zkp::pedersen::tests::test_bullet_proof_multisig::hf9efca6961c2e153 at pedersen.rs:1611
frame #6: 0x0000000100fe45e4 Dinghy`secp256k1zkp::pedersen::tests::test_bullet_proof_multisig::_$u7b$$u7b$closure$u7d$$u7d$::he12b73a0ec3b3e1c((null)=0x000000016f24e8de) at pedersen.rs:1467
error: need to add support for DW_TAG_base_type '()' encoded with DW_ATE = 0x7, bit_size = 0
frame #7: 0x000000010103cd70 Dinghy`core::ops::function::FnOnce::call_once::hab10037076c9bf16((null)=closure @ 0x000000016f24e8de, (null)=<unavailable>) at function.rs:238
frame #8: 0x000000010108505c Dinghy`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h7cd9458e96c61134 [inlined] test::run_test::_$u7b$$u7b$closure$u7d$$u7d$::hcfb9d86a7c3d2c96 at lib.rs:1468 [opt]
frame #9: 0x0000000101085058 Dinghy`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h7cd9458e96c61134 [inlined] core::ops::function::FnOnce::call_once::h4391d3a834d88d8b at function.rs:238 [opt]
frame #10: 0x0000000101085058 Dinghy`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h7cd9458e96c61134 at boxed.rs:672 [opt]
frame #11: 0x000000010113ca84 Dinghy`__rust_maybe_catch_panic at lib.rs:102 [opt]
frame #12: 0x00000001010a1b20 Dinghy`std::sys_common::backtrace::__rust_begin_short_backtrace::hfba72662a42f7cac [inlined] std::panicking::try::h732fe36cab73cb41 at panicking.r
s:289 [opt]
frame #13: 0x00000001010a1af8 Dinghy`std::sys_common::backtrace::__rust_begin_short_backtrace::hfba72662a42f7cac [inlined] std::panic::catch_unwind::hac4e2f50e06b27fe at panic.
rs:392 [opt]
frame #14: 0x00000001010a1af8 Dinghy`std::sys_common::backtrace::__rust_begin_short_backtrace::hfba72662a42f7cac [inlined] test::run_test::run_test_inner::_$u7b$$u7b$closure$u7
d$$u7d$::h006e4850988c9367 at lib.rs:1423 [opt]
frame #15: 0x00000001010a1a5c Dinghy`std::sys_common::backtrace::__rust_begin_short_backtrace::hfba72662a42f7cac at backtrace.rs:136 [opt]
frame #16: 0x00000001010a23d4 Dinghy`std::panicking::try::do_call::h4daf77ea764d46fd [inlined] std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d
$$u7d$::hdf44bf80f31b708f at mod.rs:409 [opt]
frame #17: 0x00000001010a23ac Dinghy`std::panicking::try::do_call::h4daf77ea764d46fd [inlined] _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce
$LT$$LP$$RP$$GT$$GT$::call_once::hfe8230c624f93446 at panic.rs:313 [opt]
frame #18: 0x00000001010a23ac Dinghy`std::panicking::try::do_call::h4daf77ea764d46fd at panicking.rs:310 [opt]
frame #19: 0x000000010113ca84 Dinghy`__rust_maybe_catch_panic at lib.rs:102 [opt]
frame #20: 0x000000010109189c Dinghy`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h9f47ca2e7bc599f5 [inlined] std::panicking::try::h25ee5a857b5a665a at panicki
ng.rs:289 [opt]
frame #21: 0x0000000101091840 Dinghy`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h9f47ca2e7bc599f5 [inlined] std::panic::catch_unwind::hb4be13ae309c1f2b at panic.rs:392 [opt]
frame #22: 0x0000000101091840 Dinghy`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h9f47ca2e7bc599f5 [inlined] std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::hc8e2b8523d8822bb at mod.rs:408 [opt]
frame #23: 0x000000010109181c Dinghy`_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::h9f47ca2e7bc599f5 at boxed.rs:672 [opt]
frame #24: 0x0000000101132334 Dinghy`std::sys::unix::thread::Thread::new::thread_start::h53cadc7a8d993d1d [inlined] _$LT$alloc..boxed..Box$LT$$LP$dyn$u20$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$RP$$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h1550d5c67ef40595 at boxed.rs:682 [opt]
frame #25: 0x000000010113232c Dinghy`std::sys::unix::thread::Thread::new::thread_start::h53cadc7a8d993d1d [inlined] std::sys_common::thread::start_thread::ha4b13f99b17bd904 at thread.rs:24 [opt]
frame #26: 0x0000000101132320 Dinghy`std::sys::unix::thread::Thread::new::thread_start::h53cadc7a8d993d1d at thread.rs:90 [opt]
frame #27: 0x00000001c06e825c libsystem_pthread.dylib`<redacted> + 128
frame #28: 0x00000001c06e81bc libsystem_pthread.dylib`_pthread_start + 48
ERROR cargo_dinghy > Error: LLDB returned error code Some(255)
I would appreciate any clues how I can fix this, thanks in advance!
Just did a cargo test
, the pedersen::tests::test_bullet_proof_multisig
fails
As discussed in rust-bitcoin/rust-secp256k1#209, it'd be helpful to rename the symbols so that they don't clash if multiple versions of the crate(s) are used.
I just can not find where the function secp256k1_bulletproof_rangeproof_prove is defined.
anyone can help me?
I assume it goes with this project:
https://github.com/ElementsProject/secp256k1-zkp/tree/secp256k1-zkp/src
thanks.
from @garyyu:
The github project fork network is important, it will bring much more eyes on the fixes on the whole fork network, and will bring more developers to contribute on it.
Unfortunately, for some history reason (there were a lot of changes and do-overs of the Grin secp256k libs… they used to be integrated right into the grin repo but were pulled out and rebuilt, etc), The forked from info is lost, both at https://github.com/mimblewimble/rust-secp256k1-zkp 1 and at https://github.com/mimblewimble/rust-secp256k1-zkp 1
I propose to restore this forked from info.
As a demo here: https://github.com/garyyu/rust-secp256k1 3, I can ‘restore’ the forked from. (Note: it’s not a true restore! because github don’t support this function and I guess it’s not allowed in github, forever. More exactly, it’s a re-creation.)
https://github.com/rust-bitcoin/rust-secp256k1 1 is the original forked from of https://github.com/mimblewimble/rust-secp256k1-zkp 1 . Btw, rust-bitcoin/rust-secp256k1 has 53 fork, but mimblewimble/rust-secp256k1-zkp only have 8.
How to restore the forked from?
fork rust-bitcoin/rust-secp256k1 into mimblewimble
find the real fork point, for example: https://github.com/garyyu/rust-secp256k1/releases/tag/fork-point
remove the master branch, and create new master branch from fork-point
merge from master at mimblewimble/rust-secp256k1-zkp
remove all exising tags
push all mimblewimble/rust-secp256k1-zkp tags
Done.
After the new repo is ready, we can change its name as rust-secp256k1-zkp and rename the old one as (obsoleted)rust-secp256k1-zkp.
A small problem: there’s no good way to restore the exising github issues and github pull-request. But since only 5 closed issues and 21 closed PR, it should be acceptable.
And one more thing: rust-bitcoin/rust-secp256k1 doesn’t split the depend/secp256k1 as an indepent repo, so we can do the same thing, to obsolete the mimblewimble/secp256k1-zkp. Or perhaps do the same thing for mimblewimble/secp256k1-zkp.
Expose surjection
module from underlying secp256k1-zkp
lib -
We are going to need "surjection proofs" to investigate implementing Confidential Assets.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.