Example #1
0
// DecryptAndVerify returns the chacha20 decrypted messages.
// An error is returned when the poly1305 message authenticator (seal) could not be verified.
// Nonce should be 8 byte.
func DecryptAndVerify(key, nonce, message []byte, mac [16]byte, add []byte) ([]byte, error) {

	chacha20, err := chacha20.New(key, nonce)
	if err != nil {
		panic(err)
	}

	// poly1305 key is chacha20 over 32 zeros
	var poly1305Key [32]byte
	var chacha20KeyOut = make([]byte, 64)
	var zeros = make([]byte, 64)
	chacha20.XORKeyStream(chacha20KeyOut, zeros)
	copy(poly1305Key[:], chacha20KeyOut)

	var chacha20Out = make([]byte, len(message))
	var poly1305Out [16]byte

	// poly1305 byte order
	// - add bytes up to mod 16 (if available)
	// - message up to mod 16
	// - number of add bytes up to mod 8
	// - number of message bytes up to mod 8
	var poly1305In []byte
	if len(add) > 0 {
		poly1305In = AddBytes(poly1305In, add, 16)
	}

	poly1305In = AddBytes(poly1305In, message, 16)
	addLength := make([]byte, 8)
	msgLength := make([]byte, 8)
	binary.LittleEndian.PutUint64(addLength, uint64(len(add)))
	binary.LittleEndian.PutUint64(msgLength, uint64(len(message)))

	poly1305In = AddBytes(poly1305In, addLength, 8)
	poly1305In = AddBytes(poly1305In, msgLength, 8)

	poly1305.Sum(&poly1305Out, poly1305In, &poly1305Key)

	if poly1305.Verify(&mac, poly1305In, &poly1305Key) == false {
		return nil, errors.New("MAC not equal: " + hex.EncodeToString(poly1305Out[:]) + " != " + hex.EncodeToString(mac[:]))
	}

	chacha20.XORKeyStream(chacha20Out, message)
	return chacha20Out, nil
}
Example #2
0
// EncryptAndSeal returns the chacha20 encrypted message and poly1305 message authentictor (also refered as seals)
// Nonce should be 8 byte
func EncryptAndSeal(key, nonce, message []byte, add []byte) ([]byte /*encrypted*/, [16]byte /*mac*/, error) {

	chacha20, err := chacha20.New(key, nonce)
	if err != nil {
		panic(err)
	}

	// poly1305 key is chacha20 over 32 zeros
	var poly1305Key [32]byte
	var chacha20KeyOut = make([]byte, 64)
	var zeros = make([]byte, 64)
	chacha20.XORKeyStream(chacha20KeyOut, zeros)
	copy(poly1305Key[:], chacha20KeyOut)

	var chacha20Out = make([]byte, len(message))
	var poly1305Out [16]byte
	chacha20.XORKeyStream(chacha20Out, message)

	var poly1305In []byte
	if len(add) > 0 {
		poly1305In = AddBytes(poly1305In, add, 16)
	}

	poly1305In = AddBytes(poly1305In, chacha20Out, 16)
	addLength := make([]byte, 8)
	msgLength := make([]byte, 8)
	binary.LittleEndian.PutUint64(addLength, uint64(len(add)))
	binary.LittleEndian.PutUint64(msgLength, uint64(len(message)))

	poly1305In = AddBytes(poly1305In, addLength, 8)
	poly1305In = AddBytes(poly1305In, msgLength, 8)

	poly1305.Sum(&poly1305Out, poly1305In, &poly1305Key)

	return chacha20Out, poly1305Out, nil
}