And if you're interested about original functions here you are:
func writeWithPadding(p *poly1305.MAC, b []byte) { p.Write(b) if rem := len(b) % 16; rem != 0 { var buf [16]byte padLen := 16 - rem p.Write(buf[:padLen]) } } func writeUint64(p *poly1305.MAC, n int) { var buf [8]byte binary.LittleEndian.PutUint64(buf[:], uint64(n)) p.Write(buf[:]) } func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte { ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize) ciphertext, tag := out[:len(plaintext)], out[len(plaintext):] if alias.InexactOverlap(out, plaintext) { panic("chacha20poly1305: invalid buffer overlap") } var polyKey [32]byte s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce) s.XORKeyStream(polyKey[:], polyKey[:]) s.SetCounter(1) // set the counter to 1, skipping 32 bytes s.XORKeyStream(ciphertext, plaintext) p := poly1305.New(&polyKey) writeWithPadding(p, additionalData) writeWithPadding(p, ciphertext) writeUint64(p, len(additionalData)) writeUint64(p, len(plaintext)) p.Sum(tag[:0]) return ret } func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { tag := ciphertext[len(ciphertext)-16:] ciphertext = ciphertext[:len(ciphertext)-16] var polyKey [32]byte s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce) s.XORKeyStream(polyKey[:], polyKey[:]) s.SetCounter(1) // set the counter to 1, skipping 32 bytes p := poly1305.New(&polyKey) writeWithPadding(p, additionalData) writeWithPadding(p, ciphertext) writeUint64(p, len(additionalData)) writeUint64(p, len(ciphertext)) ret, out := sliceForAppend(dst, len(ciphertext)) if alias.InexactOverlap(out, ciphertext) { panic("chacha20poly1305: invalid buffer overlap") } if !p.Verify(tag) { for i := range out { out[i] = 0 } return nil, errOpen } s.XORKeyStream(out, ciphertext) return ret, nil } You can find the source files at https://cs.opensource.google/go/x/crypto/+/refs/tags/v0.14.0:chacha20poly1305/ . The reported functions can be found at https://cs.opensource.google/go/x/crypto/+/refs/tags/v0.14.0:chacha20poly1305/chacha20poly1305_generic.go . On Wednesday, November 8, 2023 at 4:25:07 PM UTC+1 Lucas Marchetti wrote: > Hi Jeff, thanks for the reply. > > I've deleted the other messages cause I've found the solution by my own. > > So, I've tested the whole thing with a test vector as you said and I found > out, looking to Golang library's source code, that the output given to me > was: *Nonce + Ciphertext + MAC*. > You were right: the last one was actually an authentication tag. > > I decided to reimplement manually the *Seal *and *Open* functions > removing the MAC generation and append. > I think I'm gonna implement it back in a bit: I prefer to go without > authenticated encryption at the moment. > > With a custom function I'm now able to remove the Nonce too and get the > clear ciphertext that I can finally decrypt using Crypto++. > > Here is the source code of the changed functions. > > func sliceForAppend(in []byte, n int) (head, tail []byte) { > > if total := len(in) + n; cap(in) >= total { > > head = in[:total] > > } else { > > head = make([]byte, total) > copy(head, in) > > } > > tail = head[len(in):] > return > > } > > func sealGeneric(dst, nonce, plaintext []byte) []byte { > > ret, out := sliceForAppend(dst, len(plaintext)) > ciphertext, _ := out[:len(plaintext)], out[len(plaintext):] > > var polyKey [32]byte > s, _ := chacha20.NewUnauthenticatedCipher(key[:], nonce) > s.XORKeyStream(polyKey[:], polyKey[:]) > s.SetCounter(1) // set the counter to 1, skipping 32 bytes > s.XORKeyStream(ciphertext, plaintext) > > return ret > > } > > func openGeneric(dst, nonce, ciphertext []byte) ([]byte, error) { > > var polyKey [32]byte > s, _ := chacha20.NewUnauthenticatedCipher(key[:], nonce) > s.XORKeyStream(polyKey[:], polyKey[:]) > s.SetCounter(1) // set the counter to 1, skipping 32 bytes > > ret, out := sliceForAppend(dst, len(ciphertext)) > > s.XORKeyStream(out, ciphertext) > > return ret, nil > > } > > That's how I call encryption and decryption: > > func EncrytionWithChaChaPoly() { > > msg := make([]byte, 0) > msg = append(msg, > > > 0x4c,0x61,0x64,0x69,0x65,0x73,0x20,0x61,0x6e,0x64,0x20,0x47,0x65,0x6e,0x74,0x6c, > > 0x65,0x6d,0x65,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x63,0x6c,0x61,0x73, > > 0x73,0x20,0x6f,0x66,0x20,0x27,0x39,0x39,0x3a,0x20,0x49,0x66,0x20,0x49,0x20,0x63, > > 0x6f,0x75,0x6c,0x64,0x20,0x6f,0x66,0x66,0x65,0x72,0x20,0x79,0x6f,0x75,0x20,0x6f, > > 0x6e,0x6c,0x79,0x20,0x6f,0x6e,0x65,0x20,0x74,0x69,0x70,0x20,0x66,0x6f,0x72,0x20, > > 0x74,0x68,0x65,0x20,0x66,0x75,0x74,0x75,0x72,0x65,0x2c,0x20,0x73,0x75,0x6e,0x73, > > 0x63,0x72,0x65,0x65,0x6e,0x20,0x77,0x6f,0x75,0x6c,0x64,0x20,0x62,0x65,0x20,0x69, > 0x74,0x2e, > > ) > > nonce := make([]byte, 0) > nonce = append(nonce, > 0x07,0x00,0x00,0x00,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x07,0x00,0x00,0x00,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47) > > fmt.Println("Nonce:") > fmt.Println(nonce) > > // Encrypt the message and append the ciphertext to the nonce. > encryptedMsg = sealGeneric(nonce, nonce, msg) > > fmt.Println("\nCipher:") > fmt.Println(encryptedMsg) > fmt.Println(len(encryptedMsg)) > > } > > func DecryptionWithChaChaPoly(){ > > if len(encryptedMsg) < aead.NonceSize() { > panic("ciphertext too short") > } > > // Split nonce and ciphertext. > nonce, ciphertext := encryptedMsg[:aead.NonceSize()], > encryptedMsg[aead.NonceSize():] > > // Decrypt the message and check it wasn't tampered with. > plaintext, err := openGeneric(nil, nonce, ciphertext) > > if err != nil { > panic(err) > } > > fmt.Println("\nRecover:") > fmt.Printf("%s\n", plaintext) > > } > > Tell me if I did something wrong. > > Thanks in advance. > On Sunday, November 5, 2023 at 8:26:27 PM UTC+1 Jeffrey Walton wrote: > >> On Sun, Nov 5, 2023 at 4:38 AM Lucas Marchetti <lmarch...@gmail.com> >> wrote: >> >>> Sorry, seeing now that I've linked the wrong Golang library, here it is: >>> https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305 >>> >>> On Sunday, November 5, 2023 at 10:10:44 AM UTC+1 Lucas Marchetti wrote: >>> >>>> I've just made a test encrypting the string "Hello World!" with both >>>> client and server functions and these are the results. >>>> >>>> [image: Screenshot 2023-11-05 100312.png] >>>> >>>> Both green-highlighted bytes corresponds to the input string but, as >>>> you can see, there is a different padding that I'm 100% sure is the source >>>> of the problem. >>>> >>>> On Saturday, November 4, 2023 at 7:39:31 PM UTC+1 Lucas Marchetti wrote: >>>> >>>>> Good evening. >>>>> >>>>> I'm building a client-server application and I want to implement a >>>>> XChaCha20 communication over TCP after performing key exchange. >>>>> >>>>> What I'm issuing is a bad decryption output like the one shown in the >>>>> pic. >>>>> >>>>> [image: Screenshot 2023-11-04 193625.png] >>>>> >>>>> I'm currently using crypto++ 8.9 in the client-side and >>>>> https://pkg.go.dev/golang.org/x/crypto/chacha20 in the server-side. >>>>> >>>>> Is that something related to sealing or authentication implemented in >>>>> the Golang library? >>>>> >>>>> Functions that I'm using: >>>>> >>>>> [image: Screenshot 2023-11-04 193751.png] >>>>> >>>>> [image: Screenshot 2023-11-04 193832.png] >>>>> >>>>> Thanks in advance. >>>>> >>>> If you want help, then you should provide source code and post a link >> to a minimal reproducer. Pictures are not helpful. >> >> The wiki is full of little working examples. For example, < >> https://www.cryptopp.com/wiki/XChaCha20> and < >> https://www.cryptopp.com/wiki/XChaCha20Poly1305>. >> >> You should also probably start with test vectors, and then move onto >> arbitrary messages once things work with test vectors. Here are the ones >> Crypto++ uses for XChaCha: < >> https://github.com/weidai11/cryptopp/blob/master/TestVectors/chacha.txt>. >> And here are the ones for ChaCha20/Poly1305: < >> https://github.com/weidai11/cryptopp/blob/master/TestVectors/chacha20poly1305.txt#L4669 >> >. >> >> I'm just guessing, but the 16-bytes of garbage at the end of the >> [encrypted] message may be a Poly1305 authentication tag. But it is just a >> guess. The go documentation should tell you what you have. >> >> Jeff >> > -- You received this message because you are subscribed to the Google Groups "Crypto++ Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/cryptopp-users/bbe5ba70-1d8b-4bdd-bfc0-4c176e420da2n%40googlegroups.com.