Skip to content

Commit

Permalink
added ecdsa dispatcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Arvolear committed Apr 25, 2024
1 parent 8abb5af commit 7f3a9f9
Show file tree
Hide file tree
Showing 9 changed files with 626 additions and 7 deletions.
404 changes: 404 additions & 0 deletions contracts/authenticators/ECDSASHA1Authenticator.sol

Large diffs are not rendered by default.

78 changes: 78 additions & 0 deletions contracts/dispatchers/ECDSASHA1Dispatcher.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import {PoseidonUnit2L} from "@iden3/contracts/lib/Poseidon.sol";

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

import {VerifierHelper} from "@solarity/solidity-lib/libs/zkp/snarkjs/VerifierHelper.sol";

import {IPassportDispatcher} from "../interfaces/dispatchers/IPassportDispatcher.sol";
import {ECDSASHA1Authenticator} from "../authenticators/ECDSASHA1Authenticator.sol";

contract ECDSASHA1Dispatcher is IPassportDispatcher, Initializable {
using VerifierHelper for address;

address public authenticator;
address public verifier;

function __ECDSASHA1Dispatcher_init(
address authenticator_,
address verifier_
) external initializer {
authenticator = authenticator_;
verifier = verifier_;
}

function authenticate(
bytes memory challenge_,
bytes memory passportSignature_,
bytes memory passportPublicKey_
) external view returns (bool) {
uint256 r_;
uint256 s_;
uint256 x_;
uint256 y_;

assembly {
r_ := mload(add(passportSignature_, 32))
s_ := mload(add(passportSignature_, 64))

x_ := mload(add(passportPublicKey_, 32))
y_ := mload(add(passportPublicKey_, 64))
}

return ECDSASHA1Authenticator(authenticator).authenticate(challenge_, r_, s_, x_, y_);
}

function verifyZKProof(
uint256[] memory pubSignals_,
VerifierHelper.ProofPoints memory zkPoints_
) external view returns (bool) {
return verifier.verifyProof(pubSignals_, zkPoints_);
}

function getPassportChallenge(
uint256 identityKey_
) external pure returns (bytes memory challenge_) {
challenge_ = new bytes(8);

for (uint256 i = 0; i < challenge_.length; ++i) {
challenge_[challenge_.length - i - 1] = bytes1(uint8(identityKey_ >> (8 * i)));
}
}

function getPassportKey(bytes memory passportPublicKey_) external pure returns (uint256) {
uint256[2] memory decomposed_;

assembly {
mstore(decomposed_, mload(add(passportPublicKey_, 32)))
mstore(add(decomposed_, 32), mload(add(passportPublicKey_, 64)))
}

decomposed_[0] %= 2 ** 248;
decomposed_[1] %= 2 ** 248;

return PoseidonUnit2L.poseidon(decomposed_);
}
}
1 change: 1 addition & 0 deletions contracts/registration/PassportTypes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pragma solidity 0.8.16;

bytes32 constant RSA_SHA1_2688 = keccak256("RSA_SHA1_2688");
bytes32 constant RSA_SHA1_2704 = keccak256("RSA_SHA1_2704");
bytes32 constant ECDSA_SHA1_2704 = keccak256("ECDSA_SHA1_2704");
19 changes: 18 additions & 1 deletion deploy/1_setup.migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import { deployPoseidons } from "./helpers/helper";
import {
Registration__factory,
RSASHA1Dispatcher__factory,
ECDSASHA1Dispatcher__factory,
RSASHA1Authenticator__factory,
ECDSASHA1Authenticator__factory,
RSASHA12688Verifier__factory,
RSASHA12704Verifier__factory,
VerifierMock__factory,
} from "@ethers-v6";

import { RSA_SHA1_2688, RSA_SHA1_2704 } from "@/scripts/utils/passport-types";
import { ECDSA_SHA1_2704, RSA_SHA1_2688, RSA_SHA1_2704 } from "@/scripts/utils/passport-types";

const treeHeight = 80;
const tssSigner = "0x038D006846a3e203738cF80A02418e124203beb2";
Expand All @@ -35,21 +38,35 @@ const deployRSASHA12704Dispatcher = async (deployer: Deployer) => {
return dispatcher;
};

const deployECDSASHA1Dispatcher = async (deployer: Deployer) => {
const verifier = await deployer.deploy(VerifierMock__factory);
const authenticator = await deployer.deploy(ECDSASHA1Authenticator__factory);
const dispatcher = await deployer.deploy(ECDSASHA1Dispatcher__factory);

await dispatcher.__ECDSASHA1Dispatcher_init(await authenticator.getAddress(), await verifier.getAddress());

return dispatcher;
};

