I’ve posted quite a few times now, about Lithium-Ion Batteries, without ever answering the question of how Lithium-Ion *Polymer* Batteries differ. And I think that I should write a posting about that subject, which this time around, will contain no links to other articles.

My previous postings assumed that standard, lithium-ion batteries are being examined, which were not of the polymer variety, but those postings did mention plenty of possible electrode materials. Well, batteries are not solely defined by their electrode materials, but are sometimes defined as much, by the choice of electrolyte which Engineers put their trust in.

In a standard, lithium-ion battery, most of the time, the electrolyte needs to be kept under pressure, in order to be liquid. In fact, this means that the standard battery variety also has a pressurized container around it, from which its electrodes are insulated electrically, but that adds bulk. The electrolytes in question are not acids, as was once the case with lead – lead oxide batteries, but are very flammable.

In a polymer-variety battery, *the electrolyte* is the polymer, but the same assortment of electrode materials is still available. The favorite composition for *the positive electrode* seems to be *lithium-iron-phosphate*. Because the electrolyte is the polymer, it counts as a solid, which does not need to be kept under pressure, and through which lithium ions *effuse*, even though this solid is also flexible. As soon as this option presents itself, it creates advantages on two fronts:

- Energy-to-mass ratio,
- Safety.

1) One benchmark by which progress in advanced batteries is measured, is whether they can achieve an equal or greater energy-to-mass ratio, to that of gasoline burning in air. And the answer to that question is that the electrode materials often can, but that when the mass of the pressurized container is taken into account, this ratio is no longer achieved. Since the polymer-variety batteries do not need such a container, they can be made lightweight enough, to achieve this ratio. And this is especially true, if the material of the positive electrode, *is* lithium-cobalt-oxide, which is also known to hold the highest charge densities. But, this would no longer be the safest electrode-material to use.

2) When a standard-variety battery does in fact fail, not only can the electrolyte catch fire, but inevitably, the pressurized container also breaches, which means that burning liquid shoots out. A polymer-variety battery can fail in the same way. But at least, when it does, it will not act as a flamethrower. A polymer-variety battery could become red-hot and then charred, can emit smoke, but still won’t be as dangerous as the standard-variety battery was.

Now I suppose that the question could be asked separately, of whether the standard lithium-ion batteries are at increased risk of erupting on airplanes, because the cabin-pressure decreases. And my answer would be, ‘Not, if the designers of the pressurized container knew what they were doing.’ There is a slight increase in relative pressure, just because the exterior pressure decreases, but this should not be enough to breach the container. Breaches tend to happen for thermal reasons – i.e., because batteries become overheated.

But the people who manage airline flights will flag any type of item that could catch fire, simply because a fire in the passenger cabin of an airplane in-flight, is especially dangerous. Appliances that caught fire on airplanes, typically also caught fire on the ground…

One mistake which some people may make, is to assume that all Lithium-Ion Polymer Batteries, are flexible batteries. This is an easy mistake to make, because most polymers are flexible. But of course, as long as the only part of the battery which is a polymer is the electrolyte, what follows is that the composition of either electrode could still be rigid.

The concept of flexible batteries also exists, but is separate from the concept of Li-Ion batteries of either type.

What has become deprecated, is the use of a metallic lithium negative electrode. It’s been replaced in almost 100% of all cases by graphite, which is able to store lithium ions. This change has cost each battery about 0.2V of resulting voltage. Or, it has eased the voltage with which each battery must be charged, reducing it, by 0.2V .

But graphite is not really flexible either.

Dirk

]]>

I’ve known some people who had the preconceived idea, that in general, batteries would generate – or produce – a voltage of 1.5V, and whose main distinction was either between battery formats, or brand-names. This idea would imply that those people had no exposure to The series of electrode potentials which all elements and most compounds have, relative to hydrogen. Different electrode potentials lead to different battery potentials, as long as the latter are taken separately, for the positive and the negative electrode.

But additionally, Engineers had an early goal, of supplying 1.5V batteries, which could act as direct drop-in replacements, for Carbon-Zinc batteries, where the carbon or manganese-oxide powder actually act as a hydrogen electrode, but which would provide much higher amounts of charge, before becoming passive. And so somewhere along the way, they also designed 1.5V lithium-based batteries, that could not be recharged. Considering that lithium itself has an electrode potential of about -3V, the only way in which this could be realized, was in a composition being chosen for the positive electrode, which offset some of those 3V, *against* the efficient generation of electricity.

In other words, these batteries wasted some of the energy which lithium offers as a fuel, just to arrive at less than 3V battery voltage. And closer examination of that subject should reveal, that *some choice of metal* was likely, as a *positive* electrode. But this is easily doable, as many metals will absorb the element lithium, yet have some electrode potential of their own, near -1.5V . Either Zinc or Manganese in their metallic form should work.

Dirk

]]>

I have visited this subject before, but feel that I should post about it again.

The way Lithium-Ion batteries first became popular, they either had metallic lithium, or graphite as their negative electrode, and lithium-cobalt-oxide as their positive electrode. This stored much energy, but also presented an initial cause for alarm, especially since some of the then-new batteries were prone to catch fire, when over-charged. In response, there existed a trend followed by some companies and manufacturers, to switch to lithium-manganese-oxide, either in the layered or the spinel form, as the next-best positive electrode. ( :2 )

It would seem that the lithium-cobalt-oxide batteries produce 4.2V when fully charged, while the lithium-manganese-oxide batteries only produce 3.7V when fully charged ( :1 ) , and the latter battery-type was deemed ‘safer’.

Additionally, there exists a battery-type which has *lithium-iron-phosphate*, which is even safer than the 3.7V batteries, and which only produces 3.6V when fully charged. This third family of batteries is used in Segways and some electric cars, where it would be exceptionally unfortunate if the batteries could explode, simply due to a traffic accident – a hypothetical collision.

*All the voltages which I’m citing here are against a lithium-graphite negative electrode*.

What seems to have happened – and I don’t have proof – would be called a ‘trend reversal’. Some manufacturers have switched back to using the lithium-cobalt-oxide batteries, simply because those store more energy.

Why do consumers need to know this? So that they don’t place 3.7V batteries – which are labeled identically to the other type – into 4.2V chargers, *and leave them there*. That’s all.

I suppose that a valid question which some readers might have would be, ‘What has become of the safety / over-charging issue?’ And my answer would be that *most of* today’s charging circuits have become ‘smarter’, and less prone actually to over-charging the batteries. The best example of this is the smart-phone. However, if some people buy separate batteries for ‘Vapers’, then those devices have a reputation of ‘no charging intelligence’, i.e., of sometimes over-charging the battery.

The typical behavior of a dumb charger is, to ‘Apply a constant voltage of 4.2V, and when the current which the battery draws falls below a certain amount of current, give an indication that the battery is fully charged. *But keep applying 4.2V, even after the LED has changed color*.’ The lithium-manganese-oxide batteries will also tolerate such charging voltages for brief periods of time. And the lithium-cobalt-oxide batteries will realize their maximum held charge that way.

The thing not to do, is to keep whichever batteries in their *dumb* charger for long periods of time, after the LED indicates they are charged.

I also want to add, that this posting is meant to voice an issue, with the low-budget lithium-ion batteries, in the modern era. I understand that high-budget, big-ticket items exist, such as…

(Updated 10/21/2018, 22h55 … )

(As of 10/17/2018 : )

According to the latest WiKiPedia article, “lithium-nickel-manganese-cobalt-oxide” has been proposed since 2008. In reality, I just see this as a compromise between the manganese-oxide and the cobalt-oxide compositions. ( :4 )

How would this help a small-time consumer understand the labeling of individually bought, online-bought 18650 batteries, not to put in his 4.2V charger?

(Update 10/18/2018. 13h50 : )

