func (dag *Dagger) Eval(N *big.Int) *big.Int { pow := common.BigPow(2, 26) dag.xn = pow.Div(N, pow) sha := sha3.NewKeccak256() sha.Reset() ret := new(big.Int) for k := 0; k < 4; k++ { d := sha3.NewKeccak256() b := new(big.Int) d.Reset() d.Write(dag.hash.Bytes()) d.Write(dag.xn.Bytes()) d.Write(N.Bytes()) d.Write(big.NewInt(int64(k)).Bytes()) b.SetBytes(Sum(d)) pk := (b.Uint64() & 0x1ffffff) sha.Write(dag.Node(9, pk).Bytes()) } return ret.SetBytes(Sum(sha)) }
// 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 (dag *Dagger) Node(L uint64, i uint64) *big.Int { if L == i { return dag.hash } var m *big.Int if L == 9 { m = big.NewInt(16) } else { m = big.NewInt(3) } sha := sha3.NewKeccak256() sha.Reset() d := sha3.NewKeccak256() b := new(big.Int) ret := new(big.Int) for k := 0; k < int(m.Uint64()); k++ { d.Reset() d.Write(dag.hash.Bytes()) d.Write(dag.xn.Bytes()) d.Write(big.NewInt(int64(L)).Bytes()) d.Write(big.NewInt(int64(i)).Bytes()) d.Write(big.NewInt(int64(k)).Bytes()) b.SetBytes(Sum(d)) pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) sha.Write(dag.Node(L-1, pk).Bytes()) } ret.SetBytes(Sum(sha)) return ret }
func TestRLPXFrameRW(t *testing.T) { var ( aesSecret = make([]byte, 16) macSecret = make([]byte, 16) egressMACinit = make([]byte, 32) ingressMACinit = make([]byte, 32) ) for _, s := range [][]byte{aesSecret, macSecret, egressMACinit, ingressMACinit} { rand.Read(s) } conn := new(bytes.Buffer) s1 := secrets{ AES: aesSecret, MAC: macSecret, EgressMAC: sha3.NewKeccak256(), IngressMAC: sha3.NewKeccak256(), } s1.EgressMAC.Write(egressMACinit) s1.IngressMAC.Write(ingressMACinit) rw1 := newRLPXFrameRW(conn, s1) s2 := secrets{ AES: aesSecret, MAC: macSecret, EgressMAC: sha3.NewKeccak256(), IngressMAC: sha3.NewKeccak256(), } s2.EgressMAC.Write(ingressMACinit) s2.IngressMAC.Write(egressMACinit) rw2 := newRLPXFrameRW(conn, s2) // send some messages for i := 0; i < 10; i++ { // write message into conn buffer wmsg := []interface{}{"foo", "bar", strings.Repeat("test", i)} err := Send(rw1, uint64(i), wmsg) if err != nil { t.Fatalf("WriteMsg error (i=%d): %v", i, err) } // read message that rw1 just wrote msg, err := rw2.ReadMsg() if err != nil { t.Fatalf("ReadMsg error (i=%d): %v", i, err) } if msg.Code != uint64(i) { t.Fatalf("msg code mismatch: got %d, want %d", msg.Code, i) } payload, _ := ioutil.ReadAll(msg.Payload) wantPayload, _ := rlp.EncodeToBytes(wmsg) if !bytes.Equal(payload, wantPayload) { t.Fatalf("msg payload mismatch:\ngot %x\nwant %x", payload, wantPayload) } } }
func newTestTransport(id discover.NodeID, fd net.Conn) transport { wrapped := newRLPX(fd).(*rlpx) wrapped.rw = newRLPXFrameRW(fd, secrets{ MAC: zero16, AES: zero16, IngressMAC: sha3.NewKeccak256(), EgressMAC: sha3.NewKeccak256(), }) return &testTransport{id: id, rlpx: wrapped} }
func Sha3(data ...[]byte) []byte { d := sha3.NewKeccak256() for _, b := range data { d.Write(b) } return d.Sum(nil) }
func Sha3Hash(data ...[]byte) (h common.Hash) { d := sha3.NewKeccak256() for _, b := range data { d.Write(b) } d.Sum(h[:0]) return h }
func verify(hash common.Hash, diff *big.Int, nonce uint64) bool { sha := sha3.NewKeccak256() n := make([]byte, 8) binary.PutUvarint(n, nonce) sha.Write(n) sha.Write(hash[:]) verification := new(big.Int).Div(common.BigPow(2, 256), diff) res := common.BigD(sha.Sum(nil)) return res.Cmp(verification) <= 0 }
func rlpHash(x interface{}) (h common.Hash) { hw := sha3.NewKeccak256() rlp.Encode(hw, x) hw.Sum(h[:0]) return h }
// TODO: copied from crypto.go , move to sha3 package? func Sha3(data []byte) []byte { d := sha3.NewKeccak256() d.Write(data) return d.Sum(nil) }