Newer
Older
// Copyright 2017 Monax Industries Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import (
"crypto/rand"
. "github.com/hyperledger/burrow/keys"
// NOTE: prior to building out /crypto, use
// tendermint/go-crypto for the mock client
"github.com/tendermint/ed25519"
"golang.org/x/crypto/ripemd160"
//---------------------------------------------------------------------
// Mock ed25510 key for mock keys client
// Simple ed25519 key structure for mock purposes with ripemd160 address
type MockKey struct {
Address []byte
PrivateKey [ed25519.PrivateKeySize]byte
PublicKey []byte
}
func newMockKey() (*MockKey, error) {
key := &MockKey{
Address: make([]byte, 20),
PublicKey: make([]byte, ed25519.PublicKeySize),
}
// this is a mock key, so the entropy of the source is purely
// for testing
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
copy(key.PrivateKey[:], privateKey[:])
copy(key.PublicKey[:], publicKey[:])
// prepend 0x01 for ed25519 public key
typedPublicKeyBytes := append([]byte{0x01}, key.PublicKey...)
hasher := ripemd160.New()
hasher.Write(typedPublicKeyBytes)
key.Address = hasher.Sum(nil)
return key, nil
}
func (mockKey *MockKey) Sign(message []byte) ([]byte, error) {
signatureBytes := make([]byte, ed25519.SignatureSize)
signature := ed25519.Sign(&mockKey.PrivateKey, message)
copy(signatureBytes[:], signature[:])
return signatureBytes, nil
}
//---------------------------------------------------------------------
// Implementation assertion
var _ KeyClient = (*MockKeyClient)(nil)
knownKeys map[string]*MockKey
Benjamin Bollen
committed
func NewMockKeyClient() *MockKeyClient {
return &MockKeyClient{
knownKeys: make(map[string]*MockKey),
Benjamin Bollen
committed
}
}
func (mock *MockKeyClient) NewKey() (address []byte) {
// Only tests ED25519 curve and ripemd160.
key, err := newMockKey()
if err != nil {
panic(fmt.Sprintf("Mocked key client failed on key generation: %s", err))
}
mock.knownKeys[fmt.Sprintf("%X", key.Address)] = key
return key.Address
func (mock *MockKeyClient) Sign(signBytesString string, signAddress []byte) ([]byte, error) {
key := mock.knownKeys[fmt.Sprintf("%X", signAddress)]
if key == nil {
return nil, fmt.Errorf("Unknown address (%X)", signAddress)
}
signBytes, err := hex.DecodeString(signBytesString)
if err != nil {
return nil, fmt.Errorf("Sign bytes string is invalid hex string: %s", err.Error())
}
return key.Sign(signBytes)
}
func (mock *MockKeyClient) PublicKey(address []byte) (publicKey []byte, err error) {
key := mock.knownKeys[fmt.Sprintf("%X", address)]
if key == nil {
return nil, fmt.Errorf("Unknown address (%X)", address)
return key.PublicKey, nil