I suppose that this observation raises the potential question, of what happens if, a smart-phone contains ‘safer’ lithium-manganese-oxide electrodes, but if its charging circuit raises the battery-voltage all the way to 4.2V. And after some consideration I’ve concluded that very little happens, except for the possibility, that as soon as charging has stopped, the battery voltage will seem to drop from that 4.2V target very quickly, even though very little charge or current has been drawn from the battery. This will also result in the charge-indicator dipping below 90% much faster, than it will later dip from 70%-60%…

The real problem I see happening, would be if the smart-phone contained lithium-cobalt-oxide batteries, let’s say ‘just because the manufacturer wanted to increase the battery capacity’, and if the charging circuit did the same thing. In that case, to leave the lithium-cobalt-oxide batteries continuously connected to 4.2V may eventually lead to the famous problem, ‘of their catching fire’.

(Update 10/18/2018, 21h45 : )

1: )

I suppose that for people who are not familiar with concepts in Electronics, I should add that voltage and current are two separate parameters, and charge is more-closely related to current, than it is to voltage.

When people loosely say, that a battery operates ‘at a specific voltage’, such as ‘at 3.7V’, what this means can confuse some people. What this really means is, that at voltages close to 3.7V, the charge of the battery changes the fastest, and that due to voltage-changes near such a voltage, the amount of current that flows will be greatest. The result should be a sideways s-shaped curve…

Thus, even if a battery that functions most-efficiently at 3.7V is over-charged modestly, all it really means, is that due to further voltage-increases, its charge-level changes *progressively less*. It’s only due to more-considerable over-charging, that a stable battery will fail.

However, it would be hypothetically possible to have a battery-type the charge-level of which just keeps increasing with voltage. While some people would see this as an unstable device, other people might just see it as an opportunity, to store more and more energy.

(Update 10/19/2018, 6h10 : )

I suppose there’s another observation to add. If the composition of the positive electrode, when discharged, Is LiCoO_{2}, then it follows that this electrode only has a limited number of Lithium Ions to shed. This implies that:

- The total amount of charge that such a battery can store, regardless of the hypothetical curve above, has a definite limit,
- According to conventional wisdom, the material is only allowed to shed 1/2 its lithium ions, before its composition changes irreversibly,
- CoO
_{2}is not only oxidized, but is itself a chemically active oxidizer, which will donate oxygen to the electrolyte, and thereby start the reaction, where the battery catches fire, - If a derived electrode material is to be found that can actually shed a higher fraction of its available lithium ions safely, then this would need to be a material which without, also fails to become an active oxidizer.

(Update 10/20/2018, 22h40 : )

2: )

One fact which had originally caught my attention, was that The lithium-manganese-oxide batteries come in two varieties: Spinel and Layered, in the order of discovery. Regardless of what the voltage-curves are, according to the article just linked to, a major difference between these two crystal structures is that, the spinel variety has as formula LiMn_{2}O_{4}, while the layered variety has as formula Li_{2}MnO_{3}. What this also suggests, is that *some advanced* variety can potentially shed twice as many lithium ions, more or less, than the spinel variety. ( :3 )

This could be of interest to the manufacturers of high-budget devices such as smart-phones, which could benefit by storing twice the charge of earlier smart-phones.

But if a seller of separate batteries had as their aim, to mislabel the batteries they sell, such as at the low-budget end of the market, then this can give them plausible deniability. The reason for this would be, that achieving twice the charging capacity of a simpler type of battery, could now have two explanations, at least as long as this detail is not mentioned in the labeling of the battery:

- The battery sold could be
*an advanced*, lithium-manganese-oxide battery, or, - The battery sold could be a lithium-cobalt-oxide battery.

Both would seem to hold approximately twice the charge, that the spinel, lithium-manganese-oxide battery was able to hold. The consumer would not know, what he’s getting.

(Update 10/20/2018, 22h40 : )

3: )

I suppose that a legitimate question to ask next might be, ‘How can one estimate how much energy a battery with a given Chemistry stores?’

And then one observation to note would be, that most of the battery’s voltage stems from the (negative) electrode potential of the lithium, where all the electrode voltages are given relative to hydrogen, for which reason very little of the battery-voltage is in fact decided by the positive electrode. There could be some differentiation, but it would be minute.

*When a reference article states a voltage of 4.5V, relative to metallic lithium, this is just equivalent to 4.3V, relative to lithium-graphite*.

And so the next factor to estimate, would be how much volume one mole of the material, of the positive electrode, occupies. And for that purpose, I’d treat oxygen atoms as though they were equivalent to the transition-metal atoms – even though Chemically, they’re very different. In a regular crystal, either type of atom will occupy approximately the same amount of space. And so I’d add the number of transition-metal atoms, to the number of oxygen atoms, and the result I’d get would be:

- LiMn
_{2}O_{4}-> 6 units of volume. - Li
_{2}MnO_{3}-> 4 units of volume. - LiCoO
_{2}-> 3 units of volume.

Even though this estimation is only very coarse, it puts the energy densities in the correct order.

I would add, *If Pure* Li_{2}MnO_{3} was to undergo a reaction in which it loses its second lithium ion, it would do so at a higher electrode voltage, from the voltage, at which it lost its first. An ability to do so would also imply the existence of manganese-trioxide, which does not exist as a known, stable substance.

But then, in the case of the advanced, lithium-manganese-oxide composition:

- LiMn
_{2}O_{4}· Li_{2}MnO_{3}-> 10 units of volume, yielding up to 3 available lithium ions (?) , as opposed to 6 units of volume, yielding up to 1 available lithium ion.

(Update 10/21/2018, 14h30 : )

4: )

If the electrode material is to be taken seriously, which I named lithium-nickel-manganese-cobalt-oxide, there are two observations to take into account:

- Every time the resulting crystal possesses a manganese atom, it basically replaces a cobalt atom. Every time it possesses a nickel atom, that atom replaces either a manganese or a cobalt atom.
- The actual nickel atoms do not contribute directly, to the ability of the crystal to offer lithium ions to the battery. They only improve the stability of the crystal, and maybe enable for the first time, cross-linking between manganese and cobalt atoms.

I seem to recall that a lithium-nickel-cobalt-oxide battery existed, earlier than the actual lithium-cobalt-oxide battery. The introduction of the latter type actually did away with the presence of nickel atoms, and increased the total amount of lithium ions the electrode could offer. Doing so may also have reduced the stability of the batteries in question.

Dirk

]]>

One of the conventions which I was taught when first learning C++, was that, when declaring an integer variable, the designations were to be used, such as:

```
short int a = 0; // A 16-bit integer
int b = 0; // A 32-bit integer
long int c = 0; // Another, 32-bit integer
```

But, since those ancient days, many developments have come to computers, that include 64-bit CPUs. And so the way the plain-looking declarations now work, is:

```
short int a = 0; // A 16-bit integer
int b = 0; // A 32-bit integer
long int c = 0; // Usually, either a 32-bit or a 64-bit, depending on the CPU.
long long d = 0; // Almost always, a 64-bit integer
```

The fact is not so surprising, that even on 32-bit CPUs, modern C++ runtimes will support 64-bit values partially, because support for longer fields, than the CPU registers, can be achieved, using subroutines that treat longer numbers similarly to how in Elementary School, we were taught to perform multiplication, long division, etc., except that where people were once taught how to perform these operations in Base-10 digits, the subroutine can break longer fields into 32-bit words.

In order to avoid any such confusion, the code is sometimes written in C or C++, like so:

```
uint16_t a = 0;
uint32_t b = 0;
uint64_t c = 0;
```

The ability to put these variables into the source-code does not pose as much of a problem, as the need which sometimes exists, to state literals, which can be assigned to these variables. Hence, a developer on a 64-bit machine might be tempted to put something like this:

```
uint64_t c = 1L << 32;
```

