Maison >développement back-end >Golang >Utilisez cipher.AEAD.Seal() pour afficher l'utilisation de la mémoire

Utilisez cipher.AEAD.Seal() pour afficher l'utilisation de la mémoire

WBOY
WBOYavant
2024-02-06 10:03:03996parcourir

使用 cipher.AEAD.Seal() 查看内存使用情况

Contenu de la question

J'utilise l'implémentation ChaCha20-Poly1305 de Go pour crypter des données, mais lorsque je crypte certains fichiers volumineux, l'utilisation de la mémoire est plus élevée que prévu. Pour autant que je sache, l'implémentation du chiffrement AEAD de Go signifie que nous devons conserver l'intégralité des données en mémoire pour créer le hachage, mais l'utilisation de la mémoire est deux fois supérieure à la taille du texte en clair.

Le petit programme suivant essayant de chiffrer 4 Gio de données le met en évidence (dans un programme réel, keynonce ne devrait pas être vide) :

package main

import (
  "os"
  "fmt"
  "runtime"
  "golang.org/x/crypto/chacha20poly1305"
)

func main() {
  showMemUsage("START")

  plaintext := make([]byte, 4 * 1024 * 1024 * 1024) // 4 GiB

  showMemUsage("STAGE 1")

  key := make([]byte, chacha20poly1305.KeySize)
  if cipher, err := chacha20poly1305.New(key); err == nil {
    showMemUsage("STAGE 2")

    nonce := make([]byte, chacha20poly1305.NonceSize)
    cipher.Seal(plaintext[:0], nonce, plaintext, nil)
  }

  showMemUsage("END")
}

func showMemUsage(tag string) {
  var m runtime.MemStats

  runtime.ReadMemStats(&m)
  fmt.Fprintf(os.Stdout, "[%s] Alloc = %v MiB, TotalAlloc = %v MiB\n", tag, m.Alloc / 1024 / 1024, m.TotalAlloc / 1024 / 1024)
}

Selon le code source de crypto/cipher/gcm.go (utilisé à la fois par AES-GCM et ChaCha20-Poly1305), il y a les commentaires suivants :

// To reuse plaintext's storage for the encrypted output, use plaintext[:0]
// as dst. Otherwise, the remaining capacity of dst must not overlap plaintext.
Seal(dst, nonce, plaintext, additionalData []byte) []byte

Cela signifie que je devrais pouvoir réutiliser la mémoire, j'ai essayé de le faire, mais cela n'a aucun effet sur la quantité de mémoire utilisée par mon application - après avoir appelé Seal() nous finissons toujours par utiliser 8 Go de mémoire Can 4 Les Gio de données doivent-ils être chiffrés ?

[START] Alloc = 0 MiB, TotalAlloc = 0 MiB
[STAGE 1] Alloc = 4096 MiB, TotalAlloc = 4096 MiB
[STAGE 2] Alloc = 4096 MiB, TotalAlloc = 4096 MiB
[END] Alloc = 8192 MiB, TotalAlloc = 8192 MiB

S'il réutilise la mémoire (comme indiqué), alors je ne devrais pas m'attendre à une augmentation significative autre que le hachage relativement petit que le chiffrement AEAD ajoute au texte chiffré ?


Bonne réponse


Vous avez oublié de prendre en compte le jeton d'authentification ajouté au texte chiffré. Si vous lui faites de la place dans la dotation initiale, aucune dotation supplémentaire n'est nécessaire :

package main

import (
        "fmt"
        "os"
        "runtime"

        "golang.org/x/crypto/chacha20poly1305"
)

func main() {
        showMemUsage("START")

        plaintext := make([]byte, 4<<30, 4<<30+chacha20poly1305.Overhead)

        showMemUsage("STAGE 1")

        key := make([]byte, chacha20poly1305.KeySize)
        if cipher, err := chacha20poly1305.New(key); err == nil {
                showMemUsage("STAGE 2")

                nonce := make([]byte, chacha20poly1305.NonceSize)
                cipher.Seal(plaintext[:0], nonce, plaintext, nil)
        }

        showMemUsage("END")
}

func showMemUsage(tag string) {
        var m runtime.MemStats

        runtime.ReadMemStats(&m)
        fmt.Fprintf(os.Stdout, "[%s] Alloc = %v MiB, TotalAlloc = %v MiB\n", tag, m.Alloc>>20, m.TotalAlloc>>20)
}

// Output:
// [START] Alloc = 0 MiB, TotalAlloc = 0 MiB
// [STAGE 1] Alloc = 4096 MiB, TotalAlloc = 4096 MiB
// [STAGE 2] Alloc = 4096 MiB, TotalAlloc = 4096 MiB
// [END] Alloc = 4096 MiB, TotalAlloc = 4096 MiB

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer