Coder Social home page Coder Social logo

zengo-x / multi-party-ecdsa Goto Github PK

View Code? Open in Web Editor NEW
940.0 54.0 307.0 1.41 MB

Rust implementation of {t,n}-threshold ECDSA (elliptic curve digital signature algorithm).

License: GNU General Public License v3.0

Rust 99.93% Shell 0.07%
ecdsa multi-party-ecdsa signature rust secret-shares blockchain cryptography cryptocurrency

multi-party-ecdsa's Introduction

Multi-party ECDSA

Build Status License: GPL v3

IMPORTANT NOTE

This repository is no longer maintained. Most specifically, Zengo will not provide any security updates or hotfixes (should an issue arise). This library was originally created to enable users to experiment with MPC and TSS functionality using different protocols, including such that are not used in production by Zengo wallet. Zengo wallet’s production MPC code can be found in https://github.com/ZenGo-X/gotham-city/master

Introduction

This project is a Rust implementation of {t,n}-threshold ECDSA (elliptic curve digital signature algorithm).

Threshold ECDSA includes two protocols:

  • Key Generation for creating secret shares.
  • Signing for using the secret shares to generate a signature.

ECDSA is used extensively for crypto-currencies such as Bitcoin, Ethereum (secp256k1 curve), NEO (NIST P-256 curve) and much more. This library can be used to create MultiSig and ThresholdSig crypto wallet. For a full background on threshold signatures please read our Binance academy article Threshold Signatures Explained.

Library Introduction

The library was built with four core design principles in mind:

  1. Multi-protocol support
  2. Built for cryptography engineers
  3. Foolproof
  4. Black box use of cryptographic primitives

To learn about the core principles as well as on the audit process and security of the library, please read our Intro to multiparty ecdsa library blog post.

Use It

The library implements four different protocols for threshold ECDSA. The protocols presents different tradeoffs in terms of parameters, security assumptions and efficiency.

Protocol High Level code
Lindell 17 [1] Gotham-city (accepted to CIW19) is a two party bitcoin wallet, including benchmarks. KMS is a Rust wrapper library that implements a general purpose two party key management system. thresh-sig-js is a Javascript SDK
Gennaro, Goldfeder 19 [2] (video) tss-ecdsa-cli is a wrapper CLI for full threshold access structure, including network and threshold HD keys (BIP32). See Demo in this library to get better low level understanding
Castagnos et. al. 19 [3] Currently enabled as a feature in this library. To Enable, build with --features=cclst. to Test, use cargo test --features=cclst -- --test-threads=1
Gennaro, Goldfeder 20 [4] A full threshold protocol that supports identifying malicious parties. If signing fails - a list of malicious parties is returned. The protocol requires only a broadcast channel (all messages are broadcasted)

Run GG20 Demo

In the following steps we will generate 2-of-3 threshold signing key and sign a message with 2 parties.

Setup

  1. You need Rust and GMP library (optionally) to be installed on your computer.

    • Run cargo build --release --examples
    • Don't have GMP installed? Use this command instead:
      cargo build --release --examples --no-default-features --features curv-kzen/num-bigint
      But keep in mind that it will be less efficient.

    Either of commands will produce binaries into ./target/release/examples/ folder.

  2. cd ./target/release/examples/

Start an SM server

./gg20_sm_manager

That will start an HTTP server on http://127.0.0.1:8000. Other parties will use that server in order to communicate with each other. Note that communication channels are neither encrypted nor authenticated. In production, you must encrypt and authenticate parties messages.

Run Keygen

Open 3 terminal tabs for each party. Run:

  1. ./gg20_keygen -t 1 -n 3 -i 1 --output local-share1.json
  2. ./gg20_keygen -t 1 -n 3 -i 2 --output local-share2.json
  3. ./gg20_keygen -t 1 -n 3 -i 3 --output local-share3.json

Each command corresponds to one party. Once keygen is completed, you'll have 3 new files: local-share1.json, local-share2.json, local-share3.json corresponding to local secret share of each party.

Run Signing

Since we use 2-of-3 scheme (t=1 n=3), any two parties can sign a message. Run:

  1. ./gg20_signing -p 1,2 -d "hello" -l local-share1.json
  2. ./gg20_signing -p 1,2 -d "hello" -l local-share2.json

Each party will produce a resulting signature. -p 1,2 specifies indexes of parties who attends in signing (each party has an associated index given at keygen, see argument -i), -l file.json sets a path to a file with secret local share, and -d "hello" is a message being signed.

Running Demo on different computers

While previous steps show how to run keygen & signing on local computer, you actually can run each party on dedicated machine. To do this, you should ensure that parties can reach SM Server, and specify its address via command line argument, eg:

./gg20_keygen --address http://10.0.1.9:8000/ ...

Run GG18 Demo

The following steps are for setup, key generation with n parties and signing with t+1 parties.

Setup

  1. We use shared state machine architecture (see white city). The parameters parties and threshold can be configured by changing the file: param. a keygen will run with parties parties and signing will run with any subset of threshold + 1 parties. param file should be located in the same path of the client software.

  2. Install Rust. Run cargo build --release --examples (it will build into /target/release/examples/)

  3. Run the shared state machine: ./gg18_sm_manager. By default, it's configured to be in 127.0.0.1:8000, this can be changed in Rocket.toml file. The Rocket.toml file should be in the same folder you run sm_manager from.

KeyGen

run gg18_keygen_client as follows: ./gg18_keygen_client http://127.0.0.1:8000 keys.store. Replace IP and port with the ones configured in setup. Once n parties join the application will run till finish. At the end each party will get a local keys file keys.store (change filename in command line). This contains secret and public data of the party after keygen. The file therefore should remain private.

Sign

Run ./gg18_sign_client. The application should be in the same folder as the keys.store file (or custom filename generated in keygen). the application takes three arguments: IP:port as in keygen, filename and message to be signed: ./gg18_sign_client http://127.0.0.1:8001 keys.store "KZen Networks". The same message should be used by all signers. Once t+1 parties join the protocol will run and will output to screen signature (R,s).

The ./gg18_sign_client executable initially tries to unhex its input message (the third parameter). Before running ensure two things:

  1. If you want to pass a binary message to be signed - hex it.
  2. If you want to pass a textual message in a non-hex form, make sure it can't be unhexed. Simply put, the safest way to use the signing binary is to just always hex your messages before passing them to the ./gg18_sign_client executable.

Example

To sign the message hello world, first calculate its hexadecimal representation. This yields the 68656c6c6f20776f726c64. Then, run:

./gg18_sign_client http://127.0.0.1:8000 keys.store "68656c6c6f20776f726c64"

GG18 demo

Run ./run.sh (located in /demo folder) in the main folder. Move params file to the same folder as the executables (usually /target/release/examples). The script will spawn a shared state machine, clients in the number of parties and signing requests for the threshold + 1 first parties.

gg18_sm_manager rocket server runs in production mode by default. You may modify the ./run.sh to config it to run in different environments. For example, to run rocket server in development:

ROCKET_ENV=development ./target/release/examples/sm_manager

Contributions & Development Process

The contribution workflow is described in CONTRIBUTING.md, in addition the Rust utilities wiki contains information on workflow and environment set-up.

License

Multi-party ECDSA is released under the terms of the GPL-3.0 license. See LICENSE for more information.

Contact

Feel free to reach out or join ZenGo X Telegram for discussions on code and research.

References

[1] https://eprint.iacr.org/2017/552.pdf

[2] https://eprint.iacr.org/2019/114.pdf

[3] https://eprint.iacr.org/2019/503.pdf

[4] https://eprint.iacr.org/2020/540.pdf

multi-party-ecdsa's People

Contributors

1xstj avatar dmytrotym avatar elichai avatar evantedesco avatar gauthamastro avatar gbenattar avatar haoyuathz avatar k1rill-fedoseev avatar kigawas avatar leontiadzen avatar matanhamilis avatar nmahendru avatar oleiba avatar omershlo avatar rex4539 avatar rimbi avatar romanz avatar talbeerysec avatar tetratorus avatar tmpfs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

multi-party-ecdsa's Issues

test_d_log_proof_party_two_party_one' panicked at 'assertion failed: party_two_seco nd_message.d_log_proof_result.is_ok()'

Run with: seq 50 | xargs -Iz cargo test:

failures:

