// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.math.ec.custom.sec;

import org.bouncycastle.math.ec.ECConstants;
import java.security.SecureRandom;
import org.bouncycastle.math.ec.AbstractECLookupTable;
import org.bouncycastle.math.raw.Nat;
import org.bouncycastle.math.ec.ECLookupTable;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.math.ec.ECFieldElement;
import java.math.BigInteger;
import org.bouncycastle.math.ec.ECCurve;

public class SecP521R1Curve extends AbstractFp
{
    public static final BigInteger q;
    private static final int SECP521R1_DEFAULT_COORDS = 2;
    private static final ECFieldElement[] SECP521R1_AFFINE_ZS;
    protected SecP521R1Point infinity;
    
    public SecP521R1Curve() {
        super(SecP521R1Curve.q);
        this.infinity = new SecP521R1Point(this, null, null);
        this.a = this.fromBigInteger(new BigInteger(1, Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")));
        this.b = this.fromBigInteger(new BigInteger(1, Hex.decodeStrict("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")));
        this.order = new BigInteger(1, Hex.decodeStrict("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"));
        this.cofactor = BigInteger.valueOf(1L);
        this.coord = 2;
    }
    
    @Override
    protected ECCurve cloneCurve() {
        return new SecP521R1Curve();
    }
    
    @Override
    public boolean supportsCoordinateSystem(final int n) {
        switch (n) {
            case 2: {
                return true;
            }
            default: {
                return false;
            }
        }
    }
    
    @Override
    public BigInteger getQ() {
        return SecP521R1Curve.q;
    }
    
    @Override
    public int getFieldSize() {
        return SecP521R1Curve.q.bitLength();
    }
    
    @Override
    public ECFieldElement fromBigInteger(final BigInteger bigInteger) {
        return new SecP521R1FieldElement(bigInteger);
    }
    
    @Override
    protected ECPoint createRawPoint(final ECFieldElement ecFieldElement, final ECFieldElement ecFieldElement2) {
        return new SecP521R1Point(this, ecFieldElement, ecFieldElement2);
    }
    
    @Override
    protected ECPoint createRawPoint(final ECFieldElement ecFieldElement, final ECFieldElement ecFieldElement2, final ECFieldElement[] array) {
        return new SecP521R1Point(this, ecFieldElement, ecFieldElement2, array);
    }
    
    @Override
    public ECPoint getInfinity() {
        return this.infinity;
    }
    
    @Override
    public ECLookupTable createCacheSafeLookupTable(final ECPoint[] array, final int n, final int n2) {
        final int[] array2 = new int[n2 * 17 * 2];
        int n3 = 0;
        for (int i = 0; i < n2; ++i) {
            final ECPoint ecPoint = array[n + i];
            Nat.copy(17, ((SecP521R1FieldElement)ecPoint.getRawXCoord()).x, 0, array2, n3);
            n3 += 17;
            Nat.copy(17, ((SecP521R1FieldElement)ecPoint.getRawYCoord()).x, 0, array2, n3);
            n3 += 17;
        }
        return new AbstractECLookupTable() {
            @Override
            public int getSize() {
                return n2;
            }
            
            @Override
            public ECPoint lookup(final int n) {
                final int[] create = Nat.create(17);
                final int[] create2 = Nat.create(17);
                int n2 = 0;
                for (int i = 0; i < n2; ++i) {
                    final int n3 = (i ^ n) - 1 >> 31;
                    for (int j = 0; j < 17; ++j) {
                        final int[] array = create;
                        final int n4 = j;
                        array[n4] ^= (array2[n2 + j] & n3);
                        final int[] array2 = create2;
                        final int n5 = j;
                        array2[n5] ^= (array2[n2 + 17 + j] & n3);
                    }
                    n2 += 34;
                }
                return this.createPoint(create, create2);
            }
            
            @Override
            public ECPoint lookupVar(final int n) {
                final int[] create = Nat.create(17);
                final int[] create2 = Nat.create(17);
                final int n2 = n * 17 * 2;
                for (int i = 0; i < 17; ++i) {
                    final int[] array = create;
                    final int n3 = i;
                    array[n3] ^= array2[n2 + i];
                    final int[] array2 = create2;
                    final int n4 = i;
                    array2[n4] ^= array2[n2 + 17 + i];
                }
                return this.createPoint(create, create2);
            }
            
            private ECPoint createPoint(final int[] array, final int[] array2) {
                return SecP521R1Curve.this.createRawPoint(new SecP521R1FieldElement(array), new SecP521R1FieldElement(array2), SecP521R1Curve.SECP521R1_AFFINE_ZS);
            }
        };
    }
    
    @Override
    public ECFieldElement randomFieldElement(final SecureRandom secureRandom) {
        final int[] create = Nat.create(17);
        SecP521R1Field.random(secureRandom, create);
        return new SecP521R1FieldElement(create);
    }
    
    @Override
    public ECFieldElement randomFieldElementMult(final SecureRandom secureRandom) {
        final int[] create = Nat.create(17);
        SecP521R1Field.randomMult(secureRandom, create);
        return new SecP521R1FieldElement(create);
    }
    
    static {
        q = SecP521R1FieldElement.Q;
        SECP521R1_AFFINE_ZS = new ECFieldElement[] { new SecP521R1FieldElement(ECConstants.ONE) };
    }
}
