Skip to content

Latest commit

 

History

History
869 lines (691 loc) · 31 KB

File metadata and controls

869 lines (691 loc) · 31 KB

Secure Voting System

Government-grade voting system built on node-ecies-lib with comprehensive cryptographic security and exhaustive testing. Node.js optimized with native crypto and Buffer support.

Features

✅ Fully Secure Methods (Single-round, Privacy-preserving)

  • Plurality - First-past-the-post (most common) ✅ Fully Implemented
  • Approval - Vote for multiple candidates ✅ Fully Implemented
  • Weighted - Stakeholder voting with configurable limits ✅ Fully Implemented
  • Borda Count - Ranked voting with point allocation ✅ Fully Implemented
  • Score Voting - Rate candidates 0-10 ✅ Fully Implemented
  • Yes/No - Referendums and ballot measures ✅ Fully Implemented
  • Yes/No/Abstain - With abstention option ✅ Fully Implemented
  • Supermajority - Requires 2/3 or 3/4 threshold ✅ Fully Implemented

⚠️ Multi-Round Methods (Requires intermediate decryption)

  • Ranked Choice (IRV) - Instant runoff with elimination ✅ Fully Implemented
  • Two-Round - Top 2 runoff election ✅ Fully Implemented
  • STAR - Score Then Automatic Runoff ✅ Fully Implemented
  • STV - Single Transferable Vote (proportional representation) ✅ Fully Implemented

❌ Insecure Methods (No privacy - for special cases only)

  • Quadratic - Quadratic voting (requires non-homomorphic operations) ✅ Fully Implemented
  • Consensus - Requires 95%+ agreement ✅ Fully Implemented
  • Consent-Based - Sociocracy-style (no strong objections) ✅ Fully Implemented

Core Security Features

  • Homomorphic Encryption - Votes remain encrypted until tally using Paillier cryptosystem
  • Threshold Decryption - Distributed trust with k-of-n Guardians; no single party can decrypt alone
  • Real-Time Tallies - Configurable interval decryption during voting with ZK proofs
  • Verifiable Receipts - Cryptographically signed confirmations with ECDSA
  • Public Bulletin Board - Transparent, append-only vote publication with Merkle tree integrity
  • Immutable Audit Log - Cryptographic hash chain for all operations
  • Event Logger - Comprehensive event tracking with microsecond timestamps and sequence numbers
  • Role Separation - Poll aggregator cannot decrypt votes (separate PollTallier)
  • Double-Vote Prevention - Each member votes once per poll
  • Attack Resistance - Tested against manipulation attempts
  • Node.js Optimized - Uses native crypto module and Buffer for performance
  • Government-Grade Testing - 1100+ test cases covering all methods and edge cases

Architecture

Role Separation

┌─────────────────────────────────────────────────────────────┐
│                    SECURE ARCHITECTURE                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Poll (Vote Aggregator)                                     │
│  ├─ Paillier PUBLIC key only  ← encrypts & aggregates      │
│  ├─ Authority's EC keys       ← signs receipts              │
│  └─ Cannot decrypt votes                                    │
│                                                              │
│  PollTallier (Separate Entity)                              │
│  ├─ Paillier PRIVATE key      ← decrypts ONLY after close  │
│  └─ Computes results                                        │
│                                                              │
│  Voter (Member from node-ecies-lib)                         │
│  ├─ EC keypair                ← verifies receipts           │
│  └─ Voting public key         ← encrypts votes              │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Key Components

  1. Poll (poll-core.ts) - Aggregates encrypted votes, issues receipts, enforces rules
  2. VotingPoll (poll.ts) - High-level voting with encrypted receipts
  3. PollTallier (tallier.ts) - Holds private key, decrypts results after close
  4. VoteEncoder (encoder.ts) - Encrypts votes using Paillier homomorphic encryption
  5. PollFactory (factory.ts) - Convenient poll creation with method-specific configurations
  6. ImmutableAuditLog (audit.ts) - Cryptographic hash chain for audit trail (Requirement 1.1)
  7. PublicBulletinBoard (bulletin-board.ts) - Transparent, append-only vote publication (Requirement 1.2)
  8. PollEventLogger (event-logger.ts) - Comprehensive event tracking (Requirement 1.3)
  9. VotingSecurityValidator (security.ts) - Security level validation and enforcement

Voting Methods

All Methods Fully Implemented ✅

All 17 voting methods are fully implemented with:

  • VoteEncoder: Inherits generic encode() method from ecies-lib that supports all voting methods
  • PollFactory: Dedicated methods for core types (createPlurality, createApproval, etc.) and generic create() method for all methods
  • Node.js Optimization: Uses Buffer instead of Uint8Array for better Node.js performance
  • Complete Testing: Full test coverage for all methods and security levels
  • Cross-Platform Compatibility: 100% compatible with browser implementation

Currently Implemented Methods

✅ Fully Homomorphic (Single-round, Privacy-preserving)

  • Plurality - createPlurality() / encode(VotingMethod.Plurality, ...)
  • Approval - createApproval() / encode(VotingMethod.Approval, ...)
  • Weighted - createWeighted() / encode(VotingMethod.Weighted, ...)
  • Borda Count - createBorda() / encode(VotingMethod.Borda, ...)
  • Score Voting - create(..., VotingMethod.Score, ...) / encode(VotingMethod.Score, ...)
  • Yes/No - create(..., VotingMethod.YesNo, ...) / encode(VotingMethod.YesNo, ...)
  • Yes/No/Abstain - create(..., VotingMethod.YesNoAbstain, ...) / encode(VotingMethod.YesNoAbstain, ...)
  • Supermajority - create(..., VotingMethod.Supermajority, ...) / encode(VotingMethod.Supermajority, ...)

⚠️ Multi-Round (Requires intermediate decryption)

  • Ranked Choice (IRV) - createRankedChoice() / encode(VotingMethod.RankedChoice, ...)
  • Two-Round - create(..., VotingMethod.TwoRound, ...) / encode(VotingMethod.TwoRound, ...)
  • STAR - create(..., VotingMethod.STAR, ...) / encode(VotingMethod.STAR, ...)
  • STV - create(..., VotingMethod.STV, ...) / encode(VotingMethod.STV, ...)

❌ Insecure (For special cases only)

  • Quadratic - create(..., VotingMethod.Quadratic, ...) / encode(VotingMethod.Quadratic, ...)
  • Consensus - create(..., VotingMethod.Consensus, ...) / encode(VotingMethod.Consensus, ...)
  • Consent-Based - create(..., VotingMethod.ConsentBased, ...) / encode(VotingMethod.ConsentBased, ...)

Implementation Architecture

The Node.js voting system uses a flexible architecture that extends the browser implementation:

  1. Inherited Methods: Core voting methods inherit from @digitaldefiance/ecies-lib base classes
  2. Buffer Specialization: All binary data uses Node.js Buffer instead of Uint8Array
  3. Generic Support: The generic encode() method handles all 17 voting methods
  4. Dedicated Factories: Core methods have dedicated factory methods for convenience
  5. Cross-Platform: 100% binary compatible with browser implementation
import { VotingSecurityValidator, SecurityLevel, VotingMethod } from '@digitaldefiance/node-ecies-lib';

// Check security level
const level = VotingSecurityValidator.getSecurityLevel(VotingMethod.Plurality);
// Returns: SecurityLevel.FullyHomomorphic

// Validate before use
VotingSecurityValidator.validate(VotingMethod.Quadratic); // Throws error
VotingSecurityValidator.validate(VotingMethod.Quadratic, { allowInsecure: true }); // OK

Method Comparison

Method Security Implementation Status Use Case Multi-Winner
Plurality ✅ Full ✅ Complete General elections No
Approval ✅ Full ✅ Complete Committee selection No
Weighted ✅ Full ✅ Complete Shareholder voting No
Borda ✅ Full ✅ Complete Ranked preferences No
Score ✅ Full ✅ Complete Rating candidates No
YesNo ✅ Full ✅ Complete Referendums No
YesNoAbstain ✅ Full ✅ Complete Referendums with abstention No
Supermajority ✅ Full ✅ Complete Constitutional changes No
RankedChoice ⚠️ Multi ✅ Complete Modern elections No
TwoRound ⚠️ Multi ✅ Complete Presidential elections No
STAR ⚠️ Multi ✅ Complete Hybrid score/runoff No
STV ⚠️ Multi ✅ Complete Proportional representation Yes
Quadratic ❌ None ✅ Complete Budget allocation No
Consensus ❌ None ✅ Complete Small groups No
ConsentBased ❌ None ✅ Complete Cooperatives No

Government Requirements (EARS Specification)

1.1 Immutable Audit Log ✅

import { ImmutableAuditLog } from '@digitaldefiance/node-ecies-lib';

const auditLog = new ImmutableAuditLog(authority);

// Record poll creation
auditLog.recordPollCreated(pollId, { choices: ['A', 'B'] });

// Record vote cast
auditLog.recordVoteCast(pollId, voterIdHash);

// Record poll closure
auditLog.recordPollClosed(pollId, { finalTally: [100n, 200n] });

// Verify chain integrity
const isValid = auditLog.verifyChain();

Features:

  • Cryptographically signed entries
  • Hash-chained for immutability
  • Microsecond-precision timestamps
  • Verifiable chain of custody

1.2 Public Bulletin Board ✅

import { PublicBulletinBoard } from '@digitaldefiance/node-ecies-lib';

const board = new PublicBulletinBoard(authority);

// Publish encrypted vote
const entry = board.publishVote(pollId, encryptedVote, voterIdHash);

// Publish tally with proof
const proof = board.publishTally(
  pollId,
  tallies,
  choices,
  encryptedVotes
);

// Any observer can download and verify
const allEntries = board.getAllEntries();
const isValid = board.verifyEntry(entry);
const isTallyValid = board.verifyTallyProof(proof);

// Export for archival
const archive = board.export();

Features:

  • Append-only publication
  • Merkle tree for structural integrity
  • Zero-knowledge proofs of correct decryption
  • Public verification by any observer
  • Complete export for archival

1.3 Event Logging ✅

import { PollEventLogger, EventType } from '@digitaldefiance/node-ecies-lib';

const eventLogger = new PollEventLogger();

// Log poll creation
eventLogger.logPollCreated(pollId, creatorId, {
  method: 'plurality',
  choices: ['Alice', 'Bob', 'Charlie'],
});

// Log vote cast
eventLogger.logVoteCast(pollId, voterToken, {
  ipAddress: '192.168.1.1',
});

// Log poll closure
eventLogger.logPollClosed(pollId, tallyHash, {
  totalVotes: 100,
});

// Query events
const allEvents = eventLogger.getEvents();
const pollEvents = eventLogger.getEventsForPoll(pollId);
const voteEvents = eventLogger.getEventsByType(EventType.VoteCast);

// Verify sequence integrity
const isValid = eventLogger.verifySequence();

// Export for archival
const archive = eventLogger.export();

Features:

  • Microsecond-precision timestamps
  • Sequential event numbering
  • Comprehensive event types (creation, voting, closure, verification, tally, audit)
  • Anonymized voter tokens
  • Poll configuration tracking
  • Sequence integrity verification

Usage

Prerequisites

import { Member, ECIESService } from '@digitaldefiance/node-ecies-lib';
import { MemberType, EmailString } from '@digitaldefiance/ecies-lib';
import {
  PollFactory,
  VoteEncoder,
  PollTallier,
  VotingMethod,
  VotingSecurityValidator
} from '@digitaldefiance/node-ecies-lib';

const eciesService = new ECIESService();

// Create authority with voting keys
const { member: authority, mnemonic } = Member.newMember(
  eciesService,
  MemberType.System,
  'Election Authority',
  new EmailString('authority@example.com')
);
await authority.deriveVotingKeys();

// Create voters
const { member: voter1 } = Member.newMember(
  eciesService,
  MemberType.Individual,
  'Alice',
  new EmailString('alice@example.com')
);
await voter1.deriveVotingKeys();

Quick Start

import { Member, ECIESService } from '@digitaldefiance/node-ecies-lib';
import { PollFactory, VoteEncoder, PollTallier } from '@digitaldefiance/node-ecies-lib';

// 1. Create authority
const eciesService = new ECIESService();
const { member: authority, mnemonic } = Member.newMember(
  eciesService,
  MemberType.System,
  'Election Authority',
  new EmailString('authority@example.com')
);
await authority.deriveVotingKeys();

// 2. Create poll
const poll = PollFactory.createPlurality(
  ['Alice', 'Bob', 'Charlie'],
  authority
);

// 3. Create voters and cast votes
const { member: voter } = Member.newMember(/* ... */);
await voter.deriveVotingKeys();

const encoder = new VoteEncoder(authority.votingPublicKey!);
const vote = encoder.encodePlurality(0, 3); // Vote for Alice
const receipt = poll.vote(voter, vote);

