+MODULE = Catacomb PACKAGE = Catacomb::Share::GF PREFIX = gfshare_
+
+Share_GF *
+new(me, t, sz)
+ SV *me
+ UV t
+ UV sz
+ CODE:
+ RETVAL = CREATE(Share_GF);
+ if (t < 1 || t > 255)
+ croak("share threshhold out of range");
+ gfshare_create(RETVAL, t, sz);
+ OUTPUT:
+ RETVAL
+
+UV
+sz(s)
+ Share_GF *s
+ CODE:
+ RETVAL = s->sz;
+ OUTPUT:
+ RETVAL
+
+UV
+t(s)
+ Share_GF *s
+ CODE:
+ RETVAL = s->t;
+ OUTPUT:
+ RETVAL
+
+UV
+i(s)
+ Share_GF *s
+ CODE:
+ RETVAL = s->i;
+ OUTPUT:
+ RETVAL
+
+SV *
+DESTROY(s)
+ Share_GF *s
+ CODE:
+ gfshare_destroy(s);
+ DESTROY(s);
+ XSRETURN_YES;
+
+SV *
+mkshares(s, x, r = &rand_global)
+ Share_GF *s
+ SV *x
+ grand *r
+ PREINIT:
+ char *p;
+ STRLEN len;
+ CODE:
+ p = SvPV(x, len);
+ if (len != s->sz)
+ croak("secret length mismatch");
+ gfshare_mkshares(s, r, p);
+ s->i = ~0u;
+ XSRETURN_YES;
+
+SV *
+get(s, i)
+ Share_GF *s
+ UV i
+ CODE:
+ if (i >= 255)
+ croak("share index out of range");
+ if (s->i != ~0u)
+ croak("not making shares");
+ RETVAL = NEWSV(0, s->sz);
+ SvPOK_on(RETVAL);
+ gfshare_get(s, i, SvPVX(RETVAL));
+ SvCUR_set(RETVAL, s->sz);
+ OUTPUT:
+ RETVAL
+
+unsigned
+add(s, i, x)
+ Share_GF *s
+ UV i
+ SV *x
+ PREINIT:
+ char *p;
+ STRLEN len;
+ CODE:
+ p = SvPV(x, len);
+ if (len != s->sz)
+ croak("secret length mismatch");
+ if (i == ~0u)
+ croak("making shares");
+ if (i >= 255)
+ croak("share index out of range");
+ if (s->i >= s->t)
+ croak("too many shares");
+ RETVAL = gfshare_add(s, i, p);
+ OUTPUT:
+ RETVAL
+
+SV *
+combine(s)
+ Share_GF *s
+ CODE:
+ if (s->i == ~0u)
+ croak("making shares");
+ if (s->i != s->t)
+ croak("not enough shares yet");
+ RETVAL = NEWSV(0, s->sz);
+ SvPOK_on(RETVAL);
+ gfshare_combine(s, SvPVX(RETVAL));
+ SvCUR_set(RETVAL, s->sz);
+ OUTPUT:
+ RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::Share::Prime PREFIX = share_
+
+Share_Prime *
+new(me, t, p = &PL_sv_undef)
+ SV *me
+ UV t
+ SV *p
+ CODE:
+ RETVAL = CREATE(Share_Prime);
+ if (t < 1 || t > MPW_MAX)
+ croak("share threshhold out of range");
+ share_create(RETVAL, t);
+ if (SvOK(p))
+ RETVAL->p = mp_fromsv(p, "p", 0, 1);
+ OUTPUT:
+ RETVAL
+
+mp *
+p(s)
+ Share_Prime *s
+ CODE:
+ if (!s->p)
+ XSRETURN_UNDEF;
+ RETVAL = MP_COPY(s->p);
+ OUTPUT:
+ RETVAL
+
+UV
+t(s)
+ Share_Prime *s
+ CODE:
+ RETVAL = s->t;
+ OUTPUT:
+ RETVAL
+
+UV
+i(s)
+ Share_Prime *s
+ CODE:
+ RETVAL = s->i;
+ OUTPUT:
+ RETVAL
+
+SV *
+DESTROY(s)
+ Share_Prime *s
+ CODE:
+ share_destroy(s);
+ DESTROY(s);
+ XSRETURN_YES;
+
+SV *
+mkshares(s, x, r = &rand_global)
+ Share_Prime *s
+ mp *x
+ grand *r
+ CODE:
+ if (s->p && MP_CMP(s->p, <=, x))
+ croak("secret out of range");
+ share_mkshares(s, r, x);
+ s->i = ~0u;
+ XSRETURN_YES;
+
+mp *
+share_get(s, i)
+ Share_Prime *s
+ UV i
+ INIT:
+ if (i >= MPW_MAX)
+ croak("share index out of range");
+ if (s->i != ~0u)
+ croak("not making shares");
+ C_ARGS:
+ s, MP_NEW, i
+
+unsigned
+share_add(s, i, x)
+ Share_Prime *s
+ UV i
+ mp *x
+ INIT:
+ if (!s->p)
+ croak("no prime set");
+ if (i == ~0u)
+ croak("making shares");
+ if (i >= MPW_MAX)
+ croak("share index out of range");
+ if (s->i >= s->t)
+ croak("too many shares");
+ C_ARGS:
+ s, i, x
+
+mp *
+share_combine(s)
+ Share_Prime *s
+ INIT:
+ if (s->i == ~0u)
+ croak("making shares");
+ if (s->i != s->t)
+ croak("not enough shares yet");
+