finished mostly.  code at:

https://github.com/Pascal-J/BN-openssl-bindings-for-J

New sample functions I added since yesterday are a lcg and blum blum shub RNGs.

In J and explicit and tacit BN code

the creation parameters for lcg are: PrimeModulus Addition and seed

298617423759287597949893501491962328326117452597400961294601101680264341574651169007633933450439527729433352349130831796973181706060273249989873557896536953533949729466518411328037250569573370887517227493158889591388495032255785041665435956093
 1902831092831029812830 
85129617461891649734274611646334861564198564772449744004786622524842236224099696226154815067523x

those should auto linebreak in mail reader.  The parameters for BBS generator 
are the first and third(last)

the key J code for each is:
roll =: (] | 'seed'  ([ assign  a + ]) (p|seed) (p|*) 3 : 'seed')"0
rollb =: (] | 'seedb' assign  [: p&|@(*:) 3 : 'seedb')"0

The equivalent BN code.  First explicit:
rollE =: 3 : 0"0 NB. LCG  (M is basically static initial seed)
BNmod_mul__C S;S;M;P;CTX__C 
BNmod_add__C S;S;A;P;CTX__C 
BNmod_word__C S;y 
) 

rollE =: 3 : 0"0 NB. BBS
BNmod_sqr__C S;S;P;CTX__C 
BNmod_word__C S;y 
)




timings:




=======

More timings, not dumping the file just yet, but showing interface samples.  I 
made a direct pointer locale that still manages memory.  Its much faster than 
managing J objects, but will segfault if you think you are passing a pointer 
when you are not.  The J object version gives an innocent locale error.  So 
there is room for both.

Miller Rabin prime test in J

MRabin =: 4 : 0 NB. millerrabin test.  x is random witnesses < y 
e =. <. @ -:^:(0=2&|)^:a: y-1 
for_a. x  do. if. (+./c=y-1) +: 1={:c=. a y&|@^"0 e do. 0 return. end. end. 
1 
)

In oop BN mode,

MRabinBN=: 4 : 0 NB. millerrabin text.  x is random witnesses < y 
Y =. newM y 
E =. newM e =. <. @ -:^:(0=2&|)^:a: y-1 
for_a. 'I' inl newM x  do. 
BNmod_exp"1   EEi ;"0 1 a ;"1  EEi;"0 1 I__Y ; (CTX)[EEi =. 'I' inl EE =. dupM 
E 
'toX a:' inl EE 
if. (+./ (y-1) = 'toX a:' inl EE) +: 1= BNget_word {: EEi do. out=.0 return. 
end. 
end. 1 
) 


In new raw BN mode (still managed memory)

MRabinBN=: 4 : 0 NB. millerrabin text.  x is random witnesses < y 
Y =. newM y 
E =. newM e =. <. @ -:^:(0=2&|)^:a: y-1 
for_a. newM x  do. 
BNmod_exp"1   EEi ;"0 1 a ;"1  EEi;"0 1 Y ; (CTX)[EEi  =. dupM E 
NB.pD toX  EEi 
if. (+./ (y-1) = toX  EEi) +: 1= BNget_word {: EEi do. out=.0 return. end. 

end.  1 
)

testing a prime with 3 witnesses

C is OOP locale, D is direct locale

Pure J,
timespacex '123 129830012 12382902983209832098338901x MRabin__C 
16513016020288569463710715785129617461891649734274611646334861564198564772449744004786622524842236224099696226154815067523x'
0.22579 3.07098e6

Direct BN: 100+x faster
timespacex '123 129830012 12382902983209832098338901x MRabinBN__D 
16513016020288569463710715785129617461891649734274611646334861564198564772449744004786622524842236224099696226154815067523x'
 
0.00196416 18816 


Object BN: 40x faster, 
timespacex '123 129830012 12382902983209832098338901x MRabinBN__C 
16513016020288569463710715785129617461891649734274611646334861564198564772449744004786622524842236224099696226154815067523x'
 
0.00597568 68096 


J is faster at pure multiplication (of many smaller numbers) though. But its 
easy, as in the miller rabin code above to mix and match J operations with BN 
operations  modular exponentiation is the main thing it does fast.


ProductW =: 3 : 0 
acc =. newM {: y 
(}: y) 4 : 'y[ BNfree a [ BNmul_word y;a =. newI x' reduce acc 
)

timespacex 'ProductW__D p: i.300' 
0.013215 79488 
timespacex '*/  p: i.300x' 
0.00380256 109312 


There's actually not much gain to erasing things as you go along, instead of 
all at once when you are done (if you have the memory).  This is my new sum 
code, XC displays the Jxint values and releases the BNs

sum =:   (][ [: BNadd_ctx_ ] ; ;)/@:newM

XC__D sum__D i.10 
45

product just needs to add a context (only variable in the manager)

product =: (][ [: BNmul_ctx_ ] ;wCTX ;)/@:newM

XC__D product__D p: i.10 
6469693230

speed gains over J as numbers get larger (timings include memory free)

timespacex'( ] * 32 ^ ~ [ ) / p: i. 50x' 
0.0053535982868485486 339840 


timespacex'''XC (][[:BNmul ];wCTX ];[ [ [:BNexp [;wCTX a ;~[)/@:newM p:i.50 [ a 
=: newM 32'' inl D' 
0.0057142381714437853 63232 


timespacex'''XC (][[:BNmul ];wCTX ];[ [ [:BNexp [;wCTX a ;~[)/@:newM p:i.200 [ 
a =: newM 47'' inl D' 
0.0611437 182528 
timespacex'( ] * 47 ^ ~ [ ) / p: i. 200x' 
0.135313 259840 

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to