Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
d6357aa6
Commit
d6357aa6
authored
May 12, 2015
by
Jeffrey Wilcke
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #631 from Gustav-Simonsson/improve_key_store_crypto
Improve key store crypto
parents
58d6ec68
e389585f
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
241 additions
and
196 deletions
+241
-196
account_manager.go
accounts/account_manager.go
+21
-21
admin.go
cmd/geth/admin.go
+3
-3
js.go
cmd/geth/js.go
+2
-1
js_test.go
cmd/geth/js_test.go
+2
-2
main.go
cmd/geth/main.go
+4
-5
gui.go
cmd/mist/gui.go
+1
-1
flags.go
cmd/utils/flags.go
+1
-1
natspec_e2e_test.go
common/natspec/natspec_e2e_test.go
+5
-4
crypto.go
crypto/crypto.go
+6
-6
key.go
crypto/key.go
+55
-20
key_store_passphrase.go
crypto/key_store_passphrase.go
+89
-42
key_store_plain.go
crypto/key_store_plain.go
+15
-14
key_store_test.go
crypto/key_store_test.go
+1
-1
rand_entropy.go
crypto/randentropy/rand_entropy.go
+1
-50
secp256.go
crypto/secp256k1/secp256.go
+2
-2
secp256_test.go
crypto/secp256k1/secp256_test.go
+10
-10
backend.go
eth/backend.go
+9
-6
worker.go
miner/worker.go
+1
-1
types.go
rpc/types.go
+8
-1
block_test.go
tests/block_test.go
+1
-1
block_test_util.go
tests/block_test_util.go
+1
-1
xeth.go
xeth/xeth.go
+3
-3
No files found.
accounts/account_manager.go
View file @
d6357aa6
...
...
@@ -33,7 +33,6 @@ and accounts persistence is derived from stored keys' addresses
package
accounts
import
(
"bytes"
"crypto/ecdsa"
crand
"crypto/rand"
"errors"
...
...
@@ -41,6 +40,7 @@ import (
"sync"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
...
...
@@ -50,12 +50,12 @@ var (
)
type
Account
struct
{
Address
[]
byte
Address
common
.
Address
}
type
Manager
struct
{
keyStore
crypto
.
KeyStore2
unlocked
map
[
string
]
*
unlocked
unlocked
map
[
common
.
Address
]
*
unlocked
mutex
sync
.
RWMutex
}
...
...
@@ -67,40 +67,40 @@ type unlocked struct {
func
NewManager
(
keyStore
crypto
.
KeyStore2
)
*
Manager
{
return
&
Manager
{
keyStore
:
keyStore
,
unlocked
:
make
(
map
[
string
]
*
unlocked
),
unlocked
:
make
(
map
[
common
.
Address
]
*
unlocked
),
}
}
func
(
am
*
Manager
)
HasAccount
(
addr
[]
byte
)
bool
{
func
(
am
*
Manager
)
HasAccount
(
addr
common
.
Address
)
bool
{
accounts
,
_
:=
am
.
Accounts
()
for
_
,
acct
:=
range
accounts
{
if
bytes
.
Compare
(
acct
.
Address
,
addr
)
==
0
{
if
acct
.
Address
==
addr
{
return
true
}
}
return
false
}
func
(
am
*
Manager
)
Primary
()
(
addr
[]
byte
,
err
error
)
{
func
(
am
*
Manager
)
Primary
()
(
addr
common
.
Address
,
err
error
)
{
addrs
,
err
:=
am
.
keyStore
.
GetKeyAddresses
()
if
os
.
IsNotExist
(
err
)
{
return
nil
,
ErrNoKeys
return
common
.
Address
{}
,
ErrNoKeys
}
else
if
err
!=
nil
{
return
nil
,
err
return
common
.
Address
{}
,
err
}
if
len
(
addrs
)
==
0
{
return
nil
,
ErrNoKeys
return
common
.
Address
{}
,
ErrNoKeys
}
return
addrs
[
0
],
nil
}
func
(
am
*
Manager
)
DeleteAccount
(
address
[]
byte
,
auth
string
)
error
{
func
(
am
*
Manager
)
DeleteAccount
(
address
common
.
Address
,
auth
string
)
error
{
return
am
.
keyStore
.
DeleteKey
(
address
,
auth
)
}
func
(
am
*
Manager
)
Sign
(
a
Account
,
toSign
[]
byte
)
(
signature
[]
byte
,
err
error
)
{
am
.
mutex
.
RLock
()
unlockedKey
,
found
:=
am
.
unlocked
[
string
(
a
.
Address
)
]
unlockedKey
,
found
:=
am
.
unlocked
[
a
.
Address
]
am
.
mutex
.
RUnlock
()
if
!
found
{
return
nil
,
ErrLocked
...
...
@@ -111,7 +111,7 @@ func (am *Manager) Sign(a Account, toSign []byte) (signature []byte, err error)
// TimedUnlock unlocks the account with the given address.
// When timeout has passed, the account will be locked again.
func
(
am
*
Manager
)
TimedUnlock
(
addr
[]
byte
,
keyAuth
string
,
timeout
time
.
Duration
)
error
{
func
(
am
*
Manager
)
TimedUnlock
(
addr
common
.
Address
,
keyAuth
string
,
timeout
time
.
Duration
)
error
{
key
,
err
:=
am
.
keyStore
.
GetKey
(
addr
,
keyAuth
)
if
err
!=
nil
{
return
err
...
...
@@ -124,7 +124,7 @@ func (am *Manager) TimedUnlock(addr []byte, keyAuth string, timeout time.Duratio
// Unlock unlocks the account with the given address. The account
// stays unlocked until the program exits or until a TimedUnlock
// timeout (started after the call to Unlock) expires.
func
(
am
*
Manager
)
Unlock
(
addr
[]
byte
,
keyAuth
string
)
error
{
func
(
am
*
Manager
)
Unlock
(
addr
common
.
Address
,
keyAuth
string
)
error
{
key
,
err
:=
am
.
keyStore
.
GetKey
(
addr
,
keyAuth
)
if
err
!=
nil
{
return
err
...
...
@@ -157,10 +157,10 @@ func (am *Manager) Accounts() ([]Account, error) {
return
accounts
,
err
}
func
(
am
*
Manager
)
addUnlocked
(
addr
[]
byte
,
key
*
crypto
.
Key
)
*
unlocked
{
func
(
am
*
Manager
)
addUnlocked
(
addr
common
.
Address
,
key
*
crypto
.
Key
)
*
unlocked
{
u
:=
&
unlocked
{
Key
:
key
,
abort
:
make
(
chan
struct
{})}
am
.
mutex
.
Lock
()
prev
,
found
:=
am
.
unlocked
[
string
(
addr
)
]
prev
,
found
:=
am
.
unlocked
[
addr
]
if
found
{
// terminate dropLater for this key to avoid unexpected drops.
close
(
prev
.
abort
)
...
...
@@ -169,12 +169,12 @@ func (am *Manager) addUnlocked(addr []byte, key *crypto.Key) *unlocked {
// key, i.e. when Unlock was used.
zeroKey
(
prev
.
PrivateKey
)
}
am
.
unlocked
[
string
(
addr
)
]
=
u
am
.
unlocked
[
addr
]
=
u
am
.
mutex
.
Unlock
()
return
u
}
func
(
am
*
Manager
)
dropLater
(
addr
[]
byte
,
u
*
unlocked
,
timeout
time
.
Duration
)
{
func
(
am
*
Manager
)
dropLater
(
addr
common
.
Address
,
u
*
unlocked
,
timeout
time
.
Duration
)
{
t
:=
time
.
NewTimer
(
timeout
)
defer
t
.
Stop
()
select
{
...
...
@@ -186,9 +186,9 @@ func (am *Manager) dropLater(addr []byte, u *unlocked, timeout time.Duration) {
// was launched with. we can check that using pointer equality
// because the map stores a new pointer every time the key is
// unlocked.
if
am
.
unlocked
[
string
(
addr
)
]
==
u
{
if
am
.
unlocked
[
addr
]
==
u
{
zeroKey
(
u
.
PrivateKey
)
delete
(
am
.
unlocked
,
string
(
addr
)
)
delete
(
am
.
unlocked
,
addr
)
}
am
.
mutex
.
Unlock
()
}
...
...
@@ -204,7 +204,7 @@ func zeroKey(k *ecdsa.PrivateKey) {
// USE WITH CAUTION = this will save an unencrypted private key on disk
// no cli or js interface
func
(
am
*
Manager
)
Export
(
path
string
,
addr
[]
byte
,
keyAuth
string
)
error
{
func
(
am
*
Manager
)
Export
(
path
string
,
addr
common
.
Address
,
keyAuth
string
)
error
{
key
,
err
:=
am
.
keyStore
.
GetKey
(
addr
,
keyAuth
)
if
err
!=
nil
{
return
err
...
...
cmd/geth/admin.go
View file @
d6357aa6
...
...
@@ -126,7 +126,7 @@ func (js *jsre) pendingTransactions(call otto.FunctionCall) otto.Value {
// Add the accouns to a new set
accountSet
:=
set
.
New
()
for
_
,
account
:=
range
accounts
{
accountSet
.
Add
(
common
.
BytesToAddress
(
account
.
Address
)
)
accountSet
.
Add
(
account
.
Address
)
}
//ltxs := make([]*tx, len(txs))
...
...
@@ -391,7 +391,7 @@ func (js *jsre) unlock(call otto.FunctionCall) otto.Value {
}
}
am
:=
js
.
ethereum
.
AccountManager
()
err
=
am
.
TimedUnlock
(
common
.
FromHex
(
addr
),
passphrase
,
time
.
Duration
(
seconds
)
*
time
.
Second
)
err
=
am
.
TimedUnlock
(
common
.
HexToAddress
(
addr
),
passphrase
,
time
.
Duration
(
seconds
)
*
time
.
Second
)
if
err
!=
nil
{
fmt
.
Printf
(
"Unlock account failed '%v'
\n
"
,
err
)
return
otto
.
FalseValue
()
...
...
@@ -433,7 +433,7 @@ func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
fmt
.
Printf
(
"Could not create the account: %v"
,
err
)
return
otto
.
UndefinedValue
()
}
return
js
.
re
.
ToVal
(
common
.
ToHex
(
acct
.
Address
))
return
js
.
re
.
ToVal
(
acct
.
Address
.
Hex
(
))
}
func
(
js
*
jsre
)
nodeInfo
(
call
otto
.
FunctionCall
)
otto
.
Value
{
...
...
cmd/geth/js.go
View file @
d6357aa6
...
...
@@ -26,6 +26,7 @@ import (
"strings"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/docserver"
"github.com/ethereum/go-ethereum/common/natspec"
"github.com/ethereum/go-ethereum/eth"
...
...
@@ -164,7 +165,7 @@ func (self *jsre) UnlockAccount(addr []byte) bool {
return
false
}
// TODO: allow retry
if
err
:=
self
.
ethereum
.
AccountManager
()
.
Unlock
(
addr
,
pass
);
err
!=
nil
{
if
err
:=
self
.
ethereum
.
AccountManager
()
.
Unlock
(
common
.
BytesToAddress
(
addr
)
,
pass
);
err
!=
nil
{
return
false
}
else
{
fmt
.
Println
(
"Account is now unlocked for this session."
)
...
...
cmd/geth/js_test.go
View file @
d6357aa6
...
...
@@ -45,7 +45,7 @@ type testjethre struct {
}
func
(
self
*
testjethre
)
UnlockAccount
(
acc
[]
byte
)
bool
{
err
:=
self
.
ethereum
.
AccountManager
()
.
Unlock
(
acc
,
""
)
err
:=
self
.
ethereum
.
AccountManager
()
.
Unlock
(
common
.
BytesToAddress
(
acc
)
,
""
)
if
err
!=
nil
{
panic
(
"unable to unlock"
)
}
...
...
@@ -68,7 +68,7 @@ func testJEthRE(t *testing.T) (string, *testjethre, *eth.Ethereum) {
// set up mock genesis with balance on the testAddress
core
.
GenesisData
=
[]
byte
(
testGenesis
)
ks
:=
crypto
.
NewKeyStorePassphrase
(
filepath
.
Join
(
tmp
,
"keys"
))
ks
:=
crypto
.
NewKeyStorePassphrase
(
filepath
.
Join
(
tmp
,
"keys
tore
"
))
am
:=
accounts
.
NewManager
(
ks
)
ethereum
,
err
:=
eth
.
New
(
&
eth
.
Config
{
DataDir
:
tmp
,
...
...
cmd/geth/main.go
View file @
d6357aa6
...
...
@@ -365,11 +365,10 @@ func unlockAccount(ctx *cli.Context, am *accounts.Manager, account string) (pass
// Load startup keys. XXX we are going to need a different format
// Attempt to unlock the account
passphrase
=
getPassPhrase
(
ctx
,
""
,
false
)
accbytes
:=
common
.
FromHex
(
account
)
if
len
(
accbytes
)
==
0
{
if
len
(
account
)
==
0
{
utils
.
Fatalf
(
"Invalid account address '%s'"
,
account
)
}
err
=
am
.
Unlock
(
accbytes
,
passphrase
)
err
=
am
.
Unlock
(
common
.
StringToAddress
(
account
)
,
passphrase
)
if
err
!=
nil
{
utils
.
Fatalf
(
"Unlock account failed '%v'"
,
err
)
}
...
...
@@ -385,11 +384,11 @@ func startEth(ctx *cli.Context, eth *eth.Ethereum) {
account
:=
ctx
.
GlobalString
(
utils
.
UnlockedAccountFlag
.
Name
)
if
len
(
account
)
>
0
{
if
account
==
"primary"
{
accbytes
,
err
:=
am
.
Primary
()
primaryAcc
,
err
:=
am
.
Primary
()
if
err
!=
nil
{
utils
.
Fatalf
(
"no primary account: %v"
,
err
)
}
account
=
common
.
ToHex
(
accbytes
)
account
=
primaryAcc
.
Hex
(
)
}
unlockAccount
(
ctx
,
am
,
account
)
}
...
...
cmd/mist/gui.go
View file @
d6357aa6
...
...
@@ -232,7 +232,7 @@ func (self *Gui) loadMergedMiningOptions() {
func
(
gui
*
Gui
)
insertTransaction
(
window
string
,
tx
*
types
.
Transaction
)
{
var
inout
string
from
,
_
:=
tx
.
From
()
if
gui
.
eth
.
AccountManager
()
.
HasAccount
(
common
.
Hex2Bytes
(
from
.
Hex
())
)
{
if
gui
.
eth
.
AccountManager
()
.
HasAccount
(
from
)
{
inout
=
"send"
}
else
{
inout
=
"recv"
...
...
cmd/utils/flags.go
View file @
d6357aa6
...
...
@@ -346,7 +346,7 @@ func GetChain(ctx *cli.Context) (*core.ChainManager, common.Database, common.Dat
func
GetAccountManager
(
ctx
*
cli
.
Context
)
*
accounts
.
Manager
{
dataDir
:=
ctx
.
GlobalString
(
DataDirFlag
.
Name
)
ks
:=
crypto
.
NewKeyStorePassphrase
(
filepath
.
Join
(
dataDir
,
"keys"
))
ks
:=
crypto
.
NewKeyStorePassphrase
(
filepath
.
Join
(
dataDir
,
"keys
tore
"
))
return
accounts
.
NewManager
(
ks
)
}
...
...
common/natspec/natspec_e2e_test.go
View file @
d6357aa6
...
...
@@ -4,6 +4,7 @@ import (
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/ethereum/go-ethereum/accounts"
...
...
@@ -84,7 +85,7 @@ type testFrontend struct {
}
func
(
self
*
testFrontend
)
UnlockAccount
(
acc
[]
byte
)
bool
{
self
.
ethereum
.
AccountManager
()
.
Unlock
(
acc
,
"password"
)
self
.
ethereum
.
AccountManager
()
.
Unlock
(
common
.
BytesToAddress
(
acc
)
,
"password"
)
return
true
}
...
...
@@ -103,19 +104,19 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
os
.
RemoveAll
(
"/tmp/eth-natspec/"
)
err
=
os
.
MkdirAll
(
"/tmp/eth-natspec/keys"
,
os
.
ModePerm
)
err
=
os
.
MkdirAll
(
"/tmp/eth-natspec/keys
tore
"
,
os
.
ModePerm
)
if
err
!=
nil
{
panic
(
err
)
}
// create a testAddress
ks
:=
crypto
.
NewKeyStorePassphrase
(
"/tmp/eth-natspec/keys"
)
ks
:=
crypto
.
NewKeyStorePassphrase
(
"/tmp/eth-natspec/keys
tore
"
)
am
:=
accounts
.
NewManager
(
ks
)
testAccount
,
err
:=
am
.
NewAccount
(
"password"
)
if
err
!=
nil
{
panic
(
err
)
}
testAddress
:=
common
.
Bytes2Hex
(
testAccount
.
Address
)
testAddress
:=
strings
.
TrimPrefix
(
testAccount
.
Address
.
Hex
(),
"0x"
)
// set up mock genesis with balance on the testAddress
core
.
GenesisData
=
[]
byte
(
`{
...
...
crypto/crypto.go
View file @
d6357aa6
...
...
@@ -181,11 +181,11 @@ func Decrypt(prv *ecdsa.PrivateKey, ct []byte) ([]byte, error) {
// Used only by block tests.
func
ImportBlockTestKey
(
privKeyBytes
[]
byte
)
error
{
ks
:=
NewKeyStorePassphrase
(
common
.
DefaultDataDir
()
+
"/keys"
)
ks
:=
NewKeyStorePassphrase
(
common
.
DefaultDataDir
()
+
"/keys
tore
"
)
ecKey
:=
ToECDSA
(
privKeyBytes
)
key
:=
&
Key
{
Id
:
uuid
.
NewRandom
(),
Address
:
PubkeyToAddress
(
ecKey
.
PublicKey
),
Address
:
common
.
BytesToAddress
(
PubkeyToAddress
(
ecKey
.
PublicKey
)
),
PrivateKey
:
ecKey
,
}
err
:=
ks
.
StoreKey
(
key
,
""
)
...
...
@@ -231,13 +231,13 @@ func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error
ecKey
:=
ToECDSA
(
ethPriv
)
key
=
&
Key
{
Id
:
nil
,
Address
:
PubkeyToAddress
(
ecKey
.
PublicKey
),
Address
:
common
.
BytesToAddress
(
PubkeyToAddress
(
ecKey
.
PublicKey
)
),
PrivateKey
:
ecKey
,
}
derivedAddr
:=
common
.
Bytes2Hex
(
key
.
Address
)
derivedAddr
:=
hex
.
EncodeToString
(
key
.
Address
.
Bytes
())
// needed because .Hex() gives leading "0x"
expectedAddr
:=
preSaleKeyStruct
.
EthAddr
if
derivedAddr
!=
expectedAddr
{
err
=
errors
.
New
(
"decrypted addr not equal to expected addr"
)
err
=
errors
.
New
(
fmt
.
Sprintf
(
"decrypted addr not equal to expected addr "
,
derivedAddr
,
expectedAddr
)
)
}
return
key
,
err
}
...
...
@@ -252,7 +252,7 @@ func aesCBCDecrypt(key []byte, cipherText []byte, iv []byte) (plainText []byte,
decrypter
.
CryptBlocks
(
paddedPlainText
,
cipherText
)
plainText
=
PKCS7Unpad
(
paddedPlainText
)
if
plainText
==
nil
{
err
=
errors
.
New
(
"Decryption failed: PKCS7Unpad failed after decryption"
)
err
=
errors
.
New
(
"Decryption failed: PKCS7Unpad failed after
AES
decryption"
)
}
return
plainText
,
err
}
...
...
crypto/key.go
View file @
d6357aa6
...
...
@@ -26,44 +26,69 @@ package crypto
import
(
"bytes"
"crypto/ecdsa"
"encoding/hex"
"encoding/json"
"io"
"code.google.com/p/go-uuid/uuid"
"github.com/ethereum/go-ethereum/common"
)
const
(
version
=
"1"
)
type
Key
struct
{
Id
uuid
.
UUID
// Version 4 "random" for unique id not derived from key data
// to simplify lookups we also store the address
Address
[]
byte
Address
common
.
Address
// we only store privkey as pubkey/address can be derived from it
// privkey in this struct is always in plaintext
PrivateKey
*
ecdsa
.
PrivateKey
}
type
plainKeyJSON
struct
{
Id
[]
byte
Address
[]
byte
PrivateKey
[]
byte
Address
string
`json:"address"`
PrivateKey
string
`json:"privatekey"`
Id
string
`json:"id"`
Version
string
`json:"version"`
}
type
cipherJSON
struct
{
Salt
[]
byte
IV
[]
byte
CipherText
[]
byte
type
encryptedKeyJSON
struct
{
Address
string
`json:"address"`
Crypto
cryptoJSON
Id
string
`json:"id"`
Version
string
`json:"version"`
}
type
encryptedKeyJSON
struct
{
Id
[]
byte
Address
[]
byte
Crypto
cipherJSON
type
cryptoJSON
struct
{
Cipher
string
`json:"cipher"`
CipherText
string
`json:"ciphertext"`
CipherParams
cipherparamsJSON
`json:"cipherparams"`
KDF
string
`json:"kdf"`
KDFParams
scryptParamsJSON
`json:"kdfparams"`
MAC
string
`json:"mac"`
Version
string
`json:"version"`
}
type
cipherparamsJSON
struct
{
IV
string
`json:"iv"`
}
type
scryptParamsJSON
struct
{
N
int
`json:"n"`
R
int
`json:"r"`
P
int
`json:"p"`
DkLen
int
`json:"dklen"`
Salt
string
`json:"salt"`
}
func
(
k
*
Key
)
MarshalJSON
()
(
j
[]
byte
,
err
error
)
{
jStruct
:=
plainKeyJSON
{
k
.
Id
,
k
.
Address
,
FromECDSA
(
k
.
PrivateKey
),
hex
.
EncodeToString
(
k
.
Address
[
:
]),
hex
.
EncodeToString
(
FromECDSA
(
k
.
PrivateKey
)),
k
.
Id
.
String
(),
version
,
}
j
,
err
=
json
.
Marshal
(
jStruct
)
return
j
,
err
...
...
@@ -77,19 +102,29 @@ func (k *Key) UnmarshalJSON(j []byte) (err error) {
}
u
:=
new
(
uuid
.
UUID
)
*
u
=
keyJSON
.
Id
*
u
=
uuid
.
Parse
(
keyJSON
.
Id
)
k
.
Id
=
*
u
k
.
Address
=
keyJSON
.
Address
k
.
PrivateKey
=
ToECDSA
(
keyJSON
.
PrivateKey
)
addr
,
err
:=
hex
.
DecodeString
(
keyJSON
.
Address
)
if
err
!=
nil
{
return
err
}
privkey
,
err
:=
hex
.
DecodeString
(
keyJSON
.
PrivateKey
)
if
err
!=
nil
{
return
err
}
k
.
Address
=
common
.
BytesToAddress
(
addr
)
k
.
PrivateKey
=
ToECDSA
(
privkey
)
return
err
return
nil
}
func
NewKeyFromECDSA
(
privateKeyECDSA
*
ecdsa
.
PrivateKey
)
*
Key
{
id
:=
uuid
.
NewRandom
()
key
:=
&
Key
{
Id
:
id
,
Address
:
PubkeyToAddress
(
privateKeyECDSA
.
PublicKey
),
Address
:
common
.
BytesToAddress
(
PubkeyToAddress
(
privateKeyECDSA
.
PublicKey
)
),
PrivateKey
:
privateKeyECDSA
,
}
return
key
...
...
crypto/key_store_passphrase.go
View file @
d6357aa6
...
...
@@ -28,24 +28,25 @@ the private key is encrypted and on disk uses another JSON encoding.
Cryptography:
1. Encryption key is scrypt derived key from user passphrase. Scrypt parameters
1. Encryption key is first 16 bytes of SHA3-256 of first 16 bytes of
scrypt derived key from user passphrase. Scrypt parameters
(work factors) [1][2] are defined as constants below.
2. Scrypt salt is 32 random bytes from CSPRNG. It is appended to ciphertext.
3. Checksum is SHA3 of the private key bytes.
4. Plaintext is concatenation of private key bytes and checksum.
5. Encryption algo is AES 256 CBC [3][4]
6. CBC IV is 16 random bytes from CSPRNG. It is appended to ciphertext.
2. Scrypt salt is 32 random bytes from CSPRNG.
It's stored in plain next to ciphertext in key file.
3. MAC is SHA3-256 of concatenation of ciphertext and last 16 bytes of scrypt derived key.
4. Plaintext is the EC private key bytes.
5. Encryption algo is AES 128 CBC [3][4]
6. CBC IV is 16 random bytes from CSPRNG.
It's stored in plain next to ciphertext in key file.
7. Plaintext padding is PKCS #7 [5][6]
Encoding:
1. On disk,
ciphertext
, salt and IV are encoded in a nested JSON object.
1. On disk,
the ciphertext, MAC
, salt and IV are encoded in a nested JSON object.
cat a key file to see the structure.
2. byte arrays are base64 JSON strings.
3. The EC private key bytes are in uncompressed form [7].
They are a big-endian byte slice of the absolute value of D [8][9].
4. The checksum is the last 32 bytes of the plaintext byte array and the
private key is the preceeding bytes.
References:
...
...
@@ -75,11 +76,14 @@ import (
"path/filepath"
"code.google.com/p/go-uuid/uuid"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto/randentropy"
"golang.org/x/crypto/scrypt"
)
const
(
keyHeaderVersion
=
"1"
keyHeaderKDF
=
"scrypt"
// 2^18 / 8 / 1 uses 256MB memory and approx 1s CPU time on a modern CPU.
scryptN
=
1
<<
18
scryptr
=
8
...
...
@@ -99,7 +103,7 @@ func (ks keyStorePassphrase) GenerateNewKey(rand io.Reader, auth string) (key *K
return
GenerateNewKeyDefault
(
ks
,
rand
,
auth
)
}
func
(
ks
keyStorePassphrase
)
GetKey
(
keyAddr
[]
byte
,
auth
string
)
(
key
*
Key
,
err
error
)
{
func
(
ks
keyStorePassphrase
)
GetKey
(
keyAddr
common
.
Address
,
auth
string
)
(
key
*
Key
,
err
error
)
{
keyBytes
,
keyId
,
err
:=
DecryptKey
(
ks
,
keyAddr
,
auth
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -112,43 +116,63 @@ func (ks keyStorePassphrase) GetKey(keyAddr []byte, auth string) (key *Key, err
return
key
,
err
}
func
(
ks
keyStorePassphrase
)
GetKeyAddresses
()
(
addresses
[]
[]
byte
,
err
error
)
{
func
(
ks
keyStorePassphrase
)
GetKeyAddresses
()
(
addresses
[]
common
.
Address
,
err
error
)
{
return
GetKeyAddresses
(
ks
.
keysDirPath
)
}
func
(
ks
keyStorePassphrase
)
StoreKey
(
key
*
Key
,
auth
string
)
(
err
error
)
{
authArray
:=
[]
byte
(
auth
)
salt
:=
randentropy
.
GetEntropy
Mixed
(
32
)
salt
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
derivedKey
,
err
:=
scrypt
.
Key
(
authArray
,
salt
,
scryptN
,
scryptr
,
scryptp
,
scryptdkLen
)
if
err
!=
nil
{
return
err
}
encryptKey
:=
Sha3
(
derivedKey
[
:
16
])[
:
16
]
keyBytes
:=
FromECDSA
(
key
.
PrivateKey
)
keyBytesHash
:=
Sha3
(
keyBytes
)
toEncrypt
:=
PKCS7Pad
(
append
(
keyBytes
,
keyBytesHash
...
))
toEncrypt
:=
PKCS7Pad
(
keyBytes
)
AES
256Block
,
err
:=
aes
.
NewCipher
(
derived
Key
)
AES
128Block
,
err
:=
aes
.
NewCipher
(
encrypt
Key
)
if
err
!=
nil
{
return
err
}
iv
:=
randentropy
.
GetEntropy
Mixed
(
aes
.
BlockSize
)
// 16
AES
256CBCEncrypter
:=
cipher
.
NewCBCEncrypter
(
AES256
Block
,
iv
)
iv
:=
randentropy
.
GetEntropy
CSPRNG
(
aes
.
BlockSize
)
// 16
AES
128CBCEncrypter
:=
cipher
.
NewCBCEncrypter
(
AES128
Block
,
iv
)
cipherText
:=
make
([]
byte
,
len
(
toEncrypt
))
AES256CBCEncrypter
.
CryptBlocks
(
cipherText
,
toEncrypt
)
AES128CBCEncrypter
.
CryptBlocks
(
cipherText
,
toEncrypt
)
mac
:=
Sha3
(
derivedKey
[
16
:
32
],
cipherText
)
cipherStruct
:=
cipherJSON
{
salt
,
iv
,
cipherText
,
scryptParamsJSON
:=
scryptParamsJSON
{
N
:
scryptN
,
R
:
scryptr
,
P
:
scryptp
,
DkLen
:
scryptdkLen
,
Salt
:
hex
.
EncodeToString
(
salt
),
}
keyStruct
:=
encryptedKeyJSON
{
key
.
Id
,
key
.
Address
,
cipherStruct
,
cipherParamsJSON
:=
cipherparamsJSON
{
IV
:
hex
.
EncodeToString
(
iv
),
}
keyJSON
,
err
:=
json
.
Marshal
(
keyStruct
)
cryptoStruct
:=
cryptoJSON
{
Cipher
:
"aes-128-cbc"
,
CipherText
:
hex
.
EncodeToString
(
cipherText
),
CipherParams
:
cipherParamsJSON
,
KDF
:
"scrypt"
,
KDFParams
:
scryptParamsJSON
,
MAC
:
hex
.
EncodeToString
(
mac
),
Version
:
"1"
,
}
encryptedKeyJSON
:=
encryptedKeyJSON
{
hex
.
EncodeToString
(
key
.
Address
[
:
]),
cryptoStruct
,
key
.
Id
.
String
(),
version
,
}
keyJSON
,
err
:=
json
.
Marshal
(
encryptedKeyJSON
)
if
err
!=
nil
{
return
err
}
...
...
@@ -156,18 +180,18 @@ func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) {
return
WriteKeyFile
(
key
.
Address
,
ks
.
keysDirPath
,
keyJSON
)
}
func
(
ks
keyStorePassphrase
)
DeleteKey
(
keyAddr
[]
byte
,
auth
string
)
(
err
error
)
{
func
(
ks
keyStorePassphrase
)
DeleteKey
(
keyAddr
common
.
Address
,
auth
string
)
(
err
error
)
{
// only delete if correct passphrase is given
_
,
_
,
err
=
DecryptKey
(
ks
,
keyAddr
,
auth
)
if
err
!=
nil
{
return
err
}
keyDirPath
:=
filepath
.
Join
(
ks
.
keysDirPath
,
hex
.
EncodeToString
(
keyAddr
))
keyDirPath
:=
filepath
.
Join
(
ks
.
keysDirPath
,
hex
.
EncodeToString
(
keyAddr
[
:
]
))
return
os
.
RemoveAll
(
keyDirPath
)
}
func
DecryptKey
(
ks
keyStorePassphrase
,
keyAddr
[]
byte
,
auth
string
)
(
keyBytes
[]
byte
,
keyId
[]
byte
,
err
error
)
{
func
DecryptKey
(
ks
keyStorePassphrase
,
keyAddr
common
.
Address
,
auth
string
)
(
keyBytes
[]
byte
,
keyId
[]
byte
,
err
error
)
{
fileContent
,
err
:=
GetKeyFile
(
ks
.
keysDirPath
,
keyAddr
)
if
err
!=
nil
{
return
nil
,
nil
,
err
...
...
@@ -176,25 +200,48 @@ func DecryptKey(ks keyStorePassphrase, keyAddr []byte, auth string) (keyBytes []
keyProtected
:=
new
(
encryptedKeyJSON
)
err
=
json
.
Unmarshal
(
fileContent
,
keyProtected
)
keyId
=
keyProtected
.
Id
salt
:=
keyProtected
.
Crypto
.
Salt
iv
:=
keyProtected
.
Crypto
.
IV
cipherText
:=
keyProtected
.
Crypto
.
CipherText
keyId
=
uuid
.
Parse
(
keyProtected
.
Id
)
authArray
:=
[]
byte
(
auth
)
derivedKey
,
err
:=
scrypt
.
Key
(
authArray
,
salt
,
scryptN
,
scryptr
,
scryptp
,
scryptdkLen
)
mac
,
err
:=
hex
.
DecodeString
(
keyProtected
.
Crypto
.
MAC
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
iv
,
err
:=
hex
.
DecodeString
(
keyProtected
.
Crypto
.
CipherParams
.
IV
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
cipherText
,
err
:=
hex
.
DecodeString
(
keyProtected
.
Crypto
.
CipherText
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
plainText
,
err
:=
aesCBCDecrypt
(
derivedKey
,
cipherText
,
iv
)
salt
,
err
:=
hex
.
DecodeString
(
keyProtected
.
Crypto
.
KDFParams
.
Salt
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
n
:=
keyProtected
.
Crypto
.
KDFParams
.
N
r
:=
keyProtected
.
Crypto
.
KDFParams
.
R
p
:=
keyProtected
.
Crypto
.
KDFParams
.
P
dkLen
:=
keyProtected
.
Crypto
.
KDFParams
.
DkLen
authArray
:=
[]
byte
(
auth
)
derivedKey
,
err
:=
scrypt
.
Key
(
authArray
,
salt
,
n
,
r
,
p
,
dkLen
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
keyBytes
=
plainText
[
:
len
(
plainText
)
-
32
]
keyBytesHash
:=
plainText
[
len
(
plainText
)
-
32
:
]
if
!
bytes
.
Equal
(
Sha3
(
keyBytes
),
keyBytesHash
)
{
err
=
errors
.
New
(
"Decryption failed: checksum mismatch"
)
calculatedMAC
:=
Sha3
(
derivedKey
[
16
:
32
],
cipherText
)
if
!
bytes
.
Equal
(
calculatedMAC
,
mac
)
{
err
=
errors
.
New
(
"Decryption failed: MAC mismatch"
)
return
nil
,
nil
,
err
}
plainText
,
err
:=
aesCBCDecrypt
(
Sha3
(
derivedKey
[
:
16
])[
:
16
],
cipherText
,
iv
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
return
keyBytes
,
keyId
,
err
return
plainText
,
keyId
,
err
}
crypto/key_store_plain.go
View file @
d6357aa6
...
...
@@ -27,6 +27,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"io"
"io/ioutil"
"os"
...
...
@@ -37,10 +38,10 @@ import (
type
KeyStore2
interface
{
// create new key using io.Reader entropy source and optionally using auth string
GenerateNewKey
(
io
.
Reader
,
string
)
(
*
Key
,
error
)
GetKey
(
[]
byte
,
string
)
(
*
Key
,
error
)
// key from addr and auth string
GetKeyAddresses
()
([]
[]
byte
,
error
)
// get all addresses
StoreKey
(
*
Key
,
string
)
error
// store key optionally using auth string
DeleteKey
(
[]
byte
,
string
)
error
// delete key by addr and auth string
GetKey
(
common
.
Address
,
string
)
(
*
Key
,
error
)
// key from addr and auth string
GetKeyAddresses
()
([]
common
.
Address
,
error
)
// get all addresses
StoreKey
(
*
Key
,
string
)
error
// store key optionally using auth string
DeleteKey
(
common
.
Address
,
string
)
error
// delete key by addr and auth string
}
type
keyStorePlain
struct
{
...
...
@@ -66,7 +67,7 @@ func GenerateNewKeyDefault(ks KeyStore2, rand io.Reader, auth string) (key *Key,
return
key
,
err
}
func
(
ks
keyStorePlain
)
GetKey
(
keyAddr
[]
byte
,
auth
string
)
(
key
*
Key
,
err
error
)
{
func
(
ks
keyStorePlain
)
GetKey
(
keyAddr
common
.
Address
,
auth
string
)
(
key
*
Key
,
err
error
)
{
fileContent
,
err
:=
GetKeyFile
(
ks
.
keysDirPath
,
keyAddr
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -77,7 +78,7 @@ func (ks keyStorePlain) GetKey(keyAddr []byte, auth string) (key *Key, err error
return
key
,
err
}
func
(
ks
keyStorePlain
)
GetKeyAddresses
()
(
addresses
[]
[]
byte
,
err
error
)
{
func
(
ks
keyStorePlain
)
GetKeyAddresses
()
(
addresses
[]
common
.
Address
,
err
error
)
{
return
GetKeyAddresses
(
ks
.
keysDirPath
)
}
...
...
@@ -90,19 +91,19 @@ func (ks keyStorePlain) StoreKey(key *Key, auth string) (err error) {
return
err
}
func
(
ks
keyStorePlain
)
DeleteKey
(
keyAddr
[]
byte
,
auth
string
)
(
err
error
)
{
keyDirPath
:=
filepath
.
Join
(
ks
.
keysDirPath
,
hex
.
EncodeToString
(
keyAddr
))
func
(
ks
keyStorePlain
)
DeleteKey
(
keyAddr
common
.
Address
,
auth
string
)
(
err
error
)
{
keyDirPath
:=
filepath
.
Join
(
ks
.
keysDirPath
,
keyAddr
.
Hex
(
))
err
=
os
.
RemoveAll
(
keyDirPath
)
return
err
}
func
GetKeyFile
(
keysDirPath
string
,
keyAddr
[]
byte
)
(
fileContent
[]
byte
,
err
error
)
{
fileName
:=
hex
.
EncodeToString
(
keyAddr
)
func
GetKeyFile
(
keysDirPath
string
,
keyAddr
common
.
Address
)
(
fileContent
[]
byte
,
err
error
)
{
fileName
:=
hex
.
EncodeToString
(
keyAddr
[
:
]
)
return
ioutil
.
ReadFile
(
filepath
.
Join
(
keysDirPath
,
fileName
,
fileName
))
}
func
WriteKeyFile
(
addr
[]
byte
,
keysDirPath
string
,
content
[]
byte
)
(
err
error
)
{
addrHex
:=
hex
.
EncodeToString
(
addr
)
func
WriteKeyFile
(
addr
common
.
Address
,
keysDirPath
string
,
content
[]
byte
)
(
err
error
)
{
addrHex
:=
hex
.
EncodeToString
(
addr
[
:
]
)
keyDirPath
:=
filepath
.
Join
(
keysDirPath
,
addrHex
)
keyFilePath
:=
filepath
.
Join
(
keyDirPath
,
addrHex
)
err
=
os
.
MkdirAll
(
keyDirPath
,
0700
)
// read, write and dir search for user
...
...
@@ -112,7 +113,7 @@ func WriteKeyFile(addr []byte, keysDirPath string, content []byte) (err error) {
return
ioutil
.
WriteFile
(
keyFilePath
,
content
,
0600
)
// read, write for user
}
func
GetKeyAddresses
(
keysDirPath
string
)
(
addresses
[]
[]
byte
,
err
error
)
{
func
GetKeyAddresses
(
keysDirPath
string
)
(
addresses
[]
common
.
Address
,
err
error
)
{
fileInfos
,
err
:=
ioutil
.
ReadDir
(
keysDirPath
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -122,7 +123,7 @@ func GetKeyAddresses(keysDirPath string) (addresses [][]byte, err error) {
if
err
!=
nil
{
continue
}
addresses
=
append
(
addresses
,
address
)
addresses
=
append
(
addresses
,
common
.
BytesToAddress
(
address
)
)
}
return
addresses
,
err
}
crypto/key_store_test.go
View file @
d6357aa6
package
crypto
import
(
"github.com/ethereum/go-ethereum/crypto/randentropy"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto/randentropy"
"reflect"
"testing"
)
...
...
crypto/randentropy/rand_entropy.go
View file @
d6357aa6
...
...
@@ -2,12 +2,8 @@ package randentropy
import
(
crand
"crypto/rand"
"encoding/binary"
"github.com/ethereum/go-ethereum/crypto/sha3"
"io"
"os"
"strings"
"time"
)
var
Reader
io
.
Reader
=
&
randEntropy
{}
...
...
@@ -16,7 +12,7 @@ type randEntropy struct {
}
func
(
*
randEntropy
)
Read
(
bytes
[]
byte
)
(
n
int
,
err
error
)
{
readBytes
:=
GetEntropy
Mixed
(
len
(
bytes
))
readBytes
:=
GetEntropy
CSPRNG
(
len
(
bytes
))
copy
(
bytes
,
readBytes
)
return
len
(
bytes
),
nil
}
...
...
@@ -29,40 +25,6 @@ func Sha3(data []byte) []byte {
return
d
.
Sum
(
nil
)
}
// TODO: verify. this needs to be audited
// we start with crypt/rand, then XOR in additional entropy from OS
func
GetEntropyMixed
(
n
int
)
[]
byte
{
startTime
:=
time
.
Now
()
.
UnixNano
()
// for each source, we take SHA3 of the source and use it as seed to math/rand
// then read bytes from it and XOR them onto the bytes read from crypto/rand
mainBuff
:=
GetEntropyCSPRNG
(
n
)
// 1. OS entropy sources
startTimeBytes
:=
make
([]
byte
,
32
)
binary
.
PutVarint
(
startTimeBytes
,
startTime
)
startTimeHash
:=
Sha3
(
startTimeBytes
)
mixBytes
(
mainBuff
,
startTimeHash
)
pid
:=
os
.
Getpid
()
pidBytes
:=
make
([]
byte
,
32
)
binary
.
PutUvarint
(
pidBytes
,
uint64
(
pid
))
pidHash
:=
Sha3
(
pidBytes
)
mixBytes
(
mainBuff
,
pidHash
)
osEnv
:=
os
.
Environ
()
osEnvBytes
:=
[]
byte
(
strings
.
Join
(
osEnv
,
""
))
osEnvHash
:=
Sha3
(
osEnvBytes
)
mixBytes
(
mainBuff
,
osEnvHash
)
// not all OS have hostname in env variables
osHostName
,
err
:=
os
.
Hostname
()
if
err
!=
nil
{
osHostNameBytes
:=
[]
byte
(
osHostName
)
osHostNameHash
:=
Sha3
(
osHostNameBytes
)
mixBytes
(
mainBuff
,
osHostNameHash
)
}
return
mainBuff
}
func
GetEntropyCSPRNG
(
n
int
)
[]
byte
{
mainBuff
:=
make
([]
byte
,
n
)
_
,
err
:=
io
.
ReadFull
(
crand
.
Reader
,
mainBuff
)
...
...
@@ -71,14 +33,3 @@ func GetEntropyCSPRNG(n int) []byte {
}
return
mainBuff
}
func
mixBytes
(
buff
[]
byte
,
mixBuff
[]
byte
)
[]
byte
{
bytesToMix
:=
len
(
buff
)
if
bytesToMix
>
32
{
bytesToMix
=
32
}
for
i
:=
0
;
i
<
bytesToMix
;
i
++
{
buff
[
i
]
^=
mixBuff
[
i
]
}
return
buff
}
crypto/secp256k1/secp256.go
View file @
d6357aa6
...
...
@@ -59,7 +59,7 @@ func GenerateKeyPair() ([]byte, []byte) {
const
seckey_len
=
32
var
pubkey
[]
byte
=
make
([]
byte
,
pubkey_len
)
var
seckey
[]
byte
=
randentropy
.
GetEntropy
Mixed
(
seckey_len
)
var
seckey
[]
byte
=
randentropy
.
GetEntropy
CSPRNG
(
seckey_len
)
var
pubkey_ptr
*
C
.
uchar
=
(
*
C
.
uchar
)(
unsafe
.
Pointer
(
&
pubkey
[
0
]))
var
seckey_ptr
*
C
.
uchar
=
(
*
C
.
uchar
)(
unsafe
.
Pointer
(
&
seckey
[
0
]))
...
...
@@ -99,7 +99,7 @@ func GeneratePubKey(seckey []byte) ([]byte, error) {
}
func
Sign
(
msg
[]
byte
,
seckey
[]
byte
)
([]
byte
,
error
)
{
nonce
:=
randentropy
.
GetEntropy
Mixed
(
32
)
nonce
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
var
sig
[]
byte
=
make
([]
byte
,
65
)
var
recid
C
.
int
...
...
crypto/secp256k1/secp256_test.go
View file @
d6357aa6
...
...
@@ -14,7 +14,7 @@ const SigSize = 65 //64+1
func
Test_Secp256_00
(
t
*
testing
.
T
)
{
var
nonce
[]
byte
=
randentropy
.
GetEntropy
Mixed
(
32
)
//going to get bitcoins stolen!
var
nonce
[]
byte
=
randentropy
.
GetEntropy
CSPRNG
(
32
)
//going to get bitcoins stolen!
if
len
(
nonce
)
!=
32
{
t
.
Fatal
()
...
...
@@ -52,7 +52,7 @@ func Test_Secp256_01(t *testing.T) {
//test size of messages
func
Test_Secp256_02s
(
t
*
testing
.
T
)
{
pubkey
,
seckey
:=
GenerateKeyPair
()
msg
:=
randentropy
.
GetEntropy
Mixed
(
32
)
msg
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
sig
,
_
:=
Sign
(
msg
,
seckey
)
CompactSigTest
(
sig
)
if
sig
==
nil
{
...
...
@@ -75,7 +75,7 @@ func Test_Secp256_02s(t *testing.T) {
//test signing message
func
Test_Secp256_02
(
t
*
testing
.
T
)
{
pubkey1
,
seckey
:=
GenerateKeyPair
()
msg
:=
randentropy
.
GetEntropy
Mixed
(
32
)
msg
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
sig
,
_
:=
Sign
(
msg
,
seckey
)
if
sig
==
nil
{
t
.
Fatal
(
"Signature nil"
)
...
...
@@ -98,7 +98,7 @@ func Test_Secp256_02(t *testing.T) {
//test pubkey recovery
func
Test_Secp256_02a
(
t
*
testing
.
T
)
{
pubkey1
,
seckey1
:=
GenerateKeyPair
()
msg
:=
randentropy
.
GetEntropy
Mixed
(
32
)
msg
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
sig
,
_
:=
Sign
(
msg
,
seckey1
)
if
sig
==
nil
{
...
...
@@ -127,7 +127,7 @@ func Test_Secp256_02a(t *testing.T) {
func
Test_Secp256_03
(
t
*
testing
.
T
)
{
_
,
seckey
:=
GenerateKeyPair
()
for
i
:=
0
;
i
<
TESTS
;
i
++
{
msg
:=
randentropy
.
GetEntropy
Mixed
(
32
)
msg
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
sig
,
_
:=
Sign
(
msg
,
seckey
)
CompactSigTest
(
sig
)
...
...
@@ -143,7 +143,7 @@ func Test_Secp256_03(t *testing.T) {
func
Test_Secp256_04
(
t
*
testing
.
T
)
{
for
i
:=
0
;
i
<
TESTS
;
i
++
{
pubkey1
,
seckey
:=
GenerateKeyPair
()
msg
:=
randentropy
.
GetEntropy
Mixed
(
32
)
msg
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
sig
,
_
:=
Sign
(
msg
,
seckey
)
CompactSigTest
(
sig
)
...
...
@@ -166,7 +166,7 @@ func Test_Secp256_04(t *testing.T) {
// -SIPA look at this
func
randSig
()
[]
byte
{
sig
:=
randentropy
.
GetEntropy
Mixed
(
65
)
sig
:=
randentropy
.
GetEntropy
CSPRNG
(
65
)
sig
[
32
]
&=
0x70
sig
[
64
]
%=
4
return
sig
...
...
@@ -174,7 +174,7 @@ func randSig() []byte {
func
Test_Secp256_06a_alt0
(
t
*
testing
.
T
)
{
pubkey1
,
seckey
:=
GenerateKeyPair
()
msg
:=
randentropy
.
GetEntropy
Mixed
(
32
)
msg
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
sig
,
_
:=
Sign
(
msg
,
seckey
)
if
sig
==
nil
{
...
...
@@ -205,12 +205,12 @@ func Test_Secp256_06a_alt0(t *testing.T) {
func
Test_Secp256_06b
(
t
*
testing
.
T
)
{
pubkey1
,
seckey
:=
GenerateKeyPair
()
msg
:=
randentropy
.
GetEntropy
Mixed
(
32
)
msg
:=
randentropy
.
GetEntropy
CSPRNG
(
32
)
sig
,
_
:=
Sign
(
msg
,
seckey
)
fail_count
:=
0
for
i
:=
0
;
i
<
TESTS
;
i
++
{
msg
=
randentropy
.
GetEntropy
Mixed
(
32
)
msg
=
randentropy
.
GetEntropy
CSPRNG
(
32
)
pubkey2
,
_
:=
RecoverPubkey
(
msg
,
sig
)
if
bytes
.
Equal
(
pubkey1
,
pubkey2
)
==
true
{
t
.
Fail
()
...
...
eth/backend.go
View file @
d6357aa6
...
...
@@ -386,14 +386,17 @@ func (s *Ethereum) StartMining(threads int) error {
func
(
s
*
Ethereum
)
Etherbase
()
(
eb
common
.
Address
,
err
error
)
{
eb
=
s
.
etherbase
if
(
eb
==
common
.
Address
{})
{
var
ebbytes
[]
byte
ebbytes
,
err
=
s
.
accountManager
.
Primary
()
eb
=
common
.
BytesToAddress
(
ebbytes
)
if
(
eb
==
common
.
Address
{})
{
primary
,
err
:=
s
.
accountManager
.
Primary
()
if
err
!=
nil
{
return
eb
,
err
}
if
(
primary
==
common
.
Address
{})
{
err
=
fmt
.
Errorf
(
"no accounts found"
)
return
eb
,
err
}
eb
=
primary
}
return
return
eb
,
nil
}
func
(
s
*
Ethereum
)
StopMining
()
{
s
.
miner
.
Stop
()
}
...
...
@@ -542,7 +545,7 @@ func (self *Ethereum) syncAccounts(tx *types.Transaction) {
return
}
if
self
.
accountManager
.
HasAccount
(
from
.
Bytes
()
)
{
if
self
.
accountManager
.
HasAccount
(
from
)
{
if
self
.
chainManager
.
TxState
()
.
GetNonce
(
from
)
<
tx
.
Nonce
()
{
self
.
chainManager
.
TxState
()
.
SetNonce
(
from
,
tx
.
Nonce
())
}
...
...
miner/worker.go
View file @
d6357aa6
...
...
@@ -474,7 +474,7 @@ func gasprice(price *big.Int, pct int64) *big.Int {
func
accountAddressesSet
(
accounts
[]
accounts
.
Account
)
*
set
.
Set
{
accountSet
:=
set
.
New
()
for
_
,
account
:=
range
accounts
{
accountSet
.
Add
(
common
.
BytesToAddress
(
account
.
Address
)
)
accountSet
.
Add
(
account
.
Address
)
}
return
accountSet
}
rpc/types.go
View file @
d6357aa6
...
...
@@ -18,6 +18,7 @@ package rpc
import
(
"encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
"math/big"
...
...
@@ -117,7 +118,13 @@ func newHexData(input interface{}) *hexdata {
binary
.
BigEndian
.
PutUint32
(
buff
,
input
)
d
.
data
=
buff
case
string
:
// hexstring
d
.
data
=
common
.
Big
(
input
)
.
Bytes
()
// aaargh ffs TODO: avoid back-and-forth hex encodings where unneeded
bytes
,
err
:=
hex
.
DecodeString
(
strings
.
TrimPrefix
(
input
,
"0x"
))
if
err
!=
nil
{
d
.
isNil
=
true
}
else
{
d
.
data
=
bytes
}
default
:
d
.
isNil
=
true
}
...
...
tests/block_test.go
View file @
d6357aa6
...
...
@@ -99,7 +99,7 @@ func runBlockTest(name string, test *BlockTest, t *testing.T) {
}
func
testEthConfig
()
*
eth
.
Config
{
ks
:=
crypto
.
NewKeyStorePassphrase
(
filepath
.
Join
(
common
.
DefaultDataDir
(),
"keys"
))
ks
:=
crypto
.
NewKeyStorePassphrase
(
filepath
.
Join
(
common
.
DefaultDataDir
(),
"keys
tore
"
))
return
&
eth
.
Config
{
DataDir
:
common
.
DefaultDataDir
(),
...
...
tests/block_test_util.go
View file @
d6357aa6
...
...
@@ -113,7 +113,7 @@ func (t *BlockTest) InsertPreState(ethereum *eth.Ethereum) (*state.StateDB, erro
if
acct
.
PrivateKey
!=
""
{
privkey
,
err
:=
hex
.
DecodeString
(
strings
.
TrimPrefix
(
acct
.
PrivateKey
,
"0x"
))
err
=
crypto
.
ImportBlockTestKey
(
privkey
)
err
=
ethereum
.
AccountManager
()
.
TimedUnlock
(
addr
,
""
,
999999
*
time
.
Second
)
err
=
ethereum
.
AccountManager
()
.
TimedUnlock
(
common
.
BytesToAddress
(
addr
)
,
""
,
999999
*
time
.
Second
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
xeth/xeth.go
View file @
d6357aa6
...
...
@@ -365,7 +365,7 @@ func (self *XEth) Accounts() []string {
accounts
,
_
:=
self
.
backend
.
AccountManager
()
.
Accounts
()
accountAddresses
:=
make
([]
string
,
len
(
accounts
))
for
i
,
ac
:=
range
accounts
{
accountAddresses
[
i
]
=
common
.
ToHex
(
ac
.
Address
)
accountAddresses
[
i
]
=
ac
.
Address
.
Hex
(
)
}
return
accountAddresses
}
...
...
@@ -781,7 +781,7 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st
if
err
!=
nil
||
len
(
accounts
)
==
0
{
from
=
statedb
.
GetOrNewStateObject
(
common
.
Address
{})
}
else
{
from
=
statedb
.
GetOrNewStateObject
(
common
.
BytesToAddress
(
accounts
[
0
]
.
Address
)
)
from
=
statedb
.
GetOrNewStateObject
(
accounts
[
0
]
.
Address
)
}
}
else
{
from
=
statedb
.
GetOrNewStateObject
(
common
.
HexToAddress
(
fromStr
))
...
...
@@ -817,7 +817,7 @@ func (self *XEth) ConfirmTransaction(tx string) bool {
}
func
(
self
*
XEth
)
doSign
(
from
common
.
Address
,
hash
common
.
Hash
,
didUnlock
bool
)
([]
byte
,
error
)
{
sig
,
err
:=
self
.
backend
.
AccountManager
()
.
Sign
(
accounts
.
Account
{
Address
:
from
.
Bytes
()
},
hash
.
Bytes
())
sig
,
err
:=
self
.
backend
.
AccountManager
()
.
Sign
(
accounts
.
Account
{
Address
:
from
},
hash
.
Bytes
())
if
err
==
accounts
.
ErrLocked
{
if
didUnlock
{
return
nil
,
fmt
.
Errorf
(
"signer account still locked after successful unlock"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment