func kissGenerateCtx(underly io.ReadWriteCloser, our_priv natrium.ECDHPrivate, their_pub natrium.ECDHPublic) *kissContext { shared_secret := natrium.ECDHSecret(our_priv, their_pub) read_nonce := natrium.SecureHash(append(our_priv.PublicKey(), their_pub...), nil) write_nonce := natrium.SecureHash(append(their_pub, our_priv.PublicKey()...), nil) toret := new(kissContext) toret.read_buff = new(bytes.Buffer) toret.transport = underly toret.read_chug = natrium.AEAD(natrium.SecureHash(shared_secret, read_nonce)) toret.write_chug = natrium.AEAD(natrium.SecureHash(shared_secret, write_nonce)) return toret }
// LLObfsServerHandshake negotiates low-level obfuscation (content hiding but no // volume hiding) on a network connection, acting as the server. The master // secret must be provided. func LLObfsServerHandshake(secret []byte, transport io.ReadWriteCloser) (io.ReadWriteCloser, error) { // Client needs to send proof that they actually have our secret proof := make([]byte, 64) _, err := io.ReadFull(transport, proof) if err != nil { return nil, err } kilog.FineDebug("llobfs: server obtained proof") // We need to verify proof nonce := proof[:32] hash := proof[32:] if subtle.ConstantTimeCompare(natrium.SecureHash(secret, nonce), hash) != 1 { return nil, errors.New("Client did not give the right proof") } // Generate our ephemeral keys our_keys := UDHGenerateKeys() // Send our public key _, err = transport.Write(our_keys.Public) if err != nil { return nil, err } kilog.FineDebug("llobfs: server sent public key") // Read their public key their_public := make([]byte, 1536/8) _, err = io.ReadFull(transport, their_public) if err != nil { return nil, err } kilog.FineDebug("llobfs: server read public key") // Compute shared secret shared_secret := UDHSecret(our_keys.Private, their_public) // Read and write keys read_key := natrium.SecureHash(shared_secret, []byte("llobfs-upstream-key")) write_key := natrium.SecureHash(shared_secret, []byte("llobfs-downstream-key")) // Create struct toret := new(llobfsContext) toret.read_chug, _ = rc4.NewCipher(read_key) toret.write_chug, _ = rc4.NewCipher(write_key) dummy := make([]byte, 1536) toret.read_chug.XORKeyStream(dummy, dummy) toret.write_chug.XORKeyStream(dummy, dummy) toret.underlying = transport return toret, nil }
func (sg *servGroup) connAmb(i int) (*kiricom.ServerCtx, error) { nonce := make([]byte, 8) binary.BigEndian.PutUint64(nonce, uint64(i)) hash := natrium.SecureHash(sg.aidee.PublicKey(), nonce) kilog.Debug("serv: building circuit %v -> %x for %v", i, hash, sg.aidee.PublicKey()) var tgt directory.ChordKey tgt.FromBytes(hash) // build circuit to each and every one of them thingy, err := buildCirc(tgt) if err != nil { //thingy.Destroy() return nil, err } haha, err := thingy.RegAmbassador(sg.aidee.PublicKey()) if err != nil { thingy.Destroy() if err == core2core.ErrRejectedReq { kilog.Warning("serv: circuit number %v for %v rejected", i, sg.aidee.PublicKey()) return nil, err } else { return nil, err } } return haha, nil }
// makes a hash value out of the naked neighbor info to sign func (nin neighInfoNaked) HashValue() []byte { acc := make([]byte, 8) binary.LittleEndian.PutUint64(acc, uint64(nin.Expires)) acc = append(acc, nin.IssuedTo...) for _, bts := range nin.NeighList { acc = append(acc, bts...) } return natrium.SecureHash(acc, nil) }
// LLObfsClientHandshake negotiates low-level obfuscation as a client. The server // secret must be given so that the client can prove knowledge. func LLObfsClientHandshake(secret []byte, transport io.ReadWriteCloser) (io.ReadWriteCloser, error) { // Prove knowledge to client first nonce := make([]byte, 32) rand.Read(nonce) hash := natrium.SecureHash(secret, nonce) _, err := transport.Write(append(nonce, hash...)) if err != nil { return nil, err } kilog.FineDebug("llobfs: client sent proof") // Read their public key their_public := make([]byte, 1536/8) _, err = io.ReadFull(transport, their_public) if err != nil { return nil, err } kilog.FineDebug("llobfs: client read server's public key") // Make our keys our_keys := UDHGenerateKeys() // Send our public key _, err = transport.Write(our_keys.Public) if err != nil { return nil, err } kilog.FineDebug("llobfs: client sent public key") // Compute shared secret shared_secret := UDHSecret(our_keys.Private, their_public) // Derive keys read_key := natrium.SecureHash(shared_secret, []byte("llobfs-downstream-key")) write_key := natrium.SecureHash(shared_secret, []byte("llobfs-upstream-key")) toret := new(llobfsContext) toret.read_chug, _ = rc4.NewCipher(read_key) toret.write_chug, _ = rc4.NewCipher(write_key) dummy := make([]byte, 1536) toret.read_chug.XORKeyStream(dummy, dummy) toret.write_chug.XORKeyStream(dummy, dummy) toret.underlying = transport return toret, nil }
func (cc *CollisionCache) Search() Solution { var found []byte wg := new(sync.WaitGroup) offset := uint64(rand.Uint32())<<32 | uint64(rand.Uint32()) fmt.Printf("*** OFFSET = %v ***\n", offset) wg.Add(runtime.GOMAXPROCS(0)) for i := 0; i < runtime.GOMAXPROCS(0); i++ { i := i go func() { defer wg.Done() stpt := (^uint64(0) / uint64(runtime.GOMAXPROCS(0))) * (uint64(i) - 1) stpt += offset for i := stpt; found == nil; i++ { //fmt.Println(i) bts := (*[8]byte)(unsafe.Pointer(&i))[:] hsh := uint64(*(*uint64)( unsafe.Pointer(&natrium.SecureHash(cc.nonce, bts)[0]))) hsh >>= uint(64 - cc.pflen) cc.Lock() ex, ok := cc.cash[hsh] cc.cash[hsh] = i cc.Unlock() if ok && ex != i { fmt.Printf("%v collides with %v (%v)\n", ex, i, hsh) fnd := make([]byte, 16) binary.LittleEndian.PutUint64(fnd[:8], ex) binary.LittleEndian.PutUint64(fnd[8:], i) found = fnd break } } }() } wg.Wait() return found }
func newCircGroup(dest natrium.EdDSAPublic) (*circGroup, error) { // 8 targets in total targets := make([]directory.ChordKey, 8) for i := 0; i < 8; i++ { nonce := make([]byte, 8) binary.BigEndian.PutUint64(nonce, uint64(i)) hash := natrium.SecureHash(dest, nonce) targets[i].FromBytes(hash) } toret := new(circGroup) toret.inchan = make(chan chan io.ReadWriteCloser) toret.dedchan = make(chan bool) okaych := make(chan bool, 10) // spin off goroutines for i, tgt := range targets { tgt := tgt i := i kilog.Debug("circ: building circuit %v -> %x for %v", i, tgt.ToBytes(), dest) go func() { goto SKIP // error DIE_IN_DISGRACE: kilog.Warning("circ: circuit action %v for %v (%x) is aborted!", i, dest, tgt.ToBytes()) // TODO don't die when just one circuit dies //toret.Destroy() return SKIP: spider, err := buildCirc(tgt) if err != nil { toret.Destroy() goto DIE_IN_DISGRACE } kilog.Debug("circ: circuit to the closest node to %x (%v) established", tgt.ToBytes(), spider.CurrentPublic()) kilog.Debug("circ: patching through ambassador %v to %v...", i, dest) thing, err := spider.ConnAmbassador(dest) if err != nil { spider.Destroy() goto DIE_IN_DISGRACE } kilog.Debug("circ: patched through ambassador to %v! circuit length %v", dest, spider.CircLength()) defer thing.Close() /*if spider.CircLength() < 1 { kilog.Debug("circ: aborting %v due to bad length", i) return }*/ okaych <- true for { select { case req := <-toret.inchan: kilog.Debug("circ: request to %v routed through %v", dest, i) wire, err := thing.Dial() if err != nil { kilog.Warning("circ: request to %v through %v encountered unusable dialer!", dest, i) go func() { select { case toret.inchan <- req: case <-time.After(time.Second * 2): close(req) } }() return } go func() { select { case req <- wire: case <-toret.dedchan: kilog.Debug("circ: circuit %v for %v closing down safely", i, dest) } }() case <-toret.dedchan: kilog.Debug("circ: circuit %v for %v closing down safely", i, dest) return } } }() } select { case <-okaych: case <-time.After(time.Second * 20): kilog.Warning("circ: nothing happened in 20 seconds for %v, dying", dest) toret.Destroy() return nil, io.ErrNoProgress } // return return toret, nil }