// 4. Close and tally
poll.close();
const tallier = new PollTallier(
  authority,
  authority.votingPrivateKey!,
  authority.votingPublicKey!
);
const results = tallier.tally(poll);

console.log('Winner:', results.choices[results.winner!]);

Ranked Choice Voting (True IRV)

const poll = PollFactory.createRankedChoice(
  ['Alice', 'Bob', 'Charlie', 'Diana'],
  authority
);

const encoder = new VoteEncoder(authority.votingPublicKey!);

// Voter ranks: Alice > Bob > Charlie
const vote = encoder.encodeRankedChoice([0, 1, 2], 4);
poll.vote(voter, vote);

// ... more votes ...

poll.close();
const results = tallier.tally(poll);

// Results include elimination rounds
console.log('Winner:', results.choices[results.winner!]);
console.log('Rounds:', results.rounds);
console.log('Eliminated:', results.eliminated);

Weighted Voting

const poll = PollFactory.createWeighted(
  ['Proposal A', 'Proposal B'],
  authority,
  1000n // Maximum weight
);

const encoder = new VoteEncoder(authority.votingPublicKey!);

// Large stakeholder votes with weight 500
const vote = encoder.encodeWeighted(0, 500n, 2);
poll.vote(whale, vote);

Score Voting

const poll = PollFactory.create(
  ['Candidate A', 'Candidate B', 'Candidate C'],
  VotingMethod.Score,
  authority
);

const encoder = new VoteEncoder(authority.votingPublicKey!);

// Rate candidates 0-10
const vote = encoder.encode(
  VotingMethod.Score,
  { choiceIndex: 0, score: 8 },  // Give Candidate A a score of 8
  3
);
poll.vote(voter, vote);

Yes/No Referendum

const poll = PollFactory.create(
  ['Approve Budget Increase'],
  VotingMethod.YesNo,
  authority
);

const encoder = new VoteEncoder(authority.votingPublicKey!);
const vote = encoder.encode(
  VotingMethod.YesNo,
  { choiceIndex: 0 },  // Vote yes (0 = yes, 1 = no)
  2
);
poll.vote(voter, vote);

Supermajority Voting

const poll = PollFactory.create(
  ['Constitutional Amendment'],
  VotingMethod.Supermajority,
  authority,
  { supermajorityThreshold: { numerator: 2, denominator: 3 } }  // Requires 2/3 majority
);

const encoder = new VoteEncoder(authority.votingPublicKey!);
const vote = encoder.encode(
  VotingMethod.Supermajority,
  { choiceIndex: 0 },
  1
);
poll.vote(voter, vote);

poll.close();
const results = tallier.tally(poll);
// results.winner is only set if 2/3 threshold is met

STAR Voting

const poll = PollFactory.create(
  ['Alice', 'Bob', 'Charlie'],
  VotingMethod.STAR,
  authority
);

const encoder = new VoteEncoder(authority.votingPublicKey!);
// First round: score all candidates
const vote = encoder.encode(
  VotingMethod.STAR,
  { scores: [8, 6, 9] },  // Score each candidate 0-10
  3
);
poll.vote(voter, vote);

Two-Round Voting

const poll = PollFactory.create(
  ['Alice', 'Bob', 'Charlie', 'Diana'],
  VotingMethod.TwoRound,
  authority
);

const encoder = new VoteEncoder(authority.votingPublicKey!);
const vote = encoder.encode(
  VotingMethod.TwoRound,
  { choiceIndex: 0 },  // Vote for Alice in first round
  4
);
poll.vote(voter, vote);

STV (Single Transferable Vote)

const poll = PollFactory.create(
  ['Alice', 'Bob', 'Charlie', 'Diana'],
  VotingMethod.STV,
  authority
);

const encoder = new VoteEncoder(authority.votingPublicKey!);
const vote = encoder.encode(
  VotingMethod.STV,
  { rankings: [0, 2, 1] },  // Alice > Charlie > Bob (Diana not ranked)
  4
);
poll.vote(voter, vote);

Node.js Buffer Examples

// Using Buffer for poll and voter IDs
const pollId = Buffer.from('poll-12345', 'utf8');
const voterIdHash = Buffer.from(crypto.createHash('sha256').update(voter.id).digest());

// All voting operations work with Buffer
const poll = new Poll(
  pollId,
  ['Option A', 'Option B'],
  VotingMethod.Plurality,
  authority,
  authority.votingPublicKey!
);
// Check security level before creating poll
const level = VotingSecurityValidator.getSecurityLevel(VotingMethod.Quadratic);
console.log(level); // SecurityLevel.Insecure

// Validate method (throws if insecure)
try {
  VotingSecurityValidator.validate(VotingMethod.Quadratic);
} catch (error) {
  console.error('Method is not secure!');
}

// Allow insecure methods explicitly
VotingSecurityValidator.validate(VotingMethod.Quadratic, { allowInsecure: true });

Security Validation

// Check security level before creating poll
const level = VotingSecurityValidator.getSecurityLevel(VotingMethod.Quadratic);
console.log(level); // SecurityLevel.Insecure

// Validate method (throws if insecure)
try {
  VotingSecurityValidator.validate(VotingMethod.Quadratic);
} catch (error) {
  console.error('Method is not secure!');
}

// Allow insecure methods explicitly
VotingSecurityValidator.validate(VotingMethod.Quadratic, { allowInsecure: true });

// Require fully secure methods only
VotingSecurityValidator.validate(VotingMethod.RankedChoice, { requireFullySecure: true });
// Throws: RankedChoice requires intermediate decryption

Quick Reference

Export Type Purpose
Poll Class Core poll with vote aggregation
VotingPoll Class High-level voting with encrypted receipts
PollTallier Class Decrypts and tallies votes
VoteEncoder Class Encrypts votes by method
PollFactory Class Convenient poll creation
VotingSecurityValidator Class Security level validation
ImmutableAuditLog Class Hash-chained audit trail
PublicBulletinBoard Class Append-only vote publication
PollEventLogger Class Event tracking with timestamps
VotingMethod Enum All 17 voting methods
SecurityLevel Enum Security classifications
EventType Enum Event types for logging
AuditEventType Enum Audit event types
VoteReceipt Interface Cryptographic vote receipt
PollResults Interface Tally results with winner(s)
EncryptedVote Interface Encrypted vote structure

API Reference

The system includes 1100+ government-grade test cases across multiple test files:

# Run all voting tests
yarn test voting.spec.ts          # Core voting functionality
yarn test voting-stress.spec.ts   # Stress tests with large datasets
yarn test poll-core.spec.ts       # Poll core functionality
yarn test poll-audit.spec.ts      # Audit log integration
yarn test factory.spec.ts         # Poll factory
yarn test encoder.spec.ts         # Vote encoding
yarn test security.spec.ts        # Security validation
yarn test audit.spec.ts           # Audit log
yarn test bulletin-board.spec.ts  # Bulletin board
yarn test event-logger.spec.ts    # Event logger
yarn test poll.spec.ts            # VotingPoll with encrypted receipts

Testing

  • All 17 Methods: Plurality, Approval, Weighted, Borda, Score, YesNo, YesNoAbstain, Supermajority, RankedChoice, TwoRound, STAR, STV, Quadratic, Consensus, ConsentBased
  • Security validation (fully homomorphic, multi-round, insecure classifications)
  • Attack resistance (vote manipulation, double voting, unauthorized decryption)
  • Cryptographic correctness (homomorphic addition, receipt signatures)
  • Edge cases (ties, single voter, unanimous votes, empty rankings)
  • Large scale (1000 voters, 100 choices)
  • Boundary conditions (max weights, zero votes, partial rankings)
  • Determinism (same votes = same results)
  • Receipt verification (signature validation, tampering detection)
  • Multi-round elimination (IRV, STAR, STV, Two-Round)
  • Government requirements (audit log, bulletin board, event logger)
  • Stress testing (concurrent operations, memory limits)
  • Cross-platform compatibility (Node.js Buffer ↔ Browser Uint8Array)
  • Buffer operations (Node.js-specific binary data handling)

Test Coverage

Extends Browser Implementation

This Node.js implementation (@digitaldefiance/node-ecies-lib) extends the browser implementation (@digitaldefiance/ecies-lib) with Node.js-specific optimizations:

// VoteEncoder extends the browser VoteEncoder with Buffer specialization
export class VoteEncoder extends BaseVoteEncoder<Buffer> {
  constructor(votingPublicKey: PublicKey) {
    super(votingPublicKey);
  }
  // All encoding methods inherited from base class
  // Generic type parameter TID specialized to Buffer
}

// PollFactory extends browser PollFactory to return Node.js Poll instances
export class PollFactory extends BasePollFactory {
  static override create<TID extends PlatformID = Buffer>(
    choices: string[],
    method: VotingMethod,
    authority: Member<TID>,
    options?: { maxWeight?: bigint },
  ): Poll<TID> {
    // Returns node-ecies-lib Poll instance with Buffer support
  }
}

PlatformID Type Extension

The Node.js implementation extends the PlatformID type to include mongoose ObjectIds:

// From platform-id.ts
export type PlatformID =
  | BasePlatformID        // Uint8Array | GuidV4 | ObjectId | string
  | Buffer                // Node.js Buffer
  | Types.ObjectId;       // Mongoose ObjectId

This allows seamless integration with MongoDB and mongoose-based applications:

import { Types } from '@digitaldefiance/mongoose-types';

// Use mongoose ObjectId as poll/voter ID
const pollId = new Types.ObjectId();
const poll = PollFactory.create(['A', 'B'], VotingMethod.Plurality, authority);

All Voting Methods Supported

The Node.js implementation supports all 17 voting methods through inheritance:

  1. Dedicated Methods (5): encodePlurality, encodeApproval, encodeWeighted, encodeBorda, encodeRankedChoice
  2. Generic Method: encode(method, data, choiceCount) handles all 17 methods
  3. Factory Methods: Both dedicated (createPlurality, etc.) and generic (create) methods available

Complete Method List:

  • Plurality, Approval, Weighted, Borda, Score ✅
  • YesNo, YesNoAbstain, Supermajority ✅
  • RankedChoice, TwoRound, STAR, STV ✅
  • Quadratic, Consensus, ConsentBased ✅

Node.js Specific Features

Node.js Implementation Details

All voting operations use Node.js Buffer instead of Uint8Array for better performance:

// Poll IDs, voter IDs, and hashes are all Buffers
const pollId = Buffer.from([1, 2, 3, 4]);
const voterIdHash = Buffer.from(crypto.createHash('sha256').update(voter.id).digest());

Buffer Support

Uses Node.js native crypto module for:

  • SHA-256 hashing (audit log, bulletin board)
  • Random bytes generation (nonces, IDs)
  • Microsecond timestamps via process.hrtime.bigint()

Native Crypto

The voting system in node-ecies-lib is 100% compatible with the browser-based ecies-lib voting system:

  • Same Paillier encryption parameters
  • Same vote encoding formats
  • Same receipt structures
  • Same audit log format

Data encrypted in Node.js can be tallied in the browser and vice versa.

Documentation

Core Documentation

  • README.md (this file) - Overview and quick start
  • docs/GOVERNMENT-REQUIREMENTS.md - Complete EARS specification with implementation status
  • docs/PHASE2-README.md - Voter registration and eligibility system (design phase)
  • docs/PHASE2-SUMMARY.md - Executive summary of Phase 2 features

Examples

The examples.ts file contains comprehensive usage examples:

Basic Voting Methods:

  • examplePlurality() - Simple majority voting
  • exampleRankedChoice() - Instant runoff voting (IRV)
  • exampleWeighted() - Stakeholder voting with weights
  • exampleBorda() - Ranked voting with point allocation
  • exampleApproval() - Multi-choice approval voting
  • exampleReceipts() - Receipt generation and verification

Node.js-Specific Examples:

  • exampleFilePersistence() - Save/load encrypted votes to/from disk
  • exampleStreamProcessing() - Process large voter datasets using streams
  • exampleBufferCrypto() - Cryptographic operations with Buffer
  • exampleAuditLogExport() - Export audit logs to JSON files
import {
  examplePlurality,
  exampleFilePersistence,
  exampleBufferCrypto
} from '@digitaldefiance/node-ecies-lib/voting/examples';

// Run examples
await examplePlurality();
await exampleFilePersistence();
await exampleBufferCrypto();

Platform Differences

This Node.js implementation differs from the browser implementation in these ways:

Feature Browser (ecies-lib) Node.js (node-ecies-lib)
Binary Data Uint8Array Buffer
Crypto API Web Crypto API Node.js crypto module
File I/O Not available Native fs module
Streams Not available Native Node.js streams
Performance Browser-optimized V8-optimized

All cryptographic operations, security properties, and voting methods are identical between platforms.

Threshold Voting (Node.js Extensions)

The threshold voting module enables real-time, distributed vote tallying where no single party can decrypt votes alone. The Node.js implementation extends the browser ecies-lib threshold module with Buffer support for improved performance.