---- protocols::two_party_ecdsa::lindell_2017::test::tests::test_d_log_proof_party_two_party_one stdout ----
thread 'protocols::two_party_ecdsa::lindell_2017::test::tests::test_d_log_proof_party_two_party_one' panicked at 'assertion failed: party_two_seco
nd_message.d_log_proof_result.is_ok()', src/protocols/two_party_ecdsa/lindell_2017/test.rs:26:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::print
             at libstd/sys_common/backtrace.rs:71
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:221
   4: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
             at libstd/panicking.rs:475
   5: secp256k1_sha256_transform
             at /Users/travis/build/rust-lang/rust/src/libstd/panicking.rs:409
   6: multi_party_ecdsa::protocols::two_party_ecdsa::lindell_2017::test::tests::test_d_log_proof_party_two_party_one
             at src/protocols/two_party_ecdsa/lindell_2017/test.rs:26
   7: multi_party_ecdsa::__test::TESTS::{{closure}}
             at src/protocols/two_party_ecdsa/lindell_2017/test.rs:9
   8: core::ops::function::FnOnce::call_once
             at /Users/travis/build/rust-lang/rust/src/libcore/ops/function.rs:223
   9: <F as alloc::boxed::FnBox<A>>::call_box
             at libtest/lib.rs:1454
             at /Users/travis/build/rust-lang/rust/src/libcore/ops/function.rs:223
             at /Users/travis/build/rust-lang/rust/src/liballoc/boxed.rs:640
  10: panic_unwind::dwarf::eh::read_encoded_pointer
             at libpanic_unwind/lib.rs:106


failures:
    protocols::two_party_ecdsa::lindell_2017::test::tests::test_d_log_proof_party_two_party_one

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

Update benchmarks

rust-paillier has been updated from n to nn. This change should effect the benchmark of keygen.

Can't run both CCLST keygen and sign test at the same time

While running protocols::two_party_ecdsa::cclst_2019::test::tests::test_two_party_sign or protocols::two_party_ecdsa::cclst_2019::test::tests::test_full_key_gen is always working and passing. Trying to just cargo test --features=cclst returns a PARI error. Each time a different one:

It can sometimes work, while other times the following errors are received:

  ***   the PARI stack overflows !
  current stack size: 10000000 (9.537 Mbytes)
  [hint] set 'parisizemax' to a non-zero value in your GPRC

  ***   ***   Error in the PARI system. End of program.
  unknown type 31.  ***   Error in the PARI system. End of program
  ***   
the PARI stack overflows !
  current stack size: 10000000 (9.537 Mbytes)
  [hint] set 'parisizemax' to a non-zero value in your GPRC
  ***   Error in the PARI system. End of program.
  ***   unknown type 26.  ***   Error in the PARI system. End of program.

Might be connected topari_init in class_groups lib

Benchmarks!

Currently we have only keyGen benches:

  • we need to update keygen benchs (currently there are compilation errors)
  • we need to add signing benchs

thread 'test_two_party_keygen' panicked at 'assertion failed'

Run with: seq 50 | xargs -Iz cargo test:

---- test_two_party_keygen stdout ----
thread 'test_two_party_keygen' panicked at 'assertion failed: party_two::PaillierPublic::verify_range_proof(&party_two_paillier, &challenge,
                                              &encrypted_pairs, &proof)', tests/keygen_integ_test.rs:53:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::print
             at libstd/sys_common/backtrace.rs:71
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:221
   4: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
             at libstd/panicking.rs:475
   5: secp256k1_sha256_transform
             at /Users/travis/build/rust-lang/rust/src/libstd/panicking.rs:409
   6: keygen_integ_test::test_two_party_keygen
             at tests/keygen_integ_test.rs:53
   7: keygen_integ_test::__test::TESTS::{{closure}}
             at tests/keygen_integ_test.rs:8
   8: core::ops::function::FnOnce::call_once
             at /Users/travis/build/rust-lang/rust/src/libcore/ops/function.rs:223
   9: <F as alloc::boxed::FnBox<A>>::call_box
             at libtest/lib.rs:1454
             at /Users/travis/build/rust-lang/rust/src/libcore/ops/function.rs:223
             at /Users/travis/build/rust-lang/rust/src/liballoc/boxed.rs:640
  10: panic_unwind::dwarf::eh::read_encoded_pointer
             at libpanic_unwind/lib.rs:106


failures:
    test_two_party_keygen

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

