示例#1
0
文件: rlpx.go 项目: 5mil/go-expanse
// secrets is called after the handshake is completed.
// It extracts the connection secrets from the handshake values.
func (h *encHandshake) secrets(auth, authResp []byte) (secrets, error) {
	ecdheSecret, err := h.randomPrivKey.GenerateShared(h.remoteRandomPub, sskLen, sskLen)
	if err != nil {
		return secrets{}, err
	}

	// derive base secrets from ephemeral key agreement
	sharedSecret := crypto.Sha3(ecdheSecret, crypto.Sha3(h.respNonce, h.initNonce))
	aesSecret := crypto.Sha3(ecdheSecret, sharedSecret)
	s := secrets{
		RemoteID: h.remoteID,
		AES:      aesSecret,
		MAC:      crypto.Sha3(ecdheSecret, aesSecret),
	}

	// setup sha3 instances for the MACs
	mac1 := sha3.NewKeccak256()
	mac1.Write(xor(s.MAC, h.respNonce))
	mac1.Write(auth)
	mac2 := sha3.NewKeccak256()
	mac2.Write(xor(s.MAC, h.initNonce))
	mac2.Write(authResp)
	if h.initiator {
		s.EgressMAC, s.IngressMAC = mac1, mac2
	} else {
		s.EgressMAC, s.IngressMAC = mac2, mac1
	}

	return s, nil
}
示例#2
0
文件: udp.go 项目: 5mil/go-expanse
func decodePacket(buf []byte) (packet, NodeID, []byte, error) {
	if len(buf) < headSize+1 {
		return nil, NodeID{}, nil, errPacketTooSmall
	}
	hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:]
	shouldhash := crypto.Sha3(buf[macSize:])
	if !bytes.Equal(hash, shouldhash) {
		return nil, NodeID{}, nil, errBadHash
	}
	fromID, err := recoverNodeID(crypto.Sha3(buf[headSize:]), sig)
	if err != nil {
		return nil, NodeID{}, hash, err
	}
	var req packet
	switch ptype := sigdata[0]; ptype {
	case pingPacket:
		req = new(ping)
	case pongPacket:
		req = new(pong)
	case findnodePacket:
		req = new(findnode)
	case neighborsPacket:
		req = new(neighbors)
	default:
		return nil, fromID, hash, fmt.Errorf("unknown type: %d", ptype)
	}
	s := rlp.NewStream(bytes.NewReader(sigdata[1:]), 0)
	err = s.Decode(req)
	return req, fromID, hash, err
}
示例#3
0
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)
	return sha
}
示例#4
0
func ecrecoverFunc(in []byte) []byte {
	in = common.RightPadBytes(in, 128)
	// "in" is (hash, v, r, s), each 32 bytes
	// but for ecrecover we want (r, s, v)

	r := common.BytesToBig(in[64:96])
	s := common.BytesToBig(in[96:128])
	// Treat V as a 256bit integer
	vbig := common.Bytes2Big(in[32:64])
	v := byte(vbig.Uint64())

	if !crypto.ValidateSignatureValues(v, r, s) {
		glog.V(logger.Debug).Infof("EC RECOVER FAIL: v, r or s value invalid")
		return nil
	}

	// v needs to be at the end and normalized for libsecp256k1
	vbignormal := new(big.Int).Sub(vbig, big.NewInt(27))
	vnormal := byte(vbignormal.Uint64())
	rsv := append(in[64:128], vnormal)
	pubKey, err := crypto.Ecrecover(in[:32], rsv)
	// make sure the public key is a valid one
	if err != nil {
		glog.V(logger.Error).Infof("EC RECOVER FAIL: ", err)
		return nil
	}

	// the first byte of pubkey is bitcoin heritage
	return common.LeftPadBytes(crypto.Sha3(pubKey[1:])[12:], 32)
}
示例#5
0
// sets defaults on the config
func setDefaults(cfg *Config) {
	if cfg.Difficulty == nil {
		cfg.Difficulty = new(big.Int)
	}
	if cfg.Time == nil {
		cfg.Time = big.NewInt(time.Now().Unix())
	}
	if cfg.GasLimit == nil {
		cfg.GasLimit = new(big.Int).Set(common.MaxBig)
	}
	if cfg.GasPrice == nil {
		cfg.GasPrice = new(big.Int)
	}
	if cfg.Value == nil {
		cfg.Value = new(big.Int)
	}
	if cfg.BlockNumber == nil {
		cfg.BlockNumber = new(big.Int)
	}
	if cfg.GetHashFn == nil {
		cfg.GetHashFn = func(n uint64) common.Hash {
			return common.BytesToHash(crypto.Sha3([]byte(new(big.Int).SetUint64(n).String())))
		}
	}
}
示例#6
0
// Tests that at any point in time during a sync, only complete sub-tries are in
// the database.
func TestIncompleteStateSync(t *testing.T) {
	// Create a random state to copy
	srcDb, srcRoot, srcAccounts := makeTestState()

	// Create a destination state and sync with the scheduler
	dstDb, _ := ethdb.NewMemDatabase()
	sched := NewStateSync(srcRoot, dstDb)

	added := []common.Hash{}
	queue := append([]common.Hash{}, sched.Missing(1)...)
	for len(queue) > 0 {
		// Fetch a batch of state nodes
		results := make([]trie.SyncResult, len(queue))
		for i, hash := range queue {
			data, err := srcDb.Get(hash.Bytes())
			if err != nil {
				t.Fatalf("failed to retrieve node data for %x: %v", hash, err)
			}
			results[i] = trie.SyncResult{Hash: hash, Data: data}
		}
		// Process each of the state nodes
		if index, err := sched.Process(results); err != nil {
			t.Fatalf("failed to process result #%d: %v", index, err)
		}
		for _, result := range results {
			added = append(added, result.Hash)
		}
		// Check that all known sub-tries in the synced state is complete
		for _, root := range added {
			// Skim through the accounts and make sure the root hash is not a code node
			codeHash := false
			for _, acc := range srcAccounts {
				if bytes.Compare(root.Bytes(), crypto.Sha3(acc.code)) == 0 {
					codeHash = true
					break
				}
			}
			// If the root is a real trie node, check consistency
			if !codeHash {
				if err := checkStateConsistency(dstDb, root); err != nil {
					t.Fatalf("state inconsistent: %v", err)
				}
			}
		}
		// Fetch the next batch to retrieve
		queue = append(queue[:0], sched.Missing(1)...)
	}
	// Sanity check that removing any node from the database is detected
	for _, node := range added[1:] {
		key := node.Bytes()
		value, _ := dstDb.Get(key)

		dstDb.Delete(key)
		if err := checkStateConsistency(dstDb, added[0]); err == nil {
			t.Fatalf("trie inconsistency not caught, missing: %x", key)
		}
		dstDb.Put(key, value)
	}
}
示例#7
0
// Calculates the sha3 over req.Params.Data
func (self *web3Api) Sha3(req *shared.Request) (interface{}, error) {
	args := new(Sha3Args)
	if err := self.codec.Decode(req.Params, &args); err != nil {
		return nil, err
	}

	return common.ToHex(crypto.Sha3(common.FromHex(args.Data))), nil
}
示例#8
0
func TestEmptyTrie(t *testing.T) {
	trie := NewEmpty()
	res := trie.Hash()
	exp := crypto.Sha3(common.Encode(""))
	if !bytes.Equal(res, exp) {
		t.Errorf("expected %x got %x", exp, res)
	}
}
示例#9
0
func SaveInfo(info *ContractInfo, filename string) (contenthash common.Hash, err error) {
	infojson, err := json.Marshal(info)
	if err != nil {
		return
	}
	contenthash = common.BytesToHash(crypto.Sha3(infojson))
	err = ioutil.WriteFile(filename, infojson, 0600)
	return
}
示例#10
0
文件: rlpx.go 项目: 5mil/go-expanse
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:], msg.InitiatorPubkey[:])
	n += copy(buf[n:], msg.Nonce[:])
	buf[n] = 0 // token-flag
	return ecies.Encrypt(rand.Reader, h.remotePub, buf, nil, nil)
}
示例#11
0
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(),
		IngressMAC: hash,
		EgressMAC:  hash,
	})

	golden := unhex(`
00828ddae471818bb0bfa6b551d1cb42
01010101010101010101010101010101
ba628a4ba590cb43f7848f41c4382885
01010101010101010101010101010101
`)

	// Check WriteMsg. This puts a message into the buffer.
	if err := Send(rw, 8, []uint{1, 2, 3, 4}); err != nil {
		t.Fatalf("WriteMsg error: %v", err)
	}
	written := buf.Bytes()
	if !bytes.Equal(written, golden) {
		t.Fatalf("output mismatch:\n  got:  %x\n  want: %x", written, golden)
	}

	// Check ReadMsg. It reads the message encoded by WriteMsg, which
	// is equivalent to the golden message above.
	msg, err := rw.ReadMsg()
	if err != nil {
		t.Fatalf("ReadMsg error: %v", err)
	}
	if msg.Size != 5 {
		t.Errorf("msg size mismatch: got %d, want %d", msg.Size, 5)
	}
	if msg.Code != 8 {
		t.Errorf("msg code mismatch: got %d, want %d", msg.Code, 8)
	}
	payload, _ := ioutil.ReadAll(msg.Payload)
	wantPayload := unhex("C401020304")
	if !bytes.Equal(payload, wantPayload) {
		t.Errorf("msg payload mismatch:\ngot  %x\nwant %x", payload, wantPayload)
	}
}
示例#12
0
// DeliverNodeData injects a node state data retrieval response into the queue.
// The method returns the number of node state entries originally requested, and
// the number of them actually accepted from the delivery.
func (q *queue) DeliverNodeData(id string, data [][]byte, callback func(error, int)) (int, error) {
	q.lock.Lock()
	defer q.lock.Unlock()

	// Short circuit if the data was never requested
	request := q.statePendPool[id]
	if request == nil {
		return 0, errNoFetchesPending
	}
	stateReqTimer.UpdateSince(request.Time)
	delete(q.statePendPool, id)

	// If no data was retrieved, mark their hashes as unavailable for the origin peer
	if len(data) == 0 {
		for hash, _ := range request.Hashes {
			request.Peer.MarkLacking(hash)
		}
	}
	// Iterate over the downloaded data and verify each of them
	accepted, errs := 0, make([]error, 0)
	process := []trie.SyncResult{}
	for _, blob := range data {
		// Skip any state trie entires that were not requested
		hash := common.BytesToHash(crypto.Sha3(blob))
		if _, ok := request.Hashes[hash]; !ok {
			errs = append(errs, fmt.Errorf("non-requested state data %x", hash))
			continue
		}
		// Inject the next state trie item into the processing queue
		process = append(process, trie.SyncResult{hash, blob})
		accepted++

		delete(request.Hashes, hash)
		delete(q.stateTaskPool, hash)
	}
	// Start the asynchronous node state data injection
	atomic.AddInt32(&q.stateProcessors, 1)
	go func() {
		defer atomic.AddInt32(&q.stateProcessors, -1)
		q.deliverNodeData(process, callback)
	}()
	// Return all failed or missing fetches to the queue
	for hash, index := range request.Hashes {
		q.stateTaskQueue.Push(hash, float32(index))
	}
	// If none of the data items were good, it's a stale delivery
	switch {
	case len(errs) == 0:
		return accepted, nil
	case len(errs) == len(request.Hashes):
		return accepted, errStaleDelivery
	default:
		return accepted, fmt.Errorf("multiple failures: %v", errs)
	}
}
示例#13
0
func (self *Trie) Hash() []byte {
	var hash []byte
	if self.root != nil {
		t := self.root.Hash()
		if byts, ok := t.([]byte); ok && len(byts) > 0 {
			hash = byts
		} else {
			hash = crypto.Sha3(common.Encode(self.root.RlpData()))
		}
	} else {
		hash = crypto.Sha3(common.Encode(""))
	}

	if !bytes.Equal(hash, self.roothash) {
		self.revisions.PushBack(self.roothash)
		self.roothash = hash
	}

	return hash
}
示例#14
0
文件: udp.go 项目: 5mil/go-expanse
func encodePacket(priv *ecdsa.PrivateKey, ptype byte, req interface{}) ([]byte, error) {
	b := new(bytes.Buffer)
	b.Write(headSpace)
	b.WriteByte(ptype)
	if err := rlp.Encode(b, req); err != nil {
		glog.V(logger.Error).Infoln("error encoding packet:", err)
		return nil, err
	}
	packet := b.Bytes()
	sig, err := crypto.Sign(crypto.Sha3(packet[headSize:]), priv)
	if err != nil {
		glog.V(logger.Error).Infoln("could not sign packet:", err)
		return nil, err
	}
	copy(packet[macSize:], sig)
	// 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:]))
	return packet, nil
}
示例#15
0
func bloom9(b []byte) *big.Int {
	b = crypto.Sha3(b[:])

	r := new(big.Int)

	for i := 0; i < 6; i += 2 {
		t := big.NewInt(1)
		b := (uint(b[i+1]) + (uint(b[i]) << 8)) & 2047
		r.Or(r, t.Lsh(t, b))
	}

	return r
}
示例#16
0
func doFrom(tx *Transaction, homestead bool) (common.Address, error) {
	if from := tx.from.Load(); from != nil {
		return from.(common.Address), nil
	}
	pubkey, err := tx.publicKey(homestead)
	if err != nil {
		return common.Address{}, err
	}
	var addr common.Address
	copy(addr[:], crypto.Sha3(pubkey[1:])[12:])
	tx.from.Store(addr)
	return addr, nil
}
示例#17
0
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))))
		var key [8]byte
		copy(key[:], hash[:8])
		if bytes.Equal(key[:], abiKey[:]) {
			meth = m
			meth.name = name
			return
		}
	}
	return
}
示例#18
0
func (self *Trie) store(node Node) interface{} {
	data := common.Encode(node)
	if len(data) >= 32 {
		key := crypto.Sha3(data)
		if node.Dirty() {
			//fmt.Println("save", node)
			//fmt.Println()
			self.cache.Put(key, data)
		}

		return key
	}

	return node.RlpData()
}
示例#19
0
func TestSecureGetKey(t *testing.T) {
	trie := newEmptySecure()
	trie.Update([]byte("foo"), []byte("bar"))

	key := []byte("foo")
	value := []byte("bar")
	seckey := crypto.Sha3(key)

	if !bytes.Equal(trie.Get(key), value) {
		t.Errorf("Get did not return bar")
	}
	if k := trie.GetKey(seckey); !bytes.Equal(k, key) {
		t.Errorf("GetKey returned %q, want %q", k, key)
	}
}
示例#20
0
// Seal closes the envelope by spending the requested amount of time as a proof
// of work on hashing the data.
func (self *Envelope) Seal(pow time.Duration) {
	d := make([]byte, 64)
	copy(d[:32], self.rlpWithoutNonce())

	finish, bestBit := time.Now().Add(pow).UnixNano(), 0
	for nonce := uint32(0); time.Now().UnixNano() < finish; {
		for i := 0; i < 1024; i++ {
			binary.BigEndian.PutUint32(d[60:], nonce)

			firstBit := common.FirstBitSet(common.BigD(crypto.Sha3(d)))
			if firstBit > bestBit {
				self.Nonce, bestBit = nonce, firstBit
			}
			nonce++
		}
	}
}
示例#21
0
func (self *adminApi) Register(req *shared.Request) (interface{}, error) {
	args := new(RegisterArgs)
	if err := self.coder.Decode(req.Params, &args); err != nil {
		return nil, shared.NewDecodeParamError(err.Error())
	}

	sender := common.HexToAddress(args.Sender)
	// sender and contract address are passed as hex strings
	codeb := self.xeth.CodeAtBytes(args.Address)
	codeHash := common.BytesToHash(crypto.Sha3(codeb))
	contentHash := common.HexToHash(args.ContentHashHex)
	registry := registrar.New(self.xeth)

	_, err := registry.SetHashToHash(sender, codeHash, contentHash)
	if err != nil {
		return false, err
	}

	return true, nil
}
示例#22
0
func TestMethodSignature(t *testing.T) {
	String, _ := NewType("string")
	String32, _ := NewType("string32")
	m := Method{"foo", false, []Argument{Argument{"bar", String32}, Argument{"baz", String}}, Type{}}
	exp := "foo(string32,string)"
	if m.String() != exp {
		t.Error("signature mismatch", exp, "!=", m.String())
	}

	idexp := crypto.Sha3([]byte(exp))[:4]
	if !bytes.Equal(m.Id(), idexp) {
		t.Errorf("expected ids to match %x != %x", m.Id(), idexp)
	}

	uintt, _ := NewType("uint")
	m = Method{"foo", false, []Argument{Argument{"bar", uintt}}, Type{}}
	exp = "foo(uint256)"
	if m.String() != exp {
		t.Error("signature mismatch", exp, "!=", m.String())
	}
}
示例#23
0
func TestPack(t *testing.T) {
	abi, err := JSON(strings.NewReader(jsondata2))
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	sig := crypto.Sha3([]byte("foo(uint32)"))[:4]
	sig = append(sig, make([]byte, 32)...)
	sig[35] = 10

	packed, err := abi.Pack("foo", uint32(10))
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	if !bytes.Equal(packed, sig) {
		t.Errorf("expected %x got %x", sig, packed)
	}
}
示例#24
0
// also called by admin.contractInfo.get
func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, ds *docserver.DocServer) (content []byte, err error) {
	// retrieve contract hash from state
	codehex := xeth.CodeAt(contractAddress)
	codeb := xeth.CodeAtBytes(contractAddress)

	if codehex == "0x" {
		err = fmt.Errorf("contract (%v) not found", contractAddress)
		return
	}
	codehash := common.BytesToHash(crypto.Sha3(codeb))
	// set up nameresolver with natspecreg + urlhint contract addresses
	reg := registrar.New(xeth)

	// resolve host via HashReg/UrlHint Resolver
	hash, err := reg.HashToHash(codehash)
	if err != nil {
		return
	}
	if ds.HasScheme("bzz") {
		content, err = ds.Get("bzz://"+hash.Hex()[2:], "")
		if err == nil { // non-fatal
			return
		}
		err = nil
		//falling back to urlhint
	}

	uri, err := reg.HashToUrl(hash)
	if err != nil {
		return
	}

	// get content via http client and authenticate content using hash
	content, err = ds.GetAuthContent(uri, hash)
	if err != nil {
		return
	}
	return
}
示例#25
0
func TestMultiPack(t *testing.T) {
	abi, err := JSON(strings.NewReader(jsondata2))
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	sig := crypto.Sha3([]byte("bar(uint32,uint16)"))[:4]
	sig = append(sig, make([]byte, 64)...)
	sig[35] = 10
	sig[67] = 11

	packed, err := abi.Pack("bar", uint32(10), uint16(11))
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	if !bytes.Equal(packed, sig) {
		t.Errorf("expected %x got %x", sig, packed)
	}
}
示例#26
0
func TestPackSliceBig(t *testing.T) {
	abi, err := JSON(strings.NewReader(jsondata2))
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	sig := crypto.Sha3([]byte("slice256(uint256[2])"))[:4]
	sig = append(sig, make([]byte, 64)...)
	sig[35] = 1
	sig[67] = 2

	packed, err := abi.Pack("slice256", []*big.Int{big.NewInt(1), big.NewInt(2)})
	if err != nil {
		t.Error(err)
		t.FailNow()
	}

	if !bytes.Equal(packed, sig) {
		t.Errorf("expected %x got %x", sig, packed)
	}
}
示例#27
0
// NewTopic creates a topic from the 4 byte prefix of the SHA3 hash of the data.
//
// 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])
	return Topic(prefix)
}
示例#28
0
func abiSignature(s string) string {
	return common.ToHex(crypto.Sha3([]byte(s))[:4])
}
示例#29
0
import (
	"testing"

	"github.com/expanse-project/go-expanse/common"
	"github.com/expanse-project/go-expanse/crypto"
)

type testBackend struct {
	// contracts mock
	contracts map[string](map[string]string)
}

var (
	text     = "test"
	codehash = common.StringToHash("1234")
	hash     = common.BytesToHash(crypto.Sha3([]byte(text)))
	url      = "bzz://bzzhash/my/path/contr.act"
)

func NewTestBackend() *testBackend {
	self := &testBackend{}
	self.contracts = make(map[string](map[string]string))
	return self
}

func (self *testBackend) initHashReg() {
	self.contracts[HashRegAddr[2:]] = make(map[string]string)
	key := storageAddress(storageMapping(storageIdx2Addr(1), codehash[:]))
	self.contracts[HashRegAddr[2:]][key] = hash.Hex()
}
示例#30
0
// 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...))
}