|
@@ -0,0 +1,525 @@
|
|
|
+
|
|
|
+package com.oblivm.backend.circuits.arithmetic;
|
|
|
+
|
|
|
+import java.util.Arrays;
|
|
|
+
|
|
|
+import com.oblivm.backend.circuits.CircuitLib;
|
|
|
+import com.oblivm.backend.flexsc.CompEnv;
|
|
|
+import com.oblivm.backend.util.Utils;
|
|
|
+
|
|
|
+public class IntegerLib<T> extends CircuitLib<T> implements ArithmeticLib<T> {
|
|
|
+
|
|
|
+ public int width;
|
|
|
+
|
|
|
+ public IntegerLib(CompEnv<T> e) {
|
|
|
+ super(e);
|
|
|
+ width = 32;
|
|
|
+ }
|
|
|
+
|
|
|
+ public IntegerLib(CompEnv<T> e, int width) {
|
|
|
+ super(e);
|
|
|
+ this.width = width;
|
|
|
+ }
|
|
|
+
|
|
|
+ static final int S = 0;
|
|
|
+ static final int COUT = 1;
|
|
|
+
|
|
|
+ public T[] publicValue(double v) {
|
|
|
+ int intv = (int) v;
|
|
|
+ return toSignals(intv, width);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected T[] add(T x, T y, T cin) {
|
|
|
+ T[] res = env.newTArray(2);
|
|
|
+
|
|
|
+ T t1 = xor(x, cin);
|
|
|
+ T t2 = xor(y, cin);
|
|
|
+ res[S] = xor(x, t2);
|
|
|
+ t1 = and(t1, t2);
|
|
|
+ res[COUT] = xor(cin, t1);
|
|
|
+
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public T[] addFull(T[] x, T[] y, boolean cin) {
|
|
|
+ assert (x != null && y != null && x.length == y.length) : "add: bad inputs.";
|
|
|
+
|
|
|
+ T[] res = env.newTArray(x.length + 1);
|
|
|
+ T[] t = add(x[0], y[0], env.newT(cin));
|
|
|
+ res[0] = t[S];
|
|
|
+ for (int i = 0; i < x.length - 1; i++) {
|
|
|
+ t = add(x[i + 1], y[i + 1], t[COUT]);
|
|
|
+ res[i + 1] = t[S];
|
|
|
+ }
|
|
|
+ res[res.length - 1] = t[COUT];
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] add(T[] x, T[] y, boolean cin) {
|
|
|
+ return Arrays.copyOf(addFull(x, y, cin), x.length);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] add(T[] x, T[] y) {
|
|
|
+
|
|
|
+ return add(x, y, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] sub(T x, T y) throws Exception {
|
|
|
+ T[] ax = env.newTArray(2);
|
|
|
+ ax[1] = SIGNAL_ZERO;
|
|
|
+ ax[0] = x;
|
|
|
+ T[] ay = env.newTArray(2);
|
|
|
+ ay[1] = SIGNAL_ZERO;
|
|
|
+ ay[0] = y;
|
|
|
+ return sub(x, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] sub(T[] x, T[] y) {
|
|
|
+ assert (x != null && y != null && x.length == y.length) : "sub: bad inputs.";
|
|
|
+
|
|
|
+ return add(x, not(y), true);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] incrementByOne(T[] x) {
|
|
|
+ T[] one = zeros(x.length);
|
|
|
+ one[0] = SIGNAL_ONE;
|
|
|
+ return add(x, one);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] decrementByOne(T[] x) {
|
|
|
+ T[] one = zeros(x.length);
|
|
|
+ one[0] = SIGNAL_ONE;
|
|
|
+ return sub(x, one);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] conditionalIncreament(T[] x, T flag) {
|
|
|
+ T[] one = zeros(x.length);
|
|
|
+ one[0] = mux(SIGNAL_ZERO, SIGNAL_ONE, flag);
|
|
|
+ return add(x, one);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] conditionalDecrement(T[] x, T flag) {
|
|
|
+ T[] one = zeros(x.length);
|
|
|
+ one[0] = mux(SIGNAL_ZERO, SIGNAL_ONE, flag);
|
|
|
+ return sub(x, one);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T geq(T[] x, T[] y) {
|
|
|
+ assert (x.length == y.length) : "bad input";
|
|
|
+
|
|
|
+ T[] result = sub(x, y);
|
|
|
+ return not(result[result.length - 1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T leq(T[] x, T[] y) {
|
|
|
+ return geq(y, x);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] multiply(T[] x, T[] y) {
|
|
|
+ return Arrays.copyOf(multiplyInternal(x, y), x.length);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public T[] multiplyFull(T[] x, T[] y) {
|
|
|
+ return multiplyInternal(x, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ private T[] multiplyInternal(T[] x, T[] y) {
|
|
|
+
|
|
|
+ assert (x != null && y != null) : "multiply: bad inputs";
|
|
|
+ T[] res = zeros(x.length + y.length);
|
|
|
+ T[] zero = zeros(x.length);
|
|
|
+
|
|
|
+ T[] toAdd = mux(zero, x, y[0]);
|
|
|
+ System.arraycopy(toAdd, 0, res, 0, toAdd.length);
|
|
|
+
|
|
|
+ for (int i = 1; i < y.length; ++i) {
|
|
|
+ toAdd = Arrays.copyOfRange(res, i, i + x.length);
|
|
|
+ toAdd = add(toAdd, mux(zero, x, y[i]), false);
|
|
|
+ System.arraycopy(toAdd, 0, res, i, toAdd.length);
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] absolute(T[] x) {
|
|
|
+ T reachedOneSignal = SIGNAL_ZERO;
|
|
|
+ T[] result = zeros(x.length);
|
|
|
+ for (int i = 0; i < x.length; ++i) {
|
|
|
+ T comp = eq(SIGNAL_ONE, x[i]);
|
|
|
+ result[i] = xor(x[i], reachedOneSignal);
|
|
|
+ reachedOneSignal = or(reachedOneSignal, comp);
|
|
|
+ }
|
|
|
+ return mux(x, result, x[x.length - 1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] div(T[] x, T[] y) {
|
|
|
+ T[] absoluteX = absolute(x);
|
|
|
+ T[] absoluteY = absolute(y);
|
|
|
+ T[] PA = divInternal(absoluteX, absoluteY);
|
|
|
+ return addSign(Arrays.copyOf(PA, x.length), xor(x[x.length - 1], y[y.length - 1]));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public T[] divInternal(T[] x, T[] y) {
|
|
|
+ T[] PA = zeros(x.length + y.length);
|
|
|
+ T[] B = y;
|
|
|
+ System.arraycopy(x, 0, PA, 0, x.length);
|
|
|
+ for (int i = 0; i < x.length; ++i) {
|
|
|
+ PA = leftShift(PA);
|
|
|
+ T[] tempP = sub(Arrays.copyOfRange(PA, x.length, PA.length), B);
|
|
|
+ PA[0] = not(tempP[tempP.length - 1]);
|
|
|
+ System.arraycopy(mux(tempP, Arrays.copyOfRange(PA, x.length, PA.length), tempP[tempP.length - 1]), 0, PA,
|
|
|
+ x.length, y.length);
|
|
|
+ }
|
|
|
+ return PA;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] mod(T[] x, T[] y) {
|
|
|
+ T Xneg = x[x.length - 1];
|
|
|
+ T[] absoluteX = absolute(x);
|
|
|
+ T[] absoluteY = absolute(y);
|
|
|
+ T[] PA = divInternal(absoluteX, absoluteY);
|
|
|
+ T[] res = Arrays.copyOfRange(PA, y.length, PA.length);
|
|
|
+ return mux(res, sub(toSignals(0, res.length), res), Xneg);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] addSign(T[] x, T sign) {
|
|
|
+ T[] reachedOneSignal = zeros(x.length);
|
|
|
+ T[] result = env.newTArray(x.length);
|
|
|
+ for (int i = 0; i < x.length - 1; ++i) {
|
|
|
+ reachedOneSignal[i + 1] = or(reachedOneSignal[i], x[i]);
|
|
|
+ result[i] = xor(x[i], reachedOneSignal[i]);
|
|
|
+ }
|
|
|
+ result[x.length - 1] = xor(x[x.length - 1], reachedOneSignal[x.length - 1]);
|
|
|
+ return mux(x, result, sign);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] commonPrefix(T[] x, T[] y) {
|
|
|
+ assert (x != null && y != null) : "multiply: bad inputs";
|
|
|
+ T[] result = xor(x, y);
|
|
|
+
|
|
|
+ for (int i = x.length - 2; i >= 0; --i) {
|
|
|
+ result[i] = or(result[i], result[i + 1]);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] leadingZeros(T[] x) {
|
|
|
+ assert (x != null) : "leading zeros: bad inputs";
|
|
|
+
|
|
|
+ T[] result = Arrays.copyOf(x, x.length);
|
|
|
+ for (int i = result.length - 2; i >= 0; --i) {
|
|
|
+ result[i] = or(result[i], result[i + 1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return numberOfOnes(not(result));
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] lengthOfCommenPrefix(T[] x, T[] y) {
|
|
|
+ assert (x != null) : "lengthOfCommenPrefix : bad inputs";
|
|
|
+
|
|
|
+ return leadingZeros(xor(x, y));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Integer manipulation
|
|
|
+ */
|
|
|
+ public T[] leftShift(T[] x) {
|
|
|
+ assert (x != null) : "leftShift: bad inputs";
|
|
|
+ return leftPublicShift(x, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] rightShift(T[] x) {
|
|
|
+ assert (x != null) : "rightShift: bad inputs";
|
|
|
+ return rightPublicShift(x, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] leftPublicShift(T[] x, int s) {
|
|
|
+ assert (x != null && s < x.length) : "leftshift: bad inputs";
|
|
|
+
|
|
|
+ T res[] = env.newTArray(x.length);
|
|
|
+ System.arraycopy(zeros(s), 0, res, 0, s);
|
|
|
+ System.arraycopy(x, 0, res, s, x.length - s);
|
|
|
+
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] rightPublicShift(T[] x, int s) {
|
|
|
+ assert (x != null && s < x.length) : "rightshift: bad inputs";
|
|
|
+
|
|
|
+ T[] res = env.newTArray(x.length);
|
|
|
+ System.arraycopy(x, s, res, 0, x.length - s);
|
|
|
+ System.arraycopy(zeros(s), 0, res, x.length - s, s);
|
|
|
+
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] conditionalLeftPublicShift(T[] x, int s, T sign) {
|
|
|
+ assert (x != null && s < x.length) : "leftshift: bad inputs";
|
|
|
+
|
|
|
+ T[] res = env.newTArray(x.length);
|
|
|
+ System.arraycopy(mux(Arrays.copyOfRange(x, 0, s), zeros(s), sign), 0, res, 0, s);
|
|
|
+ System.arraycopy(mux(Arrays.copyOfRange(x, s, x.length), Arrays.copyOfRange(x, 0, x.length), sign), 0, res, s,
|
|
|
+ x.length - s);
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] conditionalRightPublicShift(T[] x, int s, T sign) {
|
|
|
+ assert (x != null && s < x.length) : "rightshift: bad inputs";
|
|
|
+
|
|
|
+ T res[] = env.newTArray(x.length);
|
|
|
+ System.arraycopy(mux(Arrays.copyOfRange(x, 0, x.length - s), Arrays.copyOfRange(x, s, x.length), sign), 0, res,
|
|
|
+ 0, x.length - s);
|
|
|
+ System.arraycopy(mux(Arrays.copyOfRange(x, x.length - s, x.length), zeros(s), sign), 0, res, x.length - s, s);
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] leftPrivateShift(T[] x, T[] lengthToShift) {
|
|
|
+ T[] res = Arrays.copyOf(x, x.length);
|
|
|
+
|
|
|
+ for (int i = 0; ((1 << i) < x.length) && i < lengthToShift.length; ++i)
|
|
|
+ res = conditionalLeftPublicShift(res, (1 << i), lengthToShift[i]);
|
|
|
+ T clear = SIGNAL_ZERO;
|
|
|
+ for (int i = 0; i < lengthToShift.length; ++i) {
|
|
|
+ if ((1 << i) >= x.length)
|
|
|
+ clear = or(clear, lengthToShift[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return mux(res, zeros(x.length), clear);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] rightPrivateShift(T[] x, T[] lengthToShift) {
|
|
|
+ T[] res = Arrays.copyOf(x, x.length);
|
|
|
+
|
|
|
+ for (int i = 0; ((1 << i) < x.length) && i < lengthToShift.length; ++i)
|
|
|
+ res = conditionalRightPublicShift(res, (1 << i), lengthToShift[i]);
|
|
|
+ T clear = SIGNAL_ZERO;
|
|
|
+ for (int i = 0; i < lengthToShift.length; ++i) {
|
|
|
+ if ((1 << i) >= x.length)
|
|
|
+ clear = or(clear, lengthToShift[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return mux(res, zeros(x.length), clear);
|
|
|
+ }
|
|
|
+
|
|
|
+ T compare(T x, T y, T cin) {
|
|
|
+ T t1 = xor(x, cin);
|
|
|
+ T t2 = xor(y, cin);
|
|
|
+ t1 = and(t1, t2);
|
|
|
+ return xor(x, t1);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T compare(T[] x, T[] y) {
|
|
|
+ assert (x != null && y != null && x.length == y.length) : "compare: bad inputs.";
|
|
|
+
|
|
|
+ T t = env.newT(false);
|
|
|
+ for (int i = 0; i < x.length; i++) {
|
|
|
+ t = compare(x[i], y[i], t);
|
|
|
+ }
|
|
|
+
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T eq(T x, T y) {
|
|
|
+ assert (x != null && y != null) : "CircuitLib.eq: bad inputs";
|
|
|
+
|
|
|
+ return not(xor(x, y));
|
|
|
+ }
|
|
|
+
|
|
|
+ public T eq(T[] x, T[] y) {
|
|
|
+ assert (x != null && y != null && x.length == y.length) : "CircuitLib.eq[]: bad inputs.";
|
|
|
+
|
|
|
+ T res = env.newT(true);
|
|
|
+ for (int i = 0; i < x.length; i++) {
|
|
|
+ T t = eq(x[i], y[i]);
|
|
|
+ res = env.and(res, t);
|
|
|
+ }
|
|
|
+
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] twosComplement(T[] x) {
|
|
|
+ T reachOne = SIGNAL_ZERO;
|
|
|
+ T[] result = env.newTArray(x.length);
|
|
|
+ for (int i = 0; i < x.length; ++i) {
|
|
|
+ result[i] = xor(x[i], reachOne);
|
|
|
+ reachOne = or(reachOne, x[i]);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] hammingDistance(T[] x, T[] y) {
|
|
|
+ T[] a = xor(x, y);
|
|
|
+ return numberOfOnes(a);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] numberOfOnes(T[] t) {
|
|
|
+ if (t.length == 0) {
|
|
|
+ T[] res = env.newTArray(1);
|
|
|
+ res[0] = SIGNAL_ZERO;
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+ if (t.length == 1) {
|
|
|
+ return t;
|
|
|
+ } else {
|
|
|
+ int length = 1;
|
|
|
+ int w = 1;
|
|
|
+ while (length <= t.length) {
|
|
|
+ length <<= 1;
|
|
|
+ w++;
|
|
|
+ }
|
|
|
+ length >>= 1;
|
|
|
+
|
|
|
+ T[] res1 = numberOfOnesN(Arrays.copyOfRange(t, 0, length));
|
|
|
+ T[] res2 = numberOfOnes(Arrays.copyOfRange(t, length, t.length));
|
|
|
+ return add(padSignal(res1, w), padSignal(res2, w));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] numberOfOnesN(T[] res) {
|
|
|
+ if (res.length == 1)
|
|
|
+ return res;
|
|
|
+ T[] left = numberOfOnesN(Arrays.copyOfRange(res, 0, res.length / 2));
|
|
|
+ T[] right = numberOfOnesN(Arrays.copyOfRange(res, res.length / 2, res.length));
|
|
|
+ return unSignedAdd(left, right);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] unSignedAdd(T[] x, T[] y) {
|
|
|
+ assert (x != null && y != null && x.length == y.length) : "add: bad inputs.";
|
|
|
+ T[] res = env.newTArray(x.length + 1);
|
|
|
+
|
|
|
+ T[] t = add(x[0], y[0], env.newT(false));
|
|
|
+ res[0] = t[S];
|
|
|
+ for (int i = 0; i < x.length - 1; i++) {
|
|
|
+ t = add(x[i + 1], y[i + 1], t[COUT]);
|
|
|
+ res[i + 1] = t[S];
|
|
|
+ }
|
|
|
+ res[res.length - 1] = t[COUT];
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] unSignedMultiply(T[] x, T[] y) {
|
|
|
+ assert (x != null && y != null) : "multiply: bad inputs";
|
|
|
+
|
|
|
+ T[] res = zeros(x.length + y.length);
|
|
|
+ T[] zero = zeros(x.length);
|
|
|
+
|
|
|
+ T[] toAdd = mux(zero, x, y[0]);
|
|
|
+ System.arraycopy(toAdd, 0, res, 0, toAdd.length);
|
|
|
+
|
|
|
+ for (int i = 1; i < y.length; ++i) {
|
|
|
+ toAdd = Arrays.copyOfRange(res, i, i + x.length);
|
|
|
+ toAdd = unSignedAdd(toAdd, mux(zero, x, y[i]));
|
|
|
+ System.arraycopy(toAdd, 0, res, i, toAdd.length);
|
|
|
+
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] karatsubaMultiply(T[] x, T[] y) {
|
|
|
+ if (x.length <= 18)
|
|
|
+ return unSignedMultiply(x, y);
|
|
|
+
|
|
|
+ int length = (x.length + y.length);
|
|
|
+
|
|
|
+ T[] xlo = Arrays.copyOfRange(x, 0, x.length / 2);
|
|
|
+ T[] xhi = Arrays.copyOfRange(x, x.length / 2, x.length);
|
|
|
+ T[] ylo = Arrays.copyOfRange(y, 0, y.length / 2);
|
|
|
+ T[] yhi = Arrays.copyOfRange(y, y.length / 2, y.length);
|
|
|
+
|
|
|
+ int nextlength = Math.max(x.length / 2, x.length - x.length / 2);
|
|
|
+ xlo = padSignal(xlo, nextlength);
|
|
|
+ xhi = padSignal(xhi, nextlength);
|
|
|
+ ylo = padSignal(ylo, nextlength);
|
|
|
+ yhi = padSignal(yhi, nextlength);
|
|
|
+
|
|
|
+ T[] z0 = karatsubaMultiply(xlo, ylo);
|
|
|
+ T[] z2 = karatsubaMultiply(xhi, yhi);
|
|
|
+
|
|
|
+ T[] z1 = sub(padSignal(karatsubaMultiply(unSignedAdd(xlo, xhi), unSignedAdd(ylo, yhi)), 2 * nextlength + 2),
|
|
|
+ padSignal(unSignedAdd(padSignal(z2, 2 * nextlength), padSignal(z0, 2 * nextlength)),
|
|
|
+ 2 * nextlength + 2));
|
|
|
+ z1 = padSignal(z1, length);
|
|
|
+ z1 = leftPublicShift(z1, x.length / 2);
|
|
|
+
|
|
|
+ T[] z0Pad = padSignal(z0, length);
|
|
|
+ T[] z2Pad = padSignal(z2, length);
|
|
|
+ z2Pad = leftPublicShift(z2Pad, 2 * (x.length / 2));
|
|
|
+ return add(add(z0Pad, z1), z2Pad);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] min(T[] x, T[] y) {
|
|
|
+ T leq = leq(x, y);
|
|
|
+ return mux(y, x, leq);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] sqrt(T[] a) {
|
|
|
+ int newLength = a.length;
|
|
|
+ if (newLength % 2 == 1)
|
|
|
+ newLength++;
|
|
|
+ T[] x = padSignal(a, newLength);
|
|
|
+
|
|
|
+ T[] rem = zeros(x.length);
|
|
|
+ T[] root = zeros(x.length);
|
|
|
+ for (int i = 0; i < x.length / 2; i++) {
|
|
|
+ root = leftShift(root);
|
|
|
+ rem = add(leftPublicShift(rem, 2), rightPublicShift(x, x.length - 2));
|
|
|
+ x = leftPublicShift(x, 2);
|
|
|
+ T[] oldRoot = root;
|
|
|
+ root = copy(root);
|
|
|
+ root[0] = SIGNAL_ONE;
|
|
|
+ T[] remMinusRoot = sub(rem, root);
|
|
|
+ T isRootSmaller = not(remMinusRoot[remMinusRoot.length - 1]);
|
|
|
+ rem = mux(rem, remMinusRoot, isRootSmaller);
|
|
|
+ root = mux(oldRoot, incrementByOne(root), isRootSmaller);
|
|
|
+ }
|
|
|
+ return padSignal(rightShift(root), a.length);
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] inputOfAlice(double d) {
|
|
|
+ return env.inputOfAlice(Utils.fromLong((long) d, width));
|
|
|
+ }
|
|
|
+
|
|
|
+ public T[] inputOfBob(double d) {
|
|
|
+ return env.inputOfBob(Utils.fromLong((long) d, width));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public CompEnv<T> getEnv() {
|
|
|
+ return env;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public T[] toSecureInt(T[] a, IntegerLib<T> lib) {
|
|
|
+ return a;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public T[] toSecureFloat(T[] a, FloatLib<T> lib) {
|
|
|
+ T[] v = padSignal(a, lib.VLength);
|
|
|
+ T[] p = leadingZeros(v);
|
|
|
+ v = leftPrivateShift(v, p);
|
|
|
+ p = padSignal(p, lib.PLength);
|
|
|
+ p = sub(zeros(p.length), p);
|
|
|
+ return lib.pack(new FloatLib.Representation<T>(SIGNAL_ZERO, v, p));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public T[] toSecureFixPoint(T[] a, FixedPointLib<T> lib) {
|
|
|
+ return leftPublicShift(padSignal(a, lib.width), lib.offset);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public double outputToAlice(T[] a) {
|
|
|
+ return Utils.toInt(env.outputToAlice(a));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int numBits() {
|
|
|
+ return width;
|
|
|
+ }
|
|
|
+}
|