herumi / bls

288 stars 132 forks source link

Supporting latest hash-to-curve #79

Closed b00f closed 2 years ago

b00f commented 2 years ago

Do you have plan to support new hash-to-curves? As I can see here the latest version is 13. The latest supported version is 5 (if I am not mistaken)

herumi commented 2 years ago

My library outputs the same points like the ones written in J.10.1. BLS12381G2_XMD:SHA-256_SSWURO of https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/ . https://github.com/herumi/mcl/blob/master/test/mapto_wb19_test.cpp#L474-L535

Those outputs does not changed from draft-08 https://www.ietf.org/rfcdiff?url1=draft-irtf-cfrg-hash-to-curve-08&url2=draft-irtf-cfrg-hash-to-curve-13&difftype=--hwdiff .

So I don't think that updates are necessary. How about it?

b00f commented 2 years ago

As I can see you are right, It hasn't change. By the way, my main concerns is why the driven public key from your library is not the same with bls12_381_plus.

As an example consider this private key: d0c6a560de2e60b6ac55386defefdf93b0c907290c2ad1b4dbd3338186bfdc68

Herumi: 37bfe636693eac0b674ae6603442192ef0432ad84384f0cec8bea5f63c9f45c29bf085b8b9b7f069ae873ccefe61a50a59ad3fefd729af5d63e9cb2325a8f064ab2514b3f846dbfded53234800603a9e752422ad48b99f835bcd95df945aac93

bls12_381_plus: af0f74917f5065af94727ae9541b0ddcfb5b828a9e016b02498f477ed37fb44d5d882495afb6fd4f9773e4ea9deee436030c4d61c6e3a1151585e1d838cae1444a438d089ce77e10c492a55f6908125c5be9b236a246e4082d08de564e111e65

Any explanation?

herumi commented 2 years ago

I think that the reason is using a different basepoint. If you use a "1" as a private key, then the public key shows the basepoint because publickey = privatekey * basepoint. Could you show me the result? How do you use my library?

b00f commented 2 years ago

Here is the test based on your library: https://github.com/zarbchain/zarb-go/blob/c673f2c08285eccde214567f084e9ff1dad9ffdc/crypto/bls/signature_test.go#L104-L113

Look here for the implementation:

herumi commented 2 years ago

https://github.com/zarbchain/zarb-go/blob/main/crypto/bls/bls.go#L4 Could you try not https://github.com/herumi/bls-go-binary but https://github.com/herumi/bls-eth-go-binary ? The latter is the compatible mode with Ethereum 2 spec.

b00f commented 2 years ago

The issue is that the signature for bls-eth-go-binary set to 96 bytes, which I prefer to not use it. It increased the size of the block certificates: https://zarb.network/guide/learn-certificate.html

herumi commented 2 years ago

I've added SetGeneratorOfPublicKey. https://github.com/herumi/bls-go-binary/blob/master/bls/bls.go#L806 If you want to get the same public key with bls12_381_plus, then you have to set the generator of the public key by yourself because the standard parameter is not defined.

herumi commented 2 years ago

There are many specifications to be defined to use a BLS signature.

  1. PublicKey is G1 or G2?
  2. how to serialize SecretKey, PublicKey, and Signature to a byte string or hex string.
  3. the generator of G1 and G2.
  4. how to map a byte string to G1 and G2.

ETH spec defines all of them (i.e., bls-eth-go-binary), but it is not fixed for bls-go-binary. 3 seems to be okay, then we should check the generator. PublicKey = Generator * secretKey, so if secretKey = 1, then PublicKey = Generator and we can get the generator. Could you please set a secretKey = 1 and tell me the public key on bls12_381_plus? So I can advice more.

b00f commented 2 years ago

Here they have explained about the generator: https://docs.rs/bls12_381_plus/0.6.0/bls12_381_plus/notes/design/index.html

As you requested, I generated Public key for: SecretKey: 0100000000000000000000000000000000000000000000000000000000000000 Public Key: 93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8

Another issue I have, calling SetGeneratorOfPublicKey with above public key panics!

if err := bls.Init(bls.BLS12_381); err != nil {
   panic(err)
}

var gen = new(bls.PublicKey)
err := gen.SetHexString("93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8")
if err != nil {
   panic(err) // panics here
}
bls.SetGeneratorOfPublicKey(gen)
herumi commented 2 years ago

SecretKey: 0100000000000000000000000000000000000000000000000000000000000000 shows that your format of SecretKey is little-endian. So 'd0c6a560de2e60b6ac55386defefdf93b0c907290c2ad1b4dbd3338186bfdc68' means 0x68dcbf868133d3dbb4d12a0c2907c9b093dfefef6d3855acb6602ede60a5c6d0.

Please see https://github.com/herumi/mcl/blob/master/api.md#set-string for the format of PublicKey::SetHexString.

package main

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

func main() {
  bls.Init(bls.BLS12_381)
  // use serialization mode compatible with ETH
  bls.SetETHserialization(true)
  // set generator
  var gen bls.PublicKey
  // https://docs.rs/bls12_381_plus/0.6.0/bls12_381_plus/notes/design/index.html#fixed-generators
  err := gen.SetHexString("1 24aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8 13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801 606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be")
  if err != nil {
    fmt.Printf("err1=%v\n", err)
    return
  }
  fmt.Printf("gen=%x\n", gen.Serialize())
  bls.SetGeneratorOfPublicKey(&gen)
  var sec bls.SecretKey
  sec.SetHexString("1")
  pub := sec.GetPublicKey()
  fmt.Printf("pub(sec=1)=%x\n", pub.Serialize())
  err = sec.SetHexString("0x68dcbf868133d3dbb4d12a0c2907c9b093dfefef6d3855acb6602ede60a5c6d0")
  if err != nil {
    fmt.Printf("err2=%v\n", err)
    return
  }
  fmt.Printf("sec=%x\n", sec.Serialize())
  pub = sec.GetPublicKey()
  fmt.Printf("pub=%x\n", pub.Serialize())
}

The result is the following:

% go run examples/a.go
gen=93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8
pub(sec=1)=93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8
sec=68dcbf868133d3dbb4d12a0c2907c9b093dfefef6d3855acb6602ede60a5c6d0
pub=af0f74917f5065af94727ae9541b0ddcfb5b828a9e016b02498f477ed37fb44d5d882495afb6fd4f9773e4ea9deee436030c4d61c6e3a1151585e1d838cae1444a438d089ce77e10c492a55f6908125c5be9b236a246e4082d08de564e111e65

I think that it is what you want.

herumi commented 2 years ago

It is better to use Serialize() and Deserialize() not {Set,Get}String for interoperability with the other library.

herumi commented 2 years ago

You can use gen.DeserializeHexStr("93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8") instead of SetHexString.

b00f commented 2 years ago

@herumi Thanks a lot.