I want to generate a random number in the range [0, n] safely, where N is a parameter. However, System.Security.Cryptography.RandomNumberGenerator provides a GetBytes () method to fill an array with only one random values.
(I need a random integer for the nonces used in a slightly modified version of SRP. The "little modified" part is out of my control, and the only reason I'm touching crypto stuff.) < / P>
I have written a method to do this, but I have a better or at least confirmation that I am correcting it.
By using System.Numerics /// & lt; Summary & gt; The range [0 generates evenly random integers in bounds in the boundary] & Lt; / Summary & gt; Public stable BigInteger RandomIntegerBelow (this System.Security.Cryptography.RandomNumberGenerator source, BigInteger bound) {contract. Requirements & lt; ArgumentException & gt; (Source! = Null); Contract Requirement & lt; Logic Exclamation & gt; (Bound & gt; 0); Contract. Sign (contract results: lie> big intanger> ()> = 0); Contract. Sign (contract results; lieant; bigentier & gt; () & lt; bound); // Beit buffer be able to hold any value under bound worker buffer = (bound = Binding); Var Validity Bound = Generated Bound - Generated Bound% Bound; Contract Entry (validity bound> gt; = bound); While (true) {// [0, 2 ^ (buffer length * 8 - 1), evenly produce random values. Getbytes (buffer); Buffer [buffer. Length - 1] & amp; = 0x7F; // sign force for positive var r = new buffer; // Repeat the partial piece (R & gt; = validity bound); Refund R%; }}
Your code looks correct and fair however, you want to change it a bit , If you are after the performance, and depending on the speed of the random source you are using. This idea is to mask some other bits so that the random value is smaller than r 2 * bound . If the <>> of >> except the Mask (X + 8) / 8) bytes, and upper (n * 8-x) bits. In C #, it should look like this: var x = bit lang (bound); Var n = ((x + 8) / 8); Var buffer = new byte [n]; Variable Masks = 0xFF & gt; & Gt; (8 * n - x); While (true) {source.GetBytes (buffer); Buffer [N - 1] & amp; = Mask; Var r = new buffer (buffer); If (R & lt; binding) returns r; } With this type of code, you may have to ask more random bytes from the source, but you can avoid modular deductions (% operator). A proper PRNG should be faster than division on large integer, so it should be a better business - but it really depends on the performance of the random source, and, because it is a question of performance, it is not completely It is possible to answer without any effort, as part of an overall SRP implementation, it will not take any kind of difference in mind. I have a BitLength () function that does not exist above in C # (a bitLength () in the BigIntegr class of Java method, but apparently Microsoft forgot to include one in its large integer implementation - which is a shame, because it seems that the implementation actually involves a private sector, which is _bits Which maintains that value). Bit length can be calculated efficiently, by representation in the bytes of the bound value, so the code will become something like this: var buffer = bound. To beteere (); Var n = buffer. Lambi; Var MSB = Buffer [N-1]; Var Mask = 0; While (masks & lt; msb) mask = (mask & lt; <1) + 1; While (true) {source.GetBytes (buffer); Buffer [N - 1] & amp; = Mask; Var r = new buffer (buffer); If (R & lt; binding) returns r; } I am using the fact that the length of the encoding of bound , in the bytes ToByteArray () , is that OK I need n .
Comments
Post a Comment