Java Code Examples for org.bouncycastle.math.ec.ECPoint#isInfinity()

The following examples show how to use org.bouncycastle.math.ec.ECPoint#isInfinity() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ECDSA.java    From bushido-java-core with GNU General Public License v3.0 6 votes vote down vote up
private boolean hasError(ECDSASignature signature) {
    final BigInteger r = signature.r;
    final BigInteger s = signature.s;
    if (!(r.compareTo(BigInteger.ZERO) == 1 && r.compareTo(key.params.getN()) == -1) || !(s.compareTo(BigInteger.ZERO) == 1 && s.compareTo(key.params.getN()) == -1)) {
        //r and s not in range
        return true;
    }
    final BigInteger e = BigIntegerUtil.fromBytes(hashbuf, 16, endian);
    final BigInteger n = key.params.getN();
    final BigInteger sinv = s.modInverse(n);
    final BigInteger u1 = sinv.multiply(e).mod(n);
    final BigInteger u2 = sinv.multiply(r).mod(n);
    final ECPoint g = key.params.getG();
    final ECPoint p = ECAlgorithms.sumOfTwoMultiplies(g, u1, key.curve.getCurve().decodePoint(key.getPublic()), u2).normalize();
    if (p.isInfinity()) {
        //p is infinity
        return true;
    }
    if (p.getAffineXCoord().toBigInteger().mod(n).compareTo(r) != 0) {
        //invalid signature
        return true;
    } else {
        return false;
    }
}
 
Example 2
Source File: SM2Util.java    From chain33-sdk-java with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * 判断生成的公钥是否合法
 * 
 * @param publicKey
 * @return
 */
private static boolean checkPublicKey(ECPoint publicKey) {

	if (!publicKey.isInfinity()) {

		BigInteger x = publicKey.getXCoord().toBigInteger();
		BigInteger y = publicKey.getYCoord().toBigInteger();

		if (between(x, new BigInteger("0"), p) && between(y, new BigInteger("0"), p)) {

			BigInteger xResult = x.pow(3).add(a.multiply(x)).add(b).mod(p);
			BigInteger yResult = y.pow(2).mod(p);

			if (yResult.equals(xResult) && publicKey.multiply(n).isInfinity()) {
				return true;
			}
		}
	}
	return false;
}
 
Example 3
Source File: SM2Util.java    From chain33-sdk-java with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * 密钥协商发起方交换
 * 
 * @param entity 传输实体
 * @return 发起方检验后的传输实体(null:检验失败)
 */
public TransportEntity InitiatorExchange(TransportEntity entity) {
	BigInteger x1 = RA.getXCoord().toBigInteger();
	x1 = _2w.add(x1.and(_2w.subtract(BigInteger.ONE)));

	BigInteger tA = keyPair.getPrivateKey().add(x1.multiply(rA)).mod(n);
	ECPoint RB = curve.decodePoint(entity.R).normalize();
	
	BigInteger x2 = RB.getXCoord().toBigInteger();
	x2 = _2w.add(x2.and(_2w.subtract(BigInteger.ONE)));

	ECPoint bPublicKey=curve.decodePoint(entity.K).normalize();
	ECPoint temp = bPublicKey.add(RB.multiply(x2).normalize()).normalize();
	ECPoint U = temp.multiply(ecc_bc_spec.getH().multiply(tA)).normalize();
	if (U.isInfinity())
		throw new IllegalStateException();
	this.V=U;
	
	byte[] xU = U.getXCoord().toBigInteger().toByteArray();
	byte[] yU = U.getYCoord().toBigInteger().toByteArray();
	byte[] KA = KDF(join(xU, yU,
			this.Z, entity.Z), 16);
	key = KA;

	byte[] s1= sm3hash(new byte[] { 0x02 }, yU,
			sm3hash(xU, this.Z, entity.Z, RA.getXCoord().toBigInteger().toByteArray(),
					RA.getYCoord().toBigInteger().toByteArray(), RB.getXCoord().toBigInteger().toByteArray(),
					RB.getYCoord().toBigInteger().toByteArray()));

	if(!Arrays.equals(entity.S, s1)) {
		return null;
	}

	byte[] sA = sm3hash(new byte[]{0x03}, yU,
			sm3hash(xU, this.Z, entity.Z, RA.getXCoord().toBigInteger().toByteArray(),
					RA.getYCoord().toBigInteger().toByteArray(), RB.getXCoord().toBigInteger().toByteArray(),
					RB.getYCoord().toBigInteger().toByteArray()));

	return new TransportEntity(RA.getEncoded(false), sA, this.Z, keyPair.getPublicKey());
}
 
