1111111111

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.bouncycastle.crypto.engines;

import java.math.BigInteger;
import java.security.SecureRandom;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECMultiplier;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.Memoable;
import org.bouncycastle.util.Pack;

public class SM2Engine {
    private final Digest digest;
    private final SM2Engine.Mode mode;
    private boolean forEncryption;
    private ECKeyParameters ecKey;
    private ECDomainParameters ecParams;
    private int curveLength;
    private SecureRandom random;

    public SM2Engine() {
        this((Digest)(new SM3Digest()));
    }

    public SM2Engine(SM2Engine.Mode var1) {
        this(new SM3Digest(), var1);
    }

    public SM2Engine(Digest var1) {
        this(var1, SM2Engine.Mode.C1C2C3);
    }

    public SM2Engine(Digest var1, SM2Engine.Mode var2) {
        if (var2 == null) {
            throw new IllegalArgumentException("mode cannot be NULL");
        } else {
            this.digest = var1;
            this.mode = var2;
        }
    }

    public void init(boolean var1, CipherParameters var2) {
        this.forEncryption = var1;
        if (var1) {
            ParametersWithRandom var3 = (ParametersWithRandom)var2;
            this.ecKey = (ECKeyParameters)var3.getParameters();
            this.ecParams = this.ecKey.getParameters();
            ECPoint var4 = ((ECPublicKeyParameters)this.ecKey).getQ().multiply(this.ecParams.getH());
            if (var4.isInfinity()) {
                throw new IllegalArgumentException("invalid key: [h]Q at infinity");
            }

            this.random = var3.getRandom();
        } else {
            this.ecKey = (ECKeyParameters)var2;
            this.ecParams = this.ecKey.getParameters();
        }

        this.curveLength = (this.ecParams.getCurve().getFieldSize() + 7) / 8;
    }

    public byte[] processBlock(byte[] var1, int var2, int var3) throws InvalidCipherTextException {
        return this.forEncryption ? this.encrypt(var1, var2, var3) : this.decrypt(var1, var2, var3);
    }

    public int getOutputSize(int var1) {
        return 1 + 2 * this.curveLength + var1 + this.digest.getDigestSize();
    }

    protected ECMultiplier createBasePointMultiplier() {
        return new FixedPointCombMultiplier();
    }

    private byte[] encrypt(byte[] var1, int var2, int var3) throws InvalidCipherTextException {
        byte[] var4 = new byte[var3];
        System.arraycopy(var1, var2, var4, 0, var4.length);
        ECMultiplier var5 = this.createBasePointMultiplier();

        byte[] var6;
        ECPoint var7;
        do {
            BigInteger var8 = this.nextK();
            ECPoint var9 = var5.multiply(this.ecParams.getG(), var8).normalize();
            var6 = var9.getEncoded(false);
            var7 = ((ECPublicKeyParameters)this.ecKey).getQ().multiply(var8).normalize();
            this.kdf(this.digest, var7, var4);
        } while(this.notEncrypted(var4, var1, var2));

        byte[] var10 = new byte[this.digest.getDigestSize()];
        this.addFieldElement(this.digest, var7.getAffineXCoord());
        this.digest.update(var1, var2, var3);
        this.addFieldElement(this.digest, var7.getAffineYCoord());
        this.digest.doFinal(var10, 0);
        switch(this.mode) {
        case C1C3C2:
            return Arrays.concatenate(var6, var10, var4);
        default:
            return Arrays.concatenate(var6, var4, var10);
        }
    }

