-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecrypt.go
65 lines (55 loc) · 1.49 KB
/
decrypt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package elog
import (
"crypto/aes"
"crypto/cipher"
"crypto/sha256"
"encoding/binary"
"io"
"os"
"golang.org/x/exp/rand"
)
type SeedOpts struct {
Seed uint64
F SeedFunc
}
func Decrypt(encrypted, decrypted *os.File, opts SeedOpts) error {
encrypted_data, err := io.ReadAll(encrypted)
if err != nil {
return err
}
encrypted_length := len(encrypted_data)
current_index := 0
current_hash := make([]byte, 32)
current_seed := opts.Seed
randomizer := rand.New(rand.NewSource(opts.Seed))
for current_index < encrypted_length {
entry_length_bytes := encrypted_data[current_index : current_index+8]
entry_length := int(binary.LittleEndian.Uint64(entry_length_bytes))
current_index += 8
ciphertext := encrypted_data[current_index : current_index+entry_length]
current_index += entry_length
aes, err := aes.NewCipher(current_hash)
if err != nil {
return err
}
gcm, err := cipher.NewGCM(aes)
if err != nil {
return err
}
// We predict the nonce using the randomizer w/ the given seed.
nonce := make([]byte, gcm.NonceSize())
randomizer.Read(nonce)
plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
// Unless the inital seed or seed function is wrong, this should never happen.
if err != nil {
return err
}
// Write the plain-text log entry into the plain-text log file.
decrypted.Write(plaintext)
new_hash := sha256.Sum256(plaintext)
copy(current_hash, new_hash[:])
current_seed = opts.F(current_seed)
randomizer.Seed(current_seed)
}
return nil
}