Skip to content

Commit 12801fc

Browse files
author
Levko Burburas
committed
Merge remote-tracking branch 'steganography/master' into art-reg/integrate-pqsignature
2 parents 22a48d4 + 555cf67 commit 12801fc

File tree

13 files changed

+833
-0
lines changed

13 files changed

+833
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*.log
2+
**/.DS_Store
23
**/mocks/
34
**/vendor/

pqsignature/steganography/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Rafael Passos (@Auyer)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

pqsignature/steganography/README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Steganography Lib
2+
3+
[![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](http://godoc.org/github.com/auyer/steganography)
4+
[![Go Report Card](https://goreportcard.com/badge/github.com/auyer/steganography)](https://goreportcard.com/report/github.com/auyer/steganography)
5+
[![LICENSE MIT](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://img.shields.io/badge/license-MIT-brightgreen.svg)
6+
[![CircleCI](https://circleci.com/gh/auyer/steganography.svg?style=svg)](https://circleci.com/gh/auyer/steganography)
7+
[![codecov](https://codecov.io/gh/auyer/steganography/branch/master/graph/badge.svg)](https://codecov.io/gh/auyer/steganography)
8+
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)
9+
10+
Steganography is a library written in Pure go to allow simple LSB steganography on images. It is capable of both encoding and decoding images. It can store files of any format.
11+
This library is inspired by [Stego by EthanWelsh](https://github.com/EthanWelsh/Stego), a command line utility with the same purpose.
12+
13+
## Installation
14+
```go
15+
go get -u github.com/auyer/steganography
16+
```
17+
18+
## Demonstration
19+
20+
| Original |Encoded |
21+
| -------------------- | ------------------|
22+
| ![Original File](examples/stegosaurus.png) | ![Encoded File](examples/encoded_stegosaurus.png)
23+
24+
The second image contains the first paragaph of the description of a stegosaurus on [Wikipedia](https://en.wikipedia.org/wiki/Stegosaurus), also available in [examples/message.txt](https://raw.githubusercontent.com/auyer/steganography/master/examples/message.txt) as an example.
25+
26+
------
27+
Getting Started
28+
------
29+
```go
30+
package main
31+
import (
32+
"bufio"
33+
"image/png"
34+
"io/ioutil"
35+
36+
"github.com/auyer/steganography"
37+
)
38+
```
39+
40+
Encode
41+
------
42+
Write mode is used to take a message and embed it into an image file using LSB steganography in order to produce a secret image file that will contain your message.
43+
44+
Note that the minnimum image size is 24 pixels for one byte. For each additional byte, it is necessary 3 more pixels.
45+
46+
```go
47+
inFile, _ := os.Open("input_file.png") // opening file
48+
reader := bufio.NewReader(inFile) // buffer reader
49+
img, _ := png.Decode(reader) // decoding to golang's image.Image
50+
51+
w := new(bytes.Buffer) // buffer that will recieve the results
52+
err := steganography.Encode(w, img, []byte("message")) // Encode the message into the image
53+
if err != nil {
54+
log.Printf("Error Encoding file %v", err)
55+
return
56+
}
57+
outFile, _ := os.Create("out_file.png") // create file
58+
w.WriteTo(outFile) // write buffer to it
59+
outFile.Close()
60+
```
61+
note: all error checks were removed for brevity, but they should be included.
62+
63+
Size of Message
64+
------
65+
Length mode can be used in order to preform a preliminary check on the carrier image in order to deduce how large of a file it can store.
66+
67+
```go
68+
sizeOfMessage := steganography.GetMessageSizeFromImage(img) // retrieves the size of the encoded message
69+
```
70+
71+
Decode
72+
-----
73+
Read mode is used to read an image that has been encoded using LSB steganography, and extract the hidden message from that image.
74+
75+
```go
76+
inFile, _ := os.Open(encodedInputFile) // opening file
77+
defer inFile.Close()
78+
79+
reader := bufio.NewReader(inFile) // buffer reader
80+
img, _ := png.Decode(reader) // decoding to golang's image.Image
81+
82+
sizeOfMessage := steganography.GetMessageSizeFromImage(img) // retrieving message size to decode in the next line
83+
84+
msg := steganography.Decode(sizeOfMessage, img) // decoding the message from the file
85+
fmt.Println(string(msg))
86+
87+
```
88+
note: all error checks were removed for brevity, but they should be included.
89+
90+
Complete Example
91+
------
92+
For a complete example, see the [examples/stego.go](examples/stego.go) file. It is a command line app based on the original fork of this repository, but modifid to use the Steganography library.
93+
94+
-----
95+
### Attributions
96+
- Stegosaurus Picture By Matt Martyniuk - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=42215661
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Example usage:
2+
3+
Decoding message: go run stego.go -d -i encoded_stegosaurus.png
4+
5+
Encoding message: go run stego.go -e -i stegosaurus.png -mi message.txt -o encoded_stegosaurus.png
6+
7+
Usage stego.go
8+
9+
-help Will show this message below
10+
11+
-d Specifies if you would like to decode a message from a given PNG file
12+
13+
-e Specifies if you would like to encode a message to a given PNG file
14+
15+
-i string Path to the the input image
16+
17+
-mi string Path to the message input file
18+
19+
-mo string Path to the message output file
20+
21+
-o string Path to the the output image (default "encoded.png")
195 KB
Loading
78.7 KB
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The quadrupedal Stegosaurus is one of the most easily identifiable dinosaur genera, due to the distinctive double row of kite-shaped plates rising vertically along the rounded back and the two pairs of long spikes extending horizontally near the end of the tail. Although large individuals could grow up to 9 m (29.5 ft) in length[4] and 5.3 to 7 metric tons (5.8 to 7.7 short tons) in weight,[5][6] the various species of Stegosaurus were dwarfed by contemporaries, the giant sauropods. Some form of armor appears to have been necessary, as Stegosaurus species coexisted with large predatory theropod dinosaurs, such as Allosaurus and Ceratosaurus.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"flag"
7+
"fmt"
8+
"image"
9+
"io/ioutil"
10+
"log"
11+
"os"
12+
13+
"github.com/pastelnetwork/steganography"
14+
)
15+
16+
var pictureInputFile string
17+
var pictureOutputFile string
18+
var messageInputFile string
19+
var messageOutputFile string
20+
var decode bool
21+
var encode bool
22+
var help bool
23+
24+
// init creates the necessary flags to run program from the command line
25+
func init() {
26+
27+
flag.BoolVar(&decode, "d", false, "Specifies if you would like to decode a message from a given PNG file")
28+
flag.BoolVar(&encode, "e", false, "Specifies if you would like to encode a message to a given PNG file")
29+
30+
flag.StringVar(&pictureInputFile, "i", "", "Path to the the input image")
31+
flag.StringVar(&pictureOutputFile, "o", "encoded.png", "Path to the the output image")
32+
33+
flag.StringVar(&messageInputFile, "mi", "", "Path to the message input file")
34+
flag.StringVar(&messageOutputFile, "mo", "", "Path to the message output file")
35+
36+
flag.BoolVar(&help, "help", false, "Help")
37+
38+
flag.Parse()
39+
}
40+
41+
// OpenImageFromPath returns a image.Image from a file path. A helper function to deal with decoding the image into a usable format. This method is optional.
42+
func OpenImageFromPath(filename string) (image.Image, error) {
43+
inFile, err := os.Open(filename)
44+
if err != nil {
45+
return nil, err
46+
}
47+
defer inFile.Close()
48+
reader := bufio.NewReader(inFile)
49+
img, _, err := image.Decode(reader)
50+
if err != nil {
51+
return nil, err
52+
}
53+
return img, nil
54+
}
55+
56+
func main() {
57+
if encode {
58+
message, err := ioutil.ReadFile(messageInputFile) // Read the message from the message file (alternative to os.Open )
59+
if err != nil {
60+
print("Error reading from file!!!")
61+
return
62+
}
63+
64+
inFile, err := os.Open(pictureInputFile) // Opens input file provided in the flags
65+
if err != nil {
66+
log.Fatalf("Error opening file %s: %v", pictureInputFile, err)
67+
}
68+
defer inFile.Close()
69+
70+
reader := bufio.NewReader(inFile) // Reads binary data from picture file
71+
img, _, err := image.Decode(reader)
72+
if err != nil {
73+
log.Fatalf("Error opening file %v", err)
74+
}
75+
encodedImg := new(bytes.Buffer)
76+
err = steganography.Encode(encodedImg, img, message) // Calls library and Encodes the message into a new buffer
77+
if err != nil {
78+
log.Fatalf("Error encoding message into file %v", err)
79+
}
80+
outFile, err := os.Create(pictureOutputFile) // Creates file to write the message into
81+
if err != nil {
82+
log.Fatalf("Error creating file %s: %v", pictureOutputFile, err)
83+
}
84+
bufio.NewWriter(outFile).Write(encodedImg.Bytes()) // writes file to disk
85+
86+
} else if decode {
87+
88+
inFile, err := os.Open(pictureInputFile) // Opens input file provided in the flags
89+
if err != nil {
90+
log.Fatalf("Error opening file %s: %v", pictureInputFile, err)
91+
}
92+
defer inFile.Close()
93+
94+
reader := bufio.NewReader(inFile)
95+
img, _, err := image.Decode(reader)
96+
if err != nil {
97+
log.Fatal("error decoding file", img)
98+
}
99+
100+
sizeOfMessage := steganography.GetMessageSizeFromImage(img) // Uses the library to check the message size
101+
102+
msg := steganography.Decode(sizeOfMessage, img) // Read the message from the picture file
103+
104+
// if the user specifies a location to write the message to...
105+
if messageOutputFile != "" {
106+
err := ioutil.WriteFile(messageOutputFile, msg, 0644) // write the message to the given output file
107+
108+
if err != nil {
109+
fmt.Println("There was an error writing to file: ", messageOutputFile)
110+
}
111+
} else { // otherwise, print the message to STDOUT
112+
for i := range msg {
113+
fmt.Printf("%c", msg[i])
114+
}
115+
}
116+
} else {
117+
fmt.Println("How to use this script:")
118+
fmt.Println("-i: the input image to encode in / decode from")
119+
fmt.Println()
120+
fmt.Println("-e: take a message and encodes it into a specified location")
121+
fmt.Println("-mi: input message to for the encoding option (ENCODING ONLY)")
122+
fmt.Println("-o: where you would like to store the encodeded image (ENCODING ONLY)")
123+
fmt.Println("\t+ EX: ./main -e -i plain.png -mi message.txt -o secret.png")
124+
fmt.Println()
125+
fmt.Println("-d: take a picture and decodes the message from it")
126+
fmt.Println("-mo: output message. Lempty for STDIO (DECODING ONLY)")
127+
fmt.Println("\t+ EX: ./stego -d -i secret.png -mo secret.txt")
128+
return
129+
}
130+
}
85.4 KB
Loading
78.1 KB
Loading

0 commit comments

Comments
 (0)