Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AND, OR and XOR bitops to Integer class #336

Closed
noloader opened this issue Nov 23, 2016 · 2 comments
Closed

Add AND, OR and XOR bitops to Integer class #336

noloader opened this issue Nov 23, 2016 · 2 comments

Comments

@noloader
Copy link
Collaborator

noloader commented Nov 23, 2016

Add AND, OR and XOR bitops to Integer class.

This will help support some ciphers, like Poly1305. Users may also find it useful, so an external interface should be made available.

The primitive operations are already available in <words.h>: AndWords, OrWords and XorWords.

@noloader
Copy link
Collaborator Author

noloader commented Nov 23, 2016

Here's the test data generator. To compile and run it, issue javac TestData.java && java TestData.

import java.util.Random;
import java.util.Formatter;
import java.math.BigInteger;

public class TestData {
   public static void main(String[] args) throws Exception {
      System.out.println("Java-based test data generator");
      System.out.println("==============================\n");
      
      System.out.println("struct Bitops_TestTuple");
      System.out.println("{");
      System.out.println("    // m,n are operands; a,o,x are and,or,xor results");
      System.out.println("    const char *m, *n, *a, *o, *x;");
      System.out.println("};");
      
      Random prng = new Random();
      
      ///////////////////////////////////////////////////////////////
      System.out.println("static const Bitops_TestTuple tests[] = {");
      ///////////////////////////////////////////////////////////////
      
      // 32-bit test data
      {
         int m,n,a,o,x;
         for(int i=0; i < 16; i++)
         {
            m = prng.nextInt(); n = prng.nextInt();
            a = m & n;
            o = m | n;
            x = m ^ n;

            Formatter formatter = new Formatter();
            formatter.format("        \"0x%s\", \"0x%s\", \"0x%s\", \"0x%s\", \"0x%s\"",
               Integer.toHexString(m), Integer.toHexString(n),
               Integer.toHexString(a), Integer.toHexString(o), Integer.toHexString(x));

            System.out.println("    {");
            System.out.println(formatter);
            System.out.println("    },");
         }
      }

      // 64-bit test data
      {
         long m,n,a,o,x;
         for(int i=0; i < 16; i++)
         {
            m = prng.nextLong(); n = prng.nextLong();
            a = m & n;
            o = m | n;
            x = m ^ n;

            Formatter formatter = new Formatter();
            formatter.format("        \"0x%s\", \"0x%s\", \"0x%s\", \"0x%s\", \"0x%s\"",
               Long.toHexString(m), Long.toHexString(n),
               Long.toHexString(a), Long.toHexString(o), Long.toHexString(x));

            System.out.println("    {");
            System.out.println(formatter);
            System.out.println("    },");
         }
      }
      
      // arbitrary-sized test data
      {
         BigInteger m,n,a,o,x;
         for(int i=0; i < 64; i++)
         {
            // int s1 = prng.nextInt(128, 1024), s2 = prng.nextInt(128, 1024);
            int s1 = 128 + (prng.nextInt(1024 - 128));
            int s2 = 128 + (prng.nextInt(1024 - 128));
   
            m = new BigInteger(s1, prng); n = new BigInteger(s2, prng);
            a = m.and(n);
            o = m.or(n);
            x = m.xor(n);

            Formatter formatter = new Formatter();
            formatter.format("        \"0x%s\",\n" +
                             "        \"0x%s\",\n" +
                             "        \"0x%s\",\n" +
                             "        \"0x%s\",\n" +
                             "        \"0x%s\""    ,                            
               m.toString(16), n.toString(16), a.toString(16),
               o.toString(16), x.toString(16));

            System.out.println("    {");
            System.out.println(formatter);
            System.out.println("    },");
         }
      }
      
      ///////////////////////////////////////////////////////////////
      System.out.println("};");  // Bitops_TestTuple
      ///////////////////////////////////////////////////////////////
      
       /*
    bool opa=true, opo=true, opx=true;

    //////////////////// AND ////////////////////

    for (size_t i=0; i<COUNTOF(tests); i++)
    {
        Integer m(tests[i].m), n(tests[i].n), a(tests[i].a);

        opa &= ((m & n) == a);
        opa &= ((-m & n) == a);
        opa &= ((m & -n) == a);
        opa &= ((-m & -n) == a);
      
        Integer t(m); t &= n;
        opa &= (t == a);
        t = n; t &= m;		  
        opa &= (t == a);

        opa &= ((m & m) == m);
        opa &= ((n & n) == n);		   
    }

    if (!opa)
       cout << "FAILED:";
    else
       cout << "passed:";
    cout << "  " << " Bitwise AND from 32-bits to 1024-bits" << endl;

    //////////////////// OR ////////////////////

    for (size_t i=0; i<COUNTOF(tests); i++)
    {
        Integer m(tests[i].m), n(tests[i].n), o(tests[i].o);

        opo &= ((m | n) == o);
        opo &= ((-m | n) == o);
        opo &= ((m | -n) == o);
        opo &= ((-m | -n) == o);
      
        Integer t(m); t |= n;
        opo &= (t == o);
        t = n; t |= m;		  
        opo &= (t == o);

        opo &= ((m | m) == m);
        opo &= ((n | n) == n);
    }

    if (!opo)
       cout << "FAILED:";
    else
       cout << "passed:";
    cout << "  " << " Bitwise OR from 32-bits to 1024-bits" << endl;

    //////////////////// XOR ////////////////////

    for (size_t i=0; i<COUNTOF(tests); i++)
    {
        Integer m(tests[i].m), n(tests[i].n),x(tests[i].x);

        opx &= ((m ^ n) == x);
        opx &= ((-m ^ n) == x);
        opx &= ((m ^ -n) == x);
        opx &= ((-m ^ -n) == x);

        Integer t(m); t ^= n;
        opx &= (t == x);
        t = n; t ^= m;		  
        opx &= (t == x);

        opx &= ((m ^ m) == Integer::Zero());
        opx &= ((n ^ n) == Integer::Zero());
    }

    if (!opx)
       cout << "FAILED:";
    else
       cout << "passed:";
    cout << "  " << " Bitwise XOR from 32-bits to 1024-bits" << endl;

    return opa && opo && opx;
       */
   }
}

@noloader
Copy link
Collaborator Author

noloader commented Nov 24, 2016

Also see Commit 16ffe513a4211019, Commit beb9df9d9e3755ce and Commit ccef9149afc698fc. The first commit added the functionality. The last two commits were defensive to ensure no unexpected behavior on a corner case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant