Initial commit

This commit is contained in:
unknown
2026-05-14 00:42:39 +02:00
commit dae8a0a4a1
37 changed files with 1226 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
module cryptography
import x.crypto.ascon
import crypto.rand
import crypto.hmac
import x.crypto.curve25519
import crypto.sha256
import encoding.base64
import structs
fn ascon_key_generator() string {
key := rand.bytes(ascon.key_size) or {
logs.error('cryptography:cryptography:ascon_key_generator', 'ascon key generation failed due to: \'$err\'')
return ''
}
return key.hex()
}
fn ascon_encrypt(key_hex string, plaintext string) string {
key := []u8(key_hex.hex())
nonce := rand.bytes(ascon.nonce_size) or {
logs.error('cryptography:cryptography:ascon_encrypt', 'nonce generation failed due to: \'$err\'')
return ''
}
ad := []u8{}
ciphertext := ascon.encrypt(key, nonce, ad, plaintext.bytes()) or {
logs.error('cryptography:cryptography:ascon_encrypt', 'encrypt failed: \'$err\'')
return ''
}
mut combined := []u8{len: nonce.len + ciphertext.len}
combined << nonce
combined << ciphertext
data_b64 := base64.encode(combined)
return data_b64
}
fn ascon_decrypt(key_hex string, data_b64 string) string {
key := []u8(key_hex.hex())
combined := base64.decode(data_b64)
if combined.len < ascon.nonce_size {
logs.error('cryptography:cryptography:ascon_decrypt', 'data blob is too short')
return ''
}
nonce := combined[..ascon.nonce_size]
ciphertext := combined[ascon.nonce_size..]
plaintext_bytes := ascon.decrypt(key, nonce, []u8{}, ciphertext) or {
logs.error('cryptography:cryptography:ascon_decrypt', 'decrypt failed: \'$err\'')
return ''
}
return plaintext_bytes.bytestr()
}
fn generate_keypair() !structs.KeyPair {
mut secret_key_bytes := curve25519.PrivateKey.new() or {
logs.error('cryptography:cryptography:generate_keypair', 'x25519 secret key generation failed due to: \'$err\'')
return error('x25519 secret key generation failed due to: \'$err\'')
}
public_key_bytes := secret_key_bytes.public_key() or {
logs.error('cryptography:cryptography:generate_keypair', 'x25519 public key computation/generation failed due to: \'$err\'')
return error('x25519 public key computation/generation failed due to: \'$err\'')
}
logs.info('cryptography:cryptography:generate_keypair', 'Generated x25519 keypair')
return structs.KeyPair{
secret: secret_key_bytes
public: public_key_bytes
}
}
fn compute_shared_secret(mut secret_key curve25519.PrivateKey, public_key curve25519.PublicKey) ![]u8 {
shared_secret_raw := curve25519.derive_shared_secret(mut secret_key, public_key) or {
logs.error('cryptography:cryptography:compute_shared_secret', 'x25519 raw shared_secret computation/derivation failed due to: \'$err\'')
return []u8{}
}
logs.info('cryptography:cryptography:compute_shared_secret', 'Computed x25519 raw shared_secret')
return shared_secret_raw
}
fn hkdf_sha256(ikm []u8, salt []u8, length int) []u8 {
prk := hmac.new(salt, ikm, sha256.sum, sha256.block_size)
info := []u8{}
mut okm := []u8{}
mut previous_block := []u8{}
mut counter := u8(1)
for okm.len < length {
mut block_input := previous_block.clone()
block_input << info
block_input << counter
block := hmac.new(prk, block_input, sha256.sum, sha256.block_size)
okm << block
previous_block = block.clone()
counter++
}
logs.info('cryptography:cryptography:hkdf_sha256', 'Derived HMAC-x25519 shared_secret')
return okm[..length]
}
fn salt_randomizer() []u8 {
logs.info('cryptography:cryptography:salt_randomizer', 'Generated CSPRNG randomized salt')
return rand.bytes(32) or {
logs.error('cryptography:cryptography:salt_randomizer', 'CSPRNG randomized salt generation failed due to: \'$err\'')
return []u8{}
}
}