chiark / gitweb /
server/, keys/: Add bulk crypto transform based on NaCl `crypto_secretbox'.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 26 May 2016 08:26:09 +0000 (09:26 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 14 May 2017 17:19:09 +0000 (18:19 +0100)
keys/tripe-keys.conf.5.in
keys/tripe-keys.in
keys/tripe-keys.master
server/bulkcrypto.c
server/tests.at
server/tripe.8.in
server/tripe.h
t/keyring-alpha

index ee67e9a367c660e93e26d74eed398c6e76a7782d..ab4c9e16d6f0e5fa6e69068b1f08c273e9e91c5f 100644 (file)
@@ -229,25 +229,56 @@ Hashing algorithm to use.  Default is
 The bulk crypto transform to use.
 Default is
 .BR iiv .
 The bulk crypto transform to use.
 Default is
 .BR iiv .
+.ne 8
+.TP
 .I mac
 .I mac
-Message authentication algorithm to use.  Default is
-.IB hash -hmac/ halfhashlen \fR,
-where
+Message authentication algorithm to use.
+Default depends on
+.I bulk
+as follows.
+.TS
+center;
+| ci | ci |
+| lb | lb |.
+_
+bulk   mac
+_
+v0     \fIhash\fB-hmac/\fIhalfhashlen
+iiv    \fIhash\fB-hmac/\fIhalfhashlenrijndael-cbc
+naclbox        poly1305/128
+_
+.TE
+.IP
+(In the above,
 .I halfhashlen
 is half of
 .IR hash 's
 .I halfhashlen
 is half of
 .IR hash 's
-output length.
+output length.)
 .TP
 .I mgf
 Mask-generation algorithm to use.  Default is
 .IB hash -mgf \fR.
 This is probably a good choice.
 .TP
 .I mgf
 Mask-generation algorithm to use.  Default is
 .IB hash -mgf \fR.
 This is probably a good choice.
-.ne 6
+.ne 7
 .TP
 .I cipher
 .TP
 .I cipher
-Symmetric encryption scheme to use.  Default is
-.BR rijndael-cbc .
-.ne 6
+Symmetric encryption scheme to use.
+Default depends on
+.I bulk
+as follows.
+.TS
+center;
+| ci | ci |
+| lb | lb |.
+_
+bulk   cipher
+_
+v0     rijndael-cbc
+iiv    rijndael-cbc
+naclbox        chacha20
+_
+.TE
+.ne 7
 .TP
 .I sig
 Signature scheme to use.  Must be one of those recognized by
 .TP
 .I sig
 Signature scheme to use.  Must be one of those recognized by
index 81d2ff707a38243fca6ff9b555579dbe62e5bcf5..62b62b6ec7aaa7b8e7691bf9302e0c01f3e0dbb6 100644 (file)
@@ -248,14 +248,17 @@ def conf_defaults():
                ('kx-expire', 'now + 1 year'),
                ('kx-warn-days', '28'),
                ('bulk', 'iiv'),
                ('kx-expire', 'now + 1 year'),
                ('kx-warn-days', '28'),
                ('bulk', 'iiv'),
-               ('cipher', 'rijndael-cbc'),
+               ('cipher', lambda: conf['bulk'] == 'naclbox'
+                                    and 'salsa20' or 'rijndael-cbc'),
                ('hash', 'sha256'),
                ('master-keygen-flags', '-l'),
                ('master-attrs', ''),
                ('mgf', '${hash}-mgf'),
                ('hash', 'sha256'),
                ('master-keygen-flags', '-l'),
                ('master-attrs', ''),
                ('mgf', '${hash}-mgf'),
-               ('mac', lambda: '%s-hmac/%d' %
-                         (conf['hash'],
-                          C.gchashes[conf['hash']].hashsz * 4)),
+               ('mac', lambda: conf['bulk'] == 'naclbox'
+                                 and 'poly1305/128'
+                                 or '%s-hmac/%d' %
+                                      (conf['hash'],
+                                       C.gchashes[conf['hash']].hashsz * 4)),
                ('sig', lambda: {'dh': 'dsa', 'ec': 'ecdsa'}[conf['kx']]),
                ('sig-fresh', 'always'),
                ('sig-genalg', lambda: {'kcdsa': 'dh',
                ('sig', lambda: {'dh': 'dsa', 'ec': 'ecdsa'}[conf['kx']]),
                ('sig-fresh', 'always'),
                ('sig-genalg', lambda: {'kcdsa': 'dh',
@@ -580,6 +583,10 @@ def cmd_mtu(args):
     mtu -= mac_tagsz()                  # MAC tag
     mtu -= 4                            # Sequence number
 
     mtu -= mac_tagsz()                  # MAC tag
     mtu -= 4                            # Sequence number
 
+  elif bulk == 'naclbox':
+    mtu -= 16                           # MAC tag
+    mtu -= 4                            # Sequence number
+
   else:
     die("Unknown bulk transform `%s'" % bulk)
 
   else:
     die("Unknown bulk transform `%s'" % bulk)
 