Un-consistency in unit test test_bit_length_create_commitment

To reproduce, in: multi-party-ecdsa/src/cryptographic_primitives/commitments/hash_commitment.rs, you can add a for loop in the test itself:

    #[test]
    fn test_bit_length_create_commitment() {
        for _ in 1..100 {
            let message = BigInt::sample(SECURITY_BITS);
            let (commitment, blind_factor) = HashCommitment::create_commitment(&message);
            //test commitment length  - works because SHA256 output length the same as sec_bits
            assert_eq!(commitment.to_str_radix(16).len(), SECURITY_BITS / 4);
            assert_eq!(blind_factor.to_str_radix(16).len(), SECURITY_BITS / 4);
        }
    }
---- cryptographic_primitives::commitments::hash_commitment::tests::test_bit_length_create_commitment stdout ----
	thread 'cryptographic_primitives::commitments::hash_commitment::tests::test_bit_length_create_commitment' panicked at 'assertion failed: `(left == right)`
  left: `63`,
 right: `64`', src/cryptographic_primitives/commitments/hash_commitment.rs:69:13
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:

Android

Issue stub to integrate changes required to run on Android

Signing "randomly" fail on the verify signature assertion

After writing benches which execute signing many times, here is what I see:

thread 'main' panicked at 'assertion failed: party_one::verify(&ec_context, &signature, &pubkey, &message).is_ok()', benches/two_party_ecdsa/lindell_2017/signing.rs:68:13
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::begin_panic
   6: bencher::Bencher::iter
   7: bencher::Bencher::auto_bench
   8: bencher::run_tests_console
   9: signing::main
  10: std::rt::lang_start::{{closure}}
  11: std::panicking::try::do_call
  12: __rust_maybe_catch_panic
  13: std::rt::lang_start_internal
  14: main

Write SecondMsgClientProofVerification.

Write SecondMsgClientProofVerification of party 1, it can be inspired by the following code that we wrote in the past. Also make sure to document that properly (or create a follow up issue).

pub struct SecondMsgClientProofVerification {
    pk_commitment_blind_factor: BigUint,
    zk_pok_blind_factor: BigUint,

    pk: PublicKey,
    pk_t_rand_commitment : PublicKey,
    challenge_response : BigUint,
}

impl SecondMsgClientProofVerification {
    pub fn create(s: &Secp256k1,
                  client_pk_t_rand_commitment: &PublicKey,
                  client_challenge_response: &BigUint,
                  client_pk: &PublicKey) -> Result<(), &'static str>
    {
        //TODO: change. challenge is not a commitment, it is a hash function.
        let challenge = MPCUtils::get_commitment(
            vec![
                &client_pk_t_rand_commitment.to_point().x,
                &s.get_base_point().x,
                &client_pk.to_point().x],
            &Secp256k1::get_q());

        let mut client_pk_challenge = client_pk.clone();
        assert!(client_pk_challenge.mul_assign(&s, &SecretKey::from_big_uint(s, &challenge)).is_ok());

        let mut pk_verifier = PublicKey::to_key(&s, &s.get_base_point());
        assert!(pk_verifier.mul_assign(
            s, &SecretKey::from_big_uint(s, client_challenge_response)).is_ok());

        assert!(pk_verifier.combine(&s, &client_pk_challenge).is_ok());

        if pk_verifier == *client_pk_t_rand_commitment {
            Ok(())
        } else {
            Err("Error during the zero knowledge proof of knowledge of the client private key!")
        }

        // TODO: use local in-memory hash to output SecondMsgClientProofVerification
    }
}

Permissive Relicensing

Suggesting that you might relicense this project under MIT or BSD or Public Domain.

Many cryptographic libraries are licensed as such (e.g., secp256k1, libsnark, nacl, etc).

This makes it easier to include them in a diverse set of projects, and is more likely to get attention from outside contributors.

GPL is a fine license and has many benefits, so I understand the desire to use it, but for crypto libraries something more permissive is probably appropriate.

Add optional range proofs for Alice and Bob in GG18

In the multi-party ECDSA case, in mta.rs, in impl MessageA the range proofs are not
included for Alice, and in impl MessageB, instead it is only computing a proof of
knowledge of a discrete logarithm of bG instead of proving that b is in the
appropriate range as per page 8 of GG18, where it says Bob should be proving in ZK
that b < K

