incentive-system

A cryptographic incentive system.

https://github.com/cryptimeleon/incentive-system

Science Score: 44.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (10.0%) to scientific vocabulary

Keywords

android crypto docker java jetpack-compose kotlin spring-boot
Last synced: 6 months ago · JSON representation ·

Repository

A cryptographic incentive system.

Basic Info
  • Host: GitHub
  • Owner: cryptimeleon
  • License: apache-2.0
  • Language: Java
  • Default Branch: main
  • Homepage:
  • Size: 61 MB
Statistics
  • Stars: 4
  • Watchers: 2
  • Forks: 0
  • Open Issues: 31
  • Releases: 1
Topics
android crypto docker java jetpack-compose kotlin spring-boot
Created about 5 years ago · Last pushed over 1 year ago
Metadata Files
Readme License Citation

README.md

Cryptimeleon Incentive System main

This project is an implementation of a privacy-preserving incentive system (loyalty/point-collection system). It is based on the Privacy-Preserving Incentive Systems with Highly Efficient Point-Collection paper published in 2020 with improvements for real-world scenarios. Our incentive system for retail stores rewards users for their shopping behavior, e.g. for buying certain products or shopping regularly. In contrast to currently deployed incentive systems, it protects users' privacy using cryptography.

The core of our implementation is an Android app that realizes the shopping process of scanning product barcodes, paying in the app, and showing a QR code as proof of payment upon leaving the store.

See https://incentimeleon.cryptimeleon.org for more details.

Walkthrough

We provide a walkthrough of a user's view of the system during a shopping:

Onboarding

On the first startup, the user goes through the onboarding process, needs to register once with their name, and can potentially change the deployment's URL. Then, the app generates keys and registers the user with their identity. Note that this identity cannot be linked with transactions and is only used to trace users who attempt a double-spending attack.

Shopping

The user has joined the system. In the background, the app queried all running promotions (campaigns) and joined each promotion which means that the user has an empty token for each promotion on their phone. Now, the user can go shopping: For this, they go to the scanner view, give the app access to the camera, and scan products while going through the store. This process resembles new retail technology where users can scan products along the go, pay, and leave the store, all without interacting with a cashier or cash register. For demo purposes, we provide the barcodes on the incentive system's web frontend. After scanning, the user can select updates to their promotions that apply, e.g. collect 1 point for the hazelnut spread in the basket. Further, they can view the privacy implications of the selected updates in the privacy details view. On checkout, the app runs the crypto protocols and payment process and then displays a QR code of the corresponding basket. This serves as proof/receipt when leaving the store and for claiming physical rewards.

Promotions

A core concept of the business logic of our incentive system is the concept of promotions. For each token that a user has, there is a respective promotion with well-defined rules. Our prototype currently supports three types of promotions: 1. VIP promotion: Users earn points for spending money. After reaching a certain amount, they reach a VIP level (Bronze, Silver, Gold) that enables permanent effects like discounts. 2. Point count promotions: Point count promotions are the simplest promotions. Users can collect points, e.g. for buying certain items, and spend points to get rewards. Our Hazelspread promotion is such a promotion: For every four jars of hazelnut spread users get one for free. 3. Streak promotion: Users can build up a streak by shopping within seven days of the last visit. Having a certain streak enables rewards.

In the app, users can see their current state in all running promotions and which rewards they are eligible to get. Further, we display a token id, a hash of the current token, which is similar to a GitHub commit hash.

Double-spending Attacks

The canonical attack to our incentive system is a double-spending attack: An attack, where an attacker copies a digital token and spends it twice to either obtain two valid remainder tokens and therefore double their money, or to claim some reward twice and therefore get more than the token is worth. We implement attack capabilities in our app to showcase how our system handles these attacks. Note that in a real-world deployment, some of these attacks would only be possible with timing attacks (i.e. within a small period until services synchronize data), or in case a store goes offline.

For the first attack scenario, the attacker enables the discard remainder token and store after payment options in the apps attack ui. This tells the app to use the current token until deactivated, instead of replacing it with a new token after a transaction. In the example, the attacker has enough points to get a reward and claims it at the store. If they try to spend the same token again at the same store, they get caught and their identity leaks, we show this later. However, they can go to another store (in our case change the current store in the settings), and spend the token again to get a second reward. After some time, the stores synchronize their transaction data and find this double-spending attack. The link algorithm extracts the attacker's identity such that stores can reclaim the stolen rewards with legal measures.

In the second attack scenario, the attacker wants to take a token T1 worth 16 and spend 4 points twice to get two valid tokens T2 each worth 12 points. These would be worth 24 in total and thus the attacker would have stolen 8 points. To try this, the attacker enables the discard remainder token option in the double-spending options. Then, they do the first spend transaction at the first store, which is successful. Then, they switch the store and try to get another remainder token. This attempt is blocked directly by the provider service, which is the only service that can update tokens and prevents this attack with a blacklist. Further, the attacker again leaked their identity and can be penalized for this double-spending attempt.

We previously mentioned that attackers' identities leak during double-spending attacks. For this, we have a web frontend with an overview of all registered users and their public keys. During double-spending, the corresponding secret key leaks and stores can identify attackers. Every store has a UI that displays all baskets and marks baskets that are associated with a double-spending attack in red. For this prototype, we only use a name to identify users, however, in the real world, this could be enriched with more information.

Developing

This project consists of an android app developed with Kotlin and Jetpack Compose, multiple Spring Boot services and packages for the cryptographic protocols and business logic (promotions). The cryptographic protocols are powered by cryptimeleon.

Building

To build the project, you need Java 11 and Android SDK 33 (can be installed with sdkmanager or via Android Studio).

Benchmark

To run a benchmark, install mcl following these instructions and run ./gradlew :crypto:benchmark.

Swagger API

When you start the services (either locally or via docker), you can access the swagger api page at basepath/swagger-ui/index.html.

Creating promotions and choosing images

You can configure own promotion-sets in the bootstrap service. To add images, put the image in the web/public/assets/ folder. Use the promotionname in lower case with spaces replaced by underscores and choose the jpg format. For a promotion named Christmas Promotion, name the image `christmaspromotion.jpg`.

Deployment

Services

We provide docker images of the services for custom deployments. To deploy the incentive-system follow these steps (tested on linux and macOS): 0. Install docker (tested on version 20.10.12) and docker-compose (tested on version 1.29.2) 1. Checkout this repository (you only need the contents of the deployment folder) 2. Change the HOST variable in deployment/deploy.sh to your server's url or localhost:8009 for a local installation 3. Run ./deployment/deploy.sh 4. The deployment runs at port 8009

If you want to build docker images locally, you can use the command ./deployment/build-docker-images.sh.

App

You can change the deployment's url in app/build.gradle by setting the deploymentBaseUrl variable before building. For local deployments, use the naming scheme http://xxx.xxx.xxx.xxx:8009 and add the line android:usesCleartextTraffic="true" to the AndroidManifest.xml to enable http.

License

Apache License 2.0, see LICENSE file.

Acknowledgements

We developed this project at Paderborn University within the transfer project T2 of the CRC 901 – On-The-Fly Computing.

Owner

  • Name: cryptimeleon
  • Login: cryptimeleon
  • Kind: organization
  • Location: Paderborn, Germany

Cryptographic prototyping

Citation (CITATION.cff)

# This CITATION.cff file was generated with cffinit.
# Visit https://bit.ly/cffinit to generate yours today!

cff-version: 1.2.0
title: Incentimeleon
message: >-
  Paper to be cited is being written. Until that is published, please cite this repository.
type: software
authors:
  - given-names: Jan
    family-names: Bobolz
  - given-names: Fabian
    family-names: Eidens
  - given-names: Paul
    family-names: Kramer
  - given-names: Patrick
    family-names: Schürmann
  - name: "Open-Source Contributors"
