Xor() public method

public Xor ( BigInteger value ) : BigInteger
value BigInteger
return BigInteger
Ejemplo n.º 1
0
		public int DoFinal(byte[] output, int outOff)
		{
			int extra = bufOff;
			if (!forEncryption)
			{
				if (extra < macSize)
					throw new InvalidCipherTextException("data too short");

				extra -= macSize;
			}

			if (extra > 0)
			{
				byte[] tmp = new byte[BlockSize];
				Array.Copy(bufBlock, 0, tmp, 0, extra);
				gCTRBlock(tmp, extra, output, outOff);
			}

			// Final gHASH
			BigInteger X = BigInteger.ValueOf(A.Length * 8).ShiftLeft(64).Add(
				BigInteger.ValueOf(totalLength * 8));
			//trace("len(A)||len(C): " + dumpBigInt(X));

			S = multiply(S.Xor(X), H);
			//trace("GHASH(H,A,C): " + dumpBigInt(S));

			// T = MSBt(GCTRk(J0,S))
			byte[] tBytes = new byte[BlockSize];
			cipher.ProcessBlock(J0, 0, tBytes, 0);
			//trace("E(K,Y0): " + new string(Hex.encode(tmp)));
			BigInteger T = S.Xor(new BigInteger(1, tBytes));

			// TODO Fix this if tagLength becomes configurable
			byte[] tag = asBlock(T);
			//trace("T: " + new string(Hex.encode(tag)));

			int resultLen = extra;

			if (forEncryption)
			{
				this.macBlock = tag;
				Array.Copy(tag, 0, output, outOff + bufOff, tag.Length);
				resultLen += tag.Length;
			}
			else
			{
				this.macBlock = new byte[macSize];
				Array.Copy(bufBlock, extra, macBlock, 0, macSize);
				if (!Arrays.AreEqual(tag, this.macBlock))
					throw new InvalidCipherTextException("mac check in GCM failed");
			}

			Reset(false);

			return resultLen;
		}
        /// <summary>
        /// Generate a set of M-of-N parts for a specific private key.
        /// If desiredPrivKey is null, then a random key will be selected.
        /// </summary>
        public void Generate(int PartsNeededToDecode, int PartsToGenerate, byte[] desiredPrivKey)
        {
            if (PartsNeededToDecode > PartsToGenerate) {
                throw new ApplicationException("Number of parts needed exceeds number of parts to generate.");
            }

            if (PartsNeededToDecode > 8 || PartsToGenerate > 8) {
                throw new ApplicationException("Maximum number of parts is 8");
            }

            if (PartsNeededToDecode < 1 || PartsToGenerate < 1) {
                throw new ApplicationException("Minimum number of parts is 1");
            }

            if (desiredPrivKey != null && desiredPrivKey.Length != 32) {
                throw new ApplicationException("Desired private key must be 32 bytes");
            }

            KeyParts.Clear();
            decodedKeyParts.Clear();

            SecureRandom sr = new SecureRandom();

            // Get 8 random big integers into v[i].
            byte[][] vvv = new byte[8][];
            BigInteger[] v = new BigInteger[8];

            for (int i = 0; i < 8; i++) {
                byte[] b = new byte[32];
                sr.NextBytes(b, 0, 32);
                // For larger values of i, chop off some most-significant-bits to prevent overflows as they are
                // multiplied with increasingly larger factors.
                if (i >= 7) {
                    b[0] &= 0x7f;
                }
                v[i] = new BigInteger(1, b);
                Debug.WriteLine(String.Format("v({0})={1}", i, v[i].ToString()));

            }

            // if a certain private key is desired, then specify it.
            if (desiredPrivKey != null) {
                // replace v[0] with xor(v[1...7]) xor desiredPrivKey
                BigInteger newv0 = BigInteger.Zero;
                for (int i=1; i<PartsNeededToDecode; i++) {
                    newv0 = newv0.Xor(v[i]);
                }
                v[0] = newv0.Xor(new BigInteger(1,desiredPrivKey));

            }

            // Generate the expected private key from all the parts
            BigInteger privkey = new BigInteger("0");
            for (int i = 0; i < PartsNeededToDecode; i++) {
                privkey = privkey.Xor(v[i]);
            }

            // Get the bitcoin address
            byte[] keybytes = privkey.ToByteArrayUnsigned();
            // make sure we have 32 bytes, we'll need it
            if (keybytes.Length < 32) {
                byte[] array32 = new byte[32];
                Array.Copy(keybytes, 0, array32, 32 - keybytes.Length, keybytes.Length);
                keybytes = array32;
            }
            KeyPair = new KeyPair(keybytes);

            byte[] checksum = Util.ComputeSha256(BitcoinAddress);

            // Generate the parts
            for (int i = 0; i < PartsToGenerate; i++) {
                BigInteger total = new BigInteger("0");
                for (int j = 0; j < PartsNeededToDecode; j++) {

                    int factor = 1;
                    for (int ii = 0; ii <= i; ii++) factor = factor * (j + 1);

                    BigInteger bfactor = new BigInteger(factor.ToString());

                    total = total.Add(v[j].Multiply(bfactor));
                }

                Debug.WriteLine(String.Format(" pc{0}={1}", i, total.ToString()));
                byte[] parts = new byte[39];
                parts[0] = 0x4f;
                parts[1] = (byte)(0x93 + PartsNeededToDecode);
                int parts23 = (((checksum[0] << 8) + checksum[1]) & 0x1ff);
                Debug.WriteLine("checksum " + parts23.ToString());
                parts23 += 0x6000;
                parts23 += (i << 9);
                byte[] btotal = total.ToByteArrayUnsigned();
                for (int jj = 0; jj < btotal.Length; jj++) {
                    parts[jj + 4 + (35 - btotal.Length)] = btotal[jj];
                }

                parts[2] = (byte)((parts23 & 0xFF00) >> 8);
                parts[3] = (byte)(parts23 & 0xFF);

                KeyParts.Add(Util.ByteArrayToBase58Check(parts));
                decodedKeyParts.Add(parts);
            }
        }