Skip to content

Commit 5352d97

Browse files
authored
Add files via upload
1 parent 3457803 commit 5352d97

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

esub.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package main
2+
3+
import (
4+
"crypto/rand"
5+
"crypto/sha3"
6+
"encoding/hex"
7+
"flag"
8+
"fmt"
9+
"golang.org/x/crypto/argon2"
10+
"golang.org/x/crypto/chacha20"
11+
"os"
12+
)
13+
14+
type esub struct {
15+
key string
16+
subject string
17+
}
18+
19+
func (e *esub) deriveKey() []byte {
20+
// Argon2id parameters (adjust time/memory/threads as needed)
21+
salt := []byte("fixed-salt-1234") // Use a unique, constant salt (or randomize & store it)
22+
key := argon2.IDKey(
23+
[]byte(e.key),
24+
salt,
25+
3, // iterations
26+
64*1024, // 64MB memory
27+
4, // threads
28+
32, // output key length (32 bytes for ChaCha20)
29+
)
30+
return key
31+
}
32+
33+
func (e *esub) esubtest() bool {
34+
if len(e.subject) != 48 { // 48 hex chars = 24 bytes
35+
return false
36+
}
37+
38+
esubBytes, err := hex.DecodeString(e.subject)
39+
if err != nil || len(esubBytes) != 24 {
40+
return false
41+
}
42+
43+
nonce := esubBytes[:12]
44+
receivedCiphertext := esubBytes[12:]
45+
46+
key := e.deriveKey()
47+
cipher, err := chacha20.NewUnauthenticatedCipher(key, nonce)
48+
if err != nil {
49+
return false
50+
}
51+
52+
// Hash "text" with SHA-256 (better than RIPEMD-160)
53+
textHash := sha3.Sum256([]byte("text"))
54+
expectedCiphertext := make([]byte, 12)
55+
cipher.XORKeyStream(expectedCiphertext, textHash[:12])
56+
57+
return hex.EncodeToString(expectedCiphertext) == hex.EncodeToString(receivedCiphertext)
58+
}
59+
60+
func (e *esub) esubgen() string {
61+
nonce := make([]byte, 12)
62+
if _, err := rand.Read(nonce); err != nil {
63+
panic(err)
64+
}
65+
66+
key := e.deriveKey()
67+
cipher, err := chacha20.NewUnauthenticatedCipher(key, nonce)
68+
if err != nil {
69+
panic(err)
70+
}
71+
72+
textHash := sha3.Sum256([]byte("text"))
73+
ciphertext := make([]byte, 12)
74+
cipher.XORKeyStream(ciphertext, textHash[:12])
75+
76+
return hex.EncodeToString(append(nonce, ciphertext...))
77+
}
78+
79+
func main() {
80+
flag.Parse()
81+
cmdargs := flag.Args()
82+
switch len(cmdargs) {
83+
case 1:
84+
e := new(esub)
85+
e.key = cmdargs[0]
86+
fmt.Println(e.esubgen())
87+
case 2:
88+
e := new(esub)
89+
e.key = cmdargs[0]
90+
e.subject = cmdargs[1]
91+
if !e.esubtest() {
92+
fmt.Println("Fail: esub not generated with this key")
93+
os.Exit(1)
94+
}
95+
fmt.Println("Validated: esub is valid for this key")
96+
default:
97+
fmt.Println("Usage: esub <key> [subject]")
98+
os.Exit(2)
99+
}
100+
}

go.mod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module esub
2+
3+
go 1.24.2
4+
5+
require golang.org/x/crypto v0.37.0
6+
7+
require golang.org/x/sys v0.32.0 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
2+
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
3+
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
4+
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=

0 commit comments

Comments
 (0)