-
Notifications
You must be signed in to change notification settings - Fork 1
/
outguess.go
103 lines (91 loc) · 2.06 KB
/
outguess.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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package outguess
import (
"errors"
"fmt"
"io"
"github.com/henkman/outguess/arc"
"github.com/henkman/outguess/stegjpeg"
)
type iterator struct {
as arc.Stream
skipmod uint32
off uint32
}
func (it *iterator) Current() uint32 {
return it.off
}
func (it *iterator) Next() uint32 {
it.off += (it.as.GetWord() % it.skipmod) + 1
return it.off
}
func (it *iterator) Seed(seed uint16) {
reseed := [2]byte{
uint8(seed),
uint8(seed >> 8),
}
it.as.AddRandom(reseed[:])
}
func (it *iterator) Adapt(bm []byte, bits uint32, datalen uint) {
bo := bits - it.off
var sa float32
if bo > bits/32 {
sa = 2
} else {
sa = 2 - float32((bits/32)-bo)/float32(bits/32)
}
it.skipmod = uint32(sa * float32(bits-it.off) / float32(8*datalen))
}
func steg_retrbyte(bm []byte, bits uint32, it *iterator) uint32 {
var tmp, bit uint32
i := it.Current()
for bit = 0; bit < bits; bit++ {
if bm[i/8]&(1<<(i&7)) != 0 {
tmp |= 1 << bit
}
i = it.Next()
}
return tmp
}
func Get(file io.Reader, msg io.Writer, key []byte) error {
if key == nil {
key = []byte("Default key")
}
_, bm, err := stegjpeg.Decode(file)
if err != nil {
return err
}
var as arc.Stream
as.InitKey([]byte("Encryption"), key)
tas := as
var it iterator
it.skipmod = 32
it.as.InitKey([]byte("Seeding"), key)
it.off = it.as.GetWord() % it.skipmod
var buf [4]byte
for i, _ := range buf {
buf[i] = byte(steg_retrbyte(bm.Bitmap, 8, &it)) ^ as.GetByte()
}
seed := uint16(buf[0]) | uint16(buf[1])<<8
datalen := uint(buf[2]) | uint(buf[3])<<8
if datalen > uint(bm.Bytes) {
return errors.New(fmt.Sprintf(
"Extracted datalen is too long: %d > %d\n", datalen, len(bm.Bitmap)))
}
encdata := make([]byte, datalen)
it.Seed(seed)
var n uint
for datalen > 0 {
it.Adapt(bm.Bitmap, bm.Bits, datalen)
encdata[n] = byte(steg_retrbyte(bm.Bitmap, 8, &it))
n++
datalen--
}
for i, _ := range encdata {
encdata[i] ^= tas.GetByte()
}
_, err = msg.Write(encdata)
return err
}
func Put(file, msg io.Reader, key []byte, out io.Writer) error {
return errors.New("writing not yet implemented")
}