Skip to content

Commit

Permalink
chore: proper identity + change order
Browse files Browse the repository at this point in the history
  • Loading branch information
maxgttph committed Jul 5, 2024
1 parent 1615c65 commit 560dbef
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 30 deletions.
18 changes: 10 additions & 8 deletions src/GetTokens.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import * as faceApi from "face-api.js";
import { computed, nextTick, onMounted, ref, watchEffect } from "vue";
import { needWebAuthnCredentials, registerWebAuthnIfNeeded, signChallengeWithWebAuthn, webAuthnIdentity } from "./webauthn";
import { needWebAuthnCredentials, registerWebAuthnIfNeeded, signChallengeWithWebAuthn, getWebAuthnIdentity } from "./webauthn";
import { proveECDSA, proveSmile, proveERC20Transfer } from "./prover";
import { computeSmileArgs, runSmile } from "./CairoRunner";
import { setupCosmos, broadcastTx, checkTxStatus, ensureContractsRegistered } from "./cosmos";
Expand Down Expand Up @@ -249,25 +249,27 @@ const signAndSend = async () => {
smilePromiseDone.value = false;
erc20PromiseDone.value = false;
status.value = "proving";
const identity = getWebAuthnIdentity();
try {
// Start locally proving that we are who we claim to be by signing the transaction hash
// TODO: this is currently a random challenge
const webAuthnValues = await signChallengeWithWebAuthn();
const ecdsaPromise = proveECDSA(webAuthnValues);
// Send the proof of smile to Giza or something
const smilePromise = proveSmile({
identity: webAuthnIdentity,
image: [...grayScale]
});
identity: identity,
image: [...grayScale]
});
// Locally or backend prove an erc20 transfer
const erc20Promise = proveERC20Transfer({
balances: getBalances(),
amount: 100,
from: "faucet",
to: webAuthnIdentity,
to: identity,
});
const challenge = Uint8Array.from("0123456789abcdef0123456789abcdef", c => c.charCodeAt(0));
const webAuthnValues = await signChallengeWithWebAuthn(challenge);
const ecdsaPromise = proveECDSA(webAuthnValues);
ecdsaPromise.then(() => ecdsaPromiseDone.value = true);
smilePromise.then(() => smilePromiseDone.value = true);
erc20Promise.then(() => erc20PromiseDone.value = true);
Expand Down
35 changes: 27 additions & 8 deletions src/cosmos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,20 @@ function uint8ArrayToBase64(array: Uint8Array): string {
return btoa(result);
}

