mirror of
https://github.com/Picocrypt/Picocrypt.git
synced 2025-05-12 13:48:31 +02:00
Merge 0a061a20b8
into f0bfe3ba03
This commit is contained in:
commit
b2daa11a1c
6 changed files with 187 additions and 125 deletions
|
@ -1,6 +1,7 @@
|
||||||
# Future
|
# v1.48 (Released 04/11/2025)
|
||||||
<ul>
|
<ul>
|
||||||
<li>Migrate golang.org/x/crypto to standard library imports (https://github.com/golang/go/issues/65269)</li>
|
<li>✓ Allow pressing 'Enter' key to press Start/Process button</li>
|
||||||
|
<li>✓ Warn user when encrypting multiple files to an external drive</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
# v1.47 (Released 02/19/2025)
|
# v1.47 (Released 02/19/2025)
|
||||||
|
|
10
README.md
10
README.md
|
@ -18,8 +18,6 @@ Picocrypt is a very small (hence <i>Pico</i>), very simple, yet very secure encr
|
||||||
## Windows
|
## Windows
|
||||||
Picocrypt for Windows is as simple as it gets. To download the latest, standalone, and portable executable for Windows, click <a href="https://github.com/Picocrypt/Picocrypt/releases/latest/download/Picocrypt.exe">here</a>. If Microsoft Defender or your antivirus flags Picocrypt as a virus, please do your part and submit it as a false positive for the betterment of everyone.
|
Picocrypt for Windows is as simple as it gets. To download the latest, standalone, and portable executable for Windows, click <a href="https://github.com/Picocrypt/Picocrypt/releases/latest/download/Picocrypt.exe">here</a>. If Microsoft Defender or your antivirus flags Picocrypt as a virus, please do your part and submit it as a false positive for the betterment of everyone.
|
||||||
|
|
||||||
If you use Picocrypt frequently, you can download an installer <a href="https://github.com/Picocrypt/Picocrypt/releases/download/1.47/Install-Picocrypt.exe">here</a> for easier launching. It does not require any admin permissions to install and it also bundles a software OpenGL renderer for compatibility, so if the portable executable isn't working, this installer likely will.
|
|
||||||
|
|
||||||
## macOS
|
## macOS
|
||||||
Picocrypt for macOS is very simple as well. Download Picocrypt <a href="https://github.com/Picocrypt/Picocrypt/releases/latest/download/Picocrypt.dmg">here</a>, open the container, and drag Picocrypt to your Applications. You may need to manually trust the app from a terminal and control-click on the app if macOS prevents you from opening it:
|
Picocrypt for macOS is very simple as well. Download Picocrypt <a href="https://github.com/Picocrypt/Picocrypt/releases/latest/download/Picocrypt.dmg">here</a>, open the container, and drag Picocrypt to your Applications. You may need to manually trust the app from a terminal and control-click on the app if macOS prevents you from opening it:
|
||||||
```
|
```
|
||||||
|
@ -92,6 +90,14 @@ While being simple, Picocrypt also strives to be powerful in the hands of knowle
|
||||||
<li><strong>Recursively</strong>: If you want to encrypt and/or decrypt a large set of files individually, this option will tell Picocrypt to go through every recursive file that you drop in and encrypt/decrypt it separately. This is useful, for example, if you are encrypting thousands of large documents and want to be able to decrypt any one of them in particular without having to download and decrypt the entire set of documents. Keep in mind that this is a very complex feature that should only be used if you know what you are doing.</li>
|
<li><strong>Recursively</strong>: If you want to encrypt and/or decrypt a large set of files individually, this option will tell Picocrypt to go through every recursive file that you drop in and encrypt/decrypt it separately. This is useful, for example, if you are encrypting thousands of large documents and want to be able to decrypt any one of them in particular without having to download and decrypt the entire set of documents. Keep in mind that this is a very complex feature that should only be used if you know what you are doing.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
# Caveats
|
||||||
|
When encrypting multiple files, Picocrypt will automatically zip them into one file before encrypting it. However, this requires a two-step process that creates an unencrypted temporary `.zip.tmp` file in the same destination folder. This has two implications:
|
||||||
|
<ol>
|
||||||
|
<li>There must be at least double the available free space on the target drive as the combined total size of input files</li>
|
||||||
|
<li>The target drive must be safe to save confidential data; if not, the unencrypted temporary file may be recoverable even after deletion</li>
|
||||||
|
</ol>
|
||||||
|
To mitigate these caveats, Picocrypt will show info and warning labels accordingly. However, it is best to prevent these issues altogether <strong>by always encrypting and decrypting on your main host drive</strong> and then copying encrypted volumes to and from external sources, <strong>or zipping up input files beforehand and encrypting that single file</strong> which doesn't have these caveats.
|
||||||
|
|
||||||
# Security
|
# Security
|
||||||
For more information on how Picocrypt handles cryptography, see <a href="Internals.md">Internals</a> for the technical details. If you're worried about the safety of me or this project, let me assure you that this repository won't be hijacked or backdoored. I have 2FA (TOTP) enabled on all accounts with a tie to Picocrypt (GitHub, etc.), in addition to full-disk encryption on all of my portable devices. For further hardening, Picocrypt uses my isolated forks of dependencies and I fetch upstream only when I have taken a look at the changes and believe that there aren't any security issues. This means that if a dependency gets hacked or deleted by the author, Picocrypt will be using my fork of it and remain completely unaffected. I've also meticulously gone through every single setting in the Picocrypt organization and repos, locking down access behind multiple layers of security such as read-only base-level member permissions, required PRs and mandatory approvals (which no one can do but me), mandatory CODEOWNERS approvals, and I'm the only member of the Picocrypt organization and repos (except for PicoGo). You can feel confident about using Picocrypt as long as you understand:
|
For more information on how Picocrypt handles cryptography, see <a href="Internals.md">Internals</a> for the technical details. If you're worried about the safety of me or this project, let me assure you that this repository won't be hijacked or backdoored. I have 2FA (TOTP) enabled on all accounts with a tie to Picocrypt (GitHub, etc.), in addition to full-disk encryption on all of my portable devices. For further hardening, Picocrypt uses my isolated forks of dependencies and I fetch upstream only when I have taken a look at the changes and believe that there aren't any security issues. This means that if a dependency gets hacked or deleted by the author, Picocrypt will be using my fork of it and remain completely unaffected. I've also meticulously gone through every single setting in the Picocrypt organization and repos, locking down access behind multiple layers of security such as read-only base-level member permissions, required PRs and mandatory approvals (which no one can do but me), mandatory CODEOWNERS approvals, and I'm the only member of the Picocrypt organization and repos (except for PicoGo). You can feel confident about using Picocrypt as long as you understand:
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
1.47
|
1.48
|
253
src/Picocrypt.go
253
src/Picocrypt.go
|
@ -2,7 +2,7 @@ package main
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Picocrypt v1.47
|
Picocrypt v1.48
|
||||||
Copyright (c) Evan Su
|
Copyright (c) Evan Su
|
||||||
Released under a GNU GPL v3 License
|
Released under a GNU GPL v3 License
|
||||||
https://github.com/Picocrypt/Picocrypt
|
https://github.com/Picocrypt/Picocrypt
|
||||||
|
@ -30,6 +30,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -60,7 +61,7 @@ var TRANSPARENT = color.RGBA{0x00, 0x00, 0x00, 0x00}
|
||||||
|
|
||||||
// Generic variables
|
// Generic variables
|
||||||
var window *giu.MasterWindow
|
var window *giu.MasterWindow
|
||||||
var version = "v1.47"
|
var version = "v1.48"
|
||||||
var dpi float32
|
var dpi float32
|
||||||
var mode string
|
var mode string
|
||||||
var working bool
|
var working bool
|
||||||
|
@ -131,6 +132,9 @@ var mainStatus = "Ready"
|
||||||
var mainStatusColor = WHITE
|
var mainStatusColor = WHITE
|
||||||
var popupStatus string
|
var popupStatus string
|
||||||
|
|
||||||
|
var temporaryZip bool
|
||||||
|
var externalDst bool
|
||||||
|
|
||||||
// Progress variables
|
// Progress variables
|
||||||
var progress float32
|
var progress float32
|
||||||
var progressInfo string
|
var progressInfo string
|
||||||
|
@ -173,10 +177,117 @@ func (p *compressorProgress) Read(data []byte) (int, error) {
|
||||||
return read, err
|
return read, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var onClickStartButton = func() {
|
||||||
|
// Start button should be disabled if these conditions are true; don't do anything if so
|
||||||
|
if (len(keyfiles) == 0 && password == "") || (mode == "encrypt" && password != cpassword) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if keyfile && keyfiles == nil {
|
||||||
|
mainStatus = "Please select your keyfiles"
|
||||||
|
mainStatusColor = RED
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tmp, err := strconv.Atoi(splitSize)
|
||||||
|
if split && (splitSize == "" || tmp <= 0 || err != nil) {
|
||||||
|
mainStatus = "Invalid chunk size"
|
||||||
|
mainStatusColor = RED
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if output file already exists
|
||||||
|
_, err = os.Stat(outputFile)
|
||||||
|
|
||||||
|
// Check if any split chunks already exist
|
||||||
|
if split {
|
||||||
|
names, _ := filepath.Glob(outputFile + ".*")
|
||||||
|
if len(names) > 0 {
|
||||||
|
err = nil
|
||||||
|
} else {
|
||||||
|
err = os.ErrNotExist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If files already exist, show the overwrite modal
|
||||||
|
if err == nil && !recursively {
|
||||||
|
showOverwrite = true
|
||||||
|
modalId++
|
||||||
|
giu.Update()
|
||||||
|
} else { // Nothing to worry about, start working
|
||||||
|
showProgress = true
|
||||||
|
fastDecode = true
|
||||||
|
canCancel = true
|
||||||
|
modalId++
|
||||||
|
giu.Update()
|
||||||
|
if !recursively {
|
||||||
|
go func() {
|
||||||
|
work()
|
||||||
|
working = false
|
||||||
|
showProgress = false
|
||||||
|
giu.Update()
|
||||||
|
}()
|
||||||
|
} else {
|
||||||
|
// Store variables as they will be cleared
|
||||||
|
oldPassword := password
|
||||||
|
oldKeyfile := keyfile
|
||||||
|
oldKeyfiles := keyfiles
|
||||||
|
oldKeyfileOrdered := keyfileOrdered
|
||||||
|
oldKeyfileLabel := keyfileLabel
|
||||||
|
oldComments := comments
|
||||||
|
oldParanoid := paranoid
|
||||||
|
oldReedsolo := reedsolo
|
||||||
|
oldDeniability := deniability
|
||||||
|
oldSplit := split
|
||||||
|
oldSplitSize := splitSize
|
||||||
|
oldSplitSelected := splitSelected
|
||||||
|
oldDelete := delete
|
||||||
|
files := allFiles
|
||||||
|
go func() {
|
||||||
|
for _, file := range files {
|
||||||
|
// Simulate dropping the file
|
||||||
|
onDrop([]string{file})
|
||||||
|
|
||||||
|
// Restore variables and options
|
||||||
|
password = oldPassword
|
||||||
|
cpassword = oldPassword
|
||||||
|
keyfile = oldKeyfile
|
||||||
|
keyfiles = oldKeyfiles
|
||||||
|
keyfileOrdered = oldKeyfileOrdered
|
||||||
|
keyfileLabel = oldKeyfileLabel
|
||||||
|
comments = oldComments
|
||||||
|
paranoid = oldParanoid
|
||||||
|
reedsolo = oldReedsolo
|
||||||
|
deniability = oldDeniability
|
||||||
|
split = oldSplit
|
||||||
|
splitSize = oldSplitSize
|
||||||
|
splitSelected = oldSplitSelected
|
||||||
|
delete = oldDelete
|
||||||
|
|
||||||
|
work()
|
||||||
|
if !working {
|
||||||
|
resetUI()
|
||||||
|
cancel(nil, nil)
|
||||||
|
showProgress = false
|
||||||
|
giu.Update()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
working = false
|
||||||
|
showProgress = false
|
||||||
|
giu.Update()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The main user interface
|
// The main user interface
|
||||||
func draw() {
|
func draw() {
|
||||||
giu.SingleWindow().Flags(524351).Layout(
|
giu.SingleWindow().Flags(524351).Layout(
|
||||||
giu.Custom(func() {
|
giu.Custom(func() {
|
||||||
|
if giu.IsKeyReleased(giu.KeyEnter) {
|
||||||
|
onClickStartButton()
|
||||||
|
return
|
||||||
|
}
|
||||||
if showPassgen {
|
if showPassgen {
|
||||||
giu.PopupModal("Generate password:##"+strconv.Itoa(modalId)).Flags(6).Layout(
|
giu.PopupModal("Generate password:##"+strconv.Itoa(modalId)).Flags(6).Layout(
|
||||||
giu.Row(
|
giu.Row(
|
||||||
|
@ -499,7 +610,7 @@ func draw() {
|
||||||
giu.Checkbox("Paranoid mode", ¶noid),
|
giu.Checkbox("Paranoid mode", ¶noid),
|
||||||
giu.Tooltip("Provides the highest level of security attainable"),
|
giu.Tooltip("Provides the highest level of security attainable"),
|
||||||
giu.Dummy(-170, 0),
|
giu.Dummy(-170, 0),
|
||||||
giu.Style().SetDisabled(recursively).To(
|
giu.Style().SetDisabled(recursively || !(len(allFiles) > 1 || len(onlyFolders) > 0)).To(
|
||||||
giu.Checkbox("Compress files", &compress).OnChange(func() {
|
giu.Checkbox("Compress files", &compress).OnChange(func() {
|
||||||
if !(len(allFiles) > 1 || len(onlyFolders) > 0) {
|
if !(len(allFiles) > 1 || len(onlyFolders) > 0) {
|
||||||
if compress {
|
if compress {
|
||||||
|
@ -629,6 +740,21 @@ func draw() {
|
||||||
} else {
|
} else {
|
||||||
file += filepath.Ext(inputFile) + ".pcv"
|
file += filepath.Ext(inputFile) + ".pcv"
|
||||||
}
|
}
|
||||||
|
externalDst = false
|
||||||
|
GOOS := strings.ToLower(runtime.GOOS)
|
||||||
|
if strings.HasPrefix(GOOS, "windows") {
|
||||||
|
if !strings.HasPrefix(file, "C:") {
|
||||||
|
externalDst = true
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(GOOS, "linux") {
|
||||||
|
if strings.Contains(file, "/media/") || strings.Contains(file, "/mnt/") {
|
||||||
|
externalDst = true
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(GOOS, "darwin") {
|
||||||
|
if strings.Contains(file, "/Volumes/") {
|
||||||
|
externalDst = true
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if strings.HasSuffix(inputFile, ".zip.pcv") {
|
if strings.HasSuffix(inputFile, ".zip.pcv") {
|
||||||
file += ".zip"
|
file += ".zip"
|
||||||
|
@ -653,106 +779,32 @@ func draw() {
|
||||||
return startLabel
|
return startLabel
|
||||||
}
|
}
|
||||||
return "Process"
|
return "Process"
|
||||||
}()).Size(giu.Auto, 34).OnClick(func() {
|
}()).Size(giu.Auto, 34).OnClick(onClickStartButton),
|
||||||
if keyfile && keyfiles == nil {
|
giu.Custom(func() {
|
||||||
mainStatus = "Please select your keyfiles"
|
if mainStatus != "Ready" {
|
||||||
mainStatusColor = RED
|
giu.Style().SetColor(giu.StyleColorText, mainStatusColor).To(
|
||||||
|
giu.Label(mainStatus),
|
||||||
|
).Build()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tmp, err := strconv.Atoi(splitSize)
|
if temporaryZip && externalDst {
|
||||||
if split && (splitSize == "" || tmp <= 0 || err != nil) {
|
giu.Style().SetColor(giu.StyleColorText, YELLOW).To(
|
||||||
mainStatus = "Invalid chunk size"
|
giu.Label("Warning: unencrypted temp files will be created"),
|
||||||
mainStatusColor = RED
|
).Build()
|
||||||
return
|
} else if temporaryZip {
|
||||||
}
|
giu.Style().SetColor(giu.StyleColorText, WHITE).To(
|
||||||
|
giu.Label("Ready (info: will create a temporary zip file)"),
|
||||||
// Check if output file already exists
|
).Build()
|
||||||
_, err = os.Stat(outputFile)
|
} else if externalDst {
|
||||||
|
giu.Style().SetColor(giu.StyleColorText, WHITE).To(
|
||||||
// Check if any split chunks already exist
|
giu.Label("Ready (info: target may be an external drive)"),
|
||||||
if split {
|
).Build()
|
||||||
names, _ := filepath.Glob(outputFile + ".*")
|
} else {
|
||||||
if len(names) > 0 {
|
giu.Style().SetColor(giu.StyleColorText, mainStatusColor).To(
|
||||||
err = nil
|
giu.Label("Ready"),
|
||||||
} else {
|
).Build()
|
||||||
err = os.ErrNotExist
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If files already exist, show the overwrite modal
|
|
||||||
if err == nil && !recursively {
|
|
||||||
showOverwrite = true
|
|
||||||
modalId++
|
|
||||||
giu.Update()
|
|
||||||
} else { // Nothing to worry about, start working
|
|
||||||
showProgress = true
|
|
||||||
fastDecode = true
|
|
||||||
canCancel = true
|
|
||||||
modalId++
|
|
||||||
giu.Update()
|
|
||||||
if !recursively {
|
|
||||||
go func() {
|
|
||||||
work()
|
|
||||||
working = false
|
|
||||||
showProgress = false
|
|
||||||
giu.Update()
|
|
||||||
}()
|
|
||||||
} else {
|
|
||||||
// Store variables as they will be cleared
|
|
||||||
oldPassword := password
|
|
||||||
oldKeyfile := keyfile
|
|
||||||
oldKeyfiles := keyfiles
|
|
||||||
oldKeyfileOrdered := keyfileOrdered
|
|
||||||
oldKeyfileLabel := keyfileLabel
|
|
||||||
oldComments := comments
|
|
||||||
oldParanoid := paranoid
|
|
||||||
oldReedsolo := reedsolo
|
|
||||||
oldDeniability := deniability
|
|
||||||
oldSplit := split
|
|
||||||
oldSplitSize := splitSize
|
|
||||||
oldSplitSelected := splitSelected
|
|
||||||
oldDelete := delete
|
|
||||||
files := allFiles
|
|
||||||
go func() {
|
|
||||||
for _, file := range files {
|
|
||||||
// Simulate dropping the file
|
|
||||||
onDrop([]string{file})
|
|
||||||
|
|
||||||
// Restore variables and options
|
|
||||||
password = oldPassword
|
|
||||||
cpassword = oldPassword
|
|
||||||
keyfile = oldKeyfile
|
|
||||||
keyfiles = oldKeyfiles
|
|
||||||
keyfileOrdered = oldKeyfileOrdered
|
|
||||||
keyfileLabel = oldKeyfileLabel
|
|
||||||
comments = oldComments
|
|
||||||
paranoid = oldParanoid
|
|
||||||
reedsolo = oldReedsolo
|
|
||||||
deniability = oldDeniability
|
|
||||||
split = oldSplit
|
|
||||||
splitSize = oldSplitSize
|
|
||||||
splitSelected = oldSplitSelected
|
|
||||||
delete = oldDelete
|
|
||||||
|
|
||||||
work()
|
|
||||||
if !working {
|
|
||||||
resetUI()
|
|
||||||
cancel(nil, nil)
|
|
||||||
showProgress = false
|
|
||||||
giu.Update()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
working = false
|
|
||||||
showProgress = false
|
|
||||||
giu.Update()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
giu.Style().SetColor(giu.StyleColorText, mainStatusColor).To(
|
|
||||||
giu.Label(mainStatus),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
|
||||||
giu.Custom(func() {
|
giu.Custom(func() {
|
||||||
|
@ -989,6 +1041,7 @@ func onDrop(names []string) {
|
||||||
// Set the input and output paths
|
// Set the input and output paths
|
||||||
inputFile = filepath.Join(filepath.Dir(names[0]), "Encrypted") + ".zip"
|
inputFile = filepath.Join(filepath.Dir(names[0]), "Encrypted") + ".zip"
|
||||||
outputFile = inputFile + ".pcv"
|
outputFile = inputFile + ".pcv"
|
||||||
|
temporaryZip = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively add all files in 'onlyFolders' to 'allFiles'
|
// Recursively add all files in 'onlyFolders' to 'allFiles'
|
||||||
|
@ -2251,6 +2304,8 @@ func resetUI() {
|
||||||
mainStatus = "Ready"
|
mainStatus = "Ready"
|
||||||
mainStatusColor = WHITE
|
mainStatusColor = WHITE
|
||||||
popupStatus = ""
|
popupStatus = ""
|
||||||
|
temporaryZip = false
|
||||||
|
externalDst = false
|
||||||
|
|
||||||
progress = 0
|
progress = 0
|
||||||
progressInfo = ""
|
progressInfo = ""
|
||||||
|
|
14
src/go.mod
14
src/go.mod
|
@ -3,18 +3,18 @@ module Picocrypt
|
||||||
go 1.24.2
|
go 1.24.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Picocrypt/dialog v0.0.0-20240831001746-9ca708a9cd29
|
github.com/Picocrypt/dialog v0.0.0-20250412233924-78f7b909315b
|
||||||
github.com/Picocrypt/giu v0.0.0-20240831005244-5771b35043ac
|
github.com/Picocrypt/giu v0.0.0-20250412235908-fe90a482e6f2
|
||||||
github.com/Picocrypt/imgui-go v0.0.0-20240831004007-6f60d7beadf6
|
github.com/Picocrypt/imgui-go v0.0.0-20250412235405-d86b230f5fbb
|
||||||
github.com/Picocrypt/infectious v0.0.0-20240830233326-3a050f65f9ec
|
github.com/Picocrypt/infectious v0.0.0-20250412183341-9f88c6307b39
|
||||||
github.com/Picocrypt/serpent v0.0.0-20240830233833-9ad6ab254fd7
|
github.com/Picocrypt/serpent v0.0.0-20240830233833-9ad6ab254fd7
|
||||||
github.com/Picocrypt/zxcvbn-go v0.0.0-20240831000415-fccb38ccb913
|
github.com/Picocrypt/zxcvbn-go v0.0.0-20250412183938-d59695960527
|
||||||
golang.org/x/crypto v0.37.0
|
golang.org/x/crypto v0.37.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Picocrypt/gl v0.0.0-20240831002619-6531d2bba5fc // indirect
|
github.com/Picocrypt/gl v0.0.0-20250412234430-767b58dbf936 // indirect
|
||||||
github.com/Picocrypt/glfw/v3.3/glfw v0.0.0-20240831003212-7f16c5fb374b // indirect
|
github.com/Picocrypt/glfw/v3.3/glfw v0.0.0-20250412234750-7b96bfdb8dd8 // indirect
|
||||||
github.com/Picocrypt/mainthread v0.0.0-20240831004314-496f638392b3 // indirect
|
github.com/Picocrypt/mainthread v0.0.0-20240831004314-496f638392b3 // indirect
|
||||||
github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57 // indirect
|
github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57 // indirect
|
||||||
golang.org/x/sys v0.32.0 // indirect
|
golang.org/x/sys v0.32.0 // indirect
|
||||||
|
|
28
src/go.sum
28
src/go.sum
|
@ -1,23 +1,23 @@
|
||||||
github.com/Picocrypt/dialog v0.0.0-20240831001746-9ca708a9cd29 h1:WIgRST/mpLiBEG2MF5MRPBDYYevLw7y14cwUEDjG5+Q=
|
github.com/Picocrypt/dialog v0.0.0-20250412233924-78f7b909315b h1:k5YGEx61N6K8l2l6AQ1u5W2aR+47sVZWFyqXS/f5lIA=
|
||||||
github.com/Picocrypt/dialog v0.0.0-20240831001746-9ca708a9cd29/go.mod h1:raXVkdcX4495+fW9Ac+kvPMHRNk0rOcNXEWFD71B2As=
|
github.com/Picocrypt/dialog v0.0.0-20250412233924-78f7b909315b/go.mod h1:OyaP0Tz19qL3RAGq5Ntues+WVrIbHh5MrfqoA/qhqeg=
|
||||||
github.com/Picocrypt/giu v0.0.0-20240831005244-5771b35043ac h1:Z21enGbi450NyI7UZSoEuu//axifyGl63BJVjHX3ZXc=
|
github.com/Picocrypt/giu v0.0.0-20250412235908-fe90a482e6f2 h1:SPR2efZTpZJON/2mNifLi68Gl9Epxh/1nXb3kGGHCcg=
|
||||||
github.com/Picocrypt/giu v0.0.0-20240831005244-5771b35043ac/go.mod h1:x7jbmZVofU9rn5WJj2+riU85Zo0MFlfp1sMTnKFQhc0=
|
github.com/Picocrypt/giu v0.0.0-20250412235908-fe90a482e6f2/go.mod h1:jd6AonK0ZI02R7GqLWb4gWJz/A2ClF36Y4fFMR8Lzbk=
|
||||||
github.com/Picocrypt/gl v0.0.0-20240831002619-6531d2bba5fc h1:5ckKMFhiz/Af6+sdkGlw74BU+rKRmoFWqU/rXHGUe3g=
|
github.com/Picocrypt/gl v0.0.0-20250412234430-767b58dbf936 h1:6MChjQ4AZC2ISBjbgZU/z6tSUxYP50NkRvAu0T2kjlY=
|
||||||
github.com/Picocrypt/gl v0.0.0-20240831002619-6531d2bba5fc/go.mod h1:VknKAZzEoKP9nqrc/dveCwR5L01B9V8yLqtpvYmQ3DA=
|
github.com/Picocrypt/gl v0.0.0-20250412234430-767b58dbf936/go.mod h1:pMdf3io/y3I+zYZ6/xFb3MlI2AgL38enDDIKuR0n2qA=
|
||||||
github.com/Picocrypt/glfw/v3.3/glfw v0.0.0-20240831003212-7f16c5fb374b h1:hSaQU4P9KbMg9s2Jp2mTk9G5G+zkf4Yse5YRoxWTDTk=
|
github.com/Picocrypt/glfw/v3.3/glfw v0.0.0-20250412234750-7b96bfdb8dd8 h1:i8wXJhSYIJTXb6sqBS6JZW7QosI9u8Ysy1BHZCTuZEc=
|
||||||
github.com/Picocrypt/glfw/v3.3/glfw v0.0.0-20240831003212-7f16c5fb374b/go.mod h1:r5awTCSm/ugmTRKmT8Hr0T4xGPI6K35eFK0s3jYCW+s=
|
github.com/Picocrypt/glfw/v3.3/glfw v0.0.0-20250412234750-7b96bfdb8dd8/go.mod h1:cX5N2TrX03DC5i5eplxopglDue/vHDs+6Ng9G9uItaI=
|
||||||
github.com/Picocrypt/imgui-go v0.0.0-20240831004007-6f60d7beadf6 h1:Y6SuxbSkQSU1hdEOpoMvp6Akq3RVX6KP1U4pKjGv3qo=
|
github.com/Picocrypt/imgui-go v0.0.0-20250412235405-d86b230f5fbb h1:0XMtv2CXx3QvC9ikeH43fJl6ql8j5EsnaiOqhsToFnY=
|
||||||
github.com/Picocrypt/imgui-go v0.0.0-20240831004007-6f60d7beadf6/go.mod h1:mGfOCkgyafVMIs1tU70va3lFSh6hSb+Vq4paVLX1Fjg=
|
github.com/Picocrypt/imgui-go v0.0.0-20250412235405-d86b230f5fbb/go.mod h1:N+NVTIIMz6icYltvaKHMvmVIllZDYUyscJ8wpcLKDZ4=
|
||||||
github.com/Picocrypt/infectious v0.0.0-20240830233326-3a050f65f9ec h1:/cop0/v0HxIJm1XGDgIlzNJ3e4HhM8nIUPZi5RZ/n1w=
|
github.com/Picocrypt/infectious v0.0.0-20250412183341-9f88c6307b39 h1:czHyPoiNrILv9xjfQ87UFllJgak8W6gVcYkmfOay/BE=
|
||||||
github.com/Picocrypt/infectious v0.0.0-20240830233326-3a050f65f9ec/go.mod h1:aaFq/WMVxrU2Exl/tXbTFSXajZrqw0mgn/wi42n0fK4=
|
github.com/Picocrypt/infectious v0.0.0-20250412183341-9f88c6307b39/go.mod h1:2ZVEanURxuWmxYZ6W6xMMy4ZR6xmQr16Vq/XPTLIspQ=
|
||||||
github.com/Picocrypt/mainthread v0.0.0-20240831004314-496f638392b3 h1:a62XmbZYhHGDR15C1gxp/IPfJX5SflrJuGpqNoOOK7w=
|
github.com/Picocrypt/mainthread v0.0.0-20240831004314-496f638392b3 h1:a62XmbZYhHGDR15C1gxp/IPfJX5SflrJuGpqNoOOK7w=
|
||||||
github.com/Picocrypt/mainthread v0.0.0-20240831004314-496f638392b3/go.mod h1:bsUKeX+/53rCTrItl3YUaeaN5tXl1v6326ZI90xIOsc=
|
github.com/Picocrypt/mainthread v0.0.0-20240831004314-496f638392b3/go.mod h1:bsUKeX+/53rCTrItl3YUaeaN5tXl1v6326ZI90xIOsc=
|
||||||
github.com/Picocrypt/serpent v0.0.0-20240830233833-9ad6ab254fd7 h1:G36G2vmQAS7CVoHQrHDGAoCWll/0kPCI8Dk7mgwcJFE=
|
github.com/Picocrypt/serpent v0.0.0-20240830233833-9ad6ab254fd7 h1:G36G2vmQAS7CVoHQrHDGAoCWll/0kPCI8Dk7mgwcJFE=
|
||||||
github.com/Picocrypt/serpent v0.0.0-20240830233833-9ad6ab254fd7/go.mod h1:BxsgRYwUVd92aEwXnXsfXfHw8aHlD/PUyExC/wwk9oI=
|
github.com/Picocrypt/serpent v0.0.0-20240830233833-9ad6ab254fd7/go.mod h1:BxsgRYwUVd92aEwXnXsfXfHw8aHlD/PUyExC/wwk9oI=
|
||||||
github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57 h1:jusSXTp0h5wz8lxNXStw0jXr/ogZF6rzRF8gu0534hA=
|
github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57 h1:jusSXTp0h5wz8lxNXStw0jXr/ogZF6rzRF8gu0534hA=
|
||||||
github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57/go.mod h1:FkeZHdKlITdP34VknO8yLdRY5pCi+iWEhDSA0YsBhZc=
|
github.com/Picocrypt/w32 v0.0.0-20240831001500-1183079d4d57/go.mod h1:FkeZHdKlITdP34VknO8yLdRY5pCi+iWEhDSA0YsBhZc=
|
||||||
github.com/Picocrypt/zxcvbn-go v0.0.0-20240831000415-fccb38ccb913 h1:QGv9QiTkNZ2iRmXEd7nNopaUJMBhBdBcsvWPl+v51AY=
|
github.com/Picocrypt/zxcvbn-go v0.0.0-20250412183938-d59695960527 h1:IqypAzv5COsByMhiSdwlgafA5SBRG7Z0binnBSo3htM=
|
||||||
github.com/Picocrypt/zxcvbn-go v0.0.0-20240831000415-fccb38ccb913/go.mod h1:dMyJ/0E4MeBo2wH1ZYmvPTChnYSj2MjLUndvYQt0vGw=
|
github.com/Picocrypt/zxcvbn-go v0.0.0-20250412183938-d59695960527/go.mod h1:u0rcUNEwy7st1DnPxdOJdTsh0aSRhrdMOxlIGrXR1Ls=
|
||||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||||
|
|
Loading…
Add table
Reference in a new issue