The rational why we might want to have the range proof is in GG18 on page 9,
basically it would allow a malicious party to make the threshold signature fail
verification and let them go unblamed.

Motivation to drop the range proofs is discussed in Section 5 (page 19) of the paper but we think that it should be optional.

Make the {2,2} protocol state machine

First Step
take the hash of the public key to be a token.
save to local storage (cache):

  1. id for token
  2. next for next function for this token

place a test at the beginning of every function for party_one,party_two such that only if :

  1. the token id is registered in the storage
  2. the function that is being called is next

Then execute the function and update next, otherwise abort.

After the last function of the protocol has been called - clean the id from storage

Second Step
make a token that will connect between key generation and signing so that the signing parties in case they run Key Generation multiple times will know which private key to use for signing.
suggestion: use the local public keys (H(secret_share * G)) to identify keys. This should be saved to permanent storage.

More specific message naming

Let's take KeyGenBroadcastMessage1 in gg2018 as an example. It can be improved since:

  1. Broadcast has no more information except that we should broadcast this kind of message, but we may also broadcast other messages, thus, the Broadcast should not be used here.

  2. Actually it's Commit, Decommit = Com(pk, M, R) in the paper, it can be simply called KeyGenCommit

Run 2-party ECDSA on iOS.

The purpose of this task is to build a proof of concept for running this code on iOS.
Nice to have: simple benches that we will be able to compare with benches running on a machine.

Success criteria:

  • Ability to call locally at least one function of 2-party ECDSA on iOS
  • Documentation on how to run
  • Simple benches (execution time for functions of your choice)

InvalidPublicKey during signature generation

Hi. I am using 0.2.8 version of multi-party-ecdsa.
In particular, I have used {1,3} party scheme.
I have recently faced with the following error during signature generation process:

DEBUG: number: 1, uuid: "0x2c658b237993db261cb073e6d9d985ea0383441380cc1fd47f55993e2d35ef18"
DEBUG: ["round0"] party 2 => party 1
DEBUG: ["round1"] party 2 => party 1
DEBUG: ["round2"] party 2 => party 1
DEBUG: ["round3"] party 2 => party 1
DEBUG: ["round4"] party 2 => party 1
DEBUG: ["round5"] party 2 => party 1
DEBUG: ["round6"] party 2 => party 1
DEBUG: ["round7"] party 2 => party 1
DEBUG: ["round8"] party 2 => party 1
DEBUG: ["round9"] party 2 => party 1
DEBUG: party 1 Output Signature: 

R: SecretKey(782b3aef10b775721336204d593683bdf2bd57b2cbd43e7e05073f3db5507dbb)
s: SecretKey(28c35476586b15d1dba7ab8c7cef8a1ab6c333cbf8a3aae06df7d3edb3aad1f9) 


DEBUG: thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidPublicKey', src/libcore/result.rs:1165:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

Signatures generation was restarted several times, but this did not help, the same error appeared every time.
Unfortunately, I was not able to reproduce this issue with more verbose logging.

2p -ecdsa protocol : use curv lib for dh key exchange

there's a redundancy where the same code for ECDH is found in curv:
https://github.com/KZen-networks/curv/blob/master/src/cryptographic_primitives/twoparty/dh_key_exchange.rs
and is alos used by 2p-ecdsa for key generation and ephemeral key generation.
The only difference is that in 2p-ecdsa, party 1 must choose x1 < q/3 (for q curve order) for the range proof later to work. this can be done by generating x1 in this lib such that the condition holds and call curv ECDH with predefined randomness.

how to export the pubkey when use gg18_keygen_client ?

follow the multi-party-ecdsa demo, when keygen use gg18_keygen_client, the output file keys.store, that is a json file.
what's the mean of all fields ? especially how to generate the pubkey based on keys.store file ?

Add a "blame phase" to GG18

Identifiable Abort in Threshold Signatures (IATS) - problem statement

Informally, IATS is a way for honest parties to either output a valid signature or to agree on the set of parties that behaved maliciously in the computation.
Formally, there are various security properties that allow for different levels of “accountability” in MPC . Taken from https://eprint.iacr.org/2016/611.pdf here is an example of Openability and Auditability properties and how they can be dressed on top of MPC ideal functionality. In our case we are mainly concerned with Identifiable Abort or better Public Verifiability which allows honest parties to prove to a third party (did not participate in the computation) that a given party behaved in a malicious way. (https://eprint.iacr.org/2016/187.pdf section 8)