Example 4
Source File: ECCurvePoint.java    From InflatableDonkey with MIT License 5 votes vote down vote up
public byte[] agreement(BigInteger d) {
    // TODO thread safety of ECPoint unclear.
    synchronized (lock) {
        ECPoint P = Q.multiply(d).normalize();
        if (P.isInfinity()) {
            throw new IllegalStateException("invalid EDCH: infinity");
        }

        return P.getAffineXCoord().getEncoded();
    }
}
 
Example 5
Source File: SM2Signer.java    From web3sdk with Apache License 2.0 5 votes vote down vote up
private boolean verifySignature(BigInteger r, BigInteger s) {
    BigInteger n = ecParams.getN();

    // 5.3.1 Draft RFC:  SM2 Public Key Algorithms
    // B1
    if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) {
        return false;
    }

    // B2
    if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) {
        return false;
    }

    // B3
    byte[] eHash = digestDoFinal();

    // B4
    BigInteger e = calculateE(eHash);

    // B5
    BigInteger t = r.add(s).mod(n);
    if (t.equals(ZERO)) {
        return false;
    }

    // B6
    ECPoint q = ((ECPublicKeyParameters) ecKey).getQ();
    ECPoint x1y1 = ECAlgorithms.sumOfTwoMultiplies(ecParams.getG(), s, q, t).normalize();
    if (x1y1.isInfinity()) {
        return false;
    }

    // B7
    BigInteger expectedR = e.add(x1y1.getAffineXCoord().toBigInteger()).mod(n);

    return expectedR.equals(r);
}
 
Example 6
Source File: Signer.java    From evt4j with MIT License 5 votes vote down vote up
/**
 * return true if the value r and s represent a DSA signature for the passed in
 * message (for standard DSA the message should be a SHA-1 hash of the real
 * message to be verified).
 */
@Override
public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) {
    ECDomainParameters ec = key.getParameters();
    BigInteger n = ec.getN();
    BigInteger e = calculateE(n, message);

    // r in the range [1,n-1]
    if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) {
        return false;
    }

    // s in the range [1,n-1]
    if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) {
        return false;
    }

    BigInteger c = s.modInverse(n);

    BigInteger u1 = e.multiply(c).mod(n);
    BigInteger u2 = r.multiply(c).mod(n);

    ECPoint G = ec.getG();
    ECPoint Q = ((ECPublicKeyParameters) key).getQ();

    ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2).normalize();

    // components must be bogus.
    if (point.isInfinity()) {
        return false;
    }

    BigInteger v = point.getAffineXCoord().toBigInteger().mod(n);

    return v.equals(r);
}
 
Example 7
Source File: SM2PreprocessSigner.java    From gmhelper with Apache License 2.0 5 votes vote down vote up
private boolean verifySignature(byte[] eHash, BigInteger r, BigInteger s) {
    BigInteger n = ecParams.getN();

    // 5.3.1 Draft RFC:  SM2 Public Key Algorithms
    // B1
    if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) {
        return false;
    }

    // B2
    if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) {
        return false;
    }

    // B3 eHash

    // B4
    BigInteger e = calculateE(eHash);

    // B5
    BigInteger t = r.add(s).mod(n);
    if (t.equals(ZERO)) {
        return false;
    }

    // B6
    ECPoint q = ((ECPublicKeyParameters) ecKey).getQ();
    ECPoint x1y1 = ECAlgorithms.sumOfTwoMultiplies(ecParams.getG(), s, q, t).normalize();
    if (x1y1.isInfinity()) {
        return false;
    }

    // B7
    BigInteger expectedR = e.add(x1y1.getAffineXCoord().toBigInteger()).mod(n);

    return expectedR.equals(r);
}
 
Example 8
Source File: SM2Tool.java    From ID-SDK with Apache License 2.0 5 votes vote down vote up
/**
 * 判断生成的公钥是否合法
 * 
 * @param publicKey
 * @return
 */
private boolean checkPublicKey(ECPoint publicKey) {

	if (!publicKey.isInfinity()) {

		BigInteger x = publicKey.getXCoord().toBigInteger();
		BigInteger y = publicKey.getYCoord().toBigInteger();

		if (between(x, new BigInteger("0"), p) && between(y, new BigInteger("0"), p)) {

			BigInteger xResult = x.pow(3).add(a.multiply(x)).add(b).mod(p);

			if (debug)
				System.out.println("xResult: " + xResult.toString());

			BigInteger yResult = y.pow(2).mod(p);

			if (debug)
				System.out.println("yResult: " + yResult.toString());

			if (yResult.equals(xResult) && publicKey.multiply(n).isInfinity()) {
				return true;
			}
		}
	}
	return false;
}
 
Example 9
Source File: SM2Util.java    From chain33-sdk-java with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * 公钥加密
 * 
 * @param input
 *            加密原文
 * @param publicKey
 *            公钥
 * @return
 */
public static byte[] encrypt(String input, ECPoint publicKey) {

	byte[] inputBuffer = input.getBytes();
	byte[] C1Buffer;
	ECPoint kpb;
	byte[] t;
	do {
		/* 1 产生随机数k,k属于[1, n-1] */
		BigInteger k = random(n);

		/* 2 计算椭圆曲线点C1 = [k]G = (x1, y1) */
		ECPoint C1 = G.multiply(k);
		C1Buffer = C1.getEncoded(false);

		/*
		 * 3 计算椭圆曲线点 S = [h]Pb
		 */
		BigInteger h = ecc_bc_spec.getH();
		if (h != null) {
			ECPoint S = publicKey.multiply(h);
			if (S.isInfinity())
				throw new IllegalStateException();
		}

		/* 4 计算 [k]PB = (x2, y2) */
		kpb = publicKey.multiply(k).normalize();

		/* 5 计算 t = KDF(x2||y2, klen) */
		byte[] kpbBytes = kpb.getEncoded(false);
		t = KDF(kpbBytes, inputBuffer.length);
	} while (allZero(t));

	/* 6 计算C2=M^t */
	byte[] C2 = new byte[inputBuffer.length];
	for (int i = 0; i < inputBuffer.length; i++) {
		C2[i] = (byte) (inputBuffer[i] ^ t[i]);
	}

	/* 7 计算C3 = Hash(x2 || M || y2) */
	byte[] C3 = sm3hash(kpb.getXCoord().toBigInteger().toByteArray(), inputBuffer,
			kpb.getYCoord().toBigInteger().toByteArray());

	/* 8 输出密文 C=C1 || C2 || C3 */

	byte[] encryptResult = new byte[C1Buffer.length + C2.length + C3.length];

	System.arraycopy(C1Buffer, 0, encryptResult, 0, C1Buffer.length);
	System.arraycopy(C2, 0, encryptResult, C1Buffer.length, C2.length);
	System.arraycopy(C3, 0, encryptResult, C1Buffer.length + C2.length, C3.length);

	return encryptResult;
}
 
Example 10
Source File: SM2Util.java    From chain33-sdk-java with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * 私钥解密
 * 
 * @param encryptData
 *            密文数据字节数组
 * @param privateKey
 *            解密私钥
 * @return
 */
public static String decrypt(byte[] encryptData, BigInteger privateKey) {
	byte[] C1Byte = new byte[65];
	System.arraycopy(encryptData, 0, C1Byte, 0, C1Byte.length);

	ECPoint C1 = curve.decodePoint(C1Byte).normalize();

	/*
	 * 计算椭圆曲线点 S = [h]C1 是否为无穷点
	 */
	BigInteger h = ecc_bc_spec.getH();
	if (h != null) {
		ECPoint S = C1.multiply(h);
		if (S.isInfinity())
			throw new IllegalStateException();
	}
	/* 计算[dB]C1 = (x2, y2) */
	ECPoint dBC1 = C1.multiply(privateKey).normalize();

	/* 计算t = KDF(x2 || y2, klen) */
	byte[] dBC1Bytes = dBC1.getEncoded(false);
	int klen = encryptData.length - 65 - DIGEST_LENGTH;
	byte[] t = KDF(dBC1Bytes, klen);

	if (allZero(t)) {
		System.err.println("all zero");
		throw new IllegalStateException();
	}

	/* 5 计算M'=C2^t */
	byte[] M = new byte[klen];
	for (int i = 0; i < M.length; i++) {
		M[i] = (byte) (encryptData[C1Byte.length + i] ^ t[i]);
	}

	/* 6 计算 u = Hash(x2 || M' || y2) 判断 u == C3是否成立 */
	byte[] C3 = new byte[DIGEST_LENGTH];

	System.arraycopy(encryptData, encryptData.length - DIGEST_LENGTH, C3, 0, DIGEST_LENGTH);
	byte[] u = sm3hash(dBC1.getXCoord().toBigInteger().toByteArray(), M,
			dBC1.getYCoord().toBigInteger().toByteArray());
	if (Arrays.equals(u, C3)) {
		try {
			return new String(M, "UTF8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	} else {
		return null;
	}
}
 
Example 11
Source File: SECP256K1.java    From cava with Apache License 2.0 4 votes vote down vote up
/**
 * Given the components of a signature and a selector value, recover and return the public key that generated the
 * signature according to the algorithm in SEC1v2 section 4.1.6.
 *
 * <p>
 * The recovery id is an index from 0 to 3 which indicates which of the 4 possible keys is the correct one. Because
 * the key recovery operation yields multiple potential keys, the correct key must either be stored alongside the
 * signature, or you must be willing to try each recovery id in turn until you find one that outputs the key you are
 * expecting.
 *
 * <p>
 * If this method returns null it means recovery was not possible and recovery id should be iterated.
 *
 * <p>
 * Given the above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the output is
 * null OR a key that is not the one you expect, you try again with the next recovery id.
 *
 * @param v Which possible key to recover.
 * @param r The R component of the signature.
 * @param s The S component of the signature.
 * @param messageHash Hash of the data that was signed.
 * @return A ECKey containing only the public part, or {@code null} if recovery wasn't possible.
 */
@Nullable
private static BigInteger recoverFromSignature(int v, BigInteger r, BigInteger s, Bytes32 messageHash) {
  assert (v == 0 || v == 1);
  assert (r.signum() >= 0);
  assert (s.signum() >= 0);
  assert (messageHash != null);

  // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
  // So it's encoded in the recovery id (v).
  ECPoint R = decompressKey(r, (v & 1) == 1);
  // 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).
  if (R == null || !R.multiply(Parameters.CURVE_ORDER).isInfinity()) {
    return null;
  }

  // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
  BigInteger e = messageHash.toUnsignedBigInteger();
  // 1.6. For k from 1 to 2 do the following. (loop is outside this function via iterating v)
  // 1.6.1. Compute a candidate public key as:
  //   Q = mi(r) * (sR - eG)
  //
  // Where mi(x) is the modular multiplicative inverse. We transform this into the following:
  //   Q = (mi(r) * s ** R) + (mi(r) * -e ** G)
  // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n).
  // In the above equation ** is point multiplication and + is point addition (the EC group
  // operator).
  //
  // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
  // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.
  BigInteger eInv = BigInteger.ZERO.subtract(e).mod(Parameters.CURVE_ORDER);
  BigInteger rInv = r.modInverse(Parameters.CURVE_ORDER);
  BigInteger srInv = rInv.multiply(s).mod(Parameters.CURVE_ORDER);
  BigInteger eInvrInv = rInv.multiply(eInv).mod(Parameters.CURVE_ORDER);
  ECPoint q = ECAlgorithms.sumOfTwoMultiplies(Parameters.CURVE.getG(), eInvrInv, R, srInv);

  if (q.isInfinity()) {
    return null;
  }

  byte[] qBytes = q.getEncoded(false);
  // We remove the prefix
  return new BigInteger(1, Arrays.copyOfRange(qBytes, 1, qBytes.length));
}
 
Example 12
Source File: SECP256K1.java    From incubator-tuweni with Apache License 2.0 4 votes vote down vote up
/**
 * Given the components of a signature and a selector value, recover and return the public key that generated the
 * signature according to the algorithm in SEC1v2 section 4.1.6.
 *
 * <p>
 * The recovery id is an index from 0 to 3 which indicates which of the 4 possible keys is the correct one. Because
 * the key recovery operation yields multiple potential keys, the correct key must either be stored alongside the
 * signature, or you must be willing to try each recovery id in turn until you find one that outputs the key you are
 * expecting.
 *
 * <p>
 * If this method returns null it means recovery was not possible and recovery id should be iterated.
 *
 * <p>
 * Given the above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the output is
 * null OR a key that is not the one you expect, you try again with the next recovery id.
 *
 * @param v Which possible key to recover.
 * @param r The R component of the signature.
 * @param s The S component of the signature.
 * @param messageHash Hash of the data that was signed.
 * @return A ECKey containing only the public part, or {@code null} if recovery wasn't possible.
 */
@Nullable
private static BigInteger recoverFromSignature(int v, BigInteger r, BigInteger s, Bytes32 messageHash) {
  assert (v == 0 || v == 1);
  assert (r.signum() >= 0);
  assert (s.signum() >= 0);
  assert (messageHash != null);

  // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities.
  // So it's encoded in the recovery id (v).
  ECPoint R = decompressKey(r, (v & 1) == 1);
  // 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility).
  if (R == null || !R.multiply(Parameters.CURVE_ORDER).isInfinity()) {
    return null;
  }

  // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification.
  BigInteger e = messageHash.toUnsignedBigInteger();
  // 1.6. For k from 1 to 2 do the following. (loop is outside this function via iterating v)
  // 1.6.1. Compute a candidate public key as:
  //   Q = mi(r) * (sR - eG)
  //
  // Where mi(x) is the modular multiplicative inverse. We transform this into the following:
  //   Q = (mi(r) * s ** R) + (mi(r) * -e ** G)
  // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n).
  // In the above equation ** is point multiplication and + is point addition (the EC group
  // operator).
  //
  // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive
  // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8.
  BigInteger eInv = BigInteger.ZERO.subtract(e).mod(Parameters.CURVE_ORDER);
  BigInteger rInv = r.modInverse(Parameters.CURVE_ORDER);
  BigInteger srInv = rInv.multiply(s).mod(Parameters.CURVE_ORDER);
  BigInteger eInvrInv = rInv.multiply(eInv).mod(Parameters.CURVE_ORDER);
  ECPoint q = ECAlgorithms.sumOfTwoMultiplies(Parameters.CURVE.getG(), eInvrInv, R, srInv);

  if (q.isInfinity()) {
    return null;
  }

  byte[] qBytes = q.getEncoded(false);
  // We remove the prefix
  return new BigInteger(1, Arrays.copyOfRange(qBytes, 1, qBytes.length));
}
 
Example 13
Source File: ECDSASigner.java    From web3sdk with Apache License 2.0 4 votes vote down vote up
/**
 * return true if the value r and s represent a DSA signature for the passed in message (for
 * standard DSA the message should be a SHA-1 hash of the real message to be verified).
 */
@Override
public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) {
    ECDomainParameters ec = key.getParameters();
    BigInteger n = ec.getN();
    BigInteger e = calculateE(n, message);

    // r in the range [1,n-1]
    if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) {
        return false;
    }

    // s in the range [1,n-1]
    if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) {
        return false;
    }

    BigInteger c = s.modInverse(n);

    BigInteger u1 = e.multiply(c).mod(n);
    BigInteger u2 = r.multiply(c).mod(n);

    ECPoint G = ec.getG();
    ECPoint Q = ((ECPublicKeyParameters) key).getQ();

    ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2);

    // components must be bogus.
    if (point.isInfinity()) {
        return false;
    }

    /*
     * If possible, avoid normalizing the point (to save a modular inversion in the curve field).
     *
     * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
     * If the cofactor is known and small, we generate those possible field values and project each
     * of them to the same "denominator" (depending on the particular projective coordinates in use)
     * as the calculated point.X. If any of the projected values matches point.X, then we have:
     *     (point.X / Denominator mod p) mod n == r
     * as required, and verification succeeds.
     *
     * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
     * the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
     */
    ECCurve curve = point.getCurve();
    if (curve != null) {
        BigInteger cofactor = curve.getCofactor();
        if (cofactor != null && cofactor.compareTo(EIGHT) <= 0) {
            ECFieldElement D = getDenominator(curve.getCoordinateSystem(), point);
            if (D != null && !D.isZero()) {
                ECFieldElement X = point.getXCoord();
                while (curve.isValidFieldElement(r)) {
                    ECFieldElement R = curve.fromBigInteger(r).multiply(D);
                    if (R.equals(X)) {
                        return true;
                    }
                    r = r.add(n);
                }
                return false;
            }
        }
    }

    BigInteger v = point.normalize().getAffineXCoord().toBigInteger().mod(n);
    return v.equals(r);
}
 
