feat: Port crypt library from Core
This commit ports the crypt library from the Core repository to the Enchantrix repository. It includes the following changes: - The project is now a Go module. - The `lthn` and `crypt` packages have been ported from the Core repository. - The PGP functionality has been commented out pending resolution of dependency issues. - The old Deno project has been moved to the `vault` directory. - The README has been updated to reflect the new project structure.
This commit is contained in:
parent
ff59745c7d
commit
c1434a45ce
15 changed files with 322 additions and 11 deletions
21
README.md
21
README.md
|
|
@ -1,16 +1,15 @@
|
|||
# Enchantrix
|
||||
|
||||
The Little CryptoSuite that could.
|
||||
Enchantrix is a Go-based encryption library for the Core framework, designed to provide a secure and easy-to-use framework for handling sensitive data in Web3 applications. It will feature Poly-ChaCha stream proxying and a custom `.trix` file format for encrypted data.
|
||||
|
||||
## Test-Driven Development
|
||||
|
||||
This project follows a strict Test-Driven Development (TDD) methodology. All new functionality must be accompanied by a comprehensive suite of tests.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To get started with Enchantrix, you'll need to have Go installed. You can then run the tests using the following command:
|
||||
|
||||
```shell
|
||||
deno test
|
||||
go test ./...
|
||||
```
|
||||
|
||||
This is used in Lethean, however; is not for DIRECT code-level public use, misuse of this software, can result in criminal charges, on you, not me.
|
||||
|
||||
Do not edit, EXTEND or otherwise play with ANY variable, unless you UNDERSTAND to silicon, what you are doing.
|
||||
|
||||
[Read Before Use](DISCLAIMER.md) you've been warned.
|
||||
|
||||
- ffmpeg
|
||||
`deno run --unstable --allow-read --allow-run https://github.com/Snider/Enchatrix/lib/media/video/fmpeg.ts`
|
||||
|
|
|
|||
148
crypt.go
Normal file
148
crypt.go
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
package crypt
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Snider/Enchantrix/lthn"
|
||||
)
|
||||
|
||||
// HashType defines the supported hashing algorithms.
|
||||
type HashType string
|
||||
|
||||
const (
|
||||
LTHN HashType = "lthn"
|
||||
SHA512 HashType = "sha512"
|
||||
SHA256 HashType = "sha256"
|
||||
SHA1 HashType = "sha1"
|
||||
MD5 HashType = "md5"
|
||||
)
|
||||
|
||||
// --- Hashing ---
|
||||
|
||||
// Hash computes a hash of the payload using the specified algorithm.
|
||||
func Hash(lib HashType, payload string) string {
|
||||
switch lib {
|
||||
case LTHN:
|
||||
return lthn.Hash(payload)
|
||||
case SHA512:
|
||||
hash := sha512.Sum512([]byte(payload))
|
||||
return hex.EncodeToString(hash[:])
|
||||
case SHA1:
|
||||
hash := sha1.Sum([]byte(payload))
|
||||
return hex.EncodeToString(hash[:])
|
||||
case MD5:
|
||||
hash := md5.Sum([]byte(payload))
|
||||
return hex.EncodeToString(hash[:])
|
||||
case SHA256:
|
||||
fallthrough
|
||||
default:
|
||||
hash := sha256.Sum256([]byte(payload))
|
||||
return hex.EncodeToString(hash[:])
|
||||
}
|
||||
}
|
||||
|
||||
// --- Checksums ---
|
||||
|
||||
// Luhn validates a number using the Luhn algorithm.
|
||||
func Luhn(payload string) bool {
|
||||
payload = strings.ReplaceAll(payload, " ", "")
|
||||
sum := 0
|
||||
isSecond := false
|
||||
for i := len(payload) - 1; i >= 0; i-- {
|
||||
digit, err := strconv.Atoi(string(payload[i]))
|
||||
if err != nil {
|
||||
return false // Contains non-digit
|
||||
}
|
||||
|
||||
if isSecond {
|
||||
digit = digit * 2
|
||||
if digit > 9 {
|
||||
digit = digit - 9
|
||||
}
|
||||
}
|
||||
|
||||
sum += digit
|
||||
isSecond = !isSecond
|
||||
}
|
||||
return sum%10 == 0
|
||||
}
|
||||
|
||||
// Fletcher16 computes the Fletcher-16 checksum.
|
||||
func Fletcher16(payload string) uint16 {
|
||||
data := []byte(payload)
|
||||
var sum1, sum2 uint16
|
||||
for _, b := range data {
|
||||
sum1 = (sum1 + uint16(b)) % 255
|
||||
sum2 = (sum2 + sum1) % 255
|
||||
}
|
||||
return (sum2 << 8) | sum1
|
||||
}
|
||||
|
||||
// Fletcher32 computes the Fletcher-32 checksum.
|
||||
func Fletcher32(payload string) uint32 {
|
||||
data := []byte(payload)
|
||||
if len(data)%2 != 0 {
|
||||
data = append(data, 0)
|
||||
}
|
||||
|
||||
var sum1, sum2 uint32
|
||||
for i := 0; i < len(data); i += 2 {
|
||||
val := binary.LittleEndian.Uint16(data[i : i+2])
|
||||
sum1 = (sum1 + uint32(val)) % 65535
|
||||
sum2 = (sum2 + sum1) % 65535
|
||||
}
|
||||
return (sum2 << 16) | sum1
|
||||
}
|
||||
|
||||
// Fletcher64 computes the Fletcher-64 checksum.
|
||||
func Fletcher64(payload string) uint64 {
|
||||
data := []byte(payload)
|
||||
if len(data)%4 != 0 {
|
||||
padding := 4 - (len(data) % 4)
|
||||
data = append(data, make([]byte, padding)...)
|
||||
}
|
||||
|
||||
var sum1, sum2 uint64
|
||||
for i := 0; i < len(data); i += 4 {
|
||||
val := binary.LittleEndian.Uint32(data[i : i+4])
|
||||
sum1 = (sum1 + uint64(val)) % 4294967295
|
||||
sum2 = (sum2 + sum1) % 4294967295
|
||||
}
|
||||
return (sum2 << 32) | sum1
|
||||
}
|
||||
|
||||
// --- PGP ---
|
||||
|
||||
// @snider
|
||||
// The PGP functions are commented out pending resolution of the dependency issues.
|
||||
//
|
||||
// import "io"
|
||||
// import "github.com/Snider/Enchantrix/openpgp"
|
||||
//
|
||||
// // EncryptPGP encrypts data for a recipient, optionally signing it.
|
||||
// func EncryptPGP(writer io.Writer, recipientPath, data string, signerPath, signerPassphrase *string) error {
|
||||
// var buf bytes.Buffer
|
||||
// err := openpgp.EncryptPGP(&buf, recipientPath, data, signerPath, signerPassphrase)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// // Copy the encrypted data to the original writer.
|
||||
// if _, err := writer.Write(buf.Bytes()); err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// // DecryptPGP decrypts a PGP message, optionally verifying the signature.
|
||||
// func DecryptPGP(recipientPath, message, passphrase string, signerPath *string) (string, error) {
|
||||
// return openpgp.DecryptPGP(recipientPath, message, passphrase, signerPath)
|
||||
// }
|
||||
48
crypt_test.go
Normal file
48
crypt_test.go
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package crypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHash(t *testing.T) {
|
||||
payload := "hello"
|
||||
hash := Hash(LTHN, payload)
|
||||
assert.NotEmpty(t, hash)
|
||||
}
|
||||
|
||||
func TestLuhn(t *testing.T) {
|
||||
assert.True(t, Luhn("79927398713"))
|
||||
assert.False(t, Luhn("79927398714"))
|
||||
}
|
||||
|
||||
func TestFletcher16(t *testing.T) {
|
||||
assert.Equal(t, uint16(0xC8F0), Fletcher16("abcde"))
|
||||
assert.Equal(t, uint16(0x2057), Fletcher16("abcdef"))
|
||||
assert.Equal(t, uint16(0x0627), Fletcher16("abcdefgh"))
|
||||
}
|
||||
|
||||
func TestFletcher32(t *testing.T) {
|
||||
expected := uint32(0xF04FC729)
|
||||
actual := Fletcher32("abcde")
|
||||
fmt.Printf("Fletcher32('abcde'): expected: %x, actual: %x\n", expected, actual)
|
||||
assert.Equal(t, expected, actual)
|
||||
|
||||
expected = uint32(0x56502D2A)
|
||||
actual = Fletcher32("abcdef")
|
||||
fmt.Printf("Fletcher32('abcdef'): expected: %x, actual: %x\n", expected, actual)
|
||||
assert.Equal(t, expected, actual)
|
||||
|
||||
expected = uint32(0xEBE19591)
|
||||
actual = Fletcher32("abcdefgh")
|
||||
fmt.Printf("Fletcher32('abcdefgh'): expected: %x, actual: %x\n", expected, actual)
|
||||
assert.Equal(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestFletcher64(t *testing.T) {
|
||||
assert.Equal(t, uint64(0xc8c6c527646362c6), Fletcher64("abcde"))
|
||||
assert.Equal(t, uint64(0xc8c72b276463c8c6), Fletcher64("abcdef"))
|
||||
assert.Equal(t, uint64(0x312e2b28cccac8c6), Fletcher64("abcdefgh"))
|
||||
}
|
||||
14
go.mod
Normal file
14
go.mod
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
module github.com/Snider/Enchantrix
|
||||
|
||||
go 1.25
|
||||
|
||||
require github.com/stretchr/testify v1.11.1
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
23
go.sum
Normal file
23
go.sum
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
61
lthn/lthn.go
Normal file
61
lthn/lthn.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package lthn
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
// keyMap is the default character-swapping map used for the quasi-salting process.
|
||||
var keyMap = map[rune]rune{
|
||||
'o': '0',
|
||||
'l': '1',
|
||||
'e': '3',
|
||||
'a': '4',
|
||||
's': 'z',
|
||||
't': '7',
|
||||
'0': 'o',
|
||||
'1': 'l',
|
||||
'3': 'e',
|
||||
'4': 'a',
|
||||
'7': 't',
|
||||
}
|
||||
|
||||
// SetKeyMap sets the key map for the notarisation process.
|
||||
func SetKeyMap(newKeyMap map[rune]rune) {
|
||||
keyMap = newKeyMap
|
||||
}
|
||||
|
||||
// GetKeyMap gets the current key map.
|
||||
func GetKeyMap() map[rune]rune {
|
||||
return keyMap
|
||||
}
|
||||
|
||||
// Hash creates a reproducible hash from a string.
|
||||
func Hash(input string) string {
|
||||
salt := createSalt(input)
|
||||
hash := sha256.Sum256([]byte(input + salt))
|
||||
return hex.EncodeToString(hash[:])
|
||||
}
|
||||
|
||||
// createSalt creates a quasi-salt from a string by reversing it and swapping characters.
|
||||
func createSalt(input string) string {
|
||||
if input == "" {
|
||||
return ""
|
||||
}
|
||||
runes := []rune(input)
|
||||
salt := make([]rune, len(runes))
|
||||
for i := 0; i < len(runes); i++ {
|
||||
char := runes[len(runes)-1-i]
|
||||
if replacement, ok := keyMap[char]; ok {
|
||||
salt[i] = replacement
|
||||
} else {
|
||||
salt[i] = char
|
||||
}
|
||||
}
|
||||
return string(salt)
|
||||
}
|
||||
|
||||
// Verify checks if an input string matches a given hash.
|
||||
func Verifyf(input string, hash string) bool {
|
||||
return Hash(input) == hash
|
||||
}
|
||||
18
lthn/lthn_test.go
Normal file
18
lthn/lthn_test.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package lthn
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHash(t *testing.T) {
|
||||
hash := Hash("hello")
|
||||
assert.NotEmpty(t, hash)
|
||||
}
|
||||
|
||||
func TestVerify(t *testing.T) {
|
||||
hash := Hash("hello")
|
||||
assert.True(t, Verifyf("hello", hash))
|
||||
assert.False(t, Verifyf("world", hash))
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue