From 27e694ed5b51daa8cfe6ca9695b9c98f3f6710bc Mon Sep 17 00:00:00 2001 From: rnd Date: Sat, 19 May 2018 11:54:56 +0200 Subject: [PATCH] crypto bugfixes dsa added (experimental) --- scripts/misc/crypto/bignum.lua | 106 +++++++++++------- scripts/misc/crypto/dsa.lua | 132 +++++++++++++++++++++++ scripts/misc/crypto/import_ssh_prime.lua | 47 ++++++++ 3 files changed, 244 insertions(+), 41 deletions(-) create mode 100644 scripts/misc/crypto/dsa.lua create mode 100644 scripts/misc/crypto/import_ssh_prime.lua diff --git a/scripts/misc/crypto/bignum.lua b/scripts/misc/crypto/bignum.lua index 098ef07..552fd49 100644 --- a/scripts/misc/crypto/bignum.lua +++ b/scripts/misc/crypto/bignum.lua @@ -99,6 +99,70 @@ local exporthex_test = function() end --exporthex_test() +local base64c = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z", +"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z", +"1","2","3","4","5","6","7","8","9","0","+","/"} +local base64n = {}; for i=1,#base64c do base64n[base64c[i]]=i-1 end + +bignum.exportbase64 = function(n) + local binary = bignum.base2binary(n); + local base64 = bignum.binary2base(binary,64); + local data = base64.digits; local ret = {}; + for i = #data,1,-1 do ret[#data-i+1] = base64c[data[i]+1] end + return table.concat(ret,"") +end + +bignum.importbase64 = function(base64,newbase) + local digits = {}; local length = string.len(base64); + for i = length,1,-1 do digits[length-i+1] = base64n[string.sub(base64,i,i)] end + local base64 = bignum.new(64,1,digits); + local binary = bignum.base2binary(base64); + return bignum.binary2base(binary,newbase); +end + +local base64_test = function() + local n = bignum.rnd(10,1,177); + say("B = " .. bignum.tostring(n)) + local b64 = bignum.exportbase64(n); + say("B64 = " .. b64) + local m = bignum.importbase64(b64,10) + say("B = " .. bignum.tostring(m)) +end +--base64_test() + +bignum.exportascii = function(n) -- 32 - 127 (96) -- problem with non even base + local binary = bignum.base2binary(n); + local ascii = bignum.binary2base(binary,96); + local out = ascii.digits; + local m = 32;local ret = {}; + for i = 1, #out do + ret[#ret+1] = string.char(m+out[i]) + end + return table.concat(ret,"") +end + +bignum.importascii = function(text,newbase) + local m = 32; -- ascii 32-127 + local digits = {}; local j = 1; + for i=1, string.len(text) do + local c = string.byte(text,i)-m; + if c>=0 and c<96 then digits[j] = c; j =j +1 end + end + local ascii = bignum.new(96,1,digits); + local binary = bignum.base2binary(ascii); + return bignum.binary2base(binary,newbase); +end + +local ascii_test = function() + local n = bignum.rnd(10,1,177); -- 512 bits + say("B1 = " .. bignum.tostring(n)) + local ascii = bignum.exportascii(n); + say("ascii = " .. ascii) + local m = bignum.importascii(ascii,10) + say("B2 = " .. bignum.tostring(m)) +end +--ascii_test() + ----------------------------------------------- -- ADDITION ----------------------------------------------- @@ -535,7 +599,7 @@ bignum.binary2base = function(n, newbase) -- newbase must be even for i = #data,1,-1 do bignum._add(ret,ret,ret) -- ret = 2*ret out = ret.digits - out[1]=out[1]+ data[i]; -- if newbase is even no carry, else more complication here + out[1]=out[1]+ data[i]; -- WARNING: basically +1, if newbase is even no carry, else more complication here end return ret end @@ -688,44 +752,4 @@ DH_bench() -- note: DH security ( log problem ) can be solved for 512 bit by expert team, 1024 prime modulo for state actors ( logjam attack, "Imperfect Forward Secrecy: -- How Diffie-Hellman Fails in Practice", Oct 2015 --- rnd key exchange v2 (improved key hide when doing verification): --- auth + key exchange in one idea: A alice (client), B bob (server) --- key generation: A generates its shared secret as v = g^x for secret random x and exchanges it with B. --- this initial exchange can use DH with very large group to prevent any snooping. - --- verification: --- 1. B picks random r and tells A y=g^r+v. --- Note here that listeners only see g^r+v so they have no clue what v is or what g^r is. Even from multiple sessions they --- learn nothing if g is generator of whole group and r truly random, since then g^r can be anything with same probability. --- 2. A confirms identity by sending back hash(g^rx) = hash(v^r) = hash((y-v)^x) to prove you know a. --- 3. shared secret is then another hash of K=g^rx = (g^r)^x = (g^x)^r. - --- --- basic idea is this: i tell you y=g^r for random r, you need to tell me y^x, so i believe you know x. But hide y by adding v and with hash so --- listeners dont get any clues. - ---observations: --- 0. note that K lies in potentially smaller group generated by g^x, srp 6a is better here since for srp K = g^(b(a + ux)). --- where a,b are random --- The order of Z_p* is 2q for prime q, where p-1 = 2q ( p safe prime ). Order of g^x is either 2 or q or 2q (if (g^x)^2~= 1 then its not 2) --- So order of g^x is still (p-1)/2 in this case. --- thm: if G is finite group then order of any element divides |G|. Furthermore, if p is prime dividing |G| there exists element --- in G of order p (cauchy thm) - --- 1. Suppose there is observer C. first time of interaction he can see v=g^x sent from A to B, but getting x is not possible ( log problem ) --- 2. later C can see B send v+g^r, and if he doesnt know v already this does not reveal it to him.. If we encrypt this this might introduce --- weakness if not properly done, cause only good password would encrypt to number, bad password would be random mess. - --- WEAKNESS: if C knows v ...? --- idea: first time exchange uses larger DH group for more safety to exchange: v = g^x to prevent C from learning x. - ---srp v6a : http://srp.stanford.edu/design.html ---NOTE: srp v1 http://srp.stanford.edu/design1.html used weak approach to compute secret: S = (Wp*Xp)^Ys, where Xp = could be leaked --- pass. verifier, Wp = controlled by client, Ys = random server secret --- if rogue client know Xp he could select Wp so that Wp*Xp becomes value of his choice, hence controlling what the final shared secret --- will be. --- rnd key exchange v2 does not have that weakness. even if rogue learns v = g^x by other means he still needs to solve log problem for x. - --- prime generation: openssl prime -generate -bits 2048 -hex - self.remove() -- prevent loop in robot csm \ No newline at end of file diff --git a/scripts/misc/crypto/dsa.lua b/scripts/misc/crypto/dsa.lua new file mode 100644 index 0000000..13a8c71 --- /dev/null +++ b/scripts/misc/crypto/dsa.lua @@ -0,0 +1,132 @@ +--dsa by rnd +--digital signature algorithm + +-- parameters: p,q,g +-- 1. p,q primes such that p-1 = a'*q, for example p safe prime, p-1=2q (N bits, L bits) +-- 2. select g in Z_p of order q ( for example 2^(p-1)/q or 3^... if first one is 1) + +-- user keys: x in Z_q private key, y = g^x in Z_p = private key + +-- MAIN IDEA: given message m and random k in Z_q and r = g^k %p %q find +-- w such that: g^(hash(m)*w + x*r*w) %p %q = g^k %p %q +-- this is easy if we know x -> solve w*(h+x*r) =k in Z_q -> w = (h+x*r)^-1*k in Z_q + +-- now we hide k and x and show only y = g^x and r = g^k, problem is rewritten as: +-- PROBLEM: +-- g^(h*w) * y^(r*w) %p %q = r. So problem is determining such r and w. + +-- NOTE: the idea of %p %q is to make brute force even slower, since: +-- x=y %p %q if x=y+t1*q+t2*p for some p,q + +-- note : +--1 .the attacker doesnt have much freedom with h since he cant precisely control hash values +--2. suppose same k is reused for 2 different m. Write s = w^-1 mod q. Since +--s = k^-1*(h+r*x) mod q we get: s2 = k^-1*(h2+r*x) and s1 = k^-1*(h1+r*x), +-- or s2-s1 = k^-1( h2-h1) -> k = (s2-s1)^-1*(h2-h1).. and r^-1*(k*s-h)=x = BAD +-- must be careful that we pick very different k each time +-- 3. CAREFUL! k1 s1 = (h1+r1*x), k2 s2 =(h2+r2*x) -> k1 s1- k2 s2 - (h1-h2) = (r1-r2)*x. +-- so if we know there is little difference between k1,k2 we can try small sample different k2 and try to solve for x! + +local bignum = _G.bignum + +--512 bit +--c1d3a133c9b3720da868dda10b6a0bde0e1a47d797d3e02f2673157ad26c33970553352abd72114a48813b3f1a3d86120c2150d9c33780bf0ce31acf2e28b813 + +p = {base = 67108864, sgn = 1,digits = {36222995, 13022155, 782542, 57085150, 34349392, 42951044, 1291249, 4532514, 19578226, 29447373, 19317561, 30168555, 65023782, 32892404, 31515044, 2992175, 6872481, 14451562, 34815131, 198478}} +barrettp = {["k"] = 42, ["m"] = {["base"] = 67108864, ["sgn"] = 1,["digits"] = {28949715, 54423101, 2288892, 15960629, 25093079, 30961036, 9893219, 18572583, 6060506, 53345934, 62824245, 21175570, 51585074, 64634085, 50626132, 23908947, 34461644, 49242303, 44848557, 11882353, 4640537, 7818826, 338}}, ["n"] = {["base"] = 67108864, ["sgn"] = 1, ["digits"] = {36222995, 13022155, 782542, 57085150, 34349392, 42951044, 1291249, 4532514, 19578226, 29447373, 19317561, 30168555, 65023782, 32892404, 31515044, 2992175, 6872481, 14451562, 34815131, 198478}}} + +q = {["base"] = 67108864, ["sgn"] = 1, ["digits"] = {51665929, 6511077, 391271, 28542575, 17174696, 55029954, 645624, 2266257, 43343545, 48278118, 43213212, 15084277, 32511891, 16446202, 49311954, 35050519, 3436240, 40780213, 17407565, 99239}} +barrettq = {["k"] = 42, ["m"] = {["base"] = 67108864, ["sgn"] = 1, ["digits"] = {50630993, 11411608, 4806431, 31921258, 50186158, 61922072, 19786438, 37145166, 12121012, 39583004, 58539627, 42351141, 36061284, 62159307, 34143401, 47817895, 1814424, 31375743, 22588251, 23764707, 9281074, 15637652, 676}}, ["n"] = {["base"] = 67108864, ["sgn"] = 1, ["digits"] = {51665929, 6511077, 391271, 28542575, 17174696, 55029954, 645624, 2266257, 43343545, 48278118, 43213212, 15084277, 32511891, 16446202, 49311954, 35050519, 3436240, 40780213, 17407565, 99239}}} + +--2048 bit +--db726369acb4a51666ee14e0dc4305afc11692cc0dfa9d06b399ebc7b541b095ca3f48633ed936e0d4633af1c8b72886829c5fdd98861c44acdadc54075dc3beeb3d4a4bf9fb13b2c943e8bcb8c8df4440a84753c87d1512ff3db5083941ac88764c674da50771fdd7f4db99d7281e653253191df1f0137004b81488ecf9d15c49462c5438d4c060fa5a36e3e8e73ca1969d312b1b11df3e6fa3ce0a87641f4007884470d4911da45df914143c2c446a51443d6595c84cf83467825cf08007546e04c5137acac3ec0f413c522f5904d3b5230b4f5f2a26a0a8ad318ab541d1cd69079b0cb040827e2eb48f4fb7bc76623b96c7d38c603a186e24ae70a3bd66b3 + +-- p = { + -- base = 2^26, sgn = 1, + -- digits = {62744243, 19635240, 60917474, 55456128, 37459655, 32447896, 55112955, 34207930, 51163200, 56246758, 55844124, 45401642, 36085928, 47437770, 20664880, 12411923, 54606930, 45153027, 5322668, 22132755, 15761415, 18473111, 8703875, 16094807, 6967620, 17763089, 31428929, 38041233, 4485332, 63963618, 11040321, 29265720, 51502910, 55331526, 63576425, 59745180, 16407094, 37040152, 6473027, 54882597, 8973561, 77317, 52363575, 21783671, 1991986, 48657866, 64847693, 43261383, 38561613, 7021085, 55608212, 4979958, 63470869, 2757076, 9303108, 61010659, 62048579, 50233028, 45339812, 24579835, 47993863, 51456822, 31033441, 34238847, 12003462, 13548658, 57544006, 26016612, 30031688, 22047781, 27180155, 41163470, 46927354, 66078116, 29634650, 62411651, 10819174, 14314285, 898854} +-- } +-- barrettp = { + -- ["k"] = 160, ["m"] = {["base"] = 67108864, ["sgn"] = 1, + -- ["digits"] = {52173231, 58926316, 7134135, 58005281, 29642925, 1996, 43704342, 19181367, 51834951, 40753938, 5670116, 25083444, 53681109, 39194353, 21018693, 16186348, 52641345, 34474171, 45582158, 65632598, 6663244, 17715531, 46582518, 715815, 35941432, 62741031, 14063905, 37500214, 33724930, 25815530, 29521098, 42349641, 30021354, 56331771, 20197595, 44642351, 39774, 15935544, 18538053, 54085894, 20262092, 170794, 877950, 7075184, 15922733, 42275553, 19627281, 61124663, 6351068, 20488035, 52369744, 26751026, 17905178, 25990200, 47243983, 42954366, 65859731, 23375626, 40610711, 9951837, 9139091, 55630155, 4911180, 17490059, 43409254, 37055369, 1417704, 12145177, 9055946, 41623298, 33230333, 1111792, 21966597, 20877280, 44498082, 6831928, 22418430, 4437100, 27282748, 12568457, 44322344, 74}}, ["n"] = {["base"] = 67108864, ["sgn"] = 1, ["digits"] = {62744243, 19635240, 60917474, 55456128, 37459655, 32447896, 55112955, 34207930, 51163200, 56246758, 55844124, 45401642, 36085928, 47437770, 20664880, 12411923, 54606930, 45153027, 5322668, 22132755, 15761415, 18473111, 8703875, 16094807, 6967620, 17763089, 31428929, 38041233, 4485332, 63963618, 11040321, 29265720, 51502910, 55331526, 63576425, 59745180, 16407094, 37040152, 6473027, 54882597, 8973561, 77317, 52363575, 21783671, 1991986, 48657866, 64847693, 43261383, 38561613, 7021085, 55608212, 4979958, 63470869, 2757076, 9303108, 61010659, 62048579, 50233028, 45339812, 24579835, 47993863, 51456822, 31033441, 34238847, 12003462, 13548658, 57544006, 26016612, 30031688, 22047781, 27180155, 41163470, 46927354, 66078116, 29634650, 62411651, 10819174, 14314285, 898854}} + +local importsshprime = function(GH) -- use this to precompute all the needed prime stuff for extra speed + local base = 2^26; + local G1 = bignum.importhex(GH); local G2 = bignum.base2binary(G1); + + local p = bignum.binary2base(G2,base); + code1 = minetest.serialize(p.digits) -- prime GH digits + local t = os.clock(); + + local barrettp = bignum.get_barrett(p);say(os.clock()-t) -- precompute barrett form + local code2 = minetest.serialize(barrettp) + + local q = bignum.new(base,1,p.digits); q.digits[1] = q.digits[1]-1; bignum.div2(q,q); -- q = (p-1)/2 + local code3 = minetest.serialize(q) + + local barrettq = bignum.get_barrett(q); -- precompute q and this! + local code4 = minetest.serialize(barrettq) + + local msg = "p " ..code1.."\nbarrettp " .. code2 .. "\nq " .. code3 .. "\nbarrettq " .. code4; + local form = "size[5,5] textarea[0,0;6,6;MSG;MESSAGE;" .. minetest.formspec_escape(msg) .. "]" + minetest.show_formspec("robot", form) +end + +--importsshprime("c1d3a133c9b3720da868dda10b6a0bde0e1a47d797d3e02f2673157ad26c33970553352abd72114a48813b3f1a3d86120c2150d9c33780bf0ce31acf2e28b813") + + + +DSA = {}; +--msg = 520 bit number base 2^26 +DSA.sign = function(msg,x) -- msg = (hash) message as number, x = private key + local m = 20; local base = 2^26; + local k = bignum.rnd(base,1,m); -- random value! + + --warning: possible problem if q1.digits[1]-2 = 1-2<0 cause we didnt do carry! extremely unlikely, since digits in base 2^26. + local q1 = bignum.new(base,1,q.digits); q1.digits[1] = q1.digits[1]-2; -- q-2, needed to compute c^-1 = c^(q-2) mod q. + local g = bignum.new(base,1,{2^2}); -- g^q = 1 mod q ( g = 2^(p-1)/q mod p = 2^2) + local temp = bignum.modpow(g,k, barrettp); -- g^k mod p + local r = bignum.new(base,1,{});bignum.mod(temp,barrettq,r); --r = g^k mod p mod q + bignum.mul(x,r,temp); bignum._add(msg,temp,temp); -- temp = m+x*r + local temp1 = bignum.new(base,1,{});bignum.mod(temp,barrettq,temp1) -- range is very important, temp1 < q or modpow can freeze + temp = bignum.modpow(temp1, q1, barrettq); --(m+x*r)^-1 -- FREEZE PROBLEM if temp1>q. cause then temp1^2>q^2 and barret modpow fail.. + + local w = bignum.new(base,1,{}); + bignum.mul(temp,k,w);bignum.mod(w,barrettq,temp1) + return {r,temp1} -- w = temp1 = (m+x*r)^-1*k in Z_q +end + + + +DSA.verify = function(msg,sig,y) -- m = message, sig = {r,w} = signature, y = public key (= g^x) + -- CHECK: g^(m*w) * y^(r*w) %p %q == r + local m = 20; local base = 2^26; + local g = bignum.new(base,1,{2^2}); + local temp1 = bignum.new(base,1,{}); + bignum.mul(msg,sig[2],temp1); temp1 = bignum.modpow(g,temp1,barrettp); -- temp1 = g^(m*w) mod p + local temp2 = bignum.new(base,1,{}); + bignum.mul(sig[1],sig[2],temp2); temp2 = bignum.modpow(y,temp2,barrettp); -- temp2 = y^(r*w) mod p + local temp = bignum.new(base,1,{}); + bignum.mul(temp1,temp2,temp); bignum.mod(temp,barrettq,temp1); -- temp1 = g^(m*w) * y^(r*w) %p %q + return bignum.is_equal(temp1,sig[1]) +end + + +dsa_sign_test = function() + local x = bignum.rnd(2^26,1,20) -- private key + local g = bignum.new(2^26,1,{2^2}); + local y = bignum.modpow(g,x,barrettp) -- public key + + local msg = bignum.importascii("hello world",2^26) -- will cut off at 520 bytes, use hash here for real thing + + local sig = DSA.sign(msg,x) + --say(minetest.serialize(sig)) + + local ok = DSA.verify(msg,sig,y) + say(ok and "true" or "false") +end +dsa_sign_test() + + + + +self.remove() \ No newline at end of file diff --git a/scripts/misc/crypto/import_ssh_prime.lua b/scripts/misc/crypto/import_ssh_prime.lua new file mode 100644 index 0000000..83e5f04 --- /dev/null +++ b/scripts/misc/crypto/import_ssh_prime.lua @@ -0,0 +1,47 @@ +-- generate prime in openssl: openssl prime -generate -safe -bits 512 -hex + +--512 bit +--c1d3a133c9b3720da868dda10b6a0bde0e1a47d797d3e02f2673157ad26c33970553352abd72114a48813b3f1a3d86120c2150d9c33780bf0ce31acf2e28b813 + +p = { + base = 2^26, sgn = 1, + digits = {36222995, 13022155, 782542, 57085150, 34349392, 42951044, 1291249, 4532514, 19578226, 29447373, 19317561, 30168555, 65023782, 32892404, 31515044, 2992175, 6872481, 14451562, 34815131, 198478} +} + +barrettp = { + ["k"] = 42, ["m"] = {["base"] = 67108864, ["sgn"] = 1, + ["digits"] = {28949715, 54423101, 2288892, 15960629, 25093079, 30961036, 9893219, 18572583, 6060506, 53345934, 62824245, 21175570, 51585074, 64634085, 50626132, 23908947, 34461644, 49242303, 44848557, 11882353, 4640537, 7818826, 338}}, ["n"] = {["base"] = 67108864, ["sgn"] = 1, ["digits"] = {36222995, 13022155, 782542, 57085150, 34349392, 42951044, 1291249, 4532514, 19578226, 29447373, 19317561, 30168555, 65023782, 32892404, 31515044, 2992175, 6872481, 14451562, 34815131, 198478}} +} + +--2048 bit +--db726369acb4a51666ee14e0dc4305afc11692cc0dfa9d06b399ebc7b541b095ca3f48633ed936e0d4633af1c8b72886829c5fdd98861c44acdadc54075dc3beeb3d4a4bf9fb13b2c943e8bcb8c8df4440a84753c87d1512ff3db5083941ac88764c674da50771fdd7f4db99d7281e653253191df1f0137004b81488ecf9d15c49462c5438d4c060fa5a36e3e8e73ca1969d312b1b11df3e6fa3ce0a87641f4007884470d4911da45df914143c2c446a51443d6595c84cf83467825cf08007546e04c5137acac3ec0f413c522f5904d3b5230b4f5f2a26a0a8ad318ab541d1cd69079b0cb040827e2eb48f4fb7bc76623b96c7d38c603a186e24ae70a3bd66b3 + +p = { + base = 2^26, sgn = 1, + digits = {62744243, 19635240, 60917474, 55456128, 37459655, 32447896, 55112955, 34207930, 51163200, 56246758, 55844124, 45401642, 36085928, 47437770, 20664880, 12411923, 54606930, 45153027, 5322668, 22132755, 15761415, 18473111, 8703875, 16094807, 6967620, 17763089, 31428929, 38041233, 4485332, 63963618, 11040321, 29265720, 51502910, 55331526, 63576425, 59745180, 16407094, 37040152, 6473027, 54882597, 8973561, 77317, 52363575, 21783671, 1991986, 48657866, 64847693, 43261383, 38561613, 7021085, 55608212, 4979958, 63470869, 2757076, 9303108, 61010659, 62048579, 50233028, 45339812, 24579835, 47993863, 51456822, 31033441, 34238847, 12003462, 13548658, 57544006, 26016612, 30031688, 22047781, 27180155, 41163470, 46927354, 66078116, 29634650, 62411651, 10819174, 14314285, 898854} +} + +barrettp = { + ["k"] = 160, ["m"] = {["base"] = 67108864, ["sgn"] = 1, + ["digits"] = {52173231, 58926316, 7134135, 58005281, 29642925, 1996, 43704342, 19181367, 51834951, 40753938, 5670116, 25083444, 53681109, 39194353, 21018693, 16186348, 52641345, 34474171, 45582158, 65632598, 6663244, 17715531, 46582518, 715815, 35941432, 62741031, 14063905, 37500214, 33724930, 25815530, 29521098, 42349641, 30021354, 56331771, 20197595, 44642351, 39774, 15935544, 18538053, 54085894, 20262092, 170794, 877950, 7075184, 15922733, 42275553, 19627281, 61124663, 6351068, 20488035, 52369744, 26751026, 17905178, 25990200, 47243983, 42954366, 65859731, 23375626, 40610711, 9951837, 9139091, 55630155, 4911180, 17490059, 43409254, 37055369, 1417704, 12145177, 9055946, 41623298, 33230333, 1111792, 21966597, 20877280, 44498082, 6831928, 22418430, 4437100, 27282748, 12568457, 44322344, 74}}, ["n"] = {["base"] = 67108864, ["sgn"] = 1, ["digits"] = {62744243, 19635240, 60917474, 55456128, 37459655, 32447896, 55112955, 34207930, 51163200, 56246758, 55844124, 45401642, 36085928, 47437770, 20664880, 12411923, 54606930, 45153027, 5322668, 22132755, 15761415, 18473111, 8703875, 16094807, 6967620, 17763089, 31428929, 38041233, 4485332, 63963618, 11040321, 29265720, 51502910, 55331526, 63576425, 59745180, 16407094, 37040152, 6473027, 54882597, 8973561, 77317, 52363575, 21783671, 1991986, 48657866, 64847693, 43261383, 38561613, 7021085, 55608212, 4979958, 63470869, 2757076, 9303108, 61010659, 62048579, 50233028, 45339812, 24579835, 47993863, 51456822, 31033441, 34238847, 12003462, 13548658, 57544006, 26016612, 30031688, 22047781, 27180155, 41163470, 46927354, 66078116, 29634650, 62411651, 10819174, 14314285, 898854}} +} + + +local bignum = _G.bignum; +local importsshprime = function(GH, base) + local G1 = bignum.importhex(GH); local G2 = bignum.base2binary(G1); + local G3 = bignum.binary2base(G2,base); + code1 = minetest.serialize(G3.digits) -- prime GH digits + + local t = os.clock();local barrett = bignum.get_barrett(G3);say(os.clock()-t) -- precompute barrett form + local code2 = minetest.serialize(barrett) + + local form = "size[5,5] textarea[0,0;6,6;MSG;MESSAGE;" .. minetest.formspec_escape("prime " ..code1.."\nbarrett " .. code2) .. "]" + minetest.show_formspec("robot", form) +end + +GH = "db726369acb4a51666ee14e0dc4305afc11692cc0dfa9d06b399ebc7b541b095ca3f48633ed936e0d4633af1c8b72886829c5fdd98861c44acdadc54075dc3beeb3d4a4bf9fb13b2c943e8bcb8c8df4440a84753c87d1512ff3db5083941ac88764c674da50771fdd7f4db99d7281e653253191df1f0137004b81488ecf9d15c49462c5438d4c060fa5a36e3e8e73ca1969d312b1b11df3e6fa3ce0a87641f4007884470d4911da45df914143c2c446a51443d6595c84cf83467825cf08007546e04c5137acac3ec0f413c522f5904d3b5230b4f5f2a26a0a8ad318ab541d1cd69079b0cb040827e2eb48f4fb7bc76623b96c7d38c603a186e24ae70a3bd66b3"; +--GH = "bc614e" -> "12345678" -- chk ok +local code = importsshprime(GH,2^26) + +self.remove() \ No newline at end of file