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

DKG Protocol - Public Key Change After Reshare #489

Closed
leetingo opened this issue Jun 10, 2023 · 9 comments
Closed

DKG Protocol - Public Key Change After Reshare #489

leetingo opened this issue Jun 10, 2023 · 9 comments

Comments

@leetingo
Copy link

DKG Protocol - Public Key Change After Reshare

Description:

I am currently working with the DKG protocol for threshold encryption and decryption as provided under the share/dkg/pedersen folder.

While exploring the capabilities of the protocol, I've noticed that the DKG supports resharing of secrets, which is a helpful feature. However, it appears that the public key changes post-reshare, which is causing current threshold encryption fail in my application.

Expected Behavior:

Ideally, I would expect that the public key remains constant after the reshare operation.

Actual Behavior:

Currently, the public key changes each time a reshare is performed.

Steps to Reproduce:

  1. Initialize the DKG protocol
  2. Perform the reshare operation
  3. Observe the change in the public key

Additional Information:

If it is by design that the public key changes after a reshare, could you please explain the reasoning behind this? If there's a way to maintain the same public key post-reshare, I'd appreciate if you could guide me on how to do it. I noticed that checking public key remains the same is mentioned in

// 3. public polynomial is different but for the first coefficient /public
, but it is not implemented in the relevant code.

Looking forward to your support on this issue.

Thank you in advance!

@ineiti
Copy link
Member

ineiti commented Jun 21, 2023

Can you please give a short code snippet that shows this behaviour? I think you're right that the public key should stay the same, but I'm not sure we're talking about the same public key...

@leetingo
Copy link
Author

I have added a test at the end of TestDKGResharing funtion in dkg_test.go to verify whether the old public key and the new public key are the same. I'm not sure if I'm doing it right. My app use this public key to encrypt messages and the threshold encryption/decryption works fine.

Here is the relevant code snippet from the test:

// 3. for i := 0; i < len(dkgs); i++ { require.Equal(t, shares[i].Public(), newShares[i].Public()) }

@ineiti
Copy link
Member

ineiti commented Jun 26, 2023

I'll have a look into it tomorrow, but it seems you're comparing the public keys of the different nodes, which of course will be different after resharing, because that's the point of it.

You might want to look if there is some Aggregate key or so and compare that, which should be the same before and after resharing.

@ineiti
Copy link
Member

ineiti commented Jun 26, 2023

And if you can create a PR with that additional test, it'll be easier for me to check it.

@leetingo
Copy link
Author

I reviewed the dkg code again, and what I should be checking is whether the public key of each node has changed before and after resharing. According to the code comments, the public polynomial should be different after resharing, but the first coefficient of the public polynomial (which is the dkg public key) should remain unchanged.

@ineiti
Copy link
Member

ineiti commented Jul 3, 2023

Can you test whether this one stays constant after resharing?

// Public returns the public key associated with the distributed private key.

That's what I think must not change between resharing. Also, you could test that the following doesn't change, but this is already done in the tests:

https://github.com/dedis/kyber/blob/master/share/vss/pedersen/vss.go#L481

In a real-world implementation you should never have access to the other shares, so you will not be able to do the RecoverSecret. But you should always be able to do the func (d *DistKeyShare) Public() kyber.Point.

I hope that helps.

@leetingo
Copy link
Author

leetingo commented Jul 4, 2023

This is exactly what I am testing. In the test function, all the DistKeyShares generated by every node are stored in the 'shares' slice, and the DistKeyShares after resharing are stored in the 'newShares' slice. Therefore, I tested whether the Public is the same before and after resharing.

@ineiti
Copy link
Member

ineiti commented Jul 4, 2023

And the tests pass? So all is well now?

@K1li4nL
Copy link
Contributor

K1li4nL commented Aug 16, 2024

As far as I understand, this check is now present, it was introduced in #512 as we swapped our pedersen dkg implementation with the one from DRAND. Thank you for you work @leetingo ! I believe this issue as well as #491 can be closed.

// test if re-creating secret key gives same public key
var shares []*share.PriShare
for _, res := range results {
shares = append(shares, res.Key.PriShare())
}
// test if shares are public polynomial evaluation
exp := share.NewPubPoly(suite, suite.Point().Base(), results[0].Key.Commitments())
for _, share := range shares {
pubShare := exp.Eval(share.I)
expShare := suite.Point().Mul(share.V, nil)
require.True(t, pubShare.V.Equal(expShare), "share %s give pub %s vs exp %s", share.V.String(), pubShare.V.String(), expShare.String())
}

@K1li4nL K1li4nL closed this as completed Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants