I’ve just managed to successfully implement a java technology proof of concept for the SMT encryption scheme, **ecies384-aes256** and **ecies384+rsa-aes256**

The concrete schemes are defined as:

encryption( M, PF, (K-A,K-a), K-B, A-B ) -> E, L

{

validate A-B must be a 384bit X.509 encoded EC sessionKey.

EC key generate (A-A,A-a), an EC keypair on secp384r1

ECDH key agreement (A-a,A-B) => shared secret S

PFS := SHA256(PF) – convert the PF into a shared secret.

SKe || IVe:= SHA384(S||PFS),

where SKe is a 256bit AES encryption key,

IVe is a 128bit initialization vector for the AES encryption

E := AES256/CTR(SKe,IVe,ZLib(M||Sign(K-a,M||byte-len(M))))

L := byte-len(M) || A-A

where byte-len(M) is the length of M in bytes represented as 8-byte fixed length big-endian integer.

A-A is a X.509 encoded EC public key – aka the sender’s messageKey

}

The encrypted data E is the compressed message and signature symmetrically encrypted with the derived secret key. The encryption context L is the concatenation of the message plaintext length with the unique EC public key of the originator. The length of the plaintext message is known outside the encrypted data so that suitable buffer space can be made available at decryption time and bound the decompression.

decryption( PF, (K-B, K-b), (A-B, A-b), K-A, E, L ) -> M

{

E := AES256/CTR(SKe,IVe,ZLib(M||Sign(K-a,M)))

L := byte-len(M) || A-A

where byte-len(M) is the length of M in bytes represented as 8-byte fixed length big-endian integer.

A-A is a X.509 encoded EC public key

PFS := SHA256(PF) – convert the PF into a shared secret.

ECDH key agreement (A-b,A-A) => shared secret S

SKe || IVe:= SHA384(S||PFS),

M || Sign(K-a,M) := GUNZIP(byte-len(M), AES256/CTR(SKe,IVe,E))

where decompression fails if invalid stream or if decompressed length > byte-len(M) or stream ends before byte-len(M) bytes are decompressed.

verify(K-A, M, Sign(K-a,M)) and fail if signature incorrect.

}

The ecies384+rsa-aes256 is a minor variant on ecies384-aes256 where

L := RSAEncrypt( K-B, byte-len(M) || A-A )

The encryption-context is encrypted with the destination user’s RSA public 2048bit key. This scheme “hides” the senders messageKey, by encrypting it with K-B. Only the destination can decrypt the messageKey and message length the destination’s private key K-b.

A lot of my time was spent implementing a temporary file backed input and output streams, so that the indefinitely long data could be written and read with encryption/decryption happening on the fly. I will eventually release the code under some open license – but first i want to get some kind of feedback from the crypto community about the value of the scheme itself. I also want to implement a cascading of AES with some other block/stream cipher. This is discussed by Zooko at the The Least-Authority File System blog.