Which literally means, ‘Compute a constant expression, in which a variable of type (long) is left-shifted 32 bits.’ The problem here would be, that if compiled on a 32-bit platform, the literal ‘1L’ just stands for a 32-bit long integer, and usually, some type of compiler warning will ensue, about the fact that the constant expression is being left-shifted, beyond the size of the word in question, which means that the value ‘0’ would result.

If we are to write source-code that can be compiled equally-well on 32-bit and 64-bit machines, we really need to put:

```
uint64_t c = 1ULL << 32;
```

So that the literal ‘1ULL’ will start out, as having a compatible word-size. Hence, the following source-code will become plausible, in that at least it will always compile:

```
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char* argv[]) {
long int c = 1234567890UL;
if (sizeof(long int) > 7) {
c = (long int) 1234567890123456ULL;
}
cout << c << endl;
return 0;
}
```

The problem that needed to be mitigated, was not so much whether the CPU has 32-bit or 64-bit registers at run-time, but rather, that the source-code needs to compile either way.

Dirk

]]>

The fact that blood plasma exists in Medicine, should not be confused with the fact that Plasmas exist, that are defined in Physics, and which all matter can be converted to. In short, a Plasma is what becomes of a gas, when its temperature is too hot, for it to be a gas.

The long form of the answer is a bit more complex. In Elementary School, Students are taught that there exist three familiar phases of a given substance: Solid, Liquid and Gas. But according to slightly more advanced knowledge in Physics, there is no real guarantee, that there will always be these three phases. A gas first results when the thermal agitation between molecules becomes stronger – i.e. their temperature hotter – than the force that holds individual molecules together. At that point, the molecules separate and a gas results, the physical behavior of which is approximately what one would obtain, if a swarm of particles was to exist through collisions but through few other interactions.

Similarly, Liquids will form, when the molecules are forced from occupying fixed positions, but when they still don’t expand.

Well, as the degree of thermal agitation (of a Gas) is increased further, first, molecules become separated into atoms, and then, the electrons get separated from their nuclei, as a result of ordinary collisions with other atoms. This results in the negative particles – electrons – following different trajectories than the positive particles – the nuclei. And the result of that is that the collective behavior of the fluid changes, from that of a gas.

When a charged particle crosses the lines of force, of a magnetic field, a force is generated which is perpendicular to both the velocity vector and the magnetic field vector. As a result, the particles can travel without restriction along the lines of magnetic force, but their motion at right angles to it is deflected, and becomes helical. Not only that, but the direction in which the paths of the particles becomes curved, is opposite for the negative and positive particles.

For this reason, Plasmas can be confined by magnetic fields, except along the lines of the magnetic field. Increasing the strength of an applied field will also cause a Plasma to become compressed, as these helices become narrower.

A good natural example of this type of Plasma, is what becomes of the substance of the Sun. Its temperatures are easily hot enough to cause the transition from Gas to Plasma, especially since the temperature inside the Sun is much higher, than the temperatures which are observed at its surface. At 5000K, gasses are still possible. But at hundreds of thousands Kelvin, or at a Million degrees Kelvin, the bulk of the Sun’s substance becomes a Plasma.

Now, if the reader is a skeptic, who has trouble believing that ‘other phases’ can exist, than Solid, Liquid and Gas, there is an example that takes place at lower temperatures, and that involves Oxygen, namely, O_{2}. We’re aware of gaseous O_{2} as well as liquid O_{2} that gets used in rocketry. But as the O_{2} is cooled further, to 54.36K at 1 atmosphere, it solidifies. Thus, it has already demonstrated the 3 phases which we’re taught about in Elementary School. But, if we cool already-solid O_{2} below an even lower temperature, 43.8K at 1 atmosphere, its phase changes again, into yet another phase, which is also a solid one. It’s currently understood that solid O_{2} has 6 phases. (:1)

At the same time, many fluids are known to exhibit Supercritical Behavior, which is most commonly, a behavior of a fluid which is normally differentiated between Liquid and Gaseous, *losing this differentiation*, due to its critical pressure being exceeded, but at temperatures at which fluids are commonly boiled. This has nothing to do with Plasmas, but without any distinction between Liquid and Gaseous, a substance which is ordinarily though to have three phases – such as water – ends up demonstrating only two: Fluid and Non-Fluid.

So there is no ultimate reason for which matter needs to be in one out of three phases.

(Updated 10/14/2018, 10h25 … )

(As of 10/13/2018 : )

Also, failures of Science to control Fusion, are not due, to a failure to contain Plasmas with magnetic fields. They are failures to keep doing so, at temperatures and pressures – i.e., field intensities – needed to achieve fusion, i.e., at millions of degrees Kelvin. The reason for this is the fact that Plasmas generate a spontaneous field, in reaction to the applied field, such that the spontaneous field can become more intense than the applied field. Under fusion conditions, this makes the Plasmas uncontrollable, and their spontaneous field forms ‘kinks’ in the (self-)contained plasma, the geometry of which breaches the intended apparatus. Such a breach has only minor consequences to the apparatus and the people near it, but also causes a failure to harness fusion.

When experiments to control fusion were still ongoing, most of the focus was on active electronics, that would sense the onset of these kinks, and the purpose of which was to counteract them – by changing the applied field quickly – before they would become pronounced. But precisely because not all feedback-systems are stable, those efforts failed.

Further, so-called ‘low-temperature plasmas’ also exist, the ionic nature of which is not directly due to thermal agitation, but which is due to some other form of excitation, such as just, an intense, applied electrostatic field. This type of plasma is also called an ‘arc’, or an ‘electric spark’, and even though its temperatures may be lower than those of fusion plasmas, this form of plasma still exhibits the essential property, that magnetic fields will deflect it. Further, I think that the Earth’s radiation belts are also examples of low-temperature plasmas.

Further examples of one substance occupying more than 3 phases exist in the element sulfur (in its Chemically pure form). Under ambient conditions, sulfur forms ringed molecules of S_{8}, that give a solid, yellow crystalline phase. But if we try experiments which I remember clearly out of my childhood, to melt sulfur will typically result in an orange liquid forming briefly, which then quickly forms a brown polymer. Next, allowing the polymer to cool off fails to undo this second phase-change, until leaving the polymer at room temperature for more than a minute, causes it to revert to the yellow crystals one started with.

These apparent phases of sulfur could be argued, because they form when the rings of S_{8}, that have successfully become a liquid, break open, and join with other chain-fragments, forming the longer chains that tend to define a polymer. So somebody could claim that this is a Chemical change and not a Physical change. But unfortunately, Chemistry and Physics are ultimately linked. They are both descriptions of matter near the atomic scale, and in the case of sulfur, descriptions involving only one element.

And logically, if we were to heat sulfur sufficiently, *in the absence of oxygen*, chain-fragments would also break away, to form a compressible, though horrid gas-like phase.

This failure of pure sulfur to form a stable liquid affects how it needs to be mined. One process which I’m familiar with is excavation of deposits at the surface of the Earth. A different process I’m familiar with involves injecting steam into sub-surface sulfur deposits, that causes the sulfur to melt. Because simple valves can control the pressure of steam very accurately, simple valves at the surface can also control *its temperature* very accurately, such that the sulfur remains liquid long enough to flow out of the mining site.

(Update 10/14/2018, 10h25 : )

Even though other fluids can exhibit a supercritical point, the most-studied case is water. And one idea which I mentioned, was that if the pressure of some substance is supercritical, it will really only exhibit fluid and non-fluid phases.

There is a problem when trying to characterize water in this way. It has the unusual property of expanding when it freezes. What this also means is that extreme pressure will prevent water from freezing, or from staying solid. This is the main reason for which ice-skates work: Their knife-edge will put high pressure on the ice, so that the ice briefly melts beneath the skates. And this is why skates exhibit such a low coefficient of friction. It’s an everyday phenomenon.

