func (jv *JVSS) initSecret(sid SID) error { // Initialise shared secret of given type if necessary if _, ok := jv.secrets[sid]; !ok { log.Lvl2(fmt.Sprintf("Node %d: Initialising %s shared secret", jv.Index(), sid)) sec := &Secret{ receiver: poly.NewReceiver(jv.keyPair.Suite, jv.info, jv.keyPair), deals: make(map[int]*poly.Deal), sigs: make(map[int]*poly.SchnorrPartialSig), numConfs: 0, } jv.secrets[sid] = sec } secret := jv.secrets[sid] // Initialise and broadcast our deal if necessary if len(secret.deals) == 0 { kp := config.NewKeyPair(jv.keyPair.Suite) deal := new(poly.Deal).ConstructDeal(kp, jv.keyPair, jv.info.T, jv.info.R, jv.pubKeys) log.Lvl2(fmt.Sprintf("Node %d: Initialising %v deal", jv.Index(), sid)) secret.deals[jv.Index()] = deal db, _ := deal.MarshalBinary() msg := &SecInitMsg{ Src: jv.Index(), SID: sid, Deal: db, } if err := jv.Broadcast(msg); err != nil { return err } } return nil }
// ComputeSharedSecret will make the exchange of dealers between // the peers and will compute the sharedsecret at the end func (p *Peer) ComputeSharedSecret() *poly.SharedSecret { // Construct the dealer dealerKey := cliutils.KeyPair(p.suite) dealer := new(poly.Deal).ConstructDeal(&dealerKey, &p.key, p.info.T, p.info.R, p.pubKeys) // Construct the receiver receiver := poly.NewReceiver(p.suite, p.info, &p.key) // add already its own dealer _, err := receiver.AddDeal(p.Id, dealer) if err != nil { dbg.Fatal(p.String(), "could not add its own dealer >< ABORT") } // Send the dealer struct TO every one err = p.SendToAll(dealer) dbg.Lvl3(p.Name, "sent its dealer to every peers. (err =", err, ")") // Receive the dealer struct FROM every one // wait with a chan to get ALL dealers dealChan := make(chan *poly.Deal) for _, rp := range p.remote { go func(rp RemotePeer) { d := new(poly.Deal).UnmarshalInit(p.info.T, p.info.R, p.info.N, p.suite) err := p.suite.Read(rp.Conn, d) if err != nil { dbg.Fatal(p.Name, "received a strange dealer from", rp.String(), ":", err) } dealChan <- d }(rp) } // wait to get all dealers dbg.Lvl3(p.Name, "wait to receive every other peer's dealer...") n := 0 for { // get the dealer and add it d := <-dealChan dbg.Lvl3(p.Name, "collected one more dealer (count =", n, ")") // TODO: get the response back to the dealer _, err := receiver.AddDeal(p.Id, d) if err != nil { dbg.Fatal(p.Name, "has error when adding the dealer:", err) } n += 1 // we get enough dealers to compute the shared secret if n == p.info.T-1 { dbg.Lvl3(p.Name, "received every Dealers") break } } sh, err := receiver.ProduceSharedSecret() if err != nil { dbg.Fatal(p.Name, "could not produce shared secret. Abort. (err", err, ")") } dbg.Lvl3(p.Name, "produced shared secret !") return sh }
func (jv *JVSS) initSecret(sid SID) error { if sid.IsLTSS() && jv.ltssInit { return errors.New("Only one longterm secret allowed per JVSS instance") } // Initialise shared secret of given type if necessary if sec, err := jv.secrets.secret(sid); sec == nil && err != nil { log.Lvlf4("Node %d: Initialising %s shared secret", jv.Index(), sid) sec := &secret{ receiver: poly.NewReceiver(jv.keyPair.Suite, jv.info, jv.keyPair), deals: make(map[int]*poly.Deal), sigs: make(map[int]*poly.SchnorrPartialSig), numLongtermConfs: 0, } jv.secrets.addSecret(sid, sec) } secret, err := jv.secrets.secret(sid) if err != nil { // this should never happen here log.Error(err) return err } // Initialise and broadcast our deal if necessary if len(secret.deals) == 0 { kp := config.NewKeyPair(jv.keyPair.Suite) deal := new(poly.Deal).ConstructDeal(kp, jv.keyPair, jv.info.T, jv.info.R, jv.pubKeys) log.Lvlf4("Node %d: Initialising %v deal", jv.Index(), sid) secret.deals[jv.Index()] = deal db, _ := deal.MarshalBinary() msg := &SecInitMsg{ Src: jv.Index(), SID: sid, Deal: db, } if err := jv.Broadcast(msg); err != nil { log.Print(jv.Name(), "Error broadcast secInit:", err) return err } } return nil }
// First, let's generate the set of dealers and the set of receivers. // A dealer create a secret and can distribute shares of its secret // A receiver is one that receives such a share. // A dealer create its shares and then encrypt each share for the respective // receivers. In order to do that, a dealers need to know each public key of the // receivers, so it can encrypt each share with the respective public key. That // way, only the respective receiver can decrypt its own share. // The joint.go library is designed such that the set of dealers and receivers // can be completely disjoint. However, since the goal is to be able to // reconstruct a secret from some shares, there is a mimimal threshold of share // to have in order to reconstruct that secret. Therefore, the number of dealers // must AT LEAST be equal to that threshold (info.T in our example) func generateDealerReceiver(info poly.Threshold, ndeals, nreceivers int) ([]*poly.Deal, []*poly.Receiver) { // Generate the keys of the receivers receiverKeys := generateKeyPairList(nreceivers) // From it construct the list of the public keys that must be given to a // dealer. This is list is KNOWN. receiverPublics := generatePublicListFromPrivate(receiverKeys) receivers := make([]*poly.Receiver, nreceivers) for i := 0; i < nreceivers; i++ { // Create a receiver by giving it the suite, the info about the // polynomials used and its private / public key receivers[i] = poly.NewReceiver(suite, info, receiverKeys[i]) } dealers := make([]*poly.Deal, ndeals) for i := 0; i < ndeals; i++ { // Create a deal (holded by a dealer) with a fresh longterm, ephemereal // public /private key, the info, and the public keys of the receivers dealers[i] = new(poly.Deal).ConstructDeal(generateKeyPair(), generateKeyPair(), info.T, info.R, receiverPublics) } return dealers, receivers }