]> git.codecow.com Git - nano25519.git/commitdiff
Update readme to reflect current API. Add node bundle to package definition. Document...
authorChris Duncan <chris@zoso.dev>
Thu, 19 Mar 2026 06:08:00 +0000 (23:08 -0700)
committerChris Duncan <chris@zoso.dev>
Thu, 19 Mar 2026 06:08:00 +0000 (23:08 -0700)
AUTHORS.md
README.md
package.json

index b73efa0755a388a90a7c9bfa4e7c933080a94f36..f53d78c916b3578929de6298745f83bc8242b0f5 100644 (file)
@@ -5,10 +5,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
 
 # Authors
 
-[nano-nacl](https://git.codecow.com/nano-nacl.git)
+[nano-nacl](https://codecow.com/nano-nacl.git)
 
 - Chris Duncan <chris@codecow.com> (codecow.com)
 
+[libsodium](https://github.com/jedisct1/libsodium/tree/d24faf56214469b354b01c8ba36257e04737101e)
+
+- Frank Denis (@jedisct1)
+
 [tweetnacl-js](https://github.com/dchest/tweetnacl-js/tree/e6141a20553498697e9e7d92fbc4517994caff52)
 
 - Dmitry Chestnykh (@dchest)
index bac4d98c00f337fe30b595a65cdb06f58741c6df..4030ecd04caf8027683fc4ac1e472274484e5555 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,10 +7,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
 
 _Block signing and validation for Nano cryptocurrency using WebAssembly._
 
-NanoNaCl is an AssemblyScript port of tweetnacl-js, modified to hash using
-BLAKE2b instead of SHA-512 as specified for Nano cryptocurrency. It can derive
-public keys from private keys, sign blocks, and verify block signatures. All
-processing takes place client-side and offline.
+NanoNaCl is an AssemblyScript implementation of select Ed25519 functions used by
+the Nano cryptocurrency. It is modified to hash using BLAKE2b instead of SHA-512
+and can derive public keys from private keys, sign blocks, and verify block
+signatures. All processing takes place client-side and offline.
 
 For more information about the public key derivation algorithm used by Nano, see
 <https://docs.nano.org/integration-guides/the-basics/#account-public-key>
@@ -27,19 +27,9 @@ For more information about the block format defined for hashing and signing, see
 npm i nano-nacl
 ```
 
-## Usage
-
-### Import
-
-The easiest way to use NanoNaCl is to import it into your NodeJS project.
-
-```javascript
-import { derive, sign, verify } from "nano-nacl";
-// OR
-import * as NanoNaCl from "nano-nacl";
-```
+### Browser
 
-You can also use it directly on a webpage with a script module:
+NanoNaCl can be used directly on a webpage with a script module:
 
 ```html
 <script type="module">
@@ -50,57 +40,121 @@ You can also use it directly on a webpage with a script module:
 </script>
 ```
 
+### NodeJS
+
+NanoNaCl can be imported into NodeJS projects:
+
+```javascript
+import { derive, sign, verify } from "nano-nacl";
+```
+
+## Usage
+
+Each function has a synchronous implementation which is preferable for speed.
+These versions require Uint8Array byte arrays and return the same.
+
+If a non-blocking solution is required, asynchronous implementations are
+provided which use Web Workers in the browser or Worker threads in NodeJS. These
+versions require hex strings and return the same.
+
 ### Derive
 
 ```javascript
-// `sk` is a 64-char hex string secret key
-const sk = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
+// `prv` is a 32-byte Uint8Array private key
+const prv = new Uint8Array(32);
+const pub = NanoNaCl.derive(prvBytes);
+// `pub` is a 32-byte Uint8Array public key for a Nano account
+```
+
+### Derive (async)
 
-const pk = await NanoNaCl.derive(sk);
-// `pk` is a 64-char hex string public key for a Nano account
+```javascript
+// `prv` is a 64-character hex string private key
+const prv = "0000000000000000000000000000000000000000000000000000000000000000";
+const pub = await NanoNaCl.deriveAsync(prv);
+// `pub` is a 64-character hex string public key for a Nano account
 ```
 
 ### Sign
 
+```javascript
+// `hash` is a 32-byte Uint8Array hash of a valid Nano transaction block
+const hash = new Uint8Array(32);
+// `prv` is a 32-byte Uint8Array private key
+const prv = new Uint8Array(32);
+// `pub` is a 32-byte Uint8Array public key derived from `prv`
+const pub = NanoNaCl.derive(prv);
+// `sk` is a 64-byte Uint8Array secret key joining private and public keys
+const sk = new Uint8Array([...prv, ...pub]);
+
+const sig = NanoNaCl.sign(hash, sk);
+// `sig` is a 64-byte Uint8Array signature for the block hash
+```
+
+### Sign (async)
+
 ```javascript
 // `hash` is a 64-char hex string hash of a valid Nano transaction block
 const hash = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
-// `sk` is a 64-char hex string secret key
-const sk = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
-
-const sig = await NanoNaCl.sign(hash, sk);
+// `prv` is a 64-char hex string private key
+const prv = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
+// `pub` is a 64-char hex string public key derived from `prv`
+const pub = await NanoNaCl.deriveAsync(prv);
+// `sk` is a 128-char hex string secret key joining private and public keys
+const sk = prv + pub;
+
+const sig = await NanoNaCl.signAsync(hash, sk);
 // `sig` is a 128-char hex string signature on the blockhash
 ```
 
 ### Verify
 
 ```javascript
-// `hash` is a 64-char hex string hash of a valid Nano transaction block
-const hash = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
-// `sig` is a 128-char hex string signature on the blockhash
+// `sig` is a 64-byte Uint8Array signature on a block hash
+const sig = new Uint8Array(64);
+// `hash` is a 32-byte Uint8Array hash of a valid Nano transaction block
+const hash = new Uint8Array(32);
+// `pub` is a 32-byte Uint8Array public key for a Nano account
+const pub = new Uint8Array(32);
+
+const v = NanoNaCl.verify(sig, hash, pub);
+// `v` is a boolean 'true' if the same `prv` that derives `pub` was also used to create `sig` by signing `hash`, else 'false'
+```
+
+### Verify (async)
+
+```javascript
+// `sig` is a 128-char hex string signature on a block hash
 const sig =
   "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
-// `pk` is a 64-char hex string public key for a Nano account
-const pk = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
+// `hash` is a 64-char hex string hash of a valid Nano transaction block
+const hash = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
+// `pub` is a 64-char hex string public key for a Nano account
+const pub = "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210";
 
-const v = await NanoNaCl.verify(hash, sig, pk);
-// `v` is a boolean 'true' if `pk` was used to sign `hash` with `sig`, else 'false'
+const v = await NanoNaCl.verifyAsync(sig, hash, pub);
+// `v` is a boolean 'true' if the same `prv` that derives `pub` was also used to create `sig` by signing `hash`, else 'false'
 ```
 
 ## Notes
 
-The tweetnacl-js implementation was selected as the basis for NanoNaCl due to
-its historical reliability and security. For this project, it has been altered
-to use BLAKE2b as its internal hashing algorithm instead of SHA-512. It has also
-been optimized for Nano cryptocurrency needs, and many tweetnacl-js functions
-have been removed due to the very narrow use case to which it is applied here.
+The tweetnacl-js implementation was originally selected as the basis for
+NanoNaCl due to its historical reliability and security. Over time, however, it
+became clear that tweetnacl was designed to optimize size and not speed. Soon
+after, libsodium became the reference from which functionality was ported.
+
+For this project, the internal hash mechanism was altered to use BLAKE2b
+instead of SHA-512 so that it aligns with the Nano protocol. It has also been
+optimized specifically for Nano needs; many functions have been modified or
+removed due to the very narrow use case to which it is applied here.
 
 ## Tests
 
 A few basic tests are availabe in the source repository.
 
-- `test/index.html` in the source repository contains a web interface to change
-  execution options and compare results.
+- `index.html` is a web interface to test browser execution and compare
+  performance with other browser-based implementations.
+- `test.mjs` is a basic test for NodeJS to check result validity.
 
 ## Building
 
@@ -110,7 +164,7 @@ A few basic tests are availabe in the source repository.
 1. Compile, minify, and bundle
 
 ```console
-git clone https://git.codecow.com/nano-nacl.git
+git clone https://codecow.com/nano-nacl.git
 cd nano-nacl
 npm i
 ```
@@ -126,7 +180,12 @@ See AUTHORS.md
 ## Licenses
 
 GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
-tweetnacl-js is public domain under the Unlicense and was copied from the
+
+libsodium is distributed under the ISC license and was referenced from the
+following commit hash:
+<https://github.com/jedisct1/libsodium/tree/d24faf56214469b354b01c8ba36257e04737101e>
+
+tweetnacl-js is public domain under the Unlicense and was referenced from the
 following commit hash:
 <https://github.com/dchest/tweetnacl-js/tree/e6141a20553498697e9e7d92fbc4517994caff52>
 
index f8043adfaa6f9590c3886a69a3d36c54e121001b..af8a7c40ae6379e981a426f204b6e467d2723aa3 100644 (file)
@@ -12,7 +12,7 @@
                "coin",
                "wasm"
        ],
-       "homepage": "https://codecow.com",
+       "homepage": "https://git.codecow.com",
        "bugs": "bug-nano-nacl@codecow.com",
        "license": "(GPL-3.0-or-later AND MIT)",
        "author": "Chris Duncan <chris@codecow.com>",
@@ -22,7 +22,6 @@
        },
        "files": [
                "/dist",
-               "/docs",
                "/LICENSES",
                "AUTHORS.md",
                "package.json.license"
@@ -35,7 +34,7 @@
        },
        "repository": {
                "type": "git",
-               "url": "git+https://git.codecow.com/nano-nacl.git"
+               "url": "git+https://codecow.com/nano-nacl.git"
        },
        "scripts": {
                "build": "npm run clean && npm run compile && node ./esbuild/dev.mjs",
@@ -56,6 +55,7 @@
        "exports": {
                ".": {
                        "types": "./dist/index.d.ts",
+                       "node": "./dist/node.js",
                        "default": "./dist/browser.js"
                }
        },