ecpoint.java

来自「内容:基于jdk1.4的加密算法的具体实现」· Java 代码 · 共 503 行 · 第 1/2 页

JAVA
503
字号
package org.bouncycastle.math.ec;import java.math.BigInteger;import org.bouncycastle.asn1.x9.X9IntegerConverter;/** * base class for points on elliptic curves. */public abstract class ECPoint{    ECCurve        curve;    ECFieldElement x;    ECFieldElement y;        private static X9IntegerConverter converter = new X9IntegerConverter();    protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y)    {        this.curve = curve;        this.x = x;        this.y = y;    }        public ECCurve getCurve()    {        return curve;    }        public ECFieldElement getX()    {        return x;    }    public ECFieldElement getY()    {        return y;    }    public boolean isInfinity()    {        return x == null && y == null;    }        public boolean equals(        Object  other)    {        if (other == this)        {            return true;        }        if (!(other instanceof ECPoint))        {            return false;        }        ECPoint o = (ECPoint)other;        if (this.isInfinity())        {            return o.isInfinity();        }        return x.equals(o.x) && y.equals(o.y);    }    public int hashCode()    {        if (this.isInfinity())        {            return 0;        }                return x.hashCode() ^ y.hashCode();    }    public abstract byte[] getEncoded();    public abstract ECPoint add(ECPoint b);    public abstract ECPoint subtract(ECPoint b);    public abstract ECPoint twice();    public abstract ECPoint multiply(BigInteger b);    /**     * Elliptic curve points over Fp     */    public static class Fp extends ECPoint    {        private boolean withCompression;                /**         * Create a point which encodes with point compression.         *          * @param curve the curve to use         * @param x affine x co-ordinate         * @param y affine y co-ordinate         */        public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y)        {            this(curve, x, y, false);        }        /**         * Create a point that encodes with or without point compresion.         *          * @param curve the curve to use         * @param x affine x co-ordinate         * @param y affine y co-ordinate         * @param withCompression if true encode with point compression         */        public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)        {            super(curve, x, y);            if ((x != null && y == null) || (x == null && y != null))            {                throw new IllegalArgumentException("Exactly one of the field elements is null");            }            this.withCompression = withCompression;        }                 /**         * return the field element encoded with point compression. (S 4.3.6)         */        public byte[] getEncoded()        {            int qLength = converter.getByteLength(x);                        if (withCompression)            {                byte    PC;                    if (this.getY().toBigInteger().testBit(0))                {                    PC = 0x03;                }                else                {                    PC = 0x02;                }                    byte[]  X = converter.integerToBytes(this.getX().toBigInteger(), qLength);                byte[]  PO = new byte[X.length + 1];                    PO[0] = PC;                System.arraycopy(X, 0, PO, 1, X.length);                    return PO;            }            else            {                byte[]  X = converter.integerToBytes(this.getX().toBigInteger(), qLength);                byte[]  Y = converter.integerToBytes(this.getY().toBigInteger(), qLength);                byte[]  PO = new byte[X.length + Y.length + 1];                                PO[0] = 0x04;                System.arraycopy(X, 0, PO, 1, X.length);                System.arraycopy(Y, 0, PO, X.length + 1, Y.length);                return PO;            }        }        // B.3 pg 62        public ECPoint add(ECPoint b)        {            if (this.isInfinity())            {                if (b.isInfinity())                {                    return new ECPoint.Fp(this.curve, null, null,                            this.withCompression);                }                return new ECPoint.Fp(b.getCurve(), b.getX(), b.getY(),                        this.withCompression);            }            if (b.isInfinity())            {                return new ECPoint.Fp(this.curve, this.x, this.y, this.withCompression);            }            // Check if b = this or b = -this            if (this.x.equals(b.x))            {                if (this.y.equals(b.y))                {                    // this = b, i.e. this must be doubled                    return this.twice();                }                else                {                    // this = -b, i.e. the result is the point at infinity                    return new ECPoint.Fp(this.curve, null, null,                            this.withCompression);                }            }            ECFieldElement gamma = b.y.subtract(this.y).divide(b.x.subtract(this.x));            ECFieldElement x3 = gamma.multiply(gamma).subtract(this.x).subtract(b.x);            ECFieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);            return new ECPoint.Fp(curve, x3, y3);        }        // B.3 pg 62        public ECPoint twice()        {            if (this.isInfinity() || (this.y.toBigInteger().equals(ECConstants.ZERO)))             {                // Twice identity element (point at infinity) is identity                // element, and if y1 == 0, then (x1, y1) == (x1, -y1)                // and hence this = -this and thus 2(x1, y1) == infinity                return new ECPoint.Fp(curve, null, null, this.withCompression);            }            ECFieldElement TWO = this.curve.fromBigInteger(BigInteger.valueOf(2));            ECFieldElement THREE = this.curve.fromBigInteger(BigInteger.valueOf(3));            ECFieldElement gamma = this.x.multiply(this.x).multiply(THREE).add(curve.a).divide(y.multiply(TWO));            ECFieldElement x3 = gamma.multiply(gamma).subtract(this.x.multiply(TWO));            ECFieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);                            return new ECPoint.Fp(curve, x3, y3, this.withCompression);        }        // D.3.2 pg 102 (see Note:)        public ECPoint subtract(ECPoint b)        {            if (b.isInfinity())            {                return new ECPoint.Fp(this.curve, this.x, this.y,                        this.withCompression);            }            // Add -b            return add(new ECPoint.Fp(this.curve, b.x, b.y.negate(),                    this.withCompression));        }        // D.3.2 pg 101        public ECPoint multiply(BigInteger k)        {            // BigInteger e = k.mod(n); // n == order this            BigInteger e = k;            BigInteger h = e.multiply(BigInteger.valueOf(3));            ECPoint R = this;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?