jruby extension#30
Conversation
generated based on C sources
headius
left a comment
There was a problem hiding this comment.
Looks good to me overall. Will be worth running some benchmarks to clean up excess allocation. A few minor review comments should be addressed.
| import java.util.Arrays; | ||
|
|
||
| public final class BCryptPbkdf { | ||
| private static final int BLF_N = 16; |
There was a problem hiding this comment.
Fix indentation to match Java standard, otherwise this will be a constant maintenance headache.
| engine.getSingletonClass().defineAnnotatedMethods(BCryptPbkdfExt.class); | ||
| } | ||
|
|
||
| @JRubyMethod(required = 4, rest = true) |
There was a problem hiding this comment.
These don't appear to be rest-arg methods so remove rest = true.
There was a problem hiding this comment.
unfortunately, failing when rest = true is removed
There was a problem hiding this comment.
10.0.5.0 (fails the same on 9.4 as well):
java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at org.jruby.dist/org.jruby.internal.runtime.methods.InvocationMethodFactory.loadArguments(InvocationMethodFactory.java:559)
at org.jruby.dist/org.jruby.internal.runtime.methods.InvocationMethodFactory.createAnnotatedMethodInvocation(InvocationMethodFactory.java:782)
at org.jruby.dist/org.jruby.internal.runtime.methods.InvocationMethodFactory.addAnnotatedMethodInvoker(InvocationMethodFactory.java:719)
at org.jruby.dist/org.jruby.internal.runtime.methods.InvocationMethodFactory.getAnnotatedMethodClass(InvocationMethodFactory.java:279)
at org.jruby.dist/org.jruby.internal.runtime.methods.InvocationMethodFactory.getAnnotatedMethod(InvocationMethodFactory.java:328)
at org.jruby.dist/org.jruby.RubyModule.defineAnnotatedMethod(RubyModule.java:1400)
at org.jruby.dist/org.jruby.RubyModule.defineAnnotatedMethod(RubyModule.java:1374)
at org.jruby.dist/org.jruby.anno.TypePopulator$ReflectiveTypePopulator.populate(TypePopulator.java:119)
at org.jruby.dist/org.jruby.RubyModule.defineAnnotatedMethodsIndividually(RubyModule.java:1368)
at org.jruby.dist/org.jruby.RubyModule.defineAnnotatedMethods(RubyModule.java:1272)
at org.netssh.bcrypt_pbkdf.BCryptPbkdfExt.load(BCryptPbkdfExt.java:18)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.jruby.dist/org.jruby.ext.jruby.JRubyUtilLibrary.loadExtension(JRubyUtilLibrary.java:258)
at org.jruby.dist/org.jruby.ext.jruby.JRubyUtilLibrary.load_ext(JRubyUtilLibrary.java:219)
| } | ||
|
|
||
|
|
||
| @JRubyMethod(required = 2, rest = true) |
There was a problem hiding this comment.
Remove rest = true and use two explicit arguments.
|
Explored a pure Ruby fallback as an alternative to this Java extension. Benchmarks show it's ~30x slower than the Java extension on JRuby — about 2.4 seconds per key load at rounds=16 (the openssh default). That's too slow to be acceptable for something that blocks every SSH connection open. So this Java extension is the right path. One thing worth considering: instead of maintaining our own Java port of the Blowfish/bcrypt_pbkdf logic, we could pull in jBCrypt (Kenny Root's fork, |
That is surprising, even after some decent warmup? |
the fork itself seem abandoned (just like the parent) for 5 years, not much going on the repo, see: kruton/jbcrypt#1 it's probably easier/safer to maintain parity C-Java sources (esp. with LLM), the jar-dependencies story is not a headache free path and gets a bit invasive since the preferred path is to vendor the .jar. |
adds a Java implementation (LLM generated based on current C sources)
the rest is plumbing for the JRuby extension ->
-javavariant of the gem