content: package dk.alexandra.fresco.suite.spdz2k.protocols.computations;
  
  import static org.junit.Assert.assertTrue;
  
  import dk.alexandra.fresco.framework.Application;
  import dk.alexandra.fresco.framework.DRes;
  import dk.alexandra.fresco.framework.MaliciousException;
  import dk.alexandra.fresco.framework.TestThreadRunner.TestThread;
  import dk.alexandra.fresco.framework.TestThreadRunner.TestThreadFactory;
  import dk.alexandra.fresco.framework.builder.numeric.Numeric;
  import dk.alexandra.fresco.framework.builder.numeric.ProtocolBuilderNumeric;
  import dk.alexandra.fresco.framework.network.Network;
  import dk.alexandra.fresco.framework.sce.evaluator.EvaluationStrategy;
  import dk.alexandra.fresco.framework.util.AesCtrDrbg;
  import dk.alexandra.fresco.framework.value.SInt;
  import dk.alexandra.fresco.suite.ProtocolSuiteNumeric;
  import dk.alexandra.fresco.suite.spdz2k.AbstractSpdz2kTest;
  import dk.alexandra.fresco.suite.spdz2k.Spdz2kProtocolSuiteK64;
  import dk.alexandra.fresco.suite.spdz2k.datatypes.CompUInt128;
  import dk.alexandra.fresco.suite.spdz2k.datatypes.CompUInt128Factory;
  import dk.alexandra.fresco.suite.spdz2k.datatypes.CompUIntFactory;
  import dk.alexandra.fresco.suite.spdz2k.datatypes.Spdz2kSInt;
  import dk.alexandra.fresco.suite.spdz2k.resource.Spdz2kResourcePool;
  import dk.alexandra.fresco.suite.spdz2k.resource.Spdz2kResourcePoolImpl;
  import dk.alexandra.fresco.suite.spdz2k.resource.storage.Spdz2kDummyDataSupplier;
  import dk.alexandra.fresco.suite.spdz2k.resource.storage.Spdz2kOpenedValueStoreImpl;
  import java.math.BigInteger;
  import java.util.function.Supplier;
  import org.junit.Test;
  
  public class TestSpdz2kMacCheckComputation extends
      AbstractSpdz2kTest<Spdz2kResourcePool<CompUInt128>> {
  
    @Test
    public void testInvalidMacCheck() {
      int noOfParties = 2;
      for (int cheatingPartyId = 1; cheatingPartyId <= noOfParties; cheatingPartyId++) {
        runTest(new TestModifyShare<>(cheatingPartyId), EvaluationStrategy.SEQUENTIAL_BATCHED,
            noOfParties);
      }
    }
  
    @Test
    public void testInvalidMacCheckThree() {
      int noOfParties = 3;
      for (int cheatingPartyId = 1; cheatingPartyId <= noOfParties; cheatingPartyId++) {
        runTest(new TestModifyShare<>(cheatingPartyId), EvaluationStrategy.SEQUENTIAL_BATCHED,
            noOfParties);
      }
    }
  
    @Override
    protected Spdz2kResourcePool<CompUInt128> createResourcePool(int playerId, int noOfParties,
        Supplier<Network> networkSupplier) {
      CompUIntFactory<CompUInt128> factory = new CompUInt128Factory();
      Spdz2kResourcePool<CompUInt128> resourcePool =
          new Spdz2kResourcePoolImpl<>(
              playerId,
              noOfParties, null,
              new Spdz2kOpenedValueStoreImpl<>(),
              new Spdz2kDummyDataSupplier<>(playerId, noOfParties, factory.createRandom(), factory),
              factory);
      resourcePool.initializeJointRandomness(networkSupplier, AesCtrDrbg::new, 32);
      return resourcePool;
    }
  
    @Override
    protected ProtocolSuiteNumeric<Spdz2kResourcePool<CompUInt128>> createProtocolSuite() {
      return new Spdz2kProtocolSuiteK64();
    }
  
    private static class TestModifyShare<ResourcePoolT extends Spdz2kResourcePool<CompUInt128>>
        extends TestThreadFactory<ResourcePoolT, ProtocolBuilderNumeric> {
  
      private final int cheatingPartyId;
  
      TestModifyShare(int cheatingPartyId) {
        this.cheatingPartyId = cheatingPartyId;
      }
  
      @Override
      public TestThread<ResourcePoolT, ProtocolBuilderNumeric> next() {
        return new TestThread<ResourcePoolT, ProtocolBuilderNumeric>() {
          @Override
          public void test() {
            Application<BigInteger, ProtocolBuilderNumeric> app = producer -> {
              Numeric numeric = producer.numeric();
              DRes<SInt> input = numeric.input(BigInteger.ONE, 1);
              return producer.seq(seq -> {
                SInt value = input.out();
                if (seq.getBasicNumericContext().getMyId() == cheatingPartyId) {
                  value = ((Spdz2kSInt<CompUInt128>) value).multiply(
                      new CompUInt128(BigInteger.valueOf(2)));
                }
                final SInt finalSInt = value;
                return seq.numeric().open(() -> finalSInt);
              });
            };
            try {
              runApplication(app);
            } catch (Exception e) {
              assertTrue(e.getCause() instanceof MaliciousException);
            }
          }
        };
      }
    }
  
  }
  