NokitaKaze.TornadoCashEncryptedNote
0.1.1
dotnet add package NokitaKaze.TornadoCashEncryptedNote --version 0.1.1
NuGet\Install-Package NokitaKaze.TornadoCashEncryptedNote -Version 0.1.1
<PackageReference Include="NokitaKaze.TornadoCashEncryptedNote" Version="0.1.1" />
paket add NokitaKaze.TornadoCashEncryptedNote --version 0.1.1
#r "nuget: NokitaKaze.TornadoCashEncryptedNote, 0.1.1"
// Install NokitaKaze.TornadoCashEncryptedNote as a Cake Addin #addin nuget:?package=NokitaKaze.TornadoCashEncryptedNote&version=0.1.1 // Install NokitaKaze.TornadoCashEncryptedNote as a Cake Tool #tool nuget:?package=NokitaKaze.TornadoCashEncryptedNote&version=0.1.1
Tornado Cash Encrypted Note.Net: Cypher/Decypher
This project is a C# implementation of Tornado Cash's encrypted notes.
More about Tornado Cash
- https://mirror.xyz/decent-dao.eth/zb1mwO0wjwv74AQvNNMvGEUFRBt7cVqyoIDrhvrwt0k
- https://youtu.be/z_cRicXX1jI
Introduction
Tornado Cash' notes encrypted with X25519-XSalsa20-Poly1305 algorithm. Each note has structure:
- Nonce. 24 bytes: disposable random 24 bytes
- Ephemeral public key. 32 bytes. Public key for a point on Curve25519
- Encrypted message itself including 12 bytes of the Tag of XSalsa20Poly1305
Plain text has structure:
{ContractAddress}-{CommitmentSecret}
Examples:
0x6Bf694a291DF3FeC1f7e69701E3ab6c592435Ae7-0x0e2d09c3b49548799444ae871c1ad7e6dd6110f80e6db8f8e544c33c45234f56caae9b5b4d4d24e1ffbc92b3f94a2228efa28efb363ed96275983a9c64a3
0x84443CFd09A48AF6eF360C6976C5392aC5023a1F-0x8449131cdfbdb26c5834930477fd26425b7d637148414dd0f74fce7feb9b1d9b130e0342dfd9249beaae603e3b07f98a66604029a32d21356c82f224a15f
Notice(sic!) Contract address has "checksummed" format with capital letters.
Encrypted note events
Event type 0xfa28df43db3553771f7209dcef046f3bdfea15870ab625dcda30ac58b82b4008
You could find Tornado Cash' contract addresses here.
Error on the site
At 2022-05-15 official Tornado Cash site has an implementation error: If your note's contract address not in the dictionary, the site will not show you ANY of your private notes. You could check it on Goerli network. Private note keys:
- 97a6f440ae04bd21dece386ed83ed65e7bc3405c271e4226f64ed421c197addb
- 97a6f440ae04bd21dece386ed83ed65e7bc3405c271e4226f64ed421c197addd
Public Interface
Encrypter.CreateRawNoteFrom(string contractAddress, string commitmentSecret): string
- Create plain non-crypted noteEncrypter.EncryptNote(string rawNote, string/byte[] notePrivateKey): byte[]
- Encrypt plain note to Encrypted Note formatDecrypter.DecryptNote(string/byte[] encryptedNote, string/byte[] notePrivateKey): string
- Create plain non-crypted note
Example
Encryption
var rawNote = Encrypter.CreateRawNoteFrom("0x6bf694a291df3fec1f7e69701e3ab6c592435ae7", "0x0e2d09c3b49548799444ae871c1ad7e6dd6110f80e6db8f8e544c33c45234f56caae9b5b4d4d24e1ffbc92b3f94a2228efa28efb363ed96275983a9c64a3");
var encryptedNote = Encrypter.EncryptNote(rawNote, "97a6f440ae04bd21dece386ed83ed65e7bc3405c271e4226f64ed421c197addb");
var encryptedNoteHex = string.Concat(encryptedNote.Select(t => t.ToFormat("X2")));
Console.WriteLine(encryptedNoteHex);
Decryption
var encryptedNoteHex = "A27BC84471DD85324572916B32D9E53536C189764010D628DBE5623D805E948F312B192E47D6F0A5C84BF0C7EEB2612916AAF14936C55C579181590D4926B1FFFD37A803303E4147326E61A21BE899D57403B356DF165D84C4228E63627A531ECB4688ABD3BDA925C8FAA1C19369097501C157FBF996BDE8E4A34B1ED51C75BF25B03ED92C1B319118F046EBBA392024DE528922000D98A1BAD0EA08AADC5ED27CF47A595C151C8CC196B23814873F914EB2D466459459BCD18E5827E29BE9699DB7AFF9D5A51BDC8C405845E3611A44058F121F969DA2AC4A101D409D9F74BABA6AE964F5B67E6454E7DBD5791675F02E"
Decrypter.DecryptNote(encryptedNoteHex, "97a6f440ae04bd21dece386ed83ed65e7bc3405c271e4226f64ed421c197addb");
Collisions / Format private keys
It's not obvious, but some area of private keys has been punched out of Curve25519. When receiving such an array, implementations of X25519 (but not X448) MUST mask the most significant bit in the final byte. This is done to preserve compatibility with point formats that reserve the sign bit for use in other protocols and to increase resistance to implementation fingerprinting.
There are still 2^252 bits for private keys. You could use this code to get sanified/formatted/main version of secret key.
privateKey = Curve25519Formatter.FormatPrivateKey(privateKey);
var collisions = GetAllCollisionPrivateKeys(privateKey);
Learn more:
- https://crypto.stackexchange.com/questions/53318/can-you-help-me-understand-multiplication-of-points-when-using-curve25519
- https://datatracker.ietf.org/doc/html/rfc7748#section-5
License
Licensed under the Apache License.
This software is provided "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- X25519-XSalsa20-Poly1305 algorithm: Daniel J. Bernstein
- NaCL.Net's author: Doron Somech
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.1 is compatible. |
-
.NETCoreApp 3.1
- NaCl.Net (>= 0.1.13)
- Nethereum.Util (>= 4.5.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.