Few other papers that are dealing with “Accountability” properties of MPC are:
https://eprint.iacr.org/2014/075.pdf,
https://link.springer.com/chapter/10.1007/978-3-319-49175-2_8 ,
https://eprint.iacr.org/2015/058.pdf ,
https://eprint.iacr.org/2018/942
A related properties are those of fairness and guaranteed output delivery in MPC.

The motivation is very simple. We wish to allow honest signers of a threshold signature to fight against Denial of Service by a small set of malicious parties that deliberately fails the computation time after time. In other words we want to preserve Liveness as long as there are less than threshold malicious parties participating. This can be translated to a “Blame” phase in protocol that rely on threshold signing. It is most critical in a n-out-of-n setting where all parties must be honest in order for the signature to be valid. An attacker can fail the signing each time and there will be no tool for the n parties to prove learn which one of them is the attacker.

Add support for {2,3} threshold signing

Lindell's Key Generation [1] protocol could be adapted to support {2,3}-threshold Signing if we implement the functionality F_rand from [2] for generating shares of random values non-interactively.

  1. each party i chooses a random number r_i and sends it to party i+1.
  • The full private key will be r_1 * r_2 * r_3
    The roles of the Prover (party1 in Lindell's protocol) and the Verifier (party2 in Lindell's protocol) and their corresponding secret shares will be defined according to the following rules:
    rule 1: Each party will play the Prover for the party that received its r_i and will play the Verifier for the party that sent to it r_(i-1)
    rule 2: The private share of the Prover will always be r_i * r_(i-1) and the Verifier private key will always be r_(i+1)
  1. Each party i calculates alpha_i = r_(i-1)*G - r_i*G and send it to the other two parties
  2. Each party checks that sum(alpha_i) = 0, and aborts otherwise
  3. Every two parties do the following (designation of prover/verifier is according to rule1) :
  • The Prover party P_(i-1) defines x_1 = r_(i-1)*r_(i-2) and sends Q_1 = x_1*G to the Verifier, indexed i.
  • The Verifier V_i checks that Q_1 = r_(i-1) * [alpha_(i-1) + r_(i-1)*G], and aborts otherwise
  • The Verifier V_i defines x_2 = r_i and send Q_2 =x_2 * G to the Prover
  • The prover P_(i-1) checks that Q_2 = alpha_(i-2) + r_(i-1)*G, and aborts otherwise
  1. The Prover and Verifier engage with Lindell's Key Generation protocol as Party1 and Party2 respectively.

Lindell's signing protocol stays the same.
Note: numbering in this protocol is circular, for example for P_1 and V_2 we get x_1 = r_1*r_3 and alpha_1 = r_3*G - r_1*G.

[1] Y. Lindell. Fast Secure Two-Party ECDSA Signing - CRYPTO 2017 (Proceedings, Part II), volume 10402 of LNCS, pages 613–644. Springer,
2017
[2] Y. Lindell, A. Nof. A Framework for Constructing Fast MPC over Arithmetic Circuits with Malicious Adversaries and an Honest-Majority. pages 259-276. CCS 2017

compare performance with "multiparty ecdsa from ecdsa assumptions"

Secure Two-party Threshold ECDSA from ECDSA Assumptions (https://eprint.iacr.org/2018/499.pdf) is a work done by Doerner et al. The PoC code is provided in https://gitlab.com/neucrypt/mpecdsa . The code is provided under the Three-clause BSD License. For initial support we should:

  • switch to secp256k1 lib (the original code currently using its own elliptic curve implementation).
  • switch to cryptographic-utils (https://github.com/KZen-networks/cryptography-utils) instead of what they use for simple cryptographic protocols and arithmetic.
  • delete communication layer (so that later we can add our own)
  • code review for secure programming
  • code optimizations

Brainstorming on unit testing for each protocol step

I would like to start a thread about how to properly unit test two party ECDSA.
Each function should be tested independently. It is obvious on how to inject edge cases as well as dummy values, the question here is how to unit test that values returned are expected (without any interaction with the other party (E.g. the client).

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.