diff --git a/src/crypto.mjs b/src/crypto.mjs index eea4cb85e87fd1f7905b4f9653dabae8848b6505..b0614ca99f0fe5eeb30372893ef0dea272e3e7f5 100644 --- a/src/crypto.mjs +++ b/src/crypto.mjs @@ -2,9 +2,9 @@ // Alt deps : import scrypt from "ecma-nacl/build/lib/scrypt/scrypt.js"; import nacl from '../generated/vendors/nacl.mjs'; // Alt import * as ed25519 from '../node_modules/noble-ed25519/index.mjs'; -import {b58,b64} from './basex.mjs'; +import {b58, b64} from './basex.mjs'; -export {b58,b64}; +export {b58, b64}; import sha from '../node_modules/js-sha256/src/sha256.mjs'; const sha256 = sha(); @@ -34,6 +34,7 @@ export async function idSecPass2cleanKeys(idSec, pass) { export function seed2keyPair(seed) { return generateKeypair(seed); } + /* Noble edition export async function seed2keyPair(rawSeed) { const pubKey = await ed25519.getPublicKey(rawSeed); @@ -90,6 +91,7 @@ export function b58pubKey2bin(b58pubKey) { binPubKey.set(decoded, 32 - decoded.length); return binPubKey; } + export function b58secretKey2bin(b58secretKey) { const binSecretKey = new Uint8Array(64); const decoded = b58.decode(b58secretKey); @@ -112,9 +114,29 @@ export function checkKey(pubKeyWithChecksum) { throw new Error('Bad checksum'); } -export function sign(unsignedDocument,secretKey){ +export async function signDocument(unsignedDocument, secretKey) { + const signHash = await sign(unsignedDocument.trim() + '\n', secretKey) + return `${unsignedDocument.trim()}\n${signHash}`; +} + +export async function sign(str, secretKey, outputFormat = 'b64') { const encoder = new TextEncoder(); - const rawSign = nacl.sign.detached(encoder.encode(unsignedDocument.trim()+'\n'), b58secretKey2bin(secretKey)); - const b64Sign = b64.encode(rawSign); - return `${unsignedDocument.trim()}\n${b64Sign}`; + const raw = await rawSign(encoder.encode(str), b58secretKey2bin(secretKey).slice(0, 32)); + switch (outputFormat.toLocaleLowerCase()) { + case 'raw': + case 'array': + case 'uint8array': + return raw; + case 'b64': + return b64.encode(raw); + case 'b58': + return b58.encode(raw); + default: + throw new Error(`OutputFormat ${outputFormat} not handled.`); + } +} + +export async function rawSign(uint8Array, rawSeed) { + const keys = await seed2keyPair(rawSeed); + return nacl.sign.detached(uint8Array, keys.secretKey); } diff --git a/src/crypto.test.mjs b/src/crypto.test.mjs index f60c4d7d6544880ff19b0766c83356685c451d1c..20c65b72ba9d8936f7a989a55be123b43cb82bd1 100644 --- a/src/crypto.test.mjs +++ b/src/crypto.test.mjs @@ -7,13 +7,13 @@ const mdp = 'b'; const pubKey = 'AoxVA41dGL2s4ogMNdbCw3FFYjFo5FPK36LuiW1tjGbG'; const secretKey = '3ZsmZhnRv137dS1s7Q3jFGKLTDyhkwguPHfnWBxzDCTTHKWGnYw9zBk3gcCUJCc72TEUuyzM7cqpo7c5LYhs1Qtv'; const seed = '9eADqX8V6VcPdJCHCVYiE1Vnift9nFNrvr9aTaXA5RJc'; -const unsignedDocument = `Version: 10 +const unsignedDocument = ` +Version: 10 Type: Identity Currency: duniter_unit_test_currency Issuer: AoxVA41dGL2s4ogMNdbCw3FFYjFo5FPK36LuiW1tjGbG UniqueID: tic -Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -`; +Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855`; const signedDocument = `Version: 10 Type: Identity Currency: duniter_unit_test_currency @@ -21,7 +21,14 @@ Issuer: AoxVA41dGL2s4ogMNdbCw3FFYjFo5FPK36LuiW1tjGbG UniqueID: tic Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 8BZ2NE/d4YO2rOFpJFZdEYTIoSL4uSX9zo6tacpHBcCIlSlhkHTIHbSJNuzLl9uVBIO0skI7NZPxEYXIJGQYBg==`; -test('sign document', async t => t.is(await app.sign(unsignedDocument,secretKey), signedDocument)); + +test('signDocument', async t => t.is(await app.signDocument(unsignedDocument,secretKey), signedDocument)); +test('b64 sign string', async t => t.is(await app.sign(unsignedDocument,secretKey), 'G6ma6n+rpJ+7PPsUuJjNtzfGQqLWNqRToSlurt8vjrHa7G0tm7oVObJjQBWGMK0zs4/25xXidT19RrfZqWV/DQ==')); +test('b58 sign string', async t => t.is(await app.sign(unsignedDocument,secretKey,'b58'), 'Z5W7C7ZUwTRPRTCrXtRqmY4WakgEXAkPBDiVEVxoTwrCSvDrup19sENe9tfFNMFKL9ZFdiFWJCSJ2ftgeeDzFsz')); +test('raw sign string', async t => t.is((await app.sign(unsignedDocument,secretKey,'raw'))[0], 27)); +test('array sign string', async t => t.is((await app.sign(unsignedDocument,secretKey,'Array'))[0], 27)); +test('uint8array sign string', async t => t.is((await app.sign(unsignedDocument,secretKey,'uint8array'))[0], 27)); +test('sign throw for bad output format', async t => t.throwsAsync(()=>app.sign(unsignedDocument,secretKey,'whattt ?'))); test('b58 should decode/encode well', t => t.is(app.b58.encode(app.b58.decode(pubKey)), pubKey)); test('b58 on pubKey with leading 1', t => t.is(app.b58.encode(app.b58.decode('12BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx')), '12BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx'));