herumi / bls

288 stars 132 forks source link

Bug report: Signature verification failure #77

Closed Qiao-Jin closed 2 years ago

Qiao-Jin commented 2 years ago

Problem:

Signature verification failure

Steps to reproduce:

  1. Generate 4 private keys p1, p2, p3, p4
  2. Calculate corresponding public keys P1, P2, P3, P4
  3. Calculate aggregate private key p = p1 + 7 p2 + 49 p3 + 343 * p4
  4. Calculate aggregate public key P = P1 + 7 P2 + 49 P3 + 343 * P4
  5. Use p to sign a message and verify it with P

Expected:

Verification pass.

Observed:

Verification failed.

Qiao-Jin commented 2 years ago

@herumi

herumi commented 2 years ago

What code do you test?

Qiao-Jin commented 2 years ago

What code do you test?

bls384_256

Qiao-Jin commented 2 years ago

And when using only P1, P2, P3 the verification result will be correct:

Steps:

  1. Generate 3 private keys p1, p2, p3
  2. Calculate corresponding public keys P1, P2, P3
  3. Calculate aggregate private key p = p1 + 7 p2 + 49 p3
  4. Calculate aggregate public key P = P1 + 7 P2 + 49 P3
  5. Use p to sign a message and verify it with P

Similiarly, when using 1, 2 or 3 private keys verification will be correct, but when the number exceeds 4 verification result will be incorrect.

Qiao-Jin commented 2 years ago

@herumi Could you please do a test locally to verify this result?

herumi commented 2 years ago

I don't know how to compute 49 * P3 and so on, but the following goes well. So I wonder that your code has something wrong.

package main

import (
    "fmt"
    "github.com/herumi/bls-eth-go-binary/bls"
)

func main() {
    bls.Init(bls.BLS12_381)
    n := 4
    secs := make([]bls.SecretKey, n)
    pubs := make([]bls.PublicKey, n)
    sigs := make([]bls.Sign, n)
    msg := []byte("abcdefg")
    g1vec := make([]bls.G1, n)
    g2vec := make([]bls.G2, n)
    for i := 0; i < n; i++ {
        secs[i].SetByCSPRNG()
        pubs[i] = *secs[i].GetPublicKey()
        sigs[i] = *secs[i].SignByte(msg)
        fmt.Printf("sec[%v]=%s\n", i, secs[i].SerializeToHexStr())
        g1vec[i] = *bls.CastFromPublicKey(&pubs[i])
        g2vec[i] = *bls.CastFromSign(&sigs[i])
    }
    vs := make([]bls.Fr, n)
    for i := 0; i < n; i++ {
        vs[i].SetInt64(int64(i * i + 5))
    }
    var P bls.PublicKey
    bls.G1MulVec(bls.CastFromPublicKey(&P), g1vec, vs)
    var Q bls.Sign
    bls.G2MulVec(bls.CastFromSign(&Q), g2vec, vs)
    fmt.Printf("verify=%v\n", Q.VerifyByte(&P, msg)) // show true
}
Qiao-Jin commented 2 years ago

I don't know how to compute 49 * P3 and so on, but the following goes well. So I wonder that your code has something wrong.

I use func blsPublicKeyAdd 48 times for this multiplication: https://github.com/herumi/bls/blob/3f3850a6eac71e1ce31b4a3d9b85aa7af2a2d08e/src/bls_c_impl.hpp#L601

I actually use this func to func call blsPublicKeyAdd: https://github.com/NethermindEth/cortex-cryptography-bls/blob/641f25297465e494dfcf62cd31ec44d6dc86a927/src/Cortex.Cryptography.Bls/BLSHerumi.cs#L78

In case of privateKey, I add them as big integers

Qiao-Jin commented 2 years ago

And maybe you can try this coefficient vector [1, 7, 49, 343], it seems that the sum of the coefficients can affect verification result

Qiao-Jin commented 2 years ago

It seems in your code you generate the aggregate signature with signatures. And in my code it's got from aggregated private keys...

Qiao-Jin commented 2 years ago

It seems that I got some wrong logic in my code. I will reopen this if error still exists after correction.

herumi commented 2 years ago

@Qiao-Jin I've added MulVec method, so you can use it. https://github.com/herumi/bls/blob/master/ffi/cs/bls_test.cs#L215-L233