Пример #1
0
// PointDecodeFrom provides a generic implementation of Point.DecodeFrom,
// based on Point.Decode, or Point.Pick if r is a Cipher or cipher.Stream.
// The returned byte-count is valid only when decoding from a normal Reader,
// not when picking from a pseudorandom source.
func PointUnmarshalFrom(p abstract.Point, r io.Reader) (int, error) {
	if strm, ok := r.(cipher.Stream); ok {
		p.Pick(nil, strm)
		return -1, nil // no byte-count when picking randomly
	}
	buf := make([]byte, p.MarshalSize())
	n, err := io.ReadFull(r, buf)
	if err != nil {
		return n, err
	}
	return n, p.UnmarshalBinary(buf)
}
Пример #2
0
// ConstructTree does a depth-first construction of the tree specified in the
// config file. ConstructTree must be called AFTER populating the HostConfig with
// ALL the possible hosts.
func ConstructTree(
	n *Node,
	hc *HostConfig,
	parent string,
	suite abstract.Suite,
	rand cipher.Stream,
	hosts map[string]coconet.Host,
	nameToAddr map[string]string,
	opts ConfigOptions) (int, error) {
	// passes up its X_hat, and/or an error

	// get the name associated with this address
	name, ok := nameToAddr[n.Name]
	if !ok {
		fmt.Println("unknown name in address book:", n.Name)
		return 0, errors.New("unknown name in address book")
	}

	// generate indicates whether we should generate the signing
	// node for this hostname
	generate := opts.Host == "" || opts.Host == name

	// check to make sure the this hostname is in the tree
	// it can be backed by a nil pointer
	h, ok := hosts[name]
	if !ok {
		fmt.Println("unknown host in tree:", name)
		return 0, errors.New("unknown host in tree")
	}

	var prikey abstract.Secret
	var pubkey abstract.Point
	var sn *sign.Node

	// if the JSON holds the fields field is set load from there
	if len(n.PubKey) != 0 {
		// log.Println("decoding point")
		encoded, err := hex.DecodeString(string(n.PubKey))
		if err != nil {
			log.Print("failed to decode hex from encoded")
			return 0, err
		}
		pubkey = suite.Point()
		err = pubkey.UnmarshalBinary(encoded)
		if err != nil {
			log.Print("failed to decode point from hex")
			return 0, err
		}
		// log.Println("decoding point")
		encoded, err = hex.DecodeString(string(n.PriKey))
		if err != nil {
			log.Print("failed to decode hex from encoded")
			return 0, err
		}
		prikey = suite.Secret()
		err = prikey.UnmarshalBinary(encoded)
		if err != nil {
			log.Print("failed to decode point from hex")
			return 0, err
		}
	}
	if generate {
		if prikey != nil {
			// if we have been given a private key load that
			aux := sign.NewKeyedNode(h, suite, prikey)
			aux.GenSetPool()
			hc.SNodes = append(hc.SNodes, aux)
			h.SetPubKey(pubkey)
		} else {
			// otherwise generate a random new one
			sn := sign.NewNode(h, suite, rand)
			sn.GenSetPool()
			hc.SNodes = append(hc.SNodes, sn)
			h.SetPubKey(sn.PubKey)
		}
		sn = hc.SNodes[len(hc.SNodes)-1]
		hc.Hosts[name] = sn
		if prikey == nil {
			prikey = sn.PrivKey
			pubkey = sn.PubKey
		}
		// log.Println("pubkey:", sn.PubKey)
		// log.Println("given: ", pubkey)
	}
	// if the parent of this call is empty then this must be the root node
	if parent != "" && generate {
		h.AddParent(0, parent)
	}
	// log.Println("name: ", n.Name)
	// log.Println("prikey: ", prikey)
	// log.Println("pubkey: ", pubkey)
	height := 0
	for _, c := range n.Children {
		// connect this node to its children
		cname, ok := nameToAddr[c.Name]
		if !ok {
			fmt.Println("unknown name in address book:", n.Name)
			return 0, errors.New("unknown name in address book")
		}

		if generate {
			h.AddChildren(0, cname)
		}

		// recursively construct the children
		// log.Print("ConstructTree:", h, suite, rand, hosts, nameToAddr, opts)
		h, err := ConstructTree(c, hc, name, suite, rand, hosts, nameToAddr, opts)
		if err != nil {
			return 0, err
		}
		height = max(h+1, height)
		// if generating all csn will be availible
	}
	if generate {
		sn.Height = height
	}
	// log.Println("name: ", n.Name)
	// log.Println("final x_hat: ", x_hat)
	// log.Println("final pubkey: ", pubkey)
	return height, nil
}
Пример #3
0
func handleAnnouncement(params map[string]interface{}) {
	var g abstract.Point = nil
	keyList := util.ProtobufDecodePointList(params["keys"].([]byte))
	valList := params["vals"].([]util.ByteArray)
	size := len(keyList)

	if val, ok := params["g"]; ok {
		// contains g
		byteG := val.([]byte)
		g = anonServer.Suite.Point()
		g.UnmarshalBinary(byteG)
		g = anonServer.Suite.Point().Mul(g, anonServer.Roundkey)
		// verify the previous shuffle
		verifyNeffShuffle(params)
	} else {
		g = anonServer.Suite.Point().Mul(nil, anonServer.Roundkey)
	}

	X1 := make([]abstract.Point, 1)
	X1[0] = anonServer.PublicKey

	newKeys := make([]abstract.Point, size)
	newVals := make([][]byte, size)
	for i := 0; i < len(keyList); i++ {
		// encrypt the public key using modPow
		newKeys[i] = anonServer.Suite.Point().Mul(keyList[i], anonServer.Roundkey)
		// decrypt the reputation using ElGamal algorithm
		MM, err := anon.Decrypt(anonServer.Suite, valList[i].Arr, anon.Set(X1), 0, anonServer.PrivateKey, false)
		util.CheckErr(err)
		newVals[i] = MM
		// update key map
		anonServer.KeyMap[newKeys[i].String()] = keyList[i]
	}
	byteNewKeys := util.ProtobufEncodePointList(newKeys)
	byteNewVals := util.SerializeTwoDimensionArray(newVals)
	byteG, err := g.MarshalBinary()
	util.CheckErr(err)

	if size <= 1 {
		// no need to shuffle, just send the package to next server
		pm := map[string]interface{}{
			"keys": byteNewKeys,
			"vals": byteNewVals,
			"g":    byteG,
		}
		event := &proto.Event{proto.ANNOUNCEMENT, pm}
		util.Send(anonServer.Socket, anonServer.NextHop, util.Encode(event))
		return
	}

	Xori := make([]abstract.Point, len(newVals))
	for i := 0; i < size; i++ {
		Xori[i] = anonServer.Suite.Point().Mul(nil, anonServer.PrivateKey)
	}
	byteOri := util.ProtobufEncodePointList(Xori)

	rand := anonServer.Suite.Cipher(abstract.RandomKey)
	// *** perform neff shuffle here ***
	Xbar, Ybar, _, Ytmp, prover := neffShuffle(Xori, newKeys, rand)
	prf, err := proof.HashProve(anonServer.Suite, "PairShuffle", rand, prover)
	util.CheckErr(err)

	// this is the shuffled key
	finalKeys := convertToOrigin(Ybar, Ytmp)
	finalVals := rebindReputation(newKeys, newVals, finalKeys)

	// send data to the next server
	byteXbar := util.ProtobufEncodePointList(Xbar)
	byteYbar := util.ProtobufEncodePointList(Ybar)
	byteFinalKeys := util.ProtobufEncodePointList(finalKeys)
	byteFinalVals := util.SerializeTwoDimensionArray(finalVals)
	bytePublicKey, _ := anonServer.PublicKey.MarshalBinary()
	// prev keys means the key before shuffle
	pm := map[string]interface{}{
		"xbar":       byteXbar,
		"ybar":       byteYbar,
		"keys":       byteFinalKeys,
		"vals":       byteFinalVals,
		"proof":      prf,
		"prev_keys":  byteOri,
		"prev_vals":  byteNewKeys,
		"shuffled":   true,
		"public_key": bytePublicKey,
		"g":          byteG,
	}
	event := &proto.Event{proto.ANNOUNCEMENT, pm}
	util.Send(anonServer.Socket, anonServer.NextHop, util.Encode(event))
}