Newsgroup: it.comp.sicurezza.crittografia
Titolo: che ne pensate di questo?

Visto su sci.crypt:
---------------
This message defines new symmetric cryptoalgorithm and contains an
implementation that can be used for practical testing.
The cryptoalgorithm has the following advantages:
1. Keys of arbitrary length are allowed.
2. The cryptoalgorithm is extremely easy to understand and implement.
3. The cryptoalgorithm is strong (not proved), open and free. I am the
originator of this cryptoalgorithm and I tell you: use it for free.
The cryptoalgorithm is based on the process of conversion from one numeric
system to another: a number is converted to another numeric system, the
"digits" are permuted and the result is converted back to the original
numeric system.
Description of the cryptoalgorithm:
- Plain text to encode is (long) unsigned integer number. Let's denote it by
A.
- Similarly, key is unsigned integer number B.
0. Plain text is compressed in order to transform it into a relatively
random (i.e. uncompressible) sequence of bytes using some compression
algorithm.
1. A is split into a sequence of remainders of division by B.
2. The sequence of remainders is permuted. B's value defines the
permutation.
3. The permuted sequence is converted to number A2.
- A2 is the encoded text.
---------------
Non mi sembra facilissimo da rompere... Che ne dite?
Ciao!

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Valerio wrote:
|che ne pensate di questo?
...vediamo un po'. No ho certo l'esperienza necessaria a "smontare" un
sistema anche solo semiserio (e neanche "un quarto di serio" =P) ma a
maggior ragione se troverò delle pecche si può tranquillamente dire che
è un sistema zero-serio 0=)
| This message defines new symmetric cryptoalgorithm and contains an
| implementation that can be used for practical testing.
"new" suona sempre male, ma andiamo avanti a leggere con mente aperta e
speranzosa...
| The cryptoalgorithm has the following advantages:
| 1. Keys of arbitrary length are allowed.
| 2. The cryptoalgorithm is extremely easy to understand and implement.
| 3. The cryptoalgorithm is strong (not proved), open and free. I am the
| originator of this cryptoalgorithm and I tell you: use it for free.
Ve bene, queset sono sicuramente caratteristiche desiderabili (in
assoluto), andiamo avanti...
| The cryptoalgorithm is based on the process of conversion from one numeric
| system to another: a number is converted to another numeric system, the
| "digits" are permuted and the result is converted back to the original
| numeric system.
0_o!
Forse non ho capito bene, ma stiamo dicendo che "convertire in binario +
qualche rotazione di byte" sarebbe un crittosistema?
Andiamo avanti con i particolari, magari si spiega melgio...
| Description of the cryptoalgorithm:
| - Plain text to encode is (long) unsigned integer number. Let's denote
it by
| A.
OK, ma siccome sono "rozzo" preferisco fare un esempio... vediamo:
A = "ciao" = 0x6369616F = 1.667.850.607
| - Similarly, key is unsigned integer number B.
OK... dato che l'autore nno ha posto limite ALCUNO sul numero che la
chiave può essere, proverò intenzionalmente una chiave corta e
assolutamente "non prima":
B = 16
| 0. Plain text is compressed in order to transform it into a relatively
| random (i.e. uncompressible) sequence of bytes using some compression
| algorithm.
Questo passo evito di farlo perché più che "risolvere" eventuali
problemi del cipher sottstante può facilmente solo "mascherarli".
| 1. A is split into a sequence of remainders of division by B.
Bene, quindi:
A = {6, 3, 6, 9, 6, 1, 6, 15}
| 2. The sequence of remainders is permuted. B's value defines the
| permutation.
Permutata *COME*?
Senza specificarlo, l'algoritmo non esiste...
| 3. The permuted sequence is converted to number A2.
Convertita *COME*?
Senza specificarlo, l'algoritmo non esiste...
| - A2 is the encoded text.
Eh grazie.. dopo aver "permutato e trasformato" in modo arbitrario
ottengo il testo cifrato, bella forza... è una definizione così generica
che 3/4 degli algoritmi esistenti ci ricade ^_^
NB: no in effetti no, nessuno degli algoritmi seri ci ricade: un
algoritmo non può solo permutare (principio di diffusione) ma anche
usare il principio di confusione.
| Non mi sembra facilissimo da rompere... Che ne dite?
Dico che la domanda se è facile o meno è mal posta, dato che l'algoritmo
non è specificato... ma oserei quasi dire che *QUALUNQUE* sia la
permutazione fatta l'algoritmo non è un gran che, per il fatto di non
contenere confusione...
Lapo
- --
L a p o   L u c h i n i
l a p o @ l a p o . i t
w w w . l a p o . i t /
http://www.megatokyo.it
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (Cygwin)
Comment: Using GnuPG with Mozilla - 
http://enigmail.mozdev.org
iEYEARECAAYFAkAzYdAACgkQaJiCLMjyUvtKDQCfdLqRG5sn5CO1eFOpaMpMlpVI
/UMAn3kL8YjQRdphDWxqjJqJSw22OBCS
=GrO4
-----END PGP SIGNATURE-----

 Senza specificarlo, l'algoritmo non esiste...
Per dovere di cronaca posto anche il resto del messaggio apparso su
sci.crypt, con tanto di implementazione in Java.
------------------
The following Java program is created for practical testing. It is a
complete
implementation of the cryptoalgorithm (without compression phase).
-------------------------------- A.java --------------------------------
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.util.LinkedList;
import java.util.ListIterator;
public class A
{
 public static void main(String[] args) throws Exception
 {
  if (args.length!=4) badArgs();
  String scmd=args[0];
  String skey=args[1];
  String sin=args[2];
  String sout=args[3];
  if ( !("e".equals(scmd) || "d".equals(scmd)) ) badArgs();
  boolean encrypt="e".equals(scmd);
  BigInteger b=new BigInteger(1, readFile(skey, 0));
  if (encrypt) {
     byte[] adata=readFile(sin, 1);
     // append positive most significant (random) byte
     for (int i=1; i<adata.length; i++) adata[0]^=adata[i];
     adata[0]&=(byte)0x7f;  // clear 10000000 bit
     adata[0]|=(byte)0x40;  // set   01000000 bit
     BigInteger a=new BigInteger(adata);
     BigInteger[] rems=computeRemainders(a, b);
     BigInteger[] rems2=permute(rems, b, false);
     BigInteger a2=computeNumber(rems2, b);
     writeFile(sout, a2.toByteArray(), 0);
  }
  else {
       BigInteger a=new BigInteger(readFile(sin, 0));
       BigInteger[] rems=computeRemainders(a, b);
       BigInteger[] rems2=permute(rems, b, true);
       BigInteger a2=computeNumber(rems2, b);
       writeFile(sout, a2.toByteArray(), 1);
  }
 }
 private static void badArgs()
 {
  System.err.println("Invalid args. Must be:");
  System.err.println("e|d key_file input_file output_file");
  System.exit(1);
 }
 private static byte[] readFile(String fname, int off) throws Exception
 {
  File f=new File(fname);
  FileInputStream fin=new FileInputStream(f);
  try {
      int len=(int)f.length();
      byte[] ret=new byte[len+off];
      fin.read(ret, off, len);
      return ret;
  }
  finally { fin.close(); }
 }
 private static void writeFile(String fname, byte[] data, int off)
   throws Exception
 {
  FileOutputStream fout=new FileOutputStream(fname);
  try { fout.write(data, off, data.length-off); }
  finally { fout.close(); }
 }
 public static BigInteger[] computeRemainders(BigInteger a, BigInteger b)
 {
  LinkedList lst=new LinkedList();
  while (!a.equals(BigInteger.ZERO)) {
        BigInteger[] qr=a.divideAndRemainder(b);
        lst.add(qr[1]);
        a=qr[0];
  }
  return (BigInteger[])lst.toArray(new BigInteger[lst.size()]);
 }
 public static BigInteger computeNumber(BigInteger[] rems, BigInteger b)
 {
  BigInteger a=BigInteger.ZERO;
  for (int i=rems.length-1; i>=0; i--) {
      a=a.multiply(b);
      a=a.add(rems[i]);
  }
  return a;
 }
 public static BigInteger[] permute(BigInteger[] rems, BigInteger b,
   boolean inverse)
 {
  int len=rems.length;
  BigInteger[] ret=new BigInteger[len];
  int pos[]=createPermutation(len, b, inverse);
  for (int i=0; i<len; i++) ret[pos[i]]=rems[i];
  return ret;
 }
 public static int[] createPermutation(int len, BigInteger b, boolean
inverse)
 {
  int[] ret=new int[len];
  LinkedList lst=new LinkedList();
  for (int i=0; i<len; i++) lst.add(new Integer(i));
  BigInteger b2=b;
  for (int div=len; div>=1; div--) {
      BigInteger bdiv=new BigInteger(""+div);
      if (div==len)                           // always move
         bdiv=bdiv.subtract(BigInteger.ONE);  // most significant remainder
      if (b2.compareTo(bdiv)<0) b2=b;  // restart from b
      BigInteger[] qr=b2.divideAndRemainder(bdiv);
      b2=qr[0];
      int rem=qr[1].intValue();
      ListIterator lit=lst.listIterator(rem);
      ret[div-1]=((Integer)lit.next()).intValue();
      lit.remove();
  }
  if (inverse) {
     int[] ret2=new int[len];
     for (int i=0; i<len; i++) ret2[ret[i]]=i;
     return ret2;
  }
  return ret;
 }
}
-----------------------------------8<-----------------------------------
Type
javac A.java
to compile the source. A.class file will appear.
To encode input_file using key_file, type
java A e key_file input_file output_file
The encoded text will be saved in output_file.
To decode output_file using key_file, type
java A d key_file output_file input_file2
The decoded text will be saved in input_file2 that must be equal to the
original input_file.
Implementation notes:
0. The compression phase increases the strength of the cryptoalgorithm. It
decreases probability of getting duplicate remainders, that is it increases
the permutation quality. In practice, duplicate remainders are very rare
because their number substantively less than B's value. The compression
algorithm does not have to obey any special requirements, ordinary Huffman
coding fits well.
1. The permutation algorithm must be based on key and choose a permutation
in
equiprobable way. And it must always move the most significant remainder
because leading bytes of the encoded text must differ from the original
plain
text. The used algorithm is rather straightforward and can probably be
improved.
2. Obviously, value of a number does not depend on leading zeros but leading
zeros must not be lost during encoding/decoding of A. That's why before the
encoding, some non-zero byte is appended to A. This byte will be discarded
before the writing of decoded text.
3. BigInteger datatype is signed and the most significant bit defines the
sign. As long as the cryptoalgorithm operates with unsigned integers the
special BigInteger constructor is used to create B's value. The constructor
allows to explicitly set the sign. Unfortunately, this constructor can
append
leading zero byte so it is not used for A. Instead, the most significant bit
(of the byte that is appended to A during construction) is always cleared.
4. The values of the minor bits of the byte that is appended to A are
computed via hashing bytes of the plain text. Actually, any number of bytes
with any values can be appended to A. For example, their values can depend
on
the current system time. In this case, the same key and plain text will lead
to different encoded texts. This modification of the cryptoalgorithm
substantively increases its strength.
Recommendations:
1. The key must consist of a random sequence of bits and be not less than 32
bytes (i.e. 256 bits).
2. Uneven (i.e. the least significant bit of last byte of the file is 1)
keys
should be used. It ensures that 2 and B are relatively prime numbers (have
no
common divisors).
3. To increase the strength of the cryptoalgorithm, plain text file
(input_file) must be at least 10 times longer than key_file. Obviously, if
input_file is shorter than key_file no encryption is possible.
4. As long as encryption/decryption time substantively depends on lengths of
files, it makes sense to split plain text file into parts of about
key_length*1000 size (i.e. 32000 bytes for 32 bytes key). Also it is not so
wise to use keys that longer than 64 bytes (i.e. 512 bits) in practice.
Notes:
1. All I know about this cryptoalgorithm is described above. I have
_nothing_
to add.
2. If you have some question but thoughtful analysis of the description and
the implementation does not lead to the answer then I do not know the answer
too. And I will not be able to help, sorry.
3. If you have discovered a mathematical flaw or found a bug in the
implementation, please mail me to 
new_crypto...@yahoo.com
. The
message
must be concise and have a descriptive subject. All other mails will be
ignored (no time for spam, sorry).
------------------
Ciao!

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Valerio wrote:
| Per dovere di cronaca posto anche il resto del messaggio apparso su
| sci.crypt, con tanto di implementazione in Java.
Ah ok, questo direi che taglia la testa al toro: l'autore stesso ammette
che il suo algoritmo è debolissimo ^_^
| Implementation notes:
| 0. The compression phase increases the strength of the cryptoalgorithm.
Che sia "sempre meglio comprimere" è un fatto, che un algoritmo ne abbia
"bisogno" significa ovviamente che l'algoritmo è debole...
| 1. The permutation algorithm must be based on key and choose a permutation
| in equiprobable way. And it must always move the most significant
remainder
| because leading bytes of the encoded text must differ from the original
| plain text. The used algorithm is rather straightforward and can
probably be
| improved.
Sì, come dicevo la scelta della permutaizone è critica.
Consiglio l'uso di un hash crittografico (ad esempio SHA-256) per ottenerla.
| Recommendations:
| 1. The key must consist of a random sequence of bits and be not less
than 32
| bytes (i.e. 256 bits).
Mhh... va beh, tanto il problema vero non è questo ^_^
| 2. Uneven (i.e. the least significant bit of last byte of the file is 1)
| keys should be used. It ensures that 2 and B are relatively prime
numbers (have
| no common divisors).
Mi chiedo perché debba essere relativamente primo con 2... va beh, tanto
il problema vero non è questo ^_^
| 3. To increase the strength of the cryptoalgorithm, plain text file
| (input_file) must be at least 10 times longer than key_file. Obviously, if
| input_file is shorter than key_file no encryption is possible.
Ogni tipo di limitazione "non ovvia" di questo tipo è imho "molto male"...
| 4. As long as encryption/decryption time substantively depends on
lengths of
| files, it makes sense to split plain text file into parts of about
| key_length*1000 size (i.e. 32000 bytes for 32 bytes key). Also it is
not so
| wise to use keys that longer than 64 bytes (i.e. 512 bits) in practice.
Ah, quindi per essere sicuro le chiavi devono essere "abbastanza lunghe,
ma non troppo lunghe" altrimenti la qualità degrada? -_-
| 3. If you have discovered a mathematical flaw or found a bug in the
| implementation, please mail me to 
new_crypto...@yahoo.com
. The
| message
| must be concise and have a descriptive subject. All other mails will be
| ignored (no time for spam, sorry).
Devo proprio?
1. è sempre antipatico dire alla gente che ha prodotto qualcosa di nno
sicuro
2. su sci.crypt c'è sicuramente chi sa fare un'analisi migliore della mia
3. non ho voglia di scrivere un lungo messaggio in inglese 0=)
Un solo consiglio lascio "ai posteri" che leggeranno questo post: *MAI
MAI MAI MAI MAI* usare algoritmi crittografici inventati "da
chicchessia" e non verificati "da tutti gli altri crittografi del mondo"
per alcun motivo che non sia "volevo far svagare mio figlio che fa la
seconda elementare".
;-)
- --
L a p o   L u c h i n i
l a p o @ l a p o . i t
w w w . l a p o . i t /
http://www.megatokyo.it
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (Cygwin)
Comment: Using GnuPG with Mozilla - 
http://enigmail.mozdev.org
iEYEARECAAYFAkAzkL8ACgkQaJiCLMjyUvuiywCgzJoOee0ptMuzJJ7cEWXhg0fM
VnoAmwdXh7ZBaFkiUsjtOB7aZt8kNCYW
=qra+
-----END PGP SIGNATURE-----