NokitaKaze.TornadoCashEncryptedNote 0.1.1

dotnet add package NokitaKaze.TornadoCashEncryptedNote --version 0.1.1
NuGet\Install-Package NokitaKaze.TornadoCashEncryptedNote -Version 0.1.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NokitaKaze.TornadoCashEncryptedNote" Version="0.1.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add NokitaKaze.TornadoCashEncryptedNote --version 0.1.1
#r "nuget: NokitaKaze.TornadoCashEncryptedNote, 0.1.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// 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

Build status Test status codecov Total nuget downloads

This project is a C# implementation of Tornado Cash's encrypted notes.

More about Tornado Cash

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 note
  • Encrypter.EncryptNote(string rawNote, string/byte[] notePrivateKey): byte[] - Encrypt plain note to Encrypted Note format
  • Decrypter.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:

License

Licensed under the Apache License.

This software is provided "AS IS" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.1 367 5/28/2022
0.1.0 369 5/27/2022