// 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 }
// 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 }
// 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 }
// 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 }
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 }