[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [GNU Crypto] towards a (new) high-level symmetric block cipher API(l
From: |
Raif S. Naffah |
Subject: |
Re: [GNU Crypto] towards a (new) high-level symmetric block cipher API(long) |
Date: |
Mon, 17 Mar 2003 06:33:14 +1100 |
User-agent: |
KMail/1.4.3 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160
On Sunday 16 March 2003 12:33, Casey Marshall wrote:
> Raif S. Naffah wrote:
> | hello there,
> |
> | here are some thoughts about a proposal for a new high-level API to
> | include in GNU Crypto.
> |
> | [...]
>
> I think this could be a somewhat redundant construction, and has a
> few problems.
what problems?
i've been busy refining the Cascade API and fleshing out code around it,
and i believe i have a working set. the proof-of-concept for me was
being able to construct a triple-DES from a cascade of three DES!
here is an example:
/** DES-EDE ECB encryption monte-carlo test. */
private static final String E_TV_K = "0123456789abcdef";
private static final String E_TV_3K = E_TV_K + E_TV_K + E_TV_K;
private static final String E_TV_PT = "4e6f772069732074";
private static final String E_TV_CT = "6a2a19f41eca854b";
public static final void main(String[] args) throws Exception {
byte[] kb, k3b, pt, ct;
byte[] ct1 = new byte[8];
byte[] ct2 = new byte[8];
kb = Util.toBytesFromString(E_TV_K);
k3b = Util.toBytesFromString(E_TV_3K);
pt = Util.toBytesFromString(E_TV_PT);
ct = Util.toBytesFromString(E_TV_CT);
HashMap map = new HashMap();
map.put(IBlockCipher.KEY_MATERIAL, k3b);
IBlockCipher desEDE = new TripleDES();
HashMap map1 = new HashMap();
HashMap map2 = new HashMap();
HashMap map3 = new HashMap();
map1.put(IBlockCipher.KEY_MATERIAL, kb);
map2.put(IBlockCipher.KEY_MATERIAL, kb);
map3.put(IBlockCipher.KEY_MATERIAL, kb);
Cascade new3DES = new Cascade();
new3DES.append(
Stage.getInstace(
ModeFactory.getInstance(Registry.ECB_MODE, new DES(), 8),
State.FORWARD,
map1));
new3DES.append(
Stage.getInstace(
ModeFactory.getInstance(Registry.ECB_MODE, new DES(), 8),
State.BACKWARD,
map2));
new3DES.append(
Stage.getInstace(
ModeFactory.getInstance(Registry.ECB_MODE, new DES(), 8),
State.FORWARD,
map3));
desEDE.init(map);
new3DES.init(State.FORWARD);
desEDE.encryptBlock(pt, 0, ct1, 0);
new3DES.update(pt, 0, ct2, 0);
System.out.println("ct1 == ct2 ? "+Util.areEqual(ct1, ct2));
for (int j = 0; j < 9999; j++) {
desEDE.encryptBlock(ct1, 0, ct1, 0);
new3DES.update(ct2, 0, ct2, 0);
}
System.out.println("ct == ct1 ? "+Util.areEqual(ct, ct1));
System.out.println("ct == ct2 ? "+Util.areEqual(ct, ct2));
}
in my mind, both Cascades and Assemblies serve different purposes. the
former are inherently block-oriented, operationally symmetric, and the
state of stage #i depends on all the stages from 0 to i-1. Assemblies
are different. the most distinguishing feature they display regards
the way they operate on the last construction/algorithm they contain.
considering the example of an Assembly with a Padding at the end, one
has to treat the last (incomplete) block differently than all the
others --the path applied to that last block differs from that applied
to all previous ones.
i'll post later the relevant API classes.
>... What I was thinking is a single master interface that
> works both as a collection of crypto primitives and as a node in a
> list. Something akin to:
>
> public interface IAssembly {
> ~ void init(Map[] attrib) throws ...;
> ~ int update(byte[] in, int inOffset, byte[] out, int outOffset)
> ~ throws ...;
> ~ int lastUpdate(byte[] in, int inOffset, byte[] out, int
> outOffset) ~ throws ...;
> ~ Iterator iterator();
> ~ void setNext(IAssembly ass);
> ~ IAssembly next();
> ~ ...
> }
>
> Where a concrete Assembly can contain a Mode+Cipher+Padding,
i am trying to allow Padding be applied to one or more Modes.
>... another
> Assembly, a list of Assemblies, etc. Calling update or lastUpdate on
> a "root" Assembly will start a chain of calls to *[uU]pdate, each one
> filtering its input before sending the data to its child.
this is applicable to Cascades, but not to Assemblies. in the case
where the last stage is a Padding, the last update in a forward
operation (encryption) will have to be processed through Padding first
(pad), while the last update in a backward operation (decryption) will
have to be processed through Padding last (unpad).
> I also think it would be desirable to have the Assembly be block-size
> ignorant;
that is easy to implement either in or outside an Assembly.
>... Such a construction would even allow non-cryptographic
> filters (such as a compression algorithm) to be placed into the
> chain.
>
> This is, I suppose, similar to an OutputStream in Java, except:
>
> ~ 1. The filtered data does not "come out" the end of the chain,
> but is rather passed back to the caller in the output array.
> ~ 2. The chain is iteratable.
> ~ 3. The chain is mutable (nodes can be moved, inserted, or
> removed).
i think both are useful. a stream API allows for both a PULL and PUSH
models (read/write), while what we have caters for a PUSH model only
(update).
> Additionally, an Assembly should perhaps have one additional
> component: a key derivation function. This could be simply a pointer
> that says "look for raw bytes in the attributes", a PBE KDF, a public
> key exchange method (DH), or something else.
yes!
as mentioned earlier, i'll post later a set of classes that cover the
Cascade --i haven't done anything with Assembly yet.
cheers;
rsn
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)
Comment: Que du magnifique
iD8DBQE+dNF7+e1AKnsTRiERA8FiAKCzHFLIutqKjkHRzujCwWFqU+g70QCfQ3pj
cRncPpPQB3sa7AeeEo8X6Vw=
=Ewh2
-----END PGP SIGNATURE-----