For full API documentation, see the ecies-lib Threshold Voting documentation. All shared APIs (GuardianRegistry, CeremonyCoordinator, IntervalScheduler, DecryptionCombiner, PublicTallyFeed, TallyVerifier) are re-exported from ecies-lib and work identically.

Node.js-Specific Extensions

The following classes extend the ecies-lib base with Node.js Buffer support:

Export Purpose
ThresholdKeyGenerator Buffer-based key share handling (BufferKeyShare, BufferThresholdKeyPair)
PartialDecryptionService Buffer-based partial decryption serialization (BufferPartialDecryption)
ThresholdPoll Threshold poll specialized for Buffer-based PlatformID
ThresholdPollFactory Creates threshold polls with Buffer support
ThresholdAuditLog Audit logging with Buffer-based entry handling
ThresholdPrecinctAggregator Precinct-level threshold aggregation with Buffer
ThresholdCountyAggregator County-level threshold aggregation with Buffer
ThresholdStateAggregator State-level threshold aggregation with Buffer
ThresholdNationalAggregator National-level threshold aggregation with Buffer

Quick Start

import {
  ThresholdKeyGenerator,
  GuardianRegistry,
  GuardianStatus,
  ThresholdPollFactory,
  IntervalTriggerType,
} from '@digitaldefiance/node-ecies-lib';

// 1. Generate threshold keys (3-of-5 configuration)
const keyGen = new ThresholdKeyGenerator();
const keyPair = await keyGen.generate({ totalShares: 5, threshold: 3 });

// Key shares use Buffer for serialization
const serialized: Buffer = keyGen.serializeKeyShare(keyPair.keyShares[0]);
const deserialized = keyGen.deserializeKeyShare(serialized);

// 2. Register Guardians (uses Buffer-based PlatformID)
const registry = new GuardianRegistry<Buffer>({ totalShares: 5, threshold: 3 });
keyPair.keyShares.forEach((share, i) => {
  registry.register({
    id: Buffer.from([i + 1]),
    name: `Guardian ${i + 1}`,
    shareIndex: share.index,
    verificationKey: share.verificationKey,
    status: GuardianStatus.Online,
  });
});

// 3. Create threshold poll with Buffer support
const factory = new ThresholdPollFactory(auditLog);
const poll = factory.createThresholdPoll(
  ['Alice', 'Bob', 'Charlie'],
  VotingMethod.Plurality,
  authority,
  {
    thresholdConfig: { totalShares: 5, threshold: 3 },
    intervalConfig: {
      triggerType: IntervalTriggerType.TimeBased,
      timeIntervalMs: 3600000,
      minimumIntervalMs: 60000,
      ceremonyTimeoutMs: 300000,
    },
    guardianRegistry: registry,
    keyPair,
  }
);

Cross-Platform Compatibility

Threshold voting data is fully interoperable between Node.js and browser environments:

// Serialize in Node.js with Buffer
const partialService = new PartialDecryptionService();
const serialized: Buffer = partialService.serialize(partial);

// Deserialize in browser with Uint8Array (ecies-lib)
const deserialized = browserPartialService.deserialize(new Uint8Array(serialized));

Summary

The Node.js voting system in @digitaldefiance/node-ecies-lib provides a complete implementation of all 17 voting methods with government-grade security:

✅ Complete Implementation

  • All 17 Methods: Every voting method from Plurality to ConsentBased is fully implemented and tested
  • Node.js Optimized: Uses Buffer instead of Uint8Array for better Node.js performance
  • Cross-Platform: 100% binary compatible with browser implementation
  • Extended PlatformID: Supports Buffer and mongoose ObjectId in addition to base types

✅ Government-Grade Security

  • Homomorphic Encryption: Paillier cryptosystem for privacy-preserving vote aggregation
  • Immutable Audit Log: Cryptographic hash chain for complete audit trail
  • Public Bulletin Board: Transparent, verifiable vote publication
  • Event Logging: Microsecond-precision event tracking
  • Role Separation: Poll aggregators cannot decrypt votes until closure

✅ Production Ready

  • 1100+ Tests: Comprehensive test coverage for all methods and edge cases
  • Stress Tested: Handles 1000+ voters and complex elimination scenarios
  • Attack Resistant: Prevents double voting, vote manipulation, and unauthorized decryption
  • Documentation: Complete API reference and usage examples

The system is ready for production use in government elections, corporate governance, and any application requiring secure, verifiable voting.

License

MIT