rooch-network / rooch

VApp Container with Move Language
https://rooch.network
Apache License 2.0
128 stars 54 forks source link

Web2 Social login #769

Open jolestar opened 8 months ago

jolestar commented 8 months ago

Part of #460

zk solution issues

oauth login issues

Web2 platform

Reference

Discussion

https://discord.com/channels/1078938449974935592/1167295291746173029

yubing744 commented 7 months ago

I'll try this task

yubing744 commented 7 months ago

@jolestar I drew a data flow diagram using Rooch to implement zkLogin (privacy is not guaranteed):

image

yubing744 commented 7 months ago

Rooch implements the OAuth login process:

  1. The user authenticates their identity through the OAuthProvider and obtains a JWT.

  2. Using the RoochSDK, the user generates a zero-knowledge proof that they possess a valid JWT without revealing the content of the JWT. This proof includes a proof and some public signals, such as nonceValid, jwtValid, and roochAddress.

  3. The user creates a CreateSessionKey transaction using the RoochSDK, including the public key, zero-knowledge proof, public signals, expiration time, and the scopes that define the modules on the chain that the session key can access.

  4. The RoochSDK sends the transaction to the RoochServer. The RoochServer uses the JWTZKProofAuthValidator validator to validate this transaction. If the transaction is invalid, the validator will throw an error.

  5. If the transaction is valid, the RoochServer stores the public key and the associated scopes in the user's Rooch account. The user retains the private key for subsequent transactions.

  6. The user can use their private key to initiate new transactions via the RoochSDK within the defined scopes until the Session Key expires.

This process ensures that users can authenticate their identity on the Rooch chain using their OAuthProvider account while protecting their privacy. Zero-knowledge proof allows users to prove that they have a valid JWT without revealing the content of the JWT. In addition, by using the Session Key and defining scopes, users can initiate multiple transactions over a period of time without having to authenticate their identity each time, and the access to the modules on the chain is controlled.

yubing744 commented 7 months ago

The zero-knowledge proof circuit should include the following logic:

The zero-knowledge circuit should accept the following input parameters:

  1. JWT: The JSON Web Token obtained by the user from the OAuthProvider.

  2. OAuthProvider Public Key: The public key used to verify the JWT signature.

  3. Issuer Public Key: The public key used to verify the JWT issuer.

  4. sequence_number: The sequence_number of the user's Rooch account, used to generate public signals and prevent replay attacks.

The zero-knowledge circuit should perform the following operations:

  1. Verify the signature using the OAuthProvider's public key and the header and payload of the JWT.

  2. Verify the issuer using the predefined issuer public key.

  3. Verify whether the JWT has expired.

  4. Generate roochAddress based on the information in the JWT.

  5. Generate some public signals, such as sequence_number, jwtValid, and roochAddress.

The zero-knowledge circuit should output the following parameters:

  1. Zero-knowledge proof: A proof that the user has a valid JWT, without revealing the content of the JWT.

  2. Public signals: Including sequence_number, jwtValid, and roochAddress.

yubing744 commented 7 months ago

Reference circuit implementation:

include "../../node_modules/circomlib/circuits/eddsaproof.circom";
include "../../node_modules/circomlib/circuits/comparators.circom";
include "../../node_modules/circomlib/circuits/merklehash.circom";

template VerifyJWT() {

  // Input signals  
  signal input jwt;
  signal input oauthPubKey; 
  signal input issuerPubKey;
  signal input sequence_number;

  // 1. Verify signature
  component verifySignature = EDDsaVerify();
  verifySignature.pubKey <== oauthPubKey;
  verifySignature.signature <== jwt.signature;
  verifySignature.msgHash <== jwt.header && jwt.payload;

  // 2. Verify issuer
  component verifyIssuer = EdDSAPubKeyEq();
  verifyIssuer.in[0] <== issuerPubKey;
  verifyIssuer.in[1] <== jwt.header.iss;

  // 3. Check expiration 
  component isExpired = LessThan(64);
  isExpired.in[0] <== jwt.payload.exp;
  isExpired.in[1] <== now;

  // 4. Generate roochAddress
  component generateAddress = Pedersen(21888242871839275222246405745257275088548364400416034343698204186575808495617);
  generateAddress.in <== sequence_number;

  // 5. Generate public signals
  signal jwtValid = verifySignature.out && verifyIssuer.out && !isExpired.out;
  signal roochAddress = generateAddress.out;

  // Output signals
  signal output zkProof; 
  signal output sequence_number;
  signal output jwtValid;
  signal output roochAddress;

}

component main {public} = VerifyJWT();
feliciss commented 7 months ago

I feel like using Halo2 from zcash might be a more succinct solution in the future?

https://github.com/zcash/halo2

yubing744 commented 7 months ago

I feel like using Halo2 from zcash might be a more succinct solution in the future?

https://github.com/zcash/halo2

I considered snarkjs because the game Dark Forest also uses this library. snarkjs uses circom to write verification circuits and compile them into wasm files, which can generate proofs directly in the browser.

I don’t know much about Halo2, can you elaborate on the advantages of Halo2?

feliciss commented 7 months ago

I feel like using Halo2 from zcash might be a more succinct solution in the future? https://github.com/zcash/halo2

I considered snarkjs because the game Dark Forest also uses this library. snarkjs uses circom to write verification circuits and compile them into wasm files, which can generate proofs directly in the browser.

I don’t know much about Halo2, can you elaborate on the advantages of Halo2?

Halo2 is a PLONKish arithmetization scheme zero-knowledge proof which produces larger size of proofs than Groth16, does not require trusted setups and can be used to customize custom gates and lookup tables.

There's an article describing the efficiency of each ZKP frameworks, PLONKish, R1CS, etc.:

https://ethresear.ch/t/benchmarking-zkp-development-frameworks-the-pantheon-of-zkp/14943

Here's an implementation using WASM with Halo2:

https://github.com/axiom-crypto/halo2-wasm/tree/main

feliciss commented 7 months ago

I may help design with you together for this issue. @yubing744

yubing744 commented 7 months ago

@feliciss Does Sui use Halo2 or circom? I found that zkemail(https://github.com/zkemail/) also tried to adopt Halo2

yubing744 commented 7 months ago

@jolestar sui supports Zero-knowledge proof verification (Groth16)

yubing744 commented 7 months ago

RSA verification circuit implementation reference:

yubing744 commented 6 months ago

@jolestar @feliciss I have completed the JWT verify circuit and passed the unit test.

https://github.com/yubing744/rooch/blob/feature-owen-zklogin-circuit-verify/sdk/zklogin/circuits/zklogin/tests/jwt.test.ts

image

feliciss commented 6 months ago

@feliciss Does Sui use Halo2 or circom? I found that zkemail(https://github.com/zkemail/) also tried to adopt Halo2

No. Sui uses Groth16 that's different from PLONKish implementation. Sorry for the late reply.

yubing744 commented 6 months ago

@feliciss Does Sui use Halo2 or circom? I found that zkemail(https://github.com/zkemail/) also tried to adopt Halo2

No. Sui uses Groth16 that's different from PLONKish implementation. Sorry for the late reply.

circom also supports generating Groth16 proofs. We plan to implement Rooch’s Groth16 verification with reference to Sui.