commit 0111c7a1b26f9c3a7ebf8b7ea64bc466627a4ca6
parent 9494ab7b1dcd761fbc07ca04302a37eb5374eb4c
Author: Jared Tobin <jared@jtobin.io>
Date:   Tue, 22 Sep 2020 20:33:52 -0230
up8-ticket: fix missing consts, add test suite
Diffstat:
| M | src/index.js | | | 5 | +++-- | 
| A | test/test.js | | | 109 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
2 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/src/index.js b/src/index.js
@@ -12,6 +12,7 @@ const GALOIS_BITSIZE = 8
  */
 const unpad = str => {
   if (!(str.slice(0, 1) === '0')) {
+    /* istanbul ignore next */
     throw new Error('nonzero leading digit -- please report this as a bug!')
   }
 
@@ -103,7 +104,7 @@ const gen_ticket_more = (nbits, addl) => {
  * @param  {Number}  k the desired threshold value, smaller than 'n'
  * @return  {Array<String>}  an array of 'n' @q-encoded shards
  */
-shard = (ticket, n, k) => {
+const shard = (ticket, n, k) => {
   if (!ob.isValidPatq(ticket)) {
     throw new Error('input is not @q-encoded')
   }
@@ -125,7 +126,7 @@ shard = (ticket, n, k) => {
  * @param  {Array<String>}  shards an array of @q-encoded shards
  * @return  {String}  a @q-encoded ticket
  */
-combine = shards => {
+const combine = shards => {
   const hexshards = shards.map(ob.patq2hex).map(unpad)
   const hexticket = secrets.combine(hexshards)
   return ob.hex2patq(hexticket)
diff --git a/test/test.js b/test/test.js
@@ -0,0 +1,109 @@
+const { expect } = require('chai')
+const jsc = require('jsverify')
+const ob = require('urbit-ob')
+
+const mtg = require('../src')
+
+// mocha, jsverify stuff
+
+// needs to be required explicitly
+global.crypto = require('crypto')
+
+const ticket_bytes = jsc.elements([8, 16, 24, 32, 40, 48, 56, 64])
+
+// tests
+
+describe('gen_ticket_simple', () => {
+
+  it('produces tickets of the correct bitlength', () => {
+    let prop = jsc.forall(ticket_bytes, bytes => {
+      let bits = bytes * 8
+      let ticket = mtg.gen_ticket_simple(bits)
+      let hex = ob.patq2hex(ticket)
+      let nbits = hex.length * 4
+      return (bits === nbits)
+    })
+
+    jsc.assert(prop)
+  })
+
+})
+
+describe('gen_ticket_more', () => {
+
+  it('produces tickets of the correct bitlength', async () => {
+    let given_bits = 384
+    let ticket = await mtg.gen_ticket_more(given_bits)
+    let hex = ob.patq2hex(ticket)
+    let expected_bits = hex.length * 4
+    expect(expected_bits).to.equal(given_bits)
+  })
+
+})
+
+describe('shard', () => {
+
+  it('throws on non-@q input', () => {
+    expect(() => mtg.shard('flubblub', 3, 2)).to.throw()
+  })
+
+  it("using 3/2 sharding, produces shards that are recombinable", () => {
+    let prop = jsc.forall(ticket_bytes, bytes => {
+      let bits      = bytes * 8
+      let ticket    = mtg.gen_ticket_simple(bits)
+      let shards    = mtg.shard(ticket, 3, 2)
+      let combined0 = mtg.combine(shards.slice(0, 2))
+      let combined1 = mtg.combine(shards.slice(1, 3))
+      let combined2 = mtg.combine([shards[0], shards[2]])
+      let combined3 = mtg.combine(shards)
+
+      return (
+        (ticket === combined0) &&
+        (ticket === combined1) &&
+        (ticket === combined2) &&
+        (ticket === combined3)
+      )
+    })
+
+    jsc.assert(prop)
+  })
+
+  it("using 5/3 sharding, produces shards that are recombinable", () => {
+    let prop = jsc.forall(ticket_bytes, bytes => {
+      let bits      = bytes * 8
+      let ticket    = mtg.gen_ticket_simple(bits)
+      let shards    = mtg.shard(ticket, 5, 3)
+
+      let combined0 = mtg.combine([shards[0], shards[1], shards[2]])
+      let combined1 = mtg.combine([shards[0], shards[1], shards[3]])
+      let combined2 = mtg.combine([shards[0], shards[1], shards[4]])
+
+      let combined3 = mtg.combine([shards[0], shards[2], shards[3]])
+      let combined4 = mtg.combine([shards[0], shards[2], shards[4]])
+
+      let combined5 = mtg.combine([shards[1], shards[2], shards[3]])
+      let combined6 = mtg.combine([shards[1], shards[2], shards[4]])
+
+      let combined7 = mtg.combine([shards[2], shards[3], shards[4]])
+
+      let combined8 = mtg.combine(shards)
+
+      return (
+        (ticket === combined0) &&
+        (ticket === combined1) &&
+        (ticket === combined2) &&
+        (ticket === combined3) &&
+        (ticket === combined4) &&
+        (ticket === combined5) &&
+        (ticket === combined6) &&
+        (ticket === combined7) &&
+        (ticket === combined8)
+      )
+    })
+
+    jsc.assert(prop)
+  })
+
+})
+
+