But this can also cause water to fail, at entering a solid phase, when under extreme pressures, which are then also supercritical. So then, it would really only demonstrate one phase, not two.

If the subject was Supercritical Methanol, this oddity would vanish.

1:)

Technically, it would be incorrect to refer to *all* the solid phases of Oxygen, as ‘forms of O_{2}‘. The reason for this is the fact that this designation implies the existence of actual O_{2} molecules, which will only exist if the solid is ‘a molecular solid‘. Because some solid forms of Oxygen are *covalent solids*, they should just be referred to, as ‘additional forms of *Oxygen*‘. And I see that the *metallic solids* are classified unto themselves.

Dirk

]]>

One of the problems people may face in Computer Science, is a CPU only capable of computing a logarithm in one base, say 2, but the need to compute a logarithm in another base, say (e). The way to convert is as follows:

c log_{2}(t) == log_{b}(t)

If (t == b), it follows that:

c log_{2}(b) == log_{b}(b) == 1

Hence,

c = 1 / log_{2}(b)

Dirk

]]>

In recent days I wrote some Python scripts, which generate 1024-bit prime numbers. But the next stage in my own thinking is, to try to accomplish the same thing in C++, using the GMP Multi-Precision Library, because GMP seems to be a well-supported and overall favorite C++ Multi-Precision Librrary. But when I explored this subject further, I noticed something which surprised me:

GMP is still using the ‘Linear Congruent algorithm’, as its main source of strong, pseudo-random numbers. The reason this fact surprises me is the fact that the Linear Congruent algorithm was invented as early as in the 1970s, as a cheap way to achieve pseudo-randomness, that would be good enough for games to surprise players, but which was never meant to provide crypto-quality random numbers. Actually, back in the 1970s, the registers on which this algorithm was used, may have been 16-bit or 32-bit registers, while today they are 256-bit registers, for which reason a careful and random-looking choice for the two constants is important. In fact, GMP defines the following functions, to initialize a ‘state_t’ object, to become a Linear Congruent RNG:

int gmp_randinit_lc_2exp_size (gmp_randstate_t state, mp_bitcnt_t

size)

void gmp_randinit_lc_2exp (gmp_randstate_t state, const_mpz_t a,

unsigned long c, mp_bitcnt_t m2exp)

For people who did not know, the generality of the algorithm is:

m2exp == 2 * size

X := aX + c mod 2^{m2exp}

The first of the two initializations above uses the ‘size’ parameter, in order to look up in a static, known table, what the ‘ideal’ values for the constants (a) and (c) are, to achieve maximum randomness. The second initialization allows the programmer to specify those constants himself, and poses no restrictions on what ‘m2exp’ will be.

One of the first approaches a cryptographic programmer might want to pursue, in order to generate a prime number eventually, is to read some random bits from the device-file ‘/dev/random’ (on a Linux computer), use the first initialization above, which will lead to an RNG, and then seed this RNG once from the system-provided random number, with which the programmer can then suggest both prime candidates and witnesses to determine whether the candidates are prime, until one prime number is ‘proven’.

But I see a potential ambition for any programmer who may want to go that route:

- Given that (a) and (c) are to be chosen from a known table, this presents a vulnerability, because a hypothetical attacker against this crypto-system may use these constants to gain knowledge about the internal state of the ‘state_t’ object, and therefore become aware of a limited number of prime numbers that can result, thereby narrowing his attack against eventual public keys, by only trying to prime-factorize or otherwise decrypt, using the narrowed set of primes.
*Even if*the constants (a) and (c) are secure in nature and not themselves hacked, the table presently only extends to a ‘size’ of 128 bits, which will actually mean that the modulus ‘m2exp’ is 2^{256}. And so, ‘the maximum amount of randomness’ – i.e., the Entropy – which even a 2048-bit public-key modulus can achieve, will be 256 bits. And this would also mean that the strength of the key-pair is*only*equivalent to a 128-bit, symmetrical AES key, regardless of how complex it is.- Some programmers might actually want to work with a modulus of 2
^{512}.

At the same time, there are reasons why the obvious solution, just to read all random bits from the device-file ‘/dev/urandom’, poses its own problems. One of the reasons is the fact that potentially, 300 (+) prime-number candidates may need to be generated, each of which will be 1024 bits long, and tested 200 (+) times, and that the quality of the randomness ‘/dev/urandom’ provides under those conditions may also be sub-optimal, because that source, too, is pseudo-random, and will only become minimally based on the physically-measured randomness which ‘/dev/random’ represents. And yet, ‘/dev/random’ will typically block if more than ~2048 bits are to be read from it.

I can think of an approach to solving this problem, which may overcome most of the hurdles…

(Updated 10/13/2018, 13h10 … )

In addition to the ‘Linear Congruent algorithm’, GMP offers the ‘Mersenne Twister algorithm’, which is known to be insecure, but which nevertheless provides some layer of randomization, and which is fast to compute. Its period of repetition still greatly exceeds the number of times any one prime-number candidate will be tested. The way such an RNG is initialized with GMP is like this:

void gmp_randinit_mt (gmp_randstate_t state)

What I would suggest should happen is, that first, two ‘state_t’ objects should be created, named ‘rng1′ and ‘rng2′. rng1 should be initialized as a Mersenne Twister RNG, using the third of the function prototypes I provided above. Then, a custom-function can be made to read the desired number of random bits (*i.e., 512*), from ‘/dev/random’, and only once per prime number generated. These bits can be referred to as the ‘global_seed’, and should be used to seed ‘rng1′. Then, the second prototype above – the one that requires the programmer provide the constants (a) and (c) – can be used to initialize the object named ‘rng2′, to the Linear Congruent algorithm. The value of (a) required to do so can be a *quantity of 512 bits* output from ‘rng1′, but should be OR’ed bit-wise, with the numeral (1) before being used as (a).

(5 626 616 701 960 718 857) could simply be used as (c). It’s a 63-bit prime number. And finally, the previously-read ‘global_seed’ can be used again, to seed ‘rng2′.

After that, the programmer can go about his business, of providing prime-number candidates, always using ‘rng2′, but then testing each candidate in a function, that uses ‘rng1′ to determine the witnesses, within the required ranges, to test the primeness of the generated candidates as many times as needed. This can take place, as usual, until a candidate is sufficiently attested to being prime. (:2)

One fact which has been observed about the Linear Congruent algorithm is, that its lower bits exhibit poor randomness. For this reason, when random numbers are actually generated, only the higher half of the available modulus is used. If the number of bits requested exceeds (m2exp / 2), the function simply invokes itself several times, and concatenates the results.

For such reasons, and the fact that the degree of randomness will reach an eventual limit in spite of best efforts, I wouldn’t recommend a ‘m2exp’ of more than 512 bits. Also, 512 bits will deplete the computer’s entropy pool less, to seed, than say, 1024 bits would.

(Update 10/06/2018, 18h50 : )

About the Mersenne Twister algorithm, I must admit that I do not know for the moment, how exactly it works. But there is an article about it, which was written in the context that the language Python was being used, which gave me some brief overview about the algorithm.

A key statement in this article is:

>>>

The Mersenne Twister is one of the most extensively tested random number generators in existence. However, being completely deterministic, it is not suitable for all purposes, and is completely unsuitable for cryptographic purposes.

<<<

The question which this statement poses is, in the context of pseudo-random numbers, ‘What constitutes a completely deterministic random-number generator? Aren’t they all deterministic by nature?’ And so I would offer another observation to answer that question:

As far back as the 1960s, a method was suggested to generate pseudo-random numbers, which stated to ‘Square the previous random number, and then to take the middle of that square, as the next random number.’ In other words, if 32-bit random numbers were needed, square the last one, right-shift the resulting bits by 16, and put everything back into the modulus of 2^{32}.

