Пример #1
0
// Shard produces a pseudorandom sharding of the network entity list
// based on a seed and a number of requested shards.
func (rh *RandHound) Shard(seed []byte, shards int) ([][]*onet.TreeNode, [][]abstract.Point, error) {

	if shards == 0 || rh.nodes < shards {
		return nil, nil, fmt.Errorf("Number of requested shards not supported")
	}

	// Compute a random permutation of [1,n-1]
	prng := rh.Suite().Cipher(seed)
	m := make([]int, rh.nodes-1)
	for i := range m {
		j := int(random.Uint64(prng) % uint64(i+1))
		m[i] = m[j]
		m[j] = i + 1
	}

	// Create sharding of the current roster according to the above permutation
	el := rh.List()
	sharding := make([][]*onet.TreeNode, shards)
	keys := make([][]abstract.Point, shards)
	for i, j := range m {
		sharding[i%shards] = append(sharding[i%shards], el[j])
		keys[i%shards] = append(keys[i%shards], el[j].ServerIdentity.Public)
	}

	return sharding, keys, nil
}
Пример #2
0
// Shard produces a pseudorandom sharding of the network entity list
// based on a seed and a number of requested shards.
func (rh *RandHound) Shard(seed []byte, shards uint32) ([][]*network.ServerIdentity, error) {

	if shards == 0 || rh.Group.N < shards {
		return nil, fmt.Errorf("Number of requested shards not supported")
	}

	// Compute a permutation of [0,n-1]
	prng := rh.Suite().Cipher(seed)
	m := make([]uint32, rh.Group.N)
	for i := range m {
		j := int(random.Uint64(prng) % uint64(i+1))
		m[i] = m[j]
		m[j] = uint32(i)
	}

	// Create sharding of the current Roster according to the above permutation
	el := rh.Roster().List
	n := int(rh.Group.N / shards)
	sharding := [][]*network.ServerIdentity{}
	shard := []*network.ServerIdentity{}
	for i, j := range m {
		shard = append(shard, el[j])
		if (i%n == n-1) || (i == len(m)-1) {
			sharding = append(sharding, shard)
			shard = make([]*network.ServerIdentity, 0)
		}
	}
	return sharding, nil
}
Пример #3
0
// permute the given y's and Y's
func permute(y []abstract.Secret, Y []abstract.Point) ([]abstract.Secret, []abstract.Point) {
	amount := len(Y)
	rand.Seed(int64(random.Uint64(random.Stream)))

	permutation := rand.Perm(amount)
	newy := make([]abstract.Secret, amount)
	newY := make([]abstract.Point, amount)

	for i := range Y {
		newy[i] = y[permutation[i]]
		newY[i] = Y[permutation[i]]
	}

	return newy, newY
}
Пример #4
0
// Randomly shuffle and re-randomize a set of ElGamal pairs,
// producing a correctness proof in the process.
// Returns (Xbar,Ybar), the shuffled and randomized pairs.
// If g or h is nil, the standard base point is used.
func Shuffle(group abstract.Group, g, h abstract.Point, X, Y []abstract.Point,
	rand cipher.Stream) (XX, YY []abstract.Point, P proof.Prover) {

	k := len(X)
	if k != len(Y) {
		panic("X,Y vectors have inconsistent length")
	}

	ps := PairShuffle{}
	ps.Init(group, k)

	// Pick a random permutation
	pi := make([]int, k)
	for i := 0; i < k; i++ { // Initialize a trivial permutation
		pi[i] = i
	}
	for i := k - 1; i > 0; i-- { // Shuffle by random swaps
		j := int(random.Uint64(rand) % uint64(i+1))
		if j != i {
			t := pi[j]
			pi[j] = pi[i]
			pi[i] = t
		}
	}

	// Pick a fresh ElGamal blinding factor for each pair
	beta := make([]abstract.Scalar, k)
	for i := 0; i < k; i++ {
		beta[i] = ps.grp.Scalar().Pick(rand)
	}

	// Create the output pair vectors
	Xbar := make([]abstract.Point, k)
	Ybar := make([]abstract.Point, k)
	for i := 0; i < k; i++ {
		Xbar[i] = ps.grp.Point().Mul(g, beta[pi[i]])
		Xbar[i].Add(Xbar[i], X[pi[i]])
		Ybar[i] = ps.grp.Point().Mul(h, beta[pi[i]])
		Ybar[i].Add(Ybar[i], Y[pi[i]])
	}

	prover := func(ctx proof.ProverContext) error {
		return ps.Prove(pi, g, h, beta, X, Y, rand, ctx)
	}
	return Xbar, Ybar, prover
}
Пример #5
0
func (rh *RandHound) chooseTrustees(Rc, Rs []byte) (map[uint32]uint32, []abstract.Point) {

	// Seed PRNG for selection of trustees
	var seed []byte
	seed = append(seed, Rc...)
	seed = append(seed, Rs...)
	prng := rh.Suite().Cipher(seed)

	// Choose trustees uniquely
	shareIdx := make(map[uint32]uint32)
	trustees := make([]abstract.Point, rh.Group.K)
	tns := rh.List()
	j := uint32(0)
	for uint32(len(shareIdx)) < rh.Group.K {
		i := uint32(random.Uint64(prng) % uint64(len(tns)))
		// Add trustee only if not done so before; choosing yourself as an trustee is fine; ignore leader at index 0
		if _, ok := shareIdx[i]; !ok && !tns[i].IsRoot() {
			shareIdx[i] = j // j is the share index
			trustees[j] = tns[i].ServerIdentity.Public
			j++
		}
	}
	return shareIdx, trustees
}