export = async (deployer: Deployer) => {
await deployPoseidons(deployer, [1, 2, 3, 5]);

const rsaSha12688Dispatcher = await deployRSASHA12688Dispatcher(deployer);
const rsaSha12704Dispatcher = await deployRSASHA12704Dispatcher(deployer);
const ecdsaSha1Dispatcher = await deployECDSASHA1Dispatcher(deployer);

const registration = await deployer.deploy(Registration__factory);

await registration.__Registration_init(treeHeight, tssSigner, icaoMasterTreeMerkleRoot);

await registration.addDispatcher(RSA_SHA1_2688, await rsaSha12688Dispatcher.getAddress());
await registration.addDispatcher(RSA_SHA1_2704, await rsaSha12704Dispatcher.getAddress());
await registration.addDispatcher(ECDSA_SHA1_2704, await ecdsaSha1Dispatcher.getAddress());

Reporter.reportContracts(
["Registration", `${await registration.getAddress()}`],
["RSASHA12688Dispatcher", `${await rsaSha12688Dispatcher.getAddress()}`],
["RSASHA12704Dispatcher", `${await rsaSha12704Dispatcher.getAddress()}`],
["ECDSASHA1Dispatcher", `${await ecdsaSha1Dispatcher.getAddress()}`],
);
};
1 change: 1 addition & 0 deletions scripts/utils/passport-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ import { ethers } from "hardhat";

export const RSA_SHA1_2688 = ethers.solidityPackedKeccak256(["string"], ["RSA_SHA1_2688"]);
export const RSA_SHA1_2704 = ethers.solidityPackedKeccak256(["string"], ["RSA_SHA1_2704"]);
export const ECDSA_SHA1_2704 = ethers.solidityPackedKeccak256(["string"], ["ECDSA_SHA1_2704"]);
34 changes: 34 additions & 0 deletions test/authenticators/ECDSASHA1Authenticator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ethers } from "hardhat";
import { expect } from "chai";
import { Reverter } from "@/test/helpers/";

import { ECDSASHA1Authenticator } from "@ethers-v6";

describe("RSASHA1Authenticator", () => {
const reverter = new Reverter();

let auth: ECDSASHA1Authenticator;

before("setup", async () => {
const ECDSASHA1Authenticator = await ethers.getContractFactory("ECDSASHA1Authenticator");

auth = await ECDSASHA1Authenticator.deploy();

await reverter.snapshot();
});

afterEach(reverter.revert);

describe("#authenticate", () => {
it("should authenticate passport", async () => {
const challenge = "0xe7938ea62eb1980a";

const r = "0x13DCD0CCE676DFB4C2EF2B26F3AC8BB640146391C12EC80E052ABA2D617A5888";
const s = "0x4060930A62757DC2003F4CAA38E9CFF44001E2B3D7286E03CA119B1AD7A680B1";
const x = "0x69501be7dac08517dfe4a44e1952cc9f5b21d22cbe4d3db26ea22542afbf8548";
const y = "0x3d72a4671baa4bcd74f4cdc71bf6fe45a9ddaf50c5f6e3327078c90da2fcb304";

expect(await auth.authenticate(challenge, r, s, x, y)).to.be.true;
});
});
});
88 changes: 88 additions & 0 deletions test/dispatchers/ECDSASHA1Dispatcher.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { ethers } from "hardhat";
import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
import { expect } from "chai";
import { Reverter, getPoseidon } from "@/test/helpers/";

import { ECDSASHA1Dispatcher } from "@ethers-v6";
import { VerifierHelper } from "@/generated-types/ethers/contracts/dispatchers/RSASHA1Dispatcher";

describe("ECDSASHA1Dispatcher", () => {
const reverter = new Reverter();

let OWNER: SignerWithAddress;

let dispatcher: ECDSASHA1Dispatcher;

before("setup", async () => {
[OWNER] = await ethers.getSigners();

const ECDSASHA1Verifier = await ethers.getContractFactory("VerifierMock");
const ECDSASHA1Authenticator = await ethers.getContractFactory("ECDSASHA1Authenticator");
const ECDSASHA1Dispatcher = await ethers.getContractFactory("ECDSASHA1Dispatcher", {
libraries: {
PoseidonUnit2L: await (await getPoseidon(2)).getAddress(),
},
});

dispatcher = await ECDSASHA1Dispatcher.deploy();

const ecdsaSha1Verifier = await ECDSASHA1Verifier.deploy();
const ecdsaSha1Authenticator = await ECDSASHA1Authenticator.deploy();
dispatcher = await ECDSASHA1Dispatcher.deploy();

await dispatcher.__ECDSASHA1Dispatcher_init(
await ecdsaSha1Authenticator.getAddress(),
await ecdsaSha1Verifier.getAddress(),
);

await reverter.snapshot();
});

afterEach(reverter.revert);

describe("#init", () => {
it("should not init twice", async () => {
expect(
dispatcher.__ECDSASHA1Dispatcher_init(
ethers.hexlify(ethers.randomBytes(20)),
ethers.hexlify(ethers.randomBytes(20)),
),
).to.be.revertedWith("Initializable: contract is already initialized");
});
});

describe("#authenticate", () => {
it("should authenticate", async () => {
const challenge = "0xe7938ea62eb1980a";
const signature =
"0x13DCD0CCE676DFB4C2EF2B26F3AC8BB640146391C12EC80E052ABA2D617A58884060930A62757DC2003F4CAA38E9CFF44001E2B3D7286E03CA119B1AD7A680B1";
const publicKey =
"0x69501be7dac08517dfe4a44e1952cc9f5b21d22cbe4d3db26ea22542afbf85483d72a4671baa4bcd74f4cdc71bf6fe45a9ddaf50c5f6e3327078c90da2fcb304";

expect(await dispatcher.authenticate(challenge, signature, publicKey)).to.be.true;
});
});

describe("#zkProof", () => {
it("should verify the zk proof", async () => {});
});

describe("#getPassportChallenge", () => {
it("should get the challenge correctly", async () => {
const input = "0xced3831dcf3a96049d93cbbd3eaa0010f3b97a70ef591269c8975afb4717e5";
const result = "0x69c8975afb4717e5";

expect(await dispatcher.getPassportChallenge(input)).to.equal(result);
});
});

describe("#getPassportKey", () => {
it("should get the key correctly", async () => {
const input =
"0x69501be7dac08517dfe4a44e1952cc9f5b21d22cbe4d3db26ea22542afbf85483d72a4671baa4bcd74f4cdc71bf6fe45a9ddaf50c5f6e3327078c90da2fcb304";
const result = "0x817879ff35b4a000f9207ff2be1a85c9fd39c01ac669aa7c2f6c4b743f8a168";

expect(await dispatcher.getPassportKey(input)).to.equal(result);
});
});
});
4 changes: 1 addition & 3 deletions test/dispatchers/RSASHA1Dispatcher.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ethers } from "hardhat";
import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
import { expect } from "chai";
import { Reverter, deployPoseidons, getPoseidon } from "@/test/helpers/";
import { Reverter, getPoseidon } from "@/test/helpers/";

import { RSASHA1Dispatcher } from "@ethers-v6";
import { VerifierHelper } from "@/generated-types/ethers/contracts/dispatchers/RSASHA1Dispatcher";
Expand All @@ -16,8 +16,6 @@ describe("RSASHA1Dispatcher", () => {
before("setup", async () => {
[OWNER] = await ethers.getSigners();

await deployPoseidons(OWNER, [5], false);

const RSASHA1Verifier = await ethers.getContractFactory("RSASHA12688Verifier");
const RSASHA1Authenticator = await ethers.getContractFactory("RSASHA1Authenticator");
const RSASHA1Dispatcher = await ethers.getContractFactory("RSASHA1Dispatcher", {
Expand Down
4 changes: 1 addition & 3 deletions test/registration/Registration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ethers } from "hardhat";
import { HDNodeWallet } from "ethers";
import { expect } from "chai";
import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers";
import { Reverter, deployPoseidons, getPoseidon } from "@/test/helpers/";
import { Reverter, getPoseidon } from "@/test/helpers/";
import { RSA_SHA1_2688 } from "@/scripts/utils/passport-types";

import { Registration, RegistrationMock, RSASHA1Dispatcher } from "@ethers-v6";
Expand Down Expand Up @@ -58,8 +58,6 @@ describe("Registration", () => {
[OWNER, SECOND] = await ethers.getSigners();
SIGNER = ethers.Wallet.createRandom();

await deployPoseidons(OWNER, [1, 2, 3, 5], false);

const Registration = await ethers.getContractFactory("RegistrationMock", {
libraries: {
PoseidonUnit1L: await (await getPoseidon(1)).getAddress(),
Expand Down

0 comments on commit 7f3a9f9

Please sign in to comment.