index a4b98ae7c1eb18df0432406f46ff27d85b7caf44..121bd910e8762b7a13f1234de655c71d84fd9485 100644 (file)
@@ -28,7 +28,7 @@
 ## Expiry time for peer key-exchange keys.
 # kx-expire = now + 1 year
 
 ## Expiry time for peer key-exchange keys.
 # kx-expire = now + 1 year
 
-## Bulk crypto transform to use.  May be `v0', or `iiv'.
+## Bulk crypto transform to use.  May be `v0', `iiv', or `naclbox'.
 # bulk = iiv
 
 ## Symmetric encryption scheme to use.
 # bulk = iiv
 
 ## Symmetric encryption scheme to use.
index 288eed9dbc5a741a508677c5078a2c8ebd5987ba..0e02f747cc104c40459b0db583517b1b1ab0b003 100644 (file)
@@ -749,6 +749,320 @@ static int iiv_decrypt(bulkctx *bbc, unsigned ty,
   return (0);
 }
 
   return (0);
 }
 
+/*----- The NaCl box transform --------------------------------------------*
+ *
+ * This transform is very similar to the NaCl `crypto_secretbox' transform
+ * described in Bernstein, `Cryptography in NaCl', with the difference that,
+ * rather than using XSalsa20, we use either Salsa20/r or ChaChar, because we
+ * have no need of XSalsa20's extended nonce.  The default cipher is Salsa20.
+ *
+ * Salsa20 and ChaCha accept a 64-bit nonce.  The low 32 bits are the
+ * sequence number, and the high 32 bits are the type, both big-endian.
+ *
+ *             +------+------+
+ *             | seq  | type |
+ *             +------+------+
+ *                32     32
+ *
+ * A stream is generated by concatenating the raw output blocks generated
+ * with this nonce and successive counter values starting from zero.  The
+ * first 32 bytes of the stream are used as a key for Poly1305: the first 16
+ * bytes are the universal hash key r, and the second 16 bytes are the mask
+ * value s.
+ *
+ *             +------+------+ +------...------+
+ *             |  r   |  s   | |   keystream   |
+ *             +------+------+ +------...------+
+ *               128    128           sz
+ *
+ * The remainder of the stream is XORed with the incoming plaintext to form a
+ * ciphertext with the same length.  The ciphertext (only) is then tagged
+ * using Poly1305.  The tag, sequence number, and ciphertext are concatenated
+ * in this order, and transmitted.
+ *
+ *
+ *             +---...---+------+------...------+
+ *             |   tag   | seq  |   ciphertext  |
+ *             +---...---+------+------...------+
+ *                 128     32          sz
+ *
+ * Note that there is no need to authenticate the type separately, since it
+ * was used to select the cipher nonce, and hence the Poly1305 key.  The
+ * Poly1305 tag length is fixed.
+ */
+
+typedef struct naclbox_algs {
+  bulkalgs _b;
+  const gccipher *c; size_t cksz;
+} naclbox_algs;
+
+typedef struct naclbox_ctx {
+  bulkctx _b;
+  struct { gcipher *c; } d[NDIR];
+} naclbox_ctx;
+
+
+static bulkalgs *naclbox_getalgs(const algswitch *asw, dstr *e,
+                                key_file *kf, key *k)
+{
+  naclbox_algs *a = CREATE(naclbox_algs);
+  const char *p;
+  char *qq;
+  unsigned long n;
+
+  /* --- Collect the selected cipher and check that it's supported --- */
+
+  p = key_getattr(kf, k, "cipher");
+  if (!p || strcmp(p, "salsa20") == 0) a->c = &salsa20;
+  else if (strcmp(p, "salsa20/12") == 0) a->c = &salsa2012;
+  else if (strcmp(p, "salsa20/8") == 0) a->c = &salsa208;
+  else if (strcmp(p, "chacha20") == 0) a->c = &chacha20;
+  else if (strcmp(p, "chacha12") == 0) a->c = &chacha12;
+  else if (strcmp(p, "chacha8") == 0) a->c = &chacha8;
+  else {
+    a_format(e, "unknown-cipher", "%s", p, A_END);
+    goto fail;
+  }
+
+  /* --- Collect the selected MAC, and check the tag length --- */
+
+  p = key_getattr(kf, k, "mac");
+  if (!p)
+    ;
+  else if (strncmp(p, "poly1305", 8) != 0 || (p[8] && p[8] != '/')) {
+    a_format(e, "unknown-mac", "%s", p, A_END);
+    goto fail;
+  } else if (p[8] == '/') {
+    n = strtoul(p + 9, &qq, 0);
+    if (*qq) {
+      a_format(e, "bad-tag-length-string", "%s", p + 9, A_END);
+      goto fail;
+    }
+    if (n != 128) {
+      a_format(e, "bad-tag-length", "%lu", n, A_END);
+      goto fail;
+    }
+  }
+
+  return (&a->_b);
+fail:
+  DESTROY(a);
+  return (0);
+}
+
+#ifndef NTRACE
+static void naclbox_tracealgs(const bulkalgs *aa)
+{
+  const naclbox_algs *a = (const naclbox_algs *)aa;
+
+  trace(T_CRYPTO, "crypto: cipher = %s", a->c->name);
+  trace(T_CRYPTO, "crypto: mac = poly1305/128");
+}
+#endif
+
+static int naclbox_checkalgs(bulkalgs *aa, const algswitch *asw, dstr *e)
+{
+  naclbox_algs *a = (naclbox_algs *)aa;
+
+  if ((a->cksz = keysz(asw->hashsz, a->c->keysz)) == 0) {
+    a_format(e, "cipher", "%s", a->c->name,
+            "no-key-size", "%lu", (unsigned long)asw->hashsz,
+            A_END);
+    return (-1);
+  }
+  return (0);
+}
+
+static int naclbox_samealgsp(const bulkalgs *aa, const bulkalgs *bb)
+{
+  const naclbox_algs *a = (const naclbox_algs *)aa,
+    *b = (const naclbox_algs *)bb;
+  return (a->c == b->c);
+}
+
+static void naclbox_alginfo(const bulkalgs *aa, admin *adm)
+{
+  const naclbox_algs *a = (const naclbox_algs *)aa;
+  a_info(adm, "cipher=%s", a->c->name, "cipher-keysz=32", A_END);
+  a_info(adm, "mac=poly1305", "mac-tagsz=16", A_END);
+}
+
+static size_t naclbox_overhead(const bulkalgs *aa)
+  { return (POLY1305_TAGSZ + SEQSZ); }
+
+static size_t naclbox_expsz(const bulkalgs *aa)
+  { return (MEG(2048)); }
+
+static bulkctx *naclbox_genkeys(const bulkalgs *aa, const struct rawkey *rk)
+{
+  const naclbox_algs *a = (const naclbox_algs *)aa;
+  naclbox_ctx *bc = CREATE(naclbox_ctx);
+  octet k[MAXHASHSZ];
+  int i;
+
+  for (i = 0; i < NDIR; i++) {
+    ks_derivekey(k, a->cksz, rk, i, "encryption");
+    bc->d[i].c = GC_INIT(a->c, k, a->cksz);
+  }
+  return (&bc->_b);
+}
+
+typedef struct naclbox_chal {
+  bulkchal _b;
+  gcipher *c;
+} naclbox_chal;
+
+static bulkchal *naclbox_genchal(const bulkalgs *aa)
+{
+  const naclbox_algs *a = (const naclbox_algs *)aa;
+  naclbox_chal *c = CREATE(naclbox_chal);
+  rand_get(RAND_GLOBAL, buf_t, a->cksz);
+  c->c = GC_INIT(a->c, buf_t, a->cksz);
+  IF_TRACING(T_CHAL, {
+    trace(T_CHAL, "chal: generated new challenge key");
+    trace_block(T_CRYPTO, "chal: new key", buf_t, a->cksz);
+  })
+  c->_b.tagsz = 16;
+  return (&c->_b);
+}
+
+static int naclbox_chaltag(bulkchal *bc, const void *m, size_t msz, void *t)
+{
+  naclbox_chal *c = (naclbox_chal *)bc;
+  octet b0[SALSA20_NONCESZ];
+  assert(msz <= sizeof(b0));
+  memcpy(b0, m, msz); memset(b0 + msz, 0, sizeof(b0) - msz);
+  GC_SETIV(c->c, b0);
+  GC_ENCRYPT(c->c, 0, t, c->_b.tagsz);
+  return (0);
+}
+
+static int naclbox_chalvrf(bulkchal *bc, const void *m, size_t msz,
+                          const void *t)
+{
+  naclbox_chal *c = (naclbox_chal *)bc;
+  octet b0[SALSA20_NONCESZ], b1[16];
+  assert(msz <= sizeof(b0)); assert(c->_b.tagsz <= sizeof(b1));
+  memcpy(b0, m, msz); memset(b0 + msz, 0, sizeof(b0) - msz);
+  GC_SETIV(c->c, b0);
+  GC_ENCRYPT(c->c, 0, b1, c->_b.tagsz);
+  return (ct_memeq(t, b1, c->_b.tagsz) ? 0 : -1);
+}
+
+static void naclbox_freechal(bulkchal *bc)
+  { naclbox_chal *c = (naclbox_chal *)bc; GC_DESTROY(c->c); DESTROY(c); }
+
+static void naclbox_freealgs(bulkalgs *aa)
+  { naclbox_algs *a = (naclbox_algs *)aa; DESTROY(a); }
+
+static void naclbox_freectx(bulkctx *bbc)
+{
+  naclbox_ctx *bc = (naclbox_ctx *)bbc;
+  int i;
+
+  for (i = 0; i < NDIR; i++) GC_DESTROY(bc->d[i].c);
+  DESTROY(bc);
+}
+
+static int naclbox_encrypt(bulkctx *bbc, unsigned ty,
+                          buf *b, buf *bb, uint32 seq)
+{
+  naclbox_ctx *bc = (naclbox_ctx *)bbc;
+  gcipher *c = bc->d[DIR_OUT].c;
+  poly1305_key polyk;
+  poly1305_ctx poly;
+  const octet *p = BCUR(b);
+  size_t sz = BLEFT(b);
+  octet *qmac, *qseq, *qpk;
+
+  /* --- Determine the ciphertext layout --- */
+
+  if (buf_ensure(bb, POLY1305_TAGSZ + SEQSZ + sz)) return (0);
+  qmac = BCUR(bb); qseq = qmac + POLY1305_TAGSZ; qpk = qseq + SEQSZ;
+  BSTEP(bb, POLY1305_TAGSZ + SEQSZ + sz);
+
+  /* --- Construct and set the nonce --- */
+
+  STORE32(qseq, seq);
+  memcpy(buf_u, qseq, SEQSZ); STORE32(buf_u + SEQSZ, ty);
+  GC_SETIV(c, buf_u);
+  TRACE_IV(buf_u, SALSA20_NONCESZ);
+
+  /* --- Determine the MAC key --- */
+
+  GC_ENCRYPT(c, 0, buf_u, POLY1305_KEYSZ + POLY1305_MASKSZ);
+  poly1305_keyinit(&polyk, buf_u, POLY1305_KEYSZ);
+  poly1305_macinit(&poly, &polyk, buf_u + POLY1305_KEYSZ);
+
+  /* --- Encrypt the message --- */
+
+  GC_ENCRYPT(c, p, qpk, sz);
+  TRACE_CT(qpk, sz);
+
+  /* --- Compute the MAC --- */
+
+  poly1305_hash(&poly, qpk, sz);
+  poly1305_done(&poly, qmac);
+  TRACE_MAC(qmac, POLY1305_TAGSZ);
+
+  /* --- We're done --- */
+
+  return (0);
+}
+
+static int naclbox_decrypt(bulkctx *bbc, unsigned ty,
+                      buf *b, buf *bb, uint32 *seq)
+{
+  naclbox_ctx *bc = (naclbox_ctx *)bbc;
+  gcipher *c = bc->d[DIR_IN].c;
+  poly1305_key polyk;
+  poly1305_ctx poly;
+  const octet *pmac, *pseq, *ppk;
+  size_t psz = BLEFT(b);
+  size_t sz;
+  octet *q = BCUR(bb);
+
+  /* --- Break up the packet into its components --- */
+
+  if (psz < SEQSZ + POLY1305_TAGSZ) {
+    T( trace(T_KEYSET, "keyset: block too small for keyset"); )
+    return (KSERR_MALFORMED);
+  }
+  sz = psz - SEQSZ - POLY1305_TAGSZ;
+  pmac = BCUR(b); pseq = pmac + POLY1305_TAGSZ; ppk = pseq + SEQSZ;
+
+  /* --- Construct and set the nonce --- */
+
+  memcpy(buf_u, pseq, SEQSZ); STORE32(buf_u + SEQSZ, ty);
+  GC_SETIV(c, buf_u);
+  TRACE_IV(buf_u, SALSA20_NONCESZ);
+
+  /* --- Determine the MAC key --- */
+
+  GC_ENCRYPT(c, 0, buf_u, POLY1305_KEYSZ + POLY1305_MASKSZ);
+  poly1305_keyinit(&polyk, buf_u, POLY1305_KEYSZ);
+  poly1305_macinit(&poly, &polyk, buf_u + POLY1305_KEYSZ);
+
+  /* --- Verify the MAC on the packet --- */
+
+  poly1305_hash(&poly, ppk, sz);
+  poly1305_done(&poly, buf_u);
+  if (!ct_memeq(buf_u, pmac, POLY1305_TAGSZ)) {
+    TRACE_MACERR(pmac, POLY1305_TAGSZ);
+    return (KSERR_DECRYPT);
+  }
+
+  /* --- Decrypt the packet --- */
+
+  GC_DECRYPT(c, ppk, q, sz);
+
+  /* --- Finished --- */
+
+  *seq = LOAD32(pseq);
+  BSTEP(bb, sz);
+  return (0);
+}
+
 /*----- Bulk crypto transform table ---------------------------------------*/
 
 const bulkops bulktab[] = {
 /*----- Bulk crypto transform table ---------------------------------------*/
 
 const bulkops bulktab[] = {
@@ -765,6 +1079,7 @@ const bulkops bulktab[] = {
 
   BULK("v0", v0),
   BULK("iiv", iiv),
 
   BULK("v0", v0),
   BULK("iiv", iiv),
+  BULK("naclbox", naclbox),
 
 #undef BULK
   { 0 }
 
 #undef BULK
   { 0 }
index 6c5d5e32c76886eaa4080b85bd6cf73f713614b3..88b9d160faa549c8fdb9a3d196ad4c439774371a 100644 (file)
@@ -587,11 +587,11 @@ WITH_3TRIPES([alice], [bob], [carol], [-nslip -Tmx],
 
   AT_DATA([algs-alpha], [dnl
 kx-group=ec kx-group-order-bits=256 kx-group-elt-bits=512
 
   AT_DATA([algs-alpha], [dnl
 kx-group=ec kx-group-order-bits=256 kx-group-elt-bits=512
-hash=rmd160 mgf=rmd160-mgf hash-sz=20
-bulk-transform=v0 bulk-overhead=22
-cipher=blowfish-cbc cipher-keysz=20 cipher-blksz=8
-mac=rmd160-hmac mac-keysz=20 mac-tagsz=10
-cipher-data-limit=67108864
+hash=sha256 mgf=sha256-mgf hash-sz=32
+bulk-transform=naclbox bulk-overhead=20
+cipher=salsa20 cipher-keysz=32
+mac=poly1305 mac-tagsz=16
+cipher-data-limit=2147483648
 ])
 
   AT_DATA([algs-beta-old], [dnl
 ])
 
   AT_DATA([algs-beta-old], [dnl
index bdac42185e3f6077a1a77a7671ed4b8d4f6c0c94..c19ee57a100e769f61ec3914cf18dfba72e077b9 100644 (file)
@@ -412,6 +412,34 @@ more significantly, the transform is entirely deterministic, so (a) it
 doesn't need the (possibly slow) random number generator, and (b) it
 closes a kleptographic channel, over which a compromised implementation
 could leak secret information to a third party.
 doesn't need the (possibly slow) random number generator, and (b) it
 closes a kleptographic channel, over which a compromised implementation
 could leak secret information to a third party.
+.TP
+.B naclbox
+A transform based on the NaCl
+.B crypto_secretbox
+transformation.
+The main difference is that NaCl uses XSalsa20,
+while TrIPE uses plain Salsa20 or ChaCha,
+because it doesn't need the larger nonce space.
+You can set the
+.B cipher
+key attribute to one of
+.BR salsa20 ,
+.BR salsa20/12 ,
+.BR salsa20/8 ,
+.BR chacha20 ,
+.BR chacha12 ,
+or
+.B chacha8
+to select the main cipher.
+You can set the
+.B mac
+key attribute to
+.B poly1305
+or
+.B poly1305/128
+but these are the default and no other choice is permitted.
+(This is for forward compatibility,
+in case other MACs and/or tag sizes are allowed later.)
 .SS "Other key attributes"
 The following attributes can also be set on keys.
 .TP
 .SS "Other key attributes"
 The following attributes can also be set on keys.
 .TP
index d8b35de70e2ff36a11336e8783882d7112a513d0..ad2c0bd73068a1a40af673f651dbc980375a36a8 100644 (file)
 #include <catacomb/buf.h>
 #include <catacomb/ct.h>
 
 #include <catacomb/buf.h>
 #include <catacomb/ct.h>
 
+#include <catacomb/chacha.h>
 #include <catacomb/gcipher.h>
 #include <catacomb/gmac.h>
 #include <catacomb/grand.h>
 #include <catacomb/key.h>
 #include <catacomb/paranoia.h>
 #include <catacomb/gcipher.h>
 #include <catacomb/gmac.h>
 #include <catacomb/grand.h>
 #include <catacomb/key.h>
 #include <catacomb/paranoia.h>
+#include <catacomb/poly1305.h>
+#include <catacomb/salsa20.h>
 
 #include <catacomb/noise.h>
 #include <catacomb/rand.h>
 
 #include <catacomb/noise.h>
 #include <catacomb/rand.h>
index fe5f97520db686ae0401002ac6f1e084ffb787a8..ef20b68f4349f648b386de2c18b81edae7bf2b16 100644 (file)
@@ -1,5 +1,5 @@
-65604204:tripe-ec:bob struct:[p=ec,public:0x6df064afcdc923160114d2919f014bcef1051bf5cb3071194088a10be4f0c992,0xea0f0b538cb3ad46d07d9b83eff95458b691bdfbf09188ccd7b0758bebd8f107,private=struct:[x=integer,private,burn:26559628286452801356420934030260728558957937100654818426187327519091722521190],curve=string,shared:nist%2dp256] forever forever -
-b10d3366:tripe-ec-param struct:[curve=string,shared:nist%2dp256] forever forever -
-1aac2ad7:tripe-ec:bob-new struct:[p=ec,public:0xebf0cb581592dc6244a47e9d2e6bc79f76ecb9e5f6e34d69f9f0d07eab188351,0xa6ec5ff761242a0eef1565fd7a6604dbab7b4a0552226b60f2359bccd3e80f48,private=struct:[x=integer,private,burn:15276384741843750980963471236080551062792600396841148726840678168354415102951],curve=string,shared:nist%2dp256] forever forever -
-ec1faca7:tripe-ec:alice struct:[p=ec,public:0xa886b00e1457196c1fd91f11a94cf4a081169602c5e2b576d4182eca470ec253,0xb0fa9a01d4205c912d97c4b4c8d8c5e0af869bd7cdef2139aff7579ca590b4c2,private=struct:[x=integer,private,burn:27337377592101678962721737273774069706724348359128065055711824790983665511674],curve=string,shared:nist%2dp256] forever forever -
-73bad30f:tripe-ec:carol struct:[p=ec,public:0xac7b854c5e38a74a005a8940cfe7e9cac692bfb12316de782167632b38ced9fc,0xc4467936d15ba07f4ca5e6a7bbf2afb526dec70de0f0ad78f74010e0998a66cd,private=struct:[x=integer,private,burn:62821717637637708743367607162182045550925703241285672642684065475493697147942],curve=string,shared:nist%2dp256] forever forever -
+65604204:tripe-ec:bob struct:[p=ec,public:0x6df064afcdc923160114d2919f014bcef1051bf5cb3071194088a10be4f0c992,0xea0f0b538cb3ad46d07d9b83eff95458b691bdfbf09188ccd7b0758bebd8f107,private=struct:[x=integer,private,burn:26559628286452801356420934030260728558957937100654818426187327519091722521190],curve=string,shared:nist%2dp256] forever forever bulk=naclbox&hash=sha256
+b10d3366:tripe-ec-param struct:[curve=string,shared:nist%2dp256] forever forever bulk=naclbox&hash=sha256
+1aac2ad7:tripe-ec:bob-new struct:[p=ec,public:0xebf0cb581592dc6244a47e9d2e6bc79f76ecb9e5f6e34d69f9f0d07eab188351,0xa6ec5ff761242a0eef1565fd7a6604dbab7b4a0552226b60f2359bccd3e80f48,private=struct:[x=integer,private,burn:15276384741843750980963471236080551062792600396841148726840678168354415102951],curve=string,shared:nist%2dp256] forever forever bulk=naclbox&hash=sha256
+ec1faca7:tripe-ec:alice struct:[p=ec,public:0xa886b00e1457196c1fd91f11a94cf4a081169602c5e2b576d4182eca470ec253,0xb0fa9a01d4205c912d97c4b4c8d8c5e0af869bd7cdef2139aff7579ca590b4c2,private=struct:[x=integer,private,burn:27337377592101678962721737273774069706724348359128065055711824790983665511674],curve=string,shared:nist%2dp256] forever forever bulk=naclbox&hash=sha256
+73bad30f:tripe-ec:carol struct:[p=ec,public:0xac7b854c5e38a74a005a8940cfe7e9cac692bfb12316de782167632b38ced9fc,0xc4467936d15ba07f4ca5e6a7bbf2afb526dec70de0f0ad78f74010e0998a66cd,private=struct:[x=integer,private,burn:62821717637637708743367607162182045550925703241285672642684065475493697147942],curve=string,shared:nist%2dp256] forever forever bulk=naclbox&hash=sha256