Initiliazation
This commit is contained in:
148
vv1/agent/angel/utils/cryptography/cryptography.d
Normal file
148
vv1/agent/angel/utils/cryptography/cryptography.d
Normal file
@@ -0,0 +1,148 @@
|
||||
module angel.utils.cryptography.cryptography;
|
||||
|
||||
// Internal imports
|
||||
import angel.utils.logging;
|
||||
import angel.utils.cryptography.serpent;
|
||||
import angel.utils.cryptography.threefish;
|
||||
import angel.utils.cryptography.curve25519;
|
||||
// External imports
|
||||
import std.stdio;
|
||||
import std.random;
|
||||
import std.format;
|
||||
|
||||
class Cryptography {
|
||||
public {
|
||||
struct KeyPair {
|
||||
ubyte[32] clientSecretKey;
|
||||
ubyte[32] sharedSecret;
|
||||
}
|
||||
}
|
||||
|
||||
public static KeyPair derive_25519(ubyte[] pk) {
|
||||
ubyte[32] sk; // generate client secret key
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
sk[i] = cast(ubyte)(uniform(0, 256));
|
||||
}
|
||||
|
||||
Logger.log(LogLevel.Debug, "Generated client sk");
|
||||
|
||||
ubyte[32] ss = curve25519_scalarmult(sk, pk); // derive shared secret out of pk and sk
|
||||
|
||||
Logger.log(LogLevel.Debug, format("Derived shared secret: %s", ss));
|
||||
|
||||
return KeyPair(sk, ss);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Freefishy {
|
||||
private Threefish512 cipher;
|
||||
|
||||
this(ulong[8] key, ulong[2] tweak) {
|
||||
cipher = new Threefish512();
|
||||
cipher.setup(key, tweak);
|
||||
}
|
||||
|
||||
public ubyte[] encrypt(ubyte[] payload) {
|
||||
ulong[8] plain = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
// Pack the ubyte[] into ulong[] by 8 bytes per ulong
|
||||
foreach (i, c; payload) {
|
||||
plain[i / 8] |= cast(ulong) c << ((i % 8) * 8);
|
||||
}
|
||||
|
||||
// Encrypt the ulong array
|
||||
ulong[] encrypted_three = cipher.crypt(plain);
|
||||
|
||||
// Convert the encrypted ulong[] back to ubyte[]
|
||||
ubyte[] encrypted_bytes;
|
||||
foreach (enc_val; encrypted_three) {
|
||||
foreach (i; 0..8) {
|
||||
encrypted_bytes ~= cast(ubyte)((enc_val >> (i * 8)) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.log(LogLevel.Debug, format("Threefish Encrypted: %s", encrypted_bytes));
|
||||
return encrypted_bytes;
|
||||
}
|
||||
|
||||
public ubyte[] decrypt(ubyte[] payload) {
|
||||
ulong[8] decrypted_buffer;
|
||||
|
||||
// Convert the ubyte[] payload back into ulong[] (8 bytes per ulong)
|
||||
ulong[8] cipher_payload;
|
||||
foreach (i, val; payload) {
|
||||
cipher_payload[i / 8] |= cast(ulong) val << ((i % 8) * 8);
|
||||
}
|
||||
|
||||
// Decrypt the ulong[] array
|
||||
cipher.decrypt(cipher_payload.ptr, decrypted_buffer.ptr);
|
||||
|
||||
// Convert the decrypted ulong[] back to ubyte[]
|
||||
ubyte[] decrypted_bytes;
|
||||
foreach (dec_val; decrypted_buffer) {
|
||||
foreach (i; 0..8) {
|
||||
decrypted_bytes ~= cast(ubyte)((dec_val >> (i * 8)) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.log(LogLevel.Debug, format("Threefish Decrypted: %s", decrypted_bytes));
|
||||
return decrypted_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Serpi {
|
||||
private Serpent serp;
|
||||
|
||||
this(Cryptography.KeyPair keypair) {
|
||||
auto key = cast(ubyte[]) keypair.sharedSecret.dup;
|
||||
serp.start(key);
|
||||
}
|
||||
|
||||
public ubyte[] encrypt(ubyte[] payload) {
|
||||
ubyte padding = cast(ubyte)(16 - (payload.length % 16));
|
||||
ubyte[] paddingBytes = new ubyte[padding];
|
||||
foreach (i; 0 .. padding) {
|
||||
paddingBytes[i] = padding;
|
||||
}
|
||||
ubyte[] input = payload ~ paddingBytes;
|
||||
ubyte[] output = new ubyte[input.length];
|
||||
|
||||
serp.encrypt(input, output);
|
||||
Logger.log(LogLevel.Debug, format("Serpent Encrypted data: %s", output));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public ubyte[] decrypt(ubyte[] payload) {
|
||||
ubyte[] output = new ubyte[payload.length];
|
||||
serp.decrypt(payload, output);
|
||||
|
||||
if (output.length == 0) {
|
||||
throw new Exception("Decryption failed: Output length is zero.");
|
||||
}
|
||||
|
||||
ubyte padding = output[$ - 1];
|
||||
|
||||
if (padding > 16 || padding == 0) {
|
||||
throw new Exception("Invalid padding detected");
|
||||
}
|
||||
|
||||
foreach (i; output.length - padding .. output.length) {
|
||||
if (output[i] != padding) {
|
||||
throw new Exception("Padding validation failed");
|
||||
}
|
||||
}
|
||||
|
||||
ubyte[] unpadded = output[0 .. output.length - padding];
|
||||
Logger.log(LogLevel.Debug, format("Serpent Decrypted data: %s", unpadded));
|
||||
|
||||
return unpadded;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
serp.reset();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user