func (n *noise255ctx) mac(keystream, ciphertext, authtext []byte) [16]byte { var macKey [32]byte var tag [16]byte copy(macKey[:], keystream) poly1305.Sum(&tag, n.authData(ciphertext, authtext), &macKey) return tag }
// Seal appends an encrypted and authenticated copy of message to out, which // must not overlap message. The key and nonce pair must be unique for each // distinct message and the output will be Overhead bytes longer than message. func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte { var subKey [32]byte var counter [16]byte setup(&subKey, &counter, nonce, key) // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since // Salsa20 works with 64-byte blocks, we also generate 32 bytes of // keystream as a side effect. var firstBlock [64]byte salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey) var poly1305Key [32]byte copy(poly1305Key[:], firstBlock[:]) out = out[len(out):] outLen := len(message) + poly1305.TagSize if cap(out) >= outLen { out = out[:outLen] } else if out == nil { out = make([]byte, outLen) } else { for i := 0; i < outLen; i++ { out = append(out, 0) } } // We XOR up to 32 bytes of message with the keystream generated from // the first block. firstMessageBlock := message if len(firstMessageBlock) > 32 { firstMessageBlock = firstMessageBlock[:32] } tagOut := out out = out[poly1305.TagSize:] for i, x := range firstMessageBlock { out[i] = firstBlock[32+i] ^ x } message = message[len(firstMessageBlock):] ciphertext := out out = out[len(firstMessageBlock):] // Now encrypt the rest. counter[8] = 1 salsa.XORKeyStream(out, message, &counter, &subKey) var tag [poly1305.TagSize]byte poly1305.Sum(&tag, ciphertext, &poly1305Key) copy(tagOut, tag[:]) return tagOut }