mirror of
https://github.com/HACKERALERT/Picocrypt.git
synced 2024-12-27 18:04:21 +00:00
Add web interface
This commit is contained in:
parent
86f3fb83ed
commit
cf09de407a
4 changed files with 417 additions and 0 deletions
10
web/go.mod
Normal file
10
web/go.mod
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
module Picocrypt
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/HACKERALERT/crypto v0.0.0-20220905152506-aa0dd62d8f67
|
||||||
|
github.com/HACKERALERT/infectious v0.0.0-20220905152109-2c37b99f37ff
|
||||||
|
)
|
||||||
|
|
||||||
|
require github.com/HACKERALERT/sys v0.0.0-20220905150735-46e319fb60c9 // indirect
|
6
web/go.sum
Normal file
6
web/go.sum
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
github.com/HACKERALERT/crypto v0.0.0-20220905152506-aa0dd62d8f67 h1:4WfPIopYjvBjyDg0IET7mEj32kkihLmvFgwCOmldqK8=
|
||||||
|
github.com/HACKERALERT/crypto v0.0.0-20220905152506-aa0dd62d8f67/go.mod h1:qiHCxMDsCxX4QhXd3kDYWiNOR/DZQZ7nYO/f2OgWst0=
|
||||||
|
github.com/HACKERALERT/infectious v0.0.0-20220905152109-2c37b99f37ff h1:ertDhqhixxQJJPJIpn4wmSVs2fQ3tlSDNuiZ7jHCvEs=
|
||||||
|
github.com/HACKERALERT/infectious v0.0.0-20220905152109-2c37b99f37ff/go.mod h1:GwBVHbiXRUUciGfKWwm4GCL8FvMZBLHrQq23UXW/CU8=
|
||||||
|
github.com/HACKERALERT/sys v0.0.0-20220905150735-46e319fb60c9 h1:raqLJhvqDGk9L4dnJnO0tTV5Lyba2jhQcIHEle+o1dM=
|
||||||
|
github.com/HACKERALERT/sys v0.0.0-20220905150735-46e319fb60c9/go.mod h1:I4esFWbCYc37CXVb+3qJHJiU43NGkLf66kNV/NDnXcU=
|
199
web/index.go
Normal file
199
web/index.go
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Picocrypt v1.33 (WebAssembly Version)
|
||||||
|
Copyright (c) Evan Su
|
||||||
|
Released under a GNU GPL v3 License
|
||||||
|
https://github.com/HACKERALERT/Picocrypt
|
||||||
|
|
||||||
|
~ In cryptography we trust ~
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall/js"
|
||||||
|
|
||||||
|
"github.com/HACKERALERT/crypto/argon2"
|
||||||
|
"github.com/HACKERALERT/crypto/blake2b"
|
||||||
|
"github.com/HACKERALERT/crypto/chacha20"
|
||||||
|
"github.com/HACKERALERT/crypto/hkdf"
|
||||||
|
"github.com/HACKERALERT/crypto/sha3"
|
||||||
|
"github.com/HACKERALERT/infectious"
|
||||||
|
)
|
||||||
|
|
||||||
|
var MiB = 1 << 20
|
||||||
|
var GiB = 1 << 30
|
||||||
|
var rs5, _ = infectious.NewFEC(5, 15)
|
||||||
|
var rs16, _ = infectious.NewFEC(16, 48)
|
||||||
|
var rs24, _ = infectious.NewFEC(24, 72)
|
||||||
|
var rs32, _ = infectious.NewFEC(32, 96)
|
||||||
|
var rs64, _ = infectious.NewFEC(64, 192)
|
||||||
|
var password string
|
||||||
|
|
||||||
|
func work(din []byte, mode string) []byte {
|
||||||
|
var salt []byte
|
||||||
|
var hkdfSalt []byte
|
||||||
|
var nonce []byte
|
||||||
|
var keyHash []byte
|
||||||
|
var keyHashRef []byte
|
||||||
|
var authTag []byte
|
||||||
|
var dout []byte
|
||||||
|
|
||||||
|
if mode == "encrypt" {
|
||||||
|
salt = make([]byte, 16)
|
||||||
|
hkdfSalt = make([]byte, 32)
|
||||||
|
nonce = make([]byte, 24)
|
||||||
|
rand.Read(salt)
|
||||||
|
rand.Read(hkdfSalt)
|
||||||
|
rand.Read(nonce)
|
||||||
|
dout = append(dout, rsEncode(rs5, []byte("v1.33"))...)
|
||||||
|
dout = append(dout, rsEncode(rs5, []byte("00000"))...)
|
||||||
|
dout = append(dout, rsEncode(rs5, make([]byte, 5))...)
|
||||||
|
dout = append(dout, rsEncode(rs16, salt)...)
|
||||||
|
dout = append(dout, rsEncode(rs32, hkdfSalt)...)
|
||||||
|
dout = append(dout, rsEncode(rs16, make([]byte, 16))...)
|
||||||
|
dout = append(dout, rsEncode(rs24, nonce)...)
|
||||||
|
dout = append(dout, make([]byte, 480)...)
|
||||||
|
} else {
|
||||||
|
errs, tmp := make([]error, 7), make([]byte, 15)
|
||||||
|
tmp, din = din[15:30], din[30:]
|
||||||
|
tmp, errs[0] = rsDecode(rs5, tmp)
|
||||||
|
c, _ := strconv.Atoi(string(tmp))
|
||||||
|
tmp, din = din[c*3:c*3+15], din[c*3+15:]
|
||||||
|
tmp, errs[1] = rsDecode(rs5, tmp)
|
||||||
|
if tmp[0]+tmp[1]+tmp[3] > 0 {
|
||||||
|
return []byte{1}
|
||||||
|
}
|
||||||
|
salt, din = din[:48], din[48:]
|
||||||
|
salt, errs[2] = rsDecode(rs16, salt)
|
||||||
|
hkdfSalt, din = din[:96], din[96:]
|
||||||
|
hkdfSalt, errs[3] = rsDecode(rs32, hkdfSalt)
|
||||||
|
nonce, din = din[48:120], din[120:]
|
||||||
|
nonce, errs[4] = rsDecode(rs24, nonce)
|
||||||
|
keyHashRef, din = din[:192], din[192:]
|
||||||
|
keyHashRef, errs[5] = rsDecode(rs64, keyHashRef)
|
||||||
|
authTag, din = din[96:288], din[288:]
|
||||||
|
authTag, errs[6] = rsDecode(rs64, authTag)
|
||||||
|
for _, err := range errs {
|
||||||
|
if err != nil {
|
||||||
|
return []byte{2}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key := argon2.IDKey([]byte(password), salt, 4, 1<<20, 4, 32)
|
||||||
|
tmp := sha3.New512()
|
||||||
|
tmp.Write(key)
|
||||||
|
keyHash = tmp.Sum(nil)
|
||||||
|
if mode == "decrypt" && !bytes.Equal(keyHash, keyHashRef) {
|
||||||
|
return []byte{3}
|
||||||
|
}
|
||||||
|
|
||||||
|
counter := 0
|
||||||
|
chacha, _ := chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||||
|
subkey := make([]byte, 32)
|
||||||
|
hkdf := hkdf.New(sha3.New256, key, hkdfSalt, nil)
|
||||||
|
hkdf.Read(subkey)
|
||||||
|
mac, _ := blake2b.New512(subkey)
|
||||||
|
hkdf.Read(make([]byte, 32))
|
||||||
|
|
||||||
|
for {
|
||||||
|
var src []byte
|
||||||
|
if len(din) == 0 {
|
||||||
|
break
|
||||||
|
} else if len(din) < MiB {
|
||||||
|
src, din = din, nil
|
||||||
|
} else {
|
||||||
|
src, din = din[:MiB], din[MiB:]
|
||||||
|
}
|
||||||
|
dst := make([]byte, len(src))
|
||||||
|
|
||||||
|
if mode == "encrypt" {
|
||||||
|
chacha.XORKeyStream(dst, src)
|
||||||
|
mac.Write(dst)
|
||||||
|
} else {
|
||||||
|
mac.Write(src)
|
||||||
|
chacha.XORKeyStream(dst, src)
|
||||||
|
}
|
||||||
|
dout = append(dout, dst...)
|
||||||
|
|
||||||
|
counter += MiB
|
||||||
|
if counter >= 60*GiB {
|
||||||
|
nonce = make([]byte, 24)
|
||||||
|
hkdf.Read(nonce)
|
||||||
|
chacha, _ = chacha20.NewUnauthenticatedCipher(key, nonce)
|
||||||
|
hkdf.Read(make([]byte, 16))
|
||||||
|
counter = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if mode == "encrypt" {
|
||||||
|
buff := rsEncode(rs64, keyHash)
|
||||||
|
buff = append(buff, rsEncode(rs32, make([]byte, 32))...)
|
||||||
|
buff = append(buff, rsEncode(rs64, mac.Sum(nil))...)
|
||||||
|
for i, v := range buff {
|
||||||
|
dout[309+i] = v
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !bytes.Equal(mac.Sum(nil), authTag) {
|
||||||
|
return []byte{4}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return append([]byte{0}, dout...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func rsEncode(rs *infectious.FEC, data []byte) []byte {
|
||||||
|
res := make([]byte, rs.Total())
|
||||||
|
rs.Encode(data, func(s infectious.Share) {
|
||||||
|
res[s.Number] = s.Data[0]
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func rsDecode(rs *infectious.FEC, data []byte) ([]byte, error) {
|
||||||
|
tmp := make([]infectious.Share, rs.Total())
|
||||||
|
for i := 0; i < rs.Total(); i++ {
|
||||||
|
tmp[i].Number = i
|
||||||
|
tmp[i].Data = []byte{data[i]}
|
||||||
|
}
|
||||||
|
res, err := rs.Decode(nil, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return data[:rs.Total()/3], err
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
quit := make(chan struct{}, 0)
|
||||||
|
document := js.Global().Get("document")
|
||||||
|
input := document.Call("getElementById", "fin")
|
||||||
|
button := document.Call("getElementById", "work")
|
||||||
|
callback := js.FuncOf(func(v js.Value, x []js.Value) any {
|
||||||
|
var dout []byte
|
||||||
|
data := js.Global().Get("Uint8Array").New(x[0])
|
||||||
|
din := make([]byte, data.Get("length").Int())
|
||||||
|
js.CopyBytesToGo(din, data)
|
||||||
|
password = document.Call("getElementById", "password").Get("value").String()
|
||||||
|
filename := input.Get("files").Call("item", 0).Get("name").String()
|
||||||
|
if strings.HasSuffix(filename, ".pcv") {
|
||||||
|
dout = work(din, "decrypt")
|
||||||
|
} else {
|
||||||
|
dout = work(din, "encrypt")
|
||||||
|
}
|
||||||
|
arr := js.Global().Get("Uint8Array").New(len(dout))
|
||||||
|
js.CopyBytesToJS(arr, dout)
|
||||||
|
js.Global().Call("download", arr)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
button.Set("onclick", js.FuncOf(func(v js.Value, x []js.Value) any {
|
||||||
|
input.Get("files").Call("item", 0).Call("arrayBuffer").Call("then", callback)
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
|
<-quit
|
||||||
|
}
|
202
web/index.html
Normal file
202
web/index.html
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue