Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for rsa sha2 #14

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@ 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;
}

/**
* @notice Checks active authentication of a passport. The RSA algorithm is as follows:
*
* 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_,
Expand All @@ -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_);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
}

Expand All @@ -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_
Expand Down
14 changes: 11 additions & 3 deletions deploy/10_setup.migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
CRSADispatcher__factory,
PECDSASHA1Dispatcher__factory,
PNOAADispatcher__factory,
PRSASHA1Dispatcher__factory,
PRSASHADispatcher__factory,
PUniversal2048Verifier2__factory,
PUniversal2048V2Verifier2__factory,
PUniversal4096Verifier2__factory,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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());
Expand Down
9 changes: 6 additions & 3 deletions deploy/2_registration.migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
deployCRSADispatcher,
deployCRSAPSSDispatcher,
deployPNOAADispatcher,
deployPRSASHA12688Dispatcher,
deployPRSASHA2688Dispatcher,
deployPECDSASHA12704Dispatcher,
} from "./helpers";

Expand All @@ -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);
Expand Down
18 changes: 9 additions & 9 deletions deploy/helpers/dispatchers/passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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) => {
Expand Down
2 changes: 2 additions & 0 deletions scripts/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 --------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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();
});
Expand All @@ -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",
);
});
Expand Down
12 changes: 6 additions & 6 deletions test/registration/Registration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
PUniversal4096Verifier,
CRSADispatcher,
PNOAADispatcher,
PRSASHA1Dispatcher,
PRSASHADispatcher,
PECDSASHA1Dispatcher,
PoseidonSMTMock,
} from "@ethers-v6";
Expand Down Expand Up @@ -69,7 +69,7 @@ describe("Registration", () => {
let pUniversal4096Verifier: PUniversal4096Verifier;

let pNoAaDispatcher: PNOAADispatcher;
let pRsaSha1Dispatcher: PRSASHA1Dispatcher;
let pRsaSha1Dispatcher: PRSASHADispatcher;
let pEcdsaSha1Dispatcher: PECDSASHA1Dispatcher;
let cRsaDispatcher: CRSADispatcher;

Expand Down Expand Up @@ -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(),
},
Expand All @@ -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 () => {
Expand Down
Loading