// signStatement can be used to sign the contents passed in the io.Reader // (pass an io.File or use an strings.NewReader for strings) func signStatement(read io.Reader, el *onet.Roster) (*s.SignatureResponse, error) { publics := entityListToPublics(el) client := s.NewClient() msg, _ := crypto.HashStream(network.Suite.Hash(), read) pchan := make(chan *s.SignatureResponse) var err error go func() { log.Lvl3("Waiting for the response on SignRequest") response, e := client.SignatureRequest(el, msg) if e != nil { err = e close(pchan) return } pchan <- response }() select { case response, ok := <-pchan: log.Lvl5("Response:", response) if !ok || err != nil { return nil, errors.New("received an invalid repsonse") } err = cosi.VerifySignature(network.Suite, publics, msg, response.Signature) if err != nil { return nil, err } return response, nil case <-time.After(RequestTimeOut): return nil, errors.New("timeout on signing request") } }
func verifySignatureHash(b []byte, sig *s.SignatureResponse, el *onet.Roster) error { // We have to hash twice, as the hash in the signature is the hash of the // message sent to be signed publics := entityListToPublics(el) fHash, _ := crypto.HashBytes(network.Suite.Hash(), b) hashHash, _ := crypto.HashBytes(network.Suite.Hash(), fHash) if !bytes.Equal(hashHash, sig.Hash) { return errors.New("You are trying to verify a signature " + "belonging to another file. (The hash provided by the signature " + "doesn't match with the hash of the file.)") } if err := cosi.VerifySignature(network.Suite, publics, fHash, sig.Signature); err != nil { return errors.New("Invalid sig:" + err.Error()) } return nil }
func TestCoSimul(t *testing.T) { for VerifyResponse = 0; VerifyResponse < 3; VerifyResponse++ { for _, nbrHosts := range []int{1, 3, 13} { log.Lvl2("Running cosi with", nbrHosts, "hosts") local := onet.NewLocalTest() hosts, _, tree := local.GenBigTree(nbrHosts, nbrHosts, 3, true) log.Lvl2(tree.Dump()) done := make(chan bool) // create the message we want to sign for this round msg := []byte("Hello World Cosi") // Register the function generating the protocol instance var root *CoSimul // function that will be called when protocol is finished by the root doneFunc := func(sig []byte) { suite := hosts[0].Suite() if err := cosi.VerifySignature(suite, root.Publics(), msg, sig); err != nil { t.Fatal("error verifying signature:", err) } else { log.Lvl1("Verification OK") } done <- true } // Start the protocol p, err := local.CreateProtocol(Name, tree) if err != nil { t.Fatal("Couldn't create new node:", err) } root = p.(*CoSimul) root.Message = msg root.RegisterSignatureHook(doneFunc) go root.StartProtocol() select { case <-done: case <-time.After(time.Second * 2): t.Fatal("Could not get signature verification done in time") } local.CloseAll() } } }
func TestServiceCosi(t *testing.T) { defer log.AfterTest(t) log.TestOutput(testing.Verbose(), 4) local := onet.NewTCPTest() // generate 5 hosts, they don't connect, they process messages, and they // don't register the tree or entitylist hosts, el, _ := local.GenTree(5, false) defer local.CloseAll() // Send a request to the service client := NewTestClient(local) msg := []byte("hello cosi service") log.Lvl1("Sending request to service...") res, err := client.SignatureRequest(el, msg) log.ErrFatal(err, "Couldn't send") // verify the response still assert.Nil(t, cosi.VerifySignature(hosts[0].Suite(), el.Publics(), msg, res.Signature)) }
// Run implements onet.Simulation. func (cs *Simulation) Run(config *onet.SimulationConfig) error { size := len(config.Roster.List) msg := []byte("Hello World Cosi Simulation") log.Lvl2("Simulation starting with: Size=", size, ", Rounds=", cs.Rounds) for round := 0; round < cs.Rounds; round++ { log.Lvl1("Starting round", round) roundM := monitor.NewTimeMeasure("round") // create the node with the protocol, but do NOT start it yet. node, err := config.Overlay.CreateProtocolOnet(Name, config.Tree) if err != nil { return err } // the protocol itself proto := node.(*CoSimul) // give the message to sign proto.SigningMessage(msg) // tell us when it is done done := make(chan bool) fn := func(sig []byte) { roundM.Record() publics := proto.Publics() if err := cosi.VerifySignature(network.Suite, publics, msg, sig); err != nil { log.Lvl1("Round", round, " => fail verification") } else { log.Lvl2("Round", round, " => success") } done <- true } proto.RegisterSignatureHook(fn) if err := proto.Start(); err != nil { log.Error("Couldn't start protocol in round", round) } <-done } log.Lvl1("Simulation finished") return nil }
// VerifySignature returns whether the BlockLink has been signed // correctly using the aggregate key given. func (bl *BlockLink) VerifySignature(publics []abstract.Point) error { // TODO: enable real verification once we have signatures //return nil return cosi.VerifySignature(network.Suite, publics, bl.Hash, bl.Signature) }
// VerifySignature verifies if the challenge and the secret (from the response phase) form a // correct signature for this message using the aggregated public key. // This is copied from cosi, so that you don't need to include both lib/cosi // and protocols/cosi func VerifySignature(suite abstract.Suite, publics []abstract.Point, msg, sig []byte) error { return cosi.VerifySignature(suite, publics, msg, sig) }