/// <summary> /// Encrypts the ballot selections /// </summary> /// <param name="selections"></param> /// <param name="expectedNumberOfSelected"></param> /// <param name="electionGuardConfig"></param> /// <param name="externalIdentifier"></param> /// <param name="exportPath"></param> /// <param name="exportFileName"></param> /// <returns>EncryptBallotResult containing the encrypted ballot, its external id, its tracker string, /// and the file that includes the ballot</returns> public static EncryptBallotResult EncryptBallot( bool[] selections, int expectedNumberOfSelected, ElectionGuardConfig electionGuardConfig, string externalIdentifier, string exportPath = "./", string exportFileName = "") { var apiConfig = electionGuardConfig.GetApiConfig(); var serializedBytesWithGcHandle = ByteSerializer.ConvertFromBase64String(electionGuardConfig.JointPublicKey); apiConfig.SerializedJointPublicKey = serializedBytesWithGcHandle.SerializedBytes; var encryptedBallotMessage = new SerializedBytes(); var trackerPtr = new IntPtr(); try { var success = API.EncryptBallot( selections.Select(b => (byte)(b ? 1 : 0)).ToArray(), (uint)expectedNumberOfSelected, apiConfig, externalIdentifier, out encryptedBallotMessage, exportPath, exportFileName, out IntPtr outputFilename, out trackerPtr); if (!success) { throw new Exception("ElectionGuardAPI EncryptBallot failed"); } var result = new EncryptBallotResult() { ExternalIdentifier = externalIdentifier, EncryptedBallotMessage = ByteSerializer.ConvertToBase64String(encryptedBallotMessage), Tracker = Marshal.PtrToStringAnsi(trackerPtr), OutputFileName = Marshal.PtrToStringAnsi(outputFilename), }; return(result); } finally { // Free unmanaged memory API.FreeEncryptBallot(encryptedBallotMessage, trackerPtr); serializedBytesWithGcHandle.Handle.Free(); } }
/// <summary> /// CreateElection entry point - performs the initial KeyCeremony process to generate public keys and trustee keys /// </summary> /// <param name="initialConfig"></param> /// <returns>CreateElectionResult containing the private trustee keys and /// the updated ElectionGuardConfig with the public key</returns> public static CreateElectionResult CreateElection(ElectionGuardConfig initialConfig) { var apiConfig = initialConfig.GetApiConfig(); // Set up trustee states array to be allocated in the api var trusteeStates = new SerializedBytes[Constants.MaxTrustees]; try { // Call the C library API to create the election and get back the joint public key bytes // The trusteeStates array should be filled out with the appropriate serialized returns as well var success = API.CreateElection(ref apiConfig, trusteeStates); if (!success) { throw new Exception("ElectionGuardAPI CreateElection failed"); } var electionGuardConfig = new ElectionGuardConfig(apiConfig); var trusteeKeys = new Dictionary <int, string>(); // Iterate through the trusteeStates returned and convert each to its base64 representation for (var i = 0; i < trusteeStates.Length; i++) { var trusteeState = trusteeStates[i]; if (trusteeState.Length > 0) { var trusteeStateKeys = ByteSerializer.ConvertToBase64String(trusteeState); trusteeKeys.Add(i, trusteeStateKeys); } } return(new CreateElectionResult() { ElectionGuardConfig = electionGuardConfig, TrusteeKeys = trusteeKeys }); } finally { // Free bytes in unmanaged memory API.FreeCreateElection(apiConfig.SerializedJointPublicKey, trusteeStates); } }
/// <summary> /// Loads a ballot file from the file system and batch processes the specified number of ballots starting at the specified index. /// </summary> /// <param name="startIndex">The start index of the ballots in the file to load into memory</param> /// <param name="count">The count of ballots to load into memory</param> /// <param name="numberOfSelections">The expected number of selections in each ballot being loaded into memory</param> /// <param name="importFilePath">the fully qualified file path of the file containing ballots to load</param> /// <param name="externalIdentifiers">output of the external identifiers of the ballots loaded</param> /// <param name="encryptedBallotMessage">output of the encrypted ballots loaded</param> /// <returns>an integer status code mapped to an enum array signaling success or failure state</returns> public static LoadBallotsResult LoadBallotsFile( long startIndex, long count, long numberOfSelections, string importFilePath) { var externalIdentifiers = new IntPtr[count]; var encryptedBallotMessages = new SerializedBytes[count]; try { var status = (LoadBallotsStatus)API.LoadBallotsFile( (ulong)startIndex, (ulong)count, (ulong)numberOfSelections, importFilePath, externalIdentifiers, encryptedBallotMessages ); if (status != LoadBallotsStatus.Success) { throw new Exception($"ElectionGuardAPI LoadBallotsFile failed: {status}"); } var result = new LoadBallotsResult() { ExternalIdentifiers = externalIdentifiers .Select(p => Marshal.PtrToStringAnsi(p)) .Where(s => !string.IsNullOrWhiteSpace(s)) .ToList(), EncryptedBallotMessages = encryptedBallotMessages .Where(p => p.Length > 0) .Select(p => ByteSerializer.ConvertToBase64String(p)) .ToList() }; return(result); } finally { // Free unmanaged memory API.FreeLoadBallotsFile(null); } }