protected override Zp GetRecombinedResult(IList <Zp> recvList, int prime) { // Scan recvList - if there are null elements replace them arbitrarily to Zp with zero value for (int i = 0; i < recvList.Count; i++) { if (recvList[i] == null) { recvList[i] = new Zp(prime, 0); } } var xVlaues = new List <Zp>(); int w = NumTheoryUtils.GetFieldMinimumPrimitive(prime); for (int i = 0; i < recvList.Count; i++) { xVlaues.Add(new Zp(prime, NumTheoryUtils.ModPow(w, i, prime))); } // Should call Welch-Berlekamp Decoder to fix error at last stage var fixedShares = WelchBerlekampDecoder.Decode(xVlaues, recvList, PolynomialDeg, PolynomialDeg, prime); if (fixedShares == null) { throw new Exception("There were more then polynomialDegree = " + PolynomialDeg + " Cheaters - cannot extract results."); } return(ShamirSharing.Recombine(fixedShares, PolynomialDeg, prime, true)); }
/// <summary> /// Creates a random polynomial f(x,y) and then to create from it for /// the i-th player two polynomials : fi(x) = f(x,w^i) and gi(y) = f(w^i,y). /// </summary> public static IList <SecretPolynomials> ShareByzantineCase(Zp secret, int numPlayers, int polynomDeg) { if (numPlayers <= 4 * polynomDeg) { throw new System.ArgumentException("Cannot use Byzantine algoritm -- numberOfPlayers <= 4*polynomDeg - " + "use regular computation instead"); } // Creating the Random Polynomial - f(x , y) // Note : there are (t+1)^2 coefficiet for the polynomial including the free coefficient (the secret) // first row coef are of (x^0,x^1,x^2,...,x^t)y^0, second row coef are (x^0, x1,...,x^t)y^1 and so forth... var randomMatrix_f_xy = ZpMatrix.GetRandomMatrix(polynomDeg + 1, polynomDeg + 1, secret.Prime); randomMatrix_f_xy.SetMatrixCell(0, 0, secret); var polynomialShares = new List <SecretPolynomials>(); for (int i = 0; i < numPlayers; i++) { var pSecret = new SecretPolynomials(); pSecret.Fi_xPolynomial = GenerateF_i_xPolynomial(randomMatrix_f_xy, secret, i); pSecret.Gi_yPolynomial = GenerateG_i_yPolynomial(randomMatrix_f_xy, secret, i); polynomialShares.Add(pSecret); } return(polynomialShares); }
private IList <Zp> ConstructRxPolynomial(ShareDetails aSharesDetails, ShareDetails bSharesDetails, ShareDetails abSharesDetails, ShareDetails rSharesDetails) { var fax = aSharesDetails.RandomPolynomial; var fbx = bSharesDetails.RandomPolynomial; var hx = abSharesDetails.RandomPolynomial; var rx = rSharesDetails.RandomPolynomial; var RxPolynomial = new Zp[2 * PolynomialDeg + 1]; /* Initialize RxPolynomial coefs with zeros */ for (int i = 0; i < 2 * PolynomialDeg + 1; i++) { RxPolynomial[i] = new Zp(Prime, 0); } /* First calculate fax*fbx - hx */ for (int i = 0; i < fax.Count; i++) { Zp temp = fax[i]; for (int j = 0; j < fax.Count; j++) { RxPolynomial[i + j].Add(temp.ConstMul(fbx[j])); } RxPolynomial[i].Sub(hx[i]); } /* Calculate x*rx+fax*fbx - hx*/ for (int i = 0; i < rx.Count; i++) { RxPolynomial[i + 1].Add(rx[i]); } return(new List <Zp>(RxPolynomial)); }
private void ReceiveVerifications(List <VerifShareMessage> verifShares, List <ShareMsg <Zp> > inputShares) { Zp recvShare_i = null; IList <Coordinate> wrongCoordinatesList = null; // all verif. shares must have the same state key var secretPoly = inputShares[verifShares[0].PlayerToVerify].Share as SecretPolynomials; // TODO: inefficient casting! if (verifShares[0].ReceivedGoodPoly) // had received a valid polynomial? { recvShare_i = new Zp(secretPoly.Fi_xPolynomial[0]); var verifyWithList_g_j_w_i = secretPoly.calculateG_i_yValuesForVerification(NumParties, Prime); wrongCoordinatesList = CompareCoordianteList(verifShares, verifyWithList_g_j_w_i); } else { // received a corrupted polynomials from player with ID 'playerToVerify' recvShare_i = new Zp(Prime, 0); } if (verifShares[0].PlayerToVerify == Party.Id) // am I the dealer? { Debug.Assert(MyInputShares != null); HandleDealer(MyInputShares, recvShare_i); } else { HandleNotDealer(verifShares[0].ReceivedGoodPoly, wrongCoordinatesList, verifShares[0].PlayerToVerify, recvShare_i, secretPoly); } sharesForComp.Add(recvShare_i); }
internal Zp InternalCalculate(IList <Zp> inputs) { var values = new List <Zp>(); foreach (Wire wire in InputWires) { if (wire.IsInput) { if (inputs.Count <= wire.InputIndex) { throw new Exception("Input " + wire.InputIndex + " is expected - not found in the list given"); } values.Add(inputs[wire.InputIndex]); } else { Debug.Assert(wire.SourceGate != null && wire.SourceGate.IsOutputReady); values.Add(wire.ConstValue != null ? wire.ConstValue : wire.SourceGate.OutputValue); } } OutputValue = new Zp(values[0]); values.RemoveAt(0); foreach (Zp value in values) { OutputValue.Calculate(value, Operation == Operation.Div && value.Value == 0 ? Operation.Mul : Operation); } return(OutputValue); }
private static Polynomial interpolatePolynomial(IList<Zp> XVlaues, IList<Zp> YVlaues, int e, int polynomDeg, int prime) { int n = XVlaues.Count; if ((e < 0) || (n < 2 * e)) // cannot fix e errors if e <0 or n < 2e. return null; var A = getWelchBerlekampMatrix(XVlaues, YVlaues, n, e, prime); // the matrix to hold the linear system we'll solve var b = getWelchBerlekampConstraintVector(XVlaues, YVlaues, n, e, prime); // coefficients of N and E as one vector var NE = linearSolve(A, new ZpMatrix(b, VectorType.Column), prime); if (NE != null) { var N = new Zp[n - e]; var E = new Zp[e + 1]; for (int i = 0; i < n - e; i++) N[i] = new Zp(NE[i]); for (int i = n - e; i < n; i++) E[i - (n - e)] = new Zp(NE[i]); // Constraint coeef - E has degree exactly e and is monic (shoudn't be zero) E[e] = new Zp(prime, 1); return (new Polynomial(new List<Zp>(N))).divideWithRemainder(new Polynomial(new List<Zp>(E))); } return null; }
private static Polynomial interpolatePolynomial(IList <Zp> XVlaues, IList <Zp> YVlaues, int e, int polynomDeg, int prime) { int n = XVlaues.Count; if ((e < 0) || (n < 2 * e)) // cannot fix e errors if e <0 or n < 2e. { return(null); } var A = getWelchBerlekampMatrix(XVlaues, YVlaues, n, e, prime); // the matrix to hold the linear system we'll solve var b = getWelchBerlekampConstraintVector(XVlaues, YVlaues, n, e, prime); // coefficients of N and E as one vector var NE = linearSolve(A, new ZpMatrix(b, VectorType.Column), prime); if (NE != null) { var N = new Zp[n - e]; var E = new Zp[e + 1]; for (int i = 0; i < n - e; i++) { N[i] = new Zp(NE[i]); } for (int i = n - e; i < n; i++) { E[i - (n - e)] = new Zp(NE[i]); } // Constraint coeef - E has degree exactly e and is monic (shoudn't be zero) E[e] = new Zp(prime, 1); return((new Polynomial(new List <Zp>(N))).divideWithRemainder(new Polynomial(new List <Zp>(E)))); } return(null); }
//public override void Receive(Message msg) //{ // Gate anchor, myGate; // var ssmpcMsg = msg as ScalableMpcMessage; // Debug.Assert(ssmpcMsg != null); // switch (ssmpcMsg.StateKey.Stage) // { // case Stage.Input: // var inputMsg = ssmpcMsg as InputMessage; // // start a heavy-weight smpc with parent and sibling gates // myGate = Circuit.FindGate(ssmpcMsg.StateKey.GateId); // RunChildMpc(myGate.OutNodes[0], myGate, inputMsg.Data); // break; // case Stage.Mpc: // MpcProtocol smpc; // var mpcMsg = ssmpcMsg as MpcMessage; // if (MpcSessions.ContainsKey(smpcMsg.StateKey)) // mpc = MpcSessions[mpcMsg.StateKey].Mpc; // else // { // // I must be in the anchor gate // Debug.Assert(mpcMsg.ToGateId == mpcMsg.AnchorId, "Synchronization exception: Why don't I have an session for this MPC?"); // // my child gate is asking me to participate in an MPC, so create an MPC protocol instance and join // anchor = Circuit.FindGate(mpcMsg.AnchorId); // mpc = RunAnchorMpc(anchor); // } // mpc.Receive(mpcMsg.InnerMessage); // break; // } //} /// <summary> /// Starts a heavy-weight SMPC instance for an SMPC child gate player. /// </summary> protected virtual BgwProtocol RunChildMpc(Gate anchor, Gate myGate, Zp myInput) { Debug.Assert(quorumsMap.ContainsKey(anchor.QuorumIndex)); Debug.Assert(quorumsMap.ContainsKey(myGate.QuorumIndex)); // find associated quorums var childGates = anchor.InNodes; var myGateId = myGate.Id; var virtualIds = new List <int>(quorumsMap[anchor.QuorumIndex].Select(p => (anchor.Id << 16) + p)); // TODO: IMPORTANT: THE ASSUMPTION HERE LIMITS ENTITY/GATE IDs TO 32768. TO INCREASE THIS LIMIT EITHER USE UINT/ULONG IDs OR CHANGE THIS CODE. foreach (var gate in childGates) { foreach (var playerId in quorumsMap[gate.QuorumIndex]) { virtualIds.Add((gate.Id << 16) + playerId); } } var myVirtualId = (myGateId << 16) + Party.Id; // run the protocol and keep it in a the session state var key = new MpcKey(myGateId, anchor.Id); // Mahdi (3/25/14: Do we really need virtual ids?) throw new NotImplementedException(); //var mpc = new BgwProtocol(anchor.MpcCircuit, virtualIds.AsReadOnly(), myVirtualId, myInput, OnMpcSend, key); //mpc.MpcFinish += new FinishHandler(OnMpcFinish); //MpcSessions.Collect(key, new MpcSession(mpc)); //mpc.Run(); //return mpc; }
/// <summary> /// The i-th user gets a Qj(i) List from users, each user j calculated Qj(i) - the j element in the List /// </summary> public static Zp CalculateRandomShare(Zp myShare, IList <Zp> polyUpdate) { var newShare = new Zp(myShare); newShare.AddListContent(polyUpdate); return(newShare); }
/// <summary> /// Creates a random poynomial Qj(x) ,for the j player,and creates a list of elements, /// such that the i-th element is Qj(i) /// </summary> public static IList<Zp> GetRandomizedSharesByzantineCase(int numPlayers, int polynomDeg, int prime) { //polynomial q(x) free element must be zero so it won't effect the final result var polyfreeElem = new Zp(prime, 0); return PrimitiveShare(polyfreeElem, numPlayers, polynomDeg); }
private bool IsMultStepShareLegal(MultStepBCaseShare recvShareFromPlayer_i, MultStepVerificationPoly recvVerifcationPolynomial) { if (!IsRecvShareLegal(recvShareFromPlayer_i)) { return(false); } var RxPolynomial = recvVerifcationPolynomial.RxPolynomial; Zp Ratpoint0 = Zp.EvalutePolynomialAtPoint(RxPolynomial, new Zp(Prime, 0)); if (!Ratpoint0.Equals(new Zp(Prime, 0))) { return(false); } int w = NumTheoryUtils.GetFieldMinimumPrimitive(Prime); var w_InMyIndex = new Zp(Prime, NumTheoryUtils.ModPow(w, Party.Id, Prime)); Zp RjFromPublicPolynomial = Zp.EvalutePolynomialAtPoint(RxPolynomial, w_InMyIndex); Zp temp = recvShareFromPlayer_i.AShare.ConstMul(recvShareFromPlayer_i.BShare).ConstSub(recvShareFromPlayer_i.AbShare); Zp RjFromRecvPrivateInfo = w_InMyIndex.ConstMul(recvShareFromPlayer_i.RShare).ConstAdd(temp); if (!RjFromPublicPolynomial.Equals(RjFromRecvPrivateInfo)) { return(false); } return(true); }
public MultStepBCaseShare(Zp aShare, Zp bShare, Zp abShare, Zp rShare) : base(BgwShareType.MULT_STEP_BCASE) { AShare = aShare; BShare = bShare; AbShare = abShare; RShare = rShare; }
/// <summary> /// Creates a random poynomial Qj(x) ,for the j player,and creates a list of elements, /// such that the i-th element is Qj(i) /// </summary> public static IList <Zp> GetRandomizedSharesByzantineCase(int numPlayers, int polynomDeg, int prime) { //polynomial q(x) free element must be zero so it won't effect the final result var polyfreeElem = new Zp(prime, 0); return(PrimitiveShare(polyfreeElem, numPlayers, polynomDeg)); }
public Gate(GateType type, Zp quorumIndex, Common.FiniteField.Circuits.Circuit mpcCircuit) { Debug.Assert(type == GateType.Input || mpcCircuit != null, "Only input gates do not have MPC circuit."); Id = idGen++; Type = type; QuorumIndex = quorumIndex.Value; MpcCircuit = mpcCircuit; }
private static Zp[] getWelchBerlekampConstraintVector(IList<Zp> XVlaues, IList<Zp> YVlaues, int n, int e, int prime) { var bVector = new Zp[n]; for (int i = 0; i < n; i++) bVector[i] = new Zp(prime, NumTheoryUtils.ModPow(XVlaues[i].Value, e, prime) * YVlaues[i].Value); return bVector; }
public DkmsProtocol(Circuit circuit, AsyncParty p, IList<int> playerIds, Zp playerInput, int numSlots, StateKey stateKey) : base(p, playerIds, stateKey) { Circuit = circuit; Input = playerInput; Prime = playerInput.Prime; NumSlots = numSlots; }
public DkmsProtocol(Circuit circuit, AsyncParty p, IList <int> playerIds, Zp playerInput, int numSlots, StateKey stateKey) : base(p, playerIds, stateKey) { Circuit = circuit; Input = playerInput; Prime = playerInput.Prime; NumSlots = numSlots; }
/// <summary> /// Starts a heavy-weight SMPC instance for an anchor gate player. /// </summary> protected virtual BgwProtocol RunAnchorMpc(Gate anchor) { // NOTE: since in the HBC case all players have the same output, just one of them (the guy with min id) SMPCs his output to improve performance. Debug.Assert(quorumsMap.ContainsKey(anchor.QuorumIndex)); // find associated quorums var anchorChildren = anchor.InNodes; var myQuorum = quorumsMap[anchor.QuorumIndex]; var virtualIds = new List <int>(myQuorum.Select(p => (anchor.Id << 16) + p)); // TODO: IMPORTANT: THE ASSUMPTION HERE LIMITS ENTITY/GATE IDs TO 32768. TO INCREASE THIS LIMIT EITHER USE UINT/ULONG IDs OR CHANGE THIS CODE. foreach (var childGate in anchorChildren) { foreach (var playerId in quorumsMap[childGate.QuorumIndex]) { virtualIds.Add((childGate.Id << 16) + playerId); } } var myVirtualId = (anchor.Id << 16) + Party.Id; // if my id is the minimum in my quorum, then I should just SMPC with a zero, otherwise just SMPC with a random number (r_g). // save this random number in the session because it will be my input in next level's SMPC. BgwProtocol mpc; if (Party.Id == myQuorum.Min()) { // run the protocol and keep it in a the session state var key = new MpcKey(anchor.Id, anchor.Id); // Mahdi (3/25/14: Do we really need virtual ids?) throw new NotImplementedException(); //mpc = new BgwProtocol(anchor.MpcCircuit, virtualIds.AsReadOnly(), myVirtualId, new Zp(Prime), OnMpcSend, key); //mpc.MpcFinish += new FinishHandler(OnMpcFinish); //MpcSessions.Collect(key, new MpcSession(mpc)); //mpc.Run(); } else { // pick a number uniformly at random (r_g) // this random along with other players' randoms forms a global random in the quorum. var randomShare = new Zp(Prime, StaticRandom.Next(0, Prime)); // run an SMPC protocol and keep it in a session state var key = new MpcKey(anchor.Id, anchor.Id); // Mahdi (3/25/14: Do we really need virtual ids?) throw new NotImplementedException(); //mpc = new BgwProtocol(anchor.MpcCircuit, virtualIds.AsReadOnly(), myVirtualId, randomShare, OnMpcSend, key); //mpc.MpcFinish += new FinishHandler(OnMpcFinish); //MpcSessions.Collect(key, new MpcSession(mpc)); //mpc.Run(); } return(mpc); }
private static Zp[] getWelchBerlekampConstraintVector(IList <Zp> XVlaues, IList <Zp> YVlaues, int n, int e, int prime) { var bVector = new Zp[n]; for (int i = 0; i < n; i++) { bVector[i] = new Zp(prime, NumTheoryUtils.ModPow(XVlaues[i].Value, e, prime) * YVlaues[i].Value); } return(bVector); }
public ByzantineBgwProtocol(AsyncParty e, Circuit circuit, ReadOnlyCollection<int> playerIds, Zp playerInput, StateKey stateKey) : base(e, circuit, playerIds, playerInput, stateKey) { throw new NotImplementedException(); // PolynomialDeg = NumParties % 4 == 0 ? (NumParties / 4 - 1) : (NumParties / 4); // Mahdi: Changed to the following since n/3 - 1 of players can be dishonest. // degree = n - t, where t is the number of dishonest players PolynomialDeg = (int)Math.Floor(2 * NumParties / 3.0); }
public ByzantineBgwProtocol(AsyncParty e, Circuit circuit, ReadOnlyCollection <int> playerIds, Zp playerInput, StateKey stateKey) : base(e, circuit, playerIds, playerInput, stateKey) { throw new NotImplementedException(); // PolynomialDeg = NumParties % 4 == 0 ? (NumParties / 4 - 1) : (NumParties / 4); // Mahdi: Changed to the following since n/3 - 1 of players can be dishonest. // degree = n - t, where t is the number of dishonest players PolynomialDeg = (int)Math.Floor(2 * NumParties / 3.0); }
private static IList<Zp> GenerateF_i_xPolynomial(ZpMatrix f_x_y, Zp secret, int playerNum) { int w = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime); int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime); var y_values = new int[f_x_y.ColCount]; for (int i = 0; i < f_x_y.ColCount; i++) { y_values[i] = NumTheoryUtils.ModPow(w_i, i, secret.Prime); } return f_x_y.MulMatrixByScalarsVector(y_values).SumMatrixRows(); }
protected void ShareSecret(Zp secret, IList <int> players, DkmsKey key) { var shares = ShamirSharing.Share(secret, players.Count, players.Count - 1); var shareMsgs = new List <ShareMsg <Zp> >(); foreach (var share in shares) { shareMsgs.Add(new ShareMsg <Zp>(new Share <Zp>(share), key)); } Send(players, shareMsgs); }
private static IList <Zp> GenerateF_i_xPolynomial(ZpMatrix f_x_y, Zp secret, int playerNum) { int w = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime); int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime); var y_values = new int[f_x_y.ColCount]; for (int i = 0; i < f_x_y.ColCount; i++) { y_values[i] = NumTheoryUtils.ModPow(w_i, i, secret.Prime); } return(f_x_y.MulMatrixByScalarsVector(y_values).SumMatrixRows()); }
private static IList<Zp> GenerateG_i_yPolynomial(ZpMatrix f_x_y, Zp secret, int playerNum) { int w = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime); int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime); var x_values = new Zp[f_x_y.RowCount]; for (int i = 0; i < f_x_y.RowCount; i++) { x_values[i] = new Zp(secret.Prime, NumTheoryUtils.ModPow(w_i, i, secret.Prime)); } var tempArr = f_x_y.Times(new ZpMatrix(x_values, VectorType.Column)).ZpVector; return tempArr; }
private void UpdateRecvShare(IList <SecretPolynomials> recvPublicPolysList, Zp recvSecretShare_i) { if ((recvPublicPolysList != null)) { var newRecvSercretPoly = recvPublicPolysList[Party.Id]; if (newRecvSercretPoly != null) { var recvShare = newRecvSercretPoly.Fi_xPolynomial[0]; if (recvShare != null) { recvSecretShare_i.Value = recvShare.Value; } } } }
private static Zp[] TruncateVector(Zp[] vector, int toSize) { if (vector.Length < toSize) { return(null); } var truncVec = new Zp[toSize]; for (int i = 0; i < toSize; i++) { truncVec[i] = new Zp(vector[i]); } return(truncVec); }
/// <summary> /// Each party in the new quorum needs to call this with the shares received from the old quorum to calculate its share /// </summary> public static Zp CombineReshares(IList<Zp> reshares, int newQuorumSize, int prime) { int oldQuorumSize = reshares.Count; if (oldQuorumSize != newQuorumSize) throw new System.ArgumentException("Do not support case where quorums are of different sizes"); // Compute the first row of the inverse Vandermonde matrix var vandermonde = ZpMatrix.GetVandermondeMatrix(oldQuorumSize, newQuorumSize, prime); var vandermondeInv = vandermonde.Inverse.GetMatrixColumn(0); var S = new Zp(prime); for (var i = 0; i < newQuorumSize; i++) S += vandermondeInv[i] * reshares[i]; return S; }
private static IList <Zp> GenerateG_i_yPolynomial(ZpMatrix f_x_y, Zp secret, int playerNum) { int w = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime); int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime); var x_values = new Zp[f_x_y.RowCount]; for (int i = 0; i < f_x_y.RowCount; i++) { x_values[i] = new Zp(secret.Prime, NumTheoryUtils.ModPow(w_i, i, secret.Prime)); } var tempArr = f_x_y.Times(new ZpMatrix(x_values, VectorType.Column)).ZpVector; return(tempArr); }
public void Init(int numPlayers, int numQuorums, int numSlots, int quorumSize, QuorumBuildingMethod qbMethod, AdversaryModel model, Zp[] inputs, int prime) { switch (model) { case AdversaryModel.HonestButCurious: Circuit = CreateHbcCircuit(numPlayers, numQuorums, numSlots, quorumSize, prime); break; case AdversaryModel.Byzantine: Circuit = CreateByzantineCircuit(numPlayers, numQuorums, numSlots, quorumSize, prime); break; default: throw new Exception("Unknown adversary model."); } base.Init(numPlayers, numQuorums, numSlots, quorumSize, qbMethod, Circuit, inputs, prime); }
public override void Run() { Debug.Assert(quorumsMap != null); Debug.Assert(Circuit.InputGates.Count == NumParties * NumSlots); // TODO: input must be encrypted with a random number and the random must be secret shared. // share my input in a random input gate (random slot) and share zero in others var randomSlot = StaticRandom.Next(0, NumSlots); for (int s = 0; s < NumSlots; s++) { // TODO: IMPORTANT: EntityId's are assumed to be continous integers with option base 0. Not other parts of the code have this assumption. var gate = Circuit.InputGates[Party.Id * NumSlots + s]; var quorum = quorumsMap[gate.QuorumIndex]; // in the byzantine case, we have to secret share the input among 'quorum' members but // here in the HBC case, we send the masked input to only one member of 'quorum' and randoms to other players. // These randoms form a global random, which is added to the input to mask it. Zp toSend; if (s == randomSlot) { toSend = Input; } else { toSend = new Zp(Prime); // send a zero } int mask = 0; var minPlayer = quorum.Min(); var stateKey = new DkmsKey(Stage.Input, gate.Id); foreach (var player in quorum) { if (player != minPlayer) { var rand = StaticRandom.Next(0, Prime); mask += rand; Send(Party.Id, player, new InputMsg(new Zp(Prime, rand), stateKey)); } } Send(Party.Id, minPlayer, new InputMsg(Input + mask, stateKey)); } }
//public override void loadFromByteArrayNoHeader(BitStream bs, int prime) //{ // if (bs.readBoolean()) // fi_x = bs.readList(prime); // if (bs.readBoolean()) // gi_y = bs.readList(prime); //} //public override void writeToBitStreamNoHeader(BitStream bs) //{ // bs.writeBoolean(fi_x != null); // if (fi_x != null) // bs.writeList(fi_x); // bs.writeBoolean(gi_y != null); // if (gi_y != null) // bs.writeList(gi_y); //} //public override byte[] writeToByteArray() //{ // var bs = new BitStream(); // bs.writeMessageType(MessageType.ZP_LISTS); // writeToBitStreamNoHeader(bs); // bs.close(); // return bs.ByteArray; //} public virtual IList <Zp> CalculateF_i_xValuesForPlayers(int numOfPlayers, int prime) { int w_i, w = Zp.GetFieldMinimumPrimitive(prime); int value; var f_i_xValues = new List <Zp>(); for (int playerNum = 0; playerNum < numOfPlayers; playerNum++) { w_i = Zp.CalculatePower(w, playerNum, prime); value = 0; for (int j = 0; j < fi_x.Count; j++) { value += Zp.CalculatePower(w_i, j, prime) * fi_x[j].Value; } f_i_xValues.Add(new Zp(prime, value)); } return(f_i_xValues); }
/// <summary> /// Evaluates the shares of secret with polynomial of degree 'polynomDeg' and 'numPlayers' players. /// </summary> private static IList <Zp> Share(Zp secret, int numPlayers, int polynomDeg, bool usePrimitiveShare, out IList <Zp> coeffs) { #if NO_COMPUTATION // send some dummy shares var shares = new Zp[numPlayers]; for (int i = 0; i < numPlayers; i++) { shares[i] = new Zp(secret.Prime); } return(shares); #else Debug.Assert(numPlayers > polynomDeg, "Polynomial degree cannot be greater than or equal to the number of players!"); // Create a random polynomial - f(x) // Note: Polynomial of degree d has d+1 coefficients var randomMatrix = ZpMatrix.GetRandomMatrix(1, polynomDeg + 1, secret.Prime); // The free variable in the Random Polynomial (i.e. f(x)) is the secret randomMatrix.SetMatrixCell(0, 0, secret); // Polynomial coefficients coeffs = randomMatrix.GetMatrixRow(0); // Create vanderMonde matrix ZpMatrix vanderMonde; if (usePrimitiveShare) { vanderMonde = ZpMatrix.GetPrimitiveVandermondeMatrix(polynomDeg + 1, numPlayers, secret.Prime); } else { vanderMonde = ZpMatrix.GetVandermondeMatrix(polynomDeg + 1, numPlayers, secret.Prime); } // Compute f(i) for the i-th player var sharesArr = randomMatrix.Times(vanderMonde).ZpVector; Debug.Assert(sharesArr != null); Debug.Assert(sharesArr.Length == numPlayers); return(sharesArr); #endif }
/// <summary> /// Evaluates the shared secrets of secret with polynom of degree t and numberOfPlayers players. /// </summary> public static ShareDetails DetailedShare(Zp secret, int numPlayers, int polynomDeg) { if (numPlayers <= polynomDeg) throw new ArgumentException("Polynomial degree cannot be bigger or equal to the number of players"); // Creating the Random Polynomial - f(x) var randomMatrix = ZpMatrix.GetRandomMatrix(1, polynomDeg + 1, secret.Prime); // The free variable in the Random Polynomial( f(x) ) is the seceret randomMatrix.SetMatrixCell(0, 0, secret); // Create vanderMonde matrix var vanderMonde = ZpMatrix.GetPrimitiveVandermondeMatrix(polynomDeg + 1, numPlayers, secret.Prime); // Compute f(i) for the i-th player var sharesArr = randomMatrix.Times(vanderMonde).ZpVector; var details = new ShareDetails(randomMatrix.GetMatrixRow(0), sharesArr); return details; }
static void Main(string[] args) { Console.WriteLine("Started."); StaticRandom.Init(seed); int quorumSize = 20; int degree = quorumSize / 3; var secret = new Zp(Prime, 3); var shareMatrix = ZpMatrix.GetIdentityMatrix(quorumSize, Prime); // create the initial shares var initalShares = ShamirSharing.Share(secret, quorumSize, degree); for (var i = 0; i < quorumSize; i++) { IList <Zp> reshares = QuorumSharing.CreateReshares(initalShares[i], quorumSize, degree); for (var j = 0; j < quorumSize; j++) { shareMatrix.SetMatrixCell(j, i, reshares[j]); } } // combine the reshares List <Zp> finalShares = new List <Zp>(); for (var i = 0; i < quorumSize; i++) { Zp finalShare = QuorumSharing.CombineReshares(shareMatrix.GetMatrixRow(i), quorumSize, Prime); finalShares.Add(finalShare); } // combine the shares Zp final = ShamirSharing.Recombine(finalShares, degree, Prime); Console.WriteLine(final.Value); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); }
/// <summary> /// Each party in the new quorum needs to call this with the shares received from the old quorum to calculate its share /// </summary> public static Zp CombineReshares(IList <Zp> reshares, int newQuorumSize, int prime) { int oldQuorumSize = reshares.Count; if (oldQuorumSize != newQuorumSize) { throw new System.ArgumentException("Do not support case where quorums are of different sizes"); } // Compute the first row of the inverse Vandermonde matrix var vandermonde = ZpMatrix.GetVandermondeMatrix(oldQuorumSize, newQuorumSize, prime); var vandermondeInv = vandermonde.Inverse.GetMatrixColumn(0); var S = new Zp(prime); for (var i = 0; i < newQuorumSize; i++) { S += vandermondeInv[i] * reshares[i]; } return(S); }
/// <summary> /// Creates a random polynomial f(x,y) and then to create from it for /// the i-th player two polynomials : fi(x) = f(x,w^i) and gi(y) = f(w^i,y). /// </summary> public static IList<SecretPolynomials> ShareByzantineCase(Zp secret, int numPlayers, int polynomDeg) { if (numPlayers <= 4 * polynomDeg) throw new System.ArgumentException("Cannot use Byzantine algoritm -- numberOfPlayers <= 4*polynomDeg - " + "use regular computation instead"); // Creating the Random Polynomial - f(x , y) // Note : there are (t+1)^2 coefficiet for the polynomial including the free coefficient (the secret) // first row coef are of (x^0,x^1,x^2,...,x^t)y^0, second row coef are (x^0, x1,...,x^t)y^1 and so forth... var randomMatrix_f_xy = ZpMatrix.GetRandomMatrix(polynomDeg + 1, polynomDeg + 1, secret.Prime); randomMatrix_f_xy.SetMatrixCell(0, 0, secret); var polynomialShares = new List<SecretPolynomials>(); for (int i = 0; i < numPlayers; i++) { var pSecret = new SecretPolynomials(); pSecret.Fi_xPolynomial = GenerateF_i_xPolynomial(randomMatrix_f_xy, secret, i); pSecret.Gi_yPolynomial = GenerateG_i_yPolynomial(randomMatrix_f_xy, secret, i); polynomialShares.Add(pSecret); } return polynomialShares; }
// Mahdi's recombine method based on Lagrange interpolation for finite fields. public static Zp SimpleRecombine(IList <Zp> sharedSecrets, int polyDeg, int prime) { if (sharedSecrets.Count < polyDeg) { throw new System.ArgumentException("Polynomial degree cannot be bigger or equal to the number of shares"); } // find Lagrange basis polynomials free coefficients var L = new Zp[polyDeg + 1]; for (int i = 0; i < polyDeg + 1; i++) { L[i] = new Zp(prime, 1); } int ix = 0; for (var i = new Zp(prime, 1); i < polyDeg + 2; i++, ix++) { for (var j = new Zp(prime, 1); j < polyDeg + 2; j++) { if (j != i) { var additiveInverse = j.AdditiveInverse; L[ix] = L[ix] * (additiveInverse / (i + additiveInverse)); // note: division done in finite-field } } } // find the secret by multiplying each share to the corresponding Lagrange's free coefficient var secret = new Zp(prime, 0); for (int i = 0; i < polyDeg + 1; i++) { secret = secret + (L[i] * sharedSecrets[i]); } return(secret); }
static void Main(string[] args) { Console.WriteLine("Started."); StaticRandom.Init(seed); int quorumSize = 20; int degree = quorumSize / 3; var secret = new Zp(Prime, 3); var shareMatrix = ZpMatrix.GetIdentityMatrix(quorumSize, Prime); // create the initial shares var initalShares = ShamirSharing.Share(secret, quorumSize, degree); for (var i = 0; i < quorumSize; i++) { IList<Zp> reshares = QuorumSharing.CreateReshares(initalShares[i], quorumSize, degree); for (var j = 0; j < quorumSize; j++) { shareMatrix.SetMatrixCell(j, i, reshares[j]); } } // combine the reshares List<Zp> finalShares = new List<Zp>(); for (var i = 0; i < quorumSize; i++) { Zp finalShare = QuorumSharing.CombineReshares(shareMatrix.GetMatrixRow(i), quorumSize, Prime); finalShares.Add(finalShare); } // combine the shares Zp final = ShamirSharing.Recombine(finalShares, degree, Prime); Console.WriteLine(final.Value); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); }
/// <summary> /// Evaluates the shared secrets of secret with polynom of degree t and numberOfPlayers players. /// </summary> public static ShareDetails DetailedShare(Zp secret, int numPlayers, int polynomDeg) { if (numPlayers <= polynomDeg) { throw new ArgumentException("Polynomial degree cannot be bigger or equal to the number of players"); } // Creating the Random Polynomial - f(x) var randomMatrix = ZpMatrix.GetRandomMatrix(1, polynomDeg + 1, secret.Prime); // The free variable in the Random Polynomial( f(x) ) is the seceret randomMatrix.SetMatrixCell(0, 0, secret); // Create vanderMonde matrix var vanderMonde = ZpMatrix.GetPrimitiveVandermondeMatrix(polynomDeg + 1, numPlayers, secret.Prime); // Compute f(i) for the i-th player var sharesArr = randomMatrix.Times(vanderMonde).ZpVector; var details = new ShareDetails(randomMatrix.GetMatrixRow(0), sharesArr); return(details); }
private void ShareSimple(Zp sharedSecrets, Stage targetStage) { Send(new ShareMsg<Zp>(new Share<Zp>(sharedSecrets), targetStage), BadPlayers); }
private void ReceiveVerifications(List<VerifShareMessage> verifShares, List<ShareMsg<Zp>> inputShares) { Zp recvShare_i = null; IList<Coordinate> wrongCoordinatesList = null; // all verif. shares must have the same state key var secretPoly = inputShares[verifShares[0].PlayerToVerify].Share as SecretPolynomials; // TODO: inefficient casting! if (verifShares[0].ReceivedGoodPoly) // had received a valid polynomial? { recvShare_i = new Zp(secretPoly.Fi_xPolynomial[0]); var verifyWithList_g_j_w_i = secretPoly.calculateG_i_yValuesForVerification(NumParties, Prime); wrongCoordinatesList = CompareCoordianteList(verifShares, verifyWithList_g_j_w_i); } else { // received a corrupted polynomials from player with ID 'playerToVerify' recvShare_i = new Zp(Prime, 0); } if (verifShares[0].PlayerToVerify == Party.Id) // am I the dealer? { Debug.Assert(MyInputShares != null); HandleDealer(MyInputShares, recvShare_i); } else { HandleNotDealer(verifShares[0].ReceivedGoodPoly, wrongCoordinatesList, verifShares[0].PlayerToVerify, recvShare_i, secretPoly); } sharesForComp.Add(recvShare_i); }
private bool IsPublicDataContradictPrivate(SecretPolynomials myRecvPolys, IList<SecretPolynomials> recvPublicPolysList, IList<PlayerNotification> recvComplaintesList, Zp myRecvShare) { if ((recvPublicPolysList == null) || (recvPublicPolysList.Count != NumParties)) return true; var myG_j_w_iValues = myRecvPolys.calculateG_i_yValuesForVerification(NumParties, Prime); var myF_j_w_iValues = myRecvPolys.CalculateF_i_xValuesForPlayers(NumParties, Prime); for (int k = 0; k < NumParties; k++) { if ((recvComplaintesList[k] != null) && (recvComplaintesList[k].Confirmation == Confirmation.Complaint)) { var playerKNewPolys = recvPublicPolysList[k]; // Check if the dealer didn't publish all the required data or published a corrupted data if (!IsSecretPolynomialsLegal(playerKNewPolys)) return true; // Verify that the public information doesn't contradict itself - check that : f(w^k, w^k) = fk(w^k) = gk(w^k) = f(w^k, w^k) var playerKNewFk_x_w_iValues = playerKNewPolys.CalculateF_i_xValuesForPlayers(NumParties, Prime); var playerKNewGk_y_w_iValues = playerKNewPolys.calculateG_i_yValuesForVerification(NumParties, Prime); if (!playerKNewFk_x_w_iValues[k].Equals(playerKNewGk_y_w_iValues[k])) return true; if (k == Party.Id) { // Verify that the new public polynomials equals the old polynomials if (!IsSecretPolynomialsLegal(myRecvPolys) || !myRecvPolys.Equals(playerKNewPolys)) return true; } else { // Verify that the public information doesn't contradict the old information : // f(w^j, w^k) = fk(w^j) = gj(w^k) = f(w^j, w^k) && f(w^k, w^j) = fj(w^k) = gk(w^j) = f(w^k, w^j) if ((!myG_j_w_iValues[k].Equals(playerKNewFk_x_w_iValues[Party.Id])) || (!myF_j_w_iValues[k].Equals(playerKNewGk_y_w_iValues[Party.Id]))) return true; } } } return false; }
/// <summary> /// Implementation according to GRR. /// </summary> public virtual Zp ReductionRandomizationStep(Zp a, Zp b, Zp ab) { throw new NotImplementedException(); //// performing reduction & randomization step ///* Create a detailed share of a,b and ab */ //var aSharesDetails = Shamir.DetailedShare(a, NumPlayers, PolynomialDeg); //var bSharesDetails = Shamir.DetailedShare(b, NumPlayers, PolynomialDeg); //var abSharesDetails = Shamir.DetailedShare(ab, NumPlayers, PolynomialDeg); ///* Share a random polynomial r(x) of degree 2t-1 */ //var rSharesDetails = Shamir.DetailedShare( // new Zp(Prime, (int)(new Random(1).NextDouble() * Prime)), NumPlayers, 2 * PolynomialDeg - 1); //var RxPolynomial = new MultStepVerificationPoly(ConstructRxPolynomial(aSharesDetails, bSharesDetails, abSharesDetails, rSharesDetails)); ///* Build verified shares for users */ //var aShares = aSharesDetails.CreatedShares; //var bShares = bSharesDetails.CreatedShares; //var abShares = abSharesDetails.CreatedShares; //var rShares = rSharesDetails.CreatedShares; //var toSendmultStepShares = new List<MultStepBCaseShare>(); //for (int i = 0; i < NumPlayers; i++) //{ // var playerShares = new MultStepBCaseShare(); // playerShares.AShare = aShares[i]; // playerShares.BShare = bShares[i]; // playerShares.AbShare = abShares[i]; // playerShares.RShare = rShares[i]; // toSendmultStepShares.Add(playerShares); //} ///* Send and receive shares from all players */ //var toRecvmultStepShares = Sendable.asMultStepBCaseShares(Adapter.shareSecrets(toSendmultStepShares, Prime, BadPlayers)); ///* Start verifying player shares and construct a list of the received shares of ab - this list will be used to compute the regular multStep*/ //int playerToVerify = 0; //var abVerifiedList = new List<Zp>(); //foreach (var recvShareFromPlayer_i in toRecvmultStepShares) //{ // if (playerToVerify == EntityId) // { // // I'm the dealer // // Put Rx polynomial on the bulletin board // BulletinBoardProtocol.publish(RxPolynomial, BadPlayers, Adapter); // // Should advertise a demo complaint on the bulletin board - I'm not complaining about myself // var myDemoComplaint = new PlayerNotification(PlayerNotification.Confirmation.APPROVAL); // var complaintesOnMe = Sendable.asPlayerNotifications(BulletinBoardProtocol.publishAndRead(myDemoComplaint, Prime, BadPlayers, Adapter)); // // Build a message containing all the requested data // var requstedData = new List<MultStepBCaseShare>(); // for (int i = 0; i < NumPlayers; i++) // { // if ((complaintesOnMe[i] != null) && (complaintesOnMe[i].Msg.Equals(PlayerNotification.Confirmation.COMPLAINT))) // { // requstedData.Add(toSendmultStepShares[i]); // } // else requstedData.Add(null); // } // var requstedDataToPublish = new MultStepBCaseShareBundle(requstedData); // // Put the requested shares on the bulletin board . // // Note : even if you are a cheater you should publish the real shares here otherwise you will be considered as cheater // BulletinBoardProtocol.publish(requstedDataToPublish, BadPlayers, Adapter); // // Add my ab share to abShares any way // abVerifiedList.Add(toSendmultStepShares[EntityId].AbShare); // } // else // { // if (BadPlayers[playerToVerify]) // { // // Mult Step - verifying player number playerToVerify share // bool dealerIsCheater = false; // PlayerNotification myComplaint; // IList<PlayerNotification> recvComplaints; // MultStepBCaseShareBundle recvPublicShares; // // Get Rx polynomial of the 'playerToVerify' from bulletin board // var recvVerificationPolynomial = BulletinBoardProtocol.read(playerToVerify, Prime, Adapter).asMultStepVerificationPoly(); // if (IsMultStepPolynomialLegal(recvVerificationPolynomial)) // { // if (!IsMultStepShareLegal(recvShareFromPlayer_i, recvVerificationPolynomial)) // { // // Should prepare a massege that te dealer is a cheater // myComplaint = new PlayerNotification(PlayerNotification.Confirmation.COMPLAINT); // } // else // { // // Should prepare a massege that te dealer is not a cheater // myComplaint = new PlayerNotification(PlayerNotification.Confirmation.APPROVAL); // } // // Help verify complaining users shares : // // Should advertise what you thinks about the dealer on the bulletin board // recvComplaints = Sendable.asPlayerNotifications(BulletinBoardProtocol.publishAndRead(myComplaint, Prime, BadPlayers, Adapter)); // // Get complaining players share from the bulletin board - it is now a public share // recvPublicShares = BulletinBoardProtocol.read(playerToVerify, Prime, Adapter).asMultStepBCaseShareBundle(); // // Check that the dealer had published all the requested data and that the data is consistent // IList<MultStepBCaseShare> publishedShareList = null; // if (recvPublicShares != null) // publishedShareList = recvPublicShares.List; // MultStepBCaseShare publishedShare; // for (int i = 0; i < NumPlayers; i++) // { // if ((recvComplaints[i] != null) && // (recvComplaints[i].Msg.Equals(PlayerNotification.Confirmation.COMPLAINT))) // { // publishedShare = publishedShareList[i]; // if (!IsMultStepShareLegal(publishedShare, recvVerificationPolynomial)) // { // // No need to send any more complaints or aproval- the shares and the R(x) polynomial is public data // dealerIsCheater = true; // Adapter.removePlayer(playerToVerify); //don't send and receive from this player anymore... // break; // } // } // } // } // else // Multistep polynomial, R(x) isn't legal // dealerIsCheater = true; // if (dealerIsCheater) // { // // Found a cheater in multiplication step. Cheater is player number playerToVerify. // RemoveCheaterPlayer(playerToVerify); // } // else abVerifiedList.Add(recvShareFromPlayer_i.AbShare); // } // } // playerToVerify++; //} //// Finally //var firstLineAtInvVanderMonde = GetMultStepCoeffsForCheaters(0); // Contains only the needed coeffs //// Calculate the value of the polynomial H(x) at i = H(i) as defined at GRR //var tempSecret = new Zp(Prime, 0); //int goodPlayerNum = NumGoodPlayers; //for (int i = 0; i < goodPlayerNum; i++) //{ // tempSecret.Add(abVerifiedList[i].Mul(firstLineAtInvVanderMonde[i])); //} //return tempSecret; }
public override void Run() { Debug.Assert(quorumsMap != null); Debug.Assert(Circuit.InputGates.Count == NumParties * NumSlots); // TODO: input must be encrypted with a random number and the random must be secret shared. // share my input in a random input gate (random slot) and share zero in others var randomSlot = StaticRandom.Next(0, NumSlots); for (int s = 0; s < NumSlots; s++) { // TODO: IMPORTANT: EntityId's are assumed to be continous integers with option base 0. Not other parts of the code have this assumption. var gate = Circuit.InputGates[Party.Id * NumSlots + s]; var quorum = quorumsMap[gate.QuorumIndex]; // in the byzantine case, we have to secret share the input among 'quorum' members but // here in the HBC case, we send the masked input to only one member of 'quorum' and randoms to other players. // These randoms form a global random, which is added to the input to mask it. Zp toSend; if (s == randomSlot) toSend = Input; else toSend = new Zp(Prime); // send a zero int mask = 0; var minPlayer = quorum.Min(); var stateKey = new DkmsKey(Stage.Input, gate.Id); foreach (var player in quorum) { if (player != minPlayer) { var rand = StaticRandom.Next(0, Prime); mask += rand; Send(Party.Id, player, new InputMsg(new Zp(Prime, rand), stateKey)); } } Send(Party.Id, minPlayer, new InputMsg(Input + mask, stateKey)); } }
public ShareMessage(BroadcastStage stage, Zp share, int k) : base(stage, k) { Share = share; }
protected virtual void HandleDealer(IList<SecretPolynomials> shareMySecrets, Zp recvSecretShare_i) { // Should send & receive complaints on the bulletin board 1 - I'm not complaining on myself var myDemoComplaint = new PlayerNotification(Confirmation.Approval); // broadcast the complaint using BA //var bcaster = new SecureBroadcaster<PlayerNotification>( // EntityId, myDemoComplaint, EntityIds.Except(BadPlayers).ToList().AsReadOnly(), true, Prime, Send); //bcaster.Run(); //var complaintesOnMe = SecureBroadcaster.PublishAndRead(myDemoComplaint, Prime, BadPlayers); //// Prepare wanted polys according to players complaintes //var wantedPolysList = new List<SecretPolynomials>(); //bool recvCompOnMe = CreateWantedPolynomials(wantedPolysList, complaintesOnMe, shareMySecrets); //if (recvCompOnMe) //{ // // Publish wanted polynomials on the bulletin board // var secretBundle = new SecretPolynomialsBundle(wantedPolysList); // SecureBroadcaster.Publish(secretBundle, BadPlayers); // // Should send&receive complaints on the bulletin board 2 - I'm not complaining on myself // complaintesOnMe = Sendable.asPlayerNotifications( // BulletinBoardProtocol.PublishAndRead(myDemoComplaint, Prime, BadPlayers)); // // Prepare wanted polys according to players complaintes // recvCompOnMe = CreateWantedPolynomials(wantedPolysList, complaintesOnMe, shareMySecrets); // if (recvCompOnMe) // { // // Publish wanted polynomials on the bulletin board // secretBundle = new SecretPolynomialsBundle(wantedPolysList); // BulletinBoardProtocol.Publish(secretBundle, BadPlayers); // // Should send&receive complaints on the bulletin board 3 - I'm not complaining on myself // complaintesOnMe = Sendable.asPlayerNotifications( // BulletinBoardProtocol.PublishAndRead(myDemoComplaint, Prime, BadPlayers)); // // Count complaints number // int numOfcomplaints = GetNumberOfComplaints(complaintesOnMe); // if (numOfcomplaints > PolynomialDeg) // { // // Take the zero polynomial as my input (Not mandatodry) and throw exception // recvSecretShare_i.Value = 0; // throw new Exception("Other players decided that I'm a cheater :- ( - taking my input as zero."); // } // } //} }
protected override Zp GetRecombinedResult(IList<Zp> recvList, int prime) { // Scan recvList - if there are null elements replace them arbitrarily to Zp with zero value for (int i = 0; i < recvList.Count; i++) { if (recvList[i] == null) recvList[i] = new Zp(prime, 0); } var xVlaues = new List<Zp>(); int w = NumTheoryUtils.GetFieldMinimumPrimitive(prime); for (int i = 0; i < recvList.Count; i++) xVlaues.Add(new Zp(prime, NumTheoryUtils.ModPow(w, i, prime))); // Should call Welch-Berlekamp Decoder to fix error at last stage var fixedShares = WelchBerlekampDecoder.Decode(xVlaues, recvList, PolynomialDeg, PolynomialDeg, prime); if (fixedShares == null) throw new Exception("There were more then polynomialDegree = " + PolynomialDeg + " Cheaters - cannot extract results."); return ShamirSharing.Recombine(fixedShares, PolynomialDeg, prime, true); }
/// <summary> /// Starts a heavy-weight SMPC instance for an anchor gate player. /// </summary> protected virtual BgwProtocol RunAnchorMpc(Gate anchor) { // NOTE: since in the HBC case all players have the same output, just one of them (the guy with min id) SMPCs his output to improve performance. Debug.Assert(quorumsMap.ContainsKey(anchor.QuorumIndex)); // find associated quorums var anchorChildren = anchor.InNodes; var myQuorum = quorumsMap[anchor.QuorumIndex]; var virtualIds = new List<int>(myQuorum.Select(p => (anchor.Id << 16) + p)); // TODO: IMPORTANT: THE ASSUMPTION HERE LIMITS ENTITY/GATE IDs TO 32768. TO INCREASE THIS LIMIT EITHER USE UINT/ULONG IDs OR CHANGE THIS CODE. foreach (var childGate in anchorChildren) { foreach (var playerId in quorumsMap[childGate.QuorumIndex]) virtualIds.Add((childGate.Id << 16) + playerId); } var myVirtualId = (anchor.Id << 16) + Party.Id; // if my id is the minimum in my quorum, then I should just SMPC with a zero, otherwise just SMPC with a random number (r_g). // save this random number in the session because it will be my input in next level's SMPC. BgwProtocol mpc; if (Party.Id == myQuorum.Min()) { // run the protocol and keep it in a the session state var key = new MpcKey(anchor.Id, anchor.Id); // Mahdi (3/25/14: Do we really need virtual ids?) throw new NotImplementedException(); //mpc = new BgwProtocol(anchor.MpcCircuit, virtualIds.AsReadOnly(), myVirtualId, new Zp(Prime), OnMpcSend, key); //mpc.MpcFinish += new FinishHandler(OnMpcFinish); //MpcSessions.Collect(key, new MpcSession(mpc)); //mpc.Run(); } else { // pick a number uniformly at random (r_g) // this random along with other players' randoms forms a global random in the quorum. var randomShare = new Zp(Prime, StaticRandom.Next(0, Prime)); // run an SMPC protocol and keep it in a session state var key = new MpcKey(anchor.Id, anchor.Id); // Mahdi (3/25/14: Do we really need virtual ids?) throw new NotImplementedException(); //mpc = new BgwProtocol(anchor.MpcCircuit, virtualIds.AsReadOnly(), myVirtualId, randomShare, OnMpcSend, key); //mpc.MpcFinish += new FinishHandler(OnMpcFinish); //MpcSessions.Collect(key, new MpcSession(mpc)); //mpc.Run(); } return mpc; }
/// <summary> /// Implementation according to Ran Canetti /// </summary> public override void RunReductionRandomization(Zp ab) { throw new NotImplementedException(); //// performing Improved reduction & randomization step //bool cheaterFound = true; //IList<Zp> recvSharesFromPlayers = null; //while (cheaterFound) //{ // cheaterFound = false; // /* Share secret by VSS */ // recvSharesFromPlayers = SendInput(ab); // /* Generate a t degree polynomial, hi(x) , with a free coeef that equals 'ab' and create share for users from it */ // //List<Zp> shareResultWithPlayers = Shamir.primitiveShare(ab, numberOfPlayers , polynomialDeg); // /* Send to the j-th user hi(j) and receive from every other k player hk(i) */ // //recvSharesFromPlayers = shareSimple(shareResultWithPlayers); // /* Check if there were some null elements - from not playing players or cheater players and put zero instead - arbitrarily */ // for (int i = recvSharesFromPlayers.Count - 1; i >= 0; i--) // { // if (recvSharesFromPlayers[i] == null) // recvSharesFromPlayers[i] = new Zp(Prime, 0); // if (BadPlayers.Contains(i)) // recvSharesFromPlayers.RemoveAt(i); // } // var calculationPolyCoeffs = new List<Zp>(); // /* Fill the first 2t+1 coeff with zero arbitrarily */ // for (int i = 0; i < 2 * PolynomialDeg + 1; i++) // calculationPolyCoeffs.Add(new Zp(Prime, 0)); // /* Perform the following iteration to calculate the 2t+1...n coeffs of the calculation polynomial*/ // for (int k = 2 * PolynomialDeg + 1; k < recvSharesFromPlayers.Count; k++) // { // var K_LineAtInvVanderMonde = GetMultStepCoeffsForCheaters(k); // /* Calculate your share of the K-th coeff at the calculation polynomial */ // var myK_CoeffShare = new Zp(Prime, 0); // for (int i = 0; i < recvSharesFromPlayers.Count; i++) // { // myK_CoeffShare.Add(recvSharesFromPlayers[i].ConstMul(K_LineAtInvVanderMonde[i])); // } // /* Send this to all other players so all of you could recombine the real k-th coeff - no need to use the bulletin board */ // var K_CoeffShares = ShareSimple(myK_CoeffShare); // /* Fix the received codeword and get the Recombined result */ // calculationPolyCoeffs.Add(GetRecombinedResult(K_CoeffShares, Prime)); // } // var calculationPoly = new Polynomial(calculationPolyCoeffs); // if (calculationPoly.Degree == -1) // { // /* No one cheated at this stage */ // break; // } // var XValues = new List<Zp>(); // int w = Zp.GetFieldMinimumPrimitive(Prime); // for (int i = 0; i < NumPlayers; i++) // { // XValues.Add(new Zp(Prime, Zp.CalculatePower(w, i, Prime))); // } // /* Create the distorted code word */ // var distortedCodeword = new List<Zp>(); // for (int i = 0; i < NumPlayers; i++) // distortedCodeword.Add(calculationPoly.Sample(XValues[i])); // var fixedCodeword = WelchBerlekampDecoder.decode(XValues, distortedCodeword, PolynomialDeg, 2 * PolynomialDeg, Prime); // // Check For exception in codeword fixing // if (fixedCodeword == null) // { // string errorStr = "There were more then polynomialDegree = " + PolynomialDeg + " Cheaters - cannot complete mult step."; // throw new Exception(errorStr); // } // for (int i = 0; i < fixedCodeword.Count; i++) // { // if (!BadPlayers.Contains(i) && !fixedCodeword[i].Equals(distortedCodeword[i])) // { // // Player Number i is a multi-step cheater! // cheaterFound = true; // RemoveCheaterPlayer(i); // // Continue at iteration till no one will cheat // } // } //} ///* Finally calculate your share - we will get here if no one had tried to cheat */ //var firstLineAtInvVanderMonde = GetMultStepCoeffsForCheaters(0); ///* Calculate your share of the K-th coeff at the calculation polynomial */ //var tempSecret = new Zp(Prime, 0); //for (int i = 0; i < recvSharesFromPlayers.Count; i++) //{ // tempSecret.Add(recvSharesFromPlayers[i].ConstMul(firstLineAtInvVanderMonde[i])); //} //return tempSecret; }
//public override void Receive(Message msg) //{ // Gate anchor, myGate; // var ssmpcMsg = msg as ScalableMpcMessage; // Debug.Assert(ssmpcMsg != null); // switch (ssmpcMsg.StateKey.Stage) // { // case Stage.Input: // var inputMsg = ssmpcMsg as InputMessage; // // start a heavy-weight smpc with parent and sibling gates // myGate = Circuit.FindGate(ssmpcMsg.StateKey.GateId); // RunChildMpc(myGate.OutNodes[0], myGate, inputMsg.Data); // break; // case Stage.Mpc: // MpcProtocol smpc; // var mpcMsg = ssmpcMsg as MpcMessage; // if (MpcSessions.ContainsKey(smpcMsg.StateKey)) // mpc = MpcSessions[mpcMsg.StateKey].Mpc; // else // { // // I must be in the anchor gate // Debug.Assert(mpcMsg.ToGateId == mpcMsg.AnchorId, "Synchronization exception: Why don't I have an session for this MPC?"); // // my child gate is asking me to participate in an MPC, so create an MPC protocol instance and join // anchor = Circuit.FindGate(mpcMsg.AnchorId); // mpc = RunAnchorMpc(anchor); // } // mpc.Receive(mpcMsg.InnerMessage); // break; // } //} /// <summary> /// Starts a heavy-weight SMPC instance for an SMPC child gate player. /// </summary> protected virtual BgwProtocol RunChildMpc(Gate anchor, Gate myGate, Zp myInput) { Debug.Assert(quorumsMap.ContainsKey(anchor.QuorumIndex)); Debug.Assert(quorumsMap.ContainsKey(myGate.QuorumIndex)); // find associated quorums var childGates = anchor.InNodes; var myGateId = myGate.Id; var virtualIds = new List<int>(quorumsMap[anchor.QuorumIndex].Select(p => (anchor.Id << 16) + p)); // TODO: IMPORTANT: THE ASSUMPTION HERE LIMITS ENTITY/GATE IDs TO 32768. TO INCREASE THIS LIMIT EITHER USE UINT/ULONG IDs OR CHANGE THIS CODE. foreach (var gate in childGates) { foreach (var playerId in quorumsMap[gate.QuorumIndex]) virtualIds.Add((gate.Id << 16) + playerId); } var myVirtualId = (myGateId << 16) + Party.Id; // run the protocol and keep it in a the session state var key = new MpcKey(myGateId, anchor.Id); // Mahdi (3/25/14: Do we really need virtual ids?) throw new NotImplementedException(); //var mpc = new BgwProtocol(anchor.MpcCircuit, virtualIds.AsReadOnly(), myVirtualId, myInput, OnMpcSend, key); //mpc.MpcFinish += new FinishHandler(OnMpcFinish); //MpcSessions.Collect(key, new MpcSession(mpc)); //mpc.Run(); //return mpc; }
protected void ShareSecret(Zp secret, IList<int> players, DkmsKey key) { var shares = ShamirSharing.Share(secret, players.Count, players.Count - 1); var shareMsgs = new List<ShareMsg<Zp>>(); foreach (var share in shares) shareMsgs.Add(new ShareMsg<Zp>(new Share<Zp>(share), key)); Send(players, shareMsgs); }
private void UpdateRecvShare(IList<SecretPolynomials> recvPublicPolysList, Zp recvSecretShare_i) { if ((recvPublicPolysList != null)) { var newRecvSercretPoly = recvPublicPolysList[Party.Id]; if (newRecvSercretPoly != null) { var recvShare = newRecvSercretPoly.Fi_xPolynomial[0]; if (recvShare != null) recvSecretShare_i.Value = recvShare.Value; } } }
protected virtual void HandleNotDealer(bool isOrigPolyLegal, IList<Coordinate> wrongCoordinatesList, int playerToVerify, Zp recvSecretShare_i, SecretPolynomials secretPoly_i) { //// Step 2 - Check and advertise results to players on the bulletin board //var foundWrongValue1 = !isOrigPolyLegal || (wrongCoordinatesList.Count != 0); //var complaintValue = new PlayerNotification(foundWrongValue1 ? Confirmation.Complaint : Confirmation.Approval); //var recvComplaintesList = Sendable.asPlayerNotifications( // BulletinBoardProtocol.PublishAndRead(complaintValue, Prime, BadPlayers)); //// Count complaints number //int numOfcomplaints = GetNumberOfComplaints(recvComplaintesList); //// Step 3 - If there is a need, receive polynomials for the complainig sides and verify it //// currently check only polynomials - not wrong coordinates //if (numOfcomplaints != 0) //{ // // Should get a list of the public polynomials from player 'playerToVerify' - get info from the bulletin board // var sendablePolysRecv = BulletinBoardProtocol.Read(playerToVerify, Prime); // IList<SecretPolynomials> recvPublicPolysList1 = null; // if (sendablePolysRecv != null) // recvPublicPolysList1 = sendablePolysRecv.asSecretPolynomialsBundle().List; // if (foundWrongValue1) // UpdateRecvShare(recvPublicPolysList1, recvSecretShare_i); // bool foundWrongValue2 = (!isOrigPolyLegal) || IsPublicDataContradictPrivate(secretPoly_i, recvPublicPolysList1, recvComplaintesList, recvSecretShare_i); // // Check and advertise results to players on the bulletin board // complaintValue = new PlayerNotification(foundWrongValue2 ? Confirmation.Complaint : Confirmation.Approval); // recvComplaintesList = Sendable.asPlayerNotifications( // BulletinBoardProtocol.PublishAndRead(complaintValue, Prime, BadPlayers)); // // Count complaints number // numOfcomplaints = GetNumberOfComplaints(recvComplaintesList); // // Step 4 - If there is a need, recieve polynomials for the complainig sides and verify it // if (numOfcomplaints != 0) // { // // Should get a list of the public polynomials from player 'playerToVerify' - get info from the bulletin board // sendablePolysRecv = BulletinBoardProtocol.Read(playerToVerify, Prime); // IList<SecretPolynomials> recvPublicPolysList2 = null; // if (sendablePolysRecv != null) // recvPublicPolysList2 = sendablePolysRecv.asSecretPolynomialsBundle().List; // if (foundWrongValue2) // UpdateRecvShare(recvPublicPolysList2, recvSecretShare_i); // bool foundWrongValue3 = (!isOrigPolyLegal) || IsPublicDataContradictPrivate(secretPoly_i, recvPublicPolysList2, recvComplaintesList, recvSecretShare_i); // foundWrongValue3 = foundWrongValue3 || IsNewPublicDataContradictOld(recvPublicPolysList1, recvPublicPolysList2); // // Check and advertise results to players on the bulletin board // complaintValue = new PlayerNotification(foundWrongValue3 ? Confirmation.Complaint : Confirmation.Approval); // recvComplaintesList = Sendable.asPlayerNotifications( // BulletinBoardProtocol.PublishAndRead(complaintValue, Prime, BadPlayers)); // // Count complaints number // numOfcomplaints = GetNumberOfComplaints(recvComplaintesList); // /* Step 5 - Check if there is more than 'polynomialDeg' complaintes or recption timeout occured */ // if (numOfcomplaints > PolynomialDeg) // { // // Found a cheater player: playerToVerify - taking its input as zero. // // Take the zero polynomial as this user input // recvSecretShare_i.Value = 0; // RemoveCheaterPlayer(playerToVerify); // don't send and receive from this player anymore... // } // } //} //throw new NotImplementedException(); }
private IList<Zp> ConstructRxPolynomial(ShareDetails aSharesDetails, ShareDetails bSharesDetails, ShareDetails abSharesDetails, ShareDetails rSharesDetails) { var fax = aSharesDetails.RandomPolynomial; var fbx = bSharesDetails.RandomPolynomial; var hx = abSharesDetails.RandomPolynomial; var rx = rSharesDetails.RandomPolynomial; var RxPolynomial = new Zp[2 * PolynomialDeg + 1]; /* Initialize RxPolynomial coefs with zeros */ for (int i = 0; i < 2 * PolynomialDeg + 1; i++) RxPolynomial[i] = new Zp(Prime, 0); /* First calculate fax*fbx - hx */ for (int i = 0; i < fax.Count; i++) { Zp temp = fax[i]; for (int j = 0; j < fax.Count; j++) RxPolynomial[i + j].Add(temp.ConstMul(fbx[j])); RxPolynomial[i].Sub(hx[i]); } /* Calculate x*rx+fax*fbx - hx*/ for (int i = 0; i < rx.Count; i++) RxPolynomial[i + 1].Add(rx[i]); return new List<Zp>(RxPolynomial); }
private bool IsMultStepShareLegal(MultStepBCaseShare recvShareFromPlayer_i, MultStepVerificationPoly recvVerifcationPolynomial) { if (!IsRecvShareLegal(recvShareFromPlayer_i)) return false; var RxPolynomial = recvVerifcationPolynomial.RxPolynomial; Zp Ratpoint0 = Zp.EvalutePolynomialAtPoint(RxPolynomial, new Zp(Prime, 0)); if (!Ratpoint0.Equals(new Zp(Prime, 0))) { return false; } int w = NumTheoryUtils.GetFieldMinimumPrimitive(Prime); var w_InMyIndex = new Zp(Prime, NumTheoryUtils.ModPow(w, Party.Id, Prime)); Zp RjFromPublicPolynomial = Zp.EvalutePolynomialAtPoint(RxPolynomial, w_InMyIndex); Zp temp = recvShareFromPlayer_i.AShare.ConstMul(recvShareFromPlayer_i.BShare).ConstSub(recvShareFromPlayer_i.AbShare); Zp RjFromRecvPrivateInfo = w_InMyIndex.ConstMul(recvShareFromPlayer_i.RShare).ConstAdd(temp); if (!RjFromPublicPolynomial.Equals(RjFromRecvPrivateInfo)) return false; return true; }
public UserAssignment(long bridgePseudonym, Zp bridgeShare) { BridgePseudonym = bridgePseudonym; BridgeShare = bridgeShare; }
/* * Finds a solution to a system of linear equations represtented by an * n-by-n+1 matrix A: namely, denoting by B the left n-by-n submatrix of A * and by C the last column of A, finds a column vector x such that Bx=C. * If more than one solution exists, chooses one arbitrarily by setting some * values to 0. If no solutions exists, returns false. Otherwise, places * a solution into the first argument and returns true. * * Note : matrix A changes (gets converted to row echelon form). */ private static Zp[] linearSolve(ZpMatrix A, ZpMatrix B, int prime) { var invArray = NumTheoryUtils.GetFieldInverse(prime); var C = ZpMatrix.GetConcatenationMatrix(A, B); // augmented matrix int n = C.RowCount; int[] solution = new int[n]; int temp; int firstDeterminedValue = n; // we will be determining values of the solution // from n-1 down to 0. At any given time, // values from firstDeterminedValue to n-1 have been // found. Initializing to n means // no values have been found yet. // To put it another way, the variabe firstDeterminedValue // stores the position of first nonzero entry in the row just examined // (except at initialization) int rank = C.Gauss(); int[][] cContent = C.Data; // can start at rank-1, because below that are all zeroes for (int row = rank - 1; row >= 0; row--) { // remove all the known variables from the equation temp = cContent[row][n]; int col; for (col = n - 1; col >= firstDeterminedValue; col--) temp = Zp.Modulo(temp - (cContent[row][col] * solution[col]), prime); // now we need to find the first nonzero coefficient in this row // if it exists before firstDeterminedValue // because the matrix is in row echelon form, the first nonzero // coefficient cannot be before the diagonal for (col = row; col < firstDeterminedValue; col++) { if (cContent[row][col] != 0) break; } if (col < firstDeterminedValue) // this means we found a nonzero coefficient { // we can determine the variables in position from col to firstDeterminedValue // if this loop executes even once, then the system is undertermined // we arbitrarily set the undetermined variables to 0, because it make math easier for (int j = col + 1; j < firstDeterminedValue; j++) solution[j] = 0; // Now determine the variable at the nonzero coefficient //div(solution[col], temp, A.getContent()[row][col]); solution[col] = temp * invArray[Zp.Modulo(cContent[row][col], prime)]; firstDeterminedValue = col; } else { // this means there are no nonzero coefficients before firstDeterminedValue. // Because we skip all the zero rows at the bottom, the matrix is in // row echelon form, and firstDeterminedValue is equal to the // position of first nonzero entry in row+1 (unless it is equal to n), // this means we are at a row with all zeroes except in column n // The system has no solution. return null; } } // set the remaining undetermined values, if any, to 0 for (int col = 0; col < firstDeterminedValue; col++) solution[col] = 0; var ResultVec = new Zp[n]; for (int i = 0; i < n; i++) ResultVec[i] = new Zp(prime, solution[i]); return ResultVec; }