Example 14
Source File: SM2.java    From protools with Apache License 2.0 4 votes vote down vote up
/**
 * 公钥加密
 *
 * @param input     加密原文
 * @param publicKey 公钥
 * @return
 */
public byte[] encrypt(String input, ECPoint publicKey) {

    byte[] inputBuffer = input.getBytes();

    byte[] C1Buffer;
    ECPoint kpb;
    byte[] t;
    do {
        /* 1 产生随机数k,k属于[1, n-1] */
        BigInteger k = random(n);

        /* 2 计算椭圆曲线点C1 = [k]G = (x1, y1) */
        ECPoint C1 = G.multiply(k);
        C1Buffer = C1.getEncoded(false);

        /*
         * 3 计算椭圆曲线点 S = [h]Pb
         */
        BigInteger h = ecc_bc_spec.getH();
        if (h != null) {
            ECPoint S = publicKey.multiply(h);
            if (S.isInfinity()) {
                throw new IllegalStateException();
            }
        }

        /* 4 计算 [k]PB = (x2, y2) */
        kpb = publicKey.multiply(k).normalize();

        /* 5 计算 t = KDF(x2||y2, klen) */
        byte[] kpbBytes = kpb.getEncoded(false);
        t = KDF(kpbBytes, inputBuffer.length);
        // DerivationFunction kdf = new KDF1BytesGenerator(new
        // ShortenedDigest(new SHA256Digest(), DIGEST_LENGTH));
        //
        // t = new byte[inputBuffer.length];
        // kdf.init(new ISO18033KDFParameters(kpbBytes));
        // kdf.generateBytes(t, 0, t.length);
    } while (allZero(t));

    /* 6 计算C2=M^t */
    byte[] C2 = new byte[inputBuffer.length];
    for (int i = 0; i < inputBuffer.length; i++) {
        C2[i] = (byte) (inputBuffer[i] ^ t[i]);
    }

    /* 7 计算C3 = Hash(x2 || M || y2) */
    byte[] C3 = sm3hash(kpb.getXCoord().toBigInteger().toByteArray(), inputBuffer,
            kpb.getYCoord().toBigInteger().toByteArray());

    /* 8 输出密文 C=C1 || C2 || C3 */

    byte[] encryptResult = new byte[C1Buffer.length + C2.length + C3.length];

    System.arraycopy(C1Buffer, 0, encryptResult, 0, C1Buffer.length);
    System.arraycopy(C2, 0, encryptResult, C1Buffer.length, C2.length);
    System.arraycopy(C3, 0, encryptResult, C1Buffer.length + C2.length, C3.length);

    return encryptResult;
}
 
