Пример #1
0
// ReadPubKey will read the file and decrypt the public key inside
// It takes a suite to decrypt and a file name
// Returns the public key, whatever text is in front and an error if anything went wrong
func ReadPubKey(suite abstract.Suite, fileName string) (abstract.Point, string, error) {

	public := suite.Point()
	// Opening files
	pubFile, err := os.Open(fileName)
	if err != nil {
		return nil, "", err
	}
	defer pubFile.Close()

	// read the string before
	by, err := ioutil.ReadAll(pubFile)
	if err != nil {
		return nil, "", errors.New(fmt.Sprintf("Error reading the whole file  %s", err))
	}
	splits := strings.Split(string(by), " ")
	if len(splits) != 2 {
		return nil, "", errors.New(fmt.Sprintf("Error reading pub key file format is not correct (val space val)"))
	}

	before := splits[0]
	key := strings.NewReader(splits[1])

	// Some readings
	public, err = ReadPub64(suite, key)
	if err != nil {
		return nil, "", errors.New(fmt.Sprintf("Error reading the public key itself: %s", err))
	}

	return public, before, nil

}
Пример #2
0
func benchSign(suite abstract.Suite, pub []abstract.Point, pri abstract.Secret,
	niter int) {
	rand := suite.Cipher([]byte("example"))
	for i := 0; i < niter; i++ {
		Sign(suite, rand, benchMessage, Set(pub), nil, 0, pri)
	}
}
Пример #3
0
// ShuffleDecrypt performs a shuffle and partial decyption of the given ciphertexts, producing correctness
// proofs in the process
func ShuffleDecrypt(suite abstract.Suite, ciphertexts []*elgamal.CipherText,
	pks []*elgamal.PubKey, sk *elgamal.PriKey, nonce string, position int) (*VerifiableShuffle, error) {
	amount := len(ciphertexts)
	if amount == 0 {
		panic("Can't shuffle 0 ciphertexts")
	}

	c1, c2 := elgamal.Unpack(ciphertexts)

	// The ciphertexts are encrypted against these public keys; it still includes ours
	// The proof of the shuffle will also be w.r.t. this public key
	sumpk := elgamal.SumKeys(pks[position:])

	// Do the shuffle, create a proof of its correctness
	shuffledC1, shuffledC2, prover := shuffle.Shuffle(suite, sumpk.Base, sumpk.Key, c1, c2, suite.Cipher(nil))
	shuffleProof, err := proof.HashProve(suite, "ElGamalShuffle"+nonce, suite.Cipher(nil), prover)
	if err != nil {
		return nil, err
	}
	shuffled := elgamal.Pack(shuffledC1, shuffledC2)

	// Do the partial decryption, create a proof of its correctness
	decryptionProofs, decrypted := make([][]byte, amount), make([]*elgamal.CipherText, amount)
	for i := range shuffledC1 {
		decrypted[i], decryptionProofs[i], err = sk.PartialProofDecrypt(shuffled[i], nonce)
		if err != nil {
			return nil, err
		}
	}

	return &VerifiableShuffle{shuffled, decrypted, decryptionProofs, shuffleProof}, nil
}
Пример #4
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
}
Пример #5
0
// Create new signing node that incorporates a given private key
func NewKeyedNode(hn coconet.Host, suite abstract.Suite, PrivKey abstract.Secret) *Node {
	sn := &Node{Host: hn, suite: suite, PrivKey: PrivKey}
	sn.PubKey = suite.Point().Mul(nil, sn.PrivKey)

	sn.peerKeys = make(map[string]abstract.Point)

	sn.closed = make(chan error, 20)
	sn.done = make(chan int, 10)
	sn.commitsDone = make(chan int, 10)
	sn.viewChangeCh = make(chan string, 0)

	sn.RoundCommits = make(map[int][]*SigningMessage)
	sn.RoundResponses = make(map[int][]*SigningMessage)

	sn.FailureRate = 0
	h := fnv.New32a()
	h.Write([]byte(hn.Name()))
	seed := h.Sum32()
	sn.Rand = rand.New(rand.NewSource(int64(seed)))
	sn.Host.SetSuite(suite)
	sn.VoteLog = NewVoteLog()
	sn.Actions = make(map[int][]*Vote)
	sn.RoundsPerView = 0
	sn.Rounds = make(map[int]Round)
	sn.MaxWait = 50 * time.Second
	return sn
}
Пример #6
0
// Decrypt a message encrypted for a particular anonymity set.
// Returns the cleartext message on success, or an error on failure.
//
// The caller provides the anonymity set for which the message is intended,
// and the private key corresponding to one of the public keys in the set.
// Decrypt verifies that the message is encrypted correctly for this set -
// in particular, that it could be decrypted by ALL of the listed members -
// before returning successfully with the decrypted message.
// This verification ensures that a malicious sender
// cannot de-anonymize a receiver by constructing a ciphertext incorrectly
// so as to be decryptable by only some members of the set.
// As a side-effect, this verification also ensures plaintext-awareness:
// that is, it is infeasible for a sender to construct any ciphertext
// that will be accepted by the receiver without knowing the plaintext.
//
func Decrypt(suite abstract.Suite, ciphertext []byte, anonymitySet Set,
	mine int, privateKey abstract.Secret, hide bool) ([]byte, error) {

	// Decrypt and check the encrypted key-header.
	xb, hdrlen, err := decryptKey(suite, ciphertext, anonymitySet,
		mine, privateKey, hide)
	if err != nil {
		return nil, err
	}

	// Determine the message layout
	cipher := suite.Cipher(xb)
	maclen := cipher.KeySize()
	if len(ciphertext) < hdrlen+maclen {
		return nil, errors.New("ciphertext too short")
	}
	hdrhi := hdrlen
	msghi := len(ciphertext) - maclen

	// Decrypt the message and check the MAC
	ctx := ciphertext[hdrhi:msghi]
	mac := ciphertext[msghi:]
	msg := make([]byte, len(ctx))
	cipher.Message(msg, ctx, ctx)
	cipher.Partial(mac, mac, nil)
	if subtle.ConstantTimeAllEq(mac, 0) == 0 {
		return nil, errors.New("invalid ciphertext: failed MAC check")
	}
	return msg, nil
}
Пример #7
0
func verifyMessage(suite abstract.Suite, m interface{}, hash1 []byte) error {

	// Make a copy of the signature
	x := reflect.ValueOf(m).Elem().FieldByName("Sig")
	sig := reflect.New(x.Type()).Elem()
	sig.Set(x)

	// Reset signature field
	reflect.ValueOf(m).Elem().FieldByName("Sig").Set(reflect.ValueOf(crypto.SchnorrSig{})) // XXX: hack

	// Marshal ...
	mb, err := network.MarshalRegisteredType(m)
	if err != nil {
		return err
	}

	// ... and hash message
	hash2, err := crypto.HashBytes(suite.Hash(), mb)
	if err != nil {
		return err
	}

	// Copy back original signature
	reflect.ValueOf(m).Elem().FieldByName("Sig").Set(sig) // XXX: hack

	// Compare hashes
	if !bytes.Equal(hash1, hash2) {
		return errors.New("Message has a different hash than the given one")
	}

	return nil
}
Пример #8
0
func NewNode(hn coconet.Host, suite abstract.Suite, random cipher.Stream) *Node {
	sn := &Node{Host: hn, suite: suite}
	msgSuite = suite
	sn.PrivKey = suite.Secret().Pick(random)
	sn.PubKey = suite.Point().Mul(nil, sn.PrivKey)

	sn.peerKeys = make(map[string]abstract.Point)
	sn.Rounds = make(map[int]*Round)

	sn.closed = make(chan error, 20)
	sn.done = make(chan int, 10)
	sn.commitsDone = make(chan int, 10)
	sn.viewChangeCh = make(chan string, 0)

	sn.FailureRate = 0
	h := fnv.New32a()
	h.Write([]byte(hn.Name()))
	seed := h.Sum32()
	sn.Rand = rand.New(rand.NewSource(int64(seed)))
	sn.Host.SetSuite(suite)
	sn.VoteLog = NewVoteLog()
	sn.Actions = make(map[int][]*Vote)
	sn.RoundsPerView = 100
	return sn
}
Пример #9
0
// Retrieve an object in a Merkle tree,
// validating the entire path in the process.
// Returns a slice of a buffer obtained from HashGet.Get(),
// which might be shared and should be considered read-only.
func MerkleGet(suite abstract.Suite, root []byte, path MerklePath,
	ctx HashGet) ([]byte, error) {

	// Follow pointers through intermediate levels
	blob := root
	for i := range path.Ptr {
		beg := path.Ptr[i]
		end := beg + suite.HashLen()
		if end > len(blob) {
			return nil, errors.New("bad Merkle tree pointer offset")
		}
		id := HashId(blob[beg:end])
		b, e := ctx.Get(id) // Lookup the next-level blob
		if e != nil {
			return nil, e
		}
		blob = b
	}

	// Validate and extract the actual object
	beg := path.Ofs
	end := beg + path.Len
	if end > len(blob) {
		return nil, errors.New("bad Merkle tree object offset/length")
	}
	return blob[beg:end], nil
}
Пример #10
0
func NewFile(suite abstract.Suite, path string) (*File, error) {
	f, err := os.Open(path)
	if err != nil {
		log.Fatal("Failed opening file", path, err)
	}
	defer f.Close()

	fi, err := f.Stat()
	if err != nil {
		return nil, err
	}
	blocks := (fi.Size() + BlockSize - 1) / BlockSize

	x := &File{
		Name:   path,
		Hashes: make(map[string]int64, blocks),
	}

	for i := 0; int64(i) < blocks; i++ {
		tmp := make([]byte, BlockSize)
		_, err := f.Read(tmp)
		if err != nil {
			log.Fatal("Failed reading file", err)
		}
		h := suite.Hash()
		h.Write(tmp)
		x.Hashes[string(h.Sum(nil))] = int64((i * BlockSize))
	}

	return x, nil
}
Пример #11
0
// DefaultConstructors gives a default constructor for protobuf out of the global suite
func DefaultConstructors(suite abstract.Suite) protobuf.Constructors {
	constructors := make(protobuf.Constructors)
	var point abstract.Point
	var secret abstract.Scalar
	constructors[reflect.TypeOf(&point).Elem()] = func() interface{} { return suite.Point() }
	constructors[reflect.TypeOf(&secret).Elem()] = func() interface{} { return suite.Scalar() }
	return constructors
}
Пример #12
0
func newHashProver(suite abstract.Suite, protoName string,
	rand abstract.Cipher) *hashProver {
	var sc hashProver
	sc.suite = suite
	sc.pubrand = suite.Cipher([]byte(protoName))
	sc.prirand = rand
	return &sc
}
Пример #13
0
func ElGamalDecrypt(suite abstract.Suite, prikey abstract.Secret, K, C abstract.Point) (
	M abstract.Point) {

	// ElGamal-decrypt the ciphertext (K,C) to reproduce the message.
	S := suite.Point().Mul(K, prikey) // regenerate shared secret
	M = suite.Point().Sub(C, S)       // use to un-blind the message
	return
}
Пример #14
0
// VerifySignature verifies if the challenge and the secret (from the response phase) form a
// correct signature for this message using the aggregated public key.
func VerifySignature(suite abstract.Suite, msg []byte, public abstract.Point, challenge, secret abstract.Scalar) error {
	// recompute the challenge and check if it is the same
	commitment := suite.Point()
	commitment = commitment.Add(commitment.Mul(nil, secret), suite.Point().Mul(public, challenge))

	return verifyCommitment(suite, msg, commitment, challenge)

}
Пример #15
0
func ElGamalDecrypt(suite abstract.Suite, prikey abstract.Secret, K, C abstract.Point) (
	message []byte, err error) {

	// ElGamal-decrypt the ciphertext (K,C) to reproduce the message.
	S := suite.Point().Mul(K, prikey) // regenerate shared secret
	M := suite.Point().Sub(C, S)      // use to un-blind the message
	message, err = M.Data()           // extract the embedded data
	return
}
Пример #16
0
// Read a secret in hexadceimal from string
func ReadSecretHex(suite abstract.Suite, str string) (abstract.Secret, error) {
	enc, err := hex.DecodeString(str)
	if err != nil {
		return nil, err
	}
	sec := suite.Secret()
	err = sec.UnmarshalBinary(enc)
	return sec, err
}
/* The servergenerateresponse function is fairly self explanatory - this function provides an answer
   to the challenge message provided by the user. */
