Skip to content

Commit

Permalink
Merge pull request #34 from dedis/ledger_permissions
Browse files Browse the repository at this point in the history
Ledger acess rights control
  • Loading branch information
nkcr committed Apr 8, 2020
2 parents 837280a + 279b36d commit 49d0969
Show file tree
Hide file tree
Showing 34 changed files with 2,498 additions and 545 deletions.
54 changes: 54 additions & 0 deletions crypto/bls/mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bls

import (
"bytes"
fmt "fmt"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/any"
Expand Down Expand Up @@ -42,6 +43,22 @@ func (pk publicKey) Pack(encoding.ProtoMarshaler) (proto.Message, error) {
return &PublicKeyProto{Data: buffer}, nil
}

// Verify implements crypto.PublicKey. It returns nil if the signature matches
// the message with this public key.
func (pk publicKey) Verify(msg []byte, sig crypto.Signature) error {
signature, ok := sig.(signature)
if !ok {
return xerrors.Errorf("invalid signature type '%T'", sig)
}

err := bls.Verify(suite, pk.point, msg, signature.data)
if err != nil {
return xerrors.Errorf("bls verify failed: %v", err)
}

return nil
}

// Equal implements crypto.PublicKey. It returns true if the other public key
// is the same.
func (pk publicKey) Equal(other crypto.PublicKey) bool {
Expand All @@ -53,6 +70,29 @@ func (pk publicKey) Equal(other crypto.PublicKey) bool {
return pubkey.point.Equal(pk.point)
}

// MarshalText implements encoding.TextMarshaler. It returns a text
// representation of the public key.
func (pk publicKey) MarshalText() ([]byte, error) {
buffer, err := pk.MarshalBinary()
if err != nil {
return nil, xerrors.Errorf("couldn't marshal: %v", err)
}

return []byte(fmt.Sprintf("bls:%x", buffer)), nil
}

// String implements fmt.String. It returns a string representation of the
// point.
func (pk publicKey) String() string {
buffer, err := pk.MarshalText()
if err != nil {
return "bls:malformed_point"
}

// Output only the prefix and 16 characters of the buffer in hexadecimal.
return string(buffer)[:4+16]
}

// signature is a proof of the integrity of a single message associated with a
// unique public key.
type signature struct {
Expand Down Expand Up @@ -86,6 +126,13 @@ type publicKeyFactory struct {
encoder encoding.ProtoMarshaler
}

// NewPublicKeyFactory returns a new instance of the factory.
func NewPublicKeyFactory() crypto.PublicKeyFactory {
return publicKeyFactory{
encoder: encoding.NewProtoEncoder(),
}
}

// FromProto implements crypto.PublicKeyFactory. It creates a public key from
// its protobuf representation.
func (f publicKeyFactory) FromProto(src proto.Message) (crypto.PublicKey, error) {
Expand Down Expand Up @@ -120,6 +167,13 @@ type signatureFactory struct {
encoder encoding.ProtoMarshaler
}

// NewSignatureFactory returns a new instance of the factory.
func NewSignatureFactory() crypto.SignatureFactory {
return signatureFactory{
encoder: encoding.NewProtoEncoder(),
}
}

// FromProto implements crypto.SignatureFactory. It creates a BLS signature from
// its protobuf representation.
func (f signatureFactory) FromProto(src proto.Message) (crypto.Signature, error) {
Expand Down
71 changes: 49 additions & 22 deletions crypto/bls/mod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ func TestPublicKey_MarshalBinary(t *testing.T) {
require.NotEmpty(t, buffer)
}

type fakePoint struct {
type badPoint struct {
kyber.Point
}

func (p fakePoint) MarshalBinary() ([]byte, error) {
func (p badPoint) MarshalBinary() ([]byte, error) {
return nil, xerrors.New("oops")
}

Expand All @@ -60,7 +60,7 @@ func TestPublicKey_Pack(t *testing.T) {
err := quick.Check(f, nil)
require.NoError(t, err)

pubkey := publicKey{point: fakePoint{}}
pubkey := publicKey{point: badPoint{}}
_, err = pubkey.Pack(nil)
require.EqualError(t, err, "couldn't marshal point: oops")
}
Expand All @@ -69,20 +69,50 @@ type fakePublicKey struct {
crypto.PublicKey
}

func TestPublicKey_Equal(t *testing.T) {
f := func() bool {
signerA := NewSigner()
signerB := NewSigner()
require.True(t, signerA.GetPublicKey().Equal(signerA.GetPublicKey()))
require.True(t, signerB.GetPublicKey().Equal(signerB.GetPublicKey()))
require.False(t, signerA.GetPublicKey().Equal(signerB.GetPublicKey()))
require.False(t, signerA.GetPublicKey().Equal(fakePublicKey{}))
func TestPublicKey_Verify(t *testing.T) {
msg := []byte("deadbeef")
signer := NewSigner()
sig, err := signer.Sign(msg)
require.NoError(t, err)

return true
}
err = signer.GetPublicKey().Verify(msg, sig)
require.NoError(t, err)

err := quick.Check(f, nil)
err = signer.GetPublicKey().Verify([]byte{}, sig)
require.EqualError(t, err, "bls verify failed: bls: invalid signature")

err = signer.GetPublicKey().Verify(msg, fakeSignature{})
require.EqualError(t, err, "invalid signature type 'bls.fakeSignature'")
}

func TestPublicKey_Equal(t *testing.T) {
signerA := NewSigner()
signerB := NewSigner()
require.True(t, signerA.GetPublicKey().Equal(signerA.GetPublicKey()))
require.True(t, signerB.GetPublicKey().Equal(signerB.GetPublicKey()))
require.False(t, signerA.GetPublicKey().Equal(signerB.GetPublicKey()))
require.False(t, signerA.GetPublicKey().Equal(fakePublicKey{}))
}

func TestPublicKey_MarshalText(t *testing.T) {
signer := NewSigner()
text, err := signer.GetPublicKey().MarshalText()
require.NoError(t, err)
require.Contains(t, string(text), "bls:")

pk := publicKey{point: badPoint{}}
_, err = pk.MarshalText()
require.EqualError(t, err, "couldn't marshal: oops")
}

func TestPublicKey_String(t *testing.T) {
signer := NewSigner()
str := signer.GetPublicKey().(publicKey).String()
require.Contains(t, str, "bls:")

pk := publicKey{point: badPoint{}}
str = pk.String()
require.Equal(t, "bls:malformed_point", str)
}

func TestSignature_MarshalBinary(t *testing.T) {
Expand Down Expand Up @@ -137,9 +167,7 @@ func TestSignature_Equal(t *testing.T) {
}

func TestPublicKeyFactory_FromProto(t *testing.T) {
factory := publicKeyFactory{
encoder: encoding.NewProtoEncoder(),
}
factory := NewPublicKeyFactory().(publicKeyFactory)

signer := NewSigner()
packed, err := signer.GetPublicKey().Pack(nil)
Expand Down Expand Up @@ -169,9 +197,7 @@ func TestPublicKeyFactory_FromProto(t *testing.T) {
}

func TestSignatureFactory_FromProto(t *testing.T) {
factory := signatureFactory{
encoder: encoding.NewProtoEncoder(),
}
factory := NewSignatureFactory().(signatureFactory)

signer := NewSigner()
sig, err := signer.Sign([]byte{1})
Expand Down Expand Up @@ -303,8 +329,9 @@ func TestSigner_Sign(t *testing.T) {
[]crypto.PublicKey{signer.GetPublicKey()},
)
require.NoError(t, err)
err = verifier.Verify(msg, sig)
return err == nil
require.NoError(t, verifier.Verify(msg, sig))

return true
}

err := quick.Check(f, nil)
Expand Down
112 changes: 112 additions & 0 deletions crypto/common/mod.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Package common implements interfaces to support multiple algorithms. A public
// key factory and a signature factory are available. The supported algorithms
// are the followings:
// - BLS
package common

import (
"reflect"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/any"
"go.dedis.ch/fabric/crypto"
"go.dedis.ch/fabric/crypto/bls"
"go.dedis.ch/fabric/encoding"
"golang.org/x/xerrors"
)

// PublicKeyFactory is a public key factory for commonly known algorithms.
//
// - implements crypto.PublicKeyFactory
type PublicKeyFactory struct {
encoder encoding.ProtoMarshaler
factories map[reflect.Type]crypto.PublicKeyFactory
}

// NewPublicKeyFactory returns a new instance of the common public key factory.
func NewPublicKeyFactory() PublicKeyFactory {
factory := PublicKeyFactory{
encoder: encoding.NewProtoEncoder(),
factories: make(map[reflect.Type]crypto.PublicKeyFactory),
}

factory.Register((*bls.PublicKeyProto)(nil), bls.NewPublicKeyFactory())

return factory
}

// Register binds a protobuf message type to a public key factory. If a key
// already exists, it will override it.
func (f PublicKeyFactory) Register(msg proto.Message, factory crypto.PublicKeyFactory) {
key := reflect.TypeOf(msg)
f.factories[key] = factory
}

// FromProto implements crypto.PublicKeyFactory. It returns the implementation
// of the public key if the message is a known public key message, otherwise it
// returns an error.
func (f PublicKeyFactory) FromProto(in proto.Message) (crypto.PublicKey, error) {
inAny, ok := in.(*any.Any)
if ok {
var err error
in, err = f.encoder.UnmarshalDynamicAny(inAny)
if err != nil {
return nil, xerrors.Errorf("couldn't decode message: %v", err)
}
}

key := reflect.TypeOf(in)
factory := f.factories[key]
if factory == nil {
return nil, xerrors.Errorf("couldn't find factory for '%s'", key)
}

return factory.FromProto(in)
}

// SignatureFactory is a factory for commonly known algorithms.
type SignatureFactory struct {
encoder encoding.ProtoMarshaler
factories map[reflect.Type]crypto.SignatureFactory
}

// NewSignatureFactory returns a new instance of the common signature factory.
func NewSignatureFactory() SignatureFactory {
factory := SignatureFactory{
encoder: encoding.NewProtoEncoder(),
factories: make(map[reflect.Type]crypto.SignatureFactory),
}

factory.Register((*bls.SignatureProto)(nil), bls.NewSignatureFactory())

return factory
}

// Register binds a protobuf message type to a signature factory. If a key
// already exists, it will override it.
func (f SignatureFactory) Register(msg proto.Message, factory crypto.SignatureFactory) {
key := reflect.TypeOf(msg)
f.factories[key] = factory
}

// FromProto implements crypto.SignatureFactory. It returns the implementation
// of the signature if the message is a known signature message, otherwise it
// returns an error.
func (f SignatureFactory) FromProto(in proto.Message) (crypto.Signature, error) {
inAny, ok := in.(*any.Any)
if ok {
var err error
in, err = f.encoder.UnmarshalDynamicAny(inAny)
if err != nil {
return nil, xerrors.Errorf("couldn't decode message: %v", err)
}
}

key := reflect.TypeOf(in)
factory := f.factories[key]
if factory == nil {
return nil, xerrors.Errorf("couldn't find factory for '%s'", key)
}

return factory.FromProto(in)
}
Loading

0 comments on commit 49d0969

Please sign in to comment.