Beispiel #1
0
func (snLog SNLog) MarshalBinary() ([]byte, error) {
	// abstract.Write used to encode/ marshal crypto types
	b := bytes.Buffer{}
	abstract.Write(&b, &snLog.v, snLog.Suite)
	abstract.Write(&b, &snLog.V, snLog.Suite)
	abstract.Write(&b, &snLog.V_hat, snLog.Suite)
	// gob is used to encode non-crypto types
	enc := gob.NewEncoder(&b)
	err := enc.Encode(snLog.CMTRoots)
	return b.Bytes(), err
}
Beispiel #2
0
func FromPointToByte(p abstract.Point, params P256Params) []byte {
	b := bytes.Buffer{}
	abstract.Write(&b, p, params.Suite)
	//b,err := p.MarshalBinary()
	//CheckErr(err,"[-] Error while marshiling point")
	return b.Bytes()
}
Beispiel #3
0
func RunClient(s1, s2 Server, params P256Params, ch chan string) {
	// Create the client
	client := &Client{Params: params, Ch: ch, Servers: [2]Server{s1, s2}}
	// Connect to the servers
	b1 := client.Connect(s1.Address, 0)
	b2 := client.Connect(s2.Address, 1)
	defer func() { client.Servers[0].Con.Close(); client.Servers[1].Con.Close() }()
	if !b1 || !b2 {
		fmt.Fprintf(os.Stderr, "Could not connect to servers. Abort.")
		os.Exit(1)
	}

	// Message to send
	msg := GenerateRandomBytes(1024)
	client.SendToBoth(msg, "Error while sending original message")
	client.Ch <- "Sent message to both servers (" + strconv.Itoa(len(msg)) + " bytes)"

	// Receive the partial commitment of each
	client.Ch <- fmt.Sprintf("Waiting for the partial commitment of both servers...")
	pcb1, pcb2 := client.ReceiveFromBoth("Error while waiting the two partial commitment ..")
	client.Ch <- fmt.Sprintf("Received partial commitment from servers (%d,%d bytes) ", len(pcb1), len(pcb2))
	pc1, pc2 := FromByteToPoint(pcb1, params), FromByteToPoint(pcb2, params)

	// Aggregate the commitment and send back to the servers
	aggregateCommitment := pc1.Add(pc1, pc2)
	acb := FromPointToByte(aggregateCommitment, params)
	client.SendToBoth(acb, "Error while sending the aggregateCommitment to both servers")
	client.Ch <- fmt.Sprintf("Sent aggregate commitment (%d bytes) to both servers", len(acb))

	//compute collective challenge
	challenge := hashSchnorr(params.Suite, msg, aggregateCommitment)

	// Receive partial response share from clients
	prb1, prb2 := client.ReceiveFromBoth("Error while receiving partial response from servers")
	pr1, pr2 := FromByteToSecret(prb1, params), FromByteToSecret(prb2, params)
	client.Ch <- "Received both partial responses of servers..."

	// VERIFY
	// compute combined secret + combined public keys
	combinedResponse := pr1.Add(pr1, pr2)
	combinedPublicKey := s1.PublicKey.Add(s1.PublicKey, s2.PublicKey)
	// Combined Signature (to check with the already coded Schnorr verify)
	signature := bytes.Buffer{}
	sig := basicSig{challenge, combinedResponse}
	abstract.Write(&signature, &sig, params.Suite)

	err := SchnorrVerify(params.Suite, msg, combinedPublicKey, signature.Bytes())
	client.Ch <- "Verifying signature ..."
	CheckErr(err, "[-] Varying failed :( ")
	client.Ch <- "Signature passed !! "

	// ACK
	client.SendToBoth([]byte("ACK"), "Error while sending ACK to servers.. ")
	time.Sleep(1 * time.Second)

}
// Saves only the public key to disk.
func SchnorrSavePubkey(path string, suite abstract.Suite, k SchnorrPublicKey) error {
	buf := bytes.Buffer{}
	abstract.Write(&buf, &k, suite)
	f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0644)
	if err != nil {
		return err
	}
	defer f.Close()
	_, e2 := f.Write(buf.Bytes())
	return e2
}
// Saves the keypair as a binary blob on disk. The file format
// matches abstract.Write(...) so whatever that uses, we're using here.
func SchnorrSaveKeypair(path string, suite abstract.Suite, kv SchnorrKeyset) error {
	buf := bytes.Buffer{}
	abstract.Write(&buf, &kv, suite)
	f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0600)
	if err != nil {
		return err
	}
	defer f.Close()
	_, e2 := f.Write(buf.Bytes())
	return e2
}
func encodeAsB64(y abstract.Point) string {

	// there must be better ways of doing this. Ideally,
	// we should have JSON marshalling for the
	// point, secret types in dedis/crypto
	// but we don't, so, that's a shame.
	suite := ed25519.NewAES128SHA256Ed25519(true)

	buf := bytes.Buffer{}
	abstract.Write(&buf, &y, suite)
	return hex.EncodeToString(buf.Bytes())
}
Beispiel #7
0
// This simplified implementation of ElGamal Signatures is based on
// crypto/anon/sig.go
// The ring structure is removed and
// The anonimity set is reduced to one public key = no anonimity
func ElGamalSign(suite abstract.Suite, random cipher.Stream, message []byte,
	privateKey abstract.Secret, g abstract.Point) []byte {

	// Create random secret v and public point commitment T
	v := suite.Secret().Pick(random)
	T := suite.Point().Mul(g, v)

	// Create challenge c based on message and T
	c := hashElGamal(suite, message, T)

	// Compute response r = v - x*c
	r := suite.Secret()
	r.Mul(privateKey, c).Sub(v, r)

	// Return verifiable signature {c, r}
	// Verifier will be able to compute v = r + x*c
	// And check that hashElgamal for T and the message == c
	buf := bytes.Buffer{}
	sig := basicSig{c, r}
	abstract.Write(&buf, &sig, suite)
	return buf.Bytes()
}
Beispiel #8
0
// Generate a new public/private keypair with the given ciphersuite
// and Save it to the application's previously-loaded configuration.
func (f *File) GenKey(keys *Keys, suite abstract.Suite) (KeyPair, error) {

	// Create the map if it doesn't exist
	//	if *keys == nil {
	//		*keys = make(map[string] KeyInfo)
	//	}

	// Create a fresh public/private keypair
	p := KeyPair{}
	p.Gen(suite, random.Stream)
	pubId := p.PubId()

	// Write the private key file
	secname := f.dirName + "/sec-" + pubId
	r := util.Replacer{}
	if err := r.Open(secname); err != nil {
		return KeyPair{}, err
	}
	defer r.Abort()

	// Write the secret key
	if err := abstract.Write(r.File, &p.Secret, suite); err != nil {
		return KeyPair{}, err
	}

	// Commit the secret key
	if err := r.Commit(); err != nil {
		return KeyPair{}, err
	}

	// Re-write the config file with the new public key
	*keys = append(*keys, KeyInfo{suite.String(), pubId})
	if err := f.Save(); err != nil {
		return KeyPair{}, err
	}

	return p, nil
}
// Signs a given message and returns the signature.
// If no signature is possible due to an error
// returns the error in the second retval.
func SchnorrSign(suite abstract.Suite,
	kv SchnorrKeyset,
	msg []byte) ([]byte, error) {

	rsource := make([]byte, 16)
	_, err := rand.Read(rsource)
	if err != nil {
		return nil, err
	}
	// I have no idea if I just encrypted randomness or not
	// I'm hoping this just reads the state out.
	rct := suite.Cipher(rsource)

	k := suite.Secret().Pick(rct)  // some k
	r := suite.Point().Mul(nil, k) // g^k

	r_bin, _ := r.MarshalBinary()
	msg_and_r := append(msg, r_bin...)

	hasher := sha3.New256()
	hasher.Write(msg_and_r)
	h := hasher.Sum(nil)

	// again I'm hoping this just reads the state out
	// and doesn't  actually perform any ops
	hct := suite.Cipher(h)
	e := suite.Secret().Pick(hct) // H(m||r)

	s := suite.Secret()
	s.Mul(kv.X, e).Sub(k, s) // k - xe

	sig := SchnorrSignature{S: s, E: e}

	buf := bytes.Buffer{}
	abstract.Write(&buf, &sig, suite)
	return buf.Bytes(), nil
}
func TestMultisignature5ServerScenario(t *testing.T) {

	suite := ed25519.NewAES128SHA256Ed25519(true)

	// Generate ourselves two keypairs, one for each "server"
	kv_1, err := SchnorrGenerateKeypair(suite)
	if err != nil {
		t.Error(err.Error())
	}
	kv_2, err := SchnorrGenerateKeypair(suite)
	if err != nil {
		t.Error(err.Error())
	}
	kv_3, err := SchnorrGenerateKeypair(suite)
	if err != nil {
		t.Error(err.Error())
	}
	kv_4, err := SchnorrGenerateKeypair(suite)
	if err != nil {
		t.Error(err.Error())
	}
	kv_5, err := SchnorrGenerateKeypair(suite)
	if err != nil {
		t.Error(err.Error())
	}

	// Make a random message and "send" it to the server
	randomdata := make([]byte, 1024)
	_, err = rand.Read(randomdata)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	// client side
	// compute the shared public key given the public keys of each
	// participant.

	pks := []SchnorrPublicKey{SchnorrExtractPubkey(kv_1),
		SchnorrExtractPubkey(kv_2),
		SchnorrExtractPubkey(kv_3),
		SchnorrExtractPubkey(kv_4),
		SchnorrExtractPubkey(kv_5)}
	sharedpubkey := SchnorrMComputeSharedPublicKey(suite, pks)

	// SERVER
	// In response to this each server will generate two
	// arbitrary secrets and respond with a commitment.
	commit1, err := SchnorrMGenerateCommitment(suite)
	if err != nil {
		t.Error(err.Error())
	}

	commit2, err := SchnorrMGenerateCommitment(suite)
	if err != nil {
		t.Error(err.Error())
	}
	commit3, err := SchnorrMGenerateCommitment(suite)
	if err != nil {
		t.Error(err.Error())
	}
	commit4, err := SchnorrMGenerateCommitment(suite)
	if err != nil {
		t.Error(err.Error())
	}
	commit5, err := SchnorrMGenerateCommitment(suite)
	if err != nil {
		t.Error(err.Error())
	}

	// Client side
	commit_array := []SchnorrMPublicCommitment{SchnorrMPublicCommitment{commit1.PublicCommitment().T},
		SchnorrMPublicCommitment{commit2.PublicCommitment().T},
		SchnorrMPublicCommitment{commit3.PublicCommitment().T},
		SchnorrMPublicCommitment{commit4.PublicCommitment().T},
		SchnorrMPublicCommitment{commit5.PublicCommitment().T}}
	aggregate_commitment := SchnorrMComputeAggregateCommitment(suite, commit_array)

	// client and servers
	collective_challenge := SchnorrMComputeCollectiveChallenge(suite, randomdata, aggregate_commitment)

	// servers respond to client with responses
	response_1 := SchnorrMUnmarshallCCComputeResponse(suite, kv_1, commit1, collective_challenge)
	response_2 := SchnorrMUnmarshallCCComputeResponse(suite, kv_2, commit2, collective_challenge)
	response_3 := SchnorrMUnmarshallCCComputeResponse(suite, kv_3, commit3, collective_challenge)
	response_4 := SchnorrMUnmarshallCCComputeResponse(suite, kv_4, commit4, collective_challenge)
	response_5 := SchnorrMUnmarshallCCComputeResponse(suite, kv_5, commit5, collective_challenge)

	// finally, we compute a signature given the responses.
	responsearr := []SchnorrMResponse{response_1, response_2, response_3, response_4, response_5}

	sig := SchnorrMComputeSignatureFromResponses(suite, collective_challenge, responsearr)

	// After all that, we should be able to validate the signature
	// against the group public key. First we serialize the signature

	buf := bytes.Buffer{}
	abstract.Write(&buf, &sig, suite)
	bsig := buf.Bytes()

	verified, err := SchnorrVerify(suite, sharedpubkey.GetSchnorrPK(), randomdata, bsig)
	if err != nil {
		t.Error("Error during Verification")
	}
	if verified == false {
		t.Error("Verification of signature failed.")
	}
}
Beispiel #11
0
func (c *hashProver) Put(message interface{}) error {
	return abstract.Write(&c.msg, message, c.suite)
}
Beispiel #12
0
// Sign creates an optionally anonymous, optionally linkable
// signature on a given message.
//
// The caller supplies one or more public keys representing an anonymity set,
// and the private key corresponding to one of those public keys.
// The resulting signature proves to a verifier that the owner of
// one of these public keys signed the message,
// without revealing which key-holder signed the message,
// offering anonymity among the members of this explicit anonymity set.
// The other users whose keys are listed in the anonymity set need not consent
// or even be aware that they have been included in an anonymity set:
// anyone having a suitable public key may be "conscripted" into a set.
//
// If the provided anonymity set contains only one public key (the signer's),
// then this function produces a traditional non-anonymous signature,
// equivalent in both size and performance to a standard ElGamal signature.
//
// The caller may request either unlinkable or linkable anonymous signatures.
// If linkScope is nil, this function generates an unlinkable signature,
// which contains no information about which member signed the message.
// The anonymity provided by unlinkable signatures is forward-secure,
// in that a signature reveals nothing about which member generated it,
// even if all members' private keys are later released.
// For cryptographic background on unlinkable anonymity-set signatures -
// also known as ring signatures or ad-hoc group signatures -
// see Rivest, "How to Leak a Secret" at
// http://people.csail.mit.edu/rivest/RivestShamirTauman-HowToLeakASecret.pdf.
//
// If the caller passes a non-nil linkScope,
// the resulting anonymous signature will be linkable.
// This means that given two signatures produced using the same linkScope,
// a verifier will be able to tell whether
// the same or different anonymity set members produced those signatures.
// In particular, verifying a linkable signature yields a linkage tag.
// This linkage tag has a 1-to-1 correspondence with the signer's public key
// within a given linkScope, but is cryptographically unlinkable
// to either the signer's public key or to linkage tags in other scopes.
// The provided linkScope may be an arbitrary byte-string;
// the only significance these scopes have is whether they are equal or unequal.
// For details on the linkable signature algorithm this function implements,
// see Liu/Wei/Wong,
// "Linkable Spontaneous Anonymous Group Signature for Ad Hoc Groups" at
// http://www.cs.cityu.edu.hk/~duncan/papers/04liuetal_lsag.pdf.
//
// Linkage tags may be used to protect against sock-puppetry or Sybil attacks
// in situations where a verifier needs to know how many distinct members
// of an anonymity set are present or signed messages in a given context.
// It is cryptographically hard for one anonymity set member
// to produce signatures with different linkage tags in the same scope.
// An important and fundamental downside, however, is that
// linkable signatures do NOT offer forward-secure anonymity.
// If an anonymity set member's private key is later released,
// it is trivial to check whether or not that member produced a given signature.
// Also, anonymity set members who did NOT sign a message could
// (voluntarily or under coercion) prove that they did not sign it,
// e.g., simply by signing some other message in that linkage context
// and noting that the resulting linkage tag comes out different.
// Thus, linkable anonymous signatures are not appropriate to use
// in situations where there may be significant risk
// that members' private keys may later be compromised,
// or that members may be persuaded or coerced into revealing whether or not
// they produced a signature of interest.
//
func Sign(suite abstract.Suite, random cipher.Stream, message []byte,
	anonymitySet Set, linkScope []byte, mine int, privateKey abstract.Secret) []byte {

	// Note that Rivest's original ring construction directly supports
	// heterogeneous rings containing public keys of different types -
	// e.g., a mixture of RSA keys and DSA keys with varying parameters.
	// Our ring signature construction currently supports
	// only homogeneous rings containing compatible keys
	// drawn from the cipher suite (e.g., the same elliptic curve).
	// The upside to this constrint is greater flexibility:
	// e.g., we also easily obtain linkable ring signatures,
	// which are not readily feasible with the original ring construction.

	n := len(anonymitySet)              // anonymity set size
	L := []abstract.Point(anonymitySet) // public keys in anonymity set
	pi := mine

	// If we want a linkable ring signature, produce correct linkage tag,
	// as a pseudorandom base point multiplied by our private key.
	// Liu's scheme specifies the linkScope as a hash of the ring;
	// this is one reasonable choice of linkage scope,
	// but there are others, so we parameterize this choice.
	var linkBase, linkTag abstract.Point
	if linkScope != nil {
		linkStream := suite.Cipher(linkScope)
		linkBase, _ = suite.Point().Pick(nil, linkStream)
		linkTag = suite.Point().Mul(linkBase, privateKey)
	}

	// First pre-hash the parameters to H1
	// that are invariant for different ring positions,
	// so that we don't have to hash them many times.
	H1pre := signH1pre(suite, linkScope, linkTag, message)

	// Pick a random commit for my ring position
	u := suite.Secret().Pick(random)
	var UB, UL abstract.Point
	UB = suite.Point().Mul(nil, u)
	if linkScope != nil {
		UL = suite.Point().Mul(linkBase, u)
	}

	// Build the challenge ring
	s := make([]abstract.Secret, n)
	c := make([]abstract.Secret, n)
	c[(pi+1)%n] = signH1(suite, H1pre, UB, UL)
	var P, PG, PH abstract.Point
	P = suite.Point()
	PG = suite.Point()
	if linkScope != nil {
		PH = suite.Point()
	}
	for i := (pi + 1) % n; i != pi; i = (i + 1) % n {
		s[i] = suite.Secret().Pick(random)
		PG.Add(PG.Mul(nil, s[i]), P.Mul(L[i], c[i]))
		if linkScope != nil {
			PH.Add(PH.Mul(linkBase, s[i]), P.Mul(linkTag, c[i]))
		}
		c[(i+1)%n] = signH1(suite, H1pre, PG, PH)
		//fmt.Printf("s%d %s\n",i,s[i].String())
		//fmt.Printf("c%d %s\n",(i+1)%n,c[(i+1)%n].String())
	}
	s[pi] = suite.Secret()
	s[pi].Mul(privateKey, c[pi]).Sub(u, s[pi]) // s_pi = u - x_pi c_pi

	// Encode and return the signature
	buf := bytes.Buffer{}
	if linkScope != nil { // linkable ring signature
		sig := lSig{uSig{c[0], s}, linkTag}
		abstract.Write(&buf, &sig, suite)
	} else { // unlinkable ring signature
		sig := uSig{c[0], s}
		abstract.Write(&buf, &sig, suite)
	}
	return buf.Bytes()
}
Beispiel #13
0
func (dp *deniableProver) Put(message interface{}) error {
	// Add onto accumulated prover message
	return abstract.Write(dp.msg, message, dp.suite)
}
Beispiel #14
0
func FromSecretToByte(s abstract.Secret, params P256Params) []byte {
	b := bytes.Buffer{}
	abstract.Write(&b, s, params.Suite)
	return b.Bytes()
}
/* This function implements the signer protocol from the blind signature paper
   and can be bound via closure given a specific set of parameters and
   send to the serve() function

   This is not the best accept() handler ever written,  but it's better than the client side code */
func signBlindlySchnorr(conn net.Conn, suite abstract.Suite, kv crypto.SchnorrKeyset, sharedinfo []byte) {

	defer conn.Close()

	fmt.Println("SERVER", "Sending initial parameters")

	signerParams, err := crypto.NewPrivateParams(suite, sharedinfo)
	if err != nil {
		fmt.Println("SERVER", "Error creating new private parameters", err.Error())
		return
	}

	// "send" these to the user.
	userPublicParams := signerParams.DerivePubParams()
	buffer := bytes.Buffer{}
	abstract.Write(&buffer, &userPublicParams, suite)
	conn.Write(buffer.Bytes())

	// now we need to wait for the client to send us "e"
	ch := make(chan []byte)
	errorCh := make(chan error)

	// this neat little routine for wrapping read connections
	// in a class unashamedly stolen from stackoverflow:
	// http://stackoverflow.com/a/9764191
	go func(ch chan []byte, eCh chan error) {
		for {
			// try to read the data
			fmt.Println("SERVER", "Read goroutine off and going")
			buffer := make([]byte, 1026)
			_, err := conn.Read(buffer)
			if err != nil {
				// send an error if it's encountered
				errorCh <- err
				return
			}
			// send data if we read some.
			ch <- buffer
		}
	}(ch, errorCh)

	for {
		select {
		case data := <-ch:
			fmt.Println("SERVER", "Received Message")

			var challenge crypto.WISchnorrChallengeMessage
			buffer := bytes.NewBuffer(data)
			err = abstract.Read(buffer, &challenge, suite)
			if err != nil {
				fmt.Println("SERVER", "Error", err.Error())
				return
			}

			response := crypto.ServerGenerateResponse(suite, challenge, signerParams, kv)
			respbuffer := bytes.Buffer{}
			abstract.Write(&respbuffer, &response, suite)
			conn.Write(respbuffer.Bytes())

			fmt.Println("SERVER", "We're done")
			return

		case err := <-errorCh:
			if err == io.EOF {
				return
			}
			// we should, really, log instead.
			fmt.Println("Encountered error serving client")
			fmt.Println(err.Error())
			break
		}
	}

}
func runClientProtocol(configFilePath string) (bool, error) {

	// first stage, let's retrieve everything from
	// the configuration file that the client needs

	var config SchnorrMGroupConfig

	suite := ed25519.NewAES128SHA256Ed25519(true)

	fcontents, err := ioutil.ReadFile(configFilePath)
	if err != nil {
		fmt.Println("Error reading file")
		fmt.Println(err.Error())
		os.Exit(1)
	}

	err = json.Unmarshal(fcontents, &config)
	if err != nil {
		fmt.Println("Error unmarshalling")
		fmt.Println(err.Error())
		os.Exit(1)
	}

	// and now, for our next trick, a random 1KB blob

	randomdata := make([]byte, 1024)
	_, err = rand.Read(randomdata)
	if err != nil {
		fmt.Println(err.Error())
		return false, err
	}

	reportChan := make(chan controllerMessage)

	var syncChans []chan []byte

	for i, _ := range config.Members {

		syncChan := make(chan []byte)
		syncChans = append(syncChans, syncChan)
		fmt.Println("CLIENT", "C", "Launching goroutine worker")

		go serverComms(config, i, randomdata, reportChan, syncChan)
	}

	var respCount int = 0
	commitmentArray := make([]crypto.SchnorrMPublicCommitment, len(config.Members), len(config.Members))

	fmt.Println("CLIENT", "C", "Controller getting ready to receive")

	for {

		select {
		case msg := <-reportChan:

			// we should probably check all our client threads have responded
			// once and only once, but we won't

			buf := bytes.NewBuffer(msg.Message)
			commitment := crypto.SchnorrMPublicCommitment{}
			err := abstract.Read(buf, &commitment, suite)
			if err != nil {
				fmt.Println("CLIENT", "Read Error")
				fmt.Println(err.Error())
				return false, err
			}

			// we have our abstract point.
			// let's go
			fmt.Println("CLIENT", "C", "Controller got message index", msg.MemberIndex)
			commitmentArray[msg.MemberIndex] = commitment

			respCount = respCount + 1

		default:
		}

		if respCount == len(config.Members) {
			// reset and break
			respCount = 0
			break
		}
	}

	fmt.Println("CLIENT", "C", "Controller received all responses, preparing to aggregate")

	// sum the points
	aggregateCommmitment := crypto.SchnorrMComputeAggregateCommitment(suite, commitmentArray)
	collectiveChallenge := crypto.SchnorrMComputeCollectiveChallenge(suite, randomdata, aggregateCommmitment)

	bAggregateCommmitment := bytes.Buffer{}
	abstract.Write(&bAggregateCommmitment, &aggregateCommmitment, suite)

	// report
	for _, ch := range syncChans {
		fmt.Println("CLIENT", "C", "Sending aggcommitbytes back to workers")
		ch <- bAggregateCommmitment.Bytes()
	}

	// now wait for the server responses, aggregate them and compute
	// a signature from the combined servers.

	fmt.Println("CLIENT", "C", "Controller getting ready to receive")

	responseArray := make([]crypto.SchnorrMResponse, len(config.Members), len(config.Members))

	for {

		select {
		case msg := <-reportChan:

			// we should probably check all our client threads have responded
			// once and only once, but we won't

			buf := bytes.NewBuffer(msg.Message)
			response := crypto.SchnorrMResponse{}
			err := abstract.Read(buf, &response, suite)
			if err != nil {
				return false, err
			}

			fmt.Println("CLIENT", "C", "Received from", msg.MemberIndex)

			// we have our abstract point.
			// let's go
			responseArray[msg.MemberIndex] = response

			respCount = respCount + 1
			fmt.Println("CLIENT", "C", "Received responses", respCount)

		default:
		}

		if respCount == len(config.Members) {
			break
		}
	}

	sig := crypto.SchnorrMComputeSignatureFromResponses(suite, collectiveChallenge, responseArray)

	fmt.Println("Signature created, is")
	fmt.Println(sig)

	return true, nil
}
func signOneKBMSchnorr(conn net.Conn, suite abstract.Suite, kv crypto.SchnorrKeyset) {

	defer conn.Close()

	fmt.Println(suite)

	ch := make(chan []byte)
	errorCh := make(chan error)

	// this neat little routine for wrapping read connections
	// in a class unashamedly stolen from stackoverflow:
	// http://stackoverflow.com/a/9764191
	go func(ch chan []byte, eCh chan error) {
		for {
			// try to read the data
			fmt.Println("SERVER", "Read goroutine off and going")
			buffer := make([]byte, 1026)
			_, err := conn.Read(buffer)
			if err != nil {
				// send an error if it's encountered
				errorCh <- err
				return
			}
			// send data if we read some.
			ch <- buffer
		}
	}(ch, errorCh)

	var internalState byte = INIT
	var message []byte
	var aggregateCommitment crypto.SchnorrMAggregateCommmitment
	var privateCommit crypto.SchnorrMPrivateCommitment

	for {
		select {
		case data := <-ch:

			// validate state transition - we can only
			// transfer to the next state in the protocol
			// anything else and we simply ignore the message
			// eventually we time out and close the connection
			newState := data[0]

			fmt.Println("SERVER", "Selected data channel, states are", newState, internalState)
			if newState != (internalState + 1) {
				continue
			}
			internalState = newState

			payload := data[2:]

			switch newState {
			case MESSAGE:

				fmt.Println("SERVER", "Received Message")

				message = payload

				privateCommitment, err := crypto.SchnorrMGenerateCommitment(suite)
				if err != nil {
					fmt.Println("Error generating commitment")
					fmt.Println(err.Error())
					break
				}
				privateCommit = privateCommitment

				publicCommitment := privateCommitment.PublicCommitment()

				buf := bytes.Buffer{}
				abstract.Write(&buf, &publicCommitment, suite)
				conn.Write(buf.Bytes())

			case COMMITMENT:

				fmt.Println("SERVER", "Received Commitment")

				buf := bytes.NewBuffer(payload)
				err := abstract.Read(buf, &aggregateCommitment, suite)
				if err != nil {
					fmt.Println("Error binary decode of aggregateCommitment")
					fmt.Println(err.Error())
					break
				}

				collectiveChallenge := crypto.SchnorrMComputeCollectiveChallenge(suite, message, aggregateCommitment)
				response := crypto.SchnorrMUnmarshallCCComputeResponse(suite, kv, privateCommit, collectiveChallenge)

				outBuf := bytes.Buffer{}
				abstract.Write(&outBuf, &response, suite)
				conn.Write(outBuf.Bytes())

				// we're now at the end, we can break and close connection
				break
			default:
				fmt.Println("Didn't understand message, received:")
				fmt.Println(data)
			}

		case err := <-errorCh:
			if err == io.EOF {
				return
			}
			// we should, really, log instead.
			fmt.Println("Encountered error serving client")
			fmt.Println(err.Error())
			break

			// well, the *idea* was to have this but frustratingly
			// it does not compile.  Oh well.
			//case time.Tick(time.Minute):
			// more robust handling of connections.
			// don't allow clients to hold the server open
			// indefinitely.
			//break
		}
	}
}
/* Runs through the "user" side of the protocol i.e. the party
   requesting a partially blind signature */
func main() {

	kingpin.MustParse(app.Parse(os.Args[1:]))

	var kfilepath string = *appPrivatekeyfile
	var kinfopath string = *appInfo
	var hostspec string = *appHostspec

	suite := ed25519.NewAES128SHA256Ed25519(true)

	fmt.Println("CLIENT", "Connecting to", hostspec)

	pubKey, err := crypto.SchnorrLoadPubkey(kfilepath, suite)
	if err != nil {
		fmt.Println("CLIENT", "Error loading public key"+err.Error())
		return
	}

	info, err := LoadInfo(kinfopath)
	if err != nil {
		fmt.Println("CLIENT", "Error loading info"+err.Error())
		return
	}

	message := make([]byte, 1024)
	_, err = rand.Read(message)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	conn, err := net.Dial("tcp", hostspec)
	if err != nil {
		fmt.Println("CLIENT", "Error connecting to server", err.Error())
		return
	}
	defer conn.Close()

	// first up, let's receive the signer's parameter set

	buffer := make([]byte, 1026)
	_, err = conn.Read(buffer)
	if err != nil {
		fmt.Println("CLIENT", "Error reading from server", err.Error())
		return
	}

	var userPublicParams crypto.WISchnorrPublicParams
	decodeBuffer := bytes.NewBuffer(buffer)
	err = abstract.Read(decodeBuffer, &userPublicParams, suite)

	// now we've got that, complete the challenge phase (i.e. let's generate E)
	challenge, userPrivateParams, err := crypto.ClientGenerateChallenge(suite, userPublicParams, pubKey, info, message)
	if err != nil {
		fmt.Println("CLIENT", "Error generating challenge", err.Error())
		return
	}

	// encode and send to server.
	challengebuffer := bytes.Buffer{}
	abstract.Write(&challengebuffer, &challenge, suite)
	conn.Write(challengebuffer.Bytes())

	// and now we wait for the server to respond to this:
	secondread := make([]byte, 1024)
	_, err = conn.Read(secondread)
	if err != nil {
		fmt.Println("CLIENT", "Error reading from server", err.Error())
		return
	}

	var responseMessage crypto.WISchnorrResponseMessage
	decodeBuffer = bytes.NewBuffer(secondread)
	err = abstract.Read(decodeBuffer, &responseMessage, suite)
	if err != nil {
		fmt.Println("CLIENT", "Error reading response", err.Error())
		return
	}

	// we've got the response message, time to sign and check.

	// finally, we can sign the message and check it verifies.
	sig, worked := crypto.ClientSignBlindly(suite, userPrivateParams, responseMessage, pubKey, message)

	//fmt.Println(blindSignature)

	if worked != true {
		fmt.Println("CLIENT", "Error preforming blind signature")
		return
	}

	// now verify this worked fine.
	result, err := crypto.VerifyBlindSignature(suite, pubKey, sig, info, message)

	if err != nil {
		fmt.Println("CLIENT", "Error handling signature verification", err.Error())
		return
	}
	if result != true {
		fmt.Println("CLIENT", "Signature did not correctly verify.")
		return
	}

	fmt.Println("CLIENT", "Signature OK -", sig)

	return
}
Beispiel #19
0
// Encodes the message for sending.
func (msg *RequestInsuranceMessage) MarshalBinary() ([]byte, error) {
	b := bytes.Buffer{}
	abstract.Write(&b, msg, INSURE_GROUP)
	return b.Bytes(), nil
	//	return protobuf.Encode(msg);
}