Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CompactMPC/Buffers/BufferBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

namespace CompactMPC.Buffers
{
/// <summary>
/// Allows to build a byte buffer by composing existing buffers and integer values.
/// </summary>
public class BufferBuilder
{
private MessageComposer _composer;
Expand Down
24 changes: 24 additions & 0 deletions CompactMPC/ObliviousTransfer/IGeneralizedObliviousTransfer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,33 @@

namespace CompactMPC.ObliviousTransfer
{
/// <summary>
/// Common interface for 1-out-of-4 bit oblivious transfer implementations.
///
/// "Generalized" currently refers to messages of arbitrary byte lengths as opposed to
/// the <see cref="IObliviousTransfer"/> interface, which is specialized to single bit OT.
/// </summary>
public interface IGeneralizedObliviousTransfer
{
/// <summary>
/// Supplies the four options from the sender to the oblivious transfer.
/// </summary>
/// <param name="channel">The network message channel to the receiver.</param>
/// <param name="options">Array containing the four options supplied to 1-out-of-4 OT by the sender for each invocation.</param>
/// <param name="numberOfInvocations">The number of OT invocations in the transmission.</param>
/// <returns>An asynchronous task which performs the server side of the oblivious transfer.</returns>
/// <remarks>To increase efficiency, several invocations of OT can be batched into one transmission.</remarks>
Task SendAsync(IMessageChannel channel, Quadruple<byte[]>[] options, int numberOfInvocations, int numberOfMessageBytes);

/// <summary>
/// Supplies the selection index from the client side to the oblivious transfer and returns the corresponding option from the server.
/// </summary>
/// <param name="channel">The network message channel to the sender.</param>
/// <param name="selectionIndices">Array containing the selection index supplied to 1-out-of-4 OT by the client for each invocation.</param>
/// <param name="numberOfInvocations">The number of OT invocations in the transmission.</param>
/// <returns>An asynchronous task performing the client side of the oblivious transfer and returning the array containing
/// the options as selected by the client retrieved from the server.</returns>
/// <remarks>To increase efficiency, several invocations of OT can be batched into one transmission.</remarks>
Task<byte[][]> ReceiveAsync(IMessageChannel channel, QuadrupleIndexArray selectionIndices, int numberOfInvocations, int numberOfMessageBytes);
}
}
23 changes: 23 additions & 0 deletions CompactMPC/ObliviousTransfer/IObliviousTransfer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,32 @@

namespace CompactMPC.ObliviousTransfer
{
/// <summary>
/// Common interface for 1-out-of-4 single bit oblivious transfer implementations.
///
/// For a variant with arbitrary bit length for messages/options, see <see cref="IGeneralizedObliviousTransfer"/>.
/// </summary>
public interface IObliviousTransfer
{
/// <summary>
/// Supplies the four options from the sender to the oblivious transfer.
/// </summary>
/// <param name="channel">The network message channel to the receiver.</param>
/// <param name="options">Array containing the four options supplied to 1-out-of-4 OT by the sender for each invocation.</param>
/// <param name="numberOfInvocations">The number of OT invocations in the transmission.</param>
/// <returns>An asynchronous task which performs the server side of the oblivious transfer.</returns>
/// <remarks>To increase efficiency, several invocations of OT can be batched into one transmission.</remarks>
Task SendAsync(IMessageChannel channel, BitQuadrupleArray options, int numberOfInvocations);

/// <summary>
/// Supplies the selection index from the client side to the oblivious transfer and returns the corresponding option from the server.
/// </summary>
/// <param name="channel">The network message channel to the sender.</param>
/// <param name="selectionIndices">Array containing the selection index supplied to 1-out-of-4 OT by the client for each invocation.</param>
/// <param name="numberOfInvocations">The number of OT invocations in the transmission.</param>
/// <returns>An asynchronous task performing the client side of the oblivious transfer and returning the array containing
/// the options as selected by the client retrieved from the server.</returns>
/// <remarks>To increase efficiency, several invocations of OT can be batched into one transmission.</remarks>
Task<BitArray> ReceiveAsync(IMessageChannel channel, QuadrupleIndexArray selectionIndices, int numberOfInvocations);
}
}
6 changes: 6 additions & 0 deletions CompactMPC/ObliviousTransfer/InsecureObliviousTransfer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@

namespace CompactMPC.ObliviousTransfer
{
/// <summary>
/// Insecure (non-oblivious) implementation of the oblivious transfer interface.
///
/// Caution! This class is intended for testing and debugging purposes and does not provide any security.
/// Hence, it should not be used with any sensitive or in production deployments. All options are SENT IN THE PLAIN.
/// </summary>
public class InsecureObliviousTransfer : GeneralizedObliviousTransfer
{
protected override Task GeneralizedSendAsync(IMessageChannel channel, Quadruple<byte[]>[] options, int numberOfInvocations, int numberOfMessageBytes)
Expand Down
25 changes: 25 additions & 0 deletions CompactMPC/ObliviousTransfer/NaorPinkasObliviousTransfer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ protected override async Task GeneralizedSendAsync(IMessageChannel channel, Quad
listOfCs[i] = GenerateGroupElement(out exponent);
listOfExponents[i] = exponent;
});
// note(lumip): we discussed a possible vulnerability arising when two or more group elements
// are similar but decided against checking for that since the probability of it occuring is
// negligible small for the relevant group sizes.

BigInteger alpha = listOfExponents[0];

Expand Down Expand Up @@ -189,6 +192,11 @@ protected override async Task<byte[][]> GeneralizedReceiveAsync(IMessageChannel
return selectedOptions;
}

/// <summary>
/// Returns a random element from the group as well as the corresponding exponent for the group generator.
/// </summary>
/// <param name="exponent">The exponent with which the returned group element can be obtained from the group generator.</param>
/// <returns>A random group element.</returns>
private BigInteger GenerateGroupElement(out BigInteger exponent)
{
// note(lumip): do not give in to the temptation of replacing the exponent > _parameters.Q part with a
Expand All @@ -203,11 +211,22 @@ private BigInteger GenerateGroupElement(out BigInteger exponent)
return BigInteger.ModPow(_parameters.G, exponent, _parameters.P);
}

/// <summary>
/// Multiplicatively inverts a group element.
/// </summary>
/// <param name="groupElement">The group element to be inverted.</param>
/// <returns>The multiplicative inverse of the argument in the group.</returns>
private BigInteger Invert(BigInteger groupElement)
{
return BigInteger.ModPow(groupElement, _parameters.Q - 1, _parameters.P);
}

/// <summary>
/// Asynchronously writes a list of group elements (BigInteger) to a message channel.
/// </summary>
/// <param name="channel">The network message channel.</param>
/// <param name="groupElements">The list of group elements to write/send.</param>
/// <returns></returns>
private Task WriteGroupElements(IMessageChannel channel, IReadOnlyList<BigInteger> groupElements)
{
MessageComposer message = new MessageComposer(2 * groupElements.Count);
Expand All @@ -221,6 +240,12 @@ private Task WriteGroupElements(IMessageChannel channel, IReadOnlyList<BigIntege
return channel.WriteMessageAsync(message.Compose());
}

/// <summary>
/// Asynchronously reads a specified number of group elements from a message channel.
/// </summary>
/// <param name="channel">The network message channel.</param>
/// <param name="numberOfGroupElements">Number of group elements to read/receive.</param>
/// <returns></returns>
private async Task<BigInteger[]> ReadGroupElements(IMessageChannel channel, int numberOfGroupElements)
{
MessageDecomposer message = new MessageDecomposer(await channel.ReadMessageAsync());
Expand Down
31 changes: 31 additions & 0 deletions CompactMPC/ObliviousTransfer/RandomOracle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,41 @@

namespace CompactMPC.ObliviousTransfer
{
/// <summary>
/// A random oracle as canonically defined.
///
/// As per the canonical definition of the random oracle, it produces a random but deterministic output
/// for each unique query it is invoked on, i.e., the output is unpredictably random over different queries
/// but providing the same query will always yield the same output sequence.
///
/// The RandomOracle class also provides a Mask message that masks a given message with the output of the
/// random oracle for a given query. In that case the query can be seen as a shared key that allows for
/// masking and unmasking (encryption/decryption) of a message.
///
/// Naturally, a true random oracle cannot be implemented so the outputs of all implementations of
/// RandomOracle will not be perfectly random but computationally indistinguishable from true randomness
/// by the usual cryptographic standards.
/// </summary>
public abstract class RandomOracle
{
/// <summary>
/// Supplies the response of the random oracle to the given query.
///
/// As per the canonical definition of the random oracle, it produces a random but deterministic output
/// for each unique query, i.e., the output is unpredictably random over different queries but
/// providing the same query will always yield the same output sequence.
/// </summary>
/// <param name="query">The query for the random oracle.</param>
/// <returns></returns>
public abstract IEnumerable<byte> Invoke(byte[] query);

/// <summary>
/// Masks a given message by applying bitwise XOR with the random oracle output stream.
/// </summary>
/// <param name="message">The message to be masked with the random oracle output.</param>
/// <param name="query">The query for the random oracle.</param>
/// <returns>Byte array containing the masked message.</returns>
/// <exception cref="ArgumentException">Thrown when the random oracle does not provide enough data to mask the given message.</exception>
public byte[] Mask(byte[] message, byte[] query)
{
byte[] result = new byte[message.Length];
Expand Down
13 changes: 13 additions & 0 deletions SampleCircuits/SecureSetIntersection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@

namespace CompactMPC.SampleCircuits
{
/// <summary>
/// Circuit which computes the intersection of sets given in a binary word representation.
/// </summary>
/// <remarks></remarks>
/// In addition to the intersection result, a counter giving the cardinality of the intersection
/// is also calculated.
/// </remarks>
public class SecureSetIntersection
{
private SecureWord _intersection;
Expand All @@ -25,6 +32,9 @@ public SecureSetIntersection(SecureWord[] inputs, int numberOfCounterBits)
_counter = counter.OfFixedLength(numberOfCounterBits);
}

/// <summary>
/// The binary encoding of the intersection set.
/// </summary>
public SecureWord Intersection
{
get
Expand All @@ -33,6 +43,9 @@ public SecureWord Intersection
}
}

/// <summary>
/// The number of elements in the intersection set.
/// </summary>
public SecureInteger Counter
{
get
Expand Down