udi0peled / cmp_ecdsa_mpc_poc

Simulation based secure MPC protocol for ECDSA - POC and benchmark
6 stars 6 forks source link

A question abount the mpc-schnorr protocol. #2

Open james-ray opened 1 year ago

james-ray commented 1 year ago

Hi, thanks for the open of this brilliant project, I really learnt a lot from both the thesis and the code. But I got a little question about the implementation of the schnorr signature part. Would you please help me clarify it?

The signature part:

void cmp_schnorr_signing_round_1_exec(const cmp_party_t *party, const scalar_t msg) {
    printf("### Round 1.\n");

    cmp_schnorr_signing_data_t *sida = party->schnorr_signing_data;

    // Set current player's sigma

    scalar_t first_term = scalar_new();
    scalar_mul(first_term, party->secret_x, msg, party->ec_order);
    scalar_sub(sida->sigma, party->k, first_term, party->ec_order);
    scalar_free(first_term);

And the verification part:

int verify_schnorr_signature( const cmp_party_t *party, const gr_elem_t R, const scalar_t s, const scalar_t msg, const gr_elem_t pubkey)
{
  gr_elem_t result = group_elem_new(party->ec);

  group_operation(result, NULL, party->ec_gen, s, party->ec);
  group_operation(result, result, pubkey, msg, party->ec);

  int is_valid = group_elem_equal(result, R, party->ec);

  group_elem_free(result);

  return is_valid;
}

While I find the schnorr signature should use e=H(m||R), where || stands for a concatenate function. And s=r+ke. If we use msg m directly as the e here, the sig that generated will not get verified. Am I understanding wrong?

james-ray commented 1 year ago

Here is the code in btcec/schnorr/signature.go:

// Step 12.
//
// e = tagged_hash("BIP0340/challenge", bytes(R) || bytes(P) || m) mod n
var rBytes [32]byte
r := &R.X
r.PutBytesUnchecked(rBytes[:])  //rBytes是R的x坐标
pBytes := SerializePubKey(pubKey)  //pBytes是公钥序列化

commitment := chainhash.TaggedHash( 
    chainhash.TagBIP0340Challenge, rBytes[:], pBytes, hash,  // TagBIP0340Challenge是一个固定常数字符串, hash是消息摘要.   commitment就是e
)
var e btcec.ModNScalar
if overflow := e.SetBytes((*[32]byte)(commitment)); overflow != 0 {
    k.Zero()
    str := "hash of (r || P || m) too big"
    return nil, signatureError(ecdsa_schnorr.ErrSchnorrHashValue, str)
}

// Step 13.
//
// s = k + e*d mod n
s := new(btcec.ModNScalar).Mul2(&e, privKey).Add(&k)
k.Zero()

sig := NewSignature(r, s)

So, e= Hash(challenge||r||P||m).