Heim >Backend-Entwicklung >Golang >Verwenden Sie cipher.AEAD.Seal(), um die Speichernutzung anzuzeigen

Verwenden Sie cipher.AEAD.Seal(), um die Speichernutzung anzuzeigen

WBOY
WBOYnach vorne
2024-02-06 10:03:03996Durchsuche

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

Frageninhalt

Ich verwende die ChaCha20-Poly1305-Implementierung von Go, um Daten zu verschlüsseln, aber wenn ich einige große Dateien verschlüssele, ist die Speichernutzung höher als erwartet. Soweit ich weiß, bedeutet die AEAD-Verschlüsselungsimplementierung von Go, dass wir die gesamten Daten im Speicher behalten müssen, um den Hash zu erstellen, aber die Speichernutzung ist doppelt so groß wie die Klartextgröße.

Das folgende kleine Programm, das versucht, 4 GiB an Daten zu verschlüsseln, verdeutlicht dies (in einem realen Programm sollte keynonce nicht leer sein):

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)
}

Laut dem Quellcode von crypto/cipher/gcm.go (sowohl von AES-GCM als auch von ChaCha20-Poly1305 verwendet) gibt es die folgenden Kommentare:

// 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

Das bedeutet, dass ich in der Lage sein sollte, den Speicher wiederzuverwenden. Ich habe es versucht, aber es hat keine Auswirkungen auf die von meiner Anwendung verwendete Speichermenge – nach dem Aufruf Seal() verwenden wir am Ende immer 8 GiB Speicher Can 4 GiB an Daten verschlüsselt werden?

[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

Wenn der Speicher wiederverwendet wird (wie angedeutet), sollte ich dann keine signifikante Steigerung außer dem relativ kleinen Hash erwarten, den die AEAD-Verschlüsselung dem Chiffretext hinzufügt?


Richtige Antwort


Sie haben vergessen, das an den Chiffretext angehängte Authentifizierungstoken zu berücksichtigen. Wenn Sie in der Erstzuteilung Platz dafür schaffen, ist keine weitere Zuteilung notwendig: ​​

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

Das obige ist der detaillierte Inhalt vonVerwenden Sie cipher.AEAD.Seal(), um die Speichernutzung anzuzeigen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen