// Split creates PVSS shares encrypted by the public keys in X and // provides a NIZK encryption consistency proof for each share. func (pv *PVSS) Split(X []abstract.Point, secret abstract.Scalar) ([]int, []abstract.Point, []ProofCore, []byte, error) { n := len(X) // Create secret sharing polynomial priPoly := new(poly.PriPoly).Pick(pv.suite, pv.t, secret, random.Stream) // Create secret set of shares shares := new(poly.PriShares).Split(priPoly, n) // Create public polynomial commitments with respect to basis H pubPoly := new(poly.PubPoly).Commit(priPoly, pv.h) // Prepare data for encryption consistency proofs ... share := make([]abstract.Scalar, n) H := make([]abstract.Point, n) idx := make([]int, n) for i := range idx { idx[i] = i share[i] = shares.Share(i) H[i] = pv.h } // ... and create them proof, err := NewProof(pv.suite, H, X, nil) if err != nil { return nil, nil, nil, nil, err } _, sX, err := proof.SetupCollective(share...) if err != nil { return nil, nil, nil, nil, err } polyBin, err := pubPoly.MarshalBinary() if err != nil { return nil, nil, nil, nil, err } return idx, sX, proof.Core, polyBin, nil }
func (lp *LifePolicy) TakeOutPolicy(serverList []abstract.Point, selectInsurers func([]abstract.Point, int) []abstract.Point, g abstract.Group, t int, n int) (*LifePolicy, bool) { // If n is less than the expected number of shares to reconstruct the // secret, fail if n < t { return lp, false } // Initialize the policy. // If we have no selectInsurers function, use the basic algorithm. if selectInsurers == nil { selectInsurers = selectInsurersBasic } lp.insurersList = selectInsurers(serverList, n) if lp.insurersList == nil || len(lp.insurersList) < n { return lp, false } //TODO: Use bytes maybe? lp.proofList = new(list.List) // Create a new polynomial from the private key where t shares are // needed to reconstruct the secret. Then, split it into secret shares // and create the public polynomial. pripoly := new(poly.PriPoly).Pick(g, t, lp.keyPair.Secret, random.Stream) prishares := new(poly.PriShares).Split(pripoly, n) pubPoly := new(poly.PubPoly) pubPoly.Init(g, n, nil) pubPoly = new(poly.PubPoly).Commit(pripoly, nil) // Mark the policy as being in the setup stage and ready to begin // receiving PolicyApproveMessages. lp.policyStatus = PolicySetup // Send each share off to the appropriate server. for i := 0; i < n; i++ { requestMsg := new(RequestInsuranceMessage).createMessage( lp.keyPair.Public, i, prishares.Share(i), pubPoly) lp.cman.Put(lp.insurersList[i], new(PolicyMessage).createRIMessage(requestMsg)) } receivedList := make([]bool, len(lp.insurersList)) // TODO: Add a timeout such that this process will end after a certain // time and a new batch of insurers can be picked. // TODO: Make it so that it stops as soon as we get R other insurers // for t <= r <= n for lp.proofList.Len() < n { for i := 0; i < n; i++ { // If we have already received a certificate for this // node, move on. if receivedList[i] == true { continue } msg := new(PolicyMessage) lp.cman.Get(lp.insurersList[i], msg) msgType, err := lp.handlePolicyMessage(msg) // Merely for efficiency, to update the receive list. if msgType == PolicyApproved { receivedList[i] = (err == nil) } } } lp.policyStatus = PolicyReady return lp, true }