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

package org.bouncycastle.math.ec.rfc7748;

import org.bouncycastle.math.ec.rfc8032.Ed448;
import java.security.SecureRandom;
import org.bouncycastle.util.Arrays;

public abstract class X448
{
    public static final int POINT_SIZE = 56;
    public static final int SCALAR_SIZE = 56;
    private static final int C_A = 156326;
    private static final int C_A24 = 39082;
    
    public static boolean calculateAgreement(final byte[] array, final int n, final byte[] array2, final int n2, final byte[] array3, final int n3) {
        scalarMult(array, n, array2, n2, array3, n3);
        return !Arrays.areAllZeroes(array3, n3, 56);
    }
    
    public static void clampPrivateKey(final byte[] array) {
        if (array.length != 56) {
            throw new IllegalArgumentException("k");
        }
        final int n = 0;
        array[n] &= (byte)252;
        final int n2 = 55;
        array[n2] |= (byte)128;
    }
    
    private static int decode32(final byte[] array, int n) {
        return (array[n] & 0xFF) | (array[++n] & 0xFF) << 8 | (array[++n] & 0xFF) << 16 | array[++n] << 24;
    }
    
    private static void decodeScalar(final byte[] array, final int n, final int[] array2) {
        for (int i = 0; i < 14; ++i) {
            array2[i] = decode32(array, n + i * 4);
        }
        final int n2 = 0;
        array2[n2] &= 0xFFFFFFFC;
        final int n3 = 13;
        array2[n3] |= Integer.MIN_VALUE;
    }
    
    public static void generatePrivateKey(final SecureRandom secureRandom, final byte[] bytes) {
        if (bytes.length != 56) {
            throw new IllegalArgumentException("k");
        }
        secureRandom.nextBytes(bytes);
        clampPrivateKey(bytes);
    }
    
    public static void generatePublicKey(final byte[] array, final int n, final byte[] array2, final int n2) {
        scalarMultBase(array, n, array2, n2);
    }
    
    private static void pointDouble(final int[] array, final int[] array2) {
        final int[] create = X448Field.create();
        final int[] create2 = X448Field.create();
        X448Field.add(array, array2, create);
        X448Field.sub(array, array2, create2);
        X448Field.sqr(create, create);
        X448Field.sqr(create2, create2);
        X448Field.mul(create, create2, array);
        X448Field.sub(create, create2, create);
        X448Field.mul(create, 39082, array2);
        X448Field.add(array2, create2, array2);
        X448Field.mul(array2, create, array2);
    }
    
    public static void precompute() {
        Ed448.precompute();
    }
    
    public static void scalarMult(final byte[] array, final int n, final byte[] array2, final int n2, final byte[] array3, final int n3) {
        final int[] array4 = new int[14];
        decodeScalar(array, n, array4);
        final int[] create = X448Field.create();
        X448Field.decode(array2, n2, create);
        final int[] create2 = X448Field.create();
        X448Field.copy(create, 0, create2, 0);
        final int[] create3 = X448Field.create();
        create3[0] = 1;
        final int[] create4 = X448Field.create();
        create4[0] = 1;
        final int[] create5 = X448Field.create();
        final int[] create6 = X448Field.create();
        final int[] create7 = X448Field.create();
        int i = 447;
        int n4 = 1;
        do {
            X448Field.add(create4, create5, create6);
            X448Field.sub(create4, create5, create4);
            X448Field.add(create2, create3, create5);
            X448Field.sub(create2, create3, create2);
            X448Field.mul(create6, create2, create6);
            X448Field.mul(create4, create5, create4);
            X448Field.sqr(create5, create5);
            X448Field.sqr(create2, create2);
            X448Field.sub(create5, create2, create7);
            X448Field.mul(create7, 39082, create3);
            X448Field.add(create3, create2, create3);
            X448Field.mul(create3, create7, create3);
            X448Field.mul(create2, create5, create2);
            X448Field.sub(create6, create4, create5);
            X448Field.add(create6, create4, create4);
            X448Field.sqr(create4, create4);
            X448Field.sqr(create5, create5);
            X448Field.mul(create5, create, create5);
            final int n5 = array4[--i >>> 5] >>> (i & 0x1F) & 0x1;
            final int n6 = n4 ^ n5;
            X448Field.cswap(n6, create2, create4);
            X448Field.cswap(n6, create3, create5);
            n4 = n5;
        } while (i >= 2);
        for (int j = 0; j < 2; ++j) {
            pointDouble(create2, create3);
        }
        X448Field.inv(create3, create3);
        X448Field.mul(create2, create3, create2);
        X448Field.normalize(create2);
        X448Field.encode(create2, array3, n3);
    }
    
    public static void scalarMultBase(final byte[] array, final int n, final byte[] array2, final int n2) {
        final int[] create = X448Field.create();
        final int[] create2 = X448Field.create();
        Ed448.scalarMultBaseXY(Friend.INSTANCE, array, n, create, create2);
        X448Field.inv(create, create);
        X448Field.mul(create, create2, create);
        X448Field.sqr(create, create);
        X448Field.normalize(create);
        X448Field.encode(create, array2, n2);
    }
    
    private static class F extends X448Field
    {
    }
    
    public static class Friend
    {
        private static final Friend INSTANCE;
        
        private Friend() {
        }
        
        static {
            INSTANCE = new Friend();
        }
    }
}