repository-code: 'https://github.com/cryptimeleon/incentive-system'
url: 'https://incentimeleon.cryptimeleon.org'
license: Apache-2.0

GitHub Events

Total
Last Year

Issues and Pull Requests

Last synced: almost 2 years ago

All Time
  • Total issues: 54
  • Total pull requests: 46
  • Average time to close issues: 4 months
  • Average time to close pull requests: 13 days
  • Total issue authors: 3
  • Total pull request authors: 3
  • Average comments per issue: 1.02
  • Average comments per pull request: 0.37
  • Merged pull requests: 41
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • this-kramer (33)
  • pschuermann97 (19)
  • JanBobolz (2)
Pull Request Authors
  • this-kramer (36)
  • pschuermann97 (9)
  • JanBobolz (1)
Top Labels
Issue Labels
enhancement (12) feature (7) bug (4) future work (3) crypto (2) help wanted (1) deployment (1) frontend (1)
Pull Request Labels
feature (6) deployment (3) crypto (3) bug (2) documentation (2)

Dependencies

android/app/build.gradle maven
  • androidx.activity:activity-compose $activity_version implementation
  • androidx.activity:activity-ktx 1.4.0 implementation
  • androidx.appcompat:appcompat 1.4.2 implementation
  • androidx.camera:camera-camera2 1.2.0-alpha02 implementation
  • androidx.camera:camera-lifecycle 1.2.0-alpha02 implementation
  • androidx.camera:camera-view 1.2.0-alpha02 implementation
  • androidx.compose.material3:material3 1.0.0-alpha13 implementation
  • androidx.compose.material3:material3-window-size-class 1.0.0-alpha13 implementation
  • androidx.constraintlayout:constraintlayout 2.1.4 implementation
  • androidx.core:core-ktx 1.8.0 implementation
  • androidx.fragment:fragment-ktx $fragment_version implementation
  • androidx.hilt:hilt-navigation-compose 1.0.0 implementation
  • androidx.legacy:legacy-support-v4 1.0.0 implementation
  • androidx.lifecycle:lifecycle-livedata-ktx 2.4.1 implementation
  • androidx.lifecycle:lifecycle-viewmodel-ktx 2.4.1 implementation
  • androidx.navigation:navigation-fragment-ktx $nav_version implementation
  • androidx.navigation:navigation-ui-ktx $nav_version implementation
  • androidx.room:room-ktx $room_version implementation
  • androidx.room:room-runtime $room_version implementation
  • androidx.test.ext:junit-ktx 1.1.3 implementation
  • androidx.test:core-ktx 1.4.0 implementation
  • com.google.accompanist:accompanist-permissions 0.16.1 implementation
  • com.google.accompanist:accompanist-systemuicontroller 0.20.3 implementation
  • com.google.android.material:material 1.6.1 implementation
  • com.google.code.gson:gson 2.9.0 implementation
  • com.google.guava:guava 30.0-android implementation
  • com.google.guava:listenablefuture 9999.0-empty-to-avoid-conflict-with-guava implementation
  • com.google.mlkit:barcode-scanning 17.0.2 implementation
  • com.jakewharton.timber:timber 4.7.1 implementation
  • com.squareup.retrofit2:converter-gson 2.9.0 implementation
  • com.squareup.retrofit2:converter-scalars 2.9.0 implementation
  • com.squareup.retrofit2:retrofit 2.9.0 implementation
  • org.apache.commons:commons-math3 3.6.1 implementation
  • org.cryptimeleon.incentive:crypto 1.0.0 implementation
  • org.cryptimeleon.incentive:promotion 1.0.0 implementation
  • org.jetbrains.kotlinx:kotlinx-serialization-core 1.3.2 implementation
  • org.jetbrains.kotlinx:kotlinx-serialization-json 1.3.2 implementation
  • com.google.truth:truth 1.1.3 testImplementation
  • junit:junit 4.13.2 testImplementation
  • org.mockito:mockito-core 3.6.28 testImplementation
crypto/build.gradle maven
  • org.cryptimeleon:craco 3.0.2 api
  • org.cryptimeleon:math 3.1.1 api
  • org.cryptimeleon:mclwrap 3.2.0 implementation
  • org.junit.jupiter:junit-jupiter-api 5.7.2 testImplementation
  • org.junit.jupiter:junit-jupiter-engine 5.7.2 testRuntimeOnly
promotion/build.gradle maven
  • org.cryptimeleon.incentive:crypto * api
  • org.junit.jupiter:junit-jupiter-api 5.7.0 testImplementation
  • org.junit.jupiter:junit-jupiter-engine 5.7.0 testRuntimeOnly
services/bootstrap/build.gradle maven
  • junit:junit 4.12 implementation
  • org.cryptimeleon.incentive:promotion * implementation
  • org.springframework.boot:spring-boot-starter-web * implementation
  • org.springframework.boot:spring-boot-starter-webflux * implementation
  • org.springframework.boot:spring-boot-starter-test * testImplementation
services/client/build.gradle maven
  • org.cryptimeleon.incentive:crypto * implementation
  • org.cryptimeleon.incentive:promotion * implementation
  • org.springframework.boot:spring-boot-starter-web * implementation
  • org.springframework.boot:spring-boot-starter-webflux * implementation
  • io.projectreactor:reactor-test * testImplementation
  • org.springframework.boot:spring-boot-starter-test * testImplementation
services/info/build.gradle maven
  • io.springfox:springfox-boot-starter 3.0.0 implementation
  • org.cryptimeleon.incentive:crypto * implementation
  • org.springframework.boot:spring-boot-starter-web * implementation
  • org.springframework.boot:spring-boot-starter-webflux * implementation
  • org.springframework.boot:spring-boot-starter-test * testImplementation
web/package-lock.json npm
  • 853 dependencies
web/package.json npm
  • @babel/core ^7.12.16 development
  • @babel/eslint-parser ^7.12.16 development
  • @tailwindcss/typography ^0.5.2 development
  • @vue/cli-plugin-babel ~5.0.0 development
  • @vue/cli-plugin-eslint ~5.0.0 development
  • @vue/cli-service ~5.0.0 development
  • eslint ^7.32.0 development
  • eslint-plugin-vue ^8.0.3 development
  • vue-cli-plugin-tailwind ~3.0.0 development
  • autoprefixer ^10
  • core-js ^3.8.3
  • postcss ^8
  • tailwindcss ^3
  • vue ^3.2.13
  • vue-router ^4.0.16
.github/workflows/workflow.yml actions
  • actions/checkout v2 composite
  • actions/setup-java v1 composite
services/Dockerfile docker
  • openjdk 11-jdk-slim build
web/Dockerfile docker
  • nginx stable-alpine build
  • node lts-alpine build
android/build.gradle maven
services/build.gradle maven
services/provider/build.gradle maven
  • io.netty:netty-all * implementation
  • io.springfox:springfox-boot-starter 3.0.0 implementation
  • org.cryptimeleon.incentive:promotion * implementation
  • org.springframework.boot:spring-boot-starter-web * implementation
  • org.springframework.boot:spring-boot-starter-webflux * implementation
  • org.springframework.boot:spring-boot-starter-test * testImplementation
services/store/build.gradle maven
  • io.netty:netty-all * implementation
  • io.springfox:springfox-boot-starter 3.0.0 implementation
  • org.cryptimeleon.incentive:promotion * implementation
  • org.springframework.boot:spring-boot-starter-data-jpa * implementation
  • org.springframework.boot:spring-boot-starter-web * implementation
  • org.springframework.boot:spring-boot-starter-webflux * implementation
  • com.h2database:h2 * runtimeOnly
  • org.cryptimeleon.incentive:promotion * testImplementation
  • org.springframework.boot:spring-boot-starter-test * testImplementation
services/package-lock.json npm