Example 15
Source File: SM2.java    From protools with Apache License 2.0 4 votes vote down vote up
/**
 * 私钥解密
 *
 * @param encryptData 密文数据字节数组
 * @param privateKey  解密私钥
 * @return
 */
public String decrypt(byte[] encryptData, BigInteger privateKey) {

    byte[] C1Byte = new byte[65];
    System.arraycopy(encryptData, 0, C1Byte, 0, C1Byte.length);

    ECPoint C1 = curve.decodePoint(C1Byte).normalize();

    /*
     * 计算椭圆曲线点 S = [h]C1 是否为无穷点
     */
    BigInteger h = ecc_bc_spec.getH();
    if (h != null) {
        ECPoint S = C1.multiply(h);
        if (S.isInfinity()) {
            throw new IllegalStateException();
        }
    }
    /* 计算[dB]C1 = (x2, y2) */
    ECPoint dBC1 = C1.multiply(privateKey).normalize();

    /* 计算t = KDF(x2 || y2, klen) */
    byte[] dBC1Bytes = dBC1.getEncoded(false);
    int klen = encryptData.length - 65 - DIGEST_LENGTH;
    byte[] t = KDF(dBC1Bytes, klen);
    // DerivationFunction kdf = new KDF1BytesGenerator(new
    // ShortenedDigest(new SHA256Digest(), DIGEST_LENGTH));
    // if (debug)
    // System.out.println("klen = " + klen);
    // kdf.init(new ISO18033KDFParameters(dBC1Bytes));
    // kdf.generateBytes(t, 0, t.length);

    if (allZero(t)) {
        System.err.println("all zero");
        throw new IllegalStateException();
    }

    /* 5 计算M'=C2^t */
    byte[] M = new byte[klen];
    for (int i = 0; i < M.length; i++) {
        M[i] = (byte) (encryptData[C1Byte.length + i] ^ t[i]);
    }
    /* 6 计算 u = Hash(x2 || M' || y2) 判断 u == C3是否成立 */
    byte[] C3 = new byte[DIGEST_LENGTH];

    System.arraycopy(encryptData, encryptData.length - DIGEST_LENGTH, C3, 0, DIGEST_LENGTH);
    byte[] u = sm3hash(dBC1.getXCoord().toBigInteger().toByteArray(), M,
            dBC1.getYCoord().toBigInteger().toByteArray());
    if (Arrays.equals(u, C3)) {
        try {
            return new String(M, "UTF8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    } else {
        return null;
    }

}
 
Example 16
Source File: SM2.java    From protools with Apache License 2.0 4 votes vote down vote up
/**
 * 判断生成的公钥是否合法
 *
 * @param publicKey
 * @return
 */
private boolean checkPublicKey(ECPoint publicKey) {

    if (!publicKey.isInfinity()) {

        BigInteger x = publicKey.getXCoord().toBigInteger();
        BigInteger y = publicKey.getYCoord().toBigInteger();

        if (between(x, new BigInteger("0"), p) && between(y, new BigInteger("0"), p)) {

            BigInteger xResult = x.pow(3).add(a.multiply(x)).add(b).mod(p);

            BigInteger yResult = y.pow(2).mod(p);

            return yResult.equals(xResult) && publicKey.multiply(n).isInfinity();
        }
    }
    return false;
}
 
Example 17
Source File: SM2.java    From protools with Apache License 2.0 4 votes vote down vote up
/**
 * 密钥协商发起方第二步
 *
 * @param entity 传输实体
 */
public TransportEntity keyExchange_3(TransportEntity entity) {
    BigInteger x1 = RA.getXCoord().toBigInteger();
    x1 = _2w.add(x1.and(_2w.subtract(BigInteger.ONE)));

    BigInteger tA = keyPair.getPrivateKey().add(x1.multiply(rA)).mod(n);
    ECPoint RB = curve.decodePoint(entity.R).normalize();

    BigInteger x2 = RB.getXCoord().toBigInteger();
    x2 = _2w.add(x2.and(_2w.subtract(BigInteger.ONE)));

    ECPoint bPublicKey = curve.decodePoint(entity.K).normalize();
    ECPoint temp = bPublicKey.add(RB.multiply(x2).normalize()).normalize();
    ECPoint U = temp.multiply(ecc_bc_spec.getH().multiply(tA)).normalize();
    if (U.isInfinity()) {
        throw new IllegalStateException();
    }
    this.V = U;

    byte[] xU = U.getXCoord().toBigInteger().toByteArray();
    byte[] yU = U.getYCoord().toBigInteger().toByteArray();
    byte[] KA = KDF(join(xU, yU,
            this.Z, entity.Z), 16);
    key = KA;
    System.out.print("协商得A密钥:");
    printHexString(KA);
    byte[] s1 = sm3hash(new byte[]{0x02}, yU,
            sm3hash(xU, this.Z, entity.Z, RA.getXCoord().toBigInteger().toByteArray(),
                    RA.getYCoord().toBigInteger().toByteArray(), RB.getXCoord().toBigInteger().toByteArray(),
                    RB.getYCoord().toBigInteger().toByteArray()));
    if (Arrays.equals(entity.S, s1)) {
        System.out.println("B->A 密钥确认成功");
    } else {
        System.out.println("B->A 密钥确认失败");
    }
    byte[] sA = sm3hash(new byte[]{0x03}, yU,
            sm3hash(xU, this.Z, entity.Z, RA.getXCoord().toBigInteger().toByteArray(),
                    RA.getYCoord().toBigInteger().toByteArray(), RB.getXCoord().toBigInteger().toByteArray(),
                    RB.getYCoord().toBigInteger().toByteArray()));

    return new TransportEntity(RA.getEncoded(false), sA, this.Z, keyPair.getPublicKey());
}
 
Example 18
Source File: SM2Tool.java    From ID-SDK with Apache License 2.0 4 votes vote down vote up
/**
 * 私钥解密
 * 
 * @param encryptData
 *            密文数据字节数组
 * @param privateKey
 *            解密私钥
 * @return
 */
public String decrypt(byte[] encryptData, BigInteger privateKey) {

	if (debug)
		System.out.println("encryptData length: " + encryptData.length);

	byte[] C1Byte = new byte[65];
	System.arraycopy(encryptData, 0, C1Byte, 0, C1Byte.length);

	ECPoint C1 = curve.decodePoint(C1Byte).normalize();

	/*
	 * 计算椭圆曲线点 S = [h]C1 是否为无穷点
	 */
	BigInteger h = ecc_bc_spec.getH();
	if (h != null) {
		ECPoint S = C1.multiply(h);
		if (S.isInfinity())
			throw new IllegalStateException();
	}
	/* 计算[dB]C1 = (x2, y2) */
	ECPoint dBC1 = C1.multiply(privateKey).normalize();

	/* 计算t = KDF(x2 || y2, klen) */
	byte[] dBC1Bytes = dBC1.getEncoded(false);
	int klen = encryptData.length - 65 - DIGEST_LENGTH;
	byte[] t = KDF(dBC1Bytes, klen);
	if (allZero(t)) {
		System.err.println("all zero");
		throw new IllegalStateException();
	}

	/* 5 计算M'=C2^t */
	byte[] M = new byte[klen];
	for (int i = 0; i < M.length; i++) {
		M[i] = (byte) (encryptData[C1Byte.length + i] ^ t[i]);
	}
	if (debug)
		printHexString(M);

	/* 6 计算 u = Hash(x2 || M' || y2) 判断 u == C3是否成立 */
	byte[] C3 = new byte[DIGEST_LENGTH];

	if (debug)
		try {
			System.out.println("M = " + new String(M, "UTF8"));
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	System.arraycopy(encryptData, encryptData.length - DIGEST_LENGTH, C3, 0, DIGEST_LENGTH);
	byte[] u = sm3hash(dBC1.getXCoord().toBigInteger().toByteArray(), M,
			dBC1.getYCoord().toBigInteger().toByteArray());
	if (Arrays.equals(u, C3)) {
		if (debug)
			System.out.println("解密成功");
		try {
			return new String(M, "UTF8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	} else {
		if (debug) {
			System.out.print("u = ");
			printHexString(u);
			System.out.print("C3 = ");
			printHexString(C3);
			System.err.println("解密验证失败");
		}
		return null;
	}

}
 
Example 19
Source File: SM2Tool.java    From ID-SDK with Apache License 2.0 4 votes vote down vote up
/**
 * 公钥加密
 * 
 * @param input
 *            加密原文
 * @param publicKey
 *            公钥
 * @return
 */
public byte[] encrypt(String input, ECPoint publicKey) {
	byte[] inputBuffer = input.getBytes();
	if (debug)
		printHexString(inputBuffer);

	byte[] C1Buffer;
	ECPoint kpb;
	byte[] t;
	do {
		/* 1 产生随机数k,k属于[1, n-1] */
		BigInteger k = random(n);
		if (debug) {
			System.out.print("k: ");
			printHexString(k.toByteArray());
		}

		/* 2 计算椭圆曲线点C1 = [k]G = (x1, y1) */
		ECPoint C1 = G.multiply(k);
		C1Buffer = C1.getEncoded(false);
		if (debug) {
			System.out.print("C1: ");
			printHexString(C1Buffer);
		}

		/*
		 * 3 计算椭圆曲线点 S = [h]Pb
		 */
		BigInteger h = ecc_bc_spec.getH();
		if (h != null) {
			ECPoint S = publicKey.multiply(h);
			if (S.isInfinity())
				throw new IllegalStateException();
		}

		/* 4 计算 [k]PB = (x2, y2) */
		kpb = publicKey.multiply(k).normalize();

		/* 5 计算 t = KDF(x2||y2, klen) */
		byte[] kpbBytes = kpb.getEncoded(false);
		t = KDF(kpbBytes, inputBuffer.length);
	} while (allZero(t));

	/* 6 计算C2=M^t */
	byte[] C2 = new byte[inputBuffer.length];
	for (int i = 0; i < inputBuffer.length; i++) {
		C2[i] = (byte) (inputBuffer[i] ^ t[i]);
	}

	/* 7 计算C3 = Hash(x2 || M || y2) */
	byte[] C3 = sm3hash(kpb.getXCoord().toBigInteger().toByteArray(), inputBuffer,
			kpb.getYCoord().toBigInteger().toByteArray());

	/* 8 输出密文 C=C1 || C2 || C3 */

	byte[] encryptResult = new byte[C1Buffer.length + C2.length + C3.length];

	System.arraycopy(C1Buffer, 0, encryptResult, 0, C1Buffer.length);
	System.arraycopy(C2, 0, encryptResult, C1Buffer.length, C2.length);
	System.arraycopy(C3, 0, encryptResult, C1Buffer.length + C2.length, C3.length);

	if (debug) {
		System.out.print("密文: ");
		printHexString(encryptResult);
	}

	return encryptResult;
}