Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lorena-ssi / zenroom-lib / 30

16 Apr 2020 - 15:50 coverage: 86.585% (-4.2%) from 90.816%
30

Pull #6

travis-ci-com

9181eb84f9c35729a3bad740fb7f9d93?size=18&default=identiconweb-flow
Merge dc2bb99ae into fc07e85b0
Pull Request #6: fix promises

5 of 13 branches covered (38.46%)

Branch coverage included in aggregate %.

32 of 34 new or added lines in 1 file covered. (94.12%)

66 of 69 relevant lines covered (95.65%)

8.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.59
/src/index.js
1
'use strict'
2
const zenroom = require('zenroom')
1×
3

4
/**
5
 * returns the digital Root
6
 *
7
 * @param {number} n Number
8
 * @returns {number} Digital Root (1 digit)
9
 */
10
function digitalRoot (n) {
11
  return (n - 1) % 9 + 1
10×
12
}
13

14
/**
15
 * Javascript Class to interact with Zenroom.
16
 */
17
module.exports = class Zen {
1×
18
  constructor (silent = false) {
Branches [[0, 0]] missed.
19
    this.isSilent = silent
1×
20
    if (this.isSilent) {
Branches [[1, 1]] missed. 1×
21
      this.ogWriteStdout = process.stdout.write.bind(process.stdout)
1×
22
      this.ogWriteStdErr = process.stderr.write.bind(process.stderr)
1×
23
      process.on('uncaughtException', function (err) {
1×
24
        console.error((err && err.stack) ? err.stack : err)
Branches [[2, 0], [2, 1], [3, 0], [3, 1]] missed. !
25
      })
26
    }
27
  }
28

29
  /**
30
   * Executes Zencode.
31
   *
32
   * @param {object} keys  Input keys.
33
   * @param {string} script Zencode to be executed
34
   * @returns {Promise} Return a promise with the execution of the script.
35
   */
36
  async execute (keys, script) {
37
    const options = { verbosity: 0 }
25×
38

39
    return new Promise((resolve, reject) => {
25×
40
      const log = []
25×
41
      if (this.isSilent) {
Branches [[4, 1]] missed. 25×
42
        this.stdoutWrite = (data) => log.push({ stdout: data })
25×
43
        this.stderrWrite = (data) => log.push({ stderr: data })
168×
44
        process.stdout.write = this.stdoutWrite
25×
45
        process.stderr.write = this.stderrWrite // TODO: They need to implement verbosity https://github.com/DECODEproject/Zenroom/blob/master/bindings/javascript/src/wrapper.js
25×
46
      }
47
      zenroom
25×
48
        .init(options)
49
        .keys(keys)
50
        .script(script)
51
        .print((msg) => {
52
          resolve(JSON.parse(msg))
25×
53
        })
54
        .error(() => {
NEW
55
          reject(new Error('Zenroom error' + log))
!
56
        })
57
        .zencode_exec()
58
      if (this.isSilent) {
Branches [[5, 1]] missed. 25×
59
        process.stdout.write = this.ogWriteStdout
25×
60
        process.stderr.write = this.ogWriteStdErr
25×
61
      }
62
    })
63
  }
64

65
  /**
66
   * Creates a new keypair.
67
   *
68
   * @param {string} name  Holder of the keypair.
69
   * @returns {Promise} Return a promise with the execution of the creation.
70
   */
71
  async newKeyPair (name) {
72
    return this.execute(false,
2×
73
      `rule check version 1.0.0
74
      Scenario simple: Create the keypair
75
      Given that I am known as '` + name + `'
76
      When I create the keypair
77
      Then print my data`
78
    )
79
  }
80

81
  /**
82
   * Creates a new keypair.
83
   *
84
   * @param {string} name  Holder of the keypair.
85
   * @param {*} keys to create
86
   * @returns {Promise} Return a promise with the execution of the creation.
87
   */
88
  async publicKey (name, keys) {
89
    return this.execute(keys,
2×
90
      `rule check version 1.0.0
91
      Scenario simple Create the keypair
92
      Given that I am known as '` + name + `'
93
      and I have my valid 'public key'
94
      Then print my data`
95
    )
96
  }
97

98
  /**
99
   * Encrypts (asymmetric) a message with a keypair.
100
   *
101
   * @param {string} fromName Who's signing the message.
102
   * @param {object} fromKeys Keypair for the encrypter (Zencode format)
103
   * @param {string} toName Who's receiving the message.
104
   * @param {object} toKeys Public Key for the receiver (Zencode format)
105
   * @param {string} message Message to be encrypted
106
   * @returns {Promise} Return a promise with the execution of the encryption.
107
   */
108
  async encryptAsymmetric (fromName, fromKeys, toName, toKeys, message) {
109
    // Move to Hex.
110
    const msg = Buffer.from(message, 'utf8')
1×
111
    return this.execute([fromKeys, toKeys],
1×
112
      `Rule check version 1.0.0
113
      Scenario simple: ` + fromName + ' encrypts a message for ' + toName + `
114
      Given that I am known as '` + fromName + `'
115
      and I have my valid 'keypair'
116
      and I have a valid 'public key' from '` + toName + `'
117
      When I write '${msg.toString('hex')}' in 'message'
118
      and I write 'This is the header' in 'header'
119
      and I encrypt the message for '` + toName + `'
120
      Then print the 'secret_message'`
121
    )
122
  }
123

124
  /**
125
   * Decrypts (asymmetric) a message with a keypair.
126
   *
127
   * @param {string} fromName Who's signing the message.
128
   * @param {object} fromKeys Keypair for the encrypter (Zencode format)
129
   * @param {string} toName Who's receiving the message.
130
   * @param {object} toKeys Public Key for the receiver (Zencode format)
131
   * @param {string} message Message to be decrypted
132
   * @returns {Promise} Return a promise with the execution of the encryption.
133
   */
134
  async decryptAsymmetric (fromName, fromKeys, toName, toKeys, message) {
135
    return new Promise((resolve) => {
1×
136
      this.execute([fromKeys, toKeys, message],
1×
137
        `Rule check version 1.0.0
138
        Scenario simple: ` + toName + ' decrypts the message for ' + fromName + `
139
        Given that I am known as '` + toName + `'
140
        and I have my valid 'keypair'
141
        and I have a valid 'public key' from '` + fromName + `'
142
        and I have a valid 'secret_message'
143
        When I decrypt the secret message from '` + fromName + `'
144
        Then print as 'string' the 'message'
145
        and print as 'string' the 'header' inside 'secret message'`
146
      ).then((msg) => {
147
        const txt = Buffer.from(msg.message, 'hex')
1×
148
        resolve({
1×
149
          message: txt.toString('utf8')
150
        })
151
      })
152
    })
153
  }
154

155
  /**
156
   * Encrypts (symmetric) a message with a keypair.
157
   *
158
   * @param {string} password Password to encrypt the message
159
   * @param {string} message Message to be encrypted
160
   * @param {string} header Header to be included
161
   * @returns {Promise} Return a promise with the execution of the encryption.
162
   */
163
  async encryptSymmetric (password, message, header) {
164
    // Move to Hex.
165
    const msg = Buffer.from(message, 'utf8')
1×
166
    const hdr = Buffer.from(header, 'utf8')
1×
167
    // Encrypt.
168
    return this.execute(false,
1×
169
        `Rule check version 1.0.0
170
        Scenario simple: Encrypt a message with the password
171
        Given nothing
172
        When I write '${password}' in 'password'
173
        and I write '${msg.toString('hex')}' in 'whisper'
174
        and I write '${hdr.toString('hex')}' in 'header'
175
        and I encrypt the secret message 'whisper' with 'password'
176
        Then print the 'secret message'`
177
    )
178
  }
179

180
  /**
181
   * Encrypts (symmetric) a message with a keypair.
182
   *
183
   * @param {string} password Password to decrypt the message
184
   * @param {string} msgEncrypted Message to be decrypted
185
   * @returns {Promise} Return a promise with the execution of the encryption.
186
   */
187
  async decryptSymmetric (password, msgEncrypted) {
188
    return new Promise((resolve) => {
1×
189
      this.execute([msgEncrypted],
1×
190
        `Rule check version 1.0.0
191
        Scenario simple: Decrypt the message with the password
192
        Given I have a valid 'secret message'
193
        When I write '${password}' in 'password'
194
        and I decrypt the secret message with 'password'
195
        Then print as 'string' the 'text' inside 'message'
196
        and print as 'string' the 'header' inside 'message'`
197
      ).then((msg) => {
198
        const txt = Buffer.from(msg.text, 'hex')
1×
199
        const hdr = Buffer.from(msg.header, 'hex')
1×
200
        resolve({
1×
201
          header: hdr.toString('utf8'),
202
          message: txt.toString('utf8')
203
        })
204
      }).catch(_e => {
NEW
205
        resolve(false)
!
206
      })
207
    })
208
  }
209

210
  /**
211
   * Signs a message with a keypair.
212
   *
213
   * @param {string} signer Who's signing the message.
214
   * @param {object} keys Keypair for the signer (Zencode format)
215
   * @param {string} message Message to be signed
216
   * @returns {Promise} Returns a promise with the execution of the signature.
217
   */
218
  async signMessage (signer, keys, message) {
219
    return this.execute(keys,
1×
220
      `Rule check version 1.0.0
221
      Scenario simple: ` + signer + ` signs a message for Recipient
222
      Given that I am known as '` + signer + `'
223
      and I have my valid 'keypair'
224
      When I write '${message}' in 'draft'
225
      and I create the signature of 'draft'
226
      Then print my 'signature'
227
      and print my 'draft'`
228
    )
229
  }
230

231
  /**
232
   * Checks signature of a message.
233
   *
234
   * @param {string} signer Who's signing the message.
235
   * @param {object} signerPublic Who's signing the message, public Key.
236
   * @param {object} signature Signature of the message.
237
   * @param {string} verifier Message to be checked
238
   * @returns {Promise} Returns a promise with the execution of the signature.
239
   */
240
  async checkSignature (signer, signerPublic, signature, verifier) {
241
    const checkScript = `
1×
242
      rule check version 1.0.0
243
      Scenario simple: ` + verifier + ' verifies the signature from ' + signer + `
244
      Given that I am known as '` + verifier + `'
245
      and I have a valid 'public key' from '` + signer + `'
246
      and I have a valid 'signature' from '` + signer + `'
247
      and I have a 'draft'
248
      When I verify the 'draft' is signed by '` + signer + `'
249
      Then print 'signature' 'correct' as 'string'`
250
    const keys = signature
1×
251
    keys[signer].public_key = signerPublic[signer].public_key
1×
252
    return this.execute(keys, checkScript)
1×
253
  }
254

255
  /**
256
   * Creates a new Issuer keypair.
257
   *
258
   * @param {string} name  Issuer of the credential keypair.
259
   * @returns {Promise} Return a promise with the execution of the creation.
260
   */
261
  async newIssuerKeyPair (name) {
262
    return this.execute(false, `rule check version 1.0.0
1×
263
    Scenario 'coconut': issuer keygen
264
    Given that I am known as '` + name + `'
265
    When I create the issuer keypair
266
    Then print my 'issuer keypair'`)
267
  }
268

269
  /**
270
   * ZKP : Get the Verifier to be published.
271
   *
272
   * @param {string} verifier Who's signing the message.
273
   * @param {object} keys Keypair for the signer (Zencode format)
274
   * @returns {Promise} Returns a promise with the execution of the signature.
275
   */
276
  async publishVerifier (verifier, keys) {
277
    return this.execute(keys,
1×
278
      `rule check version 1.0.0
279
      Scenario 'coconut': publish verifier
280
      Given that I am known as '` + verifier + `'
281
      and I have a valid 'verifier'
282
      Then print my 'verifier'`
283
    )
284
  }
285

286
  /**
287
   * Creates a new Credential keypair.
288
   *
289
   * @param {string} name  Holder of the keypair.
290
   * @returns {Promise} Return a promise with the execution of the creation.
291
   */
292
  async newCredentialKeyPair (name) {
293
    const keygenContract = `rule check version 1.0.0
1×
294
      Scenario 'coconut': issuer keygen
295
        Given that I am known as '` + name + `'
296
        When I create the credential keypair
297
        Then print my 'credential keypair'`
298
    return this.execute(false, keygenContract)
1×
299
  }
300

301
  /**
302
   * Creates a new Signature Request.
303
   *
304
   * @param {string} name  Holder of the credential.
305
   * @param {object} credentialKeyPair Keypair for the credentials (Zencode format)
306
   * @returns {Promise} Return a promise with the execution of the creation.
307
   */
308
  async credentialSignatureRequest (name, credentialKeyPair) {
309
    return this.execute(credentialKeyPair, `rule check version 1.0.0
1×
310
      Scenario 'coconut': create request
311
      Given that I am known as '` + name + `'
312
      and I have my valid 'credential keypair'
313
      When I create the credential request
314
      Then print my 'credential request'`)
315
  }
316

317
  /**
318
   * Creates a new Credential keypair.
319
   *
320
   * @param {string} nameIssuer  Issuer of the credential.
321
   * @param {object} issuerKeyPair Keypair for the Issuer (Zencode format)
322
   * @param {object} signatureRequest signature Request by the Credential Holder.
323
   * @returns {Promise} Return a promise with the execution of the creation.
324
   */
325
  async signCredentialSignatureRequest (nameIssuer, issuerKeyPair, signatureRequest) {
326
    return this.execute([issuerKeyPair, signatureRequest],
1×
327
      `rule check version 1.0.0
328
      Scenario 'coconut': issuer sign
329
      Given that I am known as '` + nameIssuer + `'
330
      and I have my valid 'issuer keypair'
331
      and I have a valid 'credential request'
332
      When I create the credential signature
333
      Then print the 'credential signature'
334
      and print the 'verifier'`
335
    )
336
  }
337

338
  /**
339
   * Aggregates signature to the credential Proof.
340
   *
341
   * @param {string} name  Holder of the keypair.
342
   * @param {object} credentialKeyPair Keypair for the credentials (Zencode format)
343
   * @param {object} credentialSignature Credential Request Signature
344
   * @returns {Promise} Return a promise with the execution of the creation.
345
   */
346
  async aggregateCredentialSignature (name, credentialKeyPair, credentialSignature) {
347
    return this.execute([credentialKeyPair, credentialSignature],
1×
348
      `rule check version 1.0.0
349
      Scenario coconut: aggregate signature
350
      Given that I am known as '` + name + `'
351
      and I have my valid 'credential keypair'
352
      and I have a valid 'credential signature'
353
      When I create the credentials
354
      Then print my 'credentials'
355
      and print my 'credential keypair'`)
356
  }
357

358
  /**
359
   * Creates a new Credential Proof.
360
   *
361
   * @param {string} name  Holder of the credential.
362
   * @param {string} nameIssuer Issuer of the credential.
363
   * @param {object} credential to use
364
   * @param {object} verifier of credential
365
   * @returns {Promise} Return a promise with the execution of the creation.
366
   */
367
  async createCredentialProof (name, nameIssuer, credential, verifier) {
368
    return this.execute([credential, verifier],
1×
369
      `rule check version 1.0.0
370
      Scenario coconut: create proof
371
      Given that I am known as '` + name + `'
372
      and I have my valid 'credential keypair'
373
      and I have a valid 'verifier' from '` + nameIssuer + `'
374
      and I have my valid 'credentials'
375
      When I aggregate the verifiers
376
      and I create the credential proof
377
      Then print the 'credential proof'`)
378
  }
379

380
  /**
381
   * Verify a Credential Proof.
382
   *
383
   * @param {string} nameIssuer Issuer
384
   * @param {object} credentialProof to use
385
   * @param {object} verifier to use
386
   * @returns {Promise} Return a promise with the execution of the creation.
387
   */
388
  async verifyCredentialProof (nameIssuer, credentialProof, verifier) {
389
    return this.execute([credentialProof, verifier],
1×
390
      `rule check version 1.0.0
391
      Scenario coconut: verify proof
392
      Given that I have a valid 'verifier' from '` + nameIssuer + `'
393
      and I have a valid 'credential proof'
394
      When I aggregate the verifiers
395
      and I verify the credential proof
396
      Then print 'Success' 'OK' as 'string'`)
397
  }
398

399
  /**
400
   * Create a Random string
401
   *
402
   * @param {number} length Length of the random string
403
   * @returns {Promise} Return a promise with the execution of the creation.
404
   */
405
  async random (length = 32) {
406
    return new Promise((resolve) => {
6×
407
      this.execute(false,
6×
408
        `rule check version 1.0.0
409
        Scenario simple: Generate a random password
410
        Given nothing
411
        When I create the array of '1' random objects of '256' bits
412
        Then print the 'array'`).then((rnd) => {
413
        var b = Buffer.from(rnd.array[0])
6×
414
        resolve(b.toString('base64').substring(0, length))
6×
415
      })
416
    })
417
  }
418

419
  /**
420
   * Creates a random Pin
421
   *
422
   * @param {number} length Length of the random PIN
423
   * @returns {Promise} Return a promise with the execution of the creation.
424
   */
425
  async randomPin (length = 6) {
426
    return new Promise((resolve) => {
2×
427
      let pin = ''
2×
428
      this.random(length)
2×
429
        .then((rnd) => {
430
          for (let i = 0; i < length; i++) {
2×
431
            pin += digitalRoot(rnd.charCodeAt(i))
10×
432
          }
433
          resolve(pin)
2×
434
        })
435
    })
436
  }
437

438
  /**
439
   * Creates a random DID
440
   *
441
   * @returns {Promise} Return a promise with the execution of the creation.
442
   */
443
  async randomDID () {
444
    return new Promise((resolve) => {
1×
445
      this.random(32)
1×
446
        .then((rnd) => {
447
          var b = Buffer.from(rnd)
1×
448
          resolve(b.toString('base64').slice(0, 32))
1×
449
        })
450
    })
451
  }
452

453
  /**
454
   * Create a Hash
455
   *
456
   * @param {string} source to be hashed
457
   * @returns {Promise} Return a promise with the execution of the creation.
458
   */
459
  async hash (source) {
460
    return this.execute(false,
1×
461
      `rule output encoding hex
462
      Given nothing
463
      When I write '` + source + `' in 'source'
464
      and I create the hash of 'source'
465
      Then print the 'hash'`)
466
  }
467
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2023 Coveralls, Inc