Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/chaintype/mainchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func (*MainChain) GetTablePrefix() string {

// GetChainSmithingDelayTime return the value of chain smithing delay in second
func (*MainChain) GetChainSmithingDelayTime() int64 {
return 6
return 60
}

// GetName return the name of the chain : used in parsing chaintype across node
Expand Down
44 changes: 13 additions & 31 deletions common/crypto/signature.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,31 @@
package crypto

import (
"github.com/zoobc/zoobc-core/common/model"
"github.com/zoobc/zoobc-core/common/query"
"github.com/zoobc/zoobc-core/common/util"
"golang.org/x/crypto/ed25519"
)

type (
SignatureInterface interface {
Sign(payload, accountID []byte, seed string) []byte
Sign(payload []byte, accountType uint32, accountAddress, seed string) []byte
SignBlock(payload []byte, nodeSeed string) []byte
VerifySignature(payload, signature, accountID []byte) bool
VerifySignature(payload, signature []byte, accountType uint32, accountAddress string) bool
}

// Signature object handle signing and verifying different signature
Signature struct {
Executor query.ExecutorInterface
}
)

// NewSignature create new instance of signature object
func NewSignature(executor query.ExecutorInterface) *Signature {
return &Signature{
Executor: executor,
}
func NewSignature() *Signature {
return &Signature{}
}

// Sign accept account ID and payload to be signed then return the signature byte based on the
// signature method associated with account.Type
func (sig *Signature) Sign(payload, accountID []byte, seed string) []byte {

accountQuery := query.NewAccountQuery()
getQuery, condition := accountQuery.GetAccountByID(accountID)
accountRows, _ := sig.Executor.ExecuteSelect(getQuery, condition...)
var accounts []*model.Account
account := accountQuery.BuildModel(accounts, accountRows)
if len(account) == 0 {
return nil
}
switch account[0].AccountType {
func (sig *Signature) Sign(payload []byte, accountType uint32, accountAddress, seed string) []byte {
switch accountType {
case 0: // zoobc
accountPrivateKey := ed25519GetPrivateKeyFromSeed(seed)
signature := ed25519.Sign(accountPrivateKey, payload)
Expand All @@ -58,21 +45,16 @@ func (*Signature) SignBlock(payload []byte, nodeSeed string) []byte {

// VerifySignature accept payload (before without signature), signature and the account id
// then verify the signature + public key against the payload based on the
func (*Signature) VerifySignature(payload, signature, accountID []byte) bool {
// todo: Fetch account from accountID
account := &model.Account{
ID: []byte{4, 38, 68, 24, 230, 247, 88, 220, 119, 124, 51, 149, 127, 214, 82, 224, 72, 239, 56, 139,
255, 81, 229, 184, 77, 80, 80, 39, 254, 173, 28, 169},
AccountType: 0,
Address: "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE",
}
func (*Signature) VerifySignature(payload, signature []byte, accountType uint32, accountAddress string) bool {

switch account.AccountType {
switch accountType {
case 0: // zoobc
result := ed25519.Verify(accountID, payload, signature)
accountPublicKey, _ := util.GetPublicKeyFromAddress(accountAddress)
result := ed25519.Verify(accountPublicKey, payload, signature)
return result
default:
result := ed25519.Verify(accountID, payload, signature)
accountPublicKey, _ := util.GetPublicKeyFromAddress(accountAddress)
result := ed25519.Verify(accountPublicKey, payload, signature)
return result
}
}
159 changes: 51 additions & 108 deletions common/crypto/signature_test.go
Original file line number Diff line number Diff line change
@@ -1,122 +1,70 @@
package crypto

import (
"database/sql"
"reflect"
"regexp"
"testing"

"github.com/DATA-DOG/go-sqlmock"

"github.com/zoobc/zoobc-core/common/query"
)

func TestNewSignature(t *testing.T) {
type args struct {
executor query.ExecutorInterface
}
tests := []struct {
name string
args args
want *Signature
}{
{
name: "NewSignature:success",
args: args{
executor: nil,
},
want: &Signature{
Executor: nil,
},
want: &Signature{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewSignature(tt.args.executor); !reflect.DeepEqual(got, tt.want) {
if got := NewSignature(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewSignature() = %v, want %v", got, tt.want)
}
})
}
}

type mockSignatureSignExecutorSuccess struct {
query.Executor
}

func (*mockSignatureSignExecutorSuccess) ExecuteSelect(qe string, args ...interface{}) (*sql.Rows, error) {
db, mock, _ := sqlmock.New()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT id, account_type, address FROM account`)).WillReturnRows(sqlmock.NewRows([]string{
"ID", "AccountType", "Address"}).
AddRow([]byte{7, 205, 139, 247, 101, 123, 250, 42, 95, 96, 199, 181, 108, 85, 197, 164, 168, 36, 49, 12, 251, 252,
209, 82, 181, 112, 94, 41, 107, 240, 83, 180}, 0, "BCZnSfqpP5tqFQlMTYkDeBVFWnbyVK7vLr5ORFpTjgs="))
defer db.Close()
rows, _ := db.Query(qe)
return rows, nil
}

type mockSignatureSignExecutorFail struct {
query.Executor
}

func (*mockSignatureSignExecutorFail) ExecuteSelect(qe string, args ...interface{}) (*sql.Rows, error) {
db, mock, _ := sqlmock.New()
mock.ExpectQuery(regexp.QuoteMeta(`SELECT id, account_type, address FROM account`)).WillReturnRows(sqlmock.NewRows([]string{
"ID", "AccountType", "Address"}))
defer db.Close()
rows, _ := db.Query(qe)
return rows, nil
}

func TestSignature_Sign(t *testing.T) {
type fields struct {
Executor query.ExecutorInterface
}
type args struct {
payload []byte
accountID []byte
seed string
payload []byte
accountType uint32
accountAddress string
seed string
}
tests := []struct {
name string
fields fields
args args
want []byte
name string
args args
want []byte
}{
{
name: "Sign:valid",
fields: fields{
Executor: &mockSignatureSignExecutorSuccess{},
},
args: args{
payload: []byte{12, 43, 65, 65, 12, 123, 43, 12, 1, 24, 5, 5, 12, 54},
accountID: []byte{4, 38, 68, 24, 230, 247, 88, 220, 119, 124, 51, 149, 127, 214, 82, 224, 72, 239, 56, 139,
255, 81, 229, 184, 77, 80, 80, 39, 254, 173, 28, 169},
seed: "concur vocalist rotten busload gap quote stinging undiluted surfer goofiness deviation starved",
payload: []byte{12, 43, 65, 65, 12, 123, 43, 12, 1, 24, 5, 5, 12, 54},
accountType: 0,
accountAddress: "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE",
seed: "concur vocalist rotten busload gap quote stinging undiluted surfer goofiness deviation starved",
},
want: []byte{42, 62, 47, 200, 180, 101, 85, 204, 179, 147, 143, 68, 30, 111, 6, 94, 81, 248, 219, 43, 90, 6, 167,
45, 132, 96, 130, 0, 153, 244, 159, 137, 159, 113, 78, 9, 164, 154, 213, 255, 17, 206, 153, 156, 176, 206, 33,
103, 72, 182, 228, 148, 234, 15, 176, 243, 50, 221, 106, 152, 53, 54, 173, 15},
},
{
name: "Sign:fail-{no account in account table}",
fields: fields{
Executor: &mockSignatureSignExecutorFail{},
},
name: "Sign:valid-{default type}",
args: args{
payload: []byte{12, 43, 65, 65, 12, 123, 43, 12, 1, 24, 5, 5, 12, 54},
accountID: []byte{4, 38, 68, 24, 230, 247, 88, 220, 119, 124, 51, 149, 127, 214, 82, 224, 72, 239, 56, 139,
255, 81, 229, 184, 77, 80, 80, 39, 254, 173, 28, 169},
seed: "concur vocalist rotten busload gap quote stinging undiluted surfer goofiness deviation starved",
payload: []byte{12, 43, 65, 65, 12, 123, 43, 12, 1, 24, 5, 5, 12, 54},
accountType: 1000,
accountAddress: "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE",
seed: "concur vocalist rotten busload gap quote stinging undiluted surfer goofiness deviation starved",
},
want: nil,
want: []byte{42, 62, 47, 200, 180, 101, 85, 204, 179, 147, 143, 68, 30, 111, 6, 94, 81, 248, 219, 43, 90, 6, 167,
45, 132, 96, 130, 0, 153, 244, 159, 137, 159, 113, 78, 9, 164, 154, 213, 255, 17, 206, 153, 156, 176, 206, 33,
103, 72, 182, 228, 148, 234, 15, 176, 243, 50, 221, 106, 152, 53, 54, 173, 15},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Signature{
Executor: tt.fields.Executor,
}
got := s.Sign(tt.args.payload, tt.args.accountID, tt.args.seed)
s := &Signature{}
got := s.Sign(tt.args.payload, tt.args.accountType, tt.args.accountAddress, tt.args.seed)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Signature.Sign() = %v, want %v", got, tt.want)
}
Expand All @@ -125,24 +73,17 @@ func TestSignature_Sign(t *testing.T) {
}

func TestSignature_SignBlock(t *testing.T) {
type fields struct {
Executor *query.Executor
}
type args struct {
payload []byte
nodeSeed string
}
tests := []struct {
name string
fields fields
args args
want []byte
name string
args args
want []byte
}{
{
name: "SignBlock:success",
fields: fields{
Executor: nil, // todo: update when node-registration integrated
},
args: args{
payload: []byte{12, 43, 65, 65, 12, 123, 43, 12, 1, 24, 5, 5, 12, 54},
nodeSeed: "concur vocalist rotten busload gap quote stinging undiluted surfer goofiness deviation starved",
Expand All @@ -154,9 +95,7 @@ func TestSignature_SignBlock(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Signature{
Executor: tt.fields.Executor,
}
s := &Signature{}
if got := s.SignBlock(tt.args.payload, tt.args.nodeSeed); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Signature.SignBlock() = %v, want %v", got, tt.want)
}
Expand All @@ -165,42 +104,46 @@ func TestSignature_SignBlock(t *testing.T) {
}

func TestSignature_VerifySignature(t *testing.T) {
type fields struct {
Executor *query.Executor
}
type args struct {
payload []byte
signature []byte
accountID []byte
payload []byte
signature []byte
accountType uint32
accountAddress string
}
tests := []struct {
name string
fields fields
args args
want bool
name string
args args
want bool
}{
{
name: "VerifySignature:success", // todo: add fail:test after account integrated.
fields: fields{
Executor: nil, // todo: update this after account integrated
name: "VerifySignature:success",
args: args{
payload: []byte{12, 43, 65, 65, 12, 123, 43, 12, 1, 24, 5, 5, 12, 54},
accountType: 0,
accountAddress: "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE",
signature: []byte{42, 62, 47, 200, 180, 101, 85, 204, 179, 147, 143, 68, 30, 111, 6, 94, 81, 248, 219, 43, 90, 6, 167,
45, 132, 96, 130, 0, 153, 244, 159, 137, 159, 113, 78, 9, 164, 154, 213, 255, 17, 206, 153, 156, 176, 206, 33,
103, 72, 182, 228, 148, 234, 15, 176, 243, 50, 221, 106, 152, 53, 54, 173, 15},
},
want: true,
},
{
name: "VerifySignature:success-{default}",
args: args{
payload: []byte{12, 43, 65, 65, 12, 123, 43, 12, 1, 24, 5, 5, 12, 54},
payload: []byte{12, 43, 65, 65, 12, 123, 43, 12, 1, 24, 5, 5, 12, 54},
accountType: 10000,
accountAddress: "BCZEGOb3WNx3fDOVf9ZS4EjvOIv_UeW4TVBQJ_6tHKlE",
signature: []byte{42, 62, 47, 200, 180, 101, 85, 204, 179, 147, 143, 68, 30, 111, 6, 94, 81, 248, 219, 43, 90, 6, 167,
45, 132, 96, 130, 0, 153, 244, 159, 137, 159, 113, 78, 9, 164, 154, 213, 255, 17, 206, 153, 156, 176, 206, 33,
103, 72, 182, 228, 148, 234, 15, 176, 243, 50, 221, 106, 152, 53, 54, 173, 15},
accountID: []byte{4, 38, 68, 24, 230, 247, 88, 220, 119, 124, 51, 149, 127, 214, 82, 224, 72, 239, 56, 139,
255, 81, 229, 184, 77, 80, 80, 39, 254, 173, 28, 169},
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Signature{
Executor: tt.fields.Executor,
}
if got := s.VerifySignature(tt.args.payload, tt.args.signature, tt.args.accountID); got != tt.want {
s := &Signature{}
if got := s.VerifySignature(tt.args.payload, tt.args.signature, tt.args.accountType, tt.args.accountAddress); got != tt.want {
t.Errorf("Signature.VerifySignature() = %v, want %v", got, tt.want)
}
})
Expand Down
1 change: 1 addition & 0 deletions common/database/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func (m *Migration) Init(qe *query.Executor) error {
"transaction_body_length" INTEGER,
"transaction_body_bytes" BLOB,
"signature" BLOB,
"version" INTEGER,
PRIMARY KEY("id")
);`,
`
Expand Down
Loading