diff --git a/crypto/shamirs_secret_sharing/dll_dist/shamirs_secret_sharing.cpython-311-aarch64-linux-gnu.so b/crypto/shamirs_secret_sharing/dll_dist/shamirs_secret_sharing.cpython-311-aarch64-linux-gnu.so new file mode 100644 index 0000000..bb69011 Binary files /dev/null and b/crypto/shamirs_secret_sharing/dll_dist/shamirs_secret_sharing.cpython-311-aarch64-linux-gnu.so differ diff --git a/crypto/shamirs_secret_sharing/libs/python312.lib b/crypto/shamirs_secret_sharing/libs/python312.lib new file mode 100644 index 0000000..bf8c5e0 Binary files /dev/null and b/crypto/shamirs_secret_sharing/libs/python312.lib differ diff --git a/crypto/shamirs_secret_sharing/python312.dll b/crypto/shamirs_secret_sharing/python312.dll new file mode 100644 index 0000000..767c18e Binary files /dev/null and b/crypto/shamirs_secret_sharing/python312.dll differ diff --git a/crypto/shamirs_secret_sharing/shamir_bridge.dll b/crypto/shamirs_secret_sharing/shamir_bridge.dll new file mode 100644 index 0000000..9f9f437 Binary files /dev/null and b/crypto/shamirs_secret_sharing/shamir_bridge.dll differ diff --git a/crypto/shamirs_secret_sharing/test_shamir.exe b/crypto/shamirs_secret_sharing/test_shamir.exe new file mode 100644 index 0000000..ddbd292 Binary files /dev/null and b/crypto/shamirs_secret_sharing/test_shamir.exe differ diff --git a/crypto/threefish512_ctr/exts/blake3.obj b/crypto/threefish512_ctr/exts/blake3.obj new file mode 100644 index 0000000..0da9edb Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3.obj differ diff --git a/crypto/threefish512_ctr/exts/blake3_avx2.o b/crypto/threefish512_ctr/exts/blake3_avx2.o new file mode 100644 index 0000000..d349e85 Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_avx2.o differ diff --git a/crypto/threefish512_ctr/exts/blake3_avx2.obj b/crypto/threefish512_ctr/exts/blake3_avx2.obj new file mode 100644 index 0000000..d349e85 Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_avx2.obj differ diff --git a/crypto/threefish512_ctr/exts/blake3_avx512.o b/crypto/threefish512_ctr/exts/blake3_avx512.o new file mode 100644 index 0000000..7eab038 Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_avx512.o differ diff --git a/crypto/threefish512_ctr/exts/blake3_avx512.obj b/crypto/threefish512_ctr/exts/blake3_avx512.obj new file mode 100644 index 0000000..7eab038 Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_avx512.obj differ diff --git a/crypto/threefish512_ctr/exts/blake3_dispatch.obj b/crypto/threefish512_ctr/exts/blake3_dispatch.obj new file mode 100644 index 0000000..5fd8c08 Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_dispatch.obj differ diff --git a/crypto/threefish512_ctr/exts/blake3_portable.obj b/crypto/threefish512_ctr/exts/blake3_portable.obj new file mode 100644 index 0000000..743d711 Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_portable.obj differ diff --git a/crypto/threefish512_ctr/exts/blake3_sse2.o b/crypto/threefish512_ctr/exts/blake3_sse2.o new file mode 100644 index 0000000..4a5995a Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_sse2.o differ diff --git a/crypto/threefish512_ctr/exts/blake3_sse2.obj b/crypto/threefish512_ctr/exts/blake3_sse2.obj new file mode 100644 index 0000000..4a5995a Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_sse2.obj differ diff --git a/crypto/threefish512_ctr/exts/blake3_sse41.o b/crypto/threefish512_ctr/exts/blake3_sse41.o new file mode 100644 index 0000000..a123615 Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_sse41.o differ diff --git a/crypto/threefish512_ctr/exts/blake3_sse41.obj b/crypto/threefish512_ctr/exts/blake3_sse41.obj new file mode 100644 index 0000000..a123615 Binary files /dev/null and b/crypto/threefish512_ctr/exts/blake3_sse41.obj differ diff --git a/crypto/threefish512_ctr/main.d b/crypto/threefish512_ctr/main.d new file mode 100644 index 0000000..ee34704 --- /dev/null +++ b/crypto/threefish512_ctr/main.d @@ -0,0 +1,412 @@ +module crypto.threefish512_ctr.main; + +import std.random : Random, unpredictableSeed, uniform; +import std.algorithm : min; +import std.conv : emplace; +// import dmd.common.blake3; +import std.array : appender; +import std.exception : enforce; + +/* honestly dk if this is cryptographically "secure", as i took most of the implmentation from some russian dub package +i then implemented pkcs5 back then as thats all i knew +then figured just that is not enough and i only had raw stream ciphers so far +so i tried to research how to implement ctr and shit was too complicated so i vibecoded it (probably some flaws and inefficiet, but should be good enough) +and added blake3-mac as without it the implementation would be vulnerable to +replay, padding‑free oracles, bitflip and plaintext-recovery attacks */ + +// anyways, from what i read forging a blake3 mac or breaking threefish512 in itself +// is beyond fantasy rn so anyone who wants to use this should be fine + +// memcpy +extern(C) nothrow @nogc void* memcpy(void* dst, const void* src, size_t n); + +extern(C) +{ + struct blake3_hasher { + ubyte[256] opaque; + } + + void blake3_hasher_init_keyed(blake3_hasher* hasher, const ubyte* key); + void blake3_hasher_update(blake3_hasher* hasher, const ubyte* input, size_t len); + void blake3_hasher_finalize(blake3_hasher* hasher, ubyte* _out, size_t out_len); +} + +class Threefish512 +{ + private: + enum BLOCK_SIZE = 64; + enum Nw = 8; + enum Nr = 72; + enum Ns = Nr / 4; + + uint[8] p = [2, 1, 4, 7, 6, 5, 0, 3]; + uint[8] p_1 = [6, 1, 0, 7, 2, 5, 4, 3]; + + uint[4][8] r = [ + [46, 36, 19, 37], + [33, 27, 14, 42], + [17, 49, 36, 39], + [44, 9 , 54, 56], + [39, 30, 34, 24], + [13, 50, 10, 17], + [25, 29, 39, 43], + [8 , 35, 56, 22] + ]; + + ulong[3] t; + ulong[8][Ns + 1] subKeys; + + alias _mod8 = (ulong a) => a & 7UL; + + private void _mix(ref ulong[2] x, ulong r, ref ulong[2] y) + { + y[0] = x[0] + x[1]; + y[1] = (x[1] << r) | (x[1] >> (64 - r)); + y[1] ^= y[0]; + } + + private void _demix(ref ulong[2] y, ulong r, ref ulong[2] x) + { + y[1] ^= y[0]; + x[1] = (y[1] << (64 - r)) | (y[1] >> r); + x[0] = y[0] - x[1]; + } + + private void _setup(ulong* keyData, ulong* tweakData) @system + { + ulong[8] K; + ulong[2] T; + ulong[9] key; + ulong kNw = 0x1BD11BDAA9FC1A22; + + memcpy(&K[0], keyData, 64); + memcpy(&T[0], tweakData, 16); + + foreach (i; 0 .. Nw) + { + kNw ^= K[i]; + key[i] = K[i]; + } + key[8] = kNw; + + t[0] = T[0]; + t[1] = T[1]; + t[2] = T[0] ^ T[1]; + + foreach (round; 0 .. Ns + 1) + { + foreach (i; 0 .. Nw) + { + subKeys[round][i] = key[(round + i) % (Nw + 1)]; + if (i == Nw - 3) subKeys[round][i] += t[round % 3]; + else if (i == Nw - 2) subKeys[round][i] += t[(round + 1) % 3]; + else if (i == Nw - 1) subKeys[round][i] += round; + } + } + } + + private void _blockEncrypt(ulong* plainData, ulong* c) + { + ulong[8] f; + ulong[8] e; + ulong[2] x, y; + ulong[8] v; + memcpy(&v[0], plainData, 64); + + foreach (round; 0 .. Nr) + { + uint s = round >> 2; + foreach (i; 0 .. Nw) + e[i] = (round % 4 == 0) ? v[i] + subKeys[s][i] : v[i]; + + foreach (i; 0 .. Nw/2) + { + x[0] = e[i*2]; x[1] = e[i*2+1]; + _mix(x, r[_mod8(round)][i], y); + f[i*2] = y[0]; f[i*2+1] = y[1]; + } + + foreach (i; 0 .. Nw) v[i] = f[p[i]]; + } + + foreach (i; 0 .. Nw) c[i] = v[i] + subKeys[Ns][i]; + } + + public static ulong[8] generateKey() + { + ulong[8] key; + auto rng = Random(unpredictableSeed); + foreach (i; 0 .. 8) key[i] = uniform!ulong(rng); + return key; + } + + public static ulong generateNonce() + { + auto rng = Random(unpredictableSeed); + return uniform!ulong(rng); + } + + public static ubyte[32] generateMacKey() { + auto rng = Random(unpredictableSeed); + ubyte[32] key; + foreach(i; 0 .. 4) { + ulong part = uniform!ulong(rng); + foreach(b; 0 .. 8) + key[i*8 + b] = cast(ubyte)((part >> (8*b)) & 0xFF); + } + return key; + } + + public void encryptCTR(ulong* plainData, ulong* ciphertext, size_t lengthBytes, ulong[8] key, ulong nonce) + { + ulong[2] tweak = [nonce, 0]; + //_setup(key, [nonce, 0]); + _setup(key.ptr, tweak.ptr); + ulong[8] zeroBlock = 0; + size_t numBlocks = (lengthBytes + 63) / 64; + ulong counter = 0; + + foreach (blockIndex; 0 .. numBlocks) + { + t[0] = nonce; + t[1] = counter; + t[2] = t[0] ^ t[1]; + + ulong[8] keystream; + _blockEncrypt(zeroBlock.ptr, keystream.ptr); + + size_t start = blockIndex * 8; + size_t blockULongs = ((lengthBytes - start + 7)/8).min(8); + + foreach (i; 0 .. blockULongs) + ciphertext[start + i] = plainData[start + i] ^ keystream[i]; + + counter++; + } + } + + private bool ctEqual(ubyte[32] a, ubyte[32] b) + { + ubyte diff = 0; + foreach(i; 0..32) + diff |= a[i] ^ b[i]; + return diff == 0; + } + + public ubyte[32] gen_tag(ubyte[32] key_mac, ubyte[] nonce, ubyte[] ciphertext) + { + auto data = appender!(ubyte[])(); + data.put(nonce); + data.put(ciphertext); + + ubyte[32] comp_tag = blake3_mac(key_mac, data.data); + + return comp_tag; + } + + private bool verify_tag(ubyte[32] key_mac, ubyte[] nonce, ubyte[] ciphertext, ubyte[32] exp_tag) + { + ubyte[32] comp_tag = gen_tag(key_mac, nonce, ciphertext); + + return ctEqual(comp_tag, exp_tag); + } + + private ubyte[32] blake3_mac(ubyte[32] key_mac, ubyte[] data) + { + blake3_hasher hasher; + blake3_hasher_init_keyed(&hasher, key_mac.ptr); + blake3_hasher_update(&hasher, data.ptr, data.length); + + ubyte[32] oout; + blake3_hasher_finalize(&hasher, oout.ptr, 32); + return oout; + } + + public void decryptCTR(ulong* ciphertext, ulong* plainData, size_t lengthBytes, ulong[8] key, ulong nonce, ubyte[32] key_mac, ubyte[32] exp_tag) + { + ubyte[8] nbytes; + foreach(i; 0 .. 8) nbytes[i] = cast(ubyte)((nonce >> (8*i)) & 0xFF); + + ubyte[] ct_bytes = cast(ubyte[])(cast(ubyte*)ciphertext)[0 .. lengthBytes]; + if (verify_tag(key_mac, nbytes[], ct_bytes, exp_tag)) { + encryptCTR(ciphertext, plainData, lengthBytes, key, nonce); + } + } + + public void encryptBytes(ubyte[] plaintext, out ubyte[] ciphertext, out ubyte[32] tag, out ulong nonce, out ulong[8] key_enc, out ubyte[32] key_mac) + { + ciphertext.length = plaintext.length; + + size_t nLongs = (plaintext.length + 7)/8; + ulong[] plainLongs; + plainLongs.length = nLongs; + foreach(i; 0 .. nLongs) { + ulong val = 0; + foreach(b; 0 .. 8) { + size_t idx = i*8 + b; + if(idx < plaintext.length) + val |= cast(ulong)plaintext[idx] << (8*b); + } + plainLongs[i] = val; + } + + ulong[] cipherLongs; + cipherLongs.length = nLongs; + + encryptCTR(plainLongs.ptr, cipherLongs.ptr, plaintext.length, key_enc, nonce); + + foreach(i; 0 .. nLongs) { + foreach(b; 0 .. 8) { + size_t idx = i*8 + b; + if(idx < plaintext.length) + ciphertext[idx] = cast(ubyte)((cipherLongs[i] >> (8*b)) & 0xFF); + } + } + + auto data = appender!(ubyte[])(); + foreach(b; 0 .. 8) + data.put(cast(ubyte)((nonce >> (8*b)) & 0xFF)); + data.put(ciphertext); + tag = blake3_mac(key_mac, data.data); + } + + public ubyte[] decryptBytes(ubyte[] ciphertext, ubyte[32] expected_tag, ubyte[32] key_mac, ulong[8] key_enc, ulong nonce) + { + auto data = appender!(ubyte[])(); + foreach(b; 0 .. 8) + data.put(cast(ubyte)((nonce >> (8*b)) & 0xFF)); + data.put(ciphertext); + + enforce(ctEqual(blake3_mac(key_mac, data.data), expected_tag), "MAC verification failed"); + size_t nLongs = (ciphertext.length + 7)/8; + ulong[] cipherLongs; + cipherLongs.length = nLongs; + foreach(i; 0 .. nLongs) { + ulong val = 0; + foreach(b; 0 .. 8) { + size_t idx = i*8 + b; + if(idx < ciphertext.length) + val |= cast(ulong)ciphertext[idx] << (8*b); + } + cipherLongs[i] = val; + } + + ulong[] plainLongs; + plainLongs.length = nLongs; + encryptCTR(cipherLongs.ptr, plainLongs.ptr, ciphertext.length, key_enc, nonce); + + ubyte[] plaintext; + plaintext.length = ciphertext.length; + foreach(i; 0 .. nLongs) { + foreach(b; 0 .. 8) { + size_t idx = i*8 + b; + if(idx < ciphertext.length) + plaintext[idx] = cast(ubyte)((plainLongs[i] >> (8*b)) & 0xFF); + } + } + return plaintext; + } +} + +__gshared Threefish512 tfInstance = new Threefish512(); + +// Key / MAC / Nonce wrappers +extern(C) export void generateKeyC(ulong* c_out) { + auto key = Threefish512.generateKey(); // returns ulong[8] + for(size_t i = 0; i < 8; i++) + c_out[i] = key[i]; +} + +extern(C) export ulong generateNonceC() { + return Threefish512.generateNonce(); +} + +extern(C) export void generateMacKeyC(ubyte* c_out) { + auto key = Threefish512.generateMacKey(); // returns ubyte[32] + for(size_t i = 0; i < 32; i++) + c_out[i] = key[i]; +} + +// CTR encryption / decryption wrappers +extern(C) export void encryptCTR_C(ulong* plainData, ulong* ciphertext, size_t lengthBytes, + ulong* key_enc, ulong nonce) { + ulong[8] k; + for(size_t i = 0; i < 8; i++) k[i] = key_enc[i]; + tfInstance.encryptCTR(plainData, ciphertext, lengthBytes, k, nonce); +} + +extern(C) export void decryptCTR_C(ulong* ciphertext, ulong* plainData, size_t lengthBytes, + ulong* key_enc, ulong nonce, + ubyte* key_mac, ubyte* exp_tag) { + ulong[8] k; ubyte[32] mac; ubyte[32] tag; + for(size_t i = 0; i < 8; i++) k[i] = key_enc[i]; + for(size_t i = 0; i < 32; i++) { mac[i] = key_mac[i]; tag[i] = exp_tag[i]; } + tfInstance.decryptCTR(ciphertext, plainData, lengthBytes, k, nonce, mac, tag); +} + +// encryptBytes / decryptBytes wrappers +extern(C) export void encryptBytes_C(ubyte* plaintext, size_t plainLen, + ubyte* ciphertext, ubyte* tag, + ulong* nonceOut, ulong* key_encOut, ubyte* key_macOut) { + ulong[8] key_enc = Threefish512.generateKey(); + ulong nonce = Threefish512.generateNonce(); + ubyte[32] key_mac = Threefish512.generateMacKey(); + + ubyte[] pt; pt.length = plainLen; + for(size_t i = 0; i < plainLen; i++) pt[i] = plaintext[i]; + + ubyte[] ct; ct.length = plainLen; + ubyte[32] tag_arr; + tfInstance.encryptBytes(pt, ct, tag_arr, nonce, key_enc, key_mac); + + for(size_t i = 0; i < 32; i++) tag[i] = tag_arr[i]; + + for(size_t i = 0; i < plainLen; i++) ciphertext[i] = ct[i]; + for(size_t i = 0; i < 8; i++) key_encOut[i] = key_enc[i]; + for(size_t i = 0; i < 32; i++) key_macOut[i] = key_mac[i]; + *nonceOut = nonce; +} + +extern(C) export void decryptBytes_C(ubyte* ciphertext, size_t cipherLen, + ubyte* plaintextOut, + ubyte* expectedTag, ubyte* key_mac, + ulong* key_enc, ulong nonce) { + ulong[8] k; ubyte[32] mac; ubyte[32] tag; + for(size_t i = 0; i < 8; i++) k[i] = key_enc[i]; + for(size_t i = 0; i < 32; i++) { mac[i] = key_mac[i]; tag[i] = expectedTag[i]; } + + ubyte[] ct; ct.length = cipherLen; + for(size_t i = 0; i < cipherLen; i++) ct[i] = ciphertext[i]; + + ubyte[] pt = tfInstance.decryptBytes(ct, tag, mac, k, nonce); + for(size_t i = 0; i < cipherLen; i++) plaintextOut[i] = pt[i]; +} + +// gen_tag wrapper +extern(C) export void gen_tag_C(ubyte* key_mac, ubyte* nonce, size_t nonceLen, + ubyte* ciphertext, size_t cipherLen, ubyte* outTag) { + ubyte[32] k; + for(size_t i = 0; i < 32; i++) k[i] = key_mac[i]; + + ubyte[] n; n.length = nonceLen; + for(size_t i = 0; i < nonceLen; i++) n[i] = nonce[i]; + + ubyte[] ct; ct.length = cipherLen; + for(size_t i = 0; i < cipherLen; i++) ct[i] = ciphertext[i]; + + ubyte[32] tag = tfInstance.gen_tag(k, n, ct); + for(size_t i = 0; i < 32; i++) outTag[i] = tag[i]; +} + +extern(C) export void threefish512_block_encrypt_C( + ulong* key, ulong* tweak, ulong* plaintext, ulong* ciphertext) +{ + ulong[8] k; + ulong[2] t; + + for(size_t i=0;i<8;i++) k[i] = key[i]; + for(size_t i=0;i<2;i++) t[i] = tweak[i]; + + tfInstance._setup(k.ptr, t.ptr); + tfInstance._blockEncrypt(plaintext, ciphertext); +} \ No newline at end of file diff --git a/crypto/threefish512_ctr/main.dll b/crypto/threefish512_ctr/main.dll new file mode 100644 index 0000000..3a40094 Binary files /dev/null and b/crypto/threefish512_ctr/main.dll differ diff --git a/crypto/threefish512_ctr/main.exp b/crypto/threefish512_ctr/main.exp new file mode 100644 index 0000000..7c8793a Binary files /dev/null and b/crypto/threefish512_ctr/main.exp differ diff --git a/crypto/threefish512_ctr/main.lib b/crypto/threefish512_ctr/main.lib new file mode 100644 index 0000000..952b39b Binary files /dev/null and b/crypto/threefish512_ctr/main.lib differ diff --git a/crypto/threefish512_ctr/main.obj b/crypto/threefish512_ctr/main.obj new file mode 100644 index 0000000..4eff726 Binary files /dev/null and b/crypto/threefish512_ctr/main.obj differ diff --git a/crypto/threefish512_ctr/test_vec.exe b/crypto/threefish512_ctr/test_vec.exe new file mode 100644 index 0000000..22a0a00 Binary files /dev/null and b/crypto/threefish512_ctr/test_vec.exe differ diff --git a/crypto/threefish512_ctr/test_vec.obj b/crypto/threefish512_ctr/test_vec.obj new file mode 100644 index 0000000..a0331ff Binary files /dev/null and b/crypto/threefish512_ctr/test_vec.obj differ diff --git a/crypto/threefish512_ctr/threefish512.lib b/crypto/threefish512_ctr/threefish512.lib new file mode 100644 index 0000000..43c8350 Binary files /dev/null and b/crypto/threefish512_ctr/threefish512.lib differ