    private byte[] decrypt(byte[] var1, int var2, int var3) throws InvalidCipherTextException {
        byte[] var4 = new byte[this.curveLength * 2 + 1];
        System.arraycopy(var1, var2, var4, 0, var4.length);
        ECPoint var5 = this.ecParams.getCurve().decodePoint(var4);
        ECPoint var6 = var5.multiply(this.ecParams.getH());
        if (var6.isInfinity()) {
            throw new InvalidCipherTextException("[h]C1 at infinity");
        } else {
            var5 = var5.multiply(((ECPrivateKeyParameters)this.ecKey).getD()).normalize();
            int var7 = this.digest.getDigestSize();
            byte[] var8 = new byte[var3 - var4.length - var7];
            if (this.mode == SM2Engine.Mode.C1C3C2) {
                System.arraycopy(var1, var2 + var4.length + var7, var8, 0, var8.length);
            } else {
                System.arraycopy(var1, var2 + var4.length, var8, 0, var8.length);
            }

            this.kdf(this.digest, var5, var8);
            byte[] var9 = new byte[this.digest.getDigestSize()];
            this.addFieldElement(this.digest, var5.getAffineXCoord());
            this.digest.update(var8, 0, var8.length);
            this.addFieldElement(this.digest, var5.getAffineYCoord());
            this.digest.doFinal(var9, 0);
            int var10 = 0;
            int var11;
            if (this.mode == SM2Engine.Mode.C1C3C2) {
                for(var11 = 0; var11 != var9.length; ++var11) {
                    var10 |= var9[var11] ^ var1[var2 + var4.length + var11];
                }
            } else {
                for(var11 = 0; var11 != var9.length; ++var11) {
                    var10 |= var9[var11] ^ var1[var2 + var4.length + var8.length + var11];
                }
            }

            Arrays.fill(var4, (byte)0);
            Arrays.fill(var9, (byte)0);
            if (var10 != 0) {
                Arrays.fill(var8, (byte)0);
                throw new InvalidCipherTextException("invalid cipher text");
            } else {
                return var8;
            }
        }
    }

    private boolean notEncrypted(byte[] var1, byte[] var2, int var3) {
        for(int var4 = 0; var4 != var1.length; ++var4) {
            if (var1[var4] != var2[var3 + var4]) {
                return false;
            }
        }

        return true;
    }

    private void kdf(Digest var1, ECPoint var2, byte[] var3) {
        int var4 = var1.getDigestSize();
        byte[] var5 = new byte[Math.max(4, var4)];
        int var6 = 0;
        Memoable var7 = null;
        Memoable var8 = null;
        if (var1 instanceof Memoable) {
            this.addFieldElement(var1, var2.getAffineXCoord());
            this.addFieldElement(var1, var2.getAffineYCoord());
            var7 = (Memoable)var1;
            var8 = var7.copy();
        }

        int var10;
        for(int var9 = 0; var6 < var3.length; var6 += var10) {
            if (var7 != null) {
                var7.reset(var8);
            } else {
                this.addFieldElement(var1, var2.getAffineXCoord());
                this.addFieldElement(var1, var2.getAffineYCoord());
            }

            ++var9;
            Pack.intToBigEndian(var9, var5, 0);
            var1.update(var5, 0, 4);
            var1.doFinal(var5, 0);
            var10 = Math.min(var4, var3.length - var6);
            this.xor(var3, var5, var6, var10);
        }

    }

    private void xor(byte[] var1, byte[] var2, int var3, int var4) {
        for(int var5 = 0; var5 != var4; ++var5) {
            var1[var3 + var5] ^= var2[var5];
        }

    }

    private BigInteger nextK() {
        int var1 = this.ecParams.getN().bitLength();

        BigInteger var2;
        do {
            do {
                var2 = BigIntegers.createRandomBigInteger(var1, this.random);
            } while(var2.equals(BigIntegers.ZERO));
        } while(var2.compareTo(this.ecParams.getN()) >= 0);

        return var2;
    }

    private void addFieldElement(Digest var1, ECFieldElement var2) {
        byte[] var3 = BigIntegers.asUnsignedByteArray(this.curveLength, var2.toBigInteger());
        var1.update(var3, 0, var3.length);
    }

    public static enum Mode {
        C1C2C3,
        C1C3C2;

        private Mode() {
        }
    }
}

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.bouncycastle.crypto.engines;

import java.math.BigInteger;
import java.security.SecureRandom;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECMultiplier;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.Memoable;
import org.bouncycastle.util.Pack;

public class SM2Engine {
    private final Digest digest;
    private final SM2Engine.Mode mode;
    private boolean forEncryption;
    private ECKeyParameters ecKey;
    private ECDomainParameters ecParams;
    private int curveLength;
    private SecureRandom random;

    public SM2Engine() {
        this((Digest)(new SM3Digest()));
    }

    public SM2Engine(SM2Engine.Mode var1) {
        this(new SM3Digest(), var1);
    }

    public SM2Engine(Digest var1) {
        this(var1, SM2Engine.Mode.C1C2C3);
    }

    public SM2Engine(Digest var1, SM2Engine.Mode var2) {
        if (var2 == null) {
            throw new IllegalArgumentException("mode cannot be NULL");
        } else {
            this.digest = var1;
            this.mode = var2;
        }
    }

    public void init(boolean var1, CipherParameters var2) {
        this.forEncryption = var1;
        if (var1) {
            ParametersWithRandom var3 = (ParametersWithRandom)var2;
            this.ecKey = (ECKeyParameters)var3.getParameters();
            this.ecParams = this.ecKey.getParameters();
            ECPoint var4 = ((ECPublicKeyParameters)this.ecKey).getQ().multiply(this.ecParams.getH());
            if (var4.isInfinity()) {
                throw new IllegalArgumentException("invalid key: [h]Q at infinity");
            }

            this.random = var3.getRandom();
        } else {
            this.ecKey = (ECKeyParameters)var2;
            this.ecParams = this.ecKey.getParameters();
        }

        this.curveLength = (this.ecParams.getCurve().getFieldSize() + 7) / 8;
    }

    public byte[] processBlock(byte[] var1, int var2, int var3) throws InvalidCipherTextException {
        return this.forEncryption ? this.encrypt(var1, var2, var3) : this.decrypt(var1, var2, var3);
    }

    public int getOutputSize(int var1) {
        return 1 + 2 * this.curveLength + var1 + this.digest.getDigestSize();
    }

    protected ECMultiplier createBasePointMultiplier() {
        return new FixedPointCombMultiplier();
    }

    private byte[] encrypt(byte[] var1, int var2, int var3) throws InvalidCipherTextException {
        byte[] var4 = new byte[var3];
        System.arraycopy(var1, var2, var4, 0, var4.length);
        ECMultiplier var5 = this.createBasePointMultiplier();

        byte[] var6;
        ECPoint var7;
        do {
            BigInteger var8 = this.nextK();
            ECPoint var9 = var5.multiply(this.ecParams.getG(), var8).normalize();
            var6 = var9.getEncoded(false);
            var7 = ((ECPublicKeyParameters)this.ecKey).getQ().multiply(var8).normalize();
            this.kdf(this.digest, var7, var4);
        } while(this.notEncrypted(var4, var1, var2));

        byte[] var10 = new byte[this.digest.getDigestSize()];
        this.addFieldElement(this.digest, var7.getAffineXCoord());
        this.digest.update(var1, var2, var3);
        this.addFieldElement(this.digest, var7.getAffineYCoord());
        this.digest.doFinal(var10, 0);
        switch(this.mode) {
        case C1C3C2:
            return Arrays.concatenate(var6, var10, var4);
        default:
            return Arrays.concatenate(var6, var4, var10);
        }
    }

    private byte[] decrypt(byte[] var1, int var2, int var3) throws InvalidCipherTextException {
        byte[] var4 = new byte[this.curveLength * 2 + 1];
        System.arraycopy(var1, var2, var4, 0, var4.length);
        ECPoint var5 = this.ecParams.getCurve().decodePoint(var4);
        ECPoint var6 = var5.multiply(this.ecParams.getH());
        if (var6.isInfinity()) {
            throw new InvalidCipherTextException("[h]C1 at infinity");
        } else {
            var5 = var5.multiply(((ECPrivateKeyParameters)this.ecKey).getD()).normalize();
            int var7 = this.digest.getDigestSize();
            byte[] var8 = new byte[var3 - var4.length - var7];
            if (this.mode == SM2Engine.Mode.C1C3C2) {
                System.arraycopy(var1, var2 + var4.length + var7, var8, 0, var8.length);
            } else {
                System.arraycopy(var1, var2 + var4.length, var8, 0, var8.length);
            }

            this.kdf(this.digest, var5, var8);
            byte[] var9 = new byte[this.digest.getDigestSize()];
            this.addFieldElement(this.digest, var5.getAffineXCoord());
            this.digest.update(var8, 0, var8.length);
            this.addFieldElement(this.digest, var5.getAffineYCoord());
            this.digest.doFinal(var9, 0);
            int var10 = 0;
            int var11;
            if (this.mode == SM2Engine.Mode.C1C3C2) {
                for(var11 = 0; var11 != var9.length; ++var11) {
                    var10 |= var9[var11] ^ var1[var2 + var4.length + var11];
                }
            } else {
                for(var11 = 0; var11 != var9.length; ++var11) {
                    var10 |= var9[var11] ^ var1[var2 + var4.length + var8.length + var11];
                }
            }

            Arrays.fill(var4, (byte)0);
            Arrays.fill(var9, (byte)0);
            if (var10 != 0) {
                Arrays.fill(var8, (byte)0);
                throw new InvalidCipherTextException("invalid cipher text");
            } else {
                return var8;
            }
        }
    }

