mirror of
https://github.com/HACKERALERT/Picocrypt.git
synced 2025-01-04 05:38:31 +00:00
Update Picocrypt.go
This commit is contained in:
parent
3ab5c42e52
commit
ccb473703c
1 changed files with 303 additions and 38 deletions
|
@ -12,18 +12,23 @@ https://github.com/HACKERALERT/Picocrypt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
"strings"
|
"strings"
|
||||||
"path/filepath"
|
"strconv"
|
||||||
"image/color"
|
"image/color"
|
||||||
g "github.com/AllenDang/giu"
|
|
||||||
ig "github.com/AllenDang/imgui-go"
|
|
||||||
di "github.com/sqweek/dialog"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"path/filepath"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
"golang.org/x/crypto/argon2"
|
||||||
|
"golang.org/x/crypto/blake2b"
|
||||||
|
g "github.com/AllenDang/giu"
|
||||||
|
di "github.com/sqweek/dialog"
|
||||||
|
ig "github.com/AllenDang/imgui-go"
|
||||||
"github.com/klauspost/reedsolomon"
|
"github.com/klauspost/reedsolomon"
|
||||||
_ "golang.org/x/crypto/argon2"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
_ "github.com/HACKERALERT/Monocypher-Go/monocypher"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
|
@ -41,7 +46,9 @@ var inputLabel = "Drag and drop file(s) and folder(s) into this window."
|
||||||
var outputEntry string
|
var outputEntry string
|
||||||
var outputWidth float32 = 376
|
var outputWidth float32 = 376
|
||||||
var orLabel = "or"
|
var orLabel = "or"
|
||||||
|
var progress float32 = 0
|
||||||
var progressInfo = ""
|
var progressInfo = ""
|
||||||
|
var status = "Ready."
|
||||||
|
|
||||||
// User input variables
|
// User input variables
|
||||||
var password string
|
var password string
|
||||||
|
@ -52,9 +59,12 @@ var erase bool
|
||||||
var reedsolo bool
|
var reedsolo bool
|
||||||
|
|
||||||
// Reed-Solomon encoders
|
// Reed-Solomon encoders
|
||||||
|
var rs5_128,_ = reedsolomon.New(5,128)
|
||||||
var rs10_128,_ = reedsolomon.New(10,128)
|
var rs10_128,_ = reedsolomon.New(10,128)
|
||||||
var rs16_128,_ = reedsolomon.New(16,128)
|
var rs16_128,_ = reedsolomon.New(16,128)
|
||||||
var rs24_128,_ = reedsolomon.New(24,128)
|
var rs24_128,_ = reedsolomon.New(24,128)
|
||||||
|
var rs32_128,_ = reedsolomon.New(32,128)
|
||||||
|
var rs64_128,_ = reedsolomon.New(64,128)
|
||||||
|
|
||||||
// Create the user interface
|
// Create the user interface
|
||||||
func startUI(){
|
func startUI(){
|
||||||
|
@ -128,11 +138,11 @@ func startUI(){
|
||||||
),
|
),
|
||||||
|
|
||||||
// Progress bar
|
// Progress bar
|
||||||
g.ProgressBar(0).Size(-1,0).Overlay(progressInfo),
|
g.ProgressBar(progress).Size(-1,0).Overlay(progressInfo),
|
||||||
|
|
||||||
// Status label
|
// Status label
|
||||||
g.Dummy(10,0),
|
g.Dummy(10,0),
|
||||||
g.Label("Ready."),
|
g.Label(status),
|
||||||
|
|
||||||
// Credits and version
|
// Credits and version
|
||||||
g.Line(
|
g.Line(
|
||||||
|
@ -162,6 +172,9 @@ func onDrop(names []string){
|
||||||
onlyFolders = nil
|
onlyFolders = nil
|
||||||
allFiles = nil
|
allFiles = nil
|
||||||
files,folders := 0,0
|
files,folders := 0,0
|
||||||
|
|
||||||
|
// Reset UI
|
||||||
|
resetUI()
|
||||||
|
|
||||||
// Hide the ".pcv" label
|
// Hide the ".pcv" label
|
||||||
orLabel = "or"
|
orLabel = "or"
|
||||||
|
@ -190,6 +203,22 @@ func onDrop(names []string){
|
||||||
mode = "decrypt"
|
mode = "decrypt"
|
||||||
inputLabel = name+" (will decrypt)"
|
inputLabel = name+" (will decrypt)"
|
||||||
outputEntry = names[0][:len(names[0])-4]
|
outputEntry = names[0][:len(names[0])-4]
|
||||||
|
|
||||||
|
// Open input file in read-only mode
|
||||||
|
fin,_ := os.Open(names[0])
|
||||||
|
defer fin.Close()
|
||||||
|
|
||||||
|
// Read metadata and insert into box
|
||||||
|
fin.Read(make([]byte,133))
|
||||||
|
tmp := make([]byte,138)
|
||||||
|
fin.Read(tmp)
|
||||||
|
tmp = rsDecode(tmp,rs10_128,10)
|
||||||
|
metadataLength,_ := strconv.Atoi(string(tmp))
|
||||||
|
//fmt.Println(metadataLength)
|
||||||
|
tmp = make([]byte,metadataLength)
|
||||||
|
fin.Read(tmp)
|
||||||
|
metadata = string(tmp)
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
mode = "encrypt"
|
mode = "encrypt"
|
||||||
inputLabel = name+" (will encrypt)"
|
inputLabel = name+" (will encrypt)"
|
||||||
|
@ -205,6 +234,8 @@ func onDrop(names []string){
|
||||||
|
|
||||||
// Set the file as 'outputEntry'
|
// Set the file as 'outputEntry'
|
||||||
outputEntry = names[0]
|
outputEntry = names[0]
|
||||||
|
|
||||||
|
inputFile = names[0]
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
// There are multiple dropped items, check each one
|
// There are multiple dropped items, check each one
|
||||||
|
@ -267,6 +298,16 @@ func work(){
|
||||||
//headerBroken := false
|
//headerBroken := false
|
||||||
//reedsoloFixed := 0
|
//reedsoloFixed := 0
|
||||||
//reedsoloErrors := 0
|
//reedsoloErrors := 0
|
||||||
|
|
||||||
|
// Declare salt and nonce
|
||||||
|
var salt []byte
|
||||||
|
var nonce []byte
|
||||||
|
var keyHash []byte
|
||||||
|
var crcHash []byte
|
||||||
|
var nonces []byte
|
||||||
|
|
||||||
|
stat,_ := os.Stat(inputFile)
|
||||||
|
total := stat.Size()
|
||||||
|
|
||||||
// Set the output file based on mode
|
// Set the output file based on mode
|
||||||
if mode=="encrypt"{
|
if mode=="encrypt"{
|
||||||
|
@ -274,62 +315,262 @@ func work(){
|
||||||
}else{
|
}else{
|
||||||
outputFile = outputEntry
|
outputFile = outputEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open input file in read-only mode
|
||||||
|
fin,_ := os.Open(inputFile)
|
||||||
|
defer fin.Close()
|
||||||
|
|
||||||
|
var fout *os.File
|
||||||
|
|
||||||
// If encrypting, generate values. If decrypting, read values from file
|
// If encrypting, generate values. If decrypting, read values from file
|
||||||
if mode=="encrypt"{
|
if mode=="encrypt"{
|
||||||
fout,_ := os.OpenFile(
|
status = "Generating values..."
|
||||||
|
g.Update()
|
||||||
|
fout,_ = os.OpenFile(
|
||||||
outputFile,
|
outputFile,
|
||||||
os.O_WRONLY|os.O_TRUNC|os.O_CREATE,
|
os.O_RDWR|os.O_CREATE|os.O_TRUNC,
|
||||||
0666,
|
0755,
|
||||||
)
|
)
|
||||||
|
defer fout.Close()
|
||||||
|
|
||||||
// Argon2 salt and XChaCha20 nonce
|
// Argon2 salt and XChaCha20 nonce
|
||||||
salt := make([]byte,16)
|
salt = make([]byte,16)
|
||||||
nonce := make([]byte,24)
|
nonce = make([]byte,24)
|
||||||
|
|
||||||
|
// Write version to file
|
||||||
|
fout.Write(rsEncode([]byte("v1.13"),rs5_128,133))
|
||||||
|
|
||||||
// Encode the length of the metadata with Reed-Solomon
|
// Encode the length of the metadata with Reed-Solomon
|
||||||
metadataLength := []byte(fmt.Sprintf("%010d",len(metadata)))
|
metadataLength := []byte(fmt.Sprintf("%010d",len(metadata)))
|
||||||
/*shards,_ := rs10_128.Split(metadataLength)
|
|
||||||
rs10_128.Encode(shards)
|
|
||||||
tmp := make([]byte,138)
|
|
||||||
for i,shard := range(shards){
|
|
||||||
tmp[i] = shard[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
fout.Write(tmp)*/
|
|
||||||
metadataLength = rsEncode(metadataLength,rs10_128,138)
|
metadataLength = rsEncode(metadataLength,rs10_128,138)
|
||||||
|
// Write the length of the metadata to file
|
||||||
fout.Write(metadataLength)
|
fout.Write(metadataLength)
|
||||||
|
|
||||||
|
// Write the actual metadata
|
||||||
|
fout.Write([]byte(metadata))
|
||||||
|
|
||||||
// Fill salt and nonce with Go's CSPRNG
|
// Fill salt and nonce with Go's CSPRNG
|
||||||
rand.Read(salt)
|
rand.Read(salt)
|
||||||
rand.Read(nonce)
|
rand.Read(nonce)
|
||||||
|
|
||||||
|
//fmt.Println("Encrypting salt: ",salt)
|
||||||
|
//fmt.Println("Encrypting nonce: ",nonce)
|
||||||
|
|
||||||
// Encode salt with Reed-Solomon and write to file
|
// Encode salt with Reed-Solomon and write to file
|
||||||
/*shards,_ = rs16_128.Split(salt)
|
|
||||||
rs16_128.Encode(shards)
|
|
||||||
tmp = make([]byte,144)
|
|
||||||
for i,shard := range(shards){
|
|
||||||
tmp[i] = shard[0]
|
|
||||||
}
|
|
||||||
fout.Write(tmp)*/
|
|
||||||
salt = rsEncode(salt,rs16_128,144)
|
salt = rsEncode(salt,rs16_128,144)
|
||||||
fout.Write(salt)
|
fout.Write(salt)
|
||||||
|
|
||||||
// Encode nonce with Reed-Solomon and write to file
|
// Encode nonce with Reed-Solomon and write to file
|
||||||
/*shards,_ = rs24_128.Split(nonce)
|
tmp := rsEncode(nonce,rs24_128,152)
|
||||||
rs24_128.Encode(shards)
|
fout.Write(tmp)
|
||||||
tmp = make([]byte,152)
|
|
||||||
for i,shard := range(shards){
|
// Write placeholder for hash of key
|
||||||
tmp[i] = shard[0]
|
fout.Write(make([]byte,192))
|
||||||
}
|
|
||||||
fout.Write(tmp)*/
|
// Write placeholder for Blake2 CRC
|
||||||
nonce = rsEncode(nonce,rs24_128,152)
|
fout.Write(make([]byte,160))
|
||||||
fout.Write(nonce)
|
|
||||||
|
|
||||||
|
|
||||||
|
pairs := int(math.Ceil(float64(total)/1048576))
|
||||||
|
|
||||||
|
offset := 152*pairs+144
|
||||||
|
|
||||||
|
// Write placeholder for nonce/Poly1305 pairs
|
||||||
|
fout.Write(make([]byte,offset))
|
||||||
}else{
|
}else{
|
||||||
|
g.Update()
|
||||||
|
status = "Reading values..."
|
||||||
|
version := make([]byte,133)
|
||||||
|
fin.Read(version)
|
||||||
|
version = rsDecode(version,rs5_128,5)
|
||||||
|
|
||||||
|
tmp := make([]byte,138)
|
||||||
|
fin.Read(tmp)
|
||||||
|
tmp = rsDecode(tmp,rs10_128,10)
|
||||||
|
metadataLength,_ := strconv.Atoi(string(tmp))
|
||||||
|
|
||||||
|
fin.Read(make([]byte,metadataLength))
|
||||||
|
|
||||||
|
salt = make([]byte,144)
|
||||||
|
fin.Read(salt)
|
||||||
|
salt = rsDecode(salt,rs16_128,16)
|
||||||
|
|
||||||
|
nonce = make([]byte,152)
|
||||||
|
fin.Read(nonce)
|
||||||
|
nonce = rsDecode(nonce,rs24_128,24)
|
||||||
|
|
||||||
|
//fmt.Println("Decrypting salt: ",salt)
|
||||||
|
//fmt.Println("Decrypting nonce: ",nonce)
|
||||||
|
|
||||||
|
keyHash = make([]byte,192)
|
||||||
|
fin.Read(keyHash)
|
||||||
|
keyHash = rsDecode(keyHash,rs64_128,64)
|
||||||
|
|
||||||
|
crcHash = make([]byte,160)
|
||||||
|
fin.Read(crcHash)
|
||||||
|
crcHash = rsDecode(crcHash,rs32_128,32)
|
||||||
|
|
||||||
|
_tmp := math.Ceil(float64(total-int64(metadataLength+919))/float64(1048744))
|
||||||
|
nonces = make([]byte,int(_tmp*152)+144)
|
||||||
|
fin.Read(nonces)
|
||||||
|
|
||||||
|
//fmt.Println("Nonces: ",nonces)
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Update()
|
||||||
|
status = "Deriving key..."
|
||||||
|
|
||||||
|
// Derive encryption/decryption key
|
||||||
|
key := argon2.IDKey(
|
||||||
|
[]byte(password),
|
||||||
|
salt,
|
||||||
|
4,
|
||||||
|
1048576/2,
|
||||||
|
4,
|
||||||
|
32,
|
||||||
|
)[:]
|
||||||
|
|
||||||
|
key = make([]byte,32)
|
||||||
|
|
||||||
|
sha3_512 := sha3.New512()
|
||||||
|
sha3_512.Write(key)
|
||||||
|
keyHash = sha3_512.Sum(nil)
|
||||||
|
//fmt.Println("keyHash: ",keyHash)
|
||||||
|
|
||||||
|
// Check is password is correct
|
||||||
|
|
||||||
|
if mode=="decrypt"{
|
||||||
|
fout,_ = os.OpenFile(
|
||||||
|
outputFile,
|
||||||
|
os.O_RDWR|os.O_CREATE|os.O_TRUNC,
|
||||||
|
0755,
|
||||||
|
)
|
||||||
|
defer fout.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crc,_ := blake2b.New256(nil)
|
||||||
|
|
||||||
|
done := 0
|
||||||
|
counter := 0
|
||||||
|
startTime := time.Now()
|
||||||
|
|
||||||
|
cipher,_ := chacha20poly1305.NewX(key)
|
||||||
|
|
||||||
|
if mode=="decrypt"{
|
||||||
|
_mac := nonces[len(nonces)-144:]
|
||||||
|
_mac = rsDecode(_mac,rs16_128,16)
|
||||||
|
//fmt.Println("_mac len: ",len(_mac))
|
||||||
|
nonces = nonces[:len(nonces)-144]
|
||||||
|
var tmp []byte
|
||||||
|
var chunk []byte
|
||||||
|
for i,j := range(nonces){
|
||||||
|
chunk = append(chunk,j)
|
||||||
|
if (i+1)%152==0{
|
||||||
|
chunk = rsDecode(chunk,rs24_128,24)
|
||||||
|
for _,k := range(chunk){
|
||||||
|
tmp = append(tmp,k)
|
||||||
|
}
|
||||||
|
chunk = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _,j := range(_mac){
|
||||||
|
tmp = append(tmp,j)
|
||||||
|
}
|
||||||
|
//fmt.Println("ENCRYPTED NONCES: ",tmp)
|
||||||
|
// XXXXXXXXXXXXXXXXFSFSDFFFSFF
|
||||||
|
nonces,_ = cipher.Open(nil,nonce,tmp,nil)
|
||||||
|
//fmt.Println("UNENCRYPTED NONCES: ",nonces)
|
||||||
|
}
|
||||||
|
for{
|
||||||
|
//fmt.Println("Encrypt/decrypt loop")
|
||||||
|
var _data []byte
|
||||||
|
var data []byte
|
||||||
|
var _nonce []byte
|
||||||
|
if mode=="encrypt"{
|
||||||
|
_data = make([]byte,1048576)
|
||||||
|
}else{
|
||||||
|
_data = make([]byte,1048592)
|
||||||
|
}
|
||||||
|
|
||||||
|
size,err := fin.Read(_data)
|
||||||
|
if err!=nil{
|
||||||
|
break
|
||||||
|
}
|
||||||
|
data = _data[:size]
|
||||||
|
|
||||||
|
|
||||||
|
if mode=="encrypt"{
|
||||||
|
_nonce = make([]byte,24)
|
||||||
|
rand.Read(_nonce)
|
||||||
|
for _,i := range(_nonce){
|
||||||
|
nonces = append(nonces,i)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
_nonce = nonces[counter*24:counter*24+24]
|
||||||
|
}
|
||||||
|
|
||||||
|
//fmt.Println("Data nonce: ",_nonce)
|
||||||
|
//fmt.Println("Data: ",data)
|
||||||
|
if mode=="encrypt"{
|
||||||
|
data = cipher.Seal(nil,_nonce,data,nil)
|
||||||
|
crc.Write(data)
|
||||||
|
fout.Write(data)
|
||||||
|
}else{
|
||||||
|
//fmt.Println("DECODE LOOP")
|
||||||
|
crc.Write(data)
|
||||||
|
data,_ := cipher.Open(nil,_nonce,data,nil)
|
||||||
|
fout.Write(data)
|
||||||
|
//fmt.Println(authentic)
|
||||||
|
//fmt.Println("DECRYPTED DATA: ",data)
|
||||||
|
}
|
||||||
|
|
||||||
|
done += 1048576
|
||||||
|
counter++
|
||||||
|
progress = float32(done)/float32(total)
|
||||||
|
|
||||||
|
elapsed:= float64(int64(time.Now().Sub(startTime)))/float64(1000000000)
|
||||||
|
|
||||||
|
speed := (float64(done)/elapsed)/1000000
|
||||||
|
eta := float64(total-int64(done))/(speed*1000000)
|
||||||
|
|
||||||
|
progressInfo = fmt.Sprintf("%.2f%%",progress*100)
|
||||||
|
|
||||||
|
status = fmt.Sprintf("Working at %.2f MB/s (ETA: %.1fs)",speed,eta)
|
||||||
|
|
||||||
|
g.Update()
|
||||||
|
data = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if mode=="encrypt"{
|
||||||
|
//fmt.Println("'nonces' before RS: ",nonces)
|
||||||
|
fout.Seek(int64(567+len(metadata)),0)
|
||||||
|
fout.Write(rsEncode(keyHash,rs64_128,192))
|
||||||
|
fout.Write(rsEncode(crc.Sum(nil),rs32_128,160))
|
||||||
|
//fmt.Println("UNENCRYPTED NONCES: ",nonces)
|
||||||
|
tmp := cipher.Seal(nil,nonce,nonces,nil)
|
||||||
|
//fmt.Println("ENCRYPTED NONCES: ",tmp)
|
||||||
|
_mac := tmp[len(tmp)-16:]
|
||||||
|
//fmt.Println("_mac len: ",len(_mac))
|
||||||
|
tmp = tmp[:len(tmp)-16]
|
||||||
|
var chunk []byte
|
||||||
|
//fmt.Println("<Nonces>")
|
||||||
|
for i,j := range(tmp){
|
||||||
|
chunk = append(chunk,j)
|
||||||
|
if (i+1)%24==0{
|
||||||
|
fout.Write(rsEncode(chunk,rs24_128,152))
|
||||||
|
//fmt.Println(rsEncode(chunk,rs24_128,152))
|
||||||
|
chunk = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fout.Write(rsEncode(_mac,rs16_128,144))
|
||||||
|
//fmt.Println("</Nonces>")
|
||||||
|
}else{
|
||||||
|
fmt.Println("crcHash: ",crcHash)
|
||||||
|
fmt.Println("crc.Sum: ",crc.Sum(nil))
|
||||||
|
}
|
||||||
|
fmt.Println("==============================")
|
||||||
|
resetUI()
|
||||||
|
status = "Completed."
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the UI to a clean state with no nothing selected
|
// Reset the UI to a clean state with no nothing selected
|
||||||
|
@ -338,6 +579,14 @@ func resetUI(){
|
||||||
outputEntry = ""
|
outputEntry = ""
|
||||||
orLabel = "or"
|
orLabel = "or"
|
||||||
outputWidth = 376
|
outputWidth = 376
|
||||||
|
password = ""
|
||||||
|
cPassword = ""
|
||||||
|
metadata = ""
|
||||||
|
keep = false
|
||||||
|
erase = false
|
||||||
|
reedsolo = false
|
||||||
|
progress = 0
|
||||||
|
progressInfo = ""
|
||||||
g.Update()
|
g.Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +600,22 @@ func rsEncode(data []byte,encoder reedsolomon.Encoder,size int) []byte{
|
||||||
return tmp
|
return tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func rsDecode(data []byte,encoder reedsolomon.Encoder,size int) []byte{
|
||||||
|
res := make([][]byte,len(data))
|
||||||
|
for i,_ := range(data){
|
||||||
|
tmp := make([]byte,1)
|
||||||
|
tmp[0] = data[i]
|
||||||
|
res[i] = tmp
|
||||||
|
}
|
||||||
|
_ = encoder.Reconstruct(res)
|
||||||
|
res = res[:size]
|
||||||
|
tmp := make([]byte,size)
|
||||||
|
for i,shard := range(res){
|
||||||
|
tmp[i] = shard[0]
|
||||||
|
}
|
||||||
|
return tmp
|
||||||
|
}
|
||||||
|
|
||||||
// Create the master window, set callbacks, and start the UI
|
// Create the master window, set callbacks, and start the UI
|
||||||
func main(){
|
func main(){
|
||||||
window := g.NewMasterWindow("Picocrypt",480,470,g.MasterWindowFlagsNotResizable,nil)
|
window := g.NewMasterWindow("Picocrypt",480,470,g.MasterWindowFlagsNotResizable,nil)
|
||||||
|
|
Loading…
Reference in a new issue