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 <[email protected]>
>> 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/cryptopp-users/bbe5ba70-1d8b-4bdd-bfc0-4c176e420da2n%40googlegroups.com.