The problems with this approach do not include, that the next state of the generator, would be totally dependent on the previous state. *All* the pseudo-random number generators have *that* as a property. The real problem with this ancient suggestion would be twofold:

- It makes the actual state of the generator visible in every random number it outputs,
- It seems to lack another variable. Each output depends on the previous output, but not on arbitrary constants such as (a) or (c) above. Therefore, all the outputs are predictable from just knowing one previous output.

Additionally, there was a weakness in how some, low-quality random number generators used to work back in the 1970s, IIRC, which was that the Linear Congruent method was being used, but instead of only outputting the higher half of the state, the entire 32-bit register was output each time. And so a problem which still existed was:

- It makes the actual state of the generator visible in every random number it outputs.

Not only that, but if a small range of integers was actually required, such as a choice between 4 from [0 .. 3], because the most-standard way in which those could be determined from a 32-bit integer was:

out = X mod 2^{2}

The values of (‘out’) actually generated were impacted, by how low-quality the randomness of the least-significant bits of (X) were. Thus, it might have actually made more sense back then to compute:

out = X // 2^{16} mod 2^{2}

Really, the main reason *I’d* have not to use the Mersenne Twister algorithm, to suggest prime-number candidates would be, that because the version of it which I’m familiar with, only generates 53-bit floats as its basis, which means that if a number 1024 bits long was requested, this algorithm would probably only be trusted to produce a 32-bit integer in one shot, and *would need to be* asked to do so, 32 times, just so that the concatenated result was a 1024 bit suggestion. And if one accepted that, one could just as easily accept a Linear Congruent generator, that had been initialized with (size = 32). Since this posting assumes that (size = 128) *is not good enough*, there is no reason to think that (size = 32) would be good enough.

Further, if the implementation of the Mersenne Twister algorithm was *low-quality enough*, this floating-point number might simply be multiplied by the range *once*, the floor function applied, and any lowest value in the requested range added to the result. (:1) And I guess that in that case, the unsuitability for cryptographic purposes would be obvious enough.

That would mean, that if a random number was going to be picked out of a 1024-bit range, then the resulting ‘stride’, between integers that could possibly be selected, would actually be on the order of ~2^{971}. *Odd as well as even integers should still end up being selected*. But, because I have already concluded that *some* 1024-bit numbers were prime, simply by performing 256 tests on them, I’m not sure that my probabilistic method of doing so would become any stronger, if the entire 1024-bit range became available, as witnesses, for testing. (:3)

(Update 10/08/2018, 0h30 : )

1:)

The way in which such a computation would be carried out using GMP is probably different, from how it might be done using Python. It could be that (a ∈ [2 .. n-1]) can be used as a witness to test whether (n) is prime. The methods available in Python make this painless to achieve. But using GMP, if the range of the integer output is [0 .. n – 1], then a direct porting of the previous method would involve subtracting (2), performing the pseudo-random number generation, and then adding (2) to the result again. In this multi-precision arithmetic, addition or subtraction of even trivial numbers such as (2) to and from 1024-bit numbers, costs significant CPU operations. In addition, these subtractions and additions might need to be performed, for every witness (a) chosen.

Using GMP, it might actually make more sense to apply:

```
a = 0
while (a ≤ 2^32) { choose a ∈ [0 .. n) }
choose b ∈ [0 .. 2^32)
a -= b
```

I suppose that when (a) initially results as less than or equal to (2^{32}), this wastes some time. But if we can assume that (n ~= 2^{1024}), this will only happen infrequently, so that as many witnesses are chosen, this latter approach is more likely *to save* time.

(Update 10/06/2018, 20h40 : )

2:)

There would be an additional observation to make about this approach. The possibility, however slim, could arise, that the value of (a) used to seed ‘rng2′ could be such, that no actual prime numbers can result from that instance of ‘rng2′, even though it is capable of producing candidates. In such a case, because ‘rng2′ is still generating values that were only seeded once, from the system’s ‘real’ source of entropy, an eventual need might arise to query ‘/dev/random’ again, and thus to reseed everything, if the count of failed candidates exceeds some threshold.

And so a useful parameter to know, would be what the average number of attempts should be, to find a prime number of length (n) in bits. It has been stated that for an integer (m), the probability of primeness is ( 1 / ln(m) ). But since the number of bits needed to store an integer (m) is already (log_{2}(m) == n), the answer to that is ( ½n ln(2) ) attempts, where ( ln(t) ) expresses the natural logarithm of (t), assuming that only odd numbers are resulting in candidates, and assuming that the only reason for rejection, was provable non-primeness. This reflects a base-change in the logarithm. Hence, the threshold to set might be ( n ln(2) ) attempts.

When (n = 1024), this would be a threshold of (710).

(Update 10/08/2018, 7h10 : )

3:)

As is often the case, there exists A WiKiPedia Article, About the Mersenne Twister algorithm. This article offers further insight.

While the article describes the algorithm as using a 32-bit or a 64-bit integer, often, such integers can be presented as binary fractions, by actual implementations, which are in turn output as floating-point numbers. Therefore, I see no contradiction really in what this article writes, and what the earlier article wrote about the Python implementation. The earlier article seemed to suggest, that it had as its basis a 53-bit, double-precision floating-point number. But it might just as easily only have been using the 32 MSBs of that floating-point number.

If I was to guess that the version of the Mersenne Twister algorithm used by GMP had a 64-bit basis, instead of a 53- or a 32-bit basis, *If a single iteration* of this algorithm was used to generate an integer in the range of [0 .. 2^{1024}), it would just mean that the stride between possible outputs would become (2^{960} integer values).

I now think that with GMP the programmer can choose whether he or she wants a single iteration of this algorithm, or multiple iterations to be applied, by selecting which of the following two functions to use, when generating actual output:

void mpz_urandomm (mpz_t rop, gmp_randstate_t state, const_mpz_t n)

void mpz_urandomb (mpz_t rop, gmp_randstate_t state, mp_bitcnt_t n)

If the version used in GMP was the 64-bit version, then the number of iterations required to output a bit-count of 1024, would be 16. *The ‘total amount of randomness’ would then be capped at 64 bits, according to the size of the seed*.

(Update 10/08/2018, 8h55 : )

I should add, that If the goal of the exercise was to take an example like this, in which there are exaggeratedly few integer values from the RNG, and to transform those into the range [0 .. n] , *where stress is on the range being inclusive*, there are straightforward ways to achieve that, in arbitrary-precision integer Math. One way would be to take the integer output from the RNG and multiply it by (2n), and then, if that integer had as basis, say, a modulus of (2^{32}), to divide the result by (*2 ^{32} – 1*), using integer division. Next, (1) could be added to the result, and then (1/2) computed, again, using integer arithmetic. This is roughly equivalent to adding (0.5) to the final result.

But then one side-effect of this would be, that if the range was more modest, such as maybe (n = 10), the probability of an actual (0) or an actual (10) occurring, would be (1/2) the probability with which the other numbers in the range occur. *If the stress was on providing “uniform” probabilities*, then the only way I can see to proceed would be, to multiply by (n + 1), to divide by (2^{32}). But in that case, if (n >> 2^{32}), the result of (n) might never occur.

(Update 10/09/2018, 19h55 : )

* A Major Weakness in This Approach*:

The most important weakness I see in this approach is related to the relatively small number of bits used to seed the Mersenne Twister RNG (usually, 32). This would lead to the situation that there can only be ~ 4 billion possible values, as the coefficient (a), of the Linear Congruent RNG which I chose to label ‘rng2′.

What can ‘break’ some RNGs, is a set of parameters that cause convergence of the outputs, towards some subset of values that the hypothetical attacker could predict, *without* getting to see the history of outputs, or the initial seed. And some of the ~ 4 billion coefficients produced as above, may lead to this. An attacker could compute *them all*, and then ‘hope’ that his target has ended up using such a defective one.

