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) } err = rlp.DecodeBytes(sigdata[1:], req) return req, fromID, hash, err }
// 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), Token: crypto.Sha3(sharedSecret), } // 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 }
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 }
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) }
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) } }
// 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 }
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 }
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) } }
func decodeAuthMsg(prv *ecdsa.PrivateKey, token []byte, auth []byte) (*encHandshake, error) { var err error h := new(encHandshake) // generate random keypair for session h.randomPrivKey, err = ecies.GenerateKey(rand.Reader, crypto.S256(), nil) if err != nil { return nil, err } // generate random nonce h.respNonce = make([]byte, shaLen) if _, err = rand.Read(h.respNonce); err != nil { return nil, err } msg, err := crypto.Decrypt(prv, auth) if err != nil { return nil, fmt.Errorf("could not decrypt auth message (%v)", err) } // decode message parameters // signature || sha3(ecdhe-random-pubk) || pubk || nonce || token-flag h.initNonce = msg[authMsgLen-shaLen-1 : authMsgLen-1] copy(h.remoteID[:], msg[sigLen+shaLen:sigLen+shaLen+pubLen]) rpub, err := h.remoteID.Pubkey() if err != nil { return nil, fmt.Errorf("bad remoteID: %#v", err) } h.remotePub = ecies.ImportECDSAPublic(rpub) // recover remote random pubkey from signed message. if token == nil { // TODO: it is an error if the initiator has a token and we don't. check that. // no session token means we need to generate shared secret. // ecies shared secret is used as initial session token for new peers. // generate shared key from prv and remote pubkey. if token, err = h.ecdhShared(prv); err != nil { return nil, err } } signedMsg := xor(token, h.initNonce) remoteRandomPub, err := secp256k1.RecoverPubkey(signedMsg, msg[:sigLen]) if err != nil { return nil, err } // validate the sha3 of recovered pubkey remoteRandomPubMAC := msg[sigLen : sigLen+shaLen] shaRemoteRandomPub := crypto.Sha3(remoteRandomPub[1:]) if !bytes.Equal(remoteRandomPubMAC, shaRemoteRandomPub) { return nil, fmt.Errorf("sha3 of recovered ephemeral pubkey does not match checksum in auth message") } h.remoteRandomPub, _ = importPublicKey(remoteRandomPub) return h, nil }
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 }
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 }
func (tx *Transaction) From() (common.Address, error) { if from := tx.from.Load(); from != nil { return from.(common.Address), nil } pubkey, err := tx.publicKey() 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 }
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 }
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 }
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() }
// 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++ } } }
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 }
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()) } }
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) } }
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) } }
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) } }
// 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 }
// authMsg creates an encrypted initiator handshake message. func (h *encHandshake) authMsg(prv *ecdsa.PrivateKey, token []byte) ([]byte, error) { var tokenFlag byte if token == nil { // no session token found means we need to generate shared secret. // ecies shared secret is used as initial session token for new peers // generate shared key from prv and remote pubkey var err error if token, err = h.ecdhShared(prv); err != nil { return nil, err } } else { // for known peers, we use stored token from the previous session tokenFlag = 0x01 } // sign known message: // ecdh-shared-secret^nonce for new peers // token^nonce for old peers signed := xor(token, h.initNonce) signature, err := crypto.Sign(signed, h.randomPrivKey.ExportECDSA()) if err != nil { return nil, err } // encode auth message // signature || sha3(ecdhe-random-pubk) || pubk || nonce || token-flag msg := make([]byte, authMsgLen) n := copy(msg, signature) n += copy(msg[n:], crypto.Sha3(exportPubkey(&h.randomPrivKey.PublicKey))) n += copy(msg[n:], crypto.FromECDSAPub(&prv.PublicKey)[1:]) n += copy(msg[n:], h.initNonce) msg[n] = tokenFlag // encrypt auth message using remote-pubk return ecies.Encrypt(rand.Reader, h.remotePub, msg, nil, nil) }
// 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) }
func (self *SecureTrie) Delete(key []byte) Node { return self.Trie.Delete(crypto.Sha3(key)) }
func opSha3(instr instruction, env Environment, context *Context, memory *Memory, stack *stack) { offset, size := stack.pop(), stack.pop() hash := crypto.Sha3(memory.Get(offset.Int64(), size.Int64())) stack.push(common.BytesToBig(hash)) }
import ( "testing" "github.com/shiftcurrency/shift/common" "github.com/shiftcurrency/shift/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 { HashRegAddr = common.BigToAddress(common.Big0).Hex() //[2:] UrlHintAddr = common.BigToAddress(common.Big1).Hex() //[2:] self := &testBackend{} self.contracts = make(map[string](map[string]string)) self.contracts[HashRegAddr[2:]] = make(map[string]string) key := storageAddress(storageMapping(storageIdx2Addr(1), codehash[:])) self.contracts[HashRegAddr[2:]][key] = hash.Hex() self.contracts[UrlHintAddr[2:]] = make(map[string]string) mapaddr := storageMapping(storageIdx2Addr(1), hash[:])
//export env_sha3 func env_sha3(dataPtr *byte, length uint64, resultPtr unsafe.Pointer) { data := llvm2bytesRef(dataPtr, length) hash := crypto.Sha3(data) result := (*i256)(resultPtr) *result = hash2llvm(hash) }
func (self *JitVm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) { // TODO: depth is increased but never checked by VM. VM should not know about it at all. self.env.SetDepth(self.env.Depth() + 1) // TODO: Move it to Env.Call() or sth if Precompiled[string(me.Address())] != nil { // if it's address of precopiled contract // fallback to standard VM stdVm := New(self.env) return stdVm.Run(me, caller, code, value, gas, price, callData) } if self.me != nil { panic("JitVm.Run() can be called only once per JitVm instance") } self.me = me self.callerAddr = caller.Address() self.price = price self.data.gas = gas.Int64() self.data.gasPrice = price.Int64() self.data.callData = getDataPtr(callData) self.data.callDataSize = uint64(len(callData)) self.data.address = address2llvm(self.me.Address()) self.data.caller = address2llvm(caller.Address()) self.data.origin = address2llvm(self.env.Origin()) self.data.callValue = big2llvm(value) self.data.coinBase = address2llvm(self.env.Coinbase()) self.data.difficulty = big2llvm(self.env.Difficulty()) self.data.gasLimit = big2llvm(self.env.GasLimit()) self.data.number = self.env.BlockNumber().Uint64() 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? jit := C.evmjit_create() retCode := C.evmjit_run(jit, unsafe.Pointer(&self.data), unsafe.Pointer(self)) if retCode < 0 { err = errors.New("OOG from JIT") gas.SetInt64(0) // Set gas to 0, JIT does not bother } else { gas.SetInt64(self.data.gas) if retCode == 1 { // RETURN ret = C.GoBytes(unsafe.Pointer(self.data.callData), C.int(self.data.callDataSize)) } else if retCode == 2 { // SUICIDE // TODO: Suicide support logic should be moved to Env to be shared by VM implementations state := self.Env().State() receiverAddr := llvm2hashRef(bswap(&self.data.address)) receiver := state.GetOrNewStateObject(receiverAddr) balance := state.GetBalance(me.Address()) receiver.AddBalance(balance) state.Delete(me.Address()) } } C.evmjit_destroy(jit) return }
func abiSignature(s string) string { return common.ToHex(crypto.Sha3([]byte(s))[:4]) }