* Simple CLI * Ability to parse ballots * Encrypt plaintext and output to out dir * Submit ballots * Fix compiler warnings * Create output directory if it doesn't exist * Add .NET 6 to github actions * Upgrade to Visual Studio 2022 * Try to always install .NET 6 * Ensure .NET 5 AND 6 are both installed * Upgrade .NET 5 to 6 * Only install .NET 6 * Remove 2nd command per PR
This commit is contained in:
Родитель
171b97809a
Коммит
5180c1b20a
|
@ -28,8 +28,8 @@ jobs:
|
|||
"ubuntu-18.04-gcc-9.3.0",
|
||||
"ubuntu-18.04-clang-10.0.0",
|
||||
"macos-10.15-xcode-12.0",
|
||||
"windows-2019-gcc-9.2.0",
|
||||
"windows-2019-msvc-latest",
|
||||
"windows-2022-gcc-9.2.0",
|
||||
"windows-2022-msvc-latest",
|
||||
]
|
||||
include:
|
||||
- name: ubuntu-20.04-clang-10.0.0
|
||||
|
@ -48,12 +48,12 @@ jobs:
|
|||
os: macOS-10.15
|
||||
compiler: xcode
|
||||
version: "12"
|
||||
- name: windows-2019-gcc-9.2.0
|
||||
os: windows-2019
|
||||
- name: windows-2022-gcc-9.2.0
|
||||
os: windows-2022
|
||||
compiler: gcc
|
||||
version: "9"
|
||||
- name: windows-2019-msvc-latest
|
||||
os: windows-2019
|
||||
- name: windows-2022-msvc-latest
|
||||
os: windows-2022
|
||||
compiler: msvc
|
||||
version: "latest"
|
||||
|
||||
|
@ -62,6 +62,10 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
- name: Change Directory
|
||||
run: cd ${{ github.workspace }}
|
||||
- name: Install .NET 6
|
||||
uses: actions/setup-dotnet@v2
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
- name: Update Environment
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
|
|
|
@ -151,3 +151,5 @@ bindings/netframework/ElectionGuard.NetFramework/packages/
|
|||
sample-data.zip
|
||||
|
||||
sample-data-container.zip
|
||||
|
||||
bindings/netstandard/ElectionGuard/*.user
|
||||
|
|
16
Makefile
16
Makefile
|
@ -88,11 +88,11 @@ endif
|
|||
build-msvc:
|
||||
@echo 🖥️ BUILD MSVC
|
||||
ifeq ($(OPERATING_SYSTEM),Windows)
|
||||
cmake -S . -B $(ELECTIONGUARD_BUILD_LIBS_DIR)/msvc/Win32 -G "Visual Studio 16 2019" -A Win32 \
|
||||
cmake -S . -B $(ELECTIONGUARD_BUILD_LIBS_DIR)/msvc/Win32 -G "Visual Studio 17 2022" -A Win32 \
|
||||
-DCMAKE_BUILD_TYPE=$(TARGET) \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCPM_SOURCE_CACHE=$(CPM_SOURCE_CACHE)
|
||||
cmake -S . -B $(ELECTIONGUARD_BUILD_LIBS_DIR)/msvc/x64 -G "Visual Studio 16 2019" -A x64 \
|
||||
cmake -S . -B $(ELECTIONGUARD_BUILD_LIBS_DIR)/msvc/x64 -G "Visual Studio 17 2022" -A x64 \
|
||||
-DCMAKE_BUILD_TYPE=$(TARGET) \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DCAN_USE_VECTOR_INTRINSICS=ON \
|
||||
|
@ -231,7 +231,7 @@ sanitize: sanitize-asan sanitize-tsan
|
|||
sanitize-asan:
|
||||
@echo 🧼 SANITIZE ADDRESS AND UNDEFINED
|
||||
ifeq ($(OPERATING_SYSTEM),Windows)
|
||||
cmake -S . -B $(ELECTIONGUARD_BUILD_LIBS_DIR)/msvc/x64 -G "Visual Studio 16 2019" -A x64 \
|
||||
cmake -S . -B $(ELECTIONGUARD_BUILD_LIBS_DIR)/msvc/x64 -G "Visual Studio 17 2022" -A x64 \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DEXPORT_INTERNALS=ON \
|
||||
|
@ -319,12 +319,12 @@ endif
|
|||
|
||||
bench-netstandard: build-netstandard
|
||||
@echo 🧪 BENCHMARK
|
||||
@echo net 5.0 x86
|
||||
./bindings/netstandard/ElectionGuard/ElectionGuard.Encryption.Bench/bin/x86/$(TARGET)/net5.0/ElectionGuard.Encryption.Bench
|
||||
@echo net 6.0 x86
|
||||
./bindings/netstandard/ElectionGuard/ElectionGuard.Encryption.Bench/bin/x86/$(TARGET)/net6.0/ElectionGuard.Encryption.Bench
|
||||
@echo net 4.8 x86
|
||||
./bindings/netstandard/ElectionGuard/ElectionGuard.Encryption.Bench/bin/x86/$(TARGET)/net48/ElectionGuard.Encryption.Bench
|
||||
@echo net 5.0 x64
|
||||
./bindings/netstandard/ElectionGuard/ElectionGuard.Encryption.Bench/bin/x64/$(TARGET)/net5.0/ElectionGuard.Encryption.Bench
|
||||
@echo net 6.0 x64
|
||||
./bindings/netstandard/ElectionGuard/ElectionGuard.Encryption.Bench/bin/x64/$(TARGET)/net6.0/ElectionGuard.Encryption.Bench
|
||||
@echo net 4.8 x64
|
||||
./bindings/netstandard/ElectionGuard/ElectionGuard.Encryption.Bench/bin/x64/$(TARGET)/net48/ElectionGuard.Encryption.Bench
|
||||
|
||||
|
@ -359,7 +359,7 @@ endif
|
|||
test-msvc:
|
||||
@echo 🧪 TEST MSVC
|
||||
ifeq ($(OPERATING_SYSTEM),Windows)
|
||||
cmake -S . -B $(ELECTIONGUARD_BUILD_LIBS_DIR)/msvc/x64 -G "Visual Studio 16 2019" -A x64 \
|
||||
cmake -S . -B $(ELECTIONGUARD_BUILD_LIBS_DIR)/msvc/x64 -G "Visual Studio 17 2022" -A x64 \
|
||||
-DCMAKE_BUILD_TYPE=$(TARGET) \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DEXPORT_INTERNALS=ON \
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net5.0;net48</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0;net48</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Platforms>x64;x86</Platforms>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<StartupObject>ElectionGuard.Encryption.Cli.Program</StartupObject>
|
||||
<AssemblyName>eg</AssemblyName>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ElectionGuard.Encryption\ElectionGuard.Encryption.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,94 @@
|
|||
namespace ElectionGuard.Encryption.Cli.Encrypt
|
||||
{
|
||||
internal class EncryptCommand
|
||||
{
|
||||
public static Task Encrypt(EncryptOptions encryptOptions)
|
||||
{
|
||||
try
|
||||
{
|
||||
var encryptCommand = new EncryptCommand();
|
||||
return encryptCommand.EncryptInternal(encryptOptions);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task EncryptInternal(EncryptOptions encryptOptions)
|
||||
{
|
||||
encryptOptions.Validate();
|
||||
if (string.IsNullOrEmpty(encryptOptions.Context)) throw new ArgumentNullException(nameof(encryptOptions.Context));
|
||||
if (string.IsNullOrEmpty(encryptOptions.Manifest)) throw new ArgumentNullException(nameof(encryptOptions.Manifest));
|
||||
if (string.IsNullOrEmpty(encryptOptions.BallotsDir)) throw new ArgumentNullException(nameof(encryptOptions.BallotsDir));
|
||||
|
||||
var encryptionMediator = await GetEncryptionMediator(encryptOptions.Context, encryptOptions.Manifest);
|
||||
var ballotFiles = GetBallotFiles(encryptOptions.BallotsDir);
|
||||
|
||||
foreach (var ballotFile in ballotFiles)
|
||||
{
|
||||
Console.WriteLine($"Parsing: {ballotFile}");
|
||||
var plaintextBallot = await GetPlaintextBallot(ballotFile);
|
||||
var submittedBallot = EncryptAndSubmit(encryptionMediator, plaintextBallot);
|
||||
await WriteSubmittedBallot(encryptOptions, ballotFile, submittedBallot);
|
||||
}
|
||||
Console.WriteLine("Parsing Complete");
|
||||
}
|
||||
|
||||
private static SubmittedBallot EncryptAndSubmit(EncryptionMediator encryptionMediator, PlaintextBallot plaintextBallot)
|
||||
{
|
||||
var ciphertextBallot = encryptionMediator.Encrypt(plaintextBallot);
|
||||
// todo: spoil?
|
||||
var submittedBallot = new SubmittedBallot(ciphertextBallot, BallotBoxState.Cast);
|
||||
return submittedBallot;
|
||||
}
|
||||
|
||||
private static async Task<EncryptionMediator> GetEncryptionMediator(string contextFile, string manifestFile)
|
||||
{
|
||||
var context = await GetContext(contextFile);
|
||||
var internalManifest = await GetInternalManifest(manifestFile);
|
||||
var device = GetDevice();
|
||||
var encryptionMediator = new EncryptionMediator(internalManifest, context, device);
|
||||
return encryptionMediator;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetBallotFiles(string directory)
|
||||
{
|
||||
return Directory.EnumerateFiles(directory);
|
||||
}
|
||||
|
||||
private static async Task<PlaintextBallot> GetPlaintextBallot(string ballotFile)
|
||||
{
|
||||
var ballot = await File.ReadAllTextAsync(ballotFile);
|
||||
var plaintextBallot = new PlaintextBallot(ballot);
|
||||
return plaintextBallot;
|
||||
}
|
||||
|
||||
private static async Task WriteSubmittedBallot(EncryptOptions encryptOptions, string ballotFile,
|
||||
SubmittedBallot submittedBallot)
|
||||
{
|
||||
var ballotJson = submittedBallot.ToJson();
|
||||
var outFile = Path.Join(encryptOptions.OutDir, Path.GetFileName(ballotFile));
|
||||
await File.WriteAllTextAsync(outFile, ballotJson);
|
||||
}
|
||||
|
||||
private static EncryptionDevice GetDevice()
|
||||
{
|
||||
return new EncryptionDevice(12345UL, 23456UL, 34567UL, "Location");
|
||||
}
|
||||
|
||||
private static async Task<InternalManifest> GetInternalManifest(string manifestFile)
|
||||
{
|
||||
var manifestJson = await File.ReadAllTextAsync(manifestFile);
|
||||
var manifest = new Manifest(manifestJson);
|
||||
return new InternalManifest(manifest);
|
||||
}
|
||||
|
||||
private static async Task<CiphertextElectionContext> GetContext(string contextFile)
|
||||
{
|
||||
var contextJson = await File.ReadAllTextAsync(contextFile);
|
||||
return new CiphertextElectionContext(contextJson);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
using CommandLine;
|
||||
|
||||
namespace ElectionGuard.Encryption.Cli.Encrypt;
|
||||
|
||||
[Verb("encrypt", HelpText = "Encrypt ballots using a context.")]
|
||||
internal class EncryptOptions
|
||||
{
|
||||
[Option('c', "context", Required = true, HelpText = "Json file containing an ElectionGuard context that contains encryption details.")]
|
||||
public string? Context { get; set; }
|
||||
|
||||
[Option('m', "manifest", Required = true, HelpText = "Json file containing an ElectionGuard manifest that contains election details.")]
|
||||
public string? Manifest { get; set; }
|
||||
|
||||
[Option('b', "ballots", Required = true, HelpText = "File folder containing ballots to encrypt.")]
|
||||
public string? BallotsDir { get; set; }
|
||||
|
||||
[Option('o', "out", Required = true, HelpText = "File folder in which to place encrypted ballots.")]
|
||||
public string? OutDir { get; set; }
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
ValidateFiles();
|
||||
ValidateDirectories();
|
||||
}
|
||||
|
||||
private void ValidateDirectories()
|
||||
{
|
||||
if (string.IsNullOrEmpty(BallotsDir)) throw new ArgumentNullException(nameof(BallotsDir));
|
||||
if (string.IsNullOrEmpty(OutDir)) throw new ArgumentNullException(nameof(OutDir));
|
||||
|
||||
if (!Directory.Exists(BallotsDir)) throw new ArgumentException($"ballots directory does not exist"); ;
|
||||
if (!Directory.Exists(OutDir))
|
||||
{
|
||||
Directory.CreateDirectory(OutDir);
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateFiles()
|
||||
{
|
||||
var requiredFiles = new[] { Context, Manifest };
|
||||
var missingFiles = requiredFiles.Where(f => !File.Exists(f));
|
||||
foreach (var file in missingFiles)
|
||||
{
|
||||
throw new ArgumentException($"{file} does not exist");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using CommandLine;
|
||||
using ElectionGuard.Encryption.Cli.Encrypt;
|
||||
|
||||
namespace ElectionGuard.Encryption.Cli;
|
||||
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
await Parser.Default.ParseArguments<EncryptOptions>(args)
|
||||
.WithParsedAsync(EncryptCommand.Encrypt);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net5.0;net48</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0;net48</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Platforms>x64;x86</Platforms>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net5.0;net48</TargetFrameworks>
|
||||
<TargetFrameworks>net6.0;net48</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Platforms>x64;x86</Platforms>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,347 +1,347 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ElectionGuard
|
||||
{
|
||||
using NativeElementModQ = NativeInterface.ElementModQ.ElementModQHandle;
|
||||
using NativeEncryptionDevice = NativeInterface.EncryptionDevice.EncryptionDeviceHandle;
|
||||
using NativeEncryptionMediator = NativeInterface.EncryptionMediator.EncryptionMediatorHandle;
|
||||
using NativeCiphertextBallot = NativeInterface.CiphertextBallot.CiphertextBallotHandle;
|
||||
using NativeCiphertextBallotContest = NativeInterface.CiphertextBallotContest.CiphertextBallotContestHandle;
|
||||
using NativeCiphertextBallotSelection = NativeInterface.CiphertextBallotSelection.CiphertextBallotSelectionHandle;
|
||||
using NativeCompactCiphertextBallot = NativeInterface.CompactCiphertextBallot.CompactCiphertextBallotHandle;
|
||||
|
||||
/// <summary>
|
||||
/// Metadata for encryption device
|
||||
///
|
||||
/// The encryption device is a stateful container that represents abstract hardware
|
||||
/// authorized to participate in a specific election.
|
||||
///
|
||||
/// </summary>
|
||||
public class EncryptionDevice : DisposableBase
|
||||
{
|
||||
internal unsafe NativeEncryptionDevice Handle;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new EncryptionDevice
|
||||
/// </summary>
|
||||
/// <param name="deviceUuid">a unique identifier tied to the device hardware</param>
|
||||
/// <param name="sessionUuid">a unique identifier tied to the runtime session</param>
|
||||
/// <param name="launchCode">a unique identifer tied to the election</param>
|
||||
/// <param name="location">an arbitrary string meaningful to the external system
|
||||
/// such as a friendly name, description, or some other value</param>
|
||||
public unsafe EncryptionDevice(
|
||||
ulong deviceUuid,
|
||||
ulong sessionUuid,
|
||||
ulong launchCode,
|
||||
string location)
|
||||
{
|
||||
var status = NativeInterface.EncryptionDevice.New(
|
||||
deviceUuid, sessionUuid, launchCode, location, out Handle);
|
||||
status.ThrowIfError();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a new hash value
|
||||
///
|
||||
/// <return>An `ElementModQ`</return>
|
||||
/// </summary>
|
||||
public unsafe ElementModQ GetHash()
|
||||
{
|
||||
var status = NativeInterface.EncryptionDevice.GetHash(Handle, out NativeElementModQ value);
|
||||
return new ElementModQ(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// produces encription device when given json
|
||||
/// </summary>
|
||||
/// <param name="json"></param>
|
||||
public unsafe EncryptionDevice(string json)
|
||||
{
|
||||
var status = NativeInterface.EncryptionDevice.FromJson(json, out Handle);
|
||||
status.ThrowIfError();
|
||||
}
|
||||
/// <Summary>
|
||||
/// Export the encryptiondevice representation as JSON
|
||||
/// </Summary>
|
||||
public unsafe string ToJson()
|
||||
{
|
||||
var status = NativeInterface.EncryptionDevice.ToJson(Handle, out IntPtr pointer, out ulong size);
|
||||
status.ThrowIfError();
|
||||
var json = Marshal.PtrToStringAnsi(pointer);
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
protected override unsafe void DisposeUnmanaged()
|
||||
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
|
||||
{
|
||||
base.DisposeUnmanaged();
|
||||
|
||||
if (Handle == null || Handle.IsInvalid) return;
|
||||
Handle.Dispose();
|
||||
Handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An object for caching election and encryption state.
|
||||
///
|
||||
/// the encryption mediator composes ballots by querying the encryption device
|
||||
/// for a hash of its metadata and incremental timestamps/
|
||||
///
|
||||
/// this is a convenience wrapper around the encrypt methods
|
||||
/// and may not be suitable for all use cases.
|
||||
/// </summary>
|
||||
public class EncryptionMediator : DisposableBase
|
||||
{
|
||||
internal unsafe NativeEncryptionMediator Handle;
|
||||
|
||||
/// <summary>
|
||||
/// Create an `EncryptionMediator` object
|
||||
/// </summary>
|
||||
/// <param name="manifest"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="device"></param>
|
||||
public unsafe EncryptionMediator(
|
||||
InternalManifest manifest,
|
||||
CiphertextElectionContext context,
|
||||
EncryptionDevice device)
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.New(
|
||||
manifest.Handle, context.Handle, device.Handle, out Handle);
|
||||
status.ThrowIfError();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt the specified ballot using the cached election context.
|
||||
/// </summary>
|
||||
public unsafe CiphertextBallot Encrypt(
|
||||
PlaintextBallot plaintext, bool verifyProofs = false)
|
||||
{
|
||||
if (verifyProofs)
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.EncryptAndVerify(
|
||||
Handle, plaintext.Handle, out NativeCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallot(ciphertext);
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.Encrypt(
|
||||
Handle, plaintext.Handle, out NativeCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallot(ciphertext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt the specified ballot into its compact form using the cached election context.
|
||||
/// </summary>
|
||||
public unsafe CompactCiphertextBallot CompactEncrypt(
|
||||
PlaintextBallot plaintext, bool verifyProofs = false)
|
||||
{
|
||||
if (verifyProofs)
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.CompactEncryptAndVerify(
|
||||
Handle, plaintext.Handle, out NativeCompactCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CompactCiphertextBallot(ciphertext);
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.CompactEncrypt(
|
||||
Handle, plaintext.Handle, out NativeCompactCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CompactCiphertextBallot(ciphertext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
protected override unsafe void DisposeUnmanaged()
|
||||
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
|
||||
{
|
||||
base.DisposeUnmanaged();
|
||||
|
||||
if (Handle == null || Handle.IsInvalid) return;
|
||||
Handle.Dispose();
|
||||
Handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metadata for encryption
|
||||
///
|
||||
/// The encrypt object is used for encrypting ballots.
|
||||
///
|
||||
/// </summary>
|
||||
public class Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Encrypt a specific `BallotSelection` in the context of a specific `BallotContest`
|
||||
/// </summary>
|
||||
/// <param name="plaintext">the selection in the valid input form</param>
|
||||
/// <param name="description">the `SelectionDescription` from the `ContestDescription`
|
||||
/// which defines this selection's structure</param>
|
||||
/// <param name="elgamalPublicKey">the public key (K) used to encrypt the ballot</param>
|
||||
/// <param name="cryptoExtendedBaseHash">the extended base hash of the election</param>
|
||||
/// <param name="nonceSeed">an `ElementModQ` used as a header to seed the `Nonce` generated
|
||||
/// for this selection. this value can be (or derived from) the
|
||||
/// Contest nonce, but no relationship is required</param>
|
||||
/// <param name="shouldVerifyProofs">specify if the proofs should be verified prior to returning (default True)</param>
|
||||
/// <returns>A `CiphertextBallotSelection`</returns>
|
||||
public static unsafe CiphertextBallotSelection Selection(
|
||||
PlaintextBallotSelection plaintext,
|
||||
SelectionDescription description,
|
||||
ElementModP elgamalPublicKey,
|
||||
ElementModQ cryptoExtendedBaseHash,
|
||||
ElementModQ nonceSeed,
|
||||
bool shouldVerifyProofs = true
|
||||
)
|
||||
{
|
||||
var status = NativeInterface.Encrypt.Selection(
|
||||
plaintext.Handle, description.Handle, elgamalPublicKey.Handle,
|
||||
cryptoExtendedBaseHash.Handle, nonceSeed.Handle, shouldVerifyProofs,
|
||||
out NativeCiphertextBallotSelection ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallotSelection(ciphertext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt a specific `BallotContest` in the context of a specific `Ballot`
|
||||
///
|
||||
/// This method accepts a contest representation that only includes `True` selections.
|
||||
/// It will fill missing selections for a contest with `False` values, and generate `placeholder`
|
||||
/// selections to represent the number of seats available for a given contest. By adding `placeholder`
|
||||
/// votes
|
||||
/// </summary>
|
||||
/// <param name="plaintext">the selection in the valid input form</param>
|
||||
/// <param name="description">the `ContestDescriptionWithPlaceholders` from the `ContestDescription`
|
||||
/// which defines this contest's structure</param>
|
||||
/// <param name="elgamalPublicKey">the public key (K) used to encrypt the ballot</param>
|
||||
/// <param name="cryptoExtendedBaseHash">the extended base hash of the election</param>
|
||||
/// <param name="nonceSeed">an `ElementModQ` used as a header to seed the `Nonce` generated
|
||||
/// for this contest. this value can be (or derived from) the
|
||||
/// Ballot nonce, but no relationship is required</param>
|
||||
/// <param name="shouldVerifyProofs">specify if the proofs should be verified prior to returning (default True)</param>
|
||||
/// <returns>A `CiphertextBallotContest`</returns>
|
||||
public static unsafe CiphertextBallotContest Contest(
|
||||
PlaintextBallotContest plaintext,
|
||||
ContestDescription description,
|
||||
ElementModP elgamalPublicKey,
|
||||
ElementModQ cryptoExtendedBaseHash,
|
||||
ElementModQ nonceSeed,
|
||||
bool shouldVerifyProofs = true
|
||||
)
|
||||
{
|
||||
var status = NativeInterface.Encrypt.Contest(
|
||||
plaintext.Handle, description.Handle, elgamalPublicKey.Handle,
|
||||
cryptoExtendedBaseHash.Handle, nonceSeed.Handle, shouldVerifyProofs,
|
||||
out NativeCiphertextBallotContest ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallotContest(ciphertext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt a specific `Ballot` in the context of a specific `CiphertextElectionContext`
|
||||
///
|
||||
/// This method accepts a ballot representation that only includes `True` selections.
|
||||
/// It will fill missing selections for a contest with `False` values, and generate `placeholder`
|
||||
/// selections to represent the number of seats available for a given contest. By adding `placeholder`
|
||||
/// votes
|
||||
///
|
||||
/// This method also allows for ballots to exclude passing contests for which the voter made no selections.
|
||||
/// It will fill missing contests with `False` selections and generate `placeholder` selections that are marked `True`.
|
||||
/// </summary>
|
||||
/// <param name="ballot">the selection in the valid input form</param>
|
||||
/// <param name="internalManifest">the `InternalManifest` which defines this ballot's structure</param>
|
||||
/// <param name="context">all the cryptographic context for the election</param>
|
||||
/// <param name="ballotCodeSeed">Hash from previous ballot or hash from device</param>
|
||||
/// <param name="nonce">an optional value used to seed the `Nonce` generated for this ballot
|
||||
/// if this value is not provided, the secret generating mechanism of the OS provides its own</param>
|
||||
/// <param name="shouldVerifyProofs">specify if the proofs should be verified prior to returning (default True)</param>
|
||||
/// <returns>A `CiphertextBallot`</returns>
|
||||
public static unsafe CiphertextBallot Ballot(
|
||||
PlaintextBallot ballot,
|
||||
InternalManifest internalManifest,
|
||||
CiphertextElectionContext context,
|
||||
ElementModQ ballotCodeSeed,
|
||||
ElementModQ nonce = null,
|
||||
bool shouldVerifyProofs = true)
|
||||
{
|
||||
if (nonce == null)
|
||||
{
|
||||
var status = NativeInterface.Encrypt.Ballot(
|
||||
ballot.Handle, internalManifest.Handle, context.Handle,
|
||||
ballotCodeSeed.Handle, shouldVerifyProofs,
|
||||
out NativeCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallot(ciphertext);
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = NativeInterface.Encrypt.Ballot(
|
||||
ballot.Handle, internalManifest.Handle, context.Handle,
|
||||
ballotCodeSeed.Handle, nonce.Handle, shouldVerifyProofs,
|
||||
out NativeCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallot(ciphertext);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt a specific `Ballot` in the context of a specific `CiphertextElectionContext`
|
||||
///
|
||||
/// This method accepts a ballot representation that only includes `True` selections.
|
||||
/// It will fill missing selections for a contest with `False` values, and generate `placeholder`
|
||||
/// selections to represent the number of seats available for a given contest. By adding `placeholder`
|
||||
/// votes
|
||||
///
|
||||
/// This method also allows for ballots to exclude passing contests for which the voter made no selections.
|
||||
/// It will fill missing contests with `False` selections and generate `placeholder` selections that are marked `True`.
|
||||
///
|
||||
/// This version of the encrypt method returns a `compact` version of the ballot that includes a minimal representation
|
||||
/// of the plaintext ballot along with the crypto parameters that are required to expand the ballot
|
||||
/// </summary>
|
||||
/// <param name="ballot">the selection in the valid input form</param>
|
||||
/// <param name="internalManifest">the `InternalManifest` which defines this ballot's structure</param>
|
||||
/// <param name="context">all the cryptographic context for the election</param>
|
||||
/// <param name="ballotCodeSeed">Hash from previous ballot or hash from device</param>
|
||||
/// <param name="nonce">an optional value used to seed the `Nonce` generated for this ballot
|
||||
/// if this value is not provided, the secret generating mechanism of the OS provides its own</param>
|
||||
/// <param name="shouldVerifyProofs">specify if the proofs should be verified prior to returning (default True)</param>
|
||||
/// <returns>A `CiphertextBallot`</returns>
|
||||
public static unsafe CompactCiphertextBallot CompactBallot(
|
||||
PlaintextBallot ballot,
|
||||
InternalManifest internalManifest,
|
||||
CiphertextElectionContext context,
|
||||
ElementModQ ballotCodeSeed,
|
||||
ElementModQ nonce = null,
|
||||
bool shouldVerifyProofs = true)
|
||||
{
|
||||
if (nonce == null)
|
||||
{
|
||||
var status = NativeInterface.Encrypt.CompactBallot(
|
||||
ballot.Handle, internalManifest.Handle, context.Handle,
|
||||
ballotCodeSeed.Handle, shouldVerifyProofs,
|
||||
out NativeCompactCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CompactCiphertextBallot(ciphertext);
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = NativeInterface.Encrypt.CompactBallot(
|
||||
ballot.Handle, internalManifest.Handle, context.Handle,
|
||||
ballotCodeSeed.Handle, nonce.Handle, shouldVerifyProofs,
|
||||
out NativeCompactCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CompactCiphertextBallot(ciphertext);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ElectionGuard
|
||||
{
|
||||
using NativeElementModQ = NativeInterface.ElementModQ.ElementModQHandle;
|
||||
using NativeEncryptionDevice = NativeInterface.EncryptionDevice.EncryptionDeviceHandle;
|
||||
using NativeEncryptionMediator = NativeInterface.EncryptionMediator.EncryptionMediatorHandle;
|
||||
using NativeCiphertextBallot = NativeInterface.CiphertextBallot.CiphertextBallotHandle;
|
||||
using NativeCiphertextBallotContest = NativeInterface.CiphertextBallotContest.CiphertextBallotContestHandle;
|
||||
using NativeCiphertextBallotSelection = NativeInterface.CiphertextBallotSelection.CiphertextBallotSelectionHandle;
|
||||
using NativeCompactCiphertextBallot = NativeInterface.CompactCiphertextBallot.CompactCiphertextBallotHandle;
|
||||
|
||||
/// <summary>
|
||||
/// Metadata for encryption device
|
||||
///
|
||||
/// The encryption device is a stateful container that represents abstract hardware
|
||||
/// authorized to participate in a specific election.
|
||||
///
|
||||
/// </summary>
|
||||
public class EncryptionDevice : DisposableBase
|
||||
{
|
||||
internal unsafe NativeEncryptionDevice Handle;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new EncryptionDevice
|
||||
/// </summary>
|
||||
/// <param name="deviceUuid">a unique identifier tied to the device hardware</param>
|
||||
/// <param name="sessionUuid">a unique identifier tied to the runtime session</param>
|
||||
/// <param name="launchCode">a unique identifer tied to the election</param>
|
||||
/// <param name="location">an arbitrary string meaningful to the external system
|
||||
/// such as a friendly name, description, or some other value</param>
|
||||
public unsafe EncryptionDevice(
|
||||
ulong deviceUuid,
|
||||
ulong sessionUuid,
|
||||
ulong launchCode,
|
||||
string location)
|
||||
{
|
||||
var status = NativeInterface.EncryptionDevice.New(
|
||||
deviceUuid, sessionUuid, launchCode, location, out Handle);
|
||||
status.ThrowIfError();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a new hash value
|
||||
///
|
||||
/// <return>An `ElementModQ`</return>
|
||||
/// </summary>
|
||||
public unsafe ElementModQ GetHash()
|
||||
{
|
||||
var status = NativeInterface.EncryptionDevice.GetHash(Handle, out NativeElementModQ value);
|
||||
return new ElementModQ(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// produces encription device when given json
|
||||
/// </summary>
|
||||
/// <param name="json"></param>
|
||||
public unsafe EncryptionDevice(string json)
|
||||
{
|
||||
var status = NativeInterface.EncryptionDevice.FromJson(json, out Handle);
|
||||
status.ThrowIfError();
|
||||
}
|
||||
/// <Summary>
|
||||
/// Export the encryptiondevice representation as JSON
|
||||
/// </Summary>
|
||||
public unsafe string ToJson()
|
||||
{
|
||||
var status = NativeInterface.EncryptionDevice.ToJson(Handle, out IntPtr pointer, out ulong size);
|
||||
status.ThrowIfError();
|
||||
var json = Marshal.PtrToStringAnsi(pointer);
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
protected override unsafe void DisposeUnmanaged()
|
||||
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
|
||||
{
|
||||
base.DisposeUnmanaged();
|
||||
|
||||
if (Handle == null || Handle.IsInvalid) return;
|
||||
Handle.Dispose();
|
||||
Handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An object for caching election and encryption state.
|
||||
///
|
||||
/// the encryption mediator composes ballots by querying the encryption device
|
||||
/// for a hash of its metadata and incremental timestamps/
|
||||
///
|
||||
/// this is a convenience wrapper around the encrypt methods
|
||||
/// and may not be suitable for all use cases.
|
||||
/// </summary>
|
||||
public class EncryptionMediator : DisposableBase
|
||||
{
|
||||
internal unsafe NativeEncryptionMediator Handle;
|
||||
|
||||
/// <summary>
|
||||
/// Create an `EncryptionMediator` object
|
||||
/// </summary>
|
||||
/// <param name="manifest"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="device"></param>
|
||||
public unsafe EncryptionMediator(
|
||||
InternalManifest manifest,
|
||||
CiphertextElectionContext context,
|
||||
EncryptionDevice device)
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.New(
|
||||
manifest.Handle, context.Handle, device.Handle, out Handle);
|
||||
status.ThrowIfError();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt the specified ballot using the cached election context.
|
||||
/// </summary>
|
||||
public unsafe CiphertextBallot Encrypt(
|
||||
PlaintextBallot plaintext, bool verifyProofs = false)
|
||||
{
|
||||
if (verifyProofs)
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.EncryptAndVerify(
|
||||
Handle, plaintext.Handle, out NativeCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallot(ciphertext);
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.Encrypt(
|
||||
Handle, plaintext.Handle, out NativeCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallot(ciphertext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt the specified ballot into its compact form using the cached election context.
|
||||
/// </summary>
|
||||
public unsafe CompactCiphertextBallot CompactEncrypt(
|
||||
PlaintextBallot plaintext, bool verifyProofs = false)
|
||||
{
|
||||
if (verifyProofs)
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.CompactEncryptAndVerify(
|
||||
Handle, plaintext.Handle, out NativeCompactCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CompactCiphertextBallot(ciphertext);
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = NativeInterface.EncryptionMediator.CompactEncrypt(
|
||||
Handle, plaintext.Handle, out NativeCompactCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CompactCiphertextBallot(ciphertext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
protected override unsafe void DisposeUnmanaged()
|
||||
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
|
||||
{
|
||||
base.DisposeUnmanaged();
|
||||
|
||||
if (Handle == null || Handle.IsInvalid) return;
|
||||
Handle.Dispose();
|
||||
Handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metadata for encryption
|
||||
///
|
||||
/// The encrypt object is used for encrypting ballots.
|
||||
///
|
||||
/// </summary>
|
||||
public class Encrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// Encrypt a specific `BallotSelection` in the context of a specific `BallotContest`
|
||||
/// </summary>
|
||||
/// <param name="plaintext">the selection in the valid input form</param>
|
||||
/// <param name="description">the `SelectionDescription` from the `ContestDescription`
|
||||
/// which defines this selection's structure</param>
|
||||
/// <param name="elgamalPublicKey">the public key (K) used to encrypt the ballot</param>
|
||||
/// <param name="cryptoExtendedBaseHash">the extended base hash of the election</param>
|
||||
/// <param name="nonceSeed">an `ElementModQ` used as a header to seed the `Nonce` generated
|
||||
/// for this selection. this value can be (or derived from) the
|
||||
/// Contest nonce, but no relationship is required</param>
|
||||
/// <param name="shouldVerifyProofs">specify if the proofs should be verified prior to returning (default True)</param>
|
||||
/// <returns>A `CiphertextBallotSelection`</returns>
|
||||
public static unsafe CiphertextBallotSelection Selection(
|
||||
PlaintextBallotSelection plaintext,
|
||||
SelectionDescription description,
|
||||
ElementModP elgamalPublicKey,
|
||||
ElementModQ cryptoExtendedBaseHash,
|
||||
ElementModQ nonceSeed,
|
||||
bool shouldVerifyProofs = true
|
||||
)
|
||||
{
|
||||
var status = NativeInterface.Encrypt.Selection(
|
||||
plaintext.Handle, description.Handle, elgamalPublicKey.Handle,
|
||||
cryptoExtendedBaseHash.Handle, nonceSeed.Handle, shouldVerifyProofs,
|
||||
out NativeCiphertextBallotSelection ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallotSelection(ciphertext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt a specific `BallotContest` in the context of a specific `Ballot`
|
||||
///
|
||||
/// This method accepts a contest representation that only includes `True` selections.
|
||||
/// It will fill missing selections for a contest with `False` values, and generate `placeholder`
|
||||
/// selections to represent the number of seats available for a given contest. By adding `placeholder`
|
||||
/// votes
|
||||
/// </summary>
|
||||
/// <param name="plaintext">the selection in the valid input form</param>
|
||||
/// <param name="description">the `ContestDescriptionWithPlaceholders` from the `ContestDescription`
|
||||
/// which defines this contest's structure</param>
|
||||
/// <param name="elgamalPublicKey">the public key (K) used to encrypt the ballot</param>
|
||||
/// <param name="cryptoExtendedBaseHash">the extended base hash of the election</param>
|
||||
/// <param name="nonceSeed">an `ElementModQ` used as a header to seed the `Nonce` generated
|
||||
/// for this contest. this value can be (or derived from) the
|
||||
/// Ballot nonce, but no relationship is required</param>
|
||||
/// <param name="shouldVerifyProofs">specify if the proofs should be verified prior to returning (default True)</param>
|
||||
/// <returns>A `CiphertextBallotContest`</returns>
|
||||
public static unsafe CiphertextBallotContest Contest(
|
||||
PlaintextBallotContest plaintext,
|
||||
ContestDescription description,
|
||||
ElementModP elgamalPublicKey,
|
||||
ElementModQ cryptoExtendedBaseHash,
|
||||
ElementModQ nonceSeed,
|
||||
bool shouldVerifyProofs = true
|
||||
)
|
||||
{
|
||||
var status = NativeInterface.Encrypt.Contest(
|
||||
plaintext.Handle, description.Handle, elgamalPublicKey.Handle,
|
||||
cryptoExtendedBaseHash.Handle, nonceSeed.Handle, shouldVerifyProofs,
|
||||
out NativeCiphertextBallotContest ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallotContest(ciphertext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt a specific `Ballot` in the context of a specific `CiphertextElectionContext`
|
||||
///
|
||||
/// This method accepts a ballot representation that only includes `True` selections.
|
||||
/// It will fill missing selections for a contest with `False` values, and generate `placeholder`
|
||||
/// selections to represent the number of seats available for a given contest. By adding `placeholder`
|
||||
/// votes
|
||||
///
|
||||
/// This method also allows for ballots to exclude passing contests for which the voter made no selections.
|
||||
/// It will fill missing contests with `False` selections and generate `placeholder` selections that are marked `True`.
|
||||
/// </summary>
|
||||
/// <param name="ballot">the selection in the valid input form</param>
|
||||
/// <param name="internalManifest">the `InternalManifest` which defines this ballot's structure</param>
|
||||
/// <param name="context">all the cryptographic context for the election</param>
|
||||
/// <param name="ballotCodeSeed">Hash from previous ballot or hash from device</param>
|
||||
/// <param name="nonce">an optional value used to seed the `Nonce` generated for this ballot
|
||||
/// if this value is not provided, the secret generating mechanism of the OS provides its own</param>
|
||||
/// <param name="shouldVerifyProofs">specify if the proofs should be verified prior to returning (default True)</param>
|
||||
/// <returns>A `CiphertextBallot`</returns>
|
||||
public static unsafe CiphertextBallot Ballot(
|
||||
PlaintextBallot ballot,
|
||||
InternalManifest internalManifest,
|
||||
CiphertextElectionContext context,
|
||||
ElementModQ ballotCodeSeed,
|
||||
ElementModQ nonce = null,
|
||||
bool shouldVerifyProofs = true)
|
||||
{
|
||||
if (nonce == null)
|
||||
{
|
||||
var status = NativeInterface.Encrypt.Ballot(
|
||||
ballot.Handle, internalManifest.Handle, context.Handle,
|
||||
ballotCodeSeed.Handle, shouldVerifyProofs,
|
||||
out NativeCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallot(ciphertext);
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = NativeInterface.Encrypt.Ballot(
|
||||
ballot.Handle, internalManifest.Handle, context.Handle,
|
||||
ballotCodeSeed.Handle, nonce.Handle, shouldVerifyProofs,
|
||||
out NativeCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CiphertextBallot(ciphertext);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encrypt a specific `Ballot` in the context of a specific `CiphertextElectionContext`
|
||||
///
|
||||
/// This method accepts a ballot representation that only includes `True` selections.
|
||||
/// It will fill missing selections for a contest with `False` values, and generate `placeholder`
|
||||
/// selections to represent the number of seats available for a given contest. By adding `placeholder`
|
||||
/// votes
|
||||
///
|
||||
/// This method also allows for ballots to exclude passing contests for which the voter made no selections.
|
||||
/// It will fill missing contests with `False` selections and generate `placeholder` selections that are marked `True`.
|
||||
///
|
||||
/// This version of the encrypt method returns a `compact` version of the ballot that includes a minimal representation
|
||||
/// of the plaintext ballot along with the crypto parameters that are required to expand the ballot
|
||||
/// </summary>
|
||||
/// <param name="ballot">the selection in the valid input form</param>
|
||||
/// <param name="internalManifest">the `InternalManifest` which defines this ballot's structure</param>
|
||||
/// <param name="context">all the cryptographic context for the election</param>
|
||||
/// <param name="ballotCodeSeed">Hash from previous ballot or hash from device</param>
|
||||
/// <param name="nonce">an optional value used to seed the `Nonce` generated for this ballot
|
||||
/// if this value is not provided, the secret generating mechanism of the OS provides its own</param>
|
||||
/// <param name="shouldVerifyProofs">specify if the proofs should be verified prior to returning (default True)</param>
|
||||
/// <returns>A `CiphertextBallot`</returns>
|
||||
public static unsafe CompactCiphertextBallot CompactBallot(
|
||||
PlaintextBallot ballot,
|
||||
InternalManifest internalManifest,
|
||||
CiphertextElectionContext context,
|
||||
ElementModQ ballotCodeSeed,
|
||||
ElementModQ nonce = null,
|
||||
bool shouldVerifyProofs = true)
|
||||
{
|
||||
if (nonce == null)
|
||||
{
|
||||
var status = NativeInterface.Encrypt.CompactBallot(
|
||||
ballot.Handle, internalManifest.Handle, context.Handle,
|
||||
ballotCodeSeed.Handle, shouldVerifyProofs,
|
||||
out NativeCompactCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CompactCiphertextBallot(ciphertext);
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = NativeInterface.Encrypt.CompactBallot(
|
||||
ballot.Handle, internalManifest.Handle, context.Handle,
|
||||
ballotCodeSeed.Handle, nonce.Handle, shouldVerifyProofs,
|
||||
out NativeCompactCiphertextBallot ciphertext);
|
||||
status.ThrowIfError();
|
||||
return new CompactCiphertextBallot(ciphertext);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31613.86
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32519.379
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectionGuard.Encryption", "ElectionGuard.Encryption\ElectionGuard.Encryption.csproj", "{A4437B27-1101-4C91-AEBE-F97606990E2B}"
|
||||
EndProject
|
||||
|
@ -16,46 +16,78 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectionGuard.Encryption.Be
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectionGuard.Encryption.Utils", "ElectionGuard.Encryption.Utils\ElectionGuard.Encryption.Utils.csproj", "{6AC780D0-1862-4680-8B47-AD6CCF97B66C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectionGuard.Encryption.Cli", "ElectionGuard.Encryption.Cli\ElectionGuard.Encryption.Cli.csproj", "{A7289C54-F777-45EA-A6E8-9C7605706CBE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Debug|x64.Build.0 = Debug|x64
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Debug|x86.Build.0 = Debug|x86
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Release|Any CPU.Build.0 = Release|x64
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Release|x64.ActiveCfg = Release|x64
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Release|x64.Build.0 = Release|x64
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Release|x86.ActiveCfg = Release|x86
|
||||
{A4437B27-1101-4C91-AEBE-F97606990E2B}.Release|x86.Build.0 = Release|x86
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Debug|x64.Build.0 = Debug|x64
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Debug|x86.Build.0 = Debug|x86
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Release|Any CPU.Build.0 = Release|x64
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Release|x64.ActiveCfg = Release|x64
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Release|x64.Build.0 = Release|x64
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Release|x86.ActiveCfg = Release|x86
|
||||
{111BE643-7978-4CDB-9FDC-0A198139A488}.Release|x86.Build.0 = Release|x86
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Debug|x64.Build.0 = Debug|x64
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Debug|x86.Build.0 = Debug|x86
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Release|Any CPU.Build.0 = Release|x64
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Release|x64.ActiveCfg = Release|x64
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Release|x64.Build.0 = Release|x64
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Release|x86.ActiveCfg = Release|x86
|
||||
{06B6E480-D964-4351-8FF3-E62F652B8D4C}.Release|x86.Build.0 = Release|x86
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Debug|x64.Build.0 = Debug|x64
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Debug|x86.Build.0 = Debug|x86
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Release|Any CPU.Build.0 = Release|x64
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Release|x64.ActiveCfg = Release|x64
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Release|x64.Build.0 = Release|x64
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Release|x86.ActiveCfg = Release|x86
|
||||
{6AC780D0-1862-4680-8B47-AD6CCF97B66C}.Release|x86.Build.0 = Release|x86
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A7289C54-F777-45EA-A6E8-9C7605706CBE}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Загрузка…
Ссылка в новой задаче