Rumah >pembangunan bahagian belakang >Golang >Gunakan cipher.AEAD.Seal() untuk melihat penggunaan memori

Gunakan cipher.AEAD.Seal() untuk melihat penggunaan memori

WBOY
WBOYke hadapan
2024-02-06 10:03:031008semak imbas

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

Kandungan soalan

Saya menggunakan pelaksanaan ChaCha20-Poly1305 Go untuk menyulitkan data, tetapi apabila saya menyulitkan beberapa fail besar, penggunaan memori adalah lebih tinggi daripada yang saya jangkakan. Setakat yang saya tahu, pelaksanaan sifir AEAD Go bermakna kita perlu menyimpan keseluruhan data dalam ingatan untuk mencipta cincang, tetapi penggunaan memori adalah dua kali ganda saiz plaintext.

Atur cara kecil berikut yang cuba menyulitkan 4 GiB data menyerlahkan perkara ini (dalam program dunia sebenar, keynonce tidak sepatutnya kosong):

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

Menurut kod sumber crypto/cipher/gcm.go (digunakan oleh kedua-dua AES-GCM dan ChaCha20-Poly1305) terdapat ulasan berikut:

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

Ini bermakna saya sepatutnya boleh menggunakan semula memori, saya telah cuba melakukan ini, tetapi ia tidak memberi kesan pada jumlah memori yang digunakan oleh aplikasi saya - selepas memanggil Seal() kami sentiasa menggunakan 8 GiB memori Can 4 GiB data disulitkan?

[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

Jika ia menggunakan semula ingatan (seperti yang tersirat), maka saya tidak sepatutnya menjangkakan sebarang peningkatan yang ketara selain daripada cipher yang agak kecil yang ditambahkan oleh sifir AEAD pada teks sifir?


Jawapan betul


Anda terlupa untuk mengambil kira token pengesahan yang dilampirkan pada teks sifir. Jika anda memberi ruang untuknya dalam peruntukan awal, tiada peruntukan lanjut diperlukan: ​​

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

Atas ialah kandungan terperinci Gunakan cipher.AEAD.Seal() untuk melihat penggunaan memori. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam