# Project export: Aros

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2024
- Tagline: Aros is an app to verify that an image is real and not AI-generated. Aros uses hardware security and cryptography to prove that an image was clicked on your iPhone.
- Devpost: https://devpost.com/software/aros-prove-your-images-are-real
- GitHub: https://github.com/siddhantsharma301/aros/
- Demo: https://aros-dashboard.vercel.app/
- Video: https://www.youtube.com/embed/1IcaMLEzCd0?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Result: winner (QED Protocol: Best Application of Zero Knowledge Proofs ($5k Cash))
- Team: 4 GitHub contributor(s) — Siddhant Sharma (17 commits), Anjan Bharadwaj (13 commits), Maanav Khaitan (8 commits), Megha Jain (3 commits)

## Devpost submission (written by the team)

### Inspiration

With the rise of AI-generated content and DeepFakes, it's hard for people to identify what's real and what's fake. This leads to fake news and abuse. After seeing the launch of OpenAI's Sora model this week, we decided to build a solution to verify whether an image is real or AI-generated.

### What it does

Aros is an iOS app that allows you to verify that an image is real and not AI-generated. It does this by cryptographically proving that you clicked an image on your iPhone, which means that the image is real. This is how it works: When you click a photo using the Aros camera app, Aros uses your iPhone's Secure Enclave to cryptographically sign this image. This signature is posted to the online Aros registry. Anyone can use this signature and your public key to verify that the photo was clicked on your iPhone, and not generated using AI. We also built a zero-knowledge prover that verifies the signature on your image within a ZK circuit. This allows any blockchain to easily verify that an image is real.

### How we built it

This is a system architecture diagram for Aros: Secure Enclave We create a cryptographic key pair in your iPhone's Secure Enclave to rely on hardware security and ensure that your private keys are never leaked outside your iPhone. Aros uses these keys to sign your photos to prove and verify that you clicked them on your iPhone. Zero-Knowledge To easily verify the image signatures on a blockchain, we decided to build a ZK verifier for this. We used state-of-the-art cryptographic systems like the SP1 RISC-V prover from Succinct Labs to verify the image signatures within a Plonky3 circuit. iOS App and Web Registry We built the iOS app using Swift. The Aros registry is used to store each image's hash and signature, along with users' public keys. It doesn't store the raw image data so we can protect privacy. We built the Aros registry using Next.js, Typescript, and Tailwind CSS. We deployed the registry dashboard and registry API using Vercel.

### Challenges we ran into

The Secure Enclave in the iPhone uses the P-256 elliptic curve but we found it hard to find a verifier ZK circuit for this curve within Circom or Halo2. So, we decided to use the SP1 RISC-V prover from Succinct Labs to verify the image signatures and generate a Plonky3 circuit. We faced challenges with base64 encoding and decoding the public key. However, we realized that we could use the base64EncodedString function in Swift to help with this.

### Accomplishments we're proud of

It was our first time developing on iOS and using Swift, so there was a pretty steep learning curve on the first day. We're really happy that we were able to learn Swift and iOS development over the weekend and successfully build this project. It was a stretch goal for us to build a zero-knowledge verifier of the P256 signature verification. We're proud that we were able to build this, and now anyone can efficiently verify that an image is real on any blockchain as well.

### What we learned

In terms of technologies, we learned iOS development, Swift, and SwiftUI, and we also learned how to work with RISC-V ZK proving systems like the SP1 prover. We learned about hardware security, specifically how to protect private keys using the Secure Enclave on iPhones.

### What's next

We want to extend this technology beyond just images, to prove that audio and video is real and not AI-generated. We have some ideas for this and we are excited to try these out soon! We plan to deploy a verifier smart contract for the ZK circuit on Ethereum. We hope to work with social media platforms to try to integrate our system since we think fake news and images are most prevalent on social media, and Aros can help reduce misinformation online.

## README (from the GitHub repository)

# Aros
Aros is an iOS app that allows you to verify that an image is real and not AI-generated. It does this by cryptographically proving that you clicked an image on your iPhone, which means that the image is real. Aros is also the reverse of [Sora](https://openai.com/sora), which is what inspired this project!

## Inspiration
With the rise of AI-generated content and DeepFakes, it's hard for people to identify what's real and what's fake. This leads to fake news and abuse. After seeing the launch of OpenAI's Sora model this week, we decided to build a solution to verify whether an image is real or AI-generated.

## What it does
Aros is an iOS app that allows you to verify that an image is real and not AI-generated. It does this by cryptographically proving that you clicked an image on your iPhone, which means that the image is real.

This is how it works:
1. When you click a photo using the Aros camera app, Aros uses your iPhone's Secure Enclave to cryptographically sign this image.  
2. This signature is posted to the online Aros registry.  
3. Anyone can use this signature and your public key to verify that the photo was clicked on your iPhone, and not generated using AI.  
We also built a zero-knowledge prover that verifies the signature on your image within a ZK circuit. This allows any blockchain to easily verify that an image is real.

## How we built it
This is a system architecture diagram for Aros:
![Aros Architecture](./assets/system-architecture.png)

### Secure Enclave
We create a cryptographic key pair in your iPhone's Secure Enclave to rely on hardware security and ensure that your private keys are never leaked outside your iPhone. Aros uses these keys to sign your photos to prove and verify that you clicked them on your iPhone.

### Zero-Knowledge
To easily verify the image signatures on a blockchain, we decided to build a ZK verifier for this. We used state-of-the-art cryptographic systems like the SP1 RISC-V prover from Succinct Labs to verify the image signatures within a Plonky3 circuit.

### iOS App and Web Registry
We built the iOS app using Swift.

The Aros registry is used to store each image's hash and signature, along with users' public keys. It doesn't store the raw image data so we can protect privacy. We built the Aros registry using Next.js, Typescript, and Tailwind CSS. We deployed the registry dashboard and registry API using Vercel.

## Challenges we ran into
- The Secure Enclave in the iPhone uses the P-256 elliptic curve but we found it hard to find a verifier ZK circuit for this curve within Circom or Halo2. So, we decided to use the SP1 RISC-V prover from Succinct Labs to verify the image signatures and generate a Plonky3 circuit.  
- We faced challenges with base64 encoding and decoding the public key. However, we realized that we could use the base64EncodedString function in Swift to help with this.

## Accomplishments that we're proud of
- It was our first time developing on iOS and using Swift, so there was a pretty steep learning curve on the first day. We're really happy that we were able to learn Swift and iOS development over the weekend and successfully build this project.  
- It was a stretch goal for us to build a zero-knowledge verifier of the P256 signature verification. We're proud that we were able to build this, and now anyone can efficiently verify that an image is real on any blockchain as well.  

## What we learned
- In terms of technologies, we learned iOS development, Swift, and SwiftUI, and we also learned how to work with RISC-V ZK proving systems like the SP1 prover.  
- We learned about hardware security, specifically how to protect private keys using the Secure Enclave on iPhones.  

## What's next for Aros
- We want to extend this technology beyond just images, to prove that audio and video is real and not AI-generated. We have some ideas for this and we are excited to try these out soon!  
- We plan to deploy a verifier smart contract for the ZK circuit on Ethereum.  
- We hope to work with social media platforms to try to integrate our system since we think fake news and images are most prevalent on social media, and Aros can help reduce misinformation online.

## Built With
- cryptography  
- ios  
- mongodb  
- next  
- rust  
- swift  
- typescript  
- zero-knowledge  


## Detected evidence (automated analysis)

Indexed codebase: 46 recognized source files, 99 KB.
- CSS (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- React (technology) — detected in the code
- Rust (language) — detected in the code
- Swift (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- MongoDB (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (75 of 75)

```
.gitignore
aros-frontend/components/gridCards.js
aros-frontend/components/imageCards.js
aros-frontend/components/shell.js
aros-frontend/next-env.d.ts
aros-frontend/next.config.js
aros-frontend/next.config.mjs
aros-frontend/package.json
aros-frontend/pages/_app.tsx
aros-frontend/pages/_document.tsx
aros-frontend/pages/api/get-images.ts
aros-frontend/pages/api/get-pubkey.ts
aros-frontend/pages/api/get-pubkeys.ts
aros-frontend/pages/api/get-signature.ts
aros-frontend/pages/api/hello.ts
aros-frontend/pages/api/post-image.ts
aros-frontend/pages/api/post-pubkey.ts
aros-frontend/pages/index.tsx
aros-frontend/postcss.config.js
aros-frontend/prisma/schema.prisma
aros-frontend/README.md
aros-frontend/styles/globals.css
aros-frontend/styles/Home.module.css
aros-frontend/tailwind.config.js
aros-frontend/tailwind.config.ts
aros-frontend/tsconfig.json
Aros.xcodeproj/project.pbxproj
Aros.xcodeproj/xcuserdata/anjanbharadwaj.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
Aros.xcodeproj/xcuserdata/anjanbharadwaj.xcuserdatad/xcschemes/xcschememanagement.plist
Aros.xcodeproj/xcuserdata/maanavkhaitan.xcuserdatad/xcschemes/xcschememanagement.plist
Aros.xcodeproj/xcuserdata/siddhant.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
Aros.xcodeproj/xcuserdata/siddhant.xcuserdatad/xcschemes/xcschememanagement.plist
Aros/ArosApp.swift
Aros/Asset.xcassets/AppIcon.appiconset/Contents.json
Aros/Asset.xcassets/aros3.imageset/Contents.json
Aros/Asset.xcassets/aroslogo.imageset/Contents.json
Aros/Asset.xcassets/Contents.json
Aros/Assets.xcassets/AccentColor.colorset/Contents.json
Aros/Assets.xcassets/AppIcon.appiconset/Contents.json
Aros/Assets.xcassets/Contents.json
Aros/CachedImageManager.swift
Aros/Camera.swift
Aros/CameraView.swift
Aros/ContentView.swift
Aros/DataModel.swift
Aros/Info.plist
Aros/PhotoAsset.swift
Aros/PhotoAssetCollection.swift
Aros/PhotoCollection.swift
Aros/PhotoCollectionView.swift
Aros/PhotoItemView.swift
Aros/PhotoLibrary.swift
Aros/PhotoView.swift
Aros/Preview Content/Preview Assets.xcassets/Contents.json
Aros/RequestManager.swift
Aros/RequestSerialization.swift
Aros/ThumbnailView.swift
Aros/ViewfinderView.swift
ArosTests/ArosTests.swift
ArosUITests/ArosUITests.swift
ArosUITests/ArosUITestsLaunchTests.swift
README.md
secp256r1-sigverify/program/Cargo.lock
secp256r1-sigverify/program/Cargo.toml
secp256r1-sigverify/program/elf/riscv32im-succinct-zkvm-elf
secp256r1-sigverify/program/secp256r1-sigverify/program/Cargo.toml
secp256r1-sigverify/program/secp256r1-sigverify/program/src/main.rs
secp256r1-sigverify/program/secp256r1-sigverify/script/Cargo.toml
secp256r1-sigverify/program/secp256r1-sigverify/script/rust-toolchain
secp256r1-sigverify/program/secp256r1-sigverify/script/src/main.rs
secp256r1-sigverify/program/src/main.rs
secp256r1-sigverify/script/Cargo.lock
secp256r1-sigverify/script/Cargo.toml
secp256r1-sigverify/script/rust-toolchain
secp256r1-sigverify/script/src/main.rs
```

### Dependencies

- aros-frontend/package.json: @headlessui/react@^1.7.17, @heroicons/react@^2.0.18, @next/font@14.0.2, @prisma/client@^5.9.1, @types/node@20.9.0, @types/react@18.2.37, @types/react-dom@18.2.15, autoprefixer@^10.4.16, eslint@8.53.0, eslint-config-next@14.0.2, ethers@^6.8.1, next@14.0.2, postcss@^8.4.31, prisma@^5.9.1, react@18.2.0, react-dom@18.2.0, react-hot-toast@^2.4.1, tailwindcss@^3.3.5, typescript@5.2.2
- secp256r1-sigverify/program/Cargo.toml: ecdsa@0.12.4, hex-literal@0.4.1, p256@0.9.0, sp1-zkvm
- secp256r1-sigverify/program/secp256r1-sigverify/program/Cargo.toml: sp1-zkvm
- secp256r1-sigverify/program/secp256r1-sigverify/script/Cargo.toml: sp1-core
- secp256r1-sigverify/script/Cargo.toml: sp1-core

### Recent commits (newest first)

- add system architecture
- Update README.md
- Merge pull request #10 from siddhantsharma301/anjan/removebackbutton
- Merge branch 'main' into anjan/removebackbutton
- increase screens
- Merge pull request #11 from siddhantsharma301/sid/modal
- progress bar
- remove button
- add icon
- add modal fullscreen for verification
- fix zk proof program
- ZK verify secp256r1 in SP1 (#9)
- Added aros-frontend folder
- Changed gitignore
- Change splash screen (#8)
- Merge pull request #7 from siddhantsharma301/sid/gallery
- gallery looks cleaner
- Merge pull request #6 from siddhantsharma301/anjan/splashfix
- stop showing all the time
- Verify button (#5)

## Key source files (fetched from GitHub, selected and truncated for size)

### aros-frontend/package.json

```
{
  "name": "aros-dashboard",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@headlessui/react": "^1.7.17",
    "@heroicons/react": "^2.0.18",
    "@next/font": "14.0.2",
    "@prisma/client": "^5.9.1",
    "@types/node": "20.9.0",
    "@types/react": "18.2.37",
    "@types/react-dom": "18.2.15",
    "eslint": "8.53.0",
    "eslint-config-next": "14.0.2",
    "ethers": "^6.8.1",
    "next": "14.0.2",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hot-toast": "^2.4.1",
    "typescript": "5.2.2"
  },
  "devDependencies": {
    "autoprefixer": "^10.4.16",
    "postcss": "^8.4.31",
    "prisma": "^5.9.1",
    "tailwindcss": "^3.3.5"
  }
}

```

### secp256r1-sigverify/script/Cargo.toml

```
[workspace]
[package]
version = "0.1.0"
name = "secp256r1-sigverify-script"
edition = "2021"

[dependencies]
sp1-core = { git = "https://github.com/succinctlabs/sp1.git" }

```

### secp256r1-sigverify/program/Cargo.toml

```
[workspace]
[package]
version = "0.1.0"
name = "secp256r1-sigverify-program"
edition = "2021"

[dependencies]
sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git" }
p256 = "0.9.0"
ecdsa = { version = "0.12.4" }
hex-literal = "0.4.1"

[patch.crates-io]
# Patch sha2 so we can use sha precompiles
sha2-v0-10-6 = { git = "https://github.com/succinctbot/RustCrypto-hashes.git", package = "sha2", branch = "main" }

```

### secp256r1-sigverify/program/secp256r1-sigverify/program/Cargo.toml

```
[workspace]
[package]
version = "0.1.0"
name = "secp256r1-sigverify-program"
edition = "2021"

[dependencies]
sp1-zkvm = { git = "https://github.com/succinctlabs/sp1.git" }
```

### secp256r1-sigverify/program/secp256r1-sigverify/script/Cargo.toml

```
[workspace]
[package]
version = "0.1.0"
name = "secp256r1-sigverify-script"
edition = "2021"

[dependencies]
sp1-core = { git = "https://github.com/succinctlabs/sp1.git" }

```

### aros-frontend/pages/index.tsx

```typescript
import Head from 'next/head'
import Image from 'next/image'
import { Inter } from '@next/font/google'
import styles from '../styles/Home.module.css'
import Shell from "../components/shell";

const inter = Inter({ subsets: ['latin'] })

export default function Home() {
  return (
    <div className="flex min-h-screen bg-slate-50">
      <Head>
        <title>Aros</title>
        <meta name="description" content="Generated by create next app" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/aroslogo.png" />
      </Head>
      <main className="bg-slate-50 w-full h-screen">
        <Shell />
      </main>
    </div>
  )
}

```

### secp256r1-sigverify/script/src/main.rs

```rust
//! A simple script to generate and verify the proof of a given program.

use sp1_core::{utils, SP1Prover, SP1Stdin, SP1Verifier};

const ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf");

fn main() {
    // Generate proof.
    utils::setup_logger();
    let stdin = SP1Stdin::new();
    let proof = SP1Prover::prove(ELF, stdin).expect("proving failed");

    // Verify proof.
    SP1Verifier::verify(ELF, &proof).expect("verification failed");

    // Save proof.
    proof
        .save("proof-with-pis.json")
        .expect("saving proof failed");

    println!("succesfully generated and verified proof for the program!")
}

```

### secp256r1-sigverify/program/src/main.rs

```rust
#![no_main]
sp1_zkvm::entrypoint!(main);

use hex_literal::hex;
use p256::ecdsa::{signature::Verifier, Signature, VerifyingKey};
use p256::EncodedPoint;

// public key is 04278497923a1ac10241832c111b95604202d1528295a55831e1e900eafd59a0c588e737d24623cc5e195443cccd87133cac5cca523ea19767ed38f6fd9ae6e666
// private key is f9c0f1127d68262fcd532d87637fa8a2cf6e8d5af48380c14ff5c6d0301f6397

fn main() {
    let public_key_hex = hex!("04278497923a1ac10241832c111b95604202d1528295a55831e1e900eafd59a0c588e737d24623cc5e195443cccd87133cac5cca523ea19767ed38f6fd9ae6e666"); // Public key should start with '04' followed by the x and y coordinates
    let signature_hex = hex!("30460221008b7a36a9a9bb5585ec1dea15af12e5c94ce7f0bda9a078c8729e8f8cc53285ec02210087b4582d1c189c9c8a0fc4eae414d63ea50e2f1047cc8465fe3b8e0345d4be0d"); // DER-encoded signature
    let message = b"aaa";

    // Decode the public key
    let verifying_key = VerifyingKey::from_encoded_point(
        &EncodedPoint::from_bytes(&public_key_hex).expect("Invalid public key"),
    )
    .expect("Failed to create verifying key");

    // Decode the signature
    let signature = Signature::from_der(&signature_hex).expect("Invalid signature format");

    // Verify the signature
    verifying_key
        .verify(message, &signature)
        .expect("Signature verification failed");

    println!("Signature verified successfully!");
}

```

### secp256r1-sigverify/program/secp256r1-sigverify/program/src/main.rs

```rust
//! A simple program to be proven inside the zkVM.

#![no_main]
sp1_zkvm::entrypoint!(main);

pub fn main() {
    let n = sp1_zkvm::io::read::<u32>();
    let mut a = 0;
    let mut b = 1;
    let mut sum;
    for _ in 1..n {
        sum = a + b;
        a = b;
        b = sum;
    }

    sp1_zkvm::io::write(&a);
    sp1_zkvm::io::write(&b);
}

```

### secp256r1-sigverify/program/secp256r1-sigverify/script/src/main.rs

```rust
//! A simple script to generate and verify the proof of a given program.

use sp1_core::{SP1Prover, SP1Stdin, SP1Verifier};

const ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf");

fn main() {
    // Generate proof.
    let mut stdin = SP1Stdin::new();
    let n = 500u32;
    stdin.write(&n);
    let mut proof = SP1Prover::prove(ELF, stdin).expect("proving failed");

    // Read output.
    let a = proof.stdout.read::<u32>();
    let b = proof.stdout.read::<u32>();
    println!("a: {}", a);
    println!("b: {}", b);

    // Verify proof.
    SP1Verifier::verify(ELF, &proof).expect("verification failed");

    // Save proof.
    proof
        .save("proof-with-io.json")
        .expect("saving proof failed");

    println!("succesfully generated and verified proof for the program!")
}

```

[39 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]