export async function broadcastTx(ecdsaProof: string, smileProof: string, erc20Proof: Uint8Array) {
export async function broadcastTx(ecdsaProof: string, smileProof: Uint8Array, erc20Proof: Uint8Array) {
const msgAny = {
typeUrl: "/hyle.zktx.v1.MsgExecuteStateChanges",
value: {
stateChanges: [
/*{
contractName: "smile",
proof: window.btoa(smileProof),
},*/ {
{
contractName: "ecdsa_secp256r1",
proof: window.btoa(ecdsaProof),
},
{
},{
contractName: "smile_token",
proof: uint8ArrayToBase64(erc20Proof),
},{
contractName: "smile",
proof: uint8ArrayToBase64(smileProof),
},
],
},
Expand Down Expand Up @@ -107,6 +106,7 @@ export async function ensureContractsRegistered() {
amount: 1000000,
},
]);
// Creation of smile_token contract
let msgAny = {
typeUrl: "/hyle.zktx.v1.MsgRegisterContract",
value: {
Expand All @@ -133,6 +133,25 @@ export async function ensureContractsRegistered() {
});
client.broadcastTx(Uint8Array.from(TxRaw.encode(signedTx).finish()));

// Creation for smile contract
msgAny = {
typeUrl: "/hyle.zktx.v1.MsgRegisterContract",
value: {
owner: firstAccount.address,
verifier: "cairo",
contractName: "smile",
programId: new Uint8Array([123]),
stateDigest: new Uint8Array("666".split("").map((x) => x.charCodeAt(0))),
} as MsgRegisterContract,
};
signedTx = await client.sign(firstAccount.address, [msgAny], fee, "", {
accountNumber: 1,
sequence: 2,
chainId: "hyle",
});
client.broadcastTx(Uint8Array.from(TxRaw.encode(signedTx).finish()));

// Creation of ECDSA contract
const b64vKey =
"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";
const vKey = Uint8Array.from(Buffer.from(b64vKey, "base64"));
Expand All @@ -148,7 +167,7 @@ export async function ensureContractsRegistered() {
};
signedTx = await client.sign(firstAccount.address, [msgAny], fee, "", {
accountNumber: 1,
sequence: 2,
sequence: 3,
chainId: "hyle",
});
await client.broadcastTx(Uint8Array.from(TxRaw.encode(signedTx).finish()));
Expand Down
4 changes: 2 additions & 2 deletions src/prover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BarretenbergBackend, CompiledCircuit } from "@noir-lang/backend_barrete
import { Noir } from "@noir-lang/noir_js";
import webAuthnCircuit from "./webauthn.json";
import { CairoArgs, CairoSmileArgs } from "./CairoHash";
import { webAuthnIdentity } from "./webauthn";
import { getWebAuthnIdentity } from "./webauthn";

// Circuit tools setup
// Preloaded so the server starts downloading early and minimize latency.
Expand All @@ -22,7 +22,7 @@ export const proveECDSA = async (webAuthnValues: Record<string, any>) => {
next_state_len: 4,
next_state: [0, 0, 0, 0],
identity_len: 56,
identity: webAuthnIdentity,
identity: getWebAuthnIdentity(),
tx_hash_len: 43,
tx_hash: webAuthnValues.challenge,
program_outputs: {
Expand Down
21 changes: 9 additions & 12 deletions src/webauthn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ function padRightWithZeros(input: ArrayBufferLike): Uint8Array {
return paddedArray;
}

// Challenge should be 16bytes long
// https://www.w3.org/TR/webauthn-2/#sctn-cryptographic-challenges
var challenge = Uint8Array.from("0123456789abcdef0123456789abcdef", c => c.charCodeAt(0));
var creationChallenge = Uint8Array.from("0123456789abcdef0123456789abcdef", c => c.charCodeAt(0));

export const needWebAuthnCredentials = () => {
try {
Expand Down Expand Up @@ -100,7 +99,7 @@ export const registerWebAuthnIfNeeded = async () => {
requireResidentKey: false,
residentKey: "discouraged",
},
challenge: challenge,
challenge: creationChallenge,
pubKeyCredParams: [{ alg: -7, type: "public-key" }],
rp: { name: "Vibe Checker", id: "localhost" },
timeout: 600000,
Expand All @@ -119,7 +118,7 @@ export const registerWebAuthnIfNeeded = async () => {
}));
}

export const signChallengeWithWebAuthn = async () => {
export const signChallengeWithWebAuthn = async (challenge: Uint8Array) => {
const locallyStoredId = window.localStorage.getItem("credentials")!;
const rawId = Uint8Array.from(JSON.parse(locallyStoredId).raw_id as Array<number>);
const publicKey = Uint8Array.from(JSON.parse(locallyStoredId).public_key as Array<number>);
Expand Down Expand Up @@ -156,8 +155,6 @@ export const signChallengeWithWebAuthn = async () => {
var extracted_challenge = clientDataJSON.slice(36, 36 + 43);
var client_data_json_len = clientDataJSON.byteLength;

computeIdentity(Array.from(new Uint8Array(pub_key_x)), Array.from(new Uint8Array(pub_key_y)));

return {
authenticator_data: Array.from(new Uint8Array(authenticatorData)),
client_data_json_len: client_data_json_len,
Expand All @@ -169,16 +166,16 @@ export const signChallengeWithWebAuthn = async () => {
};
}

export var webAuthnIdentity: string;
export const getWebAuthnIdentity = () => {

const locallyStoredId = window.localStorage.getItem("credentials")!;
let pubKey = Uint8Array.from(JSON.parse(locallyStoredId).public_key as Array<number>);
var [pub_key_x, pub_key_y] = extractPublicKeyCoordinates(pubKey);

export const computeIdentity = (pub_key_x: number[], pub_key_y: number[]) => {
if (pub_key_x.length !== 32 || pub_key_y.length !== 32) {
throw new Error("pub_key_x and pub_key_y size need to be 32bytes.");
}
const publicKey = Buffer.concat([Buffer.from(pub_key_x), Buffer.from(pub_key_y)]);
const hash = crypto.createHash("sha256").update(publicKey).digest();
const result = hash.slice(-20);
const hexResult = Array.from(result).map((byte) => byte.toString(16).padStart(2, "0"));

webAuthnIdentity = hexResult.join("") + ".ecdsa_secp256r1";
return hexResult.join("") + ".ecdsa_secp256r1";
};

0 comments on commit 560dbef

Please sign in to comment.