But if the programmer is keen on removing this vulnerability as well, there are 512 bits of entropy in (‘global_seed’) !

I do not recommend just XOR’ing the entire ‘global_seed’ into the generated coefficient (a), because, the first operation would be to multiply this seed, as the current (X), with the (a) that was just XOR’ed. The result of that could be even more-predictable, than the result would have been, to multiply by the unmodified version of (a).

But what should be somewhat safe to do, is that the higher half of ‘global_seed’ could be XOR’ed into the higher half of (a). I think that the benefit of that would be, that the result of multiplying both higher halves, will always produce output ‘left-shifted beyond the modulus of the generator state’. But, the product of the lower half of the previous (X) with the higher half of (a) would affect the numbers generated, without causing this coincidence. And the result should be a workable version of (a), that the attacker cannot predict. That version of (a) has an equal probability of being a defective one; it just wouldn’t be a predictable, defective one.

(Update 10/10/2018, 8h35 : )

There is a detail about the Linear Congruent algorithm which I did not previously explain, on the assumption that my reader already knows it. But maybe, because the reader may not, I’ll explain it now.

Assuming that the algorithm has a workable coefficient which I labeled (a), the randomness of its outputs will stem from the randomness of *the initial seed value*, which I labeled ‘global_seed’, not, from the coefficient (a).

One step which improves the likelihood of this functioning with a pseudo-random (a), was just to set the least-significant bit of (a), as I explained directly at the beginning of this posting. The reason for that is, the fact of the LSB being set, will preserve some factor of ‘global_seed’ being represented in (X) for a potentially infinite number of iterations. *Approximately, the Linear Congruent algorithm is computing some power of (a), which will then also act, approximately, as the factor of (X)*.

However, some probability of a non-workable coefficient (a) occurring stays uniform, regardless of what methods are used to generate (a). For example, if the lower half of (a) was just to consist of all-zeroes, except for that one LSB being set, we’d have a non-workable version of (a). The main defense I’ve suggested against that was, ~~to limit the number of times that an attempt is made to generate a prime number, before reseeding~~.

(Update 10/11/2018, 14h20 : )

There is a rational basis not to think, that the concatenated outputs from even a 32-bit Mersenne Twister RNG, would produce a coefficient named (a), that will be defective in some way, as in lacking randomness.

According to the WiKi-article I linked to above, the Mersenne Twister algorithm will not fall into a rut, let’s say of always outputting 32-bit fields of zero, because it did so once. The reason for this is the fact that the state of ‘rng1′ consists of the past 624 outputs – in the 32-bit implementation – and not just, of the last 1 or 2 outputs. In other words, the chance that this algorithm will generate 32 bits of zeroes, is just as high as it generating any other 32-bit value, and just as high, of such a 32-bit value occurring in a truly random way.

So, If we assume that all possible 512-bit coefficients (a) are to be generated, and that there exist 4 billion of them, then the odds that any one 32-bit field would consist entirely of zeroes, will again be, 1 in 4 billion. But, because the 512-bit value that results would be a concatenation of 16 such fields, the chances that any 512-bit output contains one, are 16 out of 4 billion: ~16 possible outputs will contain such a field, and ~8 of them in such a way, that this field belongs to the lower half.

The odds that any possible, 512-bit output will actually contain *two* such fields, should be exponentially smaller. And thus it seems likely that none of the 4 billion possible coefficients named (a) will actually be broken examples.

Therefore, the step should never actually become necessary, which I outlined above, to mitigate the dangers, from a broken ‘rng2′.

(Update 10/12/2018, 6h50 : )

According to what I read, the Mersenne Twister algorithm must not be seeded with the 32-bit value or the 64-bit value zero.

Because the GMP library can set an arbitrary-precision integer, from an unsigned long integer, instead of always from a string, it should come as no additional computational expense, to find the maximum between one such integer, and the value (1). Therefore, a minimum of (1) can be made the seed easily, without OR’ing the arbitrary-precision seed with (1). Therefore, the full range of 4 billion seed-values can be kept, more or less, even over the need not to seed with the value (0).

(Update 10/13/2018, 13h10 : )

Because I can find no public documentation which would answer the question with certainty, I should warn my reader, that the possibility exists, that GMP only implements a 32-bit Mersenne Twister algorithm, even when the library has been compiled to run on a 64-bit CPU. This would happen because To implement a 64-bit Mersenne Twister algorithm, would actually require that the source code be rearranged to some extent. And so the approach which I would recommend to seed it would be:

```
unsigned long int mt_seed_np = 1;
mt_seed_np = mpz_get_ui( global_seed );
if (! (mt_seed_np & 0xFFFFFFFF)) {
mt_seed_np++;
}
gmp_randseed_ui(rng1, mt_seed_np);
```

Dirk

]]>

I take the somewhat unusual approach, of hosting my site and therefore also this blog, on a private PC at home which I name ‘Phoenix’. This is not how sites are usually hosted. And what it means is that, while I get to play with my own server all I want, the visibility of this blog on the Internet, is only as good, as the up-time and the connectivity of this PC.

This evening a Kernel Update was put through the system, which required I reboot this Linux computer. Therefore, my site and blog were off-line from about 20h00 until about 20h15.

I apologize for any inconvenience to my readers, but these things must be done.

The kernel update itself seemed to have no ill effects, that I can detect immediately. But in all honesty, if there was ever anything wrong with a kernel update, there are essentially two types of problems which can take place:

- The computer immediately refuses to boot,
- It takes a long time to detect a problem, and when this is done, the problem is usually also detected by somebody other than me.

So because I’m back up, there’s nothing to complain about!

FWIW, this computer had been running one session, for 35 days straight, with no real technical issues.

Dirk

]]>

One of the ways in which I function, is to write down thoughts in this blog, that may seem clear to me at first, but which, once written down, require further thought and refinement.

I’ve written numerous times about Public Key Cryptography, in which the task needs to be solved, to generate 1024-bit prime numbers – or maybe even, larger prime numbers – And I had not paid much attention to the question, of how exactly to do that efficiently. Well only yesterday, I read a posting of another blogger, that inspired me. This blogger explained in common-sense language, that a probabilistic method exists to verify whether a large number is prime, that method being called “The Miller-Rabin Test”. And the blogger in question was named Antoine Prudhomme.

This blogger left out an important part in his exercise, in which he suggested some working Python code, but that would be needed if actual production grade-code was to generate large prime numbers for practical cryptography. He left out the eventual need, to perform more than just one type of test, because this blogger’s main goal was to explain the one method of testing, that was his posting subject.

I decided to modify his code, and to add a simple Fermat Test, simply because (*in general*,) to have two different probabilistic tests, reduces the chances of false success-stories, even further than Miller-Rabin would reduce those chances by itself. But Mr. Prudhomme already mentioned that the Fermat Test exists, which is much simpler than the Miller-Rabin Test. And, I added the step of just using a Seive, with the known prime numbers up to 65535, which is known not to be prime itself. The combined effect of added tests, which my code performs prior to applying Miller-Rabin, will also speed the execution of code, because I am applying the fastest tests first, to reduce the total number of times that the slower test needs to be applied, in case the candidate-number could in fact be prime, as not having been eliminated by the earlier, simpler tests. Further, I tested my code thoroughly last night, to make sure I’ve uploaded code that works.

Here is my *initial, academic* code:

http://dirkmittler.homeip.net/text/Generate_Prime_3.py

(Corrected 10/03/2018, 23h20 … )

(Updated 10/08/2018, 9h25 … )

(As of 09/28/2018, 17h05 : )

The original algorithm seemed to waste most of its time – about 5 seconds or so – just computing the array of the first 6542 known primes, less than 65535. For a production-grade program, this time can be eliminated, by making that array a static constant, and compiling and linking it in to the object-code statically. This would be especially feasible, because each of the elements is a 16-bit integer.

(Update 09/29/2018, 19h40 : )

I have changed the way in which the functions ‘smallprimes()’ and ‘sift_primes()’ work, to make them more consistent with the way Python stores lists, and therefore also to make them faster. The script now requires only about *2.4* seconds to compute its initial list of primes, on my machine. I have replaced the code linked to above, with the updated code.

However, the complete program still seems to require about *5* seconds to compute a 1024-bit prime, on my machine. The fact that I’ve decided to test each candidate up to 256 times may contribute to that.

Additionally, I’ve examined the Miller-Rabin Test more closely, to understand it, and have come to an additional conclusion about it: It also eliminates Fermat-Test failures. I.e., these two tests do overlap, in that no candidate should exist, which the Miller-Rabin Test confirms as probable primes, but which the Fermat Test will fail. Therefore, the only real gain I made in performing the Fermat Test first, was to reduce the number of times the Miller-Rabin Test needs to be performed, thereby improving speed. And this improvement in speed also presents a justification to perform 256 tests instead of 128, the latter part of which *might* reduce the probability of a so-called ‘Carmichael Number’, a Miller-Rabin Test Liar…

* Understanding the Miller-Rabin Test*:

The reader could eventually hap into the question of why at all, the Miller-Rabin Test, as it’s presented, works. And there is a key observation about the test, which will help explain it:

Given a tentative prime (n), it would follow that the totient is (n-1), which the Miller-Rabin Test factorizes into an odd factor (r), and a power (s) of the factor (2). The key to understanding the code is to observe, *that (j) is initialized to (1), but that the squaring-loop will continue, as long as (j < s)*. This means that the inner loop gets executed (s – 1) times !

Well, if it was true that the only trivial square root was (1), then one **absurd** conclusion would be, that a number (a^r) which has yet to be squared (s) times, must have started out as being (1), so that after having been squared (s) times, the result will still be (1). But, because the two possible, trivial square-roots are in fact {-1,1} , it can happen that after being squared only (s-1) times, the result is (-1). After the result is then squared one more time, the final result (which Miller-Rabin does not bother to compute) will be (1).

What seems to follow, is that (-1) will have non-trivial square roots eventually (at least in modulus arithmetic; nobody is suggesting that imaginary numbers are being used here), so that an initial value of (a^r) may start out as non-trivial, but which when squared (s) times at the latest, will result in (1). In fact, the result of (-1) may happen, *before* (a^r) has even been squared (s-1) times, just because (a^r) may already start out as being a square, in the modulus of (n). And so the test needs to *exit* in such cases, *without rejecting* the presumed totient of (n-1), for those examples of (a).

Just to name an example, we could be trying to test whether our famous case of (2^16 + 1) is prime, which can also be written (65537). Its totient is (2^16), or, (65536). (r=1, s=16). Miller-Rabin *will try to square (a) 15 times, not 16*, and after doing so 15 times at the latest, the result will be (-1). This implies that after the 16th squaring, the result will be (1). But the intermediate result was not (1), at any time *before* it was (-1). And so the test succeeds.

* One vulnerability of the Miller-Rabin Test*:

According to what I just wrote, there follows a vulnerability in the Miller-Rabin Test, in its original form. For some value of (a), it can happen that (a^r mod n == 1), that is, without the test having squared (a^r) even once. In such cases, the test will fail to prove that (n) is not prime. Unfortunately, the Fermat Test will fail to do so as well, since it will follow that (a^(r(2^s)) mod n == 1). This does *not* mean that (n) is *not* prime, for which reason the test ‘succeeds’, thus allowing additional tests to determine whether (n) is prime or not.

One reason this can happen is the possibility that (a) was square, which, if (r) was hypothetically as small as (5), would already mean that (a^r) will be square five times over. Thus, if we were to imagine (some number) being squared 5 times, we could imagine that at some point that does not exist literally, (-1) could have been reached, and then (1), followed eventually by (a^r). *The problem is, we don’t know whether (-1) was ever a part of this virtual sequence*.

The conventional solution to this problem would have been, to perform a larger number of tests (k), so that eventually, some value of (a) will arise, for which (a^r != 1).

I have now modified the test, so that If (a^r mod n == 1), *For more than a certain number of cases tested*, that is, (~~k/2~~) times, the assumption will be that this is also true for all values of (a), and the candidate of (n) which did this will be failed. And I have replaced the code linked to above, with the result of this modification. Even if the candidate was in fact prime, this fact needs to be witnessed by a certain number of values for (a), that produce meaningful results. And then, to replace (n) also causes more tests to be performed.

(Update 09/30/2018, 12h10 : )

I suppose that there’s another hypothetical way in which the Miller-Rabin Test could fail. After being squared zero or more times, (a^r) could become (-1) for some invalid reason. That is, a non-trivial value of (a) raised to some exponent, could yield (-1), even though (n) is not prime. It was never a situation which Miller-Rabin would have been able to detect, and for that, I also see no reason to raise any sort of exception, if this already happens with (a^r). If it happened, say, with (a^(2r)), after (a^r) was explicitly squared once, then the test would not have raised any exceptions either. The only condition for which the test can reject the candidate (n), is a value for (a), such that (1) is reached before (-1) was reached.

I believe that my only defense against this problem, is actually to carry out a sufficient number of tests, again, using random values for (a).

In fact, If a candidate (n) was ever tested, which is prime, but the totient of which, that must be even, only has a single power of two, such that (s = 1), then, *almost* every time the Miller-Rabin Test was performed, (a^r mod n) should in fact be (n – 1), which I’ve been assuming is the modulus equivalent of (-1). In that case, this test is only as strong as the simple Fermat Test. And for that reason the fact represents a reassurance, that the Miller-Rabin Test can also be performed using a single exponentiation, thereby making it only as expensive computationally, as the Fermat Test would be.

Now, *If one was really stubborn*, one could reject all such cases, even though sometimes, (n) was really prime, just because the available test for primeness would not be stronger than the Fermat Test.

(Observation added 10/01/2018, 18h40 : )

If I may quote Antoine Prudhomme:

>>>

There are some composite numbers that satisfies the *Fermat’s little theorem *for all possible values of **a**. As you guessed, these numbers are called … *Carmichael numbers* (so much suspense…).

The first 3 are **561**, **1105** and **1729**.

There are only **255** Carmichael numbers **<** **10⁸**, and **20138200** **<** **10²¹** !

<<<

The three examples which Mr. Prudhomme writes literally, are all examples in which (n – 1) is divisible by (4). There is an easy trick to testing this visually, which is, after one has subtracted (1) from each number, the last two digits in Base-10 must be divisible by (4). Hence:

- 60 / 4 == 15
- 04 / 4 == 1
- 28 / 4 == 7

And so luck would seem to have it in each case, that for the Miller-Rabin Test, (s >= 2). So the fact that this test can ‘catch those liars’, while the simple Fermat Test cannot, remains consistent with what I wrote above.

Furthermore, the fact that Antoine Prudhomme gives exact answers, for integers up to 10^{21}, suggests that prime numbers up to that size are known with certainty, for example, through the use of a seive. In itself, this is not a spectacular achievement by today’s standards, that assume powerful computers can be used to factorize, say, 10^{21}. But this number being an upper bound to what Mr. Prudhomme wrote, still has significance today.

A fact which my reader may not be aware of is that in Mathematics, the fact that certain patterns seem to hold, up to the value 10^{21}, is not enough to prove that such patterns remain true for much-larger numbers. So according to Mr. Prudhomme, the (unmodified) Miller-Rabin Test may be sufficient, to find all the ‘liars’ up to that value. And according to me, all the liars that can be found this way are probably of the form that:

(n – 1 mod 4 == 0)

Well, there exists a Historical Example, in “Euler’s Conjecture”, which states that for (k=4), there are *no* cases, where:

