Compare commits
10 Commits
f644038a63
...
9d9ab04c55
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9d9ab04c55 | ||
![]() |
092f877fe1 | ||
![]() |
f8c18022ae | ||
![]() |
c3cb8eaf83 | ||
![]() |
dacdf6dcd3 | ||
![]() |
1fa9a9b36b | ||
![]() |
85c4925141 | ||
![]() |
6ca10dffc9 | ||
![]() |
e63fc0fa77 | ||
![]() |
3690ff2a59 |
49
Go/main.go
Normal file
49
Go/main.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"flag"
|
||||||
|
"math"
|
||||||
|
"strings"
|
||||||
|
"one-time-pad-utils/otp_generate"
|
||||||
|
"one-time-pad-utils/otp_encrypt"
|
||||||
|
"one-time-pad-utils/otp_decrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main(){
|
||||||
|
var genpad = flag.Bool("generate", false, "Generate a new One-Time Pad using CSPRNG")
|
||||||
|
var genpadchunks = flag.Int("chunks", 200, "Specify the amount of chunks to generate")
|
||||||
|
var encryptmessage = flag.String("encrypt", "", "Specify a message you wish to encrypt (use quotes if you have spaces)")
|
||||||
|
var decryptmessage = flag.String("decrypt", "", "Specify a message you wish to decrypt (use quotes if you have spaces)")
|
||||||
|
var otpkey = flag.String("key", "", "The specify a key for encryption (optional) and decryption (required) (use quotes if you have spaces)")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *genpad {
|
||||||
|
fmt.Printf("%v\n", otpgenerate.GenerateOTP(*genpadchunks))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if *encryptmessage != "" {
|
||||||
|
if *otpkey != ""{
|
||||||
|
fmt.Printf("%v\n", otpencrypt.OTPEncrypt(*encryptmessage,*otpkey))
|
||||||
|
} else {
|
||||||
|
encryptmessagestring := strings.Replace(*encryptmessage, " ", "", -1)
|
||||||
|
lenofmessage := math.Ceil(float64(len(encryptmessagestring))/float64(5))
|
||||||
|
generated_key := otpgenerate.GenerateOTP(int(lenofmessage))
|
||||||
|
fmt.Printf("GENERATED NEW KEY SINCE NONE WAS SPECIFIED:\n%v\n\n%v\n", generated_key, otpencrypt.OTPEncrypt(*encryptmessage, generated_key))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if *decryptmessage != "" {
|
||||||
|
if *otpkey != ""{
|
||||||
|
fmt.Printf("%v\n", otpdecrypt.OTPDecrypt(*decryptmessage,*otpkey))
|
||||||
|
} else {
|
||||||
|
fmt.Println("PLEASE SUPPLY A KEY")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
flag.PrintDefaults()
|
||||||
|
}
|
47
Go/otp_decrypt/otp_decrypt.go
Normal file
47
Go/otp_decrypt/otp_decrypt.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package otpdecrypt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"one-time-pad-utils/pad_definitions"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OTPDecrypt(message string, key string) string {
|
||||||
|
message = strings.Replace(message, " ", "", -1)
|
||||||
|
messagesplit := strings.Split(message,"")
|
||||||
|
var messagesplitint []int
|
||||||
|
|
||||||
|
key = strings.Replace(key, " ", "", -1)
|
||||||
|
keysplit := strings.Split(key,"")
|
||||||
|
var keysplitint []int
|
||||||
|
|
||||||
|
for _, char := range messagesplit {
|
||||||
|
for n, c := range paddefinitions.NumToCharMap{
|
||||||
|
if c == strings.ToUpper(char) {
|
||||||
|
messagesplitint = append(messagesplitint, n)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, char := range keysplit {
|
||||||
|
for n, c := range paddefinitions.NumToCharMap{
|
||||||
|
if c == strings.ToUpper(char) {
|
||||||
|
keysplitint = append(keysplitint, n)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(keysplitint) < len(messagesplitint) {
|
||||||
|
return ("KEY TOO SHORT TO DECRYPT MESSAGE")
|
||||||
|
}
|
||||||
|
|
||||||
|
var decryptedmessage []string
|
||||||
|
|
||||||
|
for pos, messagenum := range messagesplitint{
|
||||||
|
decryptedmessage = append(decryptedmessage, paddefinitions.NumToCharMap[(((messagenum - keysplitint[pos]) % 35) + 35) % 35]) // crazy modulo for decryption
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return (strings.Join(decryptedmessage, ""))
|
||||||
|
}
|
49
Go/otp_encrypt/otp_encrypt.go
Normal file
49
Go/otp_encrypt/otp_encrypt.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package otpencrypt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"one-time-pad-utils/pad_definitions"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OTPEncrypt(message string, key string) string {
|
||||||
|
message = strings.Replace(message, " ", "", -1)
|
||||||
|
messagesplit := strings.Split(message,"")
|
||||||
|
var messagesplitint []int
|
||||||
|
|
||||||
|
key = strings.Replace(key, " ", "", -1)
|
||||||
|
keysplit := strings.Split(key,"")
|
||||||
|
var keysplitint []int
|
||||||
|
|
||||||
|
for _, char := range messagesplit {
|
||||||
|
for n, c := range paddefinitions.NumToCharMap{
|
||||||
|
if c == strings.ToUpper(char) {
|
||||||
|
messagesplitint = append(messagesplitint, n)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, char := range keysplit {
|
||||||
|
for n, c := range paddefinitions.NumToCharMap{
|
||||||
|
if c == strings.ToUpper(char) {
|
||||||
|
keysplitint = append(keysplitint, n)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(keysplitint) < len(messagesplitint) {
|
||||||
|
return ("KEY TOO SHORT TO ENCRYPT MESSAGE")
|
||||||
|
}
|
||||||
|
|
||||||
|
var encryptedmessage []string
|
||||||
|
|
||||||
|
for pos, messagenum := range messagesplitint{
|
||||||
|
if pos != 0 && pos % 5 == 0 {
|
||||||
|
encryptedmessage = append(encryptedmessage, " ")
|
||||||
|
}
|
||||||
|
encryptedmessage = append(encryptedmessage, paddefinitions.NumToCharMap[(messagenum + keysplitint[pos]) % 35])
|
||||||
|
}
|
||||||
|
|
||||||
|
return (strings.Join(encryptedmessage, ""))
|
||||||
|
}
|
33
Go/otp_generate/otp_gen.go
Normal file
33
Go/otp_generate/otp_gen.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//One-Time Pad generator
|
||||||
|
|
||||||
|
package otpgenerate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"math/big"
|
||||||
|
"one-time-pad-utils/pad_definitions"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func GenerateOTP(chunks int) string {
|
||||||
|
count := 1
|
||||||
|
otpstring := ""
|
||||||
|
|
||||||
|
for count < (chunks*5)+1{
|
||||||
|
n, err := rand.Int(rand.Reader, big.NewInt(36)) // generate new cryptographically secure random number
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
otpstring += paddefinitions.NumToCharMap[int(n.Int64())] // print that number using the character map
|
||||||
|
if count % 5 == 0 { // add a space every 5 characters, newline after 10 chunks
|
||||||
|
if count % 50 == 0{
|
||||||
|
otpstring += "\n"
|
||||||
|
} else {
|
||||||
|
otpstring += " "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count+=1
|
||||||
|
}
|
||||||
|
|
||||||
|
return otpstring
|
||||||
|
}
|
40
Go/pad_definitions/pad_definitions.go
Normal file
40
Go/pad_definitions/pad_definitions.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package paddefinitions
|
||||||
|
|
||||||
|
var NumToCharMap = map[int]string{
|
||||||
|
0: "9",
|
||||||
|
1: "A",
|
||||||
|
2: "B",
|
||||||
|
3: "C",
|
||||||
|
4: "D",
|
||||||
|
5: "E",
|
||||||
|
6: "F",
|
||||||
|
7: "G",
|
||||||
|
8: "H",
|
||||||
|
9: "I",
|
||||||
|
10: "J",
|
||||||
|
11: "K",
|
||||||
|
12: "L",
|
||||||
|
13: "M",
|
||||||
|
14: "N",
|
||||||
|
15: "O",
|
||||||
|
16: "P",
|
||||||
|
17: "Q",
|
||||||
|
18: "R",
|
||||||
|
19: "S",
|
||||||
|
20: "T",
|
||||||
|
21: "U",
|
||||||
|
22: "V",
|
||||||
|
23: "W",
|
||||||
|
24: "X",
|
||||||
|
25: "Y",
|
||||||
|
26: "Z",
|
||||||
|
27: "0",
|
||||||
|
28: "1",
|
||||||
|
29: "2",
|
||||||
|
30: "3",
|
||||||
|
31: "4",
|
||||||
|
32: "5",
|
||||||
|
33: "6",
|
||||||
|
34: "7",
|
||||||
|
35: "8",
|
||||||
|
}
|
BIN
Instructions/alternate-chart.odt
Normal file
BIN
Instructions/alternate-chart.odt
Normal file
Binary file not shown.
BIN
Instructions/alternate-chart.pdf
Normal file
BIN
Instructions/alternate-chart.pdf
Normal file
Binary file not shown.
BIN
Instructions/dice-one-time-pad.odt
Normal file
BIN
Instructions/dice-one-time-pad.odt
Normal file
Binary file not shown.
BIN
Instructions/dice-one-time-pad.pdf
Normal file
BIN
Instructions/dice-one-time-pad.pdf
Normal file
Binary file not shown.
17
README.md
17
README.md
@@ -1,3 +1,16 @@
|
|||||||
# dice-one-time-pad
|
# 🎲 Dice One-Time Pads:
|
||||||
|
A technique to make uncrackable encrypted messages using two six-sided die.
|
||||||
|
### 📄 [Main Instructions](https://code.lexza.ch/Lexzach/dice-one-time-pad/raw/branch/main/Instructions/dice-one-time-pad.pdf)
|
||||||
|
### 🔢 [Alternate Chart](https://code.lexza.ch/Lexzach/dice-one-time-pad/raw/branch/main/Instructions/alternate-chart.pdf)
|
||||||
|
If you have a less security critical use of this One-Time Pad technique, you can use the [program written in Go](https://code.lexza.ch/Lexzach/dice-one-time-pad/src/branch/main/Go) within this repository to greatly speed up the key generation, encryption, and decryption process. This program is 100% compatible with the manual method, but is less secure because of the [CSPRNG](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) utilized as opposed to the (effectively) true random numbers of a dice.
|
||||||
|
|
||||||
A technique for generating entirely offline one time pads.
|
### How does this all work?
|
||||||
|
([Wikipedia](https://en.wikipedia.org/wiki/One-time_pad))<br>
|
||||||
|
One-time pads are a method of encryption which, if done right, result in a message that is *literally impossible* to decrypt without the key. The absolute beauty of this encryption method is that it's *extremely* easy to implement ***by hand***.<br>
|
||||||
|
However, there are four conditions that must be true for this encryption method to truly be unbreakable:
|
||||||
|
- The key must be as long as the message you wish to encrypt.
|
||||||
|
- The key must be generated using truly random methods. (which the Go program is ***not***)
|
||||||
|
- The key must never be reused.
|
||||||
|
- The key must be kept a complete secret.
|
||||||
|
<br><br>
|
||||||
|
In order to comply with the second condition, two regular 6 sided die will be used to generate the key for encryption and decryption.
|
||||||
|
Reference in New Issue
Block a user