# CloudCrypto
Cryptographic primitive implementations for secure Cloud Storage / Computing applications.
## Introduction
Traditional public key cryptographic primitives (e.g., Diffie-Hellman, RSA, ElGamals) have been widely applied in practice to secure network and storage systems. However, such schemes have limited functionalities. Researches have been made to propose advancaed cryptographic primitives and schemes to meet the functionality and security needs for cloud storage / computing paradigms.
**CloudCrypto** project aims at implementing advanced cryptographic schemes under the well-designed Java Cryptographic Architecture (JCA). To achieve this target, **CloudCrypto** leverages [Bouncy Castle](http://www.bouncycastle.org/java.html) as the underlying library, which strictly follows JCA standard. In general, Java seems not a good choice for Crypto implementations due to runtime effiency.
We choose Java as the programming language since Java provides good portability so that **CloudCrypto** can be even **directly** port to mobile and / or other embedded devices, e.g., Android.
We are providing the source code of **CloudCrypto** with no license fee. It is open source and free to use for Research & Development purpose.
We are glad to notice that Medica Corp. is experimenting with **CloudCrypto** for Research & Development purpose.
## Develop Environments
**CloudCrypto** is buit using Maven 2. Please see `pom.xml` for the dependent libiraries. In its current version, **CloudCrypto** leverages the following libraries:
- [Bouncy Castle](http://www.bouncycastle.org/java.html): supporting basic cryptographic primitives, e.g., hash functions, symmetric encryption schemes.
- [jPBC Library](http://gas.dia.unisa.it/projects/jpbc/): supporting bilinear groups.
- [JUnit](http://junit.org/junit4/): for unit test.
- [Standard Input and Output Libraries by Princeton University](http://algs4.cs.princeton.edu/code/): an easy-to-use standard input and output library from the Princeton open course *Introduction to Programming: An Interdisciplinary Approach*. We only leverages `In.java`, `Out.java`, `StdIn.java`, `StdOut.java`, `BinaryIn.java`, `BinaryOut.java`. Therefore, we directly include these files in our project. You can find the source code under the package `/src/main/java/edu/princeton/cs/algs4`.
## Pairing-Based Cryptographic Primitives
In its current verion, **CloudCrypto** mainly focuses on implementing schemes based on Bilinear Groups. The underlying algebric library is [Java Pairing-Based Cryptography Library](http://gas.dia.unisa.it/projects/jpbc/).
### Challenges
There are some schemes implementations in Java Pairing-Based Cryptography, but with the following issues:
- No avaiable serialization methods.
- The encryption scheme implementations indeed encrypt a random element in G\_T, while there is no reasonable methods that can map messages / plaintexts to elements in G\_T in an one-to-one manner. That is, one cannot decrypt the ciphertext, get the elemment in G\_T, and map it back to the original message.
### Our Solutions
In our implementations, we leverage the built-in Java serialization method, allowing serializing any CipherParameters to byte arrays. This allows users to further upload the generated CipherParameters to public Clouds. Any objects whose name ends with `SerParameter` supports serialization. The following method in `src/main/java/cn/edu/buaa/crypto/utils/PairingUtils.java`shows how to serialize / deserizalie these objects:
public static byte[] SerCipherParameter(CipherParameters cipherParameters) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(cipherParameters);
byte[] byteArray = byteArrayOutputStream.toByteArray();
objectOutputStream.close();
byteArrayOutputStream.close();
return byteArray;
}
We provide a key encapsulation mechanisms for encryption schemes, i.e., the encryption algorithm encapsulates a random session key, by which the encryptor can use to encrypt arbitrary data using symmetric encryption schemes, i.e., AES, TwoFish.
### Object `PairingParameters`
The most important object for invoking pairing-based cryptographic schemes is `PairingParameters`, which belongs to jPBC library that provides all necessary information for bilinear groups. Note that it is a littie bit complicated to correctly generate such parameters without knowing necessary backgrounds about bilinear groups. We have pre-generated some parameters, all of which can be found at `/params`. We list some of the parameters used in our unit tests:
- `a_80_256.properties`: Type A prime-order bilinear groups with 80-bit Z_p and 256-bit G. Note that the group order cannot meet the security needs for today's system. This parameters can only be used for testing the correctness of the scheme implementations.
- `a_160_512.properties`: Type A prime-order bilinear groups with 160-bit Z_p and 512-bit G.
- `a1_3_128.properties` : Type A1 composite-order bilinear groups with 3 prime factors, all of which have size 128-bit. Note that the group order cannnot meet the security needs for today's sstem. This parameter can only be used for testing the correctness of the scheme implementations.
- `a1_3_512.properties`: Type A1 composite-order bilinear groups with 3 prime factors, all of which have size 512-bit.
- `f_160.properties`: Type F prime-order bilinear groups with 160-bit Z_p. Note that this group is an asymmetric bilinear group so that it can be only used for schemes built on asymmetric bilinear groups. We recommend using this properties for the Boneh-Lynn-Shacham short signature scheme.
The following code shows how to get PairingParameters from files in /params:
//Obtain PairingParameters from /params/a_160_512.properties
PairingParameters pairingParameters = PairingFactory.getPairingParameters("params/a_160_512.properties");
## Algebric Algorithms
### Linear Secret Sharing Scheme
Linear secret sharing scheme (LSSS) is the generalization of Shamir secret sharing scheme, which is one of the most famous cryptographic primitives proposed by Shamir in 1979 (See paper [*How To Share a Secret*](http://dl.acm.org/citation.cfm?id=359176)). In 1996, Beimel introduced the concept of LSSS, showing that Shamir's scheme can be seen as a special case for LSSS (See thesis [*Secret Schemes for Secret Sharing and Key Distribution*](https://www.cs.bgu.ac.il/~beimel/Papers/thesis.pdf)). Nowadays, LSSS has been a basic primitive to construct access control mechanism in Attribute-Based Encryption (ABE) systems.
We implemented two forms of access control mechanism by LSSS, one is based on the original Shamir's scheme. The other one is based on the construction by Waters and Lewko (See [full version](https://eprint.iacr.org/2010/351.pdf) of the paper [*Decentralizing Attribute-Based Encryption*](http://link.springer.com/chapter/10.1007%2F978-3-642-20465-4_31), Appendix G).
The following code shows how to construct and use access control mechanism using LSSS. The access tree is represented by int\[\]\[\], see the comment in the [source code](https://dsl-external.bbn.com/svn/openP3S/trunk/jmiracl-crypto/src/main/java/com/bbn/projects/spar/p3s/jmiracl/crypto/utils/LSSS.java) on how to represent access tree by int\[\]\[\].
Pairing pairing = PairingFactory.getPairing(pairingParameters);
//note that Lewko-Waters LSSS do not support threshold gate access control.
int[][] accessPolicy = {
{2,2,1,2},
{2,2,3,4},
{4,3,-7,-8,-9,-10},
{2,2,-2,5},
{3,2,-4,-5,-6},
{2,1,-1,-3}
};
// rhos can be arbitrary strings
String[] rhos = new String[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
String[] satisfiedRhos = new String[] {"2", "3",