    private boolean notEncrypted(byte[] var1, byte[] var2, int var3) {
        for(int var4 = 0; var4 != var1.length; ++var4) {
            if (var1[var4] != var2[var3 + var4]) {
                return false;
            }
        }

        return true;
    }

    private void kdf(Digest var1, ECPoint var2, byte[] var3) {
        int var4 = var1.getDigestSize();
        byte[] var5 = new byte[Math.max(4, var4)];
        int var6 = 0;
        Memoable var7 = null;
        Memoable var8 = null;
        if (var1 instanceof Memoable) {
            this.addFieldElement(var1, var2.getAffineXCoord());
            this.addFieldElement(var1, var2.getAffineYCoord());
            var7 = (Memoable)var1;
            var8 = var7.copy();
        }

        int var10;
        for(int var9 = 0; var6 < var3.length; var6 += var10) {
            if (var7 != null) {
                var7.reset(var8);
            } else {
                this.addFieldElement(var1, var2.getAffineXCoord());
                this.addFieldElement(var1, var2.getAffineYCoord());
            }

            ++var9;
            Pack.intToBigEndian(var9, var5, 0);
            var1.update(var5, 0, 4);
            var1.doFinal(var5, 0);
            var10 = Math.min(var4, var3.length - var6);
            this.xor(var3, var5, var6, var10);
        }

    }

    private void xor(byte[] var1, byte[] var2, int var3, int var4) {
        for(int var5 = 0; var5 != var4; ++var5) {
            var1[var3 + var5] ^= var2[var5];
        }

    }

    private BigInteger nextK() {
        int var1 = this.ecParams.getN().bitLength();

        BigInteger var2;
        do {
            do {
                var2 = BigIntegers.createRandomBigInteger(var1, this.random);
            } while(var2.equals(BigIntegers.ZERO));
        } while(var2.compareTo(this.ecParams.getN()) >= 0);

        return var2;
    }

    private void addFieldElement(Digest var1, ECFieldElement var2) {
        byte[] var3 = BigIntegers.asUnsignedByteArray(this.curveLength, var2.toBigInteger());
        var1.update(var3, 0, var3.length);
    }

    public static enum Mode {
        C1C2C3,
        C1C3C2;

        private Mode() {
        }
    }
}

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.bouncycastle.util;

import java.math.BigInteger;
import java.security.SecureRandom;

public final class BigIntegers {
    public static final BigInteger ZERO = BigInteger.valueOf(0L);
    public static final BigInteger ONE = BigInteger.valueOf(1L);
    private static final BigInteger TWO = BigInteger.valueOf(2L);
    private static final BigInteger THREE = BigInteger.valueOf(3L);
    private static final int MAX_ITERATIONS = 1000;
    private static final BigInteger SMALL_PRIMES_PRODUCT = new BigInteger("8138e8a0fcf3a4e84a771d40fd305d7f4aa59306d7251de54d98af8fe95729a1f73d893fa424cd2edc8636a6c3285e022b0e3866a565ae8108eed8591cd4fe8d2ce86165a978d719ebf647f362d33fca29cd179fb42401cbaf3df0c614056f9c8f3cfd51e474afb6bc6974f78db8aba8e9e517fded658591ab7502bd41849462f", 16);
    private static final int MAX_SMALL = BigInteger.valueOf(743L).bitLength();

    public BigIntegers() {
    }

    public static byte[] asUnsignedByteArray(BigInteger var0) {
        byte[] var1 = var0.toByteArray();
        if (var1[0] == 0) {
            byte[] var2 = new byte[var1.length - 1];
            System.arraycopy(var1, 1, var2, 0, var2.length);
            return var2;
        } else {
            return var1;
        }
    }

    public static byte[] asUnsignedByteArray(int var0, BigInteger var1) {
        byte[] var2 = var1.toByteArray();
        if (var2.length == var0) {
            return var2;
        } else {
            int var3 = var2[0] == 0 ? 1 : 0;
            int var4 = var2.length - var3;
            if (var4 > var0) {
                throw new IllegalArgumentException("standard length exceeded for value");
            } else {
                byte[] var5 = new byte[var0];
                System.arraycopy(var2, var3, var5, var5.length - var4, var4);
                return var5;
            }
        }
    }

    public static void asUnsignedByteArray(BigInteger var0, byte[] var1, int var2, int var3) {
        byte[] var4 = var0.toByteArray();
        if (var4.length == var3) {
            System.arraycopy(var4, 0, var1, var2, var3);
        } else {
            int var5 = var4[0] == 0 ? 1 : 0;
            int var6 = var4.length - var5;
            if (var6 > var3) {
                throw new IllegalArgumentException("standard length exceeded for value");
            } else {
                int var7 = var3 - var6;
                Arrays.fill(var1, var2, var2 + var7, (byte)0);
                System.arraycopy(var4, var5, var1, var2 + var7, var6);
            }
        }
    }

