Skip to content
Snippets Groups Projects
Commit 698b605e authored by lunfardo314's avatar lunfardo314
Browse files

added BLS-BDN signature scheme and address

parent 2d8015ed
No related branches found
No related tags found
No related merge requests found
......@@ -23,6 +23,7 @@ require (
github.com/spf13/viper v1.6.2
github.com/stretchr/testify v1.5.1
github.com/valyala/fasttemplate v1.1.0 // indirect
go.dedis.ch/kyber/v3 v3.0.12
go.uber.org/atomic v1.6.0
go.uber.org/zap v1.14.0
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
......
......@@ -311,6 +311,15 @@ github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhe
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=
go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw=
go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ=
go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg=
go.dedis.ch/kyber/v3 v3.0.12 h1:15d61EyBcBoFIS97kS2c/Vz4o3FR8ALnZ2ck9J/ebYM=
go.dedis.ch/kyber/v3 v3.0.12/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U=
go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo=
go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4=
go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.mongodb.org/mongo-driver v1.0.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
......@@ -334,6 +343,7 @@ golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
......@@ -386,6 +396,7 @@ golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
......
......@@ -3,7 +3,6 @@ package address
import (
"crypto/rand"
"fmt"
"github.com/mr-tron/base58"
"golang.org/x/crypto/blake2b"
......@@ -17,7 +16,15 @@ type Digest = []byte
type Address [Length]byte
const (
// every signature scheme has a version byte associated to it.
VERSION_ED25519 = byte(1)
VERSION_BLS_BDN = byte(2)
)
// Random creates a random address, which can for example be used in unit tests.
// first byte (version) is also random
func Random() (address Address) {
// generate a random sequence of bytes
addressBytes := make([]byte, Length)
......@@ -31,6 +38,22 @@ func Random() (address Address) {
return
}
// Random creates a random address of the given type,
// first byte (version) is given
func RandomOfType(addrVersion byte) (address Address) {
// generate a random sequence of bytes
addressBytes := make([]byte, Length-1)
if _, err := rand.Read(addressBytes); err != nil {
panic(err)
}
// copy the generated bytes into the result
copy(address[1:], addressBytes)
addressBytes[0] = addrVersion
return
}
// FromBase58 creates an address from a base58 encoded string.
func FromBase58(base58String string) (address Address, err error) {
// decode string
......@@ -56,7 +79,19 @@ func FromBase58(base58String string) (address Address, err error) {
func FromED25519PubKey(key ed25119.PublicKey) (address Address) {
digest := blake2b.Sum256(key[:])
address[0] = 0
address[0] = VERSION_ED25519
copy(address[1:], digest[:])
return
}
// FromBLSPubKey creates an address from marshaled BLS public key
// unmarshaled BLS public key conforms to interface kyber.Point
func FromBLSPubKey(pubKey []byte) (address Address) {
digest := blake2b.Sum256(pubKey)
address[0] = VERSION_BLS_BDN
copy(address[1:], digest[:])
return
......
package signaturescheme
import (
"bytes"
"github.com/iotaledger/goshimmer/packages/binary/valuetransfer/address"
"go.dedis.ch/kyber/v3"
"go.dedis.ch/kyber/v3/pairing/bn256"
"go.dedis.ch/kyber/v3/sign/bdn"
"go.dedis.ch/kyber/v3/util/random"
)
// BLS_BDN implements BLS signature scheme which is robust agains rogue public key attacks
// it uses go.dedis/kyber library
// more info https://github.com/dedis/kyber/blob/master/sign/bdn/bdn.go
// usually BLS signatures are used as threshold signatures.
// This package don't implement any threshold signature related primitives.
// it only implements what is needed for the node to check validity of the BLS signatures against addresses
// and also minimum signing required for testing
var suite = bn256.NewSuite()
// blsBdnSignatureScheme defines an interface for the BLS signatures.
// here it is unmarshaled because only used for testing
type blsBdnSignatureScheme struct {
privKey kyber.Scalar
pubKey kyber.Point
}
// RandBLS_BDN creates an RANDOM instance of a signature scheme, that is used to sign the corresponding address.
// mostly intended for testing.
func RandBLS_BDN() SignatureScheme {
ret := &blsBdnSignatureScheme{}
ret.privKey, ret.pubKey = bdn.NewKeyPair(suite, random.New()) // only for testing: deterministic!
return ret
}
func (sigscheme *blsBdnSignatureScheme) Version() byte {
suite.ScalarLen()
return address.VERSION_BLS_BDN
}
func (sigscheme *blsBdnSignatureScheme) Address() address.Address {
b, err := sigscheme.pubKey.MarshalBinary()
if err != nil {
panic(err)
}
return address.FromBLSPubKey(b)
}
func (sigscheme *blsBdnSignatureScheme) Sign(data []byte) Signature {
sig, err := bdn.Sign(suite, sigscheme.privKey, data)
if err != nil {
panic(err)
}
pubKeyBin, err := sigscheme.pubKey.MarshalBinary()
if err != nil {
panic(err)
}
return &blsBdnSignature{
pubKey: pubKeyBin,
signature: sig,
}
}
// interface contract (allow the compiler to check if the implementation has all of the required methods).
var _ SignatureScheme = &blsBdnSignatureScheme{}
// BLS-BDN signature, in binary marshaled form
type blsBdnSignature struct {
pubKey []byte
signature []byte
}
func (sig *blsBdnSignature) IsValid(signedData []byte) bool {
// unmarshal public key
pubKey := suite.G2().Point()
if err := pubKey.UnmarshalBinary(sig.pubKey); err != nil {
return false
}
return bdn.Verify(suite, pubKey, signedData, sig.signature) == nil
}
func (sig *blsBdnSignature) Bytes() []byte {
b := make([]byte, 1+len(sig.pubKey)+len(sig.signature))
buf := bytes.NewBuffer(b)
buf.WriteByte(address.VERSION_BLS_BDN)
buf.Write(sig.pubKey)
buf.Write(sig.signature)
return b
}
func (sig *blsBdnSignature) Address() address.Address {
return address.FromBLSPubKey(sig.pubKey)
}
// interface contract (allow the compiler to check if the implementation has all of the required methods).
var _ Signature = &blsBdnSignature{}
package signaturescheme
import (
"github.com/magiconair/properties/assert"
"testing"
)
func TestBLS_BDN(t *testing.T) {
dataToSign := []byte("testtesttest")
blsSigScheme := RandBLS_BDN()
signature := blsSigScheme.Sign(dataToSign)
assert.Equal(t, blsSigScheme.Address() == signature.Address(), true)
assert.Equal(t, signature.IsValid(dataToSign), true)
}
......@@ -10,11 +10,6 @@ import (
// region PUBLIC API ///////////////////////////////////////////////////////////////////////////////////////////////////
const (
// every signature scheme has a version byte associated to it.
VERSION_ED25519 = byte(1)
)
// ED25519 creates an instance of a signature scheme, that is used to sign the corresponding address.
func ED25519(keyPair ed25119.KeyPair) SignatureScheme {
return &ed25519SignatureScheme{
......@@ -33,7 +28,7 @@ type ed25519SignatureScheme struct {
// Version returns the version byte that is associated to this signature scheme.
func (signatureScheme *ed25519SignatureScheme) Version() byte {
return VERSION_ED25519
return address.VERSION_ED25519
}
// Address returns the address that this signature scheme instance is securing.
......@@ -82,7 +77,7 @@ func Ed25519SignatureFromBytes(bytes []byte, optionalTargetObject ...*ed25519Sig
versionByte, err := marshalUtil.ReadByte()
if err != nil {
return
} else if versionByte != VERSION_ED25519 {
} else if versionByte != address.VERSION_ED25519 {
err = fmt.Errorf("invalid version byte when parsing ed25519 signature")
return
......@@ -116,7 +111,7 @@ func (signature *ed25519Signature) IsValid(signedData []byte) bool {
// Bytes returns a marshaled version of the signature.
func (signature *ed25519Signature) Bytes() []byte {
marshalUtil := marshalutil.New(1 + ed25119.PublicKeySize + ed25119.SignatureSize)
marshalUtil.WriteByte(VERSION_ED25519)
marshalUtil.WriteByte(address.VERSION_ED25519)
marshalUtil.WriteBytes(signature.publicKey[:])
marshalUtil.WriteBytes(signature.signature[:])
......
......@@ -47,7 +47,7 @@ func SignaturesFromBytes(bytes []byte, optionalTargetObject ...*Signatures) (res
for versionByte != 0 {
// perform signature scheme specific decoding
switch versionByte {
case signaturescheme.VERSION_ED25519:
case address.VERSION_ED25519:
marshalUtil.ReadSeek(-1)
signature, signatureErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return signaturescheme.Ed25519SignatureFromBytes(data) })
if signatureErr != nil {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment