Esempio n. 1
0
File: enc.go Progetto: Liamsi/crypto
// 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
}
Esempio n. 2
0
File: enc.go Progetto: Liamsi/crypto
// Encrypt a message for reading by any member of an explit anonymity set.
// The caller supplies one or more keys representing the anonymity set.
// If the provided set contains only one public key,
// this reduces to conventional single-receiver public-key encryption.
//
// If hide is true,
// Encrypt will produce a uniformly random-looking byte-stream,
// which reveals no metadata other than message length
// to anyone unable to decrypt the message.
// The provided abstract.Suite must support
// uniform-representation encoding of public keys for this to work.
//
func Encrypt(suite abstract.Suite, rand cipher.Stream, message []byte,
	anonymitySet Set, hide bool) []byte {

	xb, hdr := encryptKey(suite, rand, anonymitySet, hide)
	cipher := suite.Cipher(xb)

	// We now know the ciphertext layout
	hdrhi := 0 + len(hdr)
	msghi := hdrhi + len(message)
	machi := msghi + cipher.KeySize()
	ciphertext := make([]byte, machi)
	copy(ciphertext, hdr)

	// Now encrypt and MAC the message based on the master secret
	ctx := ciphertext[hdrhi:msghi]
	mac := ciphertext[msghi:machi]
	cipher.Message(ctx, message, ctx)
	cipher.Partial(mac, nil, nil)
	return ciphertext
}