aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--accounts/abi/abi_test.go10
-rw-r--r--accounts/abi/event.go2
-rw-r--r--accounts/abi/event_test.go4
-rw-r--r--accounts/abi/method.go2
-rw-r--r--cmd/geth/js_test.go2
-rw-r--r--common/bytes.go18
-rw-r--r--common/bytes_test.go20
-rw-r--r--common/compiler/solidity.go2
-rw-r--r--common/httpclient/httpclient.go2
-rw-r--r--common/httpclient/httpclient_test.go2
-rw-r--r--common/natspec/natspec.go4
-rw-r--r--common/natspec/natspec_e2e_test.go4
-rw-r--r--common/natspec/natspec_e2e_test.go.orig253
-rw-r--r--common/registrar/ethreg/api.go2
-rw-r--r--common/registrar/registrar.go4
-rw-r--r--common/registrar/registrar_test.go2
-rw-r--r--compression/rle/read_write.go4
-rw-r--r--compression/rle/read_write_test.go16
-rw-r--r--core/state/state_object.go4
-rw-r--r--core/types/bloom9.go2
-rw-r--r--core/types/bloom9_test.go2
-rw-r--r--core/types/transaction.go2
-rw-r--r--core/vm/contracts.go2
-rw-r--r--core/vm/instructions.go2
-rw-r--r--core/vm/jit.go2
-rw-r--r--core/vm/jit_test.go2
-rw-r--r--core/vm/runtime/runtime.go2
-rw-r--r--core/vm/vm.go2
-rw-r--r--core/vm/vm_jit.go4
-rw-r--r--crypto/crypto.go15
-rw-r--r--crypto/crypto_test.go10
-rw-r--r--crypto/key_store_passphrase.go8
-rw-r--r--crypto/randentropy/rand_entropy.go10
-rw-r--r--crypto/sha3/LICENSE27
-rw-r--r--crypto/sha3/PATENTS22
-rw-r--r--crypto/sha3/doc.go66
-rw-r--r--crypto/sha3/hashes.go68
-rw-r--r--crypto/sha3/keccakf.go28
-rw-r--r--crypto/sha3/register.go18
-rw-r--r--crypto/sha3/sha3.go358
-rw-r--r--crypto/sha3/sha3_test.go306
-rw-r--r--crypto/sha3/shake.go60
-rw-r--r--crypto/sha3/testdata/keccakKats.json.deflatebin0 -> 521342 bytes
-rw-r--r--crypto/sha3/xor.go16
-rw-r--r--crypto/sha3/xor_generic.go28
-rw-r--r--crypto/sha3/xor_unaligned.go58
-rw-r--r--eth/downloader/downloader_test.go5
-rw-r--r--eth/downloader/queue.go4
-rw-r--r--eth/handler_test.go2
-rw-r--r--ethdb/README.md11
-rw-r--r--generators/defaults.go2
-rw-r--r--light/odr.go4
-rw-r--r--light/state_object.go4
-rw-r--r--node/api.go2
-rw-r--r--p2p/discover/database.go2
-rw-r--r--p2p/discover/node.go2
-rw-r--r--p2p/discover/ntp.go127
-rw-r--r--p2p/discover/table.go6
-rw-r--r--p2p/discover/table_test.go4
-rw-r--r--p2p/discover/udp.go36
-rw-r--r--p2p/discover/udp_test.go2
-rw-r--r--p2p/rlpx.go8
-rw-r--r--p2p/rlpx_test.go4
-rw-r--r--[-rwxr-xr-x]params/protocol_params.go0
-rw-r--r--tests/util.go2
-rw-r--r--trie/secure_trie_test.go2
-rw-r--r--trie/trie.go2
-rw-r--r--whisper/envelope.go6
-rw-r--r--whisper/message.go2
-rw-r--r--whisper/topic.go2
70 files changed, 1080 insertions, 638 deletions
diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go
index c6a8705cd..d1b8330e3 100644
--- a/accounts/abi/abi_test.go
+++ b/accounts/abi/abi_test.go
@@ -244,7 +244,7 @@ func TestMethodSignature(t *testing.T) {
t.Error("signature mismatch", exp, "!=", m.Sig())
}
- idexp := crypto.Sha3([]byte(exp))[:4]
+ idexp := crypto.Keccak256([]byte(exp))[:4]
if !bytes.Equal(m.Id(), idexp) {
t.Errorf("expected ids to match %x != %x", m.Id(), idexp)
}
@@ -264,7 +264,7 @@ func TestPack(t *testing.T) {
t.FailNow()
}
- sig := crypto.Sha3([]byte("foo(uint32)"))[:4]
+ sig := crypto.Keccak256([]byte("foo(uint32)"))[:4]
sig = append(sig, make([]byte, 32)...)
sig[35] = 10
@@ -286,7 +286,7 @@ func TestMultiPack(t *testing.T) {
t.FailNow()
}
- sig := crypto.Sha3([]byte("bar(uint32,uint16)"))[:4]
+ sig := crypto.Keccak256([]byte("bar(uint32,uint16)"))[:4]
sig = append(sig, make([]byte, 64)...)
sig[35] = 10
sig[67] = 11
@@ -309,7 +309,7 @@ func TestPackSlice(t *testing.T) {
t.FailNow()
}
- sig := crypto.Sha3([]byte("slice(uint32[2])"))[:4]
+ sig := crypto.Keccak256([]byte("slice(uint32[2])"))[:4]
sig = append(sig, make([]byte, 64)...)
sig[35] = 1
sig[67] = 2
@@ -332,7 +332,7 @@ func TestPackSliceBig(t *testing.T) {
t.FailNow()
}
- sig := crypto.Sha3([]byte("slice256(uint256[2])"))[:4]
+ sig := crypto.Keccak256([]byte("slice256(uint256[2])"))[:4]
sig = append(sig, make([]byte, 64)...)
sig[35] = 1
sig[67] = 2
diff --git a/accounts/abi/event.go b/accounts/abi/event.go
index 7c4e092ea..e74c7c732 100644
--- a/accounts/abi/event.go
+++ b/accounts/abi/event.go
@@ -40,5 +40,5 @@ func (e Event) Id() common.Hash {
types[i] = input.Type.String()
i++
}
- return common.BytesToHash(crypto.Sha3([]byte(fmt.Sprintf("%v(%v)", e.Name, strings.Join(types, ",")))))
+ return common.BytesToHash(crypto.Keccak256([]byte(fmt.Sprintf("%v(%v)", e.Name, strings.Join(types, ",")))))
}
diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go
index 34a7a1684..cdd182512 100644
--- a/accounts/abi/event_test.go
+++ b/accounts/abi/event_test.go
@@ -19,8 +19,8 @@ func TestEventId(t *testing.T) {
{ "type" : "event", "name" : "check", "inputs": [{ "name" : "t", "type": "address" }, { "name": "b", "type": "uint256" }] }
]`,
expectations: map[string]common.Hash{
- "balance": crypto.Sha3Hash([]byte("balance(uint256)")),
- "check": crypto.Sha3Hash([]byte("check(address,uint256)")),
+ "balance": crypto.Keccak256Hash([]byte("balance(uint256)")),
+ "check": crypto.Keccak256Hash([]byte("check(address,uint256)")),
},
},
}
diff --git a/accounts/abi/method.go b/accounts/abi/method.go
index 63194e788..e259c09aa 100644
--- a/accounts/abi/method.go
+++ b/accounts/abi/method.go
@@ -72,5 +72,5 @@ func (m Method) String() string {
}
func (m Method) Id() []byte {
- return crypto.Sha3([]byte(m.Sig()))[:4]
+ return crypto.Keccak256([]byte(m.Sig()))[:4]
}
diff --git a/cmd/geth/js_test.go b/cmd/geth/js_test.go
index 4330b484c..af435e68c 100644
--- a/cmd/geth/js_test.go
+++ b/cmd/geth/js_test.go
@@ -396,7 +396,7 @@ multiply7 = Multiply7.at(contractaddress);
if sol != nil && solcVersion != sol.Version() {
modContractInfo := versionRE.ReplaceAll(contractInfo, []byte(`"compilerVersion":"`+sol.Version()+`"`))
fmt.Printf("modified contractinfo:\n%s\n", modContractInfo)
- contentHash = `"` + common.ToHex(crypto.Sha3([]byte(modContractInfo))) + `"`
+ contentHash = `"` + common.ToHex(crypto.Keccak256([]byte(modContractInfo))) + `"`
}
if checkEvalJSON(t, repl, `filename = "/tmp/info.json"`, `"/tmp/info.json"`) != nil {
return
diff --git a/common/bytes.go b/common/bytes.go
index ba6987a9e..4fb016a97 100644
--- a/common/bytes.go
+++ b/common/bytes.go
@@ -48,22 +48,6 @@ func FromHex(s string) []byte {
return nil
}
-type Bytes []byte
-
-func (self Bytes) String() string {
- return string(self)
-}
-
-func DeleteFromByteSlice(s [][]byte, hash []byte) [][]byte {
- for i, h := range s {
- if bytes.Compare(h, hash) == 0 {
- return append(s[:i:i], s[i+1:]...)
- }
- }
-
- return s
-}
-
// Number to bytes
//
// Returns the number in bytes with the specified base
@@ -154,7 +138,6 @@ func Hex2Bytes(str string) []byte {
}
func Hex2BytesFixed(str string, flen int) []byte {
-
h, _ := hex.DecodeString(str)
if len(h) == flen {
return h
@@ -167,7 +150,6 @@ func Hex2BytesFixed(str string, flen int) []byte {
return hh
}
}
-
}
func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) {
diff --git a/common/bytes_test.go b/common/bytes_test.go
index 816d2082b..2e5208477 100644
--- a/common/bytes_test.go
+++ b/common/bytes_test.go
@@ -27,26 +27,6 @@ type BytesSuite struct{}
var _ = checker.Suite(&BytesSuite{})
-func (s *BytesSuite) TestByteString(c *checker.C) {
- var data Bytes
- data = []byte{102, 111, 111}
- exp := "foo"
- res := data.String()
-
- c.Assert(res, checker.Equals, exp)
-}
-
-/*
-func (s *BytesSuite) TestDeleteFromByteSlice(c *checker.C) {
- data := []byte{1, 2, 3, 4}
- slice := []byte{1, 2, 3, 4}
- exp := []byte{1, 4}
- res := DeleteFromByteSlice(data, slice)
-
- c.Assert(res, checker.DeepEquals, exp)
-}
-
-*/
func (s *BytesSuite) TestNumberToBytes(c *checker.C) {
// data1 := int(1)
// res1 := NumberToBytes(data1, 16)
diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go
index aca3a1fc2..8d3304029 100644
--- a/common/compiler/solidity.go
+++ b/common/compiler/solidity.go
@@ -220,7 +220,7 @@ func SaveInfo(info *ContractInfo, filename string) (contenthash common.Hash, err
if err != nil {
return
}
- contenthash = common.BytesToHash(crypto.Sha3(infojson))
+ contenthash = common.BytesToHash(crypto.Keccak256(infojson))
err = ioutil.WriteFile(filename, infojson, 0600)
return
}
diff --git a/common/httpclient/httpclient.go b/common/httpclient/httpclient.go
index 23373ecaf..a0a1efd38 100644
--- a/common/httpclient/httpclient.go
+++ b/common/httpclient/httpclient.go
@@ -74,7 +74,7 @@ func (self *HTTPClient) GetAuthContent(uri string, hash common.Hash) ([]byte, er
}
// check hash to authenticate content
- chash := crypto.Sha3Hash(content)
+ chash := crypto.Keccak256Hash(content)
if chash != hash {
return nil, fmt.Errorf("content hash mismatch %x != %x (exp)", hash[:], chash[:])
}
diff --git a/common/httpclient/httpclient_test.go b/common/httpclient/httpclient_test.go
index 6c3782e15..670893f8a 100644
--- a/common/httpclient/httpclient_test.go
+++ b/common/httpclient/httpclient_test.go
@@ -36,7 +36,7 @@ func TestGetAuthContent(t *testing.T) {
client := New(dir)
text := "test"
- hash := crypto.Sha3Hash([]byte(text))
+ hash := crypto.Keccak256Hash([]byte(text))
if err := ioutil.WriteFile(path.Join(dir, "test.content"), []byte(text), os.ModePerm); err != nil {
t.Fatal("could not write test file", err)
}
diff --git a/common/natspec/natspec.go b/common/natspec/natspec.go
index 2e4d8d7a4..8197018cf 100644
--- a/common/natspec/natspec.go
+++ b/common/natspec/natspec.go
@@ -115,7 +115,7 @@ func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, client *httpc
err = fmt.Errorf("contract (%v) not found", contractAddress)
return
}
- codehash := common.BytesToHash(crypto.Sha3(codeb))
+ codehash := common.BytesToHash(crypto.Keccak256(codeb))
// set up nameresolver with natspecreg + urlhint contract addresses
reg := registrar.New(xeth)
@@ -197,7 +197,7 @@ type userDoc struct {
func (self *NatSpec) makeAbi2method(abiKey [8]byte) (meth *method) {
for signature, m := range self.userDoc.Methods {
name := strings.Split(signature, "(")[0]
- hash := []byte(common.Bytes2Hex(crypto.Sha3([]byte(signature))))
+ hash := []byte(common.Bytes2Hex(crypto.Keccak256([]byte(signature))))
var key [8]byte
copy(key[:], hash[:8])
if bytes.Equal(key[:], abiKey[:]) {
diff --git a/common/natspec/natspec_e2e_test.go b/common/natspec/natspec_e2e_test.go
index 4a9b92eb6..0730391c7 100644
--- a/common/natspec/natspec_e2e_test.go
+++ b/common/natspec/natspec_e2e_test.go
@@ -238,11 +238,11 @@ func TestNatspecE2E(t *testing.T) {
// create a contractInfo file (mock cloud-deployed contract metadocs)
// incidentally this is the info for the HashReg contract itself
ioutil.WriteFile("/tmp/"+testFileName, []byte(testContractInfo), os.ModePerm)
- dochash := crypto.Sha3Hash([]byte(testContractInfo))
+ dochash := crypto.Keccak256Hash([]byte(testContractInfo))
// take the codehash for the contract we wanna test
codeb := tf.xeth.CodeAtBytes(registrar.HashRegAddr)
- codehash := crypto.Sha3Hash(codeb)
+ codehash := crypto.Keccak256Hash(codeb)
reg := registrar.New(tf.xeth)
_, err := reg.SetHashToHash(addr, codehash, dochash)
diff --git a/common/natspec/natspec_e2e_test.go.orig b/common/natspec/natspec_e2e_test.go.orig
deleted file mode 100644
index 601a9edbd..000000000
--- a/common/natspec/natspec_e2e_test.go.orig
+++ /dev/null
@@ -1,253 +0,0 @@
-package natspec
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "strings"
- "testing"
-
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/docserver"
- "github.com/ethereum/go-ethereum/common/registrar"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/eth"
- xe "github.com/ethereum/go-ethereum/xeth"
-)
-
-const (
- testBalance = "10000000000000000000"
-
- testFileName = "long_file_name_for_testing_registration_of_URLs_longer_than_32_bytes.content"
-
- testNotice = "Register key `utils.toHex(_key)` <- content `utils.toHex(_content)`"
-
- testExpNotice = "Register key 0xadd1a7d961cff0242089674ec2ef6fca671ab15e1fe80e38859fc815b98d88ab <- content 0xb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7"
-
- testExpNotice2 = `About to submit transaction (NatSpec notice error: abi key does not match any method): {"params":[{"to":"%s","data": "0x31e12c20"}]}`
-
- testExpNotice3 = `About to submit transaction (no NatSpec info found for contract: content hash not found for '0x1392c62d05b2d149e22a339c531157ae06b44d39a674cce500064b12b9aeb019'): {"params":[{"to":"%s","data": "0x300a3bbfb3a2dea218de5d8bbe6c4645aadbf67b5ab00ecb1a9ec95dbdad6a0eed3e41a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066696c653a2f2f2f746573742e636f6e74656e74"}]}`
-)
-
-const (
- testUserDoc = `
-{
- "methods": {
- "register(uint256,uint256)": {
- "notice": "` + testNotice + `"
- }
- },
- "invariants": [
- { "notice": "" }
- ],
- "construction": [
- { "notice": "" }
- ]
-}
-`
- testAbiDefinition = `
-[{
- "name": "register",
- "constant": false,
- "type": "function",
- "inputs": [{
- "name": "_key",
- "type": "uint256"
- }, {
- "name": "_content",
- "type": "uint256"
- }],
- "outputs": []
-}]
-`
-
- testContractInfo = `
-{
- "userDoc": ` + testUserDoc + `,
- "abiDefinition": ` + testAbiDefinition + `
-}
-`
-)
-
-type testFrontend struct {
- t *testing.T
- ethereum *eth.Ethereum
- xeth *xe.XEth
- coinbase common.Address
- stateDb *state.StateDB
- txc uint64
- lastConfirm string
- wantNatSpec bool
-}
-
-func (self *testFrontend) UnlockAccount(acc []byte) bool {
- self.ethereum.AccountManager().Unlock(common.BytesToAddress(acc), "password")
- return true
-}
-
-func (self *testFrontend) ConfirmTransaction(tx string) bool {
- if self.wantNatSpec {
- ds := docserver.New("/tmp/")
- self.lastConfirm = GetNotice(self.xeth, tx, ds)
- }
- return true
-}
-
-func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
-
- os.RemoveAll("/tmp/eth-natspec/")
-
- err = os.MkdirAll("/tmp/eth-natspec/keystore", os.ModePerm)
- if err != nil {
- panic(err)
- }
-
- // create a testAddress
- ks := crypto.NewKeyStorePassphrase("/tmp/eth-natspec/keystore", crypto.LightScryptN, crypto.LightScryptP)
- am := accounts.NewManager(ks)
- testAccount, err := am.NewAccount("password")
- if err != nil {
- panic(err)
- }
- testAddress := strings.TrimPrefix(testAccount.Address.Hex(), "0x")
-
- // set up mock genesis with balance on the testAddress
- core.GenesisAccounts = []byte(`{
- "` + testAddress + `": {"balance": "` + testBalance + `"}
- }`)
-
- // only use minimalistic stack with no networking
- ethereum, err = eth.New(&eth.Config{
- DataDir: "/tmp/eth-natspec",
- AccountManager: am,
- MaxPeers: 0,
- })
-
- if err != nil {
- panic(err)
- }
-
- return
-}
-
-func testInit(t *testing.T) (self *testFrontend) {
- // initialise and start minimal ethereum stack
- ethereum, err := testEth(t)
- if err != nil {
- t.Errorf("error creating ethereum: %v", err)
- return
- }
- err = ethereum.Start()
- if err != nil {
- t.Errorf("error starting ethereum: %v", err)
- return
- }
-
- // mock frontend
- self = &testFrontend{t: t, ethereum: ethereum}
- self.xeth = xe.New(ethereum, self)
-
- addr, _ := ethereum.Etherbase()
- self.coinbase = addr
- self.stateDb = self.ethereum.ChainManager().State().Copy()
-
- // initialise the registry contracts
- reg := registrar.New(self.xeth)
- err = reg.SetHashReg("", addr)
- if err != nil {
- t.Errorf("error creating HashReg: %v", err)
- }
- err = reg.SetUrlHint("", addr)
- if err != nil {
- t.Errorf("error creating UrlHint: %v", err)
- }
- self.applyTxs()
-
- return
-
-}
-
-// this is needed for transaction to be applied to the state in testing
-// the heavy lifing is done in XEth.ApplyTestTxs
-// this is fragile,
-// and does process leaking since xeth loops cannot quit safely
-// should be replaced by proper mining with testDAG for easy full integration tests
-func (self *testFrontend) applyTxs() {
- self.txc, self.xeth = self.xeth.ApplyTestTxs(self.stateDb, self.coinbase, self.txc)
- return
-}
-
-// end to end test
-func TestNatspecE2E(t *testing.T) {
- t.Skip()
-
- tf := testInit(t)
- defer tf.ethereum.Stop()
-
- // create a contractInfo file (mock cloud-deployed contract metadocs)
- // incidentally this is the info for the registry contract itself
- ioutil.WriteFile("/tmp/"+testFileName, []byte(testContractInfo), os.ModePerm)
- dochash := common.BytesToHash(crypto.Sha3([]byte(testContractInfo)))
-
- // take the codehash for the contract we wanna test
- // codehex := tf.xeth.CodeAt(registar.HashRegAddr)
- codeb := tf.xeth.CodeAtBytes(registrar.HashRegAddr)
- codehash := common.BytesToHash(crypto.Sha3(codeb))
-
- // use resolver to register codehash->dochash->url
- // test if globalregistry works
- // registrar.HashRefAddr = "0x0"
- // registrar.UrlHintAddr = "0x0"
- reg := registrar.New(tf.xeth)
- _, err := reg.SetHashToHash(tf.coinbase, codehash, dochash)
- if err != nil {
- t.Errorf("error registering: %v", err)
- }
- _, err = reg.SetUrlToHash(tf.coinbase, dochash, "file:///"+testFileName)
- if err != nil {
- t.Errorf("error registering: %v", err)
- }
- // apply txs to the state
- tf.applyTxs()
-
- // NatSpec info for register method of HashReg contract installed
- // now using the same transactions to check confirm messages
-
- tf.wantNatSpec = true // this is set so now the backend uses natspec confirmation
- _, err = reg.SetHashToHash(tf.coinbase, codehash, dochash)
- if err != nil {
- t.Errorf("error calling contract registry: %v", err)
- }
-
- fmt.Printf("GlobalRegistrar: %v, HashReg: %v, UrlHint: %v\n", registrar.GlobalRegistrarAddr, registrar.HashRegAddr, registrar.UrlHintAddr)
- if tf.lastConfirm != testExpNotice {
- t.Errorf("Wrong confirm message. expected '%v', got '%v'", testExpNotice, tf.lastConfirm)
- }
-
- // test unknown method
- exp := fmt.Sprintf(testExpNotice2, registrar.HashRegAddr)
- _, err = reg.SetOwner(tf.coinbase)
- if err != nil {
- t.Errorf("error setting owner: %v", err)
- }
-
- if tf.lastConfirm != exp {
- t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
- }
-
- // test unknown contract
- exp = fmt.Sprintf(testExpNotice3, registrar.UrlHintAddr)
-
- _, err = reg.SetUrlToHash(tf.coinbase, dochash, "file:///test.content")
- if err != nil {
- t.Errorf("error registering: %v", err)
- }
-
- if tf.lastConfirm != exp {
- t.Errorf("Wrong confirm message, expected '%v', got '%v'", exp, tf.lastConfirm)
- }
-
-}
diff --git a/common/registrar/ethreg/api.go b/common/registrar/ethreg/api.go
index 1ba422c4d..79a6c2191 100644
--- a/common/registrar/ethreg/api.go
+++ b/common/registrar/ethreg/api.go
@@ -86,7 +86,7 @@ func (api *PrivateRegistarAPI) Register(sender common.Address, addr common.Addre
}
codeb := state.GetCode(addr)
- codeHash := common.BytesToHash(crypto.Sha3(codeb))
+ codeHash := common.BytesToHash(crypto.Keccak256(codeb))
contentHash := common.HexToHash(contentHashHex)
_, err = registrar.New(api.be).SetHashToHash(sender, codeHash, contentHash)
diff --git a/common/registrar/registrar.go b/common/registrar/registrar.go
index 24e45edb3..0606f6985 100644
--- a/common/registrar/registrar.go
+++ b/common/registrar/registrar.go
@@ -68,7 +68,7 @@ const (
)
func abiSignature(s string) string {
- return common.ToHex(crypto.Sha3([]byte(s))[:4])
+ return common.ToHex(crypto.Keccak256([]byte(s))[:4])
}
var (
@@ -401,7 +401,7 @@ func storageMapping(addr, key []byte) []byte {
data := make([]byte, 64)
copy(data[0:32], key[0:32])
copy(data[32:64], addr[0:32])
- sha := crypto.Sha3(data)
+ sha := crypto.Keccak256(data)
return sha
}
diff --git a/common/registrar/registrar_test.go b/common/registrar/registrar_test.go
index 68ee65ab4..b2287803c 100644
--- a/common/registrar/registrar_test.go
+++ b/common/registrar/registrar_test.go
@@ -31,7 +31,7 @@ type testBackend struct {
var (
text = "test"
codehash = common.StringToHash("1234")
- hash = common.BytesToHash(crypto.Sha3([]byte(text)))
+ hash = common.BytesToHash(crypto.Keccak256([]byte(text)))
url = "bzz://bzzhash/my/path/contr.act"
)
diff --git a/compression/rle/read_write.go b/compression/rle/read_write.go
index 19133119b..03dffd607 100644
--- a/compression/rle/read_write.go
+++ b/compression/rle/read_write.go
@@ -31,8 +31,8 @@ const (
tokenToken = 0xff
)
-var empty = crypto.Sha3([]byte(""))
-var emptyList = crypto.Sha3([]byte{0x80})
+var empty = crypto.Keccak256([]byte(""))
+var emptyList = crypto.Keccak256([]byte{0x80})
func Decompress(dat []byte) ([]byte, error) {
buf := new(bytes.Buffer)
diff --git a/compression/rle/read_write_test.go b/compression/rle/read_write_test.go
index ba3965025..20a23a196 100644
--- a/compression/rle/read_write_test.go
+++ b/compression/rle/read_write_test.go
@@ -67,8 +67,8 @@ func (s *CompressionRleSuite) TestDecompressSimple(c *checker.C) {
// }
// var exp []byte
-// exp = append(exp, crypto.Sha3([]byte(""))...)
-// exp = append(exp, crypto.Sha3([]byte{0x80})...)
+// exp = append(exp, crypto.Keccak256([]byte(""))...)
+// exp = append(exp, crypto.Keccak256([]byte{0x80})...)
// exp = append(exp, make([]byte, 10)...)
// if bytes.Compare(res, res) != 0 {
@@ -82,12 +82,12 @@ func (s *CompressionRleSuite) TestDecompressSimple(c *checker.C) {
// t.Error("5 * zero", res)
// }
-// res = Compress(crypto.Sha3([]byte("")))
+// res = Compress(crypto.Keccak256([]byte("")))
// if bytes.Compare(res, []byte{token, emptyShaToken}) != 0 {
// t.Error("empty sha", res)
// }
-// res = Compress(crypto.Sha3([]byte{0x80}))
+// res = Compress(crypto.Keccak256([]byte{0x80}))
// if bytes.Compare(res, []byte{token, emptyListShaToken}) != 0 {
// t.Error("empty list sha", res)
// }
@@ -100,8 +100,8 @@ func (s *CompressionRleSuite) TestDecompressSimple(c *checker.C) {
// func TestCompressMulti(t *testing.T) {
// in := []byte{0, 0, 0, 0, 0}
-// in = append(in, crypto.Sha3([]byte(""))...)
-// in = append(in, crypto.Sha3([]byte{0x80})...)
+// in = append(in, crypto.Keccak256([]byte(""))...)
+// in = append(in, crypto.Keccak256([]byte{0x80})...)
// in = append(in, token)
// res := Compress(in)
@@ -116,8 +116,8 @@ func (s *CompressionRleSuite) TestDecompressSimple(c *checker.C) {
// for i := 0; i < 20; i++ {
// in = append(in, []byte{0, 0, 0, 0, 0}...)
-// in = append(in, crypto.Sha3([]byte(""))...)
-// in = append(in, crypto.Sha3([]byte{0x80})...)
+// in = append(in, crypto.Keccak256([]byte(""))...)
+// in = append(in, crypto.Keccak256([]byte{0x80})...)
// in = append(in, []byte{123, 2, 19, 89, 245, 254, 255, token, 98, 233}...)
// in = append(in, token)
// }
diff --git a/core/state/state_object.go b/core/state/state_object.go
index 6095fc96a..0f86325c6 100644
--- a/core/state/state_object.go
+++ b/core/state/state_object.go
@@ -30,7 +30,7 @@ import (
"github.com/ethereum/go-ethereum/trie"
)
-var emptyCodeHash = crypto.Sha3(nil)
+var emptyCodeHash = crypto.Keccak256(nil)
type Code []byte
@@ -225,7 +225,7 @@ func (self *StateObject) Code() []byte {
func (self *StateObject) SetCode(code []byte) {
self.code = code
- self.codeHash = crypto.Sha3(code)
+ self.codeHash = crypto.Keccak256(code)
self.dirty = true
}
diff --git a/core/types/bloom9.go b/core/types/bloom9.go
index 372045ab2..ecf2bffc2 100644
--- a/core/types/bloom9.go
+++ b/core/types/bloom9.go
@@ -101,7 +101,7 @@ func LogsBloom(logs vm.Logs) *big.Int {
}
func bloom9(b []byte) *big.Int {
- b = crypto.Sha3(b[:])
+ b = crypto.Keccak256(b[:])
r := new(big.Int)
diff --git a/core/types/bloom9_test.go b/core/types/bloom9_test.go
index 5744bec6c..58e8f7073 100644
--- a/core/types/bloom9_test.go
+++ b/core/types/bloom9_test.go
@@ -73,7 +73,7 @@ func TestBloom9(t *testing.T) {
func TestAddress(t *testing.T) {
block := &Block{}
block.Coinbase = common.Hex2Bytes("22341ae42d6dd7384bc8584e50419ea3ac75b83f")
- fmt.Printf("%x\n", crypto.Sha3(block.Coinbase))
+ fmt.Printf("%x\n", crypto.Keccak256(block.Coinbase))
bin := CreateBloom(block)
fmt.Printf("bin = %x\n", common.LeftPadBytes(bin, 64))
diff --git a/core/types/transaction.go b/core/types/transaction.go
index 0c9c1ce18..37715ee53 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -202,7 +202,7 @@ func doFrom(tx *Transaction, homestead bool) (common.Address, error) {
return common.Address{}, err
}
var addr common.Address
- copy(addr[:], crypto.Sha3(pubkey[1:])[12:])
+ copy(addr[:], crypto.Keccak256(pubkey[1:])[12:])
tx.from.Store(addr)
return addr, nil
}
diff --git a/core/vm/contracts.go b/core/vm/contracts.go
index f204432a2..5cc9f903b 100644
--- a/core/vm/contracts.go
+++ b/core/vm/contracts.go
@@ -111,7 +111,7 @@ func ecrecoverFunc(in []byte) []byte {
}
// the first byte of pubkey is bitcoin heritage
- return common.LeftPadBytes(crypto.Sha3(pubKey[1:])[12:], 32)
+ return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32)
}
func memCpy(in []byte) []byte {
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 26f7671ff..1e1086b13 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -316,7 +316,7 @@ func opMulmod(instr instruction, pc *uint64, env Environment, contract *Contract
func opSha3(instr instruction, pc *uint64, env Environment, contract *Contract, memory *Memory, stack *stack) {
offset, size := stack.pop(), stack.pop()
- hash := crypto.Sha3(memory.Get(offset.Int64(), size.Int64()))
+ hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64()))
stack.push(common.BytesToBig(hash))
}
diff --git a/core/vm/jit.go b/core/vm/jit.go
index 504aab523..5404730c1 100644
--- a/core/vm/jit.go
+++ b/core/vm/jit.go
@@ -96,7 +96,7 @@ type Program struct {
// NewProgram returns a new JIT program
func NewProgram(code []byte) *Program {
program := &Program{
- Id: crypto.Sha3Hash(code),
+ Id: crypto.Keccak256Hash(code),
mapping: make(map[uint64]uint64),
destinations: make(map[uint64]struct{}),
code: code,
diff --git a/core/vm/jit_test.go b/core/vm/jit_test.go
index e8e078a46..4174c666f 100644
--- a/core/vm/jit_test.go
+++ b/core/vm/jit_test.go
@@ -189,7 +189,7 @@ func (self *Env) Db() Database { return nil }
func (self *Env) GasLimit() *big.Int { return self.gasLimit }
func (self *Env) VmType() Type { return StdVmTy }
func (self *Env) GetHash(n uint64) common.Hash {
- return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
+ return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String())))
}
func (self *Env) AddLog(log *Log) {
}
diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go
index 1fa06e980..565ce7b73 100644
--- a/core/vm/runtime/runtime.go
+++ b/core/vm/runtime/runtime.go
@@ -67,7 +67,7 @@ func setDefaults(cfg *Config) {
}
if cfg.GetHashFn == nil {
cfg.GetHashFn = func(n uint64) common.Hash {
- return common.BytesToHash(crypto.Sha3([]byte(new(big.Int).SetUint64(n).String())))
+ return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String())))
}
}
}
diff --git a/core/vm/vm.go b/core/vm/vm.go
index 320135ff2..d45d136b5 100644
--- a/core/vm/vm.go
+++ b/core/vm/vm.go
@@ -58,7 +58,7 @@ func (self *Vm) Run(contract *Contract, input []byte) (ret []byte, err error) {
}
var (
- codehash = crypto.Sha3Hash(contract.Code) // codehash is used when doing jump dest caching
+ codehash = crypto.Keccak256Hash(contract.Code) // codehash is used when doing jump dest caching
program *Program
)
if EnableJit {
diff --git a/core/vm/vm_jit.go b/core/vm/vm_jit.go
index 07cb52d4a..589c30fa8 100644
--- a/core/vm/vm_jit.go
+++ b/core/vm/vm_jit.go
@@ -200,7 +200,7 @@ func (self *JitVm) Run(me, caller ContextRef, code []byte, value, gas, price *bi
self.data.timestamp = self.env.Time()
self.data.code = getDataPtr(code)
self.data.codeSize = uint64(len(code))
- self.data.codeHash = hash2llvm(crypto.Sha3(code)) // TODO: Get already computed hash?
+ self.data.codeHash = hash2llvm(crypto.Keccak256(code)) // TODO: Get already computed hash?
jit := C.evmjit_create()
retCode := C.evmjit_run(jit, unsafe.Pointer(&self.data), unsafe.Pointer(self))
@@ -242,7 +242,7 @@ func (self *JitVm) Env() Environment {
//export env_sha3
func env_sha3(dataPtr *byte, length uint64, resultPtr unsafe.Pointer) {
data := llvm2bytesRef(dataPtr, length)
- hash := crypto.Sha3(data)
+ hash := crypto.Keccak256(data)
result := (*i256)(resultPtr)
*result = hash2llvm(hash)
}
diff --git a/crypto/crypto.go b/crypto/crypto.go
index 850be4da6..f1f6affac 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -43,7 +43,7 @@ import (
"golang.org/x/crypto/ripemd160"
)
-func Sha3(data ...[]byte) []byte {
+func Keccak256(data ...[]byte) []byte {
d := sha3.NewKeccak256()
for _, b := range data {
d.Write(b)
@@ -51,7 +51,7 @@ func Sha3(data ...[]byte) []byte {
return d.Sum(nil)
}
-func Sha3Hash(data ...[]byte) (h common.Hash) {
+func Keccak256Hash(data ...[]byte) (h common.Hash) {
d := sha3.NewKeccak256()
for _, b := range data {
d.Write(b)
@@ -60,11 +60,14 @@ func Sha3Hash(data ...[]byte) (h common.Hash) {
return h
}
+// Deprecated: For backward compatibility as other packages depend on these
+func Sha3(data ...[]byte) []byte { return Keccak256(data...) }
+func Sha3Hash(data ...[]byte) common.Hash { return Keccak256Hash(data...) }
+
// Creates an ethereum address given the bytes and the nonce
func CreateAddress(b common.Address, nonce uint64) common.Address {
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
- return common.BytesToAddress(Sha3(data)[12:])
- //return Sha3(common.NewValue([]interface{}{b, nonce}).Encode())[12:]
+ return common.BytesToAddress(Keccak256(data)[12:])
}
func Sha256(data []byte) []byte {
@@ -265,7 +268,7 @@ func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error
if err != nil {
return nil, err
}
- ethPriv := Sha3(plainText)
+ ethPriv := Keccak256(plainText)
ecKey := ToECDSA(ethPriv)
key = &Key{
Id: nil,
@@ -330,7 +333,7 @@ func PKCS7Unpad(in []byte) []byte {
func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
pubBytes := FromECDSAPub(&p)
- return common.BytesToAddress(Sha3(pubBytes[1:])[12:])
+ return common.BytesToAddress(Keccak256(pubBytes[1:])[12:])
}
func zeroBytes(bytes []byte) {
diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go
index 1681c7fef..58b29da49 100644
--- a/crypto/crypto_test.go
+++ b/crypto/crypto_test.go
@@ -40,13 +40,13 @@ var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232
func TestSha3(t *testing.T) {
msg := []byte("abc")
exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
- checkhash(t, "Sha3-256", func(in []byte) []byte { return Sha3(in) }, msg, exp)
+ checkhash(t, "Sha3-256", func(in []byte) []byte { return Keccak256(in) }, msg, exp)
}
func TestSha3Hash(t *testing.T) {
msg := []byte("abc")
exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
- checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Sha3Hash(in); return h[:] }, msg, exp)
+ checkhash(t, "Sha3-256-array", func(in []byte) []byte { h := Keccak256Hash(in); return h[:] }, msg, exp)
}
func TestSha256(t *testing.T) {
@@ -66,7 +66,7 @@ func BenchmarkSha3(b *testing.B) {
amount := 1000000
start := time.Now()
for i := 0; i < amount; i++ {
- Sha3(a)
+ Keccak256(a)
}
fmt.Println(amount, ":", time.Since(start))
@@ -84,7 +84,7 @@ func TestSign(t *testing.T) {
key, _ := HexToECDSA(testPrivHex)
addr := common.HexToAddress(testAddrHex)
- msg := Sha3([]byte("foo"))
+ msg := Keccak256([]byte("foo"))
sig, err := Sign(msg, key)
if err != nil {
t.Errorf("Sign error: %s", err)
@@ -238,7 +238,7 @@ func TestPythonIntegration(t *testing.T) {
k0, _ := HexToECDSA(kh)
k1 := FromECDSA(k0)
- msg0 := Sha3([]byte("foo"))
+ msg0 := Keccak256([]byte("foo"))
sig0, _ := secp256k1.Sign(msg0, k1)
msg1 := common.FromHex("00000000000000000000000000000000")
diff --git a/crypto/key_store_passphrase.go b/crypto/key_store_passphrase.go
index 94411d2f9..b7ae9e1de 100644
--- a/crypto/key_store_passphrase.go
+++ b/crypto/key_store_passphrase.go
@@ -110,7 +110,7 @@ func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) {
return err
}
- mac := Sha3(derivedKey[16:32], cipherText)
+ mac := Keccak256(derivedKey[16:32], cipherText)
scryptParamsJSON := make(map[string]interface{}, 5)
scryptParamsJSON["n"] = ks.scryptN
@@ -210,7 +210,7 @@ func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byt
return nil, nil, err
}
- calculatedMAC := Sha3(derivedKey[16:32], cipherText)
+ calculatedMAC := Keccak256(derivedKey[16:32], cipherText)
if !bytes.Equal(calculatedMAC, mac) {
return nil, nil, errors.New("Decryption failed: MAC mismatch")
}
@@ -244,12 +244,12 @@ func decryptKeyV1(keyProtected *encryptedKeyJSONV1, auth string) (keyBytes []byt
return nil, nil, err
}
- calculatedMAC := Sha3(derivedKey[16:32], cipherText)
+ calculatedMAC := Keccak256(derivedKey[16:32], cipherText)
if !bytes.Equal(calculatedMAC, mac) {
return nil, nil, errors.New("Decryption failed: MAC mismatch")
}
- plainText, err := aesCBCDecrypt(Sha3(derivedKey[:16])[:16], cipherText, iv)
+ plainText, err := aesCBCDecrypt(Keccak256(derivedKey[:16])[:16], cipherText, iv)
if err != nil {
return nil, nil, err
}
diff --git a/crypto/randentropy/rand_entropy.go b/crypto/randentropy/rand_entropy.go
index 0c2e3c051..539d3ac89 100644
--- a/crypto/randentropy/rand_entropy.go
+++ b/crypto/randentropy/rand_entropy.go
@@ -19,8 +19,6 @@ package randentropy
import (
crand "crypto/rand"
"io"
-
- "github.com/ethereum/go-ethereum/crypto/sha3"
)
var Reader io.Reader = &randEntropy{}
@@ -34,14 +32,6 @@ func (*randEntropy) Read(bytes []byte) (n int, err error) {
return len(bytes), nil
}
-// TODO: copied from crypto.go , move to sha3 package?
-func Sha3(data []byte) []byte {
- d := sha3.NewKeccak256()
- d.Write(data)
-
- return d.Sum(nil)
-}
-
func GetEntropyCSPRNG(n int) []byte {
mainBuff := make([]byte, n)
_, err := io.ReadFull(crand.Reader, mainBuff)
diff --git a/crypto/sha3/LICENSE b/crypto/sha3/LICENSE
new file mode 100644
index 000000000..6a66aea5e
--- /dev/null
+++ b/crypto/sha3/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/crypto/sha3/PATENTS b/crypto/sha3/PATENTS
new file mode 100644
index 000000000..733099041
--- /dev/null
+++ b/crypto/sha3/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/crypto/sha3/doc.go b/crypto/sha3/doc.go
new file mode 100644
index 000000000..3dab530f8
--- /dev/null
+++ b/crypto/sha3/doc.go
@@ -0,0 +1,66 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sha3 implements the SHA-3 fixed-output-length hash functions and
+// the SHAKE variable-output-length hash functions defined by FIPS-202.
+//
+// Both types of hash function use the "sponge" construction and the Keccak
+// permutation. For a detailed specification see http://keccak.noekeon.org/
+//
+//
+// Guidance
+//
+// If you aren't sure what function you need, use SHAKE256 with at least 64
+// bytes of output. The SHAKE instances are faster than the SHA3 instances;
+// the latter have to allocate memory to conform to the hash.Hash interface.
+//
+// If you need a secret-key MAC (message authentication code), prepend the
+// secret key to the input, hash with SHAKE256 and read at least 32 bytes of
+// output.
+//
+//
+// Security strengths
+//
+// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security
+// strength against preimage attacks of x bits. Since they only produce "x"
+// bits of output, their collision-resistance is only "x/2" bits.
+//
+// The SHAKE-256 and -128 functions have a generic security strength of 256 and
+// 128 bits against all attacks, provided that at least 2x bits of their output
+// is used. Requesting more than 64 or 32 bytes of output, respectively, does
+// not increase the collision-resistance of the SHAKE functions.
+//
+//
+// The sponge construction
+//
+// A sponge builds a pseudo-random function from a public pseudo-random
+// permutation, by applying the permutation to a state of "rate + capacity"
+// bytes, but hiding "capacity" of the bytes.
+//
+// A sponge starts out with a zero state. To hash an input using a sponge, up
+// to "rate" bytes of the input are XORed into the sponge's state. The sponge
+// is then "full" and the permutation is applied to "empty" it. This process is
+// repeated until all the input has been "absorbed". The input is then padded.
+// The digest is "squeezed" from the sponge in the same way, except that output
+// output is copied out instead of input being XORed in.
+//
+// A sponge is parameterized by its generic security strength, which is equal
+// to half its capacity; capacity + rate is equal to the permutation's width.
+// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means
+// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2.
+//
+//
+// Recommendations
+//
+// The SHAKE functions are recommended for most new uses. They can produce
+// output of arbitrary length. SHAKE256, with an output length of at least
+// 64 bytes, provides 256-bit security against all attacks. The Keccak team
+// recommends it for most applications upgrading from SHA2-512. (NIST chose a
+// much stronger, but much slower, sponge instance for SHA3-512.)
+//
+// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions.
+// They produce output of the same length, with the same security strengths
+// against all attacks. This means, in particular, that SHA3-256 only has
+// 128-bit collision resistance, because its output length is 32 bytes.
+package sha3
diff --git a/crypto/sha3/hashes.go b/crypto/sha3/hashes.go
new file mode 100644
index 000000000..669cd5543
--- /dev/null
+++ b/crypto/sha3/hashes.go
@@ -0,0 +1,68 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file provides functions for creating instances of the SHA-3
+// and SHAKE hash functions, as well as utility functions for hashing
+// bytes.
+
+import (
+ "hash"
+)
+
+// NewKeccak256 creates a new Keccak-256 hash.
+func NewKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} }
+
+// New224 creates a new SHA3-224 hash.
+// Its generic security strength is 224 bits against preimage attacks,
+// and 112 bits against collision attacks.
+func New224() hash.Hash { return &state{rate: 144, outputLen: 28, dsbyte: 0x06} }
+
+// New256 creates a new SHA3-256 hash.
+// Its generic security strength is 256 bits against preimage attacks,
+// and 128 bits against collision attacks.
+func New256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x06} }
+
+// New384 creates a new SHA3-384 hash.
+// Its generic security strength is 384 bits against preimage attacks,
+// and 192 bits against collision attacks.
+func New384() hash.Hash { return &state{rate: 104, outputLen: 48, dsbyte: 0x06} }
+
+// New512 creates a new SHA3-512 hash.
+// Its generic security strength is 512 bits against preimage attacks,
+// and 256 bits against collision attacks.
+func New512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x06} }
+
+// Sum224 returns the SHA3-224 digest of the data.
+func Sum224(data []byte) (digest [28]byte) {
+ h := New224()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum256 returns the SHA3-256 digest of the data.
+func Sum256(data []byte) (digest [32]byte) {
+ h := New256()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum384 returns the SHA3-384 digest of the data.
+func Sum384(data []byte) (digest [48]byte) {
+ h := New384()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum512 returns the SHA3-512 digest of the data.
+func Sum512(data []byte) (digest [64]byte) {
+ h := New512()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
diff --git a/crypto/sha3/keccakf.go b/crypto/sha3/keccakf.go
index 5fb98cbeb..13e7058fa 100644
--- a/crypto/sha3/keccakf.go
+++ b/crypto/sha3/keccakf.go
@@ -1,30 +1,6 @@
// Copyright 2014 The Go Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
package sha3
diff --git a/crypto/sha3/register.go b/crypto/sha3/register.go
new file mode 100644
index 000000000..3cf6a22e0
--- /dev/null
+++ b/crypto/sha3/register.go
@@ -0,0 +1,18 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.4
+
+package sha3
+
+import (
+ "crypto"
+)
+
+func init() {
+ crypto.RegisterHash(crypto.SHA3_224, New224)
+ crypto.RegisterHash(crypto.SHA3_256, New256)
+ crypto.RegisterHash(crypto.SHA3_384, New384)
+ crypto.RegisterHash(crypto.SHA3_512, New512)
+}
diff --git a/crypto/sha3/sha3.go b/crypto/sha3/sha3.go
index ee24df5c9..c8fd31cb0 100644
--- a/crypto/sha3/sha3.go
+++ b/crypto/sha3/sha3.go
@@ -1,237 +1,193 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Package sha3 implements the SHA3 hash algorithm (formerly called Keccak) chosen by NIST in 2012.
-// This file provides a SHA3 implementation which implements the standard hash.Hash interface.
-// Writing input data, including padding, and reading output data are computed in this file.
-// Note that the current implementation can compute the hash of an integral number of bytes only.
-// This is a consequence of the hash interface in which a buffer of bytes is passed in.
-// The internals of the Keccak-f function are computed in keccakf.go.
-// For the detailed specification, refer to the Keccak web site (http://keccak.noekeon.org/).
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
package sha3
-import (
- "encoding/binary"
- "hash"
+// spongeDirection indicates the direction bytes are flowing through the sponge.
+type spongeDirection int
+
+const (
+ // spongeAbsorbing indicates that the sponge is absorbing input.
+ spongeAbsorbing spongeDirection = iota
+ // spongeSqueezing indicates that the sponge is being squeezed.
+ spongeSqueezing
)
-// laneSize is the size in bytes of each "lane" of the internal state of SHA3 (5 * 5 * 8).
-// Note that changing this size would requires using a type other than uint64 to store each lane.
-const laneSize = 8
-
-// sliceSize represents the dimensions of the internal state, a square matrix of
-// sliceSize ** 2 lanes. This is the size of both the "rows" and "columns" dimensions in the
-// terminology of the SHA3 specification.
-const sliceSize = 5
-
-// numLanes represents the total number of lanes in the state.
-const numLanes = sliceSize * sliceSize
-
-// stateSize is the size in bytes of the internal state of SHA3 (5 * 5 * WSize).
-const stateSize = laneSize * numLanes
-
-// digest represents the partial evaluation of a checksum.
-// Note that capacity, and not outputSize, is the critical security parameter, as SHA3 can output
-// an arbitrary number of bytes for any given capacity. The Keccak proposal recommends that
-// capacity = 2*outputSize to ensure that finding a collision of size outputSize requires
-// O(2^{outputSize/2}) computations (the birthday lower bound). Future standards may modify the
-// capacity/outputSize ratio to allow for more output with lower cryptographic security.
-type digest struct {
- a [numLanes]uint64 // main state of the hash
- outputSize int // desired output size in bytes
- capacity int // number of bytes to leave untouched during squeeze/absorb
- absorbed int // number of bytes absorbed thus far
-}
+const (
+ // maxRate is the maximum size of the internal buffer. SHAKE-256
+ // currently needs the largest buffer.
+ maxRate = 168
+)
-// minInt returns the lesser of two integer arguments, to simplify the absorption routine.
-func minInt(v1, v2 int) int {
- if v1 <= v2 {
- return v1
- }
- return v2
+type state struct {
+ // Generic sponge components.
+ a [25]uint64 // main state of the hash
+ buf []byte // points into storage
+ rate int // the number of bytes of state to use
+
+ // dsbyte contains the "domain separation" bits and the first bit of
+ // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
+ // SHA-3 and SHAKE functions by appending bitstrings to the message.
+ // Using a little-endian bit-ordering convention, these are "01" for SHA-3
+ // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
+ // padding rule from section 5.1 is applied to pad the message to a multiple
+ // of the rate, which involves adding a "1" bit, zero or more "0" bits, and
+ // a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
+ // giving 00000110b (0x06) and 00011111b (0x1f).
+ // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
+ // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
+ // Extendable-Output Functions (May 2014)"
+ dsbyte byte
+ storage [maxRate]byte
+
+ // Specific to SHA-3 and SHAKE.
+ fixedOutput bool // whether this is a fixed-ouput-length instance
+ outputLen int // the default output size in bytes
+ state spongeDirection // whether the sponge is absorbing or squeezing
}
-// rate returns the number of bytes of the internal state which can be absorbed or squeezed
-// in between calls to the permutation function.
-func (d *digest) rate() int {
- return stateSize - d.capacity
-}
+// BlockSize returns the rate of sponge underlying this hash function.
+func (d *state) BlockSize() int { return d.rate }
+
+// Size returns the output size of the hash function in bytes.
+func (d *state) Size() int { return d.outputLen }
-// Reset clears the internal state by zeroing bytes in the state buffer.
-// This can be skipped for a newly-created hash state; the default zero-allocated state is correct.
-func (d *digest) Reset() {
- d.absorbed = 0
+// Reset clears the internal state by zeroing the sponge state and
+// the byte buffer, and setting Sponge.state to absorbing.
+func (d *state) Reset() {
+ // Zero the permutation's state.
for i := range d.a {
d.a[i] = 0
}
+ d.state = spongeAbsorbing
+ d.buf = d.storage[:0]
}
-// BlockSize, required by the hash.Hash interface, does not have a standard intepretation
-// for a sponge-based construction like SHA3. We return the data rate: the number of bytes which
-// can be absorbed per invocation of the permutation function. For Merkle-Damgård based hashes
-// (ie SHA1, SHA2, MD5) the output size of the internal compression function is returned.
-// We consider this to be roughly equivalent because it represents the number of bytes of output
-// produced per cryptographic operation.
-func (d *digest) BlockSize() int { return d.rate() }
+func (d *state) clone() *state {
+ ret := *d
+ if ret.state == spongeAbsorbing {
+ ret.buf = ret.storage[:len(ret.buf)]
+ } else {
+ ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate]
+ }
-// Size returns the output size of the hash function in bytes.
-func (d *digest) Size() int {
- return d.outputSize
+ return &ret
}
-// unalignedAbsorb is a helper function for Write, which absorbs data that isn't aligned with an
-// 8-byte lane. This requires shifting the individual bytes into position in a uint64.
-func (d *digest) unalignedAbsorb(p []byte) {
- var t uint64
- for i := len(p) - 1; i >= 0; i-- {
- t <<= 8
- t |= uint64(p[i])
+// permute applies the KeccakF-1600 permutation. It handles
+// any input-output buffering.
+func (d *state) permute() {
+ switch d.state {
+ case spongeAbsorbing:
+ // If we're absorbing, we need to xor the input into the state
+ // before applying the permutation.
+ xorIn(d, d.buf)
+ d.buf = d.storage[:0]
+ keccakF1600(&d.a)
+ case spongeSqueezing:
+ // If we're squeezing, we need to apply the permutatin before
+ // copying more output.
+ keccakF1600(&d.a)
+ d.buf = d.storage[:d.rate]
+ copyOut(d, d.buf)
}
- offset := (d.absorbed) % d.rate()
- t <<= 8 * uint(offset%laneSize)
- d.a[offset/laneSize] ^= t
- d.absorbed += len(p)
}
-// Write "absorbs" bytes into the state of the SHA3 hash, updating as needed when the sponge
-// "fills up" with rate() bytes. Since lanes are stored internally as type uint64, this requires
-// converting the incoming bytes into uint64s using a little endian interpretation. This
-// implementation is optimized for large, aligned writes of multiples of 8 bytes (laneSize).
-// Non-aligned or uneven numbers of bytes require shifting and are slower.
-func (d *digest) Write(p []byte) (int, error) {
- // An initial offset is needed if the we aren't absorbing to the first lane initially.
- offset := d.absorbed % d.rate()
- toWrite := len(p)
-
- // The first lane may need to absorb unaligned and/or incomplete data.
- if (offset%laneSize != 0 || len(p) < 8) && len(p) > 0 {
- toAbsorb := minInt(laneSize-(offset%laneSize), len(p))
- d.unalignedAbsorb(p[:toAbsorb])
- p = p[toAbsorb:]
- offset = (d.absorbed) % d.rate()
-
- // For every rate() bytes absorbed, the state must be permuted via the F Function.
- if (d.absorbed)%d.rate() == 0 {
- keccakF1600(&d.a)
- }
+// pads appends the domain separation bits in dsbyte, applies
+// the multi-bitrate 10..1 padding rule, and permutes the state.
+func (d *state) padAndPermute(dsbyte byte) {
+ if d.buf == nil {
+ d.buf = d.storage[:0]
}
+ // Pad with this instance's domain-separator bits. We know that there's
+ // at least one byte of space in d.buf because, if it were full,
+ // permute would have been called to empty it. dsbyte also contains the
+ // first one bit for the padding. See the comment in the state struct.
+ d.buf = append(d.buf, dsbyte)
+ zerosStart := len(d.buf)
+ d.buf = d.storage[:d.rate]
+ for i := zerosStart; i < d.rate; i++ {
+ d.buf[i] = 0
+ }
+ // This adds the final one bit for the padding. Because of the way that
+ // bits are numbered from the LSB upwards, the final bit is the MSB of
+ // the last byte.
+ d.buf[d.rate-1] ^= 0x80
+ // Apply the permutation
+ d.permute()
+ d.state = spongeSqueezing
+ d.buf = d.storage[:d.rate]
+ copyOut(d, d.buf)
+}
- // This loop should absorb the bulk of the data into full, aligned lanes.
- // It will call the update function as necessary.
- for len(p) > 7 {
- firstLane := offset / laneSize
- lastLane := minInt(d.rate()/laneSize, firstLane+len(p)/laneSize)
+// Write absorbs more data into the hash's state. It produces an error
+// if more data is written to the ShakeHash after writing
+func (d *state) Write(p []byte) (written int, err error) {
+ if d.state != spongeAbsorbing {
+ panic("sha3: write to sponge after read")
+ }
+ if d.buf == nil {
+ d.buf = d.storage[:0]
+ }
+ written = len(p)
- // This inner loop absorbs input bytes into the state in groups of 8, converted to uint64s.
- for lane := firstLane; lane < lastLane; lane++ {
- d.a[lane] ^= binary.LittleEndian.Uint64(p[:laneSize])
- p = p[laneSize:]
- }
- d.absorbed += (lastLane - firstLane) * laneSize
- // For every rate() bytes absorbed, the state must be permuted via the F Function.
- if (d.absorbed)%d.rate() == 0 {
+ for len(p) > 0 {
+ if len(d.buf) == 0 && len(p) >= d.rate {
+ // The fast path; absorb a full "rate" bytes of input and apply the permutation.
+ xorIn(d, p[:d.rate])
+ p = p[d.rate:]
keccakF1600(&d.a)
+ } else {
+ // The slow path; buffer the input until we can fill the sponge, and then xor it in.
+ todo := d.rate - len(d.buf)
+ if todo > len(p) {
+ todo = len(p)
+ }
+ d.buf = append(d.buf, p[:todo]...)
+ p = p[todo:]
+
+ // If the sponge is full, apply the permutation.
+ if len(d.buf) == d.rate {
+ d.permute()
+ }
}
-
- offset = 0
- }
-
- // If there are insufficient bytes to fill the final lane, an unaligned absorption.
- // This should always start at a correct lane boundary though, or else it would be caught
- // by the uneven opening lane case above.
- if len(p) > 0 {
- d.unalignedAbsorb(p)
}
- return toWrite, nil
-}
-
-// pad computes the SHA3 padding scheme based on the number of bytes absorbed.
-// The padding is a 1 bit, followed by an arbitrary number of 0s and then a final 1 bit, such that
-// the input bits plus padding bits are a multiple of rate(). Adding the padding simply requires
-// xoring an opening and closing bit into the appropriate lanes.
-func (d *digest) pad() {
- offset := d.absorbed % d.rate()
- // The opening pad bit must be shifted into position based on the number of bytes absorbed
- padOpenLane := offset / laneSize
- d.a[padOpenLane] ^= 0x0000000000000001 << uint(8*(offset%laneSize))
- // The closing padding bit is always in the last position
- padCloseLane := (d.rate() / laneSize) - 1
- d.a[padCloseLane] ^= 0x8000000000000000
+ return
}
-// finalize prepares the hash to output data by padding and one final permutation of the state.
-func (d *digest) finalize() {
- d.pad()
- keccakF1600(&d.a)
-}
-
-// squeeze outputs an arbitrary number of bytes from the hash state.
-// Squeezing can require multiple calls to the F function (one per rate() bytes squeezed),
-// although this is not the case for standard SHA3 parameters. This implementation only supports
-// squeezing a single time, subsequent squeezes may lose alignment. Future implementations
-// may wish to support multiple squeeze calls, for example to support use as a PRNG.
-func (d *digest) squeeze(in []byte, toSqueeze int) []byte {
- // Because we read in blocks of laneSize, we need enough room to read
- // an integral number of lanes
- needed := toSqueeze + (laneSize-toSqueeze%laneSize)%laneSize
- if cap(in)-len(in) < needed {
- newIn := make([]byte, len(in), len(in)+needed)
- copy(newIn, in)
- in = newIn
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (d *state) Read(out []byte) (n int, err error) {
+ // If we're still absorbing, pad and apply the permutation.
+ if d.state == spongeAbsorbing {
+ d.padAndPermute(d.dsbyte)
}
- out := in[len(in) : len(in)+needed]
+ n = len(out)
+
+ // Now, do the squeezing.
for len(out) > 0 {
- for i := 0; i < d.rate() && len(out) > 0; i += laneSize {
- binary.LittleEndian.PutUint64(out[:], d.a[i/laneSize])
- out = out[laneSize:]
- }
- if len(out) > 0 {
- keccakF1600(&d.a)
+ n := copy(out, d.buf)
+ d.buf = d.buf[n:]
+ out = out[n:]
+
+ // Apply the permutation if we've squeezed the sponge dry.
+ if len(d.buf) == 0 {
+ d.permute()
}
}
- return in[:len(in)+toSqueeze] // Re-slice in case we wrote extra data.
-}
-// Sum applies padding to the hash state and then squeezes out the desired nubmer of output bytes.
-func (d *digest) Sum(in []byte) []byte {
- // Make a copy of the original hash so that caller can keep writing and summing.
- dup := *d
- dup.finalize()
- return dup.squeeze(in, dup.outputSize)
+ return
}
-// The NewKeccakX constructors enable initializing a hash in any of the four recommend sizes
-// from the Keccak specification, all of which set capacity=2*outputSize. Note that the final
-// NIST standard for SHA3 may specify different input/output lengths.
-// The output size is indicated in bits but converted into bytes internally.
-func NewKeccak224() hash.Hash { return &digest{outputSize: 224 / 8, capacity: 2 * 224 / 8} }
-func NewKeccak256() hash.Hash { return &digest{outputSize: 256 / 8, capacity: 2 * 256 / 8} }
-func NewKeccak384() hash.Hash { return &digest{outputSize: 384 / 8, capacity: 2 * 384 / 8} }
-func NewKeccak512() hash.Hash { return &digest{outputSize: 512 / 8, capacity: 2 * 512 / 8} }
+// Sum applies padding to the hash state and then squeezes out the desired
+// number of output bytes.
+func (d *state) Sum(in []byte) []byte {
+ // Make a copy of the original hash so that caller can keep writing
+ // and summing.
+ dup := d.clone()
+ hash := make([]byte, dup.outputLen)
+ dup.Read(hash)
+ return append(in, hash...)
+}
diff --git a/crypto/sha3/sha3_test.go b/crypto/sha3/sha3_test.go
new file mode 100644
index 000000000..caf72f279
--- /dev/null
+++ b/crypto/sha3/sha3_test.go
@@ -0,0 +1,306 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// Tests include all the ShortMsgKATs provided by the Keccak team at
+// https://github.com/gvanas/KeccakCodePackage
+//
+// They only include the zero-bit case of the bitwise testvectors
+// published by NIST in the draft of FIPS-202.
+
+import (
+ "bytes"
+ "compress/flate"
+ "encoding/hex"
+ "encoding/json"
+ "hash"
+ "os"
+ "strings"
+ "testing"
+)
+
+const (
+ testString = "brekeccakkeccak koax koax"
+ katFilename = "testdata/keccakKats.json.deflate"
+)
+
+// Internal-use instances of SHAKE used to test against KATs.
+func newHashShake128() hash.Hash {
+ return &state{rate: 168, dsbyte: 0x1f, outputLen: 512}
+}
+func newHashShake256() hash.Hash {
+ return &state{rate: 136, dsbyte: 0x1f, outputLen: 512}
+}
+
+// testDigests contains functions returning hash.Hash instances
+// with output-length equal to the KAT length for both SHA-3 and
+// SHAKE instances.
+var testDigests = map[string]func() hash.Hash{
+ "SHA3-224": New224,
+ "SHA3-256": New256,
+ "SHA3-384": New384,
+ "SHA3-512": New512,
+ "SHAKE128": newHashShake128,
+ "SHAKE256": newHashShake256,
+}
+
+// testShakes contains functions that return ShakeHash instances for
+// testing the ShakeHash-specific interface.
+var testShakes = map[string]func() ShakeHash{
+ "SHAKE128": NewShake128,
+ "SHAKE256": NewShake256,
+}
+
+// decodeHex converts a hex-encoded string into a raw byte string.
+func decodeHex(s string) []byte {
+ b, err := hex.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+// structs used to marshal JSON test-cases.
+type KeccakKats struct {
+ Kats map[string][]struct {
+ Digest string `json:"digest"`
+ Length int64 `json:"length"`
+ Message string `json:"message"`
+ }
+}
+
+func testUnalignedAndGeneric(t *testing.T, testf func(impl string)) {
+ xorInOrig, copyOutOrig := xorIn, copyOut
+ xorIn, copyOut = xorInGeneric, copyOutGeneric
+ testf("generic")
+ if xorImplementationUnaligned != "generic" {
+ xorIn, copyOut = xorInUnaligned, copyOutUnaligned
+ testf("unaligned")
+ }
+ xorIn, copyOut = xorInOrig, copyOutOrig
+}
+
+// TestKeccakKats tests the SHA-3 and Shake implementations against all the
+// ShortMsgKATs from https://github.com/gvanas/KeccakCodePackage
+// (The testvectors are stored in keccakKats.json.deflate due to their length.)
+func TestKeccakKats(t *testing.T) {
+ testUnalignedAndGeneric(t, func(impl string) {
+ // Read the KATs.
+ deflated, err := os.Open(katFilename)
+ if err != nil {
+ t.Errorf("error opening %s: %s", katFilename, err)
+ }
+ file := flate.NewReader(deflated)
+ dec := json.NewDecoder(file)
+ var katSet KeccakKats
+ err = dec.Decode(&katSet)
+ if err != nil {
+ t.Errorf("error decoding KATs: %s", err)
+ }
+
+ // Do the KATs.
+ for functionName, kats := range katSet.Kats {
+ d := testDigests[functionName]()
+ for _, kat := range kats {
+ d.Reset()
+ in, err := hex.DecodeString(kat.Message)
+ if err != nil {
+ t.Errorf("error decoding KAT: %s", err)
+ }
+ d.Write(in[:kat.Length/8])
+ got := strings.ToUpper(hex.EncodeToString(d.Sum(nil)))
+ if got != kat.Digest {
+ t.Errorf("function=%s, implementation=%s, length=%d\nmessage:\n %s\ngot:\n %s\nwanted:\n %s",
+ functionName, impl, kat.Length, kat.Message, got, kat.Digest)
+ t.Logf("wanted %+v", kat)
+ t.FailNow()
+ }
+ continue
+ }
+ }
+ })
+}
+
+// TestUnalignedWrite tests that writing data in an arbitrary pattern with
+// small input buffers.
+func testUnalignedWrite(t *testing.T) {
+ testUnalignedAndGeneric(t, func(impl string) {
+ buf := sequentialBytes(0x10000)
+ for alg, df := range testDigests {
+ d := df()
+ d.Reset()
+ d.Write(buf)
+ want := d.Sum(nil)
+ d.Reset()
+ for i := 0; i < len(buf); {
+ // Cycle through offsets which make a 137 byte sequence.
+ // Because 137 is prime this sequence should exercise all corner cases.
+ offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1}
+ for _, j := range offsets {
+ if v := len(buf) - i; v < j {
+ j = v
+ }
+ d.Write(buf[i : i+j])
+ i += j
+ }
+ }
+ got := d.Sum(nil)
+ if !bytes.Equal(got, want) {
+ t.Errorf("Unaligned writes, implementation=%s, alg=%s\ngot %q, want %q", impl, alg, got, want)
+ }
+ }
+ })
+}
+
+// TestAppend checks that appending works when reallocation is necessary.
+func TestAppend(t *testing.T) {
+ testUnalignedAndGeneric(t, func(impl string) {
+ d := New224()
+
+ for capacity := 2; capacity <= 66; capacity += 64 {
+ // The first time around the loop, Sum will have to reallocate.
+ // The second time, it will not.
+ buf := make([]byte, 2, capacity)
+ d.Reset()
+ d.Write([]byte{0xcc})
+ buf = d.Sum(buf)
+ expected := "0000DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"
+ if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected {
+ t.Errorf("got %s, want %s", got, expected)
+ }
+ }
+ })
+}
+
+// TestAppendNoRealloc tests that appending works when no reallocation is necessary.
+func TestAppendNoRealloc(t *testing.T) {
+ testUnalignedAndGeneric(t, func(impl string) {
+ buf := make([]byte, 1, 200)
+ d := New224()
+ d.Write([]byte{0xcc})
+ buf = d.Sum(buf)
+ expected := "00DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"
+ if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected {
+ t.Errorf("%s: got %s, want %s", impl, got, expected)
+ }
+ })
+}
+
+// TestSqueezing checks that squeezing the full output a single time produces
+// the same output as repeatedly squeezing the instance.
+func TestSqueezing(t *testing.T) {
+ testUnalignedAndGeneric(t, func(impl string) {
+ for functionName, newShakeHash := range testShakes {
+ d0 := newShakeHash()
+ d0.Write([]byte(testString))
+ ref := make([]byte, 32)
+ d0.Read(ref)
+
+ d1 := newShakeHash()
+ d1.Write([]byte(testString))
+ var multiple []byte
+ for _ = range ref {
+ one := make([]byte, 1)
+ d1.Read(one)
+ multiple = append(multiple, one...)
+ }
+ if !bytes.Equal(ref, multiple) {
+ t.Errorf("%s (%s): squeezing %d bytes one at a time failed", functionName, impl, len(ref))
+ }
+ }
+ })
+}
+
+// sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing.
+func sequentialBytes(size int) []byte {
+ result := make([]byte, size)
+ for i := range result {
+ result[i] = byte(i)
+ }
+ return result
+}
+
+// BenchmarkPermutationFunction measures the speed of the permutation function
+// with no input data.
+func BenchmarkPermutationFunction(b *testing.B) {
+ b.SetBytes(int64(200))
+ var lanes [25]uint64
+ for i := 0; i < b.N; i++ {
+ keccakF1600(&lanes)
+ }
+}
+
+// benchmarkHash tests the speed to hash num buffers of buflen each.
+func benchmarkHash(b *testing.B, h hash.Hash, size, num int) {
+ b.StopTimer()
+ h.Reset()
+ data := sequentialBytes(size)
+ b.SetBytes(int64(size * num))
+ b.StartTimer()
+
+ var state []byte
+ for i := 0; i < b.N; i++ {
+ for j := 0; j < num; j++ {
+ h.Write(data)
+ }
+ state = h.Sum(state[:0])
+ }
+ b.StopTimer()
+ h.Reset()
+}
+
+// benchmarkShake is specialized to the Shake instances, which don't
+// require a copy on reading output.
+func benchmarkShake(b *testing.B, h ShakeHash, size, num int) {
+ b.StopTimer()
+ h.Reset()
+ data := sequentialBytes(size)
+ d := make([]byte, 32)
+
+ b.SetBytes(int64(size * num))
+ b.StartTimer()
+
+ for i := 0; i < b.N; i++ {
+ h.Reset()
+ for j := 0; j < num; j++ {
+ h.Write(data)
+ }
+ h.Read(d)
+ }
+}
+
+func BenchmarkSha3_512_MTU(b *testing.B) { benchmarkHash(b, New512(), 1350, 1) }
+func BenchmarkSha3_384_MTU(b *testing.B) { benchmarkHash(b, New384(), 1350, 1) }
+func BenchmarkSha3_256_MTU(b *testing.B) { benchmarkHash(b, New256(), 1350, 1) }
+func BenchmarkSha3_224_MTU(b *testing.B) { benchmarkHash(b, New224(), 1350, 1) }
+
+func BenchmarkShake128_MTU(b *testing.B) { benchmarkShake(b, NewShake128(), 1350, 1) }
+func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) }
+func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) }
+func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) }
+
+func BenchmarkSha3_512_1MiB(b *testing.B) { benchmarkHash(b, New512(), 1024, 1024) }
+
+func Example_sum() {
+ buf := []byte("some data to hash")
+ // A hash needs to be 64 bytes long to have 256-bit collision resistance.
+ h := make([]byte, 64)
+ // Compute a 64-byte hash of buf and put it in h.
+ ShakeSum256(h, buf)
+}
+
+func Example_mac() {
+ k := []byte("this is a secret key; you should generate a strong random key that's at least 32 bytes long")
+ buf := []byte("and this is some data to authenticate")
+ // A MAC with 32 bytes of output has 256-bit security strength -- if you use at least a 32-byte-long key.
+ h := make([]byte, 32)
+ d := NewShake256()
+ // Write the key into the hash.
+ d.Write(k)
+ // Now write the data.
+ d.Write(buf)
+ // Read 32 bytes of output from the hash into h.
+ d.Read(h)
+}
diff --git a/crypto/sha3/shake.go b/crypto/sha3/shake.go
new file mode 100644
index 000000000..841f9860f
--- /dev/null
+++ b/crypto/sha3/shake.go
@@ -0,0 +1,60 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file defines the ShakeHash interface, and provides
+// functions for creating SHAKE instances, as well as utility
+// functions for hashing bytes to arbitrary-length output.
+
+import (
+ "io"
+)
+
+// ShakeHash defines the interface to hash functions that
+// support arbitrary-length output.
+type ShakeHash interface {
+ // Write absorbs more data into the hash's state. It panics if input is
+ // written to it after output has been read from it.
+ io.Writer
+
+ // Read reads more output from the hash; reading affects the hash's
+ // state. (ShakeHash.Read is thus very different from Hash.Sum)
+ // It never returns an error.
+ io.Reader
+
+ // Clone returns a copy of the ShakeHash in its current state.
+ Clone() ShakeHash
+
+ // Reset resets the ShakeHash to its initial state.
+ Reset()
+}
+
+func (d *state) Clone() ShakeHash {
+ return d.clone()
+}
+
+// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 128 bits against all attacks if at
+// least 32 bytes of its output are used.
+func NewShake128() ShakeHash { return &state{rate: 168, dsbyte: 0x1f} }
+
+// NewShake256 creates a new SHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 256 bits against all attacks if
+// at least 64 bytes of its output are used.
+func NewShake256() ShakeHash { return &state{rate: 136, dsbyte: 0x1f} }
+
+// ShakeSum128 writes an arbitrary-length digest of data into hash.
+func ShakeSum128(hash, data []byte) {
+ h := NewShake128()
+ h.Write(data)
+ h.Read(hash)
+}
+
+// ShakeSum256 writes an arbitrary-length digest of data into hash.
+func ShakeSum256(hash, data []byte) {
+ h := NewShake256()
+ h.Write(data)
+ h.Read(hash)
+}
diff --git a/crypto/sha3/testdata/keccakKats.json.deflate b/crypto/sha3/testdata/keccakKats.json.deflate
new file mode 100644
index 000000000..62e85ae24
--- /dev/null
+++ b/crypto/sha3/testdata/keccakKats.json.deflate
Binary files differ
diff --git a/crypto/sha3/xor.go b/crypto/sha3/xor.go
new file mode 100644
index 000000000..d622979c1
--- /dev/null
+++ b/crypto/sha3/xor.go
@@ -0,0 +1,16 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !amd64,!386 appengine
+
+package sha3
+
+var (
+ xorIn = xorInGeneric
+ copyOut = copyOutGeneric
+ xorInUnaligned = xorInGeneric
+ copyOutUnaligned = copyOutGeneric
+)
+
+const xorImplementationUnaligned = "generic"
diff --git a/crypto/sha3/xor_generic.go b/crypto/sha3/xor_generic.go
new file mode 100644
index 000000000..fd35f02ef
--- /dev/null
+++ b/crypto/sha3/xor_generic.go
@@ -0,0 +1,28 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+import "encoding/binary"
+
+// xorInGeneric xors the bytes in buf into the state; it
+// makes no non-portable assumptions about memory layout
+// or alignment.
+func xorInGeneric(d *state, buf []byte) {
+ n := len(buf) / 8
+
+ for i := 0; i < n; i++ {
+ a := binary.LittleEndian.Uint64(buf)
+ d.a[i] ^= a
+ buf = buf[8:]
+ }
+}
+
+// copyOutGeneric copies ulint64s to a byte buffer.
+func copyOutGeneric(d *state, b []byte) {
+ for i := 0; len(b) >= 8; i++ {
+ binary.LittleEndian.PutUint64(b, d.a[i])
+ b = b[8:]
+ }
+}
diff --git a/crypto/sha3/xor_unaligned.go b/crypto/sha3/xor_unaligned.go
new file mode 100644
index 000000000..c7851a1d8
--- /dev/null
+++ b/crypto/sha3/xor_unaligned.go
@@ -0,0 +1,58 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64 386
+// +build !appengine
+
+package sha3
+
+import "unsafe"
+
+func xorInUnaligned(d *state, buf []byte) {
+ bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))
+ n := len(buf)
+ if n >= 72 {
+ d.a[0] ^= bw[0]
+ d.a[1] ^= bw[1]
+ d.a[2] ^= bw[2]
+ d.a[3] ^= bw[3]
+ d.a[4] ^= bw[4]
+ d.a[5] ^= bw[5]
+ d.a[6] ^= bw[6]
+ d.a[7] ^= bw[7]
+ d.a[8] ^= bw[8]
+ }
+ if n >= 104 {
+ d.a[9] ^= bw[9]
+ d.a[10] ^= bw[10]
+ d.a[11] ^= bw[11]
+ d.a[12] ^= bw[12]
+ }
+ if n >= 136 {
+ d.a[13] ^= bw[13]
+ d.a[14] ^= bw[14]
+ d.a[15] ^= bw[15]
+ d.a[16] ^= bw[16]
+ }
+ if n >= 144 {
+ d.a[17] ^= bw[17]
+ }
+ if n >= 168 {
+ d.a[18] ^= bw[18]
+ d.a[19] ^= bw[19]
+ d.a[20] ^= bw[20]
+ }
+}
+
+func copyOutUnaligned(d *state, buf []byte) {
+ ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
+ copy(buf, ab[:])
+}
+
+var (
+ xorIn = xorInUnaligned
+ copyOut = copyOutUnaligned
+)
+
+const xorImplementationUnaligned = "unaligned"
diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go
index 993190c38..ff57fe167 100644
--- a/eth/downloader/downloader_test.go
+++ b/eth/downloader/downloader_test.go
@@ -43,6 +43,11 @@ var (
genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000))
)
+// Reduce the block cache limit, otherwise the tests will be very heavy.
+func init() {
+ blockCacheLimit = 1024
+}
+
// makeChain creates a chain of n blocks starting at and including parent.
// the returned hash chain is ordered head->parent. In addition, every 3rd block
// contains a transaction and every 5th an uncle to allow testing correct block
diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go
index 9d0f2914d..bc9428ecf 100644
--- a/eth/downloader/queue.go
+++ b/eth/downloader/queue.go
@@ -39,7 +39,7 @@ import (
)
var (
- blockCacheLimit = 1024 // Maximum number of blocks to cache before throttling the download
+ blockCacheLimit = 8192 // Maximum number of blocks to cache before throttling the download
maxInFlightStates = 4096 // Maximum number of state downloads to allow concurrently
)
@@ -977,7 +977,7 @@ func (q *queue) DeliverNodeData(id string, data [][]byte, callback func(error, i
process := []trie.SyncResult{}
for _, blob := range data {
// Skip any state trie entires that were not requested
- hash := common.BytesToHash(crypto.Sha3(blob))
+ hash := common.BytesToHash(crypto.Keccak256(blob))
if _, ok := request.Hashes[hash]; !ok {
errs = append(errs, fmt.Errorf("non-requested state data %x", hash))
continue
diff --git a/eth/handler_test.go b/eth/handler_test.go
index 148d56cc6..e5974c23c 100644
--- a/eth/handler_test.go
+++ b/eth/handler_test.go
@@ -481,7 +481,7 @@ func testGetNodeData(t *testing.T, protocol int) {
}
// Verify that all hashes correspond to the requested data, and reconstruct a state tree
for i, want := range hashes {
- if hash := crypto.Sha3Hash(data[i]); hash != want {
+ if hash := crypto.Keccak256Hash(data[i]); hash != want {
fmt.Errorf("data hash mismatch: have %x, want %x", hash, want)
}
}
diff --git a/ethdb/README.md b/ethdb/README.md
deleted file mode 100644
index 5bed8eedc..000000000
--- a/ethdb/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# ethdb
-
-The ethdb package contains the ethereum database interfaces
-
-# Installation
-
-`go get github.com/ethereum/ethdb-go`
-
-# Usage
-
-Todo :-)
diff --git a/generators/defaults.go b/generators/defaults.go
index 386c6743d..aec4fe845 100644
--- a/generators/defaults.go
+++ b/generators/defaults.go
@@ -52,7 +52,7 @@ func main() {
json.Unmarshal(content, &m)
filepath := filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "params", os.Args[2])
- output, err := os.OpenFile(filepath, os.O_RDWR|os.O_CREATE, os.ModePerm /*0777*/)
+ output, err := os.OpenFile(filepath, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
fatal("error opening file for writing %v\n", err)
}
diff --git a/light/odr.go b/light/odr.go
index 5ed4f2325..4c69040ef 100644
--- a/light/odr.go
+++ b/light/odr.go
@@ -53,7 +53,7 @@ func (req *TrieRequest) StoreResult(db ethdb.Database) {
// storeProof stores the new trie nodes obtained from a merkle proof in the database
func storeProof(db ethdb.Database, proof []rlp.RawValue) {
for _, buf := range proof {
- hash := crypto.Sha3(buf)
+ hash := crypto.Keccak256(buf)
val, _ := db.Get(hash)
if val == nil {
db.Put(hash, buf)
@@ -78,7 +78,7 @@ func (req *NodeDataRequest) StoreResult(db ethdb.Database) {
db.Put(req.hash[:], req.GetData())
}
-var sha3_nil = crypto.Sha3Hash(nil)
+var sha3_nil = crypto.Keccak256Hash(nil)
// retrieveNodeData tries to retrieve node data with the given hash from the network
func retrieveNodeData(ctx context.Context, odr OdrBackend, hash common.Hash) ([]byte, error) {
diff --git a/light/state_object.go b/light/state_object.go
index d67fd7e40..fbb37400c 100644
--- a/light/state_object.go
+++ b/light/state_object.go
@@ -29,7 +29,7 @@ import (
"golang.org/x/net/context"
)
-var emptyCodeHash = crypto.Sha3(nil)
+var emptyCodeHash = crypto.Keccak256(nil)
// Code represents a contract code in binary form
type Code []byte
@@ -220,7 +220,7 @@ func (self *StateObject) Code() []byte {
// SetCode sets the contract code
func (self *StateObject) SetCode(code []byte) {
self.code = code
- self.codeHash = crypto.Sha3(code)
+ self.codeHash = crypto.Keccak256(code)
self.dirty = true
}
diff --git a/node/api.go b/node/api.go
index 48cbd0150..8a2578410 100644
--- a/node/api.go
+++ b/node/api.go
@@ -269,5 +269,5 @@ func (s *PublicWeb3API) ClientVersion() string {
// Sha3 applies the ethereum sha3 implementation on the input.
// It assumes the input is hex encoded.
func (s *PublicWeb3API) Sha3(input string) string {
- return common.ToHex(crypto.Sha3(common.FromHex(input)))
+ return common.ToHex(crypto.Keccak256(common.FromHex(input)))
}
diff --git a/p2p/discover/database.go b/p2p/discover/database.go
index e8e3371ff..6d448515d 100644
--- a/p2p/discover/database.go
+++ b/p2p/discover/database.go
@@ -188,7 +188,7 @@ func (db *nodeDB) node(id NodeID) *Node {
glog.V(logger.Warn).Infof("failed to decode node RLP: %v", err)
return nil
}
- node.sha = crypto.Sha3Hash(node.ID[:])
+ node.sha = crypto.Keccak256Hash(node.ID[:])
return node
}
diff --git a/p2p/discover/node.go b/p2p/discover/node.go
index c4a3b5011..139a95d80 100644
--- a/p2p/discover/node.go
+++ b/p2p/discover/node.go
@@ -67,7 +67,7 @@ func NewNode(id NodeID, ip net.IP, udpPort, tcpPort uint16) *Node {
UDP: udpPort,
TCP: tcpPort,
ID: id,
- sha: crypto.Sha3Hash(id[:]),
+ sha: crypto.Keccak256Hash(id[:]),
}
}
diff --git a/p2p/discover/ntp.go b/p2p/discover/ntp.go
new file mode 100644
index 000000000..c1a4b3af1
--- /dev/null
+++ b/p2p/discover/ntp.go
@@ -0,0 +1,127 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+// Contains the NTP time drift detection via the SNTP protocol:
+// https://tools.ietf.org/html/rfc4330
+
+package discover
+
+import (
+ "fmt"
+ "net"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/logger/glog"
+)
+
+const (
+ ntpPool = "pool.ntp.org" // ntpPool is the NTP server to query for the current time
+ ntpChecks = 3 // Number of measurements to do against the NTP server
+)
+
+// durationSlice attaches the methods of sort.Interface to []time.Duration,
+// sorting in increasing order.
+type durationSlice []time.Duration
+
+func (s durationSlice) Len() int { return len(s) }
+func (s durationSlice) Less(i, j int) bool { return s[i] < s[j] }
+func (s durationSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// checkClockDrift queries an NTP server for clock drifts and warns the user if
+// one large enough is detected.
+func checkClockDrift() {
+ drift, err := sntpDrift(ntpChecks)
+ if err != nil {
+ return
+ }
+ if drift < -driftThreshold || drift > driftThreshold {
+ warning := fmt.Sprintf("System clock seems off by %v, which can prevent network connectivity", drift)
+ howtofix := fmt.Sprintf("Please enable network time synchronisation in system settings")
+ separator := strings.Repeat("-", len(warning))
+
+ glog.V(logger.Warn).Info(separator)
+ glog.V(logger.Warn).Info(warning)
+ glog.V(logger.Warn).Info(howtofix)
+ glog.V(logger.Warn).Info(separator)
+ } else {
+ glog.V(logger.Debug).Infof("Sanity NTP check reported %v drift, all ok", drift)
+ }
+}
+
+// sntpDrift does a naive time resolution against an NTP server and returns the
+// measured drift. This method uses the simple version of NTP. It's not precise
+// but should be fine for these purposes.
+//
+// Note, it executes two extra measurements compared to the number of requested
+// ones to be able to discard the two extremes as outliers.
+func sntpDrift(measurements int) (time.Duration, error) {
+ // Resolve the address of the NTP server
+ addr, err := net.ResolveUDPAddr("udp", ntpPool+":123")
+ if err != nil {
+ return 0, err
+ }
+ // Construct the time request (empty package with only 2 fields set):
+ // Bits 3-5: Protocol version, 3
+ // Bits 6-8: Mode of operation, client, 3
+ request := make([]byte, 48)
+ request[0] = 3<<3 | 3
+
+ // Execute each of the measurements
+ drifts := []time.Duration{}
+ for i := 0; i < measurements+2; i++ {
+ // Dial the NTP server and send the time retrieval request
+ conn, err := net.DialUDP("udp", nil, addr)
+ if err != nil {
+ return 0, err
+ }
+ defer conn.Close()
+
+ sent := time.Now()
+ if _, err = conn.Write(request); err != nil {
+ return 0, err
+ }
+ // Retrieve the reply and calculate the elapsed time
+ conn.SetDeadline(time.Now().Add(5 * time.Second))
+
+ reply := make([]byte, 48)
+ if _, err = conn.Read(reply); err != nil {
+ return 0, err
+ }
+ elapsed := time.Since(sent)
+
+ // Reconstruct the time from the reply data
+ sec := uint64(reply[43]) | uint64(reply[42])<<8 | uint64(reply[41])<<16 | uint64(reply[40])<<24
+ frac := uint64(reply[47]) | uint64(reply[46])<<8 | uint64(reply[45])<<16 | uint64(reply[44])<<24
+
+ nanosec := sec*1e9 + (frac*1e9)>>32
+
+ t := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(nanosec)).Local()
+
+ // Calculate the drift based on an assumed answer time of RRT/2
+ drifts = append(drifts, sent.Sub(t)+elapsed/2)
+ }
+ // Calculate average drif (drop two extremities to avoid outliers)
+ sort.Sort(durationSlice(drifts))
+
+ drift := time.Duration(0)
+ for i := 1; i < len(drifts)-1; i++ {
+ drift += drifts[i]
+ }
+ return drift / time.Duration(measurements), nil
+}
diff --git a/p2p/discover/table.go b/p2p/discover/table.go
index abb7980f8..1de045f04 100644
--- a/p2p/discover/table.go
+++ b/p2p/discover/table.go
@@ -195,7 +195,7 @@ func (tab *Table) SetFallbackNodes(nodes []*Node) error {
cpy := *n
// Recompute cpy.sha because the node might not have been
// created by NewNode or ParseNode.
- cpy.sha = crypto.Sha3Hash(n.ID[:])
+ cpy.sha = crypto.Keccak256Hash(n.ID[:])
tab.nursery = append(tab.nursery, &cpy)
}
tab.mutex.Unlock()
@@ -208,7 +208,7 @@ func (tab *Table) SetFallbackNodes(nodes []*Node) error {
func (tab *Table) Resolve(targetID NodeID) *Node {
// If the node is present in the local table, no
// network interaction is required.
- hash := crypto.Sha3Hash(targetID[:])
+ hash := crypto.Keccak256Hash(targetID[:])
tab.mutex.Lock()
cl := tab.closest(hash, 1)
tab.mutex.Unlock()
@@ -236,7 +236,7 @@ func (tab *Table) Lookup(targetID NodeID) []*Node {
func (tab *Table) lookup(targetID NodeID, refreshIfEmpty bool) []*Node {
var (
- target = crypto.Sha3Hash(targetID[:])
+ target = crypto.Keccak256Hash(targetID[:])
asked = make(map[NodeID]bool)
seen = make(map[NodeID]bool)
reply = make(chan []*Node, alpha)
diff --git a/p2p/discover/table_test.go b/p2p/discover/table_test.go
index 30a418f44..1a2405740 100644
--- a/p2p/discover/table_test.go
+++ b/p2p/discover/table_test.go
@@ -530,12 +530,12 @@ func (*preminedTestnet) ping(toid NodeID, toaddr *net.UDPAddr) error { return ni
// various distances to the given target.
func (n *preminedTestnet) mine(target NodeID) {
n.target = target
- n.targetSha = crypto.Sha3Hash(n.target[:])
+ n.targetSha = crypto.Keccak256Hash(n.target[:])
found := 0
for found < bucketSize*10 {
k := newkey()
id := PubkeyID(&k.PublicKey)
- sha := crypto.Sha3Hash(id[:])
+ sha := crypto.Keccak256Hash(id[:])
ld := logdist(n.targetSha, sha)
if len(n.dists[ld]) < bucketSize {
n.dists[ld] = append(n.dists[ld], id)
diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go
index 81674f552..74758b6fd 100644
--- a/p2p/discover/udp.go
+++ b/p2p/discover/udp.go
@@ -51,6 +51,10 @@ const (
respTimeout = 500 * time.Millisecond
sendTimeout = 500 * time.Millisecond
expiration = 20 * time.Second
+
+ ntpFailureThreshold = 32 // Continuous timeouts after which to check NTP
+ ntpWarningCooldown = 10 * time.Minute // Minimum amount of time to pass before repeating NTP warning
+ driftThreshold = 10 * time.Second // Allowed clock drift before warning user
)
// RPC packet types
@@ -316,13 +320,15 @@ func (t *udp) handleReply(from NodeID, ptype byte, req packet) bool {
}
}
-// loop runs in its own goroutin. it keeps track of
+// loop runs in its own goroutine. it keeps track of
// the refresh timer and the pending reply queue.
func (t *udp) loop() {
var (
- plist = list.New()
- timeout = time.NewTimer(0)
- nextTimeout *pending // head of plist when timeout was last reset
+ plist = list.New()
+ timeout = time.NewTimer(0)
+ nextTimeout *pending // head of plist when timeout was last reset
+ contTimeouts = 0 // number of continuous timeouts to do NTP checks
+ ntpWarnTime = time.Unix(0, 0)
)
<-timeout.C // ignore first timeout
defer timeout.Stop()
@@ -377,19 +383,31 @@ func (t *udp) loop() {
p.errc <- nil
plist.Remove(el)
}
+ // Reset the continuous timeout counter (time drift detection)
+ contTimeouts = 0
}
}
r.matched <- matched
case now := <-timeout.C:
nextTimeout = nil
+
// Notify and remove callbacks whose deadline is in the past.
for el := plist.Front(); el != nil; el = el.Next() {
p := el.Value.(*pending)
if now.After(p.deadline) || now.Equal(p.deadline) {
p.errc <- errTimeout
plist.Remove(el)
+ contTimeouts++
+ }
+ }
+ // If we've accumulated too many timeouts, do an NTP time sync check
+ if contTimeouts > ntpFailureThreshold {
+ if time.Since(ntpWarnTime) >= ntpWarningCooldown {
+ ntpWarnTime = time.Now()
+ go checkClockDrift()
}
+ contTimeouts = 0
}
}
}
@@ -448,7 +466,7 @@ func encodePacket(priv *ecdsa.PrivateKey, ptype byte, req interface{}) ([]byte,
return nil, err
}
packet := b.Bytes()
- sig, err := crypto.Sign(crypto.Sha3(packet[headSize:]), priv)
+ sig, err := crypto.Sign(crypto.Keccak256(packet[headSize:]), priv)
if err != nil {
glog.V(logger.Error).Infoln("could not sign packet:", err)
return nil, err
@@ -457,7 +475,7 @@ func encodePacket(priv *ecdsa.PrivateKey, ptype byte, req interface{}) ([]byte,
// add the hash to the front. Note: this doesn't protect the
// packet in any way. Our public key will be part of this hash in
// The future.
- copy(packet, crypto.Sha3(packet[macSize:]))
+ copy(packet, crypto.Keccak256(packet[macSize:]))
return packet, nil
}
@@ -509,11 +527,11 @@ func decodePacket(buf []byte) (packet, NodeID, []byte, error) {
return nil, NodeID{}, nil, errPacketTooSmall
}
hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
- shouldhash := crypto.Sha3(buf[macSize:])
+ shouldhash := crypto.Keccak256(buf[macSize:])
if !bytes.Equal(hash, shouldhash) {
return nil, NodeID{}, nil, errBadHash
}
- fromID, err := recoverNodeID(crypto.Sha3(buf[headSize:]), sig)
+ fromID, err := recoverNodeID(crypto.Keccak256(buf[headSize:]), sig)
if err != nil {
return nil, NodeID{}, hash, err
}
@@ -575,7 +593,7 @@ func (req *findnode) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte
// (which is a much bigger packet than findnode) to the victim.
return errUnknownNode
}
- target := crypto.Sha3Hash(req.Target[:])
+ target := crypto.Keccak256Hash(req.Target[:])
t.mutex.Lock()
closest := t.closest(target, bucketSize).entries
t.mutex.Unlock()
diff --git a/p2p/discover/udp_test.go b/p2p/discover/udp_test.go
index 66fc4cf2c..3939a69a7 100644
--- a/p2p/discover/udp_test.go
+++ b/p2p/discover/udp_test.go
@@ -286,7 +286,7 @@ func TestUDP_findnode(t *testing.T) {
// put a few nodes into the table. their exact
// distribution shouldn't matter much, altough we need to
// take care not to overflow any bucket.
- targetHash := crypto.Sha3Hash(testTarget[:])
+ targetHash := crypto.Keccak256Hash(testTarget[:])
nodes := &nodesByDistance{target: targetHash}
for i := 0; i < bucketSize; i++ {
nodes.push(nodeAtDistance(test.table.self.sha, i+2), bucketSize)
diff --git a/p2p/rlpx.go b/p2p/rlpx.go
index 9d6cba5b6..ddfafe9a4 100644
--- a/p2p/rlpx.go
+++ b/p2p/rlpx.go
@@ -232,12 +232,12 @@ func (h *encHandshake) secrets(auth, authResp []byte) (secrets, error) {
}
// derive base secrets from ephemeral key agreement
- sharedSecret := crypto.Sha3(ecdheSecret, crypto.Sha3(h.respNonce, h.initNonce))
- aesSecret := crypto.Sha3(ecdheSecret, sharedSecret)
+ sharedSecret := crypto.Keccak256(ecdheSecret, crypto.Keccak256(h.respNonce, h.initNonce))
+ aesSecret := crypto.Keccak256(ecdheSecret, sharedSecret)
s := secrets{
RemoteID: h.remoteID,
AES: aesSecret,
- MAC: crypto.Sha3(ecdheSecret, aesSecret),
+ MAC: crypto.Keccak256(ecdheSecret, aesSecret),
}
// setup sha3 instances for the MACs
@@ -426,7 +426,7 @@ func (h *encHandshake) makeAuthResp() (msg *authRespV4, err error) {
func (msg *authMsgV4) sealPlain(h *encHandshake) ([]byte, error) {
buf := make([]byte, authMsgLen)
n := copy(buf, msg.Signature[:])
- n += copy(buf[n:], crypto.Sha3(exportPubkey(&h.randomPrivKey.PublicKey)))
+ n += copy(buf[n:], crypto.Keccak256(exportPubkey(&h.randomPrivKey.PublicKey)))
n += copy(buf[n:], msg.InitiatorPubkey[:])
n += copy(buf[n:], msg.Nonce[:])
buf[n] = 0 // token-flag
diff --git a/p2p/rlpx_test.go b/p2p/rlpx_test.go
index f9583e224..f4cefa650 100644
--- a/p2p/rlpx_test.go
+++ b/p2p/rlpx_test.go
@@ -267,8 +267,8 @@ func TestRLPXFrameFake(t *testing.T) {
buf := new(bytes.Buffer)
hash := fakeHash([]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})
rw := newRLPXFrameRW(buf, secrets{
- AES: crypto.Sha3(),
- MAC: crypto.Sha3(),
+ AES: crypto.Keccak256(),
+ MAC: crypto.Keccak256(),
IngressMAC: hash,
EgressMAC: hash,
})
diff --git a/params/protocol_params.go b/params/protocol_params.go
index 71c7035a4..71c7035a4 100755..100644
--- a/params/protocol_params.go
+++ b/params/protocol_params.go
diff --git a/tests/util.go b/tests/util.go
index 8196d7fd6..29f4c9b72 100644
--- a/tests/util.go
+++ b/tests/util.go
@@ -183,7 +183,7 @@ func (self *Env) Db() vm.Database { return self.state }
func (self *Env) GasLimit() *big.Int { return self.gasLimit }
func (self *Env) VmType() vm.Type { return vm.StdVmTy }
func (self *Env) GetHash(n uint64) common.Hash {
- return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
+ return common.BytesToHash(crypto.Keccak256([]byte(big.NewInt(int64(n)).String())))
}
func (self *Env) AddLog(log *vm.Log) {
self.state.AddLog(log)
diff --git a/trie/secure_trie_test.go b/trie/secure_trie_test.go
index 13c6cd02e..0be5b3d15 100644
--- a/trie/secure_trie_test.go
+++ b/trie/secure_trie_test.go
@@ -63,7 +63,7 @@ func TestSecureGetKey(t *testing.T) {
key := []byte("foo")
value := []byte("bar")
- seckey := crypto.Sha3(key)
+ seckey := crypto.Keccak256(key)
if !bytes.Equal(trie.Get(key), value) {
t.Errorf("Get did not return bar")
diff --git a/trie/trie.go b/trie/trie.go
index 9dfde4529..cc5dcf2a6 100644
--- a/trie/trie.go
+++ b/trie/trie.go
@@ -40,7 +40,7 @@ var (
emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
// This is the known hash of an empty state trie entry.
- emptyState = crypto.Sha3Hash(nil)
+ emptyState = crypto.Keccak256Hash(nil)
)
// ClearGlobalCache clears the global trie cache
diff --git a/whisper/envelope.go b/whisper/envelope.go
index b231c6b44..97d489b96 100644
--- a/whisper/envelope.go
+++ b/whisper/envelope.go
@@ -66,7 +66,7 @@ func (self *Envelope) Seal(pow time.Duration) {
for i := 0; i < 1024; i++ {
binary.BigEndian.PutUint32(d[60:], nonce)
- firstBit := common.FirstBitSet(common.BigD(crypto.Sha3(d)))
+ firstBit := common.FirstBitSet(common.BigD(crypto.Keccak256(d)))
if firstBit > bestBit {
self.Nonce, bestBit = nonce, firstBit
}
@@ -123,7 +123,7 @@ func (self *Envelope) Open(key *ecdsa.PrivateKey) (msg *Message, err error) {
func (self *Envelope) Hash() common.Hash {
if (self.hash == common.Hash{}) {
enc, _ := rlp.EncodeToBytes(self)
- self.hash = crypto.Sha3Hash(enc)
+ self.hash = crypto.Keccak256Hash(enc)
}
return self.hash
}
@@ -142,6 +142,6 @@ func (self *Envelope) DecodeRLP(s *rlp.Stream) error {
if err := rlp.DecodeBytes(raw, (*rlpenv)(self)); err != nil {
return err
}
- self.hash = crypto.Sha3Hash(raw)
+ self.hash = crypto.Keccak256Hash(raw)
return nil
}
diff --git a/whisper/message.go b/whisper/message.go
index 506f142ed..f05b5d8b5 100644
--- a/whisper/message.go
+++ b/whisper/message.go
@@ -146,7 +146,7 @@ func (self *Message) decrypt(key *ecdsa.PrivateKey) error {
// hash calculates the SHA3 checksum of the message flags and payload.
func (self *Message) hash() []byte {
- return crypto.Sha3(append([]byte{self.Flags}, self.Payload...))
+ return crypto.Keccak256(append([]byte{self.Flags}, self.Payload...))
}
// bytes flattens the message contents (flags, signature and payload) into a
diff --git a/whisper/topic.go b/whisper/topic.go
index 7ac3e8dc1..d37eb25ee 100644
--- a/whisper/topic.go
+++ b/whisper/topic.go
@@ -31,7 +31,7 @@ type Topic [4]byte
// Note, empty topics are considered the wildcard, and cannot be used in messages.
func NewTopic(data []byte) Topic {
prefix := [4]byte{}
- copy(prefix[:], crypto.Sha3(data)[:4])
+ copy(prefix[:], crypto.Keccak256(data)[:4])
return Topic(prefix)
}