This public key will be sent along with your email inside of a new INIT_USER_EMAIL_RECOVERY or EMAIL_AUTH activity
-
-
-
-
-
Inject Credential Bundle
-
The credential bundle will come from your email. This bundle can then be used for email recovery or auth. We can simulate this locally: see instructions here. A credential bundle is composed of a public key and an encrypted payload. The payload is encrypted to this document's embedded key (stored in local storage and displayed above). The scheme relies on HPKE (RFC 9180).
-
-
-
-
-
Stamp
-
Once you've injected the credential bundle, the credential is ready to sign. A new RECOVER activity for example. This iframe doesn't know anything about Turnkey activity however, it's a simple stamper!
-
-
-
-
-
Message log
-
Below we display a log of the messages sent / received. The forms above send messages, and the code communicates results by sending events via the postMessage API.
-
-
-
-
+ /**
+ * This is the P256 base point (aka generator)
+ * See https://www.secg.org/sec2-v2.pdf and https://neuromancer.sk/std/nist/P-256
+ */
+ var P256Generator = new P256Point(
+ new P256FieldElement(
+ BigInt(
+ "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"
+ )
+ ),
+ new P256FieldElement(
+ BigInt(
+ "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
+ )
+ )
+ );
+
+ /**********************************************************************************************
+ * End of private crypto implementation for P256 public key derivation from a private key.
+ *********************************************************************************************/
+
+ return {
+ initEmbeddedKey,
+ generateTargetKey,
+ setItemWithExpiry,
+ getItemWithExpiry,
+ getEmbeddedKey,
+ setEmbeddedKey,
+ onResetEmbeddedKey,
+ importCredential,
+ compressRawPublicKey,
+ uncompressRawPublicKey,
+ p256JWKPrivateToPublic,
+ convertEcdsaIeee1363ToDer,
+ sendMessageUp,
+ logMessage,
+ base64urlEncode,
+ base64urlDecode,
+ base58checkDecode,
+ bigIntToHex,
+ stringToBase64urlString,
+ uint8arrayToHexString,
+ uint8arrayFromHexString,
+ additionalAssociatedData,
+ };
+ })();
+
-
-
-
+ /**
+ * Decrypt the ciphertext (ArrayBuffer) given an encapsulation key (ArrayBuffer)
+ * and the receivers private key (JSON Web Key).
+ */
+ var HpkeDecrypt = async function ({
+ ciphertextBuf,
+ encappedKeyBuf,
+ receiverPrivJwk,
+ }) {
+ var kemContext = new hpke.DhkemP256HkdfSha256();
+ var receiverPriv = await kemContext.importKey(
+ "jwk",
+ { ...receiverPrivJwk },
+ false
+ );
+
+ var suite = new hpke.CipherSuite({
+ kem: kemContext,
+ kdf: new hpke.HkdfSha256(),
+ aead: new hpke.Aes256Gcm(),
+ });
+
+ var recipientCtx = await suite.createRecipientContext({
+ recipientKey: receiverPriv,
+ enc: encappedKeyBuf,
+ info: new TextEncoder().encode("turnkey_hpke"),
+ });
+
+ var receiverPubBuf = await TKHQ.p256JWKPrivateToPublic(receiverPrivJwk);
+ var aad = TKHQ.additionalAssociatedData(encappedKeyBuf, receiverPubBuf);
+ var res;
+ try {
+ res = await recipientCtx.open(ciphertextBuf, aad);
+ } catch (e) {
+ throw new Error("decryption failed: " + e);
+ }
+ return res;
+ };
+
+