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

Remove BLS signatures aggregate #540

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open

Remove BLS signatures aggregate #540

wants to merge 12 commits into from

Conversation

K1li4nL
Copy link
Contributor

@K1li4nL K1li4nL commented Aug 16, 2024

As the BLS signature aggregate scheme is vulnerable to rogue public-key attack, this pr removes the "aggregate" part of the code and use BDN where BLS aggregates were used.

@K1li4nL K1li4nL marked this pull request as draft August 16, 2024 13:25
@K1li4nL K1li4nL force-pushed the clean-up-bls branch 3 times, most recently from 0b262c6 to fbbb53b Compare August 19, 2024 06:51
@K1li4nL K1li4nL marked this pull request as ready for review August 19, 2024 07:01
Copy link
Contributor

@pierluca pierluca left a comment

Choose a reason for hiding this comment

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

Overalls LGTM, but this could benefit from @AnomalRoil 's review.

pairing/bls12381/bls12381_test.go Outdated Show resolved Hide resolved
@K1li4nL K1li4nL marked this pull request as draft September 2, 2024 09:09
@K1li4nL
Copy link
Contributor Author

K1li4nL commented Sep 2, 2024

Turning this back into draft, I didn't properly ran the benchmarks... It seems that our bdn implementation assumes kyber.Scalar to be mod.Int, making it incompatible to use with circl_bls12381

sign/bls/bls.go Outdated Show resolved Hide resolved
sign/bls/bls.go Outdated
// new version of the protocol should be used to make sure a signature
// When using aggregated signatures, this version is vulnerable to rogue
// public-key attack.
// The new version of the protocol should be used to make sure a signature
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// The new version of the protocol should be used to make sure a signature
// The `sign/bdn` package should be used to make sure a signature

// such that src[0] goes into dst[len-1] and vice versa.
// dst and src may be the same slice but otherwise must not overlap.
func reverse(dst, src []byte) []byte {
if dst == nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

What if len(dst) != len(src) ? Either explain behaviour in doc, or enforce len(dst) == len(src)?

Copy link
Contributor Author

@K1li4nL K1li4nL Sep 11, 2024

Choose a reason for hiding this comment

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

good point, I enforced the equality

sign/bdn/bdn.go Outdated
Comment on lines 86 to 95
l := len(dst)
for i, j := 0, l-1; i < (l+1)/2; {
dst[i], dst[j] = src[j], src[i]
i++
j--
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
l := len(dst)
for i, j := 0, l-1; i < (l+1)/2; {
dst[i], dst[j] = src[j], src[i]
i++
j--
}
for left, right := 0, len(dst)-1; left < right; left, right = left+1, right-1 {
dst[left], dst[right] = src[right], src[left]
}

sign/bdn/bdn.go Outdated
Comment on lines 64 to 74
b, err := mod.NewIntBytes(out[i*16:(i+1)*16], modulus128, kyber.LittleEndian).MarshalBinary()
if err != nil {
return nil, err
}
if g.Scalar().ByteOrder() == kyber.BigEndian {
reverse(b, b)
}

coefs[i] = g.Scalar()
coefs[i].SetBytes(b)
Copy link
Contributor

Choose a reason for hiding this comment

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

g.Scalar is of size 32 whereas the coefs in bdn are meant to be of size 128 bits, e.g. 16.
I think that's explaining the issues you've had so far.

Also why not just:

Suggested change
b, err := mod.NewIntBytes(out[i*16:(i+1)*16], modulus128, kyber.LittleEndian).MarshalBinary()
if err != nil {
return nil, err
}
if g.Scalar().ByteOrder() == kyber.BigEndian {
reverse(b, b)
}
coefs[i] = g.Scalar()
coefs[i].SetBytes(b)
b, err := mod.NewIntBytes(out[i*16:(i+1)*16], modulus128, g.Scalar().ByteOrder()).MarshalBinary()
if err != nil {
return nil, err
}
coefs[i] = b

Copy link
Contributor Author

@K1li4nL K1li4nL Sep 10, 2024

Choose a reason for hiding this comment

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

Although it looks cleaner, this is a breaking change, these bytes in out were always interpreted in little-endian mod 2^128 with no regard to the endianness of the suite.

About the 32bytes, yes exactly, when we assumed the suite would use mod/int as scalars we had 16bytes because the modulus of our mod/int scalar was defined as 2^128:

b, err := mod.NewIntBytes(out[i*16:(i+1)*16], modulus128, kyber.LittleEndian)

Now that we are agnostic to the scalar implementation underneath, we can't define the modulus that way (unless we touch the interface) hence we get the imprecise 32. I am not sure about the best way to solve that.

@K1li4nL K1li4nL marked this pull request as ready for review September 11, 2024 17:01
Copy link

sonarcloud bot commented Sep 11, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants