diff --git a/lib/resty/nettle/mpz.lua b/lib/resty/nettle/mpz.lua index 4fab628..8664c2d 100644 --- a/lib/resty/nettle/mpz.lua +++ b/lib/resty/nettle/mpz.lua @@ -16,6 +16,9 @@ size_t __gmpz_sizeinbase(const mpz_t op, int base); char * __gmpz_get_str(char *str, int base, const mpz_t op); int __gmpz_set_str(mpz_t rop, const char *str, int base); void __gmpz_set_ui(mpz_t, unsigned long int iv); +int __gmpz_invert(mpz_ptr, mpz_srcptr, mpz_srcptr); +void __gmpz_sub_ui(mpz_ptr, mpz_srcptr, unsigned long int); +void __gmpz_fdiv_r(mpz_ptr, mpz_srcptr, mpz_srcptr); ]] local ctx = ffi_typeof "mpz_t" @@ -60,4 +63,16 @@ function mpz.set(op, value, base) return true end +function mpz.invert(rop, op1, op2) + return gmp.__gmpz_invert(rop, op1, op2) +end + +function mpz.sub(rop, op1, op2) + gmp.__gmpz_sub_ui(rop, op1, op2) +end + +function mpz.div(rop, op1, op2) + gmp.__gmpz_fdiv_r(rop, op1, op2) +end + return mpz diff --git a/lib/resty/nettle/rsa.lua b/lib/resty/nettle/rsa.lua index 1f5f636..25203b5 100644 --- a/lib/resty/nettle/rsa.lua +++ b/lib/resty/nettle/rsa.lua @@ -106,35 +106,55 @@ function private.new(d, p, q, a, b, c, base) return nil, err end end + local p1 if p then local ok, err = mpz.set(context[0].p, p, base) if not ok then return nil, err end + if d and not a then + p1 = mpz.new() + mpz.sub(p1, context[0].p, 1) + end end + local q1 if q then local ok, err = mpz.set(context[0].q, q, base) if not ok then return nil, err end + if d and not b then + q1 = mpz.new() + mpz.sub(q1, context[0].q, 1) + end end if a then local ok, err = mpz.set(context[0].a, a, base) if not ok then return nil, err end + elseif p1 then + mpz.div(context[0].a, context[0].d, p1) end if b then local ok, err = mpz.set(context[0].b, b, base) if not ok then return nil, err end + elseif q1 then + mpz.div(context[0].b, context[0].d, q1) end + if c then local ok, err = mpz.set(context[0].c, c, base) if not ok then return nil, err end + elseif q and p then + local ret = mpz.invert(context[0].c, context[0].q, context[0].p) + if ret == 0 then + ret = mpz.invert(context[0].c, context[0].q, context[0].p) + end end if d or p or q or a or b or c then if hogweed.nettle_rsa_private_key_prepare(context) ~= 1 then diff --git a/lib/resty/nettle/types/mpz.lua b/lib/resty/nettle/types/mpz.lua index 64f6c20..b2e50e5 100644 --- a/lib/resty/nettle/types/mpz.lua +++ b/lib/resty/nettle/types/mpz.lua @@ -8,6 +8,7 @@ typedef struct { int _mp_size; mp_limb_t *_mp_d; } __mpz_struct; +typedef const __mpz_struct *mpz_srcptr; typedef __mpz_struct mpz_t[1]; typedef __mpz_struct *mpz_ptr; ]]