// 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. package mock import ( "crypto/rand" "encoding/hex" "fmt" . "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 } //--------------------------------------------------------------------- // Mock client for replacing signing done by monax-keys // Implementation assertion var _ KeyClient = (*MockKeyClient)(nil) type MockKeyClient struct { knownKeys map[string]*MockKey } func NewMockKeyClient() *MockKeyClient { return &MockKeyClient{ knownKeys: make(map[string]*MockKey), } } 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 }