# Konseal: Concept

Stealth addresses enable two parties to transact privately by allowing the sender (Alice) to generate a one-time recipient (stealth) address, which can only be controlled by the intended transaction recipient (Bob). This stealth address is not linked to Bob and provides true on-chain privacy and anonymity.

## Overview

1. Bob wants to receive a transaction from Alice on Ethereum anonymously.
2. Bob signs up to Konseal, and a **root spending key** and **meta address** are generated.
3. Bob sends Alice his **meta-address**.
4. Alice inputs Bob's **meta-address** into Konseal dApp to generate a **stealth address.**
5. Alice transfers 100 Ether to Bob's **meta-address.**
6. Bob checks the Konseal dApp and waits until the **spending address** is found.
7. Bob can now access the 100 Ether.

## Architecture

Bob wants to receive a transaction from Alice on Ethereum anonymously.

Bob signs up to Konseal to create a Private Smart Wallet. A **spending** and **viewing** key is generated for Bob. These two keys are formatted together to form Bob's **meta address.**

```
// Some code to call contracts to return stealthMetaAddress
```

The meta address is a **spending key**, **viewing key** in the following format:

```
st:eth:0x<spendingKey><viewingKey>
```

Alice inputs Bob's **meta-address** into Konseal dApp to generate a **stealth address.**

```solidity
    /// @notice Generates a stealth address from a stealth meta address.
    /// @param stealthMetaAddress The recipient's stealth meta-address.
    /// @return stealthAddress The recipient's stealth address.
    /// @return ephemeralPubKey The ephemeral public key used to generate the stealth address.
    /// @return viewTag The view tag derived from the shared secret.
    function generateStealthAddress(bytes memory stealthMetaAddress)
        external
        view
        returns (
            address stealthAddress,
            bytes memory ephemeralPubKey,
            bytes1 viewTag
        )
    {
        // Step 1: Generate a random 32-byte entropy ephemeral private key pephemeral.
        bytes32 pephemeral = keccak256(
            abi.encodePacked(
                block.timestamp,
                msg.sender,
                blockhash(block.number - 1)
            )
        );

        // Step 2: Derive the ephemeral public key Pephemeral from pephemeral.
        bytes memory ephemeralPubKeyBytes = Secp256k1.derivePublicKey(phemeral);
        bytes32 x;
        assembly {
            x := mload(add(ephemeralPubKeyBytes, 32))
        }
        bytes32 y;
        assembly {
            y := mload(add(ephemeralPubKeyBytes, 64))
        }
        uint8 parity = uint8(y) % 2 == 0 ? 0x02 : 0x03;
        ephemeralPubKey = abi.encodePacked(parity, x);

        // Step 3: Parse the spending and viewing public keys, Pspend and Pview, from the stealth meta-address.
        bytes32 Pspend;
        bytes32 Pview;
        assembly {
            Pspend := mload(add(stealthMetaAddress, 20))
            Pview := mload(add(stealthMetaAddress, 52))
        }

        // Step 4: A shared secret s is computed as s = pephemeral * Pview.
        bytes32 s = Secp256k1.multiplyModN(phemeral, Pview);

        // Step 5: The secret is hashed sh = h(s).
        bytes32 sh = keccak256(abi.encodePacked(s));

        // Step 6: The view tag v is extracted by taking the most significant byte sh[0].
        viewTag = sh[0];

        // Step 7: Multiply the hashed shared secret with the generator point Sh = sh * G.
        bytes memory ShBytes = Secp256k1.multiplyByG(sh);

        // Step 8: The recipient’s stealth public key is computed as Pstealth = Pspend + Sh.
        bytes32 Pstealth = Pspend + bytesToBytes32(ShBytes);

        // Step 9: The recipient’s stealth address is computed as pubkeyToAddress(Pstealth).
        stealthAddress = string(
            abi.encodePacked("st:eth:0x", bytesToHex(Pspend), bytesToHex(Pview))
        );

        return (stealthAddress, ephemeralPubKey, viewTag);
    }
```

Alices **ephemeralPubKey** is published to a registry smart contract.

Alice sends 100 Ether to Bob's **stealth** **meta-address.**

Bob input his **viewing spending key** into Konseal&#x20;

Konseal bot scans the **ephemeral public key registry** for the *entire list* of **ephemeral public keys** published by anyone for any reason since the last time it did the scan.

For each **ephemeral public key**, the bot attempts to combine it with Bob's **viewing spending key** to generate a **stealth address** and checks if there are any assets in that address.&#x20;

The bot computes the spending key for any address that contains funds and returns it.

Alice has the option to fund the **stealth address** and allow Bob to move the assets.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.konseal.io/konseal-concept.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
