diff --git a/src/crypto.mjs b/src/crypto.mjs index f662b162575d27ae90cb93a0fbde2e2f92419ca7..b6b60b03f6740b1a8a734c9051f542a64cd7aec0 100644 --- a/src/crypto.mjs +++ b/src/crypto.mjs @@ -2,7 +2,7 @@ // 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 as _b64} from './basex.mjs'; export {b58}; import sha from '../node_modules/js-sha256/src/sha256.mjs'; @@ -12,6 +12,25 @@ const sha256 = sha(); const generateKeypair = nacl.sign.keyPair.fromSeed; import scrypt from '../generated/vendors/scrypt.mjs'; +export const b64 = { + encode:(source)=>{ + const size = Math.ceil(source.length/3)*3; + const sizedArray = new Uint8Array(size); + + if(typeof source === 'string') sizedArray.set((new TextEncoder()).encode(source)); + else sizedArray.set(source); + + const b64str = _b64.encode(sizedArray).split(''); + for(let i = 0;i<size-source.length;i++) b64str[b64str.length-1-i] = '='; + return b64str.join(''); + }, + decode:(b64str)=> { + const rawArray = _b64.decode(b64str.replace(/=/g,'A')); + const targetSize = Math.trunc(3*b64str.length/4 - ( b64str.length - b64str.replace(/=/g,'').length )); + return rawArray.slice(0,targetSize); + } +} + export async function idSecPass2rawAll(idSec, pass) { const rawSeed = await saltPass2seed(idSec, pass); const keyPair = await seed2keyPair(rawSeed); @@ -114,9 +133,7 @@ export function checkKey(pubKeyWithChecksum) { export function sign(unsignedDocument,secretKey){ const encoder = new TextEncoder(); - const decoder = new TextDecoder(); - const rawSign = nacl.sign.detached(encoder.encode(unsignedDocument.trim()), b58secretKey2bin(secretKey)); + const rawSign = nacl.sign.detached(encoder.encode(unsignedDocument.trim()+'\n'), b58secretKey2bin(secretKey)); const b64Sign = b64.encode(rawSign); - return `${unsignedDocument.trim()}\n${b64Sign}`; } diff --git a/src/crypto.test.mjs b/src/crypto.test.mjs index 61eac96b8984729468cf5e59b4f58739a3bc1c9e..cca871960fcf6d3f3dcfd7ae00a71046dce11e38 100644 --- a/src/crypto.test.mjs +++ b/src/crypto.test.mjs @@ -7,24 +7,30 @@ 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 `; -const signedDocument = ` -Version: 10 +const signedDocument = `Version: 10 Type: Identity Currency: duniter_unit_test_currency Issuer: AoxVA41dGL2s4ogMNdbCw3FFYjFo5FPK36LuiW1tjGbG UniqueID: tic Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 -??? -`; -test.skip('sign document', async t => t.is(await app.sign(unsignedDocument,secretKey), signedDocument)); +8BZ2NE/d4YO2rOFpJFZdEYTIoSL4uSX9zo6tacpHBcCIlSlhkHTIHbSJNuzLl9uVBIO0skI7NZPxEYXIJGQYBg==`; +test('sign document', async t => t.is(await app.sign(unsignedDocument,secretKey), signedDocument)); + +test('b64 should encode Man as TWFu', t => t.is(app.b64.encode('Man'), 'TWFu')); +test('b64 should encode Ma as TWE=', t => t.is(app.b64.encode('Ma'), 'TWE=')); +test('b64 should encode M as TQ==', t => t.is(app.b64.encode('M'), 'TQ==')); +test('b64 should decode TWFu as Man', t => t.is((new TextDecoder()).decode(app.b64.decode('TWFu')), 'Man')); +test('b64 should decode TWE= as Ma', t => t.is((new TextDecoder()).decode(app.b64.decode('TWE=')), 'Ma')); +// Won't fix test('b64 should decode TWE as Ma', t => t.is((new TextDecoder()).decode(app.b64.decode('TWE')), 'Ma')); +test('b64 should decode TQ== as M', t => t.is((new TextDecoder()).decode(app.b64.decode('TQ==')), 'M')); +// Won't fix test('b64 should decode TQ as M', t => t.is((new TextDecoder()).decode(app.b64.decode('TQ')), 'M')); 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'));