feat(labs): CryptographicAgeVerificationSandbox

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2024-08-04 21:03:37 +02:00
parent d6b75e937f
commit 2116c75fc1
4 changed files with 155 additions and 0 deletions

View File

@ -0,0 +1,41 @@
package chat.revolt.internals
import java.security.MessageDigest
class CryptographicAgeVerification {
fun getProofHash(
seed: String,
userAge: Int,
minAllowedAge: Int
): Pair<ByteArray, ByteArray> {
var proof = MessageDigest.getInstance("SHA-256").digest(seed.toByteArray())
for (i in 1 until userAge - minAllowedAge) {
proof = MessageDigest.getInstance("SHA-256").digest(proof)
}
var ageHash =
MessageDigest.getInstance("SHA-256").digest(seed.toByteArray())
for (i in 1 until userAge - 1) {
ageHash = MessageDigest.getInstance("SHA-256").digest(ageHash)
}
return ageHash to proof
}
fun proveAge(
minAllowedAge: Int,
proofHash: ByteArray,
ageHash: ByteArray,
): Boolean {
var verifyHash =
MessageDigest.getInstance("SHA-256").digest(proofHash.toString().toByteArray())
for (i in 1 until minAllowedAge - 1) {
verifyHash = MessageDigest.getInstance("SHA-256").digest(verifyHash)
}
return verifyHash.contentEquals(ageHash)
}
}

View File

@ -13,6 +13,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
@ -36,6 +37,7 @@ import androidx.navigation.NavController
enum class LabsHomeScreenTab {
Home,
Mockups,
Sandboxes,
}
@OptIn(ExperimentalMaterial3Api::class)
@ -80,6 +82,19 @@ fun LabsHomeScreen(navController: NavController) {
Text("UI Mockups")
}
)
NavigationBarItem(
selected = currentTab.value == LabsHomeScreenTab.Sandboxes,
onClick = { currentTab.value = LabsHomeScreenTab.Sandboxes },
icon = {
Icon(
imageVector = Icons.Default.PlayArrow,
contentDescription = null,
)
},
label = {
Text("Sandboxes")
}
)
}
}
) {
@ -128,6 +143,22 @@ fun LabsHomeScreen(navController: NavController) {
HorizontalDivider()
}
}
LabsHomeScreenTab.Sandboxes -> {
Column(
modifier = Modifier.verticalScroll(rememberScrollState())
) {
ListItem(
headlineContent = {
Text("Cryptographic Age Verification")
},
modifier = Modifier.clickable {
navController.navigate("sandboxes/cryptoageverif")
}
)
HorizontalDivider()
}
}
}
}
}

View File

@ -13,6 +13,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import chat.revolt.api.settings.FeatureFlags
import chat.revolt.screens.labs.ui.mockups.CallScreenMockup
import chat.revolt.screens.labs.ui.sandbox.CryptographicAgeVerificationSandbox
annotation class LabsFeature
@ -62,6 +63,10 @@ fun LabsRootScreen(topNav: NavController) {
composable("mockups/call") {
CallScreenMockup()
}
composable("sandboxes/cryptoageverif") {
CryptographicAgeVerificationSandbox(labsNav)
}
}
}
}

View File

@ -0,0 +1,78 @@
package chat.revolt.screens.labs.ui.sandbox
import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.navigation.NavController
import chat.revolt.api.REVOLT_KJBOOK
import chat.revolt.internals.CryptographicAgeVerification
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CryptographicAgeVerificationSandbox(navController: NavController) {
Scaffold(
topBar = {
TopAppBar(
title = {
Text(
"Crypto Age Verify Sandbox",
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
},
navigationIcon = {
IconButton(onClick = { navController.popBackStack() }) {
Icon(Icons.AutoMirrored.Default.ArrowBack, "Back")
}
}
)
}
) { pv ->
Column(
Modifier
.padding(pv)
.fillMaxSize()
) {
Button(onClick = {
val cav = CryptographicAgeVerification()
val (ageHash, verifyHash) = cav.getProofHash(
seed = REVOLT_KJBOOK,
userAge = 21,
minAllowedAge = 18
)
Log.d(
"CryptographicAgeVerificationSandbox",
"ageHash: ${ageHash.contentToString()}"
)
Log.d(
"CryptographicAgeVerificationSandbox",
"verifyHash: ${verifyHash.contentToString()}"
)
val verification = cav.proveAge(
minAllowedAge = 18,
proofHash = verifyHash,
ageHash = ageHash
)
Log.d("CryptographicAgeVerificationSandbox", "Verification result: $verification")
}) {
Text("Run Cryptographic Age Verification")
}
}
}
}