diff --git a/contracts/passport/authenticators/PRSASHA1Authenticator.sol b/contracts/passport/authenticators/PRSASHAAuthenticator.sol similarity index 63% rename from contracts/passport/authenticators/PRSASHA1Authenticator.sol rename to contracts/passport/authenticators/PRSASHAAuthenticator.sol index 13f0418..85abb95 100644 --- a/contracts/passport/authenticators/PRSASHA1Authenticator.sol +++ b/contracts/passport/authenticators/PRSASHAAuthenticator.sol @@ -6,16 +6,18 @@ import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Ini import {RSA} from "../../utils/RSA.sol"; import {SHA1} from "../../utils/SHA1.sol"; -contract PRSASHA1Authenticator is Initializable { +contract PRSASHAAuthenticator is Initializable { using RSA for bytes; using SHA1 for bytes; - uint256 public constant HASH_LEN = 20; // SHA1 hash length - uint256 public exponent; // RSA exponent + bool public isSha1; + uint256 private hashLen; - function __PRSASHA1Authenticator_init(uint256 exponent_) external initializer { + function __PRSASHAAuthenticator_init(uint256 exponent_, bool isSha1_) external initializer { exponent = exponent_; + isSha1 = isSha1_; + hashLen = isSha1 ? 20 : 32; } /** @@ -23,7 +25,7 @@ contract PRSASHA1Authenticator is Initializable { * * 1. Decrypt the signature * 2. Remove the 1 byte (hash function indicator) suffix - * 3. The last 20 bytes of the decrypted signature is the SHA1 hash of random + challenge + * 3. The last 20 bytes of the decrypted signature is the SHA1 hash of random + challenge or the last 32 bytes in case SHA2 hash */ function authenticate( bytes memory challenge_, @@ -42,17 +44,21 @@ contract PRSASHA1Authenticator is Initializable { mstore(decipher_, sub(mload(decipher_), 1)) } - bytes memory prepared_ = new bytes(decipher_.length - HASH_LEN - 1); - bytes memory digest_ = new bytes(HASH_LEN); + bytes memory prepared_ = new bytes(decipher_.length - hashLen - 1); + bytes memory digest_ = new bytes(hashLen); for (uint256 i = 0; i < prepared_.length; ++i) { prepared_[i] = decipher_[i + 1]; } for (uint256 i = 0; i < digest_.length; ++i) { - digest_[i] = decipher_[decipher_.length - HASH_LEN + i]; + digest_[i] = decipher_[decipher_.length - hashLen + i]; } - return bytes20(digest_) == abi.encodePacked(prepared_, challenge_).sha1(); + return bytes32(digest_) == _hash(abi.encodePacked(prepared_, challenge_)); + } + + function _hash(bytes memory data_) private view returns (bytes32) { + return isSha1 ? data_.sha1() : sha256(data_); } } diff --git a/contracts/passport/dispatchers/PRSASHA1Dispatcher.sol b/contracts/passport/dispatchers/PRSASHADispatcher.sol similarity index 83% rename from contracts/passport/dispatchers/PRSASHA1Dispatcher.sol rename to contracts/passport/dispatchers/PRSASHADispatcher.sol index 78c1da0..d1794c8 100644 --- a/contracts/passport/dispatchers/PRSASHA1Dispatcher.sol +++ b/contracts/passport/dispatchers/PRSASHADispatcher.sol @@ -4,15 +4,15 @@ pragma solidity 0.8.16; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import {IPassportDispatcher} from "../../interfaces/dispatchers/IPassportDispatcher.sol"; -import {PRSASHA1Authenticator} from "../authenticators/PRSASHA1Authenticator.sol"; +import {PRSASHAAuthenticator} from "../authenticators/PRSASHAAuthenticator.sol"; import {Bytes2Poseidon} from "../../utils/Bytes2Poseidon.sol"; -contract PRSASHA1Dispatcher is IPassportDispatcher, Initializable { +contract PRSASHADispatcher is IPassportDispatcher, Initializable { using Bytes2Poseidon for bytes; address public authenticator; - function __PRSASHA1Dispatcher_init(address authenticator_) external initializer { + function __PRSASHADispatcher_init(address authenticator_) external initializer { authenticator = authenticator_; } @@ -25,7 +25,7 @@ contract PRSASHA1Dispatcher is IPassportDispatcher, Initializable { bytes memory passportPublicKey_ ) external view returns (bool) { return - PRSASHA1Authenticator(authenticator).authenticate( + PRSASHAAuthenticator(authenticator).authenticate( challenge_, passportSignature_, passportPublicKey_ diff --git a/deploy/10_setup.migration.ts b/deploy/10_setup.migration.ts index f40e1af..ebfe2c5 100644 --- a/deploy/10_setup.migration.ts +++ b/deploy/10_setup.migration.ts @@ -4,7 +4,7 @@ import { CRSADispatcher__factory, PECDSASHA1Dispatcher__factory, PNOAADispatcher__factory, - PRSASHA1Dispatcher__factory, + PRSASHADispatcher__factory, PUniversal2048Verifier2__factory, PUniversal2048V2Verifier2__factory, PUniversal4096Verifier2__factory, @@ -32,6 +32,8 @@ import { P_NO_AA, P_RSA_SHA1_2688, P_RSA_SHA1_2688_3, + P_RSA_SHA2_2688, + P_RSA_SHA2_2688_3, Z_UNIVERSAL_2048, Z_UNIVERSAL_2048_V2, Z_UNIVERSAL_4096, @@ -61,8 +63,11 @@ export = async (deployer: Deployer) => { const cRsaPss2048Sha512Dispatcher = await deployer.deployed(CRSADispatcher__factory, "CRSAPSSDispatcher SHA512 256"); const cRsaPss4096Sha512Dispatcher = await deployer.deployed(CRSADispatcher__factory, "CRSAPSSDispatcher SHA512 512"); - const pRsaSha12688Dispatcher = await deployer.deployed(PRSASHA1Dispatcher__factory, "PRSASHA1Dispatcher 65537"); - const pRsaSha126883Dispatcher = await deployer.deployed(PRSASHA1Dispatcher__factory, "PRSASHA1Dispatcher 3"); + const pRsaSha12688Dispatcher = await deployer.deployed(PRSASHADispatcher__factory, "PRSASHADispatcher 65537 SHA1"); + const pRsaSha126883Dispatcher = await deployer.deployed(PRSASHADispatcher__factory, "PRSASHADispatcher 3 SHA1"); + + const pRsaSha22688Dispatcher = await deployer.deployed(PRSASHADispatcher__factory, "PRSASHADispatcher 65537 SHA2"); + const pRsaSha226883Dispatcher = await deployer.deployed(PRSASHADispatcher__factory, "PRSASHADispatcher 3 SHA2"); const pEcdsaSha12704Dispatcher = await deployer.deployed(PECDSASHA1Dispatcher__factory); @@ -94,6 +99,9 @@ export = async (deployer: Deployer) => { await registration.mockAddPassportDispatcher(P_RSA_SHA1_2688, await pRsaSha12688Dispatcher.getAddress()); await registration.mockAddPassportDispatcher(P_RSA_SHA1_2688_3, await pRsaSha126883Dispatcher.getAddress()); + await registration.mockAddPassportDispatcher(P_RSA_SHA2_2688, await pRsaSha22688Dispatcher.getAddress()); + await registration.mockAddPassportDispatcher(P_RSA_SHA2_2688_3, await pRsaSha226883Dispatcher.getAddress()); + await registration.mockAddPassportDispatcher(P_ECDSA_SHA1_2704, await pEcdsaSha12704Dispatcher.getAddress()); await registration.mockAddPassportDispatcher(P_NO_AA, await pNoAaDispatcher.getAddress()); diff --git a/deploy/2_registration.migration.ts b/deploy/2_registration.migration.ts index 5cd31e3..712baea 100644 --- a/deploy/2_registration.migration.ts +++ b/deploy/2_registration.migration.ts @@ -6,7 +6,7 @@ import { deployCRSADispatcher, deployCRSAPSSDispatcher, deployPNOAADispatcher, - deployPRSASHA12688Dispatcher, + deployPRSASHA2688Dispatcher, deployPECDSASHA12704Dispatcher, } from "./helpers"; @@ -33,8 +33,11 @@ export = async (deployer: Deployer) => { await deployCRSAPSSDispatcher(deployer, "SHA512", "65537", "256", "0x0282010100"); await deployCRSAPSSDispatcher(deployer, "SHA512", "65537", "512", "0x0282020100"); - await deployPRSASHA12688Dispatcher(deployer, "65537"); - await deployPRSASHA12688Dispatcher(deployer, "3"); + await deployPRSASHA2688Dispatcher(deployer, "65537", "SHA1"); + await deployPRSASHA2688Dispatcher(deployer, "3", "SHA1"); + + await deployPRSASHA2688Dispatcher(deployer, "65537", "SHA2"); + await deployPRSASHA2688Dispatcher(deployer, "3", "SHA2"); await deployPNOAADispatcher(deployer); await deployPECDSASHA12704Dispatcher(deployer); diff --git a/deploy/helpers/dispatchers/passport.ts b/deploy/helpers/dispatchers/passport.ts index fbbeac4..879e0a5 100644 --- a/deploy/helpers/dispatchers/passport.ts +++ b/deploy/helpers/dispatchers/passport.ts @@ -4,8 +4,8 @@ import { PECDSASHA1Authenticator__factory, PECDSASHA1Dispatcher__factory, PNOAADispatcher__factory, - PRSASHA1Authenticator__factory, - PRSASHA1Dispatcher__factory, + PRSASHAAuthenticator__factory, + PRSASHADispatcher__factory, } from "@ethers-v6"; export const deployPNOAADispatcher = async (deployer: Deployer) => { @@ -14,16 +14,16 @@ export const deployPNOAADispatcher = async (deployer: Deployer) => { await dispatcher.__PNOAADispatcher_init(); }; -export const deployPRSASHA12688Dispatcher = async (deployer: Deployer, exponent: string) => { - const authenticator = await deployer.deploy(PRSASHA1Authenticator__factory, { - name: `PRSASHA1Authenticator ${exponent}`, +export const deployPRSASHA2688Dispatcher = async (deployer: Deployer, exponent: string, hashFunc: "SHA1" | "SHA2") => { + const authenticator = await deployer.deploy(PRSASHAAuthenticator__factory, { + name: `PRSASHAAuthenticator ${exponent} ${hashFunc}`, }); - const dispatcher = await deployer.deploy(PRSASHA1Dispatcher__factory, { - name: `PRSASHA1Dispatcher ${exponent}`, + const dispatcher = await deployer.deploy(PRSASHADispatcher__factory, { + name: `PRSASHADispatcher ${exponent} ${hashFunc}`, }); - await authenticator.__PRSASHA1Authenticator_init(exponent); - await dispatcher.__PRSASHA1Dispatcher_init(await authenticator.getAddress()); + await authenticator.__PRSASHAAuthenticator_init(exponent, hashFunc === "SHA1"); + await dispatcher.__PRSASHADispatcher_init(await authenticator.getAddress()); }; export const deployPECDSASHA12704Dispatcher = async (deployer: Deployer) => { diff --git a/scripts/utils/types.ts b/scripts/utils/types.ts index ae27844..dd36cec 100644 --- a/scripts/utils/types.ts +++ b/scripts/utils/types.ts @@ -17,6 +17,8 @@ export const C_RSAPSS_SHA512_4096 = keccak256(["string"], ["C_RSAPSS_SHA512_4096 export const P_NO_AA = keccak256(["string"], ["P_NO_AA"]); export const P_RSA_SHA1_2688 = keccak256(["string"], ["P_RSA_SHA1_2688"]); export const P_RSA_SHA1_2688_3 = keccak256(["string"], ["P_RSA_SHA1_2688_3"]); +export const P_RSA_SHA2_2688 = keccak256(["string"], ["P_RSA_SHA2_2688"]); +export const P_RSA_SHA2_2688_3 = keccak256(["string"], ["P_RSA_SHA2_2688_3"]); export const P_ECDSA_SHA1_2704 = keccak256(["string"], ["P_ECDSA_SHA1_2704"]); // -------------------------- VERIFIER -------------------------- diff --git a/test/passport/authenticators/PRSASHA1Authenticator.test.ts b/test/passport/authenticators/PRSASHAAuthenticator.test.ts similarity index 76% rename from test/passport/authenticators/PRSASHA1Authenticator.test.ts rename to test/passport/authenticators/PRSASHAAuthenticator.test.ts index bfb7d9a..923523e 100644 --- a/test/passport/authenticators/PRSASHA1Authenticator.test.ts +++ b/test/passport/authenticators/PRSASHAAuthenticator.test.ts @@ -2,19 +2,19 @@ import { ethers } from "hardhat"; import { expect } from "chai"; import { Reverter } from "@/test/helpers/"; -import { PRSASHA1Authenticator } from "@ethers-v6"; +import { PRSASHAAuthenticator } from "@ethers-v6"; -describe("PRSASHA1Authenticator", () => { +describe("PRSASHAAuthenticator", () => { const reverter = new Reverter(); - let auth: PRSASHA1Authenticator; + let auth: PRSASHAAuthenticator; before("setup", async () => { - const PRSASHA1Authenticator = await ethers.getContractFactory("PRSASHA1Authenticator"); + const PRSASHAAuthenticator = await ethers.getContractFactory("PRSASHAAuthenticator"); - auth = await PRSASHA1Authenticator.deploy(); + auth = await PRSASHAAuthenticator.deploy(); - await auth.__PRSASHA1Authenticator_init(65537); + await auth.__PRSASHAAuthenticator_init(65537, true); await reverter.snapshot(); }); diff --git a/test/passport/dispatchers/PRSASHA1Dispatcher.test.ts b/test/passport/dispatchers/PRSASHADispatcher.test.ts similarity index 69% rename from test/passport/dispatchers/PRSASHA1Dispatcher.test.ts rename to test/passport/dispatchers/PRSASHADispatcher.test.ts index 8b5e0d1..cc6513e 100644 --- a/test/passport/dispatchers/PRSASHA1Dispatcher.test.ts +++ b/test/passport/dispatchers/PRSASHADispatcher.test.ts @@ -1,7 +1,7 @@ import { expect } from "chai"; import { ethers } from "hardhat"; -import { PRSASHA1Dispatcher } from "@ethers-v6"; +import { PRSASHADispatcher } from "@ethers-v6"; import { Reverter, getPoseidon } from "@/test/helpers/"; import { @@ -11,26 +11,26 @@ import { RSAPassportPubKey, } from "@/test/helpers/constants"; -describe("PRSASHA1Dispatcher", () => { +describe("PRSASHADispatcher", () => { const reverter = new Reverter(); - let dispatcher: PRSASHA1Dispatcher; + let dispatcher: PRSASHADispatcher; before("setup", async () => { - const PRSASHA1Authenticator = await ethers.getContractFactory("PRSASHA1Authenticator"); - const PRSASHA1Dispatcher = await ethers.getContractFactory("PRSASHA1Dispatcher", { + const PRSASHAAuthenticator = await ethers.getContractFactory("PRSASHAAuthenticator"); + const PRSASHADispatcher = await ethers.getContractFactory("PRSASHADispatcher", { libraries: { PoseidonUnit5L: await (await getPoseidon(5)).getAddress(), }, }); - dispatcher = await PRSASHA1Dispatcher.deploy(); + dispatcher = await PRSASHADispatcher.deploy(); - const rsaSha1Authenticator = await PRSASHA1Authenticator.deploy(); - dispatcher = await PRSASHA1Dispatcher.deploy(); + const rsaShaAuthenticator = await PRSASHAAuthenticator.deploy(); + dispatcher = await PRSASHADispatcher.deploy(); - await rsaSha1Authenticator.__PRSASHA1Authenticator_init(65537); - await dispatcher.__PRSASHA1Dispatcher_init(await rsaSha1Authenticator.getAddress()); + await rsaShaAuthenticator.__PRSASHAAuthenticator_init(65537, true); + await dispatcher.__PRSASHADispatcher_init(await rsaShaAuthenticator.getAddress()); await reverter.snapshot(); }); @@ -39,7 +39,7 @@ describe("PRSASHA1Dispatcher", () => { describe("#init", () => { it("should not init twice", async () => { - expect(dispatcher.__PRSASHA1Dispatcher_init(ethers.hexlify(ethers.randomBytes(20)))).to.be.revertedWith( + expect(dispatcher.__PRSASHADispatcher_init(ethers.hexlify(ethers.randomBytes(20)))).to.be.revertedWith( "Initializable: contract is already initialized", ); }); diff --git a/test/registration/Registration.test.ts b/test/registration/Registration.test.ts index 4462e3f..b4fbfec 100644 --- a/test/registration/Registration.test.ts +++ b/test/registration/Registration.test.ts @@ -22,7 +22,7 @@ import { PUniversal4096Verifier, CRSADispatcher, PNOAADispatcher, - PRSASHA1Dispatcher, + PRSASHADispatcher, PECDSASHA1Dispatcher, PoseidonSMTMock, } from "@ethers-v6"; @@ -69,7 +69,7 @@ describe("Registration", () => { let pUniversal4096Verifier: PUniversal4096Verifier; let pNoAaDispatcher: PNOAADispatcher; - let pRsaSha1Dispatcher: PRSASHA1Dispatcher; + let pRsaSha1Dispatcher: PRSASHADispatcher; let pEcdsaSha1Dispatcher: PECDSASHA1Dispatcher; let cRsaDispatcher: CRSADispatcher; @@ -110,8 +110,8 @@ describe("Registration", () => { }; const deployPRSASHA1Dispatcher = async () => { - const PRSASHA1Authenticator = await ethers.getContractFactory("PRSASHA1Authenticator"); - const PRSASHA1Dispatcher = await ethers.getContractFactory("PRSASHA1Dispatcher", { + const PRSASHA1Authenticator = await ethers.getContractFactory("PRSASHAAuthenticator"); + const PRSASHA1Dispatcher = await ethers.getContractFactory("PRSASHADispatcher", { libraries: { PoseidonUnit5L: await (await getPoseidon(5)).getAddress(), }, @@ -120,8 +120,8 @@ describe("Registration", () => { const rsaSha1Authenticator = await PRSASHA1Authenticator.deploy(); pRsaSha1Dispatcher = await PRSASHA1Dispatcher.deploy(); - await rsaSha1Authenticator.__PRSASHA1Authenticator_init(65537); - await pRsaSha1Dispatcher.__PRSASHA1Dispatcher_init(await rsaSha1Authenticator.getAddress()); + await rsaSha1Authenticator.__PRSASHAAuthenticator_init(65537, true); + await pRsaSha1Dispatcher.__PRSASHADispatcher_init(await rsaSha1Authenticator.getAddress()); }; const deployPECDSASHA1Dispatcher = async () => {