From a4cd9f8e1845c11fec364a7e56cbc8c8fa8ea776 Mon Sep 17 00:00:00 2001 From: a-Sansara Date: Fri, 20 Oct 2017 00:56:17 +0200 Subject: [PATCH] initial commit --- Chamah.vala | 85 +++++++++++++++++++ build.sh | 19 +++++ out.txt | 3 + out2.txt | 1 + src/pluie/bin.vala | 132 +++++++++++++++++++++++++++++ src/pluie/crypt.Chamah.vala | 117 +++++++++++++++++++++++++ src/pluie/crypt.KeyPermuter.vala | 27 ++++++ src/pluie/crypt.MatrixBytes.vala | 69 +++++++++++++++ src/pluie/crypt.Movment.vala | 49 +++++++++++ src/pluie/crypt.Permutation.vala | 63 ++++++++++++++ src/pluie/crypt.PseudoRandom.vala | 59 +++++++++++++ src/pluie/crypt.Sbox.vala | 112 ++++++++++++++++++++++++ src/pluie/global.vala | 30 +++++++ src/pluie/io.Bytes.vala | 94 ++++++++++++++++++++ src/pluie/io.InputChunkStream.vala | 56 ++++++++++++ 15 files changed, 916 insertions(+) create mode 100644 Chamah.vala create mode 100755 build.sh create mode 100644 out.txt create mode 100644 out2.txt create mode 100644 src/pluie/bin.vala create mode 100644 src/pluie/crypt.Chamah.vala create mode 100644 src/pluie/crypt.KeyPermuter.vala create mode 100644 src/pluie/crypt.MatrixBytes.vala create mode 100644 src/pluie/crypt.Movment.vala create mode 100644 src/pluie/crypt.Permutation.vala create mode 100644 src/pluie/crypt.PseudoRandom.vala create mode 100644 src/pluie/crypt.Sbox.vala create mode 100644 src/pluie/global.vala create mode 100644 src/pluie/io.Bytes.vala create mode 100644 src/pluie/io.InputChunkStream.vala diff --git a/Chamah.vala b/Chamah.vala new file mode 100644 index 0000000..813b228 --- /dev/null +++ b/Chamah.vala @@ -0,0 +1,85 @@ +using GLib; +using Pluie; + +uint8 gmul (uint8 a, uint8 b) { + uint8 p = 0; + uint8 counter; + uint8 hi_bit_set; + for (counter = 0; counter < 8; counter++) { + if ((b & 1) == 1) + p ^= a; + hi_bit_set = (a & 0x80); + a <<= 1; + if (hi_bit_set == 0x80) + a ^= 0x1b; + b >>= 1; + } + return p; +} + +int main (string[] argv) +{ + Pluie.init (); +//~ Pluie.random = new Crypt.PseudoRandom (0x4f1b6a28); + var path = "out.txt"; + uint8[] rawdata = new uint8[0]; + int siz = 0; + uint8 CHUNK_SIZE = 12; + stdout.printf ("\n== file : %s ==============\n", path); + var ics = new Io.InputChunkStream (path, CHUNK_SIZE); + while (ics.read () != null) { + stdout.printf ("%06lu [%02u:%02u]\t", ics.get_chunk_index (), ics.get_buffer_size (), ics.get_chunk_size ()); + for (var i = 0; i < ics.get_buffer_size (); i++) { + rawdata += ics.get_buffer ()[i]; siz++; + stdout.printf ("%02x ", ics.get_buffer ()[i]); + } + stdout.printf ("\n"); + } + stdout.printf ("\n"); + rawdata += (uint8) '\0'; + rawdata.resize (siz); + stdout.printf ("len %i - data :\n%s\n", rawdata.length, (string) rawdata); + +//~ stdout.printf ("\nlength : %u\n", data.length); + var chamah = new Crypt.Chamah (path); + var data = chamah.encode (); + var file = File.new_for_path ("out2.txt"); + // delete if file already exists + if (file.query_exists ()) { + file.delete (); + } + var dos = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION)); + ulong written = 0; + while (written < data.length) { + // sum of the bytes of 'text' that already have been written to the stream + written += dos.write (data[written:data.length]); + stdout.printf ("written %lu", written); + } + stdout.printf ("\n"); + path = "out2.txt"; + stdout.printf ("\n== file : %s ==============\n", path); + ics = new Io.InputChunkStream (path, CHUNK_SIZE); + while(ics.read () != null) { + stdout.printf ("%06lu [%02u:%02u]\t", ics.get_chunk_index (), ics.get_buffer_size (), ics.get_chunk_size ()); + for (var i = 0; i < ics.get_buffer_size (); i++) { + stdout.printf ("%02x ", ics.get_buffer ()[i]); + } + stdout.printf ("\n"); + } + stdout.printf ("\n"); + + var mdata = chamah.decode (path); + + uint8[] skey = { 0xe5, 0x03, 0x07, 0xc3, 0x9f, 0xd2, 0xfe, 0x00, 0xa5, 0x4b, 0xc7, 0x28, 0xb4, 0x63, 0x12, 0x99 }; + uint8[] smask = { 0xc7, 0x4e, 0xd4, 0x00, 0xa0, 0x1d, 0x6a, 0xb1, 0x55, 0x3e, 0xa5, 0xf0, 0x06, 0xd7, 0xe3, 0x5b }; + + string hb = Hmac.compute_for_data (ChecksumType.SHA256, skey, mdata.data); + stdout.printf ("hmac-sha256 :\n%s\n", hb); + + Checksum checksum = new Checksum (ChecksumType.SHA256); + checksum.update (mdata.data, (size_t) mdata.data.length); + unowned string digest = checksum.get_string (); + stdout.printf ("sha256 :\n%s\n", digest); + + return 0; +} diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..f45d032 --- /dev/null +++ b/build.sh @@ -0,0 +1,19 @@ +path=$(dirname "${BASH_SOURCE[0]}") +cd $path +valac -X -lm \ +--pkg gee-0.8 \ +--pkg glib-2.0 \ +--pkg gio-2.0 \ +Chamah.vala \ +src/pluie/global.vala \ +src/pluie/bin.vala \ +src/pluie/crypt.Chamah.vala \ +src/pluie/crypt.Sbox.vala \ +src/pluie/crypt.MatrixBytes.vala \ +src/pluie/crypt.Permutation.vala \ +src/pluie/crypt.PseudoRandom.vala \ +src/pluie/crypt.KeyPermuter.vala \ +src/pluie/crypt.Movment.vala \ +src/pluie/io.Bytes.vala \ +src/pluie/io.InputChunkStream.vala \ +-o chamah \ diff --git a/out.txt b/out.txt new file mode 100644 index 0000000..b3e6f71 --- /dev/null +++ b/out.txt @@ -0,0 +1,3 @@ +blaz to blaz +000000000000 +azoazoazoazo diff --git a/out2.txt b/out2.txt new file mode 100644 index 0000000..c2a6af6 --- /dev/null +++ b/out2.txt @@ -0,0 +1 @@ +0QìvÌ2ÿ•÷8šXí6á/îѼTÖ8Vw»ccÌŽ(¢S \ No newline at end of file diff --git a/src/pluie/bin.vala b/src/pluie/bin.vala new file mode 100644 index 0000000..1163b35 --- /dev/null +++ b/src/pluie/bin.vala @@ -0,0 +1,132 @@ +using GLib; + +namespace Pluie.bin +{ + // left rotation + const int BOX_MODE_LROT = 0x01; + // inverse left rotation + const int BOX_MODE_ILROT = 0x02; + // reverse left rotation + const int BOX_MODE_RLROT = 0x04; + // reverse inverse left rotation + const int BOX_MODE_RILROT = 0x08; + + private void check_nbit (int v) + { +//~ check_int_range (v, 1, 8, "invalid bit value"); + } + + public uint8 set (uint8 d, int bit=1) + { + check_nbit (bit); + return d | (1 << --bit); + } + + public uint8 unset (uint8 d, int bit=1) + { + check_nbit (bit); + return d & ~(1 << --bit); + } + + public bool isset (uint8 d, int bit=1) + { + check_nbit (bit); + return (d & (0x01 << --bit)) != 0; + } + + public int[] byte_coord (ref uint8 byte) + { + int[] coord = new int[2]; + coord[1] = ((int) byte) % 16; + coord[0] = ((int) byte / 16) % 16; + return coord; + } + + public uint8 reverse (uint8 d) + { + uint8 r = 0x00; + int lim = 9; + for(var i = 1; i < lim; i++) + if (isset (d, i)) + r = bin.set (r, lim-i); + return r; + } + + public uint8 rrot (uint8 d, int nbit = 1) + { + check_nbit (nbit); + uint8 k = (uint8) nbit; + return ((d >> k) | (d << (8-k))) & ((1 << 8)-1); + } + + public uint8 lrot (uint8 d, int nbit = 1) + { + check_nbit (nbit); + uint8 k = (uint8) nbit; + return ((d << k) | (d >> (8-k))) & ((1 << 8)-1); + } + + public uint8 sbin_dec (string sbin) + { + uint8 v = 0; + for (var i=0; i < sbin.length; i++) { + v += ((uint8) int.parse (sbin[i].to_string ()))*((uint8) Math.pow (2, sbin.length-1-i)); + } + return v; + } + + public string dec_sbin (uint8 n, int bit=8) + { + string d = ""; + _dec_sbin (n, ref d); + return (@"%0$bit"+"d").printf (int.parse (d)); + } + + private void _dec_sbin (uint8 n, ref string s) + { + if (n >= 1) _dec_sbin (n/2, ref s); + s += "%u".printf (n%2); + } + + public string dec_str (uint8 n) + { + uint8[] f = {n}; + f += (uint8) '\0'; + return (string) f; + } + + public uint8[] mask (uint8[] raw, string mask) + { + uint8[] masked = new uint8[raw.length]; + for (var i = 0; i < raw.length; i++) { + masked[i] = (uint8) (raw[i] ^ mask.data[i%mask.data.length]); + } + return masked; + } + + public uint8[] smbox (uint8 generator, int mode, int start=0) + { + uint8[] box = new uint8[8]; + switch (mode) { + case BOX_MODE_LROT : + box[start] = generator; + break; + case BOX_MODE_ILROT : + box[start] = ~generator; + break; + case BOX_MODE_RLROT : + box[start] = reverse (generator); + break; + case BOX_MODE_RILROT : + box[start] = ~reverse (generator); + break; + } + int j = start; + for (var i = 1; i < 8; i++) { + if (++j > 7) j = 0; + box[j] = lrot (box[start], 1); + start = j; + } + return box; + } +} diff --git a/src/pluie/crypt.Chamah.vala b/src/pluie/crypt.Chamah.vala new file mode 100644 index 0000000..a3fe8b3 --- /dev/null +++ b/src/pluie/crypt.Chamah.vala @@ -0,0 +1,117 @@ +using GLib; +using Gee; +using Pluie; + +class Pluie.Crypt.Chamah : Object +{ + protected bool DEBUG = true; + protected Io.InputChunkStream ics; + protected uint8 chunk_size = 12; + protected uint8[] key; + protected uint8[] mask; + protected Crypt.Sbox[] allbox; + + public Chamah (string? path = null) + { + if (path != null) { + this.ics = new Io.InputChunkStream (path, this.chunk_size); + } + this.init (); + } + + public void init () + { + this.key = { 0xe5, 0x03, 0x07, 0xc3, 0x9f, 0xd2, 0xfe, 0x00, 0xa5, 0x4b, 0xc7, 0x28, 0xb4, 0x63, 0x12, 0x99 }; + this.mask = { 0xc7, 0x4e, 0xd4, 0x00, 0xa0, 0x1d, 0x6a, 0xb1, 0x55, 0x3e, 0xa5, 0xf0, 0x06, 0xd7, 0xe3, 0x5b }; + this.allbox = new Crypt.Sbox[this.key.length]; + for (var i = 0; i < this.key.length; i++) { + this.allbox[i] = new Crypt.Sbox (this.key[i], this.mask[i]); + if (DEBUG) this.allbox[i].display_sbox(); + } + } + + public int8[] round_byte_def (int8 round) + { + int8[] def = new int8[this.chunk_size]; + for (var i = 0; i < 4; i++) { + def[(round + i + (round % 2 != 0 ? 3 : 0)) % this.chunk_size] = 1; + } + return def; + } + + public uint8[] encode () + { + uint8[] udata = new uint8[0]; + int size = 0; + if (this.ics != null) { + int chunk_num = 0; + while (this.ics.read () != null) { + udata.resize ((int) udata.length + ics.get_buffer_size ()); + for (var i = 0; i < this.ics.get_buffer_size (); i++) { + udata[size++] = this.cypher (ref i, chunk_num); + } + chunk_num++; + } + } +//~ udata += (uint8) '\0'; + udata.resize (size); + stdout.printf ("\nlen %i - data :\n%s\n", udata.length, (string) udata); + return udata; + } + + private uint8 cypher (ref int i, int chunk_num) + { + uint8 byte = this.ics.get_buffer ()[i]; + int k; + if (DEBUG) stdout.printf("== %02x ===============\n", byte); + for (var round = 0; round < this.chunk_size; round++) { + k = i % 2 == 0 ? round : this.key.length-1-round; + byte = this.allbox[k].substitute (byte); + if (DEBUG) stdout.printf ("r : %02d - i : %02d - l : %02d - k : %02d - b : %02x", round, i, chunk_num, k, byte); + if (this.round_byte_def (round)[i] == 1) { + k = (round % 2 == 0 ? this.key.length - round + chunk_num : round + chunk_num ) % this.key.length; + byte = this.allbox[k].substitute (byte); + if (DEBUG) stdout.printf (" - k : %02d - b : %02x", k, byte); + } + if (DEBUG) stdout.printf ("\n"); + } + return byte; + } + + public string decode (string path) + { + this.ics = new Io.InputChunkStream (path, this.chunk_size); + uint8[] udata = new uint8[0]; + int size = 0; + if (this.ics != null) { + int chunk_num = 0; + while (this.ics.read () != null) { + udata.resize((int) udata.length + ics.get_buffer_size()); + for (var i = 0; i < this.ics.get_buffer_size (); i++) { + udata[size++] = this.decypher (ref i, chunk_num); + } + chunk_num++; + } + } + udata += (uint8) '\0'; + udata.resize (size); + stdout.printf ("\nlen %i - data :\n%s\n", udata.length, (string) udata); + return (string) udata; + } + + private uint8 decypher (ref int i, int chunk_num) + { + uint8 byte = this.ics.get_buffer ()[i]; + int k; + for (var round = this.chunk_size-1; round >= 0; round--) { + if (this.round_byte_def (round)[i] == 1) { + k = (round % 2 == 0 ? this.key.length - round + chunk_num : round + chunk_num ) % this.key.length; + byte = this.allbox[k].substitute (byte, false); + } + k = i % 2 == 0 ? round : this.key.length-1-round; + byte = this.allbox[k].substitute (byte, false); + } + return byte; + } + +} diff --git a/src/pluie/crypt.KeyPermuter.vala b/src/pluie/crypt.KeyPermuter.vala new file mode 100644 index 0000000..035429b --- /dev/null +++ b/src/pluie/crypt.KeyPermuter.vala @@ -0,0 +1,27 @@ +using GLib; +using Gee; +using Pluie; + +class Pluie.Crypt.KeyPermuter : Object +{ + protected uint8 generator; + protected Crypt.Movment mvt_index; + protected Crypt.Movment mvt_rotation; + + public KeyPermuter (uint8 generator) + { + this.generator = generator; + this.mvt_rotation = new Crypt.Movment (generator, Pluie.Crypt.Sbox.DEF_ROT_ORDER); + this.mvt_index = new Crypt.Movment (generator, Pluie.Crypt.Sbox.DEF_INDEX_ORDER); + } + + public int next_rotation () + { + return this.mvt_rotation.move (); + } + + public int next_index () + { + return this.mvt_index.move (); + } +} diff --git a/src/pluie/crypt.MatrixBytes.vala b/src/pluie/crypt.MatrixBytes.vala new file mode 100644 index 0000000..f5bf5b8 --- /dev/null +++ b/src/pluie/crypt.MatrixBytes.vala @@ -0,0 +1,69 @@ +using GLib; +using Gee; +using Pluie; + +class Pluie.Crypt.MatrixBytes : Object +{ + public Io.Bytes bytes { get; private set; } + public int size { get; private set; } + + public MatrixBytes (int size) + { + this.size = size; + this.bytes = new Io.Bytes ((int) Math.pow (size, 2)); + } + + public bool add (uint8 byte) + { + return this.bytes.add (byte); + } + + public new bool set (int col, int row, uint8 byte) + { + return this.bytes.set ((this.size*col)+row, byte); + } + + public new uint8 get (int col, int row) + { + this.check_range (col); + this.check_range (row); + return this.bytes.get ((this.size*col)+row); + } + + public uint8[] get_col (int n) + { + this.check_range (n); + return this.bytes.get_range (this.size*n, this.size); + } + + public uint8[] get_row (int n) + { + this.check_range (n); + uint8[] row = new uint8[this.size]; + for (var i = 0; i < this.size; i++) { + row[i] = this.bytes.get ((i*this.size)+n); + } + return row; + } + + public int[] coord (uint8 byte) + { + int[] c = new int[2]; + int i = this.bytes.index (byte); + if (i >= 0) { + c[0] = (int) Math.floor (i/this.size); + c[1] = i % this.size; + } + return c; + } + + public bool contains (uint8 byte) + { + return this.bytes.contains (byte); + } + + private void check_range (int n) + { + check_int_range (n, 0, this.size-1); + } +} diff --git a/src/pluie/crypt.Movment.vala b/src/pluie/crypt.Movment.vala new file mode 100644 index 0000000..d550cb6 --- /dev/null +++ b/src/pluie/crypt.Movment.vala @@ -0,0 +1,49 @@ +using GLib; +using Gee; +using Pluie; + +class Pluie.Crypt.Movment : Object +{ + protected uint8 generator; + protected uint8[] movment_def; + protected uint8[] combination; + protected int index; + Crypt.Permutation movment; + + public Movment (uint8 generator, int[] definition) + { + this.index = 0; + this.movment_def = Movment.read_definition (definition); + this.generator = generator; + this.movment = new Crypt.Permutation (this.movment_def); + } + + private static uint8[] read_definition (int[] definition) + { + bool has_null = false; + uint8[] def = new uint8[definition.length]; + for (var i = 0; i < definition.length; i++) { + if (!has_null && (has_null = definition[i] == 0)) { + i = 0; + } + def[i] = (uint8) definition[i] + (has_null ? 1 : 0); + } + return def; + } + + public int move () + { + if (this.index % this.movment_def.length == 0) { + this.index = 0; + int movment_combination = (int) Pluie.random.range (1, this.movment.count(), this.generator); +//~ stdout.printf ("movment_combination : %d\n", movment_combination); + this.combination = this.movment.combination (movment_combination); + } + int move = (int) this.combination[this.index++]; + for(var j = 0; j < this.movment_def.length; j++) { +//~ stdout.printf ("0x%02x ", this.combination[j]); + } +//~ stdout.printf ("\nmovment index %d - next movment : %d\n", this.index-1, move); + return move; + } +} diff --git a/src/pluie/crypt.Permutation.vala b/src/pluie/crypt.Permutation.vala new file mode 100644 index 0000000..f2ccf9f --- /dev/null +++ b/src/pluie/crypt.Permutation.vala @@ -0,0 +1,63 @@ +using GLib; + +class Pluie.Crypt.Permutation : Object +{ + private string[] all; + private uint8[] items; + + public Permutation (uint8[] items) + { + this.items = items; + this.all = new string[0]; + permute (ref this.items, this.items.length); + } + + public int count () + { + return this.all.length; + } + + public uint8[] combination (int index) + { + check_int_range (index, 0, this.count ()-1, "invalid combination int value"); + uint8[] combination = this.all[index].data; + combination.resize (this.items.length); + return combination; + } + + public void print () + { + stdout.printf ("\nPermutation : "); + for (var i = 0; i < this.items.length; i++) { + stdout.printf ("0x%02x ", this.items[i]); + } + stdout.printf ("'\n%i combinations\n\n", this.count ()); + for(var i =0; i < this.count (); i++) { + stdout.printf ("%d : ", i+1); + for (var j = 0; j < this.items.length; j++) { + stdout.printf ("0x%02x ", all[i].data[j]); + } + stdout.printf ("\n"); + } + } + + private static void swap (ref uint8[] data, int right, int left) + { + uint8 tmp = data[right]; + data[right] = data[left]; + data[left] = tmp; + } + + private void permute (ref uint8[] data, int pos) + { + if (pos == 1) { + this.all += ((string) data); + } + else { + for (int i = 0; i < pos; i++) { + permute (ref data, pos - 1); + swap (ref data, pos % 2 == 1 ? 0 : i, pos - 1); + } + } + } +} diff --git a/src/pluie/crypt.PseudoRandom.vala b/src/pluie/crypt.PseudoRandom.vala new file mode 100644 index 0000000..30b0821 --- /dev/null +++ b/src/pluie/crypt.PseudoRandom.vala @@ -0,0 +1,59 @@ +using GLib; + +class Pluie.Crypt.PseudoRandom : Object +{ + uint32 seed; + int index; + int8 round = 7; + + public PseudoRandom (uint32 seed) + { + this.seed = seed; + + } + + private void swap (uint *a, uint *b) + { + uint temp = *a; + *a = *b; + *b = temp; + } + + private void randomiz (ref uint[] arr, int no, uint8 generator) + { + for (int i = arr.length-1; i >= 0; i--) { + // Pick a random index from 0 to i + int j = (int) this.random (generator) % (i+1); + // Swap arr[i] with the element at random index + this.swap (&arr[i], &arr[j]); + } + } + + public uint range (int min, int max, uint8 generator) + { + var arr = new uint[max-min+1]; + for (int i = 0; i < max-min; i++) { + arr[i] = min+i; + } + arr.resize (max-min+1); + this.randomiz (ref arr, max-min+1, generator); + if (this.index > arr.length) { + this.index = 0; + } + return arr[this.index++]; + } + + private uint random (uint8 generator) + { + uint badseed = seed + generator; + uint a = (int) (badseed < 22 ? badseed ^ 0x80 : badseed) + 7; + string v; + int i; + for (var c = 0; c < this.round; c++) { + v = "%d".printf ((int) Math.pow ((a), 2)); + i = v.length > 9 ? 3 : (v.length > 6 ? 2 : 1); + a += (uint) int.parse (v[i:-i]) + 1 + c; + } + return a; + } +} diff --git a/src/pluie/crypt.Sbox.vala b/src/pluie/crypt.Sbox.vala new file mode 100644 index 0000000..3301cb1 --- /dev/null +++ b/src/pluie/crypt.Sbox.vala @@ -0,0 +1,112 @@ +using GLib; +using Gee; +using Pluie; + +class Pluie.Crypt.Sbox : Object +{ + public static int[] DEF_ROT_ORDER = { + bin.BOX_MODE_LROT, bin.BOX_MODE_ILROT, bin.BOX_MODE_RLROT, bin.BOX_MODE_RILROT + }; + public static int[] DEF_INDEX_ORDER = {1,3,5,6,7}; + protected static string SEP = "----------------------------------------------------------------------------------"; + + protected Crypt.KeyPermuter key_permuter; + public Crypt.MatrixBytes sbox_data { get; private set; } + public unowned uint8 generator { get; private set; } + public unowned uint8 mask { get; set; } + + public Sbox (uint8 generator, uint8 mask) + { + this.generator = generator; + this.mask = mask; + this.key_permuter = new Crypt.KeyPermuter (this.generator); + this.sbox_data = new Crypt.MatrixBytes (16); + this.generate (); + } + + public void generate () + { + uint8 v; + int pos; + int mode; + uint8 gen = this.generator; + uint8[] box; + uint8 kmask = this.mask; + for (var r = 0; r < 32; r++) { + pos = this.key_permuter.next_index (); + mode = this.key_permuter.next_rotation (); + box = bin.smbox (gen, mode, pos); + for (var i = 0; i < box.length; i++) { + v = box[i] == kmask ? box[i] ^ gen: box[i] ^ kmask; + this.gen_byte (ref v, ref gen, ref box, i, mode, pos); + this.sbox_data.add (v); + } + } + } + + private uint8 gen_byte (ref uint8 v, ref uint8 gen, ref uint8[] box, int i, int mode, int pos) + { + uint8 c = 0; + int max_attempt = 70; + int size = (int) Math.pow (this.sbox_data.size, 2); + while (true) { + if (this.sbox_data.contains (v)) { + if (c > max_attempt && c < size + max_attempt) { + if (c > size) c -= (uint8) size-1; + v = c++ ^ gen; + } + else { + gen = box[i] + c++; + box = bin.smbox (gen, mode, pos); + v = box[i] + c; + } + } + else break; + } + return v; + } + + public uint8? substitute (uint8 byte, bool hide=true) + { + uint8 sbyte; + int[] coord; + if (hide) { + coord = this.sbox_data.coord (byte); + sbyte = coord.length == 2 ? (uint8) coord[1]*16 + coord[0] : byte; + } + else { + coord = bin.byte_coord (ref byte); + sbyte = this.get_box_data (coord[1], coord[0]); + } + return sbyte; + } + + private uint8 move_index (int[] a, uint8 pos) + { + return pos > a.length-2 ? 0 : pos + 1; + } + + public uint8 get_box_data (int col, int row) + { + return this.sbox_data.get (col, row); + } + + public void display_sbox () + { + stdout.printf ("\n %.*s\n", 82, Sbox.SEP); + stdout.printf (" |"); + for (var col = 0; col < 16; col++) { + stdout.printf ("| %02x ", (uint8) col); + } + stdout.printf ("|\n %.*s\n", 82, Sbox.SEP); + for (var row = 0; row < 16; row++) { + for (var col = 0; col < 16; col++) { + if (col == 0) { + stdout.printf (" %02x |", (uint8) row); + } + stdout.printf ("| %02x ", this.get_box_data(col, row)); + } + stdout.printf ("|\n"); + } + } +} diff --git a/src/pluie/global.vala b/src/pluie/global.vala new file mode 100644 index 0000000..b013ef5 --- /dev/null +++ b/src/pluie/global.vala @@ -0,0 +1,30 @@ +using Pluie; + +namespace Pluie { + + Crypt.PseudoRandom random; + + public void init () + { + random = new Pluie.Crypt.PseudoRandom (0x4f1b6a57); + } + + public errordomain RangeError + { + OUT_OF_BOUND + } + + public void range_thrower (int d, int min, int max, string msg) throws RangeError + { + throw new RangeError.OUT_OF_BOUND ("RangeError "+msg+" : %d must be set between %d and %d".printf (d, min, max)); + } + + public void check_int_range (int v, int min, int max, string msg = "invalid int value") + { + if (!(v >= min && v <= max)) { + message (msg+@" : $v"); + range_thrower (v, min, max, msg); + } + } + +} diff --git a/src/pluie/io.Bytes.vala b/src/pluie/io.Bytes.vala new file mode 100644 index 0000000..65e9895 --- /dev/null +++ b/src/pluie/io.Bytes.vala @@ -0,0 +1,94 @@ +using GLib; +using Gee; +using Pluie; + +class Pluie.Io.Bytes : Object +{ + public bool duplicate { get; private set; default = true; } + public int size { get; private set; } + public int len { get; private set; default = 0; } + public uint8[] data { get; private set; } + + public Bytes (int size, bool duplicate = true) + { + this.duplicate = duplicate; + this.size = size; + this.data = new uint8[size]; + this.len = 0; + } + + public bool add (uint8 byte) + { + return this.set (this.len, byte); + } + + public new uint8? get (int index) + { + if (this.check_index (index)) { + return this.data[index]; + } + else return null; + } + + public int index (uint8 byte) + { + int index = -1; + for (var i =0; i < this.len; i++) { + if (this.data[i] == byte) { + index = i; + break; + } + } + return index; + } + + public uint8[] get_range (int index, int length) + { + bool done = false; + uint8[] list = {0}; + if (index < 0) { + index = this.len - index.abs(); + } + if (length != 0 && this.check_index (this.len - index - length.abs ())) { + int s = length < 0 ? index+length : index; + int e = length < 0 ? index : index+length; + if ((done = !(s < 0 && s < e))) { + list = (uint8[]) this.data[s:e]; + list.resize (length.abs()); + } + } + if (!done) { + message ("Pluie.bin.RangeError.OUT_OF_BOUND in Pluie.Bytes.get_range(%d, %d) caller".printf (index, length)); + } + return list; + } + + public new bool set (int index, uint8 byte) + { + bool done = !this.full () && this.check_index (index) && (!this.duplicate || !this.contains (byte)); + if (done) { + this.data[index] = byte; + if (index >= this.len) { + this.len = index+1; + } + done = true; + } + return done; + } + + public bool full () + { + return this.len == this.size; + } + + protected bool check_index (int index, bool on_length = false) + { + int max = !on_length ? this.size : this.len; + return index >= 0 && index < max; + } + + public bool contains (uint8 byte) + { + return this.index (byte) > -1; + } +} diff --git a/src/pluie/io.InputChunkStream.vala b/src/pluie/io.InputChunkStream.vala new file mode 100644 index 0000000..77efbf1 --- /dev/null +++ b/src/pluie/io.InputChunkStream.vala @@ -0,0 +1,56 @@ +using GLib; + +class Pluie.Io.InputChunkStream : Object +{ + protected ulong chunk_index; + protected uint8 chunk_size; + protected uint8 buffer_size; + protected uint8[] buffer; + protected FileStream fs; + + public InputChunkStream (string path, uint8 chunk_size) + { + this.chunk_size = chunk_size; + this.buffer = new uint8[this.chunk_size]; + this.fs = FileStream.open (path, "r"); + this.chunk_index = 0; + } + + public bool eof () + { + bool stop = this.fs.eof (); + if (stop) { + this.buffer = null; + } + return stop; + } + + public unowned uint8[] read () + { + if (!this.eof ()) { + this.buffer_size = (uint8) this.fs.read (this.buffer); + this.chunk_index++; + } + return this.buffer; + } + + public unowned uint8 get_buffer_size () + { + return this.buffer_size; + } + + public unowned uint8[] get_buffer () + { + return this.buffer; + } + + public ulong get_chunk_index () + { + return this.chunk_index-1; + } + + public uint8 get_chunk_size () + { + return this.chunk_size; + } +}