# 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.