    public static BigInteger createRandomInRange(BigInteger var0, BigInteger var1, SecureRandom var2) {
        int var3 = var0.compareTo(var1);
        if (var3 >= 0) {
            if (var3 > 0) {
                throw new IllegalArgumentException("'min' may not be greater than 'max'");
            } else {
                return var0;
            }
        } else if (var0.bitLength() > var1.bitLength() / 2) {
            return createRandomInRange(ZERO, var1.subtract(var0), var2).add(var0);
        } else {
            for(int var4 = 0; var4 < 1000; ++var4) {
                BigInteger var5 = createRandomBigInteger(var1.bitLength(), var2);
                if (var5.compareTo(var0) >= 0 && var5.compareTo(var1) <= 0) {
                    return var5;
                }
            }

            return createRandomBigInteger(var1.subtract(var0).bitLength() - 1, var2).add(var0);
        }
    }

    public static BigInteger fromUnsignedByteArray(byte[] var0) {
        return new BigInteger(1, var0);
    }

    public static BigInteger fromUnsignedByteArray(byte[] var0, int var1, int var2) {
        byte[] var3 = var0;
        if (var1 != 0 || var2 != var0.length) {
            var3 = new byte[var2];
            System.arraycopy(var0, var1, var3, 0, var2);
        }

        return new BigInteger(1, var3);
    }

    public static int intValueExact(BigInteger var0) {
        if (var0.bitLength() > 31) {
            throw new ArithmeticException("BigInteger out of int range");
        } else {
            return var0.intValue();
        }
    }

    public static long longValueExact(BigInteger var0) {
        if (var0.bitLength() > 63) {
            throw new ArithmeticException("BigInteger out of long range");
        } else {
            return var0.longValue();
        }
    }

    public static int getUnsignedByteLength(BigInteger var0) {
        return (var0.bitLength() + 7) / 8;
    }

    public static BigInteger createRandomBigInteger(int var0, SecureRandom var1) {
        return new BigInteger(1, createRandom(var0, var1));
    }

    public static BigInteger createRandomPrime(int var0, int var1, SecureRandom var2) {
        if (var0 < 2) {
            throw new IllegalArgumentException("bitLength < 2");
        } else if (var0 == 2) {
            return var2.nextInt() < 0 ? TWO : THREE;
        } else {
            BigInteger var3;
            do {
                byte[] var4 = createRandom(var0, var2);
                int var5 = 8 * var4.length - var0;
                byte var6 = (byte)(1 << 7 - var5);
                var4[0] |= var6;
                var4[var4.length - 1] = (byte)(var4[var4.length - 1] | 1);
                var3 = new BigInteger(1, var4);
                if (var0 > MAX_SMALL) {
                    while(!var3.gcd(SMALL_PRIMES_PRODUCT).equals(ONE)) {
                        var3 = var3.add(TWO);
                    }
                }
            } while(!var3.isProbablePrime(var1));

            return var3;
        }
    }

    private static byte[] createRandom(int var0, SecureRandom var1) throws IllegalArgumentException {
        if (var0 < 1) {
            throw new IllegalArgumentException("bitLength must be at least 1");
        } else {
            int var2 = (var0 + 7) / 8;
            byte[] var3 = new byte[var2];
            var1.nextBytes(var3);
            int var4 = 8 * var2 - var0;
            var3[0] &= (byte)(255 >>> var4);
            return var3;
        }
    }
}

public static ECCurve convertCurve(EllipticCurve var0) {
        ECField var1 = var0.getField();
        BigInteger var2 = var0.getA();
        BigInteger var3 = var0.getB();
        if (var1 instanceof ECFieldFp) {
            Fp var7 = new Fp(((ECFieldFp)var1).getP(), var2, var3);
            return (ECCurve)(customCurves.containsKey(var7) ? (ECCurve)customCurves.get(var7) : var7);
        } else {
            ECFieldF2m var4 = (ECFieldF2m)var1;
            int var5 = var4.getM();
            int[] var6 = ECUtil.convertMidTerms(var4.getMidTermsOfReductionPolynomial());
            return new F2m(var5, var6[0], var6[1], var6[2], var2, var3);
        }
    }
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值