Hello,

I'm implementing a chameleon hash function which works as follow: MathBin.net - Untitled
In my secret key I have an array s where each s[i] is one square root of the inverse of u[i], which is in the public key.
All of these calculations happen in Z mod N. Now on a piece of paper this all works out fine, but in java using BigInteger i'm failing in the last step because in order to calculate z' I have to divide two BigInteger, which seems to be the source of my headaches. What can I do to make the calculation which works in the math world (piece of paper)
work in my java code? At the end you can see the relevant methods

greetings,
woosim

Java Code:
       /**
         * Computes the chameleon hash h = u^c * z^2 using some random z.
         *
         * @param m message
         * @param pk public key
         * @return chameleon hash object
         */
        public CHValue hash(BigInteger m, CHPublicKey pk){
               
                // Pick random z
                BigInteger z = BigInteger.ZERO;
                while(z.compareTo(BigInteger.ZERO) == 0){ z = new BigInteger(Configuration.SECURITY_PARAMETER, sc); }
               
                return hash(m, z, pk);
        }
 
        /**
         * Computes the chameleon hash h = u^c * z^2 using a fixed z.
         *
         * @param m message
         * @param r randomness
         * @param pk public key
         * @return chameleon hash object
         */
        public CHValue hash(BigInteger m, BigInteger z, CHPublicKey pk){
                if(m == null || pk == null || z == null)
                        throw new IllegalArgumentException("ChameleonHash.hash: One or more parameter are null!");
                else if(m.bitLength() > Configuration.CHALLENGE_LENGTH)
                        throw new IllegalArgumentException("ChameleonHash.hash: message length bigger than allowed challenge length!");
               
                // Object that stores the hash
                CHValue hash = new CHValue();
               
                // Compute conditional product u^c
                BigInteger uc = BigInteger.ONE;
                char[] bitsOfM = m.toString(2).toCharArray();
               
                uc = conditionalProd(pk.getU(), bitsOfM, pk.getN());
               
                hash.setHashValue(uc.multiply(z).multiply(z).mod(pk.getN()));
                hash.setMessage(m);
                hash.setRandomness(z);
               
                return hash;
        }
 
        /**
         * computes the product of all u[i], where bits[i] equals 1 mod N
         *
         * @param u
         * @param bits
         * @return
         */
        private BigInteger conditionalProd(BigInteger[] u, char[] bits, BigInteger N){
               
                BigInteger uc = BigInteger.ONE;
               
                for(int i = 0; i < bits.length; i++){
                        if(bits[i] == '1')
                                uc = uc.multiply(u[i]).mod(N);
                }
                return uc;
        }
 
 
 
public CHValue colFinder(CHValue knownHash, BigInteger secondMessage, CHKeyPair keyPair){
               
                BigInteger[] roots = new BigInteger[4];
               
                BigInteger p = keyPair.getSk().getP();
                BigInteger q = keyPair.getSk().getQ();
                BigInteger N = keyPair.getPk().getN();
               
                BigInteger[] s = keyPair.getSk().getS();
               
                // Convert messages to binary strings
                char[] bitsOfNewMessage = secondMessage.toString(2).toCharArray();
                char[] bitsOfOldMessage = knownHash.getMessage().toString(2).toCharArray();
               
                // compute a = sqrt(condProd(u, oldMessage, N)) = inv(s_k1)*inv(s_k2)*...
                BigInteger tmp;
                BigInteger a = BigInteger.ONE;
                for(int i = 0; i < bitsOfOldMessage.length;i++){
                        if(bitsOfOldMessage[i] == '0')
                                continue;
                       
                        tmp = ModularArith.inverseModPQ(s[i], p, q);
                        a = a.multiply(tmp).mod(N);
                }
               
                // a = a*z
                a.multiply(knownHash.getRandomness()).mod(N);
               
                // compute b = sqrt(condProd(u, newMessage, N)) = inv(s_l1)*inv(s_l2)*...
                BigInteger b = BigInteger.ONE;
                tmp = BigInteger.ONE;
                for(int i = 0; i < bitsOfNewMessage.length;i++){
                        if(bitsOfNewMessage[i] == '0')
                                continue;
                       
                        tmp = ModularArith.inverseModPQ(s[i], p, q);
                        b = b.multiply(tmp).mod(N);
                }
               
                System.out.println("a: " + a);
                System.out.println("b: " + b);
                BigInteger z = a.divide(b);
                System.out.println("z: " + z + "\n");
               
                // Create new chameleon hash object
                CHValue newHash = new CHValue();
               
                newHash.setMessage(secondMessage);
                newHash.setRandomness(z);
                newHash.setHashValue(knownHash.getHashValue());
               
                return newHash;
        }