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

Generalize Test #12

Open
wants to merge 26 commits into
base: feature/base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
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
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_form_template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Bug report
description: File a bug report
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Please ensure that the bug has not already been filed in the issue tracker.
- type: input
attributes:
label: What command(s) is the bug in?
description: Leave empty if not relevant
placeholder: "For example: make test"
- type: textarea
attributes:
label: Describe the bug
description: Please include relevant code snippets as well if relevant.
validations:
required: true
- type: textarea
attributes:
label: Concrete steps to reproduce the bug. If it's able reproduce via testool, please share `test_id` from jenkins report
description: Leave empty if not relevant
18 changes: 18 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_form_template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Feature request
description: Suggest a feature
labels: ["feature"]
body:
- type: markdown
attributes:
value: |
Please ensure that the feature has not already been requested in the issue tracker.
- type: textarea
attributes:
label: Describe the feature you would like
description: Please also describe what the feature is aiming to solve, if relevant.
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add any other context to the feature (like screenshots, resources)
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/research_form_template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Research
description: Share the Research
labels: ["research"]
body:
- type: textarea
attributes:
label: What's the purpose of this research?
description: explain what you want to make sure on this research (please itemize)
placeholder: ex) to make sure what is the difference between A and B
validations:
required: true
- type: textarea
attributes:
label: Concrete milestone by steps
description: explain what we need to do to achieve this research
placeholder: ex) 1. test the library
validations:
required: true
- type: textarea
attributes:
label: Describe references if exists
description: Please refer the related papers, articles or implementations if you know
- type: markdown
attributes:
value: Please share the progress/result on the comment below!
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# MynaWallet Halo2 Circuits

This repository aims to create proofs which verifies the RSA signatures signed by Myna Card(Japan's ID Card).

## Getting Started

For a brief introduction to zero-knowledge proofs (ZK), see this [doc](https://docs.axiom.xyz/zero-knowledge-proofs/introduction-to-zk).

Halo 2 is written in Rust, so you need to [install](https://www.rust-lang.org/tools/install) Rust to use this library:

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

Clone this repo and start off in the `halo2-circuits` directory.

```bash
git clone [email protected]:MynaWallet/halo2-circuits.git
cd halo2-circuits
```

## Run test

```bash
cargo test -- --nocapture
```

## Benchmarks

```bash
cargo bench
```

Result Not Yet

## Milestones

- ✅ RSA Verification Circuit Base
- RSA Verification Circuit (SHA2 Hash as input)
- Test & Benchmarks
- Verifier Contracts
- Example Codes which call Prover
- (Phase2) RSA Verification Circuit (DER-encoded certificate as input)
- (Phase3) Selective Disclosure

See more details on the [issues](https://github.com/MynaWallet/halo2-circuits/issues)

## Workspace

Please make sure to cut your own branch from `feature/base`.

## Specs

- [Signature Verification](./spec/SignatureVerification.md)

## References

You can refer to these repos of RSA verification circuits.

- [halo2-rsa](https://github.com/zkemail/halo2-rsa/tree/feat/new_bigint)
- [zk-email-verify](https://github.com/zkemail/zk-email-verify)
27 changes: 27 additions & 0 deletions spec/SignatureVerification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# RSA Signature Verification Circuit

The Circuit which Verifies RSA signature.

## Overview

This is the circuit overview.
(The input will change in phase2.)

```mermaid
flowchart LR
hashed-->verify_signature
signature-->verify_signature
modulus-->verify_signature
subgraph circuit
verify_signature
end
verify_signature-->ok
```

## Functions

- `verify_signature()`: verify RSA signature and return assigned set values if signature is valid

## How verify_signature() works

(add it later)
140 changes: 111 additions & 29 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,69 +154,151 @@ mod test {
use rand::thread_rng;
use rand::Rng;
use rsa::{Hash, PaddingScheme, PublicKeyParts, RsaPrivateKey, RsaPublicKey};
use sha2::digest::Output;
use sha2::{Digest, Sha256};

#[test]
fn test_signature_verification() {
fn test_gen_key() -> (RsaPublicKey, RsaPrivateKey) {
let bits = 2048;

// 1. Generate a key pair.
let mut rng = thread_rng();

// let mut rng = thread_rng();
let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
let public_key = RsaPublicKey::from(&private_key);

// 2. Uniformly sample a message.
let mut msg: [u8; 128] = [0; 128];
for x in &mut msg[..] {
*x = rng.gen();
}

// 3. Compute the SHA256 hash of `msg`.
let hashed_msg = Sha256::digest(msg);
(public_key, private_key)
}

// 4. Generate a pkcs1v15 signature.
fn test_sign(private_key: RsaPrivateKey, hashed_msg: Output<Sha256>) -> Vec<u8> {
let padding = PaddingScheme::PKCS1v15Sign {
hash: Some(Hash::SHA2_256),
};
let sign = private_key

private_key
.sign(padding, &hashed_msg)
.expect("fail to sign a hashed message.");
.expect("fail to sign a hashed message.")
}

let public_key_n = BigUint::from_bytes_be(&public_key.n().clone().to_bytes_be());
fn test_hash_rng() -> Output<Sha256> {
let mut rng = thread_rng();
let mut msg: [u8; 128] = [0; 128];
for x in &mut msg[..] {
*x = rng.gen();
}
Sha256::digest(msg)
}

fn test_hash_msg(msg: Vec<u8>) -> Output<Sha256> {
Sha256::digest(msg)
}

// 公開鍵をVec<Fr>に変換
let pub_key_vec = public_key
.n()
.clone()
.to_bytes_be()
fn str2field(a: Vec<u8>) -> Vec<Fr> {
let res = a
.to_vec()
.iter()
.map(|v| Fr::from(*v as u64))
.collect::<Vec<Fr>>();

// 署名をVec<Fr>に変換
let sign_vec = sign
res
}

fn hash2field(a: Output<Sha256>) -> Vec<Fr> {
let res = a
.to_vec()
.iter()
.map(|v| Fr::from(*v as u64))
.collect::<Vec<Fr>>();

// ハッシュされたメッセージをVec<Fr>に変換
let hashed_vec = hashed_msg
res
}

#[test]
fn test_signature_verification() {
let (public_key, private_key) = test_gen_key();
let hashed_msg = test_hash_rng();
let sign = test_sign(private_key, hashed_msg);
let public_key_n = BigUint::from_bytes_be(&public_key.n().clone().to_bytes_be());

// Frに変換
let pub_key_vec = str2field(public_key.n().clone().to_bytes_be());
let sign_vec = str2field(sign.clone());
let hashed_msg_vec = hash2field(hashed_msg.clone());

// 公開鍵、署名、ハッシュされたメッセージを結合
let public_inputs = pub_key_vec
.iter()
.map(|v| Fr::from(*v as u64))
.chain(sign_vec.iter())
.chain(hashed_msg_vec.iter())
.cloned()
.collect::<Vec<Fr>>();

let circuit =
DefaultMynaCircuit::<Fr>::new(
hashed_msg.to_vec(),
sign.to_vec(),
public_key_n
);
let prover = MockProver::run(19, &circuit, vec![public_inputs]).unwrap();
assert_eq!(prover.verify(), Ok(()));
}

#[test]
fn test_invalid_signature_verification() {
let (public_key, private_key) = test_gen_key();
let hashed_msg = test_hash_rng();
let hashed_msg_2 = test_hash_msg("hellohellohello".into());
let sign = test_sign(private_key, hashed_msg);
let public_key_n = BigUint::from_bytes_be(&public_key.n().clone().to_bytes_be());

// Frに変換
let pub_key_vec = str2field(public_key.n().clone().to_bytes_be());
let sign_vec = str2field(sign.clone());
let hashed_msg_vec = hash2field(hashed_msg_2.clone()); // set different message from sign

// 公開鍵、署名、ハッシュされたメッセージを結合
let public_inputs = pub_key_vec
.iter()
.chain(sign_vec.iter())
.chain(hashed_vec.iter())
.chain(hashed_msg_vec.iter())
.cloned()
.collect::<Vec<Fr>>();

let circuit =
DefaultMynaCircuit::<Fr>::new(hashed_msg.to_vec(), sign.to_vec(), public_key_n);
DefaultMynaCircuit::<Fr>::new(
hashed_msg_2.to_vec(), // different message from signature
sign.to_vec(),
public_key_n
);
let prover = MockProver::run(19, &circuit, vec![public_inputs]).unwrap();
assert_eq!(prover.verify(), Ok(()));
assert!(prover.verify().is_err());
}

#[test]
fn test_invalid_instance() {
let (public_key, private_key) = test_gen_key();
let hashed_msg = test_hash_rng();
let sign = test_sign(private_key, hashed_msg);
let public_key_n = BigUint::from_bytes_be(&public_key.n().clone().to_bytes_be());

// Frに変換
let pub_key_vec = vec![Fr::from(3274), Fr::from(32344)];
let sign_vec = vec![Fr::from(3274), Fr::from(32344)];
let hashed_msg_vec = vec![Fr::from(3274), Fr::from(32344)];

// 公開鍵、署名、ハッシュされたメッセージを結合
let public_inputs = pub_key_vec
.iter()
.chain(sign_vec.iter())
.chain(hashed_msg_vec.iter())
.cloned()
.collect::<Vec<Fr>>();

let circuit =
DefaultMynaCircuit::<Fr>::new(
hashed_msg.to_vec(),
sign.to_vec(),
public_key_n
);
let prover = MockProver::run(19, &circuit, vec![public_inputs]).unwrap();
assert!(prover.verify().is_err());
}
Comment on lines +276 to 303
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test now fails because the circuit passes any instances

}