commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Eldar Agalarov (Updated) (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (MATH-710) Add support for fast cryptographically secure pseudorandom number generator ISAAC
Date Sun, 20 Nov 2011 01:19:52 GMT

     [ https://issues.apache.org/jira/browse/MATH-710?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Eldar Agalarov updated MATH-710:
--------------------------------

    Description: 
Dear developers, please add to Common Math library support for ISAAC random number generator.
This is a free and open-source PRNG (http://burtleburtle.net/bob/rand/isaacafa.html). 

Algorithm's rewrited (with some improvements) Java code from original C version:

import java.io.Serializable;

public final class ISAACRandom extends AbstractRandom implements Serializable, Cloneable {

    private static final long serialVersionUID = 7288197941165002400L;

    private static final int SIZE_L = 8;                /* log of size of rsl[] and mem[]
*/
    private static final int SIZE = 1 << SIZE_L;        /* size of rsl[] and mem[] */
    private static final int H_SIZE = SIZE >> 1;        /* half-size of rsl[] and mem[]
*/
    private static final int MASK = SIZE - 1 << 2;      /* for pseudorandom lookup */
    private static final int GLD_RATIO = 0x9e3779b9;    /* the golden ratio */
    private static final long SEED_MASK = 0xffffffffL;

    private int[] rsl;                                  /* the results given to the user */
    private int[] mem;                                  /* the internal state */
    private int[] arr;

    private int count;                                  /* count through the results in rsl[]
*/
    private int a;                                      /* accumulator */
    private int b;                                      /* the last result */
    private int c;                                      /* counter, guarantees cycle is at
least 2^^40 */
    private transient int x;
    private transient int i;
    private transient int j;


    public ISAACRandom() {
        this(System.currentTimeMillis());
    }

    public ISAACRandom(long seed) {
        allocArrays();
        setSeed(seed);
    }

    public ISAACRandom(int[] seed) {
        allocArrays();
        setSeed(seed);
    }

    private void allocArrays() {
        rsl = new int[SIZE];
        mem = new int[SIZE];
        arr = new int[8];
    }

    @Override
    public void setSeed(int seed) {
        setSeed(new int[]{seed});
    }

    @Override
    public void setSeed(long seed) {
        setSeed(new int[]{(int) (seed >>> 32), (int) (seed & SEED_MASK)});
    }

    @Override
    public void setSeed(int[] seed) {
        int seedLen = seed.length, rslLen = rsl.length;
        System.arraycopy(seed, 0, rsl, 0, Math.min(seedLen, rslLen));
        if (seedLen < rslLen) {
            for (i = seedLen; i < rslLen; i++) {
                long k = rsl[i - seedLen];
                rsl[i] = (int) (0x6c078965L * (k ^ k >> 30) + i & SEED_MASK);
            }
        }
        initState();
        isaac();
        count = SIZE - 1;
    }

    @Override
    protected int next(int bits) {
        if (count < 0) {
            isaac();
            count = SIZE - 1;
        }
        return rsl[count--] >>> 32 - bits;
    }

    private void isaac() {
        i = 0; j = H_SIZE; b += ++c;
        while (i < H_SIZE) isaac2();
        j = 0;
        while (j < H_SIZE) isaac2();
    }

    private void isaac2() {
        x = mem[i]; a ^= a <<  13; a += mem[j++]; isaac3();
        x = mem[i]; a ^= a >>>  6; a += mem[j++]; isaac3();
        x = mem[i]; a ^= a <<   2; a += mem[j++]; isaac3();
        x = mem[i]; a ^= a >>> 16; a += mem[j++]; isaac3();
    }

    private void isaac3() {
        mem[i] = mem[(x & MASK) >> 2] + a + b;
        b = mem[(mem[i] >> SIZE_L & MASK) >> 2] + x;
        rsl[i++] = b;
    }

    private void initState() {
        a = b = c = 0;
        arr[0] = arr[1] = arr[2] = arr[3] = arr[4] = arr[5] = arr[6] = arr[7] = GLD_RATIO;
        for (i = 0; i < 4; i++) shuffle();
        for (i = 0; i < SIZE; i++) mem[i] = rsl[i] = 0;
        for (i = 0; i < SIZE; i += 8) {
            arr[0] += rsl[i];     arr[1] += rsl[i + 1]; arr[2] += rsl[i + 2];
            arr[3] += rsl[i + 3]; arr[4] += rsl[i + 4]; arr[5] += rsl[i + 5];
            arr[6] += rsl[i + 6]; arr[7] += rsl[i + 7];
            shuffle(); setState();
        }
        for (i = 0; i < SIZE; i += 8) {
            arr[0] += mem[i];     arr[1] += mem[i + 1]; arr[2] += mem[i + 2];
            arr[3] += mem[i + 3]; arr[4] += mem[i + 4]; arr[5] += mem[i + 5];
            arr[6] += mem[i + 6]; arr[7] += mem[i + 7];
            shuffle(); setState();
        }
    }

    private void shuffle() {
        arr[0] ^= arr[1] <<  11; arr[3] += arr[0]; arr[1] += arr[2];
        arr[1] ^= arr[2] >>>  2; arr[4] += arr[1]; arr[2] += arr[3];
        arr[2] ^= arr[3] <<   8; arr[5] += arr[2]; arr[3] += arr[4];
        arr[3] ^= arr[4] >>> 16; arr[6] += arr[3]; arr[4] += arr[5];
        arr[4] ^= arr[5] <<  10; arr[7] += arr[4]; arr[5] += arr[6];
        arr[5] ^= arr[6] >>>  4; arr[0] += arr[5]; arr[6] += arr[7];
        arr[6] ^= arr[7] <<   8; arr[1] += arr[6]; arr[7] += arr[0];
        arr[7] ^= arr[0] >>>  9; arr[2] += arr[7]; arr[0] += arr[1];
    }

    private void setState() {
        mem[i] =     arr[0]; mem[i + 1] = arr[1]; mem[i + 2] = arr[2];
        mem[i + 3] = arr[3]; mem[i + 4] = arr[4]; mem[i + 5] = arr[5];
        mem[i + 6] = arr[6]; mem[i + 7] = arr[7];
    }

    @Override
    public ISAACRandom clone() {
        try {
            ISAACRandom cloned = (ISAACRandom) super.clone();
            cloned.rsl = rsl.clone();
            cloned.mem = mem.clone();
            cloned.arr = arr.clone();
            return cloned;
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e.getMessage());
        }
    }
}

  was:
Dear developers, please add to Common Math library support for ISAAC random number generator.
This is a free and open-source PRNG. Java code is below:

import java.io.Serializable;

public final class ISAACRandom extends AbstractRandom implements Serializable, Cloneable {

    private static final long serialVersionUID = 7288197941165002400L;

    private static final int SIZE_L = 8;                /* log of size of rsl[] and mem[]
*/
    private static final int SIZE = 1 << SIZE_L;        /* size of rsl[] and mem[] */
    private static final int H_SIZE = SIZE >> 1;        /* half-size of rsl[] and mem[]
*/
    private static final int MASK = SIZE - 1 << 2;      /* for pseudorandom lookup */
    private static final int GLD_RATIO = 0x9e3779b9;    /* the golden ratio */
    private static final long SEED_MASK = 0xffffffffL;

    private int[] rsl;                                  /* the results given to the user */
    private int[] mem;                                  /* the internal state */
    private int[] arr;

    private int count;                                  /* count through the results in rsl[]
*/
    private int a;                                      /* accumulator */
    private int b;                                      /* the last result */
    private int c;                                      /* counter, guarantees cycle is at
least 2^^40 */
    private transient int x;
    private transient int i;
    private transient int j;


    public ISAACRandom() {
        this(System.currentTimeMillis());
    }

    public ISAACRandom(long seed) {
        allocArrays();
        setSeed(seed);
    }

    public ISAACRandom(int[] seed) {
        allocArrays();
        setSeed(seed);
    }

    private void allocArrays() {
        rsl = new int[SIZE];
        mem = new int[SIZE];
        arr = new int[8];
    }

    @Override
    public void setSeed(int seed) {
        setSeed(new int[]{seed});
    }

    @Override
    public void setSeed(long seed) {
        setSeed(new int[]{(int) (seed >>> 32), (int) (seed & SEED_MASK)});
    }

    @Override
    public void setSeed(int[] seed) {
        int seedLen = seed.length, rslLen = rsl.length;
        System.arraycopy(seed, 0, rsl, 0, Math.min(seedLen, rslLen));
        if (seedLen < rslLen) {
            for (i = seedLen; i < rslLen; i++) {
                long k = rsl[i - seedLen];
                rsl[i] = (int) (0x6c078965L * (k ^ k >> 30) + i & SEED_MASK);
            }
        }
        initState();
        isaac();
        count = SIZE - 1;
    }

    @Override
    protected int next(int bits) {
        if (count < 0) {
            isaac();
            count = SIZE - 1;
        }
        return rsl[count--] >>> 32 - bits;
    }

    private void isaac() {
        i = 0; j = H_SIZE; b += ++c;
        while (i < H_SIZE) isaac2();
        j = 0;
        while (j < H_SIZE) isaac2();
    }

    private void isaac2() {
        x = mem[i]; a ^= a <<  13; a += mem[j++]; isaac3();
        x = mem[i]; a ^= a >>>  6; a += mem[j++]; isaac3();
        x = mem[i]; a ^= a <<   2; a += mem[j++]; isaac3();
        x = mem[i]; a ^= a >>> 16; a += mem[j++]; isaac3();
    }

    private void isaac3() {
        mem[i] = mem[(x & MASK) >> 2] + a + b;
        b = mem[(mem[i] >> SIZE_L & MASK) >> 2] + x;
        rsl[i++] = b;
    }

    private void initState() {
        a = b = c = 0;
        arr[0] = arr[1] = arr[2] = arr[3] = arr[4] = arr[5] = arr[6] = arr[7] = GLD_RATIO;
        for (i = 0; i < 4; i++) shuffle();
        for (i = 0; i < SIZE; i++) mem[i] = rsl[i] = 0;
        for (i = 0; i < SIZE; i += 8) {
            arr[0] += rsl[i];     arr[1] += rsl[i + 1]; arr[2] += rsl[i + 2];
            arr[3] += rsl[i + 3]; arr[4] += rsl[i + 4]; arr[5] += rsl[i + 5];
            arr[6] += rsl[i + 6]; arr[7] += rsl[i + 7];
            shuffle(); setState();
        }
        for (i = 0; i < SIZE; i += 8) {
            arr[0] += mem[i];     arr[1] += mem[i + 1]; arr[2] += mem[i + 2];
            arr[3] += mem[i + 3]; arr[4] += mem[i + 4]; arr[5] += mem[i + 5];
            arr[6] += mem[i + 6]; arr[7] += mem[i + 7];
            shuffle(); setState();
        }
    }

    private void shuffle() {
        arr[0] ^= arr[1] <<  11; arr[3] += arr[0]; arr[1] += arr[2];
        arr[1] ^= arr[2] >>>  2; arr[4] += arr[1]; arr[2] += arr[3];
        arr[2] ^= arr[3] <<   8; arr[5] += arr[2]; arr[3] += arr[4];
        arr[3] ^= arr[4] >>> 16; arr[6] += arr[3]; arr[4] += arr[5];
        arr[4] ^= arr[5] <<  10; arr[7] += arr[4]; arr[5] += arr[6];
        arr[5] ^= arr[6] >>>  4; arr[0] += arr[5]; arr[6] += arr[7];
        arr[6] ^= arr[7] <<   8; arr[1] += arr[6]; arr[7] += arr[0];
        arr[7] ^= arr[0] >>>  9; arr[2] += arr[7]; arr[0] += arr[1];
    }

    private void setState() {
        mem[i] =     arr[0]; mem[i + 1] = arr[1]; mem[i + 2] = arr[2];
        mem[i + 3] = arr[3]; mem[i + 4] = arr[4]; mem[i + 5] = arr[5];
        mem[i + 6] = arr[6]; mem[i + 7] = arr[7];
    }

    @Override
    public ISAACRandom clone() {
        try {
            ISAACRandom cloned = (ISAACRandom) super.clone();
            cloned.rsl = rsl.clone();
            cloned.mem = mem.clone();
            cloned.arr = arr.clone();
            return cloned;
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e.getMessage());
        }
    }
}

    
> Add support for fast cryptographically secure pseudorandom number generator ISAAC
> ---------------------------------------------------------------------------------
>
>                 Key: MATH-710
>                 URL: https://issues.apache.org/jira/browse/MATH-710
>             Project: Commons Math
>          Issue Type: New Feature
>    Affects Versions: 2.2
>            Reporter: Eldar Agalarov
>   Original Estimate: 1h
>  Remaining Estimate: 1h
>
> Dear developers, please add to Common Math library support for ISAAC random number generator.
This is a free and open-source PRNG (http://burtleburtle.net/bob/rand/isaacafa.html). 
> Algorithm's rewrited (with some improvements) Java code from original C version:
> import java.io.Serializable;
> public final class ISAACRandom extends AbstractRandom implements Serializable, Cloneable
{
>     private static final long serialVersionUID = 7288197941165002400L;
>     private static final int SIZE_L = 8;                /* log of size of rsl[] and mem[]
*/
>     private static final int SIZE = 1 << SIZE_L;        /* size of rsl[] and mem[]
*/
>     private static final int H_SIZE = SIZE >> 1;        /* half-size of rsl[] and
mem[] */
>     private static final int MASK = SIZE - 1 << 2;      /* for pseudorandom lookup
*/
>     private static final int GLD_RATIO = 0x9e3779b9;    /* the golden ratio */
>     private static final long SEED_MASK = 0xffffffffL;
>     private int[] rsl;                                  /* the results given to the user
*/
>     private int[] mem;                                  /* the internal state */
>     private int[] arr;
>     private int count;                                  /* count through the results
in rsl[] */
>     private int a;                                      /* accumulator */
>     private int b;                                      /* the last result */
>     private int c;                                      /* counter, guarantees cycle
is at least 2^^40 */
>     private transient int x;
>     private transient int i;
>     private transient int j;
>     public ISAACRandom() {
>         this(System.currentTimeMillis());
>     }
>     public ISAACRandom(long seed) {
>         allocArrays();
>         setSeed(seed);
>     }
>     public ISAACRandom(int[] seed) {
>         allocArrays();
>         setSeed(seed);
>     }
>     private void allocArrays() {
>         rsl = new int[SIZE];
>         mem = new int[SIZE];
>         arr = new int[8];
>     }
>     @Override
>     public void setSeed(int seed) {
>         setSeed(new int[]{seed});
>     }
>     @Override
>     public void setSeed(long seed) {
>         setSeed(new int[]{(int) (seed >>> 32), (int) (seed & SEED_MASK)});
>     }
>     @Override
>     public void setSeed(int[] seed) {
>         int seedLen = seed.length, rslLen = rsl.length;
>         System.arraycopy(seed, 0, rsl, 0, Math.min(seedLen, rslLen));
>         if (seedLen < rslLen) {
>             for (i = seedLen; i < rslLen; i++) {
>                 long k = rsl[i - seedLen];
>                 rsl[i] = (int) (0x6c078965L * (k ^ k >> 30) + i & SEED_MASK);
>             }
>         }
>         initState();
>         isaac();
>         count = SIZE - 1;
>     }
>     @Override
>     protected int next(int bits) {
>         if (count < 0) {
>             isaac();
>             count = SIZE - 1;
>         }
>         return rsl[count--] >>> 32 - bits;
>     }
>     private void isaac() {
>         i = 0; j = H_SIZE; b += ++c;
>         while (i < H_SIZE) isaac2();
>         j = 0;
>         while (j < H_SIZE) isaac2();
>     }
>     private void isaac2() {
>         x = mem[i]; a ^= a <<  13; a += mem[j++]; isaac3();
>         x = mem[i]; a ^= a >>>  6; a += mem[j++]; isaac3();
>         x = mem[i]; a ^= a <<   2; a += mem[j++]; isaac3();
>         x = mem[i]; a ^= a >>> 16; a += mem[j++]; isaac3();
>     }
>     private void isaac3() {
>         mem[i] = mem[(x & MASK) >> 2] + a + b;
>         b = mem[(mem[i] >> SIZE_L & MASK) >> 2] + x;
>         rsl[i++] = b;
>     }
>     private void initState() {
>         a = b = c = 0;
>         arr[0] = arr[1] = arr[2] = arr[3] = arr[4] = arr[5] = arr[6] = arr[7] = GLD_RATIO;
>         for (i = 0; i < 4; i++) shuffle();
>         for (i = 0; i < SIZE; i++) mem[i] = rsl[i] = 0;
>         for (i = 0; i < SIZE; i += 8) {
>             arr[0] += rsl[i];     arr[1] += rsl[i + 1]; arr[2] += rsl[i + 2];
>             arr[3] += rsl[i + 3]; arr[4] += rsl[i + 4]; arr[5] += rsl[i + 5];
>             arr[6] += rsl[i + 6]; arr[7] += rsl[i + 7];
>             shuffle(); setState();
>         }
>         for (i = 0; i < SIZE; i += 8) {
>             arr[0] += mem[i];     arr[1] += mem[i + 1]; arr[2] += mem[i + 2];
>             arr[3] += mem[i + 3]; arr[4] += mem[i + 4]; arr[5] += mem[i + 5];
>             arr[6] += mem[i + 6]; arr[7] += mem[i + 7];
>             shuffle(); setState();
>         }
>     }
>     private void shuffle() {
>         arr[0] ^= arr[1] <<  11; arr[3] += arr[0]; arr[1] += arr[2];
>         arr[1] ^= arr[2] >>>  2; arr[4] += arr[1]; arr[2] += arr[3];
>         arr[2] ^= arr[3] <<   8; arr[5] += arr[2]; arr[3] += arr[4];
>         arr[3] ^= arr[4] >>> 16; arr[6] += arr[3]; arr[4] += arr[5];
>         arr[4] ^= arr[5] <<  10; arr[7] += arr[4]; arr[5] += arr[6];
>         arr[5] ^= arr[6] >>>  4; arr[0] += arr[5]; arr[6] += arr[7];
>         arr[6] ^= arr[7] <<   8; arr[1] += arr[6]; arr[7] += arr[0];
>         arr[7] ^= arr[0] >>>  9; arr[2] += arr[7]; arr[0] += arr[1];
>     }
>     private void setState() {
>         mem[i] =     arr[0]; mem[i + 1] = arr[1]; mem[i + 2] = arr[2];
>         mem[i + 3] = arr[3]; mem[i + 4] = arr[4]; mem[i + 5] = arr[5];
>         mem[i + 6] = arr[6]; mem[i + 7] = arr[7];
>     }
>     @Override
>     public ISAACRandom clone() {
>         try {
>             ISAACRandom cloned = (ISAACRandom) super.clone();
>             cloned.rsl = rsl.clone();
>             cloned.mem = mem.clone();
>             cloned.arr = arr.clone();
>             return cloned;
>         } catch (CloneNotSupportedException e) {
>             throw new InternalError(e.getMessage());
>         }
>     }
> }

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message