diff --git a/.gitignore b/.gitignore index 2ce5328..01575d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ fmt schnorr.goBACKUP notes.md +rsa-rs diff --git a/README.md b/README.md index f566e66..c9fc804 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ Crypto algorithms from scratch. Academic purposes only. - [ECC ElGamal](#ecc-elgamal) - [ECC ECDSA](#ecc-ecdsa) - [Schnorr signature](#schnorr-signature) -- [Bn128](#bn128) +- [Bn128 pairing](#bn128) +- [BLS signature](#bls) --- @@ -420,7 +421,37 @@ if verified { ## Bn128 Implementation of the bn128 pairing. -Code moved to https://github.com/arnaucube/bn128 +Code moved to https://github.com/arnaucube/go-snark/tree/master/bn128 + + +## BLS +Boneh–Lynn–Shacham (BLS) signature scheme implemented in Go. +https://en.wikipedia.org/wiki/Boneh%E2%80%93Lynn%E2%80%93Shacham + +This package uses the BN128 Go implementation from https://github.com/arnaucube/go-snark/tree/master/bn128 + +### Usage +```go +bls, err := NewKeys() +assert.Nil(t, err) + +fmt.Println("privK:", bls.PrivK) +fmt.Println("pubK:", bls.PubK) + +m := []byte("test") +sig := bls.Sign(m) +fmt.Println("signature:", sig) + +verified := bls.Verify(m, sig, bls.PubK) +assert.True(t, verified) + +/* out: +privK: 28151522174243194157727175362620544050084772361374505986857263387912025505082855947281432752362814690196305655335201716186584298643231993241609823412370437094839017595372164876997343464950463323765646363122343203470911131219733598647659483557447955173651057370197665461325593653581904430885385707255151472097067657072671643359241937143381958053903725229458882818033464163487351806079175441316235756460455300637131488613568714712448336232283394011955460567718918055245116200622473324300828876609569556897836255866438665750954410544846238847540023603735360532628141508114304504053826700874403280496870140784630677100277 +pubK: [528167154220154970470523315181365784447502116458960328551053767278433374201 18282159022449399855128689249640771309991127595389457870089153259100566421596 19728585501269572907574045312283749798205079570296187960832716959652451330253] +signature: [[12832528436266902887734423636380781315321578271441494003771296275495461508593 6964131770814642748778827029569297554111206304527781019989920684169107205085] [6508357389516441729339280841134358160957092583050390612877406497974519092306 12073245715182483402311045895787625736998570529454024932833669602347318770866] [13520730275909614846121720877644124261162513989808465368770765804305866618385 19571107788574492009101590535904131414163790958090376021518899789800327786039]] +verified: true +*/ +``` --- diff --git a/bls/README.md b/bls/README.md new file mode 100644 index 0000000..f50eb03 --- /dev/null +++ b/bls/README.md @@ -0,0 +1,28 @@ +# BLS [![GoDoc](https://godoc.org/github.com/arnaucube/cryptofun/bls?status.svg)](https://godoc.org/github.com/arnaucube/cryptofun/bls) +Boneh–Lynn–Shacham (BLS) signature scheme implemented in Go. +https://en.wikipedia.org/wiki/Boneh%E2%80%93Lynn%E2%80%93Shacham + +This package uses the BN128 Go implementation from https://github.com/arnaucube/go-snark/tree/master/bn128 + +### Usage +```go +bls, err := NewKeys() +assert.Nil(t, err) + +fmt.Println("privK:", bls.PrivK) +fmt.Println("pubK:", bls.PubK) + +m := []byte("test") +sig := bls.Sign(m) +fmt.Println("signature:", sig) + +verified := bls.Verify(m, sig, bls.PubK) +assert.True(t, verified) + +/* out: +privK: 28151522174243194157727175362620544050084772361374505986857263387912025505082855947281432752362814690196305655335201716186584298643231993241609823412370437094839017595372164876997343464950463323765646363122343203470911131219733598647659483557447955173651057370197665461325593653581904430885385707255151472097067657072671643359241937143381958053903725229458882818033464163487351806079175441316235756460455300637131488613568714712448336232283394011955460567718918055245116200622473324300828876609569556897836255866438665750954410544846238847540023603735360532628141508114304504053826700874403280496870140784630677100277 +pubK: [528167154220154970470523315181365784447502116458960328551053767278433374201 18282159022449399855128689249640771309991127595389457870089153259100566421596 19728585501269572907574045312283749798205079570296187960832716959652451330253] +signature: [[12832528436266902887734423636380781315321578271441494003771296275495461508593 6964131770814642748778827029569297554111206304527781019989920684169107205085] [6508357389516441729339280841134358160957092583050390612877406497974519092306 12073245715182483402311045895787625736998570529454024932833669602347318770866] [13520730275909614846121720877644124261162513989808465368770765804305866618385 19571107788574492009101590535904131414163790958090376021518899789800327786039]] +verified: true +*/ +``` diff --git a/bls/bls.go b/bls/bls.go new file mode 100644 index 0000000..c5df6bd --- /dev/null +++ b/bls/bls.go @@ -0,0 +1,72 @@ +package bls + +import ( + "crypto/rand" + "crypto/sha256" + "math/big" + + "github.com/arnaucube/go-snark/bn128" +) + +// this BLS implementation uses the Go implementation of the BN128 pairing github.com/arnaucube/go-snark/bn128 + +const bits = 2048 + +// BLS is the data structure of the BLS signature scheme, including the BN128 pairing curve +type BLS struct { + Bn bn128.Bn128 + PrivK *big.Int + PubK [3]*big.Int +} + +// NewKeys generate new Private Key and Public Key +func NewKeys() (BLS, error) { + bn, err := bn128.NewBn128() + if err != nil { + return BLS{}, err + } + bls := BLS{} + bls.Bn = bn + bls.PrivK, err = rand.Prime(rand.Reader, bits) + if err != nil { + return BLS{}, err + } + + // pubK = pk * G + bls.PubK = bls.Bn.G1.MulScalar(bls.Bn.G1.G, bls.PrivK) + return bls, nil +} + +// Hash hashes a message m +func (bls BLS) Hash(m []byte) [3][2]*big.Int { + h := sha256.New() + h.Write(m) + hash := h.Sum(nil) + r := new(big.Int).SetBytes(hash) + // get point over the curve + point := bls.Bn.G2.MulScalar(bls.Bn.G2.G, r) + return point +} + +// Sign performs the BLS signature of a message m +func (bls BLS) Sign(m []byte) [3][2]*big.Int { + // s = pk * H(m) + h := bls.Hash(m) + sig := bls.Bn.G2.MulScalar(h, bls.PrivK) + return sig +} + +// Verify checks the signature of a message m with the given Public Key +func (bls BLS) Verify(m []byte, sig [3][2]*big.Int, pubK [3]*big.Int) bool { + // checks e(P, G) == e(G, s) + p1, err := bls.Bn.Pairing(bls.PubK, bls.Hash(m)) + if err != nil { + return false + } + p2, err := bls.Bn.Pairing(bls.Bn.G1.G, sig) + if err != nil { + return false + } + + return bls.Bn.Fq12.Equal(p1, p2) +} diff --git a/bls/bls_test.go b/bls/bls_test.go new file mode 100644 index 0000000..e94a0f3 --- /dev/null +++ b/bls/bls_test.go @@ -0,0 +1,24 @@ +package bls + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestBls(t *testing.T) { + bls, err := NewKeys() + assert.Nil(t, err) + + fmt.Println("privK:", bls.PrivK) + fmt.Println("pubK:", bls.PubK) + + m := []byte("test") + sig := bls.Sign(m) + fmt.Println("signature:", sig) + + verified := bls.Verify(m, sig, bls.PubK) + fmt.Println("verified:", verified) + assert.True(t, verified) +} diff --git a/bn128/README.md b/bn128/README.md index 582e102..2a3da70 100644 --- a/bn128/README.md +++ b/bn128/README.md @@ -1,3 +1,3 @@ ## Bn128 Implementation of the bn128 pairing. -Code moved to https://github.com/arnaucube/bn128 +Code moved to https://github.com/arnaucube/go-snark/tree/master/bn128 diff --git a/go.mod b/go.mod index 697c22c..5f0af21 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ module github.com/arnaucube/cryptofun require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/arnaucube/bn128 v0.0.0-20181124004642-3bb6b68ddbe4 + github.com/arnaucube/go-snark v0.0.0-20181207210027-19f7216d0e3d github.com/stretchr/testify v1.2.2 ) diff --git a/go.sum b/go.sum index e03ee77..233a118 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,9 @@ +github.com/arnaucube/bn128 v0.0.0-20181124004642-3bb6b68ddbe4 h1:Fy/hr/PH/8LIs8+a0oHQdAcI1mntdsM6Ndb0ZWLUtN0= +github.com/arnaucube/bn128 v0.0.0-20181124004642-3bb6b68ddbe4/go.mod h1:bIKGJe1ZaHy7HYQML7Me4q38pOpggn3JO1VPPyMe3zI= +github.com/arnaucube/cryptofun v0.0.0-20181124001128-d55d875d7a54/go.mod h1:PZE8kKpHPD1UMrS3mTfAMmEEinGtijSwjxLRqRcD64A= +github.com/arnaucube/cryptofun v0.0.0-20181124004321-9b11ae8280bd/go.mod h1:PZE8kKpHPD1UMrS3mTfAMmEEinGtijSwjxLRqRcD64A= +github.com/arnaucube/go-snark v0.0.0-20181207210027-19f7216d0e3d h1:fLsNI9g3nTSqXStD2dtkr86MMFicst28uREsXUd6jr0= +github.com/arnaucube/go-snark v0.0.0-20181207210027-19f7216d0e3d/go.mod h1:gLycS/B43DufBaH0jH8kqiE4A7w5FdOM8I9S416xh2Y= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=