initial commit
This commit is contained in:
commit
a4cd9f8e18
85
Chamah.vala
Normal file
85
Chamah.vala
Normal file
|
@ -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;
|
||||
}
|
19
build.sh
Executable file
19
build.sh
Executable file
|
@ -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 \
|
1
out2.txt
Normal file
1
out2.txt
Normal file
|
@ -0,0 +1 @@
|
|||
0Qלvּ2<D6BC>•<>ק<EFBFBD>8<EFBFBD>Xם6ב/מׁ¼Tײ8Vw»ccּ<63>(¢S
|
132
src/pluie/bin.vala
Normal file
132
src/pluie/bin.vala
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
117
src/pluie/crypt.Chamah.vala
Normal file
117
src/pluie/crypt.Chamah.vala
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
27
src/pluie/crypt.KeyPermuter.vala
Normal file
27
src/pluie/crypt.KeyPermuter.vala
Normal file
|
@ -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 ();
|
||||
}
|
||||
}
|
69
src/pluie/crypt.MatrixBytes.vala
Normal file
69
src/pluie/crypt.MatrixBytes.vala
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
49
src/pluie/crypt.Movment.vala
Normal file
49
src/pluie/crypt.Movment.vala
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
63
src/pluie/crypt.Permutation.vala
Normal file
63
src/pluie/crypt.Permutation.vala
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
59
src/pluie/crypt.PseudoRandom.vala
Normal file
59
src/pluie/crypt.PseudoRandom.vala
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
112
src/pluie/crypt.Sbox.vala
Normal file
112
src/pluie/crypt.Sbox.vala
Normal file
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
30
src/pluie/global.vala
Normal file
30
src/pluie/global.vala
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
94
src/pluie/io.Bytes.vala
Normal file
94
src/pluie/io.Bytes.vala
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
56
src/pluie/io.InputChunkStream.vala
Normal file
56
src/pluie/io.InputChunkStream.vala
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user