Skip to content

Commoncoin#23

Draft
Mitrofanius wants to merge 3 commits intomainfrom
commoncoin
Draft

Commoncoin#23
Mitrofanius wants to merge 3 commits intomainfrom
commoncoin

Conversation

@Mitrofanius
Copy link
Contributor

Common coin package with ECDH common coin implementation.

  1. My main question is if the overall logic and use of kyber libraries (dleq, share, bn254) is correct.

  2. And a follow-up one: do RecoverPubPoly and Commit (lines 142-150) do the same as the combination of shares as in the combination of shares? If not then I misunderstood something profoundly.

image

@Mitrofanius Mitrofanius requested a review from AnomalRoil May 28, 2025 23:47
Copy link

@AnomalRoil AnomalRoil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not work since you're always hashing the empty string as far as I understand the code atm. Please make sure to add some "negative tests" to catch that failure


on:
push:
branches: [ commoncoin ] # TODO should be done differently

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes this should be done properly, not just on your branch.

@@ -0,0 +1,195 @@
package commoncoin

// The value of a coin C is obtained by first

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always refer in the docs to the paper, including page and section/chapter that you're implementing when it's based on a paper.

Comment on lines 106 to 111
proof, xG, xH, err := dleq.NewDLEQProof(c.s, c.gVK, c.gTilde, c.si.V)
gTildeShare := c.s.Point().Mul(c.si.V, c.gTilde)
if !xH.Equal(gTildeShare) {
panic("NOOOO")
}
if !xG.Equal(c.s.Point().Mul(c.si.V, c.gVK)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When implementing cryptographic papers, or papers/algorithm in general, it's a good practice to refer to the spec / documentation / paper using comments, e.g.:

Suggested change
proof, xG, xH, err := dleq.NewDLEQProof(c.s, c.gVK, c.gTilde, c.si.V)
gTildeShare := c.s.Point().Mul(c.si.V, c.gTilde)
if !xH.Equal(gTildeShare) {
panic("NOOOO")
}
if !xG.Equal(c.s.Point().Mul(c.si.V, c.gVK)) {
proof, xG, xH, err := dleq.NewDLEQProof(c.s, c.gVK, c.gTilde, c.si.V)
// ~g_i = x_i*~g
gTildeShare := c.s.Point().Mul(c.si.V, c.gTilde)
// sanity check that xH == ~g_i
if !xH.Equal(gTildeShare) {
panic("NOOOO")
}
// sanity check that xG == x_i*VK_i
if !xG.Equal(c.s.Point().Mul(c.si.V, c.gVK)) {

Because then we can see that these last two checks are actually redundant: the goal of NewDLEQProof is to compute these values, so while I see why you might have wanted to check that it was correct, I think these two checks are not useful.

Instead add maybe a comment above NewDLEQProof saying what xG and xH are, because they aren't called xG and xH in the paper, right? Maybe even rename xH into gTildeShare since that's what you want.

tossResult := InvalidTossResult
for _, coinShare := range c.shares {
if c.VerifyShare(coinShare) != nil {
// log debug

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you probably want to log that, maybe at the Warn level even, not even Debug level.

n int // number of parties
}

func NewECDHCommonCoin(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function definitively needs some docs about what it does and what it expects as parameters since the name of the parameters aren't self-explanatory at all

Comment on lines 147 to 152
hash := c.s.Hash()
if _, err := pubPoly.Commit().MarshalTo(c.s.Hash()); err != nil {
return tossResult, errors.New("err marshalling gTilde^secret to the hash function")
}

hashGTildeZero := hash.Sum(nil)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems very wrong. The tests should catch that it's not working.

You're Marshalling to a new Hash instance, not the one you're computing the Sum of next. So you're always getting the same value for hashGTildeZero.

Please add a test that catches the problem and fix it.

// could copy lagrangeBasis(...) from share instead
pubPoly, err := share.RecoverPubPoly(c.s, validPubShares, c.k, c.n)
if err != nil {
return CoinOne, err

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it be rather

Suggested change
return CoinOne, err
return tossResult, err

if not, it deserves a comment.

… to add some comments referring to the paper for clarification
Copy link

@AnomalRoil AnomalRoil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM just need to make sure your tests and linter are passing now.

on:
push:
branches: [ commoncoin ] # TODO should be done differently
branches: [ main ]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just on all branches?

validPubShares = append(validPubShares, &coinShare.GTildeShare)
}
if len(validPubShares) < c.k {
return tossResult, fmt.Errorf("not enough calid coin shares to reveil common coin value")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return tossResult, fmt.Errorf("not enough calid coin shares to reveil common coin value")
return tossResult, fmt.Errorf("not enough valid coin shares to reveal common coin value")

Comment on lines +38 to +45
type CommonCoin interface {
LocalShare() (CoinShare, error)
Toss() (CoinToss, error) // combines shares internally
VerifyShare() error
AddShare(CoinShare) error
NumShares() int
ResetCoinID(coinID string) error // to start another round
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can enforce at compile time that the ECDHCommonCoin struct satisfies the CommonCoin interface by adding an empty global variable like that:

var _ CommonCoin = &ECDHCommonCoin{} 

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 this pull request may close these issues.

2 participants