From 073c943bf74cce7bd6ce90ee97dfc9b753af3cf2 Mon Sep 17 00:00:00 2001 From: Wangchong Zhou Date: Tue, 19 Dec 2023 18:03:02 +0800 Subject: [PATCH] feat(bn) add from_mpi, to_mpi and set API --- README.md | 57 +++++- lib/resty/openssl/bn.lua | 167 ++++++++++----- lib/resty/openssl/include/bn.lua | 13 +- t/openssl/bn.t | 339 +++++++++++++------------------ 4 files changed, 308 insertions(+), 268 deletions(-) diff --git a/README.md b/README.md index c0dc5429..59073ca5 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,9 @@ Table of Contents + [bn.new](#bnnew) + [bn.dup](#bndup) + [bn.istype](#bnistype) + + [bn:set](#bnset) + [bn.from_binary, bn:to_binary](#bnfrom_binary-bnto_binary) + + [bn.from_mpi, bn:to_mpi](#bnfrom_mpi-bnto_mpi) + [bn.from_hex, bn:to_hex](#bnfrom_hex-bnto_hex) + [bn.from_dec, bn:to_dec](#bnfrom_dec-bnto_dec) + [bn:to_number](#bnto_number) @@ -1380,8 +1382,20 @@ Module to expose BIGNUM structure. Note bignum is a big integer, no float operat **syntax**: *b, err = bn.new(number?)* -Creates a `bn` instance. The first argument can be a Lua number or `nil` to -creates an empty instance. +**syntax**: *b, err = bn.new(string?, base?)* + +Creates a `bn` instance. The first argument can be: + +- `nil` to creates an empty bn instance. +- A Lua number to initialize the bn instance. +- A string to initialize the bn instance. The second argument `base` specifies the base of the string, +and can take value from (compatible with Ruby OpenSSL.BN API): + - `10` or omitted, for decimal string (`"23333"`) + - `16`, for hex encoded string (`"5b25"`) + - `2`, for binary string (`"\x5b\x25"`) + - `0`, for MPI formated string (`"\x00\x00\x00\x02\x5b\x25"`) + +MPI is a format that consists of the number's length in bytes represented as a 4-byte big-endian number, and the number itself in big-endian format, where the most significant bit signals a negative number (the representation of numbers with the MSB set is prefixed with null byte). [Back to TOC](#table-of-contents) @@ -1401,6 +1415,17 @@ Returns `true` if table is an instance of `bn`. Returns `false` otherwise. [Back to TOC](#table-of-contents) +### bn.set + +**syntax**: *b, err = bn:set(number)* + +**syntax**: *b, err = bn:set(string, base?)* + +Reuse the existing bn instance and reset its value with given number or string. +Refer to [bn.new](#bnnew) for the type of arguments supported. + +[Back to TOC](#table-of-contents) + ### bn.from_binary, bn:to_binary **syntax**: *bn, err = bn.from_binary(bin)* @@ -1415,10 +1440,32 @@ Exports the BIGNUM value in binary string. used to pad leading zeros to the output to a specific length. ```lua -local b, err = require("resty.openssl.bn").from_binary(ngx.decode_base64("WyU=")) +local to_hex = require "resty.string".to_hex +local b, err = require("resty.openssl.bn").from_binary("\x5b\x25") local bin, err = b:to_binary() -ngx.say(ngx.encode_base64(bin)) --- outputs "WyU=" +ngx.say(to_hex(bin)) +-- outputs "5b25 +``` + +[Back to TOC](#table-of-contents) + +### bn.from_mpi, bn:to_mpi + +**syntax**: *bn, err = bn.from_mpi(bin)* + +**syntax**: *bin, err = bn:to_mpi()* + +Creates a `bn` instance from MPI formatted binary string. + +Exports the BIGNUM value in MPI formatted binary string. + + +```lua +local to_hex = require "resty.string".to_hex +local b, err = require("resty.openssl.bn").from_mpi("\x00\x00\x00\x02\x5b\x25") +local bin, err = b:to_mpi() +ngx.say(to_hex(bin)) +-- outputs "000000025b25 ``` [Back to TOC](#table-of-contents) diff --git a/lib/resty/openssl/bn.lua b/lib/resty/openssl/bn.lua index 3c4fce44..4c66f1ae 100644 --- a/lib/resty/openssl/bn.lua +++ b/lib/resty/openssl/bn.lua @@ -9,7 +9,6 @@ require "resty.openssl.include.bn" local crypto_macro = require("resty.openssl.include.crypto") local ctypes = require "resty.openssl.auxiliary.ctypes" local format_error = require("resty.openssl.err").format_error -local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X local _M = {} local mt = {__index = _M} @@ -17,16 +16,73 @@ local mt = {__index = _M} local bn_ptr_ct = ffi.typeof('BIGNUM*') local bn_ptrptr_ct = ffi.typeof('BIGNUM*[1]') -function _M.new(bn) +local function set_binary(ctx, s) + local ctx = C.BN_bin2bn(s, #s, ctx) + if ctx == nil then + return nil, format_error("set_binary") + end + return ctx +end + +local function set_mpi(ctx, s) + local ctx = C.BN_mpi2bn(s, #s, ctx) + if ctx == nil then + return nil, format_error("set_mpi") + end + return ctx +end + +local function set_hex(ctx, s) + local p = ffi_new(bn_ptrptr_ct) + p[0] = ctx + + if C.BN_hex2bn(p, s) == 0 then + return nil, format_error("set_hex") + end + return p[0] +end + +local function set_dec(ctx, s) + local p = ffi_new(bn_ptrptr_ct) + p[0] = ctx + + if C.BN_dec2bn(p, s) == 0 then + return nil, format_error("set_dec") + end + return p[0] +end + +local function set_bn(ctx, s, base) + if type(s) == 'number' then + if C.BN_set_word(ctx, s) ~= 1 then + return nil, format_error("set_bn") + end + elseif type(s) == 'string' then + if not base or base == 10 then + return set_dec(ctx, s) + elseif base == 16 then + return set_hex(ctx, s) + elseif base == 2 then + return set_binary(ctx, s) + elseif base == 0 then + ctx = set_mpi(ctx, s) + else + return nil, "set_bn: unsupported base: " .. base + end + elseif s then + return nil, "set_bn: expect nil, a number or a string at #1" + end + + return ctx +end + +function _M.new(some, base) local ctx = C.BN_new() ffi_gc(ctx, C.BN_free) - if type(bn) == 'number' then - if C.BN_set_word(ctx, bn) ~= 1 then - return nil, format_error("bn.new") - end - elseif bn then - return nil, "bn.new: expect nil or a number at #1" + local ctx, err = set_bn(ctx, some, base) + if err then + return nil, "bn.new: " .. err end return setmetatable( { ctx = ctx }, mt), nil @@ -50,6 +106,19 @@ function _M.dup(ctx) return self end +function _M:set(some, base) + if not some then + return nil, "expect a number or a string at #1" + end + + local _, err = set_bn(self.ctx, some, base) + if err then + return nil, "bn:set: " .. err + end + + return self +end + function _M:to_binary(pad) if pad then if type(pad) ~= "number" then @@ -80,17 +149,22 @@ function _M:to_binary(pad) return ffi_str(buf, sz) end -function _M.from_binary(s) - if type(s) ~= "string" then - return nil, "bn.from_binary: expect a string at #1" +function _M:to_mpi(no_header) + local length = C.BN_bn2mpi(self.ctx, nil) + if length <= 0 then + return nil, format_error("bn:to_mpi") end - local ctx = C.BN_bin2bn(s, #s, nil) - if ctx == nil then - return nil, format_error("bn.from_binary") + local buf = ctypes.uchar_array(length) + + local sz = C.BN_bn2mpi(self.ctx, buf) + if sz <= 0 then + return nil, format_error("bn:to_mpi") end - ffi_gc(ctx, C.BN_free) - return setmetatable( { ctx = ctx }, mt), nil + + local ret = ffi_str(buf, sz) + + return no_header and ret:sub(4) or ret end function _M:to_hex() @@ -103,21 +177,6 @@ function _M:to_hex() return s end -function _M.from_hex(s) - if type(s) ~= "string" then - return nil, "bn.from_hex: expect a string at #1" - end - - local p = ffi_new(bn_ptrptr_ct) - - if C.BN_hex2bn(p, s) == 0 then - return nil, format_error("bn.from_hex") - end - local ctx = p[0] - ffi_gc(ctx, C.BN_free) - return setmetatable( { ctx = ctx }, mt), nil -end - function _M:to_dec() local buf = C.BN_bn2dec(self.ctx) if buf == nil then @@ -129,26 +188,35 @@ function _M:to_dec() end mt.__tostring = _M.to_dec -function _M.from_dec(s) - if type(s) ~= "string" then - return nil, "bn.from_dec: expect a string at #1" - end - - local p = ffi_new(bn_ptrptr_ct) - - if C.BN_dec2bn(p, s) == 0 then - return nil, format_error("bn.from_dec") - end - local ctx = p[0] - ffi_gc(ctx, C.BN_free) - return setmetatable( { ctx = ctx }, mt), nil -end - function _M:to_number() return tonumber(C.BN_get_word(self.ctx)) end _M.tonumber = _M.to_number +local from_funcs = { + binary = set_binary, + mpi = set_mpi, + hex = set_hex, + dec = set_dec, +} + +for typ, func in pairs(from_funcs) do + local sig = "from_" .. typ + _M[sig] = function(s) + if type(s) ~= "string" then + return nil, "bn." .. sig .. ": expect a string at #1" + end + + local ctx, err = func(nil, s) + if not ctx then + return nil, "bn." .. sig .. ": " .. err + end + + ffi_gc(ctx, C.BN_free) + return setmetatable( { ctx = ctx }, mt), nil + end +end + function _M.generate_prime(bits, safe) local ctx = C.BN_new() ffi_gc(ctx, C.BN_free) @@ -373,12 +441,7 @@ function _M:is_prime(nchecks) end -- if nchecks is not defined, set to BN_prime_checks: -- select number of iterations based on the size of the number - local code - if OPENSSL_3X then - code = C.BN_check_prime(self.ctx, bn_ctx_tmp, nil) - else - code = C.BN_is_prime_ex(self.ctx, nchecks or 0, bn_ctx_tmp, nil) - end + local code = C.BN_is_prime_ex(self.ctx, nchecks or 0, bn_ctx_tmp, nil) if code == -1 then return nil, format_error("bn.is_prime") end diff --git a/lib/resty/openssl/include/bn.lua b/lib/resty/openssl/include/bn.lua index ac6dee76..7c83aad6 100644 --- a/lib/resty/openssl/include/bn.lua +++ b/lib/resty/openssl/include/bn.lua @@ -1,7 +1,6 @@ local ffi = require "ffi" require "resty.openssl.include.ossl_typ" -local OPENSSL_3X = require("resty.openssl.version").OPENSSL_3X local BN_ULONG if ffi.abi('64bit') then @@ -33,6 +32,9 @@ ffi.cdef( char *BN_bn2hex(const BIGNUM *a); char *BN_bn2dec(const BIGNUM *a); + int BN_bn2mpi(const BIGNUM *a, unsigned char *to); + BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); + void BN_set_negative(BIGNUM *a, int n); int BN_is_negative(const BIGNUM *a); @@ -60,7 +62,6 @@ ffi.cdef( int BN_cmp(BIGNUM *a, BIGNUM *b); int BN_ucmp(BIGNUM *a, BIGNUM *b); - // openssl >= 1.1 only int BN_is_zero(BIGNUM *a); int BN_is_one(BIGNUM *a); int BN_is_word(BIGNUM *a, ]] .. BN_ULONG ..[[ w); @@ -70,10 +71,4 @@ ffi.cdef( int BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb); ]] -) - -if OPENSSL_3X then - ffi.cdef [[ - int BN_check_prime(const BIGNUM *p, BN_CTX *ctx, BN_GENCB *cb); - ]] -end \ No newline at end of file +) \ No newline at end of file diff --git a/t/openssl/bn.t b/t/openssl/bn.t index 5259ba22..02c01e78 100644 --- a/t/openssl/bn.t +++ b/t/openssl/bn.t @@ -9,12 +9,13 @@ my $pwd = cwd(); my $use_luacov = $ENV{'TEST_NGINX_USE_LUACOV'} // ''; our $HttpConfig = qq{ - lua_package_path "$pwd/lib/?.lua;$pwd/lib/?/init.lua;;"; + lua_package_path "$pwd/t/openssl/?.lua;$pwd/lib/?.lua;$pwd/lib/?/init.lua;$pwd/../lua-resty-string/lib/?.lua;;"; init_by_lua_block { if "1" == "$use_luacov" then require 'luacov.tick' jit.off() end + _G.myassert = require("helper").myassert } }; @@ -26,16 +27,8 @@ __DATA__ --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").new() - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_binary() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").new()) + local b = myassert(bn:to_binary()) ngx.print(ngx.encode_base64(b)) } } @@ -51,16 +44,8 @@ bn:to_binary failed --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").new(0x5b25) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_binary() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").new(0x5b25)) + local b = myassert(bn:to_binary()) ngx.print(ngx.encode_base64(b)) } } @@ -71,29 +56,46 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 3: Duplicate the ctx +=== TEST 3: New BIGNUM instance from string +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local data = { + ["23333"] = 10, + ["5b25"] = 16, + ["5B25"] = 16, + ["\x5b\x25"] = 2, + ["\x00\x00\x00\x02\x5b\x25"] = 0, + } + for k, v in pairs(data) do + local bn = myassert(require("resty.openssl.bn").new(k, v)) + if bn:to_number() ~= 23333 then + ngx.log(ngx.ERR, bn, " != 23333: ", k, " ", v) + return + end + end + ngx.print("ok") + } + } +--- request + GET /t +--- response_body eval +"ok" +--- no_error_log +[error] + +=== TEST 4: Duplicate the ctx --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { require('ffi').cdef('typedef struct bignum_st BIGNUM; void BN_free(BIGNUM *a);') - local bn, err = require("resty.openssl.bn").new(0x5b25) - if err then - ngx.log(ngx.ERR, err) - return - end - local bn2, err = require("resty.openssl.bn").dup(bn.ctx) - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").new(0x5b25)) + local bn2 = myassert(require("resty.openssl.bn").dup(bn.ctx)) bn = nil collectgarbage("collect") - local b, err = bn2:to_binary() - if err then - ngx.log(ngx.ERR, err) - return - end + local b = myassert(bn2:to_binary()) ngx.print(ngx.encode_base64(b)) } } @@ -104,29 +106,17 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 4: from_binary, to_binary +=== TEST 5: from_binary, to_binary --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local d = ngx.decode_base64('WyU=') - local bn, err = require("resty.openssl.bn").from_binary(d) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_binary() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").from_binary(d)) + local b = myassert(bn:to_binary()) ngx.print(ngx.encode_base64(b)) - local b, err = bn:to_binary(10) - if err then - ngx.log(ngx.ERR, err) - return - end + local b = myassert(bn:to_binary(10)) ngx.print(ngx.encode_base64(b)) } } @@ -137,21 +127,13 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 5: from_hex, to_hex +=== TEST 6: from_hex, to_hex --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").from_hex("5B25") - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_hex() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").from_hex("5B25")) + local b = myassert(bn:to_hex()) ngx.print(b) } } @@ -162,21 +144,13 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 6: from_dec, to_dec +=== TEST 7: from_dec, to_dec --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").from_dec("23333") - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn:to_dec() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").from_dec("23333")) + local b = myassert(bn:to_dec()) ngx.print(b) } } @@ -187,34 +161,37 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 7: to_number +=== TEST 8: from_mpi, to_mpi +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local to_hex = require "resty.string".to_hex + local bn = myassert(require("resty.openssl.bn").from_mpi("\x00\x00\x00\x02\x5b\x25")) + local b = myassert(bn:to_mpi()) + ngx.print(to_hex(b)) + } + } +--- request + GET /t +--- response_body eval +"000000025b25" +--- no_error_log +[error] + + +=== TEST 9: to_number --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local b, err = bn.new(23333) - if err then - ngx.log(ngx.ERR, err) - return - end - local n, err = b:to_number() - if err then - ngx.log(ngx.ERR, err) - return - end + local b = myassert(bn.new(23333)) + local n = myassert(b:to_number()) ngx.say(tostring(n),type(n)) - b, err = bn.from_dec('184467440737095516161844674407370955161618446744073709551616') - if err then - ngx.log(ngx.ERR, err) - return - end - local n, err = b:to_number() - if err then - ngx.log(ngx.ERR, err) - return - end + b = myassert(bn.from_dec('184467440737095516161844674407370955161618446744073709551616')) + local n = myassert(b:to_number()) ngx.say(tostring(n),type(n)) } @@ -228,27 +205,15 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 8: unary minus +=== TEST 10: unary minus --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local bn, err = require("resty.openssl.bn").new(23333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = (-bn):to_dec() - if err then - ngx.log(ngx.ERR, err) - return - end + local bn = myassert(require("resty.openssl.bn").new(23333)) + local b = myassert((-bn):to_dec()) ngx.say(b) - local b, err = (-(-bn)):to_dec() - if err then - ngx.log(ngx.ERR, err) - return - end + local b = myassert((-(-bn)):to_dec()) ngx.say(b) } } @@ -261,21 +226,13 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 9: metamethods checks arg +=== TEST 11: metamethods checks arg --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { - local a, err = require("resty.openssl.bn").new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = require("resty.openssl.bn").new(2478652) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(require("resty.openssl.bn").new(23578164761333)) + local b = myassert(require("resty.openssl.bn").new(2478652)) local pok, perr = pcall(function() return a + "233" end) ngx.say(perr) local pok, perr = pcall(function() return "233" - a end) @@ -291,22 +248,14 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 10: add, sub, mul, div mod +=== TEST 12: add, sub, mul, div mod --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(2478652) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(2478652)) ngx.say(tostring(a+b)) ngx.say(tostring(a-b)) ngx.say(tostring(a*b)) @@ -336,22 +285,14 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 11: sqr, exp +=== TEST 13: sqr, exp --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(97) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(97)) ngx.say(tostring(a:sqr())) ngx.say(tostring(a:exp(2))) ngx.say(tostring(a:pow(2))) @@ -377,22 +318,14 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 12: gcd +=== TEST 14: gcd --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(97) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(97)) ngx.say(tostring(a:gcd(b))) ngx.say(tostring(bn.gcd(a, b))) ngx.say(tostring(bn.gcd(a, 97))) @@ -410,17 +343,13 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 13: lshift, rshift +=== TEST 15: lshift, rshift --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) ngx.say(tostring(a:lshift(2))) ngx.say(tostring(a:rshift(2))) } @@ -434,22 +363,14 @@ bn:to_binary failed --- no_error_log [error] -=== TEST 14: comparasion +=== TEST 16: comparasion --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(97) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(97)) ngx.say(tostring(a == b)) ngx.say(tostring(a ~= b)) ngx.say(tostring(a >= b)) @@ -485,7 +406,7 @@ true --- no_error_log [error] -=== TEST 15: is_one, is_zero, is_odd, is_word +=== TEST 17: is_one, is_zero, is_odd, is_word --- http_config eval: $::HttpConfig --- config location =/t { @@ -516,7 +437,7 @@ false --- no_error_log [error] -=== TEST 16: is_prime +=== TEST 18: is_prime --- http_config eval: $::HttpConfig --- config location =/t { @@ -539,27 +460,15 @@ true --- no_error_log [error] -=== TEST 17: mod_add, mod_sub, mod_mul, mul_exp, mul_sqr mod +=== TEST 19: mod_add, mod_sub, mod_mul, mul_exp, mul_sqr mod --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.new(23578164761333) - if err then - ngx.log(ngx.ERR, err) - return - end - local b, err = bn.new(2478652) - if err then - ngx.log(ngx.ERR, err) - return - end - local m, err = bn.new(65537) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.new(23578164761333)) + local b = myassert(bn.new(2478652)) + local m = myassert(bn.new(65537)) ngx.say(tostring(a:mod_add(b, m))) ngx.say(tostring(a:mod_sub(b, m))) ngx.say(tostring(a:mod_mul(b, m))) @@ -583,26 +492,18 @@ true --- no_error_log [error] -=== TEST 18: generate_prime +=== TEST 20: generate_prime --- http_config eval: $::HttpConfig --- config location =/t { content_by_lua_block { local bn = require("resty.openssl.bn") - local a, err = bn.generate_prime(10, false) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.generate_prime(10, false)) if not a:is_prime() then ngx.log(ngx.ERR, "not prime") return end - local a, err = bn.generate_prime(10, true) - if err then - ngx.log(ngx.ERR, err) - return - end + local a = myassert(bn.generate_prime(10, true)) if not a:is_prime() then ngx.log(ngx.ERR, "not prime") return @@ -616,4 +517,38 @@ true "ok " --- no_error_log +[error] + +=== TEST 21: set +--- http_config eval: $::HttpConfig +--- config + location =/t { + content_by_lua_block { + local data = { + ["23333"] = 10, + ["5b25"] = 16, + ["5B25"] = 16, + ["\x5b\x25"] = 2, + ["\x00\x00\x00\x02\x5b\x25"] = 0, + } + for k, v in pairs(data) do + local bn = myassert(require("resty.openssl.bn").new(0)) + local new_bn = myassert(bn:set(k, v)) + if bn:to_number() ~= 23333 then + ngx.log(ngx.ERR, bn, " != 23333: ", k, " ", v) + return + end + if tostring(bn.ctx) ~= tostring(new_bn.ctx) then + ngx.log(ngx.ERR, tostring(bn.ctx), " != ", tostring(new_bn.ctx), " (ctx not properly reused)") + return + end + end + ngx.print("ok") + } + } +--- request + GET /t +--- response_body eval +"ok" +--- no_error_log [error] \ No newline at end of file