func ServerGenerateResponse(suite abstract.Suite, challenge WISchnorrChallengeMessage, privateParameters WISchnorrBlindPrivateParams, privKey SchnorrKeyset) WISchnorrResponseMessage {

	c := suite.Secret()
	c.Sub(challenge.E, privateParameters.D)
	r := suite.Secret()
	r.Mul(c, privKey.X).Sub(privateParameters.U, r)

	return WISchnorrResponseMessage{r, c, privateParameters.S, privateParameters.D}
}
Пример #18
0
// ReadScalarHex reads a scalar in hexadecimal from string
func ReadScalarHex(suite abstract.Suite, str string) (abstract.Scalar, error) {
	enc, err := hex.DecodeString(str)
	if err != nil {
		return nil, err
	}
	s := suite.Scalar()
	err = s.UnmarshalBinary(enc)
	return s, err
}
Пример #19
0
// ReadPubHex reads a hexadecimal representation of a public point and convert it to the
// right struct
func ReadPubHex(suite abstract.Suite, s string) (abstract.Point, error) {
	encoded, err := hex.DecodeString(s)
	if err != nil {
		return nil, err
	}
	point := suite.Point()
	err = point.UnmarshalBinary(encoded)
	return point, err
}
Пример #20
0
// generate keys for the tree
func (t *Tree) GenKeys(suite abstract.Suite, rand abstract.Cipher) {
	t.TraverseTree(func(t *Tree) {
		PrivKey := suite.Secret().Pick(rand)
		PubKey := suite.Point().Mul(nil, PrivKey)
		prk, _ := PrivKey.MarshalBinary()
		pbk, _ := PubKey.MarshalBinary()
		t.PriKey = string(hex.EncodeToString(prk))
		t.PubKey = string(hex.EncodeToString(pbk))
	})
}
Пример #21
0
// GetSharedSecret returns the shared secret, as in the Verdict hash-based construction, for the given public and
// private keys
func GetSharedSecret(pk *PubKey, sk *PriKey) (abstract.Secret, abstract.Point) {
	var suite abstract.Suite
	suite = crypto.Suite
	point := suite.Point().Mul(pk.Elem, sk.secret)

	r := crypto.HashKDF(point)
	R := suite.Point().Mul(crypto.Generator, r)

	return r, R
}
Пример #22
0
func signH1pre(suite abstract.Suite, linkScope []byte, linkTag abstract.Point,
	message []byte) abstract.Cipher {
	H1pre := suite.Cipher(message) // m
	if linkScope != nil {
		H1pre.Write(linkScope) // L
		tag, _ := linkTag.MarshalBinary()
		H1pre.Write(tag) // ~y
	}
	return H1pre
}
Пример #23
0
// 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
	}
}
Пример #24
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
}
Пример #25
0
// computeSubtreeAggregate will compute the aggregate subtree public key for
// each node of the tree.
// root is the root of the subtree we want to compute the aggregate for
// recursive function so it will go down to the leaves then go up to the root
// Return the aggregate sub tree public key for this root (and compute each sub
// aggregate public key for each of the children).
func (t *Tree) computeSubtreeAggregate(suite abstract.Suite, root *TreeNode) abstract.Point {
	aggregate := suite.Point().Add(suite.Point().Null(), root.ServerIdentity.Public)
	// DFS search
	for _, ch := range root.Children {
		aggregate = aggregate.Add(aggregate, t.computeSubtreeAggregate(suite, ch))
	}

	// sets the field
	root.PublicAggregateSubTree = aggregate
	return aggregate
}
Пример #26
0
func signH1(suite abstract.Suite, H1pre abstract.Cipher, PG, PH abstract.Point) abstract.Secret {
	H1 := H1pre.Clone()
	PGb, _ := PG.MarshalBinary()
	H1.Write(PGb)
	if PH != nil {
		PHb, _ := PH.MarshalBinary()
		H1.Write(PHb)
	}
	H1.Message(nil, nil, nil) // finish message absorption
	return suite.Secret().Pick(H1)
}
// (Server side) This function reads the collective challenge
// from the wire, generates and serializes a response
// to that as a raw "secret"
func SchnorrMUnmarshallCCComputeResponse(suite abstract.Suite,
	kv SchnorrKeyset,
	privatecommit SchnorrMPrivateCommitment,
	cc []byte) SchnorrMResponse {
	hct := suite.Cipher(cc)
	c := suite.Secret().Pick(hct)
	r := suite.Secret()
	r.Mul(c, kv.X).Sub(privatecommit.V, r)

	return SchnorrMResponse{r}
}
Пример #28
0
func newHashVerifier(suite abstract.Suite, protoName string,
	proof []byte) *hashVerifier {
	var c hashVerifier
	if _, err := c.proof.Write(proof); err != nil {
		panic("Buffer.Write failed")
	}
	c.suite = suite
	c.prbuf = c.proof.Bytes()
	c.pubrand = suite.Cipher([]byte(protoName))
	return &c
}
Пример #29
0
func hash(suite abstract.Suite, r abstract.Point, msg []byte) (abstract.Scalar, error) {
	rBuf, err := r.MarshalBinary()
	if err != nil {
		return nil, err
	}
	cipher := suite.Cipher(rBuf)
	cipher.Message(nil, nil, msg)
	// (re)compute challenge (e)
	e := suite.Scalar().Pick(cipher)

	return e, nil
}
Пример #30
0
func newHost(suite abstract.Suite, rand cipher.Stream, hostname string) *host {
	h := &host{}
	h.name = hostname
	h.log.init(suite)

	h.pri = suite.Secret().Pick(rand)
	h.pub = suite.Point().Mul(nil, h.pri)
	h.id = abstract.HashBytes(suite, h.pub.Encode())

	h.peers = make(map[string]*peer)
	h.trees = make(map[string]*treeNode)

	return h
}