Permalink
Browse files

Encryption Example: Key Exchange + Symmetric Enc

  • Loading branch information...
akosba committed Jun 9, 2016
1 parent 5555d7e commit 03a2e75cb07d7585ad9f556effa50bffda565561
@@ -0,0 +1,107 @@
/*******************************************************************************
* Author: Ahmed Kosba <akosba@cs.umd.edu>
*******************************************************************************/
package examples.gadgets.encrypt;
import java.util.Arrays;
import util.Util;
import circuit.operations.Gadget;
import circuit.structure.Wire;
/**
* Performs Key Exchange using a field extension F_p[x]/(x^\mu - \omega), where the polynomial (x^\mu - \omega) is irreducible.
* The inputs to this gadget: the base g, the other party's input h = g^a, the bits of the secret exponent secExpBits and omega.
* The outputs of this gadget: the derived key h^s to be used for symmetric key derivation, and g^s which is sent to the other party.
*
* A sample parameter choice can be found in the test
* A sample usage is in: examples/generators/EncryptionCircuitGenerator.java
*/
public class DHKeyExchangeGadget extends Gadget {
private Wire[] g; // base
private Wire[] h; // other party's input
private Wire[] secExpBits; // the bits of the secret exponent
private long omega;
private int mu;
private Wire[] g_to_s; // exchange material g^s (to be sent to the other party)
private Wire[] h_to_s; // the derived key h^s
public DHKeyExchangeGadget(Wire[] g, Wire[] h, Wire[] expBits, long omega,
String desc) {
super(desc);
this.g = g;
this.h = h;
this.secExpBits = expBits;
this.omega = omega;
mu = g.length;
if(h.length != g.length){
throw new IllegalArgumentException("g and h must have the same dimension");
}
buildCircuit();
}
protected void buildCircuit() {
g_to_s = exp(g, secExpBits);
h_to_s = exp(h, secExpBits);
}
private Wire[] mul(Wire[] a, Wire[] b){
Wire[] c = new Wire[mu];
int i,j;
for( i = 0; i < mu; i+=1){
c[i] = generator.getZeroWire();
}
for( i = 0; i < mu; i+=1){
for( j = 0; j < mu; j+=1){
int k = i + j;
if(k < mu){
c[k] = c[k].add(a[i].mul(b[j]));
}
k = i+j-mu;
if(k >= 0){
c[k] = c[k].add(a[i].mul(b[j]).mul(omega));
}
}
}
return c;
}
private Wire[] exp(Wire[] base, Wire[] expBits){
Wire[][] powersTable =new Wire[expBits.length][mu];
powersTable[0] = base;
for(int j = 1; j < expBits.length; j+=1){
powersTable[j] = mul(powersTable[j-1],powersTable[j-1]);
}
Wire[] c = new Wire[mu];
Arrays.fill(c, generator.getZeroWire());
c[0] = generator.getOneWire();
for( int j = 0; j < expBits.length; j+=1){
Wire[] tmp = mul(c, powersTable[j]);
for(int i = 0; i < mu; i++){
c[i] = c[i].add(expBits[j].mul(tmp[i].sub(c[i])));
}
}
return c;
}
@Override
public Wire[] getOutputWires() {
return Util.concat(g_to_s, h_to_s);
}
public Wire[] getG_to_s() {
return g_to_s;
}
public Wire[] getH_to_s() {
return h_to_s;
}
}
@@ -0,0 +1,79 @@
/*******************************************************************************
* Author: Ahmed Kosba <akosba@cs.umd.edu>
*******************************************************************************/
package examples.gadgets.encrypt;
import circuit.operations.Gadget;
import circuit.structure.CircuitGenerator;
import circuit.structure.Wire;
/**
* http://csrc.nist.gov/groups/ST/lwc-workshop2015/papers/session1-shors-paper.pdf
*
*/
public class Speck128CipherGadget extends Gadget {
private Wire[] plaintext;
private Wire[] expandedKey;
private Wire[] ciphertext;
/**
*
* @param inputs: Array of 2 64-bit elements.
* @param expandedKey: Array of 32 64-bit elements. (Call expandKey(..))
* @param desc
*/
public Speck128CipherGadget(Wire[] plaintext, Wire[] expandedKey, String...desc) {
super(desc);
if (plaintext.length != 2 || expandedKey.length != 32) {
throw new IllegalArgumentException("Invalid Input");
}
this.plaintext = plaintext;
this.expandedKey = expandedKey;
buildCircuit();
}
protected void buildCircuit() {
Wire x, y;
x = plaintext[1];
y = plaintext[0];
ciphertext = new Wire[2];
for (int i = 0; i <= 31; i++) {
x = x.rotateRight(64, 8).add(y);
x.getBitWires(65);
x = x.xorBitwise(expandedKey[i], 64);
y = y.rotateLeft(64 , 3).xorBitwise(x, 64);
}
ciphertext[1] = x;
ciphertext[0] = y;
}
/**
*
* @param key: 2 64-bit words
* @return
*/
public static Wire[] expandKey(Wire[] key){
CircuitGenerator generator = CircuitGenerator.getActiveCircuitGenerator();
Wire[] k = new Wire[32];
Wire[] l =new Wire[32];
k[0] = key[0];
l[0] = key[1];
for (int i = 0; i <= 32 - 2; i++) {
l[i + 1] = k[i].add(l[i].rotateLeft(64, 56));
l[i + 1].getBitWires(65);
l[i + 1] = l[i + 1].xorBitwise(generator.createConstantWire(i), 64);
k[i+1] = k[i].rotateLeft(64, 3).xorBitwise(l[i+1], 64);
}
return k;
}
@Override
public Wire[] getOutputWires() {
return ciphertext;
}
}
@@ -0,0 +1,88 @@
/*******************************************************************************
* Author: Ahmed Kosba <akosba@cs.umd.edu>
*******************************************************************************/
package examples.gadgets.encrypt;
import java.util.Arrays;
import util.Util;
import circuit.operations.Gadget;
import circuit.structure.Wire;
import circuit.structure.WireArray;
/**
* Performs symmetric encryption in the CBC mode.
* Only supports one cipher (speck128) as an example at the moment. Other ciphers will be integrated soon.
*
*/
public class SymmetricEncryptionCBCGadget extends Gadget {
private Wire[] ciphertext;
private String cipherName;
private Wire[] keyBits;
private Wire[] plaintextBits;
private Wire[] ivBits;
private int blocksize = 128;
private int keysize = 128;
public SymmetricEncryptionCBCGadget(Wire[] plaintextBits, Wire[] keyBits,
Wire[] ivBits, String cipherName, String... desc) {
super(desc);
if(keyBits.length != keysize || ivBits.length != keysize){
throw new IllegalArgumentException("Key and IV bit vectors should be of length 128");
}
this.plaintextBits = plaintextBits;
this.ivBits = ivBits;
this.keyBits = keyBits;
this.cipherName = cipherName;
buildCircuit();
}
protected void buildCircuit() {
int numBlocks = (int) Math.ceil(plaintextBits.length * 1.0 / blocksize);
plaintextBits = new WireArray(plaintextBits).adjustLength(numBlocks * blocksize)
.asArray();
Wire[] preparedKey = prepareKey();
WireArray prevCipher = new WireArray(ivBits);
ciphertext = new Wire[0];
for (int i = 0; i < numBlocks; i++) {
WireArray msgBlock = new WireArray(Arrays.copyOfRange(plaintextBits, i
* blocksize, (i + 1) * blocksize));
Wire[] xored = msgBlock.xorWireArray(prevCipher).asArray();
if (cipherName.equals("speck128")) {
Wire[] tmp = new WireArray(xored).packBitsIntoWords(64);
Gadget gadget = new Speck128CipherGadget(tmp, preparedKey, "");
Wire[] outputs = gadget.getOutputWires();
prevCipher = new WireArray(outputs).getBits(64);
} else {
throw new UnsupportedOperationException("Other Ciphers not supported in this version!");
}
ciphertext = Util.concat(ciphertext,
prevCipher.packBitsIntoWords(64));
}
}
private Wire[] prepareKey() {
Wire[] preparedKey;
if (cipherName.equals("speck128")) {
Wire[] packedKey = new WireArray(keyBits).packBitsIntoWords(64);
preparedKey = Speck128CipherGadget.expandKey(packedKey);
} else {
throw new UnsupportedOperationException("Other Ciphers not supported in this version!");
}
return preparedKey;
}
@Override
public Wire[] getOutputWires() {
return ciphertext;
}
}
Oops, something went wrong.

0 comments on commit 03a2e75

Please sign in to comment.