- All Implemented Interfaces:
Serializable, Comparable<BigInteger>
BigInteger that takes advantage of the jbigi library for the modPow operation, which accounts for a massive segment of the processing cost of asymmetric crypto.
The jbigi library itself is basically just a JNI wrapper around the GMP library - a collection of insanely efficient routines for dealing with big numbers.
There are three environmental properties for configuring this component:
- jbigi.enable: whether to use the native library (defaults to "true")
- jbigi.impl: select which resource to use as the native implementation
- jbigi.ref: the file specified in this parameter may contain a resource name to override jbigi.impl (defaults to "jbigi.cfg")
If jbigi.enable is set to false, this class won't even attempt to use the native library, but if it is set to true (or is not specified), it will first check the platform specific library path for the "jbigi" library, as defined by Runtime.loadLibrary(String)RESTRICTED - e.g. C:\windows\jbigi.dll or /lib/libjbigi.so, as well as the CLASSPATH for a resource named 'jbigi'. If that fails, it reviews the jbigi.impl environment property - if that is set, it checks all of the components in the CLASSPATH for the file specified and attempts to load it as the native library. If jbigi.impl is not set, it uses the jcpuid library described below. If there is still no matching resource, or if that resource is not a valid OS/architecture specific library, the NativeBigInteger will revert to using the pure java implementation.
When attempting to load the native implementation as a resource from the CLASSPATH, the NativeBigInteger will make use of the jcpuid component which runs some assembly code to determine the current CPU implementation, such as "pentium4" or "zen3". We then use that, combined with the OS, to build an optimized resource name - e.g. "net/i2p/util/libjbigi-freebsd-pentium4_64.so" or "net/i2p/util/jbigi-windows-zen3_64.dll". If that resource exists, we use it. If it doesn't (or the jcpuid component fails), we try a generic native implementation using "none" for the CPU e.g. "net/i2p/util/jbigi-windows-none_64.dll".
Running this class by itself does a basic unit test and benchmarks the NativeBigInteger.modPow vs. the BigInteger.modPow by running a 2Kbit op 100 times. At the end of each test, if the native implementation is loaded this will output something like:
native run time: 6090ms (60ms each) java run time: 68067ms (673ms each) native = 8.947066860593239% of pure java time
If the native implementation is not loaded, it will start by saying:
WARN: Native BigInteger library jbigi not loaded - using pure java
Then go on to run the test, finally outputting:
java run time: 64653ms (640ms each) However, we couldn't load the native library, so this doesn't test much
- See Also:
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static StringMicroarchitecture name for display, or null if unknown.private static StringCPU model the jbigi was chosen for.private static booleanDo we want to dump some basic success/failure info to stderr during initialization? this would otherwise use the Log component, but this makes it easier for other systems to reuse this classprivate static StringResource the jbigi library was extracted from.private static final booleanWhether the JVM is 64-bit.private static final booleanWhether we are running on Android.private static final booleanWhether the CPU is ARM.private static final booleanTrue on the FreeBSD kernel.private static final booleanTrue on the KFreeBSD kernel.private static final booleanWhether we are running on macOS.private static final booleanTrue on the NetBSD kernel.private static final booleanTrue on the OpenBSD kernel.private static final booleanWhether we are running on OS/2.private static final booleanTrue on the SunOS kernel.private static final booleanOperating systems.private static final booleanWhether the CPU is x86.private static intVersion of the loaded jbigi library.private static StringVersion of the GMP library in use.private static final String_isOS2 ? "" : "lib"); File name prefix for the native library.private static final String_isOS2 ? ".dll" : _isMac ? ".jnilib" : ".so"); File name suffix for the native library.private static StringHow the native library load went.private static booleanIs native lib loaded and at least version 3, and GMP at least version 5?private static booleanDid we load the native lib correctly?private static booleanIs native lib loaded and at least version 3?private byte[]Cached ba.private static final String[]Compatible builds for AMD APUs.private static final String[]Compatible builds for AMD Athlon and Opteron.private static final String[]The main AMD product line.private static final String[]Compatible builds for ARM ARMv8.private static final String[]Compatible builds for Intel Atom.private static final String[]Compatible builds for Intel Core.private static final String[]Compatible builds for Intel Pentium.private static final String[]CPU architecture compatibility lists, in order of preference.private static final String[]Compatible builds for VIA processors.The mapping between CPU architecture and its compatibility list.private static final StringARM, 64-bit only.private static final StringThe following libraries are be available in jbigi.jar in all I2P versions originally installed as release 0.6.1.10 or later (released 2006-01-16), for linux, freebsd, osx, and windows, EXCEPT: - athlon64 not available for freebsd - osx also does not have all of them.private static final StringThe 7 optimizations below here are since 0.8.7.private static final Stringjbigi build optimized for AMD Bobcat.private static final Stringjbigi build optimized for AMD Bulldozer.private static final Stringjbigi build optimized for Core 2.private static final Stringjbigi build optimized for Core i.private static final Stringjbigi build for Core i with Broadwell instructions.private static final Stringjbigi build for Core i with Haswell instructions.private static final StringThe optimization levels defined here are since 0.9.26.private static final Stringjbigi build optimized for AMD Excavator.private static final Stringjbigi build optimized for AMD Jaguar.private static final Stringjbigi build optimized for AMD K10.private static final Stringjbigi build optimized for Intel Atom Nano.private static final Stringjbigi build optimized for the Pentium 4.private static final Stringjbigi build optimized for AMD Piledriver.private static final StringJbigi optimization name for Skylake CPUs.private static final Stringjbigi build optimized for AMD Steamroller.private static final StringNone, no optimizations.private static final StringJbigi optimization name for Zen CPUs.private static final StringJbigi optimization name for Zen 2 CPUs.private static final StringJbigi optimization name for Zen 3 CPUs.private static final StringThe CPU type the jbigi was chosen for.Fields inherited from class BigInteger
ONE, TEN, TWO, ZEROConstructor Summary
ConstructorsConstructorDescriptionNativeBigInteger(byte[] val) BigInteger from the given big-endian representation.NativeBigInteger(int signum, byte[] magnitude) BigInteger from the given signum and magnitude.NativeBigInteger(int bitlen, int certainty, Random rnd) Probable prime of given bit length.NativeBigInteger(int numbits, Random rnd) Random non-negative BigInteger.NativeBigInteger(String val) Decimal string representation.NativeBigInteger(String val, int radix) String representation in the specified radix.Copy constructor from a BigInteger.Method Summary
Modifier and TypeMethodDescriptionstatic StringamdFamily(AMDCPUInfo cpu) Microarchitecture name for an AMD CPU, reported at the newest generation its compatibility flags support.static StringProcessor family for the console info page, named the way a reader would expect rather than the way the jbigi library is named.static StringcpuModel()CPU model string fromCPUID.static StringcpuType()Detected CPU type for jbigi optimization.private static voidLog a native math debug message.private static voidLog a native math error.private static voidLog a native math error with its cause.(package private) static StringDisplay name for a jbigi optimization name, or null when the name carries no information about the processor - "none" only says that no tuned build matched.private static intThe jbigi version, fetched from the native library.static intThe jbigi version, fetched from the native library.static StringThe libgmp version string.static StringThe name of the library loaded, if known.private static final StringThe middle part of the native library name, for a non-optimized library.private static final StringgetMiddleName2(boolean optimized) The middle part of the native library name, based on the CPU type.Generate a list of resources to search for, in-order.private static voidLogs an informational message about the library load.static booleanisNative()Whether native methods will be used by this class.private static final booleanloadFromResource(String resourceName) Check all of the jars in the classpath for the file specified by the environmental property "jbigi.impl" and load it as the native library implementation.private static final booleanloadGeneric(String name) Try loading it from an explicitly build jbigi.dll / libjbigi.so first, before looking into a jbigi.jar for any other libraries.private static final voidDo whatever we can to load up the native library backing this BigInteger's native methods.static StringHuman-readable status of the native library load.Compute the modular inverse of this value modulo m using the native library.modPow(BigInteger exponent, BigInteger m) Compute base^exponent mod m using the native library.modPowCT(BigInteger exponent, BigInteger m) Compute base^exponent mod m in constant time using the native library.private static intThe libmp major version, only available since jbigi version 3.private static intThe libmp minor version, only available since jbigi version 3.private static intThe libmp patch version, only available since jbigi version 3.private static intThe jbigi version, only available since jbigi version 3.private static byte[]nativeModInverse(byte[] base, byte[] d) Compute the modular inverse of base modulo d.private static byte[]nativeModPow(byte[] base, byte[] exponent, byte[] modulus) Calculate (base ^ exponent) % modulus.private static byte[]nativeModPowCT(byte[] base, byte[] exponent, byte[] modulus) Calculate (base ^ exponent) % modulus.private static StringTries to resolve the best type of CPU that we have an optimized jbigi-dll/so for.private static voidStore the jbigi and libgmp versions.byte[]Cached byte array representation, filled in on first call.private static voidLogs a warning about the library load.private static voidLog a native math warning.Methods inherited from class BigInteger
abs, add, and, andNot, bitCount, bitLength, byteValueExact, clearBit, compareTo, divide, divideAndRemainder, doubleValue, equals, flipBit, floatValue, gcd, getLowestSetBit, hashCode, intValue, intValueExact, isProbablePrime, longValue, longValueExact, max, min, mod, multiply, negate, nextProbablePrime, not, or, parallelMultiply, pow, probablePrime, remainder, rootn, rootnAndRemainder, setBit, shiftLeft, shiftRight, shortValueExact, signum, sqrt, sqrtAndRemainder, subtract, testBit, toString, toString, valueOf, xorMethods inherited from class Number
byteValue, shortValue
Field Details
_nativeOk
private static boolean _nativeOkDid we load the native lib correctly?_nativeOk3
private static boolean _nativeOk3Is native lib loaded and at least version 3?_nativeCTOk
private static boolean _nativeCTOkIs native lib loaded and at least version 3, and GMP at least version 5?_jbigiVersion
private static int _jbigiVersionVersion of the loaded jbigi library._libGMPVersion
Version of the GMP library in use._loadStatus
How the native library load went._cpuModel
CPU model the jbigi was chosen for._extractedResource
Resource the jbigi library was extracted from._doLog
private static boolean _doLogDo we want to dump some basic success/failure info to stderr during initialization? this would otherwise use the Log component, but this makes it easier for other systems to reuse this classWell, we really want to use Log so if you are one of those "other systems" then comment out the I2PAppContext usage below.
Set to false if not in router context, so scripts using TrustedUpdate.
JBIGI_OPTIMIZATION_ATHLON64
The following libraries are be available in jbigi.jar in all I2P versions originally installed as release 0.6.1.10 or later (released 2006-01-16), for linux, freebsd, osx, and windows, EXCEPT: - athlon64 not available for freebsd - osx also does not have all of them.- See Also:
JBIGI_OPTIMIZATION_PENTIUM4
jbigi build optimized for the Pentium 4.- See Also:
JBIGI_OPTIMIZATION_ATOM
The 7 optimizations below here are since 0.8.7.- See Also:
JBIGI_OPTIMIZATION_CORE2
jbigi build optimized for Core 2.- See Also:
JBIGI_OPTIMIZATION_COREI
jbigi build optimized for Core i.- See Also:
JBIGI_OPTIMIZATION_NANO
jbigi build optimized for Intel Atom Nano.- See Also:
JBIGI_OPTIMIZATION_COREI_SBR
The optimization levels defined here are since 0.9.26.- See Also:
JBIGI_OPTIMIZATION_COREI_HWL
jbigi build for Core i with Haswell instructions.- See Also:
JBIGI_OPTIMIZATION_COREI_BWL
jbigi build for Core i with Broadwell instructions.- See Also:
JBIGI_OPTIMIZATION_K10
jbigi build optimized for AMD K10.- See Also:
JBIGI_OPTIMIZATION_BULLDOZER
jbigi build optimized for AMD Bulldozer.- See Also:
JBIGI_OPTIMIZATION_PILEDRIVER
jbigi build optimized for AMD Piledriver.- See Also:
JBIGI_OPTIMIZATION_STEAMROLLER
jbigi build optimized for AMD Steamroller.- See Also:
JBIGI_OPTIMIZATION_EXCAVATOR
jbigi build optimized for AMD Excavator.- See Also:
JBIGI_OPTIMIZATION_BOBCAT
jbigi build optimized for AMD Bobcat.- See Also:
JBIGI_OPTIMIZATION_JAGUAR
jbigi build optimized for AMD Jaguar.- See Also:
JBIGI_OPTIMIZATION_SKYLAKE
Jbigi optimization name for Skylake CPUs.- See Also:
JBIGI_OPTIMIZATION_ZEN
Jbigi optimization name for Zen CPUs.- See Also:
JBIGI_OPTIMIZATION_ZEN2
Jbigi optimization name for Zen 2 CPUs.- See Also:
JBIGI_OPTIMIZATION_ZEN3
Jbigi optimization name for Zen 3 CPUs.- See Also:
JBIGI_OPTIMIZATION_ARM_ARMV8
ARM, 64-bit only.- See Also:
JBIGI_OPTIMIZATION_X86
None, no optimizations. The default fallback for x86.- See Also:
JBIGI_COMPAT_LIST_NONE
CPU architecture compatibility lists, in order of preference.The list is organized by the chronological evolution of architectures. Totally unrelated architectures have separate lists. Sequences of architectures that aren't backwards compatible (performance wise) for some reasons have also been separated out.
Really this could be represented by a DAG, but the benefits don't outweigh the implementation time.
JBIGI_COMPAT_LIST_ARM_ARMV8
Compatible builds for ARM ARMv8.JBIGI_COMPAT_LIST_VIA
Compatible builds for VIA processors.JBIGI_COMPAT_LIST_AMD_ATHLON
Compatible builds for AMD Athlon and Opteron.JBIGI_COMPAT_LIST_AMD_APU
Compatible builds for AMD APUs.JBIGI_COMPAT_LIST_AMD_MAIN
The main AMD product line.JBIGI_COMPAT_LIST_INTEL_ATOM
Compatible builds for Intel Atom.JBIGI_COMPAT_LIST_INTEL_PENTIUM
Compatible builds for Intel Pentium.JBIGI_COMPAT_LIST_INTEL_CORE
Compatible builds for Intel Core.JBIGI_COMPAT_MAP
_isWin
private static final boolean _isWinOperating systems. True when running on Windows._isOS2
private static final boolean _isOS2Whether we are running on OS/2._isMac
private static final boolean _isMacWhether we are running on macOS._isKFreebsd
private static final boolean _isKFreebsdTrue on the KFreeBSD kernel._isFreebsd
private static final boolean _isFreebsdTrue on the FreeBSD kernel._isNetbsd
private static final boolean _isNetbsdTrue on the NetBSD kernel._isOpenbsd
private static final boolean _isOpenbsdTrue on the OpenBSD kernel._isSunos
private static final boolean _isSunosTrue on the SunOS kernel._isAndroid
private static final boolean _isAndroidWhether we are running on Android._is64
private static final boolean _is64Whether the JVM is 64-bit. See also: detecting the JRE bitness_isX86
private static final boolean _isX86Whether the CPU is x86._isArm
private static final boolean _isArmWhether the CPU is ARM._libPrefix
_isOS2 ? "" : "lib"); File name prefix for the native library._libSuffix
_isOS2 ? ".dll" : _isMac ? ".jnilib" : ".so"); File name suffix for the native library.sCPUType
The CPU type the jbigi was chosen for._cpuFamily
cachedBa
private volatile byte[] cachedBaCached ba.
Constructor Details
NativeBigInteger
public NativeBigInteger(byte[] val) BigInteger from the given big-endian representation.- Parameters:
val- big-endian two's-complement representation
NativeBigInteger
public NativeBigInteger(int signum, byte[] magnitude) BigInteger from the given signum and magnitude.- Parameters:
signum- signum of the representationmagnitude- big-endian binary representation
NativeBigInteger
Probable prime of given bit length.- Parameters:
bitlen- the bit length of the candidate prime to generatecertainty- the Miller-Rabin rounds to run, so the probability of compositeness is at most 2^-certaintyrnd- the source of the candidate bits and the Miller-Rabin witnesses
NativeBigInteger
Random non-negative BigInteger.- Parameters:
numbits- the minimum bit length of the value to generaternd- the source of the random bits
NativeBigInteger
Decimal string representation.- Parameters:
val- the decimal digits, optionally signed, to parse
NativeBigInteger
String representation in the specified radix.- Parameters:
val- the digits to parse, optionally signedradix- the base the digits are written in, from 2 to 36
NativeBigInteger
Copy constructor from a BigInteger. Warning, not very efficient.- Parameters:
val- the value to copy, whose magnitude is read as a big-endian two's complement byte array
Method Details
resolveCPUType
Tries to resolve the best type of CPU that we have an optimized jbigi-dll/so for.- Returns:
- A string containing the CPU-type or null if CPU type is unknown
nativeModPow
private static byte[] nativeModPow(byte[] base, byte[] exponent, byte[] modulus) Calculate (base ^ exponent) % modulus.- Parameters:
base- big endian twos complement representation of the base (but it must be positive)exponent- big endian twos complement representation of the exponentmodulus- big endian twos complement representation of the modulus- Returns:
- big endian twos complement representation of (base ^ exponent) % modulus
- Throws:
ArithmeticException- if modulus <= 0 (since libjbigi version 3)
nativeModPowCT
private static byte[] nativeModPowCT(byte[] base, byte[] exponent, byte[] modulus) Calculate (base ^ exponent) % modulus. Constant Time.- Parameters:
base- big endian twos complement representation of the base (but it must be positive)exponent- big endian twos complement representation of the exponentmodulus- big endian twos complement representation of the modulus- Returns:
- big endian twos complement representation of (base ^ exponent) % modulus
- Throws:
ArithmeticException- if modulus <= 0
nativeModInverse
private static byte[] nativeModInverse(byte[] base, byte[] d) Compute the modular inverse of base modulo d.- Parameters:
base- big endian twos complement representation of the number to invertd- big endian twos complement representation of the modulus- Returns:
- big endian twos complement representation of the inverse
- Throws:
ArithmeticException- if the modulus is not positive or the inverse does not exist
nativeJbigiVersion
private static int nativeJbigiVersion()The jbigi version, only available since jbigi version 3.- Returns:
- the version number reported by the loaded native library
nativeGMPMajorVersion
private static int nativeGMPMajorVersion()The libmp major version, only available since jbigi version 3.- Returns:
- the major version number of the libmp the native library links against
nativeGMPMinorVersion
private static int nativeGMPMinorVersion()The libmp minor version, only available since jbigi version 3.- Returns:
- the minor version number of the libmp the native library links against
nativeGMPPatchVersion
private static int nativeGMPPatchVersion()The libmp patch version, only available since jbigi version 3.- Returns:
- the patch version number of the libmp the native library links against
fetchJbigiVersion
private static int fetchJbigiVersion()The jbigi version, fetched from the native library.- Returns:
- 0 if no jbigi available, 2 if version not supported
setVersions
private static void setVersions()Store the jbigi and libgmp versions. Call after loading. Sets _jbigiVersion, _nativeOk3, and _libGMPVersion.getJbigiVersion
public static int getJbigiVersion()The jbigi version, fetched from the native library.- Returns:
- 0 if no jbigi available, 2 if version info not supported
getLibGMPVersion
The libgmp version string.- Returns:
- "unknown" if no jbigi available or if version not supported
modPow
Compute base^exponent mod m using the native library.- Overrides:
modPowin classBigInteger- Parameters:
exponent- must be positivem- must be positive- Throws:
ArithmeticException- if m <= 0 or exponent <=0
modPowCT
Compute base^exponent mod m in constant time using the native library.- Parameters:
exponent- must be positivem- must be positive and odd- Returns:
- this value raised to the exponent modulo m, falling back to the variable-time computation when constant-time native code is unavailable
- Throws:
ArithmeticException- if m <= 0 or m is even or exponent <=0
modInverse
Compute the modular inverse of this value modulo m using the native library.- Overrides:
modInversein classBigInteger- Throws:
ArithmeticException- if not coprime with m, or m <= 0
toByteArray
public byte[] toByteArray()Cached byte array representation, filled in on first call.- Overrides:
toByteArrayin classBigInteger
isNative
public static boolean isNative()Whether native methods will be used by this class.- Returns:
- True iff native methods will be used by this class
loadStatus
Human-readable status of the native library load.- Returns:
- A string suitable for display to the user
getLoadedResourceName
The name of the library loaded, if known. Null if unknown or not loaded. Currently non-null only if extracted from jbigi.jar.- Returns:
- the loaded resource name
cpuType
Detected CPU type for jbigi optimization.- Returns:
- the detected architecture, or "unrecognized" if it could not be probed
cpuFamily
Processor family for the console info page, named the way a reader would expect rather than the way the jbigi library is named. The optimization name is imprecise at the top of the AMD range on purpose - zen3 is the newest tuned build, so a Zen 4 or Zen 5 part resolves to it - and "none" only says that no tuned build matched, which is not a processor to print.- Returns:
- the family name, or null if the processor could not be classified
amdFamily
Microarchitecture name for an AMD CPU, reported at the newest generation its compatibility flags support. The jbigi build stops at zen3, so the library name cannot tell a Zen 3 part from a Zen 4 or Zen 5 one - naming the library here would hide which chip the machine actually has.- Parameters:
cpu- the probed CPU, may be null- Returns:
- the generation name, or null if it is not a Zen CPU
familyFor
Display name for a jbigi optimization name, or null when the name carries no information about the processor - "none" only says that no tuned build matched. AMD is named from the CPU flags instead, byamdFamily(AMDCPUInfo). Package visible for testing.- Parameters:
type- the optimization name, or null- Returns:
- the family name, or null if there is nothing useful to show
cpuModel
loadNative
private static final void loadNative()Do whatever we can to load up the native library backing this BigInteger's native methods. If it can find a custom built jbigi.dll / libjbigi.so, it'll use that. Otherwise it'll try to look in the classpath for the correct library (see loadFromResource). If the user specifies -Djbigi.enable=false it'll skip all of this.
Load order (using linux naming with cpu type "xxx") - filesystem libjbigi.so - jbigi.jar libjbigi-linux-xxx_64.so - jbigi.jar libjbigi-linux-yyy_64.so 0 or more other alternates - jbigi.jar libjbigi-linux-none_64.so
Only 64-bit native libraries are shipped.debug
Log a native math debug message.- Parameters:
s- the message to log
info
Logs an informational message about the library load.- Parameters:
s- the message to log
warn
Logs a warning about the library load.- Parameters:
s- the message to log
warn
error
error
loadGeneric
Try loading it from an explicitly build jbigi.dll / libjbigi.so first, before looking into a jbigi.jar for any other libraries.
- Parameters:
name- the library name to load, null means do nothing- Returns:
- true if it was loaded successfully, else false
loadFromResource
Check all of the jars in the classpath for the file specified by the environmental property "jbigi.impl" and load it as the native library implementation. For instance, a windows user on a p4 would define -Djbigi.impl=win-686 if there is a jbigi.jar in the classpath containing the files "win-686", "win-athlon", "freebsd-p4", "linux-p3", where each of those files contain the correct binary file for a native library (e.g. windows DLL, or a *nix .so).
This is a pretty ugly hack, using the general technique illustrated by the onion FEC libraries. It works by pulling the resource, writing out the byte stream to a temporary file, loading the native library from that file. We then attempt to copy the file from the temporary dir to the base install dir, so we don't have to do this next time - but we don't complain if it fails, so we transparently support read-only base dirs.
- Parameters:
resourceName- the resource to load, named by the "jbigi.impl" property, null means do nothing- Returns:
- true if it was loaded successfully, else false
getResourceList
Generate a list of resources to search for, in-order. SeeloadNative()comments for more info.- Returns:
- non-null
getMiddleName2
The middle part of the native library name, based on the CPU type.- Parameters:
optimized- true to use the detected CPU type, false for the generic "none" library- Returns:
- may be null if optimized is true
getMiddleName1
The middle part of the native library name, for a non-optimized library.- Returns:
- may be null if optimized is true; returns jbigi-xxx-none if optimize is false