]> git.codecow.com Git - nano25519.git/commitdiff
Add success and failure tests for output buffer arguments.
authorChris Duncan <chris@zoso.dev>
Thu, 13 Aug 2026 04:45:34 +0000 (21:45 -0700)
committerChris Duncan <chris@zoso.dev>
Thu, 13 Aug 2026 04:45:34 +0000 (21:45 -0700)
test.mjs

index 9e2ca08fef51aece7a5c2bccc35d26e93ccf3834..a9c7cd5d0ba660e279d8acf2bf81620c9670e961 100644 (file)
--- a/test.mjs
+++ b/test.mjs
@@ -29,7 +29,7 @@ function overlaps (a, b) {
                && a.byteLength !== 0
 }
 
-let outbuf, result, test, passes = 0, failures = 0
+let outbuf, length, result, test, passes = 0, failures = 0
 
 // Check string input validation
 try {
@@ -187,9 +187,41 @@ check(`sign message too long (65538 '1's)`, test)
 passes += +test
 failures += +!test
 
+// Check output buffer offset handling
+try {
+       outbuf = new Uint8Array(33)
+       result = derive(NANO_ORG_VECTOR.privateKeyBytes, outbuf)
+       result = false
+} catch (err) {
+       if (err != null && typeof err === 'object' && 'message' in err) {
+               result = err.message === 'Derive output buffer must be 32-byte Uint8Array<ArrayBuffer>'
+       } else {
+               result = false
+       }
+}
+test = result === true
+check(`derive offset outbuf wrong length`, test)
+passes += +test
+failures += +!test
+
+try {
+       outbuf = new Uint8Array(65)
+       result = sign(NANO_ORG_VECTOR.blockHashBytes, NANO_ORG_VECTOR.secretKeyBytes, outbuf)
+       result = false
+} catch (err) {
+       if (err != null && typeof err === 'object' && 'message' in err) {
+               result = err.message === 'Sign output buffer must be 64-byte Uint8Array<ArrayBuffer>'
+       } else {
+               result = false
+       }
+}
+test = result === true
+check(`sign offset outbuf wrong length`, test)
+passes += +test
+failures += +!test
+
 // Check combined imports
 result = await Nano25519.deriveAsync(NANO_ORG_VECTOR.privateKeyBytes)
-console.log(`RESULT`, result)
 test = [...result].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.publicKey.toLowerCase()
 check(`async derive from ${NANO_ORG_VECTOR.privateKey}`, test)
 passes += +test
@@ -228,8 +260,6 @@ failures += +!test
 // Check async imports with string inputs
 result = await deriveAsync(NANO_ORG_VECTOR.privateKey)
 test = result.toLowerCase() === NANO_ORG_VECTOR.publicKey.toLowerCase()
-console.log(result)
-console.log()
 check(`async derive from private key string ${NANO_ORG_VECTOR.privateKey}`, test)
 passes += +test
 failures += +!test
@@ -248,7 +278,6 @@ failures += +!test
 
 // Check async imports with byte inputs
 result = await deriveAsync(NANO_ORG_VECTOR.privateKeyBytes)
-console.log(`RESULT`, result)
 test = [...result].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.publicKey.toLowerCase()
 check(`async derive from private key bytes ${NANO_ORG_VECTOR.privateKey}`, test)
 passes += +test
@@ -307,18 +336,47 @@ failures += +!test
 // Check sync imports with byte inputs and preallocated output buffer
 outbuf = new Uint8Array(32)
 result = derive(NANO_ORG_VECTOR.privateKeyBytes, outbuf)
-test = overlaps(result, outbuf) && [...result].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.publicKey.toLowerCase()
+test = overlaps(result, outbuf)
+test &&= [...result].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.publicKey.toLowerCase()
+test &&= [...outbuf].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.publicKey.toLowerCase()
 check(`derive from private key bytes ${NANO_ORG_VECTOR.privateKey} and allocate result to output buffer`, test)
 passes += +test
 failures += +!test
 
 outbuf = new Uint8Array(64)
 result = sign(NANO_ORG_VECTOR.blockHashBytes, NANO_ORG_VECTOR.secretKeyBytes, outbuf)
-test = overlaps(result, outbuf) && [...result].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.signature.toLowerCase()
+test = overlaps(result, outbuf)
+test &&= [...result].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.signature.toLowerCase()
+test &&= [...outbuf].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.signature.toLowerCase()
 check(`sign message bytes ${NANO_ORG_VECTOR.blockHash} and allocate result to output buffer`, test)
 passes += +test
 failures += +!test
 
+// Check sync imports with byte inputs and offset output buffer
+length = 33 + crypto.getRandomValues(new Uint8Array(1))[0]
+outbuf = new Uint8Array(new ArrayBuffer(length), length - 32, 32)
+result = derive(NANO_ORG_VECTOR.privateKeyBytes, outbuf)
+test = overlaps(result, outbuf)
+test &&= [...result].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.publicKey.toLowerCase()
+test &&= [...outbuf].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.publicKey.toLowerCase()
+test &&= [...new Uint8Array(result.buffer)].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() !== NANO_ORG_VECTOR.publicKey.toLowerCase()
+test &&= [...new Uint8Array(outbuf.buffer)].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() !== NANO_ORG_VECTOR.publicKey.toLowerCase()
+check(`derive from private key bytes ${NANO_ORG_VECTOR.privateKey} to offset outbuf`, test)
+passes += +test
+failures += +!test
+
+length = 65 + crypto.getRandomValues(new Uint8Array(1))[0]
+outbuf = new Uint8Array(new ArrayBuffer(length), length - 64, 64)
+result = sign(NANO_ORG_VECTOR.blockHashBytes, NANO_ORG_VECTOR.secretKeyBytes, outbuf)
+test = overlaps(result, outbuf)
+test &&= [...result].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.signature.toLowerCase()
+test &&= [...outbuf].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() === NANO_ORG_VECTOR.signature.toLowerCase()
+test &&= [...new Uint8Array(result.buffer)].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() !== NANO_ORG_VECTOR.publicKey.toLowerCase()
+test &&= [...new Uint8Array(outbuf.buffer)].map(b => b.toString(16).padStart(2, '0')).join('').toLowerCase() !== NANO_ORG_VECTOR.publicKey.toLowerCase()
+check(`sign message bytes ${NANO_ORG_VECTOR.blockHash} to offset outbuf`, test)
+passes += +test
+failures += +!test
+
 // test both string inputs and byte inputs
 for (const { privateKey, publicKey, message, signature } of PYTHON_ED25519_BLAKE2B_VECTORS) {
        result = derive(privateKey)