🪄Konseal: Concept
Self-custodial multi-sig wallet for the Ethereum ecosystem that provides true on-chain privacy and anonymity.
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
Bob wants to receive a transaction from Alice on Ethereum anonymously.
Bob signs up to Konseal, and a root spending key and meta address are generated.
Bob sends Alice his meta-address.
Alice inputs Bob's meta-address into Konseal dApp to generate a stealth address.
Alice transfers 100 Ether to Bob's meta-address.
Bob checks the Konseal dApp and waits until the spending address is found.
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 stealthMetaAddressThe 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.
/// @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
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.
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.
Last updated