x_{1}^{k} + x_{2}^{k} + x_{3}^{k} == x_{4}^{k}

In Euler’s day, this might have been an appropriate assumption. But according to modern knowledge, the first counter-example is:

2682440^{4} + 15365639^{4} + 18796760^{4} = 20615673^{4}

Each of these terms is larger than 10^{21}, and the counter-example requires the use of computers to find. Well, in cryptography, the goal is to generate prime-numbers (n ~= 2^{1024}), which is approximately equivalent to (10^{300}), hence, equivalent to ‘a Googol Cubed’. There could, for all I know, be counter-examples, to the unmodified Miller-Rabin Test always discovering a Fermat Test Liar, *as well as* to the Fermat Test Liar *always being of the form I wrote above*…

Actually, I also know that the first counter-examples to Euler’s Conjecture, ever found, were to a form of it, in which the exponent was (5), not (4). But the example I gave above, is the smallest-known case, when the exponent is (4).

(Update 10/02/2018, 8h00 : )

:**The probability of an integer being square, modulo n**

Through simple experimentation I seem to have discovered, that the probability with which:

a^r mod n == 1

*On the assumption that r, s and n are as defined in the preceding paragraphs of my posting*,

Is equal to (1/2) if (s = 1), is equal to (1/4) if (s = 2), is equal to (1/8) if (s = 3), etc..

I take this situation to be ~~equivalent, to (a) being square modulo (n)~~, and additionally, *not* being (0) or (1), which my program will not suggest as witnesses.

This observation has helped me better determine the threshold, at which my program should reject (n), over this condition.

(Update 10/02/2018, 15h05 : )

In order to test the last premise I wrote above further, I have now added two assertions to my Python script, and have been able to run the script again, 10 times in a row, without causing any error messages. However, because (a) is being chosen at random out of [2, n-1] a limited number of times, the frequency with which the statement is true, that:

a^r mod n == 1

Is also sensitive to some random fluctuations. Yet, because the finding which I just wrote above ~~directly contradicts~~ This finding, from elsewhere on the Web, I felt I needed to test my own finding anyway, by making such non-deterministic assertions, which is normally a bad practice in programming. These assertions will at least be repeatable 90% of the time…

(Erratum 10/03/2018, 14h55 : )

It seems that I have fallen into the trap of mistaking:

(p -> q)

For:

(q -> p)

*On the assumption that r, s and n are as defined in the preceding paragraphs of my posting*,

The condition that:

a^r mod n == 1

*Does Imply* that (a) is square. *But the reverse is not true*. This is why the condition which I was interested in, can occur *less-frequently*, than (a) being square.

Furthermore, one of the assertions in my script, which I was testing my condition with, was:

```
assert is_prime(113, 256)
```

Which picks 256 random values of (a) in the appropriate range as witnesses. While it’s true that 112 is divisible by 4, it’s also true that this same number is divisible by 16. Hence, by asserting the above, my code has verified dozens of times, that the probability of my condition was on the order of (1/16), not even (1/4).

(Update 10/03/2018, 23h20 : )

I can elaborate on this idea of squareness:

To recap, (n) is a presumed prime number, and a_{1} and a_{2} can be integers modulo (n). But, let it be that:

a_{2} = a_{1}^{2} mod n

The following situation defines (r) and (s):

(n – 1) = r(2^{s})

Where (r) is odd.

Strangely, the following two statements follow from Fermat’s Little Theorem:

(a_{1}^{r})^{(2s)} mod n == 1

(a_{2}^{r})^{(2s)} mod n == 1

The second statement above is implied by the first, and by the fact that:

1^{2} mod n == 1

If (s = 1), it will follow that:

a_{2}^{r} mod n == 1

But, there could be yet another witness (a_{3}), such that:

a_{3} = a_{2}^{2} mod n

If (s = 2), it will follow that:

a_{3}^{r} mod n == 1

I would induce that the probability of:

a^{r} mod n == 1

Is approximately equal to

p^{s}

Where (p) is the probability that:

a_{2} == a_{1}^{2} mod n

*In other words, if (s = 2) and (a) is randomly chosen, this condition will be true, when (a) is square, and when the root of (a) is also square*…

Hence,

p = ½

(Update 10/08/2018, 9h25 : )

I have updated the script, and one of the main features which I have now implemented, is a cryptographically-strong random number generator, that uses the system source of randomness, which under Linux, turns out to be the device-file ‘/dev/urandom’, instead of always using the ‘Mersennes Twister’. This is the updated script:

http://dirkmittler.homeip.net/text/Generate_Prime_11.py

I think that another way in which this script differs from the earlier example, is in the possibility that this one may need to be run using Python 3.

Also, while the previous version of this script would run fine on a 64-bit machine, it would have produced sub-optimal results on a 32-bit machine, and the reason for that is the fact that (sys.maxsize) is usually (*2 ^{31} – 1*), on a 32-bit machine, and not

Enjoy,

Dirk

]]>

I use a version of Linux on the one of my computers named ‘Plato’, that has Debian / Stretch as its base, but which also has Plasma 5 as its desktop manager. This was a system which I created from a Kanotix Live DVD, from before Kanotix had an official Debian / Stretch release. According to that Live Disk, the desktop manager was LXDE ! LXDE stands for “Lightweight X Desktop Environment”, while Plasma 5 is the successor to KDE 4, and is a powerful, CPU-consuming desktop manager. In the meantime, Kanotix has created two official ‘Stretch’ releases, one with LXDE and one with Plasma 5, both named ‘Kanotix Steelfire’.

What I felt I needed to do with Plato, was to install Plasma 5 via the package manager, even though the Kanotix developers had not yet done so. This customized Plasma 5 environment has been running fine for some time.

But only recently, after my email client – Thunderbird – received an update to version 60.x, I did notice that some of my desktop notifications seemed a little odd. Instead of appearing as official Plasma / KDE notifications, they appeared either as stylized bubbles, or as more-boring drop-down lists from the center, of the top, of my screen. And so this can lead to some confusion, or to some doubt in whether the system is still stable. In fact, I’ve read some other complaints from the Web, of people who ran in to the same behavior exactly. What seemed to irk them as well as me most, was that although we can use our KDE / Plasma Notification settings to designate, where we want notifications to appear, these apparently rogue notifications seem to disregard this setting.

Well I finally got to the bottom of what was causing this. Within my Plasma 5 desktop, I still had a notification daemon running, that belonged to the experimental build. In my case, this daemon was installed as the package ‘xfce4-notifyd’. And so my gut reaction was ~~to yank that package out~~, to let Plasma 5 do its job on its own, to manage the display of notifications. **I don’t recommend that my readers do the same thing**!

In fact, Plasma 5 has trouble displaying certain notifications gracefully, that were created by simple scripts and programs. Not only that, but the way the new Thunderbird behaves is such, that if the simpler notify daemon is installed, it will use that to display email notifications. Thunderbird will now only use the KDE / Plasma notification engine, if the simpler daemon is *not* installed.

So it would seem that for “Kanotix Steelfire”, they intentionally leave this snippet of (simpler) code in-place. Therefore, If the main problem other users are facing is also, that these bubbles appear in wrong places on the screen, which they’d like to control, then the trick would be to leave ‘xfce4-notifyd’ installed – assuming it already is – and to run the command *as user*:

```
xfce4-notifyd-config
```

And this is what you’d see:

Yes, now that I reinstalled the package, I get to configure my XFCE Notifier from within my Plasma 5 desktop! For readers who may not know, XFCE is yet another, 3rd desktop manager, that predates LXDE.

So now I get to place those notification bubbles where I want them. If I leave the package out, Thunderbird knows how to use KDE / Plasma, but certain other software does not. This results in the same, ugly drop-down lists, which are then due to the difficulty in getting Plasma 5 to display notifications correctly, which seems systemic.

Dirk

]]>