예제 #1
0
파일: sig.go 프로젝트: Liamsi/crypto
// Verify checks a signature generated by Sign.
//
// The caller provides the message, anonymity set, and linkage scope
// with which the signature was purportedly produced.
// If the signature is a valid linkable signature (linkScope != nil),
// this function returns a linkage tag that uniquely corresponds
// to the signer within the given linkScope.
// If the signature is a valid unlinkable signature (linkScope == nil),
// returns an empty but non-nil byte-slice instead of a linkage tag on success.
// Returns a nil linkage tag and an error if the signature is invalid.
func Verify(suite abstract.Suite, message []byte, anonymitySet Set,
	linkScope []byte, signatureBuffer []byte) ([]byte, error) {

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

	// Decode the signature
	buf := bytes.NewBuffer(signatureBuffer)
	var linkBase, linkTag abstract.Point
	sig := lSig{}
	sig.S = make([]abstract.Secret, n)
	if linkScope != nil { // linkable ring signature
		if err := abstract.Read(buf, &sig, suite); err != nil {
			return nil, err
		}
		linkStream := suite.Cipher(linkScope)
		linkBase, _ = suite.Point().Pick(nil, linkStream)
		linkTag = sig.Tag
	} else { // unlinkable ring signature
		if err := abstract.Read(buf, &sig.uSig, suite); err != nil {
			return nil, err
		}
	}

	// Pre-hash the ring-position-invariant parameters to H1.
	H1pre := signH1pre(suite, linkScope, linkTag, message)

	// Verify the signature
	var P, PG, PH abstract.Point
	P = suite.Point()
	PG = suite.Point()
	if linkScope != nil {
		PH = suite.Point()
	}
	s := sig.S
	ci := sig.C0
	for i := 0; i < n; i++ {
		PG.Add(PG.Mul(nil, s[i]), P.Mul(L[i], ci))
		if linkScope != nil {
			PH.Add(PH.Mul(linkBase, s[i]), P.Mul(linkTag, ci))
		}
		ci = signH1(suite, H1pre, PG, PH)
	}
	if !ci.Equal(sig.C0) {
		return nil, errors.New("invalid signature")
	}

	// Return the re-encoded linkage tag, for uniqueness checking
	if linkScope != nil {
		tag, _ := linkTag.MarshalBinary()
		return tag, nil
	} else {
		return []byte{}, nil
	}
}
예제 #2
0
파일: key.go 프로젝트: Liamsi/crypto
// Retrieve a public/private keypair for a given KeyInfo configuration record.
func (f *File) Key(key *KeyInfo, suites map[string]abstract.Suite) (KeyPair, error) {

	// XXX support passphrase-encrypted or system-keychain keys

	// Lookup the appropriate ciphersuite for this public key.
	suite := suites[key.Suite]
	if suite == nil {
		return KeyPair{},
			errors.New("Unsupported ciphersuite '" + key.Suite + "'")
	}

	// Read the private key file
	secname := f.dirName + "/sec-" + key.PubId
	secf, err := os.Open(secname)
	if err != nil {
		return KeyPair{}, err
	}
	defer secf.Close()

	p := KeyPair{}
	p.Suite = suite
	if err := abstract.Read(secf, &p.Secret, suite); err != nil {
		return KeyPair{}, err
	}

	// Reconstruct and verify the public key
	p.Public = suite.Point().Mul(nil, p.Secret)
	if p.PubId() != key.PubId {
		return KeyPair{},
			errors.New("Secret does not yield public key " +
				key.PubId)
	}

	return p, nil
}
예제 #3
0
// Checks the signature against
// the message
func SchnorrVerify(suite abstract.Suite,
	kp SchnorrPublicKey,
	msg []byte, sig []byte) (bool, error) {

	buf := bytes.NewBuffer(sig)
	signature := SchnorrSignature{}
	err := abstract.Read(buf, &signature, suite)
	if err != nil {
		return false, err
	}

	s := signature.S
	e := signature.E

	var gs, ye, r abstract.Point
	gs = suite.Point().Mul(nil, s)  // g^s
	ye = suite.Point().Mul(kp.Y, e) // y^e
	r = suite.Point().Add(gs, ye)   // g^xy^e

	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
	lct := suite.Cipher(h)

	ev := suite.Secret().Pick(lct)
	return ev.Equal(e), nil
}
예제 #4
0
func FromByteToSecret(b []byte, params P256Params) abstract.Secret {
	secret := params.Suite.Secret()
	//err := secret.UnmarshalBinary(b)
	//CheckErr(err,"[-] Error while unmarshaling secret")
	abstract.Read(bytes.NewBuffer(b), secret, params.Suite)
	return secret
}
예제 #5
0
func ElGamalVerify(suite abstract.Suite, message []byte, publicKey abstract.Point,
	signatureBuffer []byte, g abstract.Point) error {

	// Decode the signature
	buf := bytes.NewBuffer(signatureBuffer)
	sig := basicSig{}
	if err := abstract.Read(buf, &sig, suite); err != nil {
		return err
	}
	r := sig.R
	c := sig.C

	// Compute base**(r + x*c) == T
	var P, T abstract.Point
	P = suite.Point()
	T = suite.Point()
	T.Add(T.Mul(g, r), P.Mul(publicKey, c))

	// Verify that the hash based on the message and T
	// matches the challange c from the signature
	c = hashElGamal(suite, message, T)
	if !c.Equal(sig.C) {
		return errors.New("invalid signature")
	}

	return nil
}
예제 #6
0
파일: snlog.go 프로젝트: ineiti/prifi
func (snLog *SNLog) UnmarshalBinary(data []byte) error {
	// abstract.Read used to decode/ unmarshal crypto types
	b := bytes.NewBuffer(data)
	err := abstract.Read(b, snLog, snLog.Suite)
	// gob is used to decode non-crypto types
	rem, _ := snLog.MarshalBinary()
	snLog.CMTRoots = data[len(rem):]
	return err
}
예제 #7
0
func FromByteToPoint(b []byte, params P256Params) abstract.Point {
	point := params.Suite.Point()
	//err := point.UnmarshalBinary(b)
	//CheckErr(err,"[-] Error while unmarshling a point")
	err := abstract.Read(bytes.NewBuffer(b), point, params.Suite)
	CheckErr(err, "Error in FromByteToPoint ...")

	return point
}
예제 #8
0
파일: deniable.go 프로젝트: Liamsi/crypto
// Prover will call this after Put()ing all commits for a given step,
// to get the master challenge to be used in its challenge/responses.
func (dp *deniableProver) PubRand(data ...interface{}) error {

	if _, err := dp.proofStep(); err != nil { // finish proof step
		return err
	}
	if err := dp.challengeStep(); err != nil { // run challenge step
		return err
	}
	return abstract.Read(dp.pubrand, data, dp.suite)
}
예제 #9
0
func decodeFromB64(buf []byte) abstract.Point {
	suite := ed25519.NewAES128SHA256Ed25519(true)

	str := string(buf)
	decodedBytes, _ := hex.DecodeString(str)
	P := suite.Point()
	decoded := bytes.NewBuffer(decodedBytes)

	_ = abstract.Read(decoded, &P, suite)
	return P
}
예제 #10
0
// Loads only the public key from disk.
func SchnorrLoadPubkey(path string, suite abstract.Suite) (SchnorrPublicKey, error) {

	fcontents, err := ioutil.ReadFile(path)
	if err != nil {
		return SchnorrPublicKey{}, err
	}
	buf := bytes.NewBuffer(fcontents)
	kv := SchnorrPublicKey{}
	err2 := abstract.Read(buf, &kv, suite)

	return kv, err2
}
예제 #11
0
// Decodes a message received.
// NOTE: In order to be encoded properly, public polynomials need to be
// initialized with the right group and minimum number of shares.
func (msg *RequestInsuranceMessage) UnmarshalBinary(data []byte) (*RequestInsuranceMessage, error) {
	msg.PubCommit = new(poly.PubPoly)
	msg.PubCommit.Init(INSURE_GROUP, TSHARES, nil)
	msg.PubKey = KEY_SUITE.Point()
	msg.Share = INSURE_GROUP.Secret().Pick(random.Stream)
	msg.ShareNumber = nist.NewInt(int64(0), big.NewInt(int64(math.MaxInt64)))
	b := bytes.NewBuffer(data)
	err := abstract.Read(b, msg, INSURE_GROUP)
	if err != nil {
		panic(err)
	}
	return msg, err
	//	return 	msg, protobuf.Decode(data, msg)

}
예제 #12
0
파일: deniable.go 프로젝트: Liamsi/crypto
// Get the next public random challenge.
func (dv *deniableVerifier) PubRand(data ...interface{}) error {

	// Signal that we need the next challenge
	dv.done <- false

	// Wait for it
	chal := <-dv.inbox

	// Produce the appropriate publicly random stream
	dv.pubrand = dv.suite.Cipher(chal)
	if err := abstract.Read(dv.pubrand, data, dv.suite); err != nil {
		return err
	}

	// Get the next proof message
	dv.getProof()
	return nil
}
예제 #13
0
/* 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
}
예제 #14
0
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
}
예제 #15
0
파일: hash.go 프로젝트: Liamsi/crypto
// Get private randomness
func (c *hashProver) PriRand(data ...interface{}) {
	if err := abstract.Read(c.prirand, data, c.suite); err != nil {
		panic("error reading random stream: " + err.Error())
	}
}
예제 #16
0
파일: hash.go 프로젝트: Liamsi/crypto
// Get public randomness that depends on every bit in the proof so far.
func (c *hashVerifier) PubRand(data ...interface{}) error {
	c.consumeMsg() // Stir in newly-read data
	return abstract.Read(c.pubrand, data, c.suite)
}
예제 #17
0
파일: hash.go 프로젝트: Liamsi/crypto
// Read structured data from the proof
func (c *hashVerifier) Get(message interface{}) error {
	return abstract.Read(&c.proof, message, c.suite)
}
예제 #18
0
파일: deniable.go 프로젝트: Liamsi/crypto
// Get private randomness
func (dp *deniableProver) PriRand(data ...interface{}) {
	if err := abstract.Read(dp.prirand, data, dp.suite); err != nil {
		panic("error reading random stream: " + err.Error())
	}
}
예제 #19
0
파일: deniable.go 프로젝트: Liamsi/crypto
// Read structured data from the proof
func (dv *deniableVerifier) Get(message interface{}) error {
	return abstract.Read(dv.prbuf, message, dv.suite)
}
예제 #20
0
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
		}
	}
}
예제 #21
0
/* 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
		}
	}

}
예제 #22
0
파일: hash.go 프로젝트: Liamsi/crypto
// Get public randomness that depends on every bit in the proof so far.
func (c *hashProver) PubRand(data ...interface{}) error {
	c.consumeMsg()
	return abstract.Read(c.pubrand, data, c.suite)
}