diff --git a/contracts/DEC.sol b/contracts/DEC.sol index cce90c4..1b325e1 100644 --- a/contracts/DEC.sol +++ b/contracts/DEC.sol @@ -6,12 +6,13 @@ pragma solidity ^0.8.24; /// @custom:experimental This is an experimental contract. contract DEC { address public owner; - Encrypted taxCode; - Encrypted municipality; - Encrypted region; - Encrypted country; + Encrypted public taxCode; + Encrypted public municipality; + Encrypted public region; + Encrypted public country; struct Encrypted { + string sha; string chiper; string nonce; } @@ -39,33 +40,15 @@ contract DEC { taxCode = _taxCode; } - function getTaxCode() external view returns (Encrypted memory) { - return taxCode; - } - function setMunicipality(Encrypted memory _municipality) external onlyOwner { municipality = _municipality; } - function getMunicipality() external view returns (Encrypted memory) { - return municipality; - } - function setRegion(Encrypted memory _region) external onlyOwner { region = _region; } - function getRegion() external view returns (Encrypted memory) { - return region; - } - function setCountry(Encrypted memory _country) external onlyOwner { country = _country; } - - function getCountry() external view returns (Encrypted memory) { - return country; - } - - } diff --git a/lib/crypto-utils.test.ts b/lib/crypto-utils.test.ts index b6ff178..e237e83 100644 --- a/lib/crypto-utils.test.ts +++ b/lib/crypto-utils.test.ts @@ -1,4 +1,4 @@ -import { encryptString, decryptString } from "./crypto-utils"; +import { encryptString, decryptString, getHash } from "./crypto-utils"; import { mockEOAs } from "./__mocks__"; describe("Crypto Utils", () => { @@ -30,4 +30,14 @@ describe("Crypto Utils", () => { expect(e.message).toBe("Error decrypting string"); } }); + + it("should return a SHA hash for a given message", () => { + const message = "Hello, world!"; + const expectedHash = + "f345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722"; + + const result = getHash(message); + + expect(result).toEqual({ sha: expectedHash }); + }); }); diff --git a/lib/crypto-utils.ts b/lib/crypto-utils.ts index 5bc8b32..7ecf019 100644 --- a/lib/crypto-utils.ts +++ b/lib/crypto-utils.ts @@ -6,7 +6,7 @@ * is because If we send the data and then encrypt it in solidity, the data will be visible in the transaction that * in the first place was used to send the data to the contract. Also, solidity doesn't have a function to encrypt. */ -import { Encrypted, Decrypted } from "./types"; +import { Encrypted, Decrypted, Sha } from "./types"; import { execSync, ExecSyncOptionsWithStringEncoding } from "child_process"; import * as path from "path"; @@ -40,6 +40,7 @@ export function encryptString( ); const response: Encrypted = JSON.parse(encrypted.toString()); + response.sha = getHash(decryptedString).sha; return response; } catch (e) { @@ -84,6 +85,26 @@ export function decryptString( } } +export function getHash(message: string): Sha { + try { + const execSyncOptions = { + stdio: "pipe", + } as ExecSyncOptionsWithStringEncoding; + + const cryptoPyPath = getCryptoPyPath(); + const hashed = execSync( + `cd ${cryptoPyPath} && python3 Crypto.py sha3_256 --input="${message}"`, + execSyncOptions, + ); + + const response: Sha = JSON.parse(hashed.toString()); + + return response; + } catch (e: any) { + throw new Error("Error hashing the message"); + } +} + /** * The crypto-py library should be manually copy-pasted (or git cloned) inside the lib folder. * Linux and MacOS users can in alternative create a symbolic link. diff --git a/lib/types.ts b/lib/types.ts index 44daf8c..8c72439 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -1,4 +1,5 @@ export type Encrypted = { + sha: string; chiper: string; nonce: string; }; @@ -6,3 +7,7 @@ export type Encrypted = { export type Decrypted = { message: string; }; + +export type Sha = { + sha: string; +}; diff --git a/package.json b/package.json index b914e9f..04c2d56 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agora", - "version": "0.9.0", + "version": "0.10.0", "description": "A confidentiality-first electronic voting system", "author": { "name": "nova collective", diff --git a/test/DEC.ts b/test/DEC.ts index d81ea9f..352c956 100644 --- a/test/DEC.ts +++ b/test/DEC.ts @@ -10,10 +10,12 @@ describe("DEC Contract", () => { const encryptedDataFactory = function ( chiper: string, nonce: string, + sha: string, ): Encrypted { return { chiper, nonce, + sha, }; }; @@ -45,29 +47,33 @@ describe("DEC Contract", () => { await (await ethers.provider.getSigner(0)).getAddress(), ); - const registeredTaxCode = await dec.getTaxCode(); - const registeredMunicipality = await dec.getMunicipality(); - const registeredRegion = await dec.getRegion(); - const registeredCountry = await dec.getCountry(); + const registeredTaxCode: Encrypted = await dec.taxCode(); + const registeredMunicipality: Encrypted = await dec.municipality(); + const registeredRegion: Encrypted = await dec.region(); + const registeredCountry: Encrypted = await dec.country(); const enTaxCode = encryptedDataFactory( - registeredTaxCode[0], - registeredTaxCode[1], + registeredTaxCode.chiper, + registeredTaxCode.nonce, + registeredTaxCode.sha, ); const enMunicipality = encryptedDataFactory( - registeredMunicipality[0], - registeredMunicipality[1], + registeredMunicipality.chiper, + registeredMunicipality.nonce, + registeredMunicipality.sha, ); const enRegion = encryptedDataFactory( - registeredRegion[0], - registeredRegion[1], + registeredRegion.chiper, + registeredRegion.nonce, + registeredRegion.sha, ); const enCountry = encryptedDataFactory( - registeredCountry[0], - registeredCountry[1], + registeredCountry.chiper, + registeredCountry.nonce, + registeredCountry.sha, ); const decodedTaxCode = decryptString( @@ -100,9 +106,13 @@ describe("DEC Contract", () => { it("Should set and get tax code correctly", async () => { await dec.setTaxCode(eTaxCode); - const getTaxCode = await dec.getTaxCode(); + const getTaxCode = await dec.taxCode(); - const gTaxCode = encryptedDataFactory(getTaxCode[0], getTaxCode[1]); + const gTaxCode = encryptedDataFactory( + getTaxCode.chiper, + getTaxCode.nonce, + getTaxCode.sha, + ); assert.equal(JSON.stringify(eTaxCode), JSON.stringify(gTaxCode)); }); @@ -110,11 +120,12 @@ describe("DEC Contract", () => { it("Should set and get municipality correctly", async () => { await dec.setMunicipality(eMunicipality); - const getMunicipality = await dec.getMunicipality(); + const getMunicipality = await dec.municipality(); const gMunicipality = encryptedDataFactory( - getMunicipality[0], - getMunicipality[1], + getMunicipality.chiper, + getMunicipality.nonce, + getMunicipality.sha, ); assert.equal(JSON.stringify(eMunicipality), JSON.stringify(gMunicipality)); @@ -123,9 +134,13 @@ describe("DEC Contract", () => { it("Should set and get region correctly", async () => { await dec.setRegion(eRegion); - const getRegion = await dec.getRegion(); + const getRegion = await dec.region(); - const gRegion = encryptedDataFactory(getRegion[0], getRegion[1]); + const gRegion = encryptedDataFactory( + getRegion.chiper, + getRegion.nonce, + getRegion.sha, + ); assert.equal(JSON.stringify(eRegion), JSON.stringify(gRegion)); }); @@ -133,9 +148,13 @@ describe("DEC Contract", () => { it("Should set and get country correctly", async () => { await dec.setCountry(eCountry); - const getCountry = await dec.getCountry(); + const getCountry = await dec.country(); - const gCountry = encryptedDataFactory(getCountry[0], getCountry[1]); + const gCountry = encryptedDataFactory( + getCountry.chiper, + getCountry.nonce, + getCountry.sha, + ); assert.equal(JSON.stringify(eCountry), JSON.stringify(gCountry)); });