1 package org.bouncycastle.math.ec.custom.sec; 2 3 import java.math.BigInteger; 4 5 import org.bouncycastle.math.raw.Nat; 6 import org.bouncycastle.math.raw.Nat512; 7 8 public class SecP521R1Field 9 { 10 // 2^521 - 1 11 static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 12 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x1FF }; 13 private static final int P16 = 0x1FF; 14 add(int[] x, int[] y, int[] z)15 public static void add(int[] x, int[] y, int[] z) 16 { 17 int c = Nat.add(16, x, y, z) + x[16] + y[16]; 18 if (c > P16 || (c == P16 && Nat.eq(16, z, P))) 19 { 20 c += Nat.inc(16, z); 21 c &= P16; 22 } 23 z[16] = c; 24 } 25 addOne(int[] x, int[] z)26 public static void addOne(int[] x, int[] z) 27 { 28 int c = Nat.inc(16, x, z) + x[16]; 29 if (c > P16 || (c == P16 && Nat.eq(16, z, P))) 30 { 31 c += Nat.inc(16, z); 32 c &= P16; 33 } 34 z[16] = c; 35 } 36 fromBigInteger(BigInteger x)37 public static int[] fromBigInteger(BigInteger x) 38 { 39 int[] z = Nat.fromBigInteger(521, x); 40 if (Nat.eq(17, z, P)) 41 { 42 Nat.zero(17, z); 43 } 44 return z; 45 } 46 half(int[] x, int[] z)47 public static void half(int[] x, int[] z) 48 { 49 int x16 = x[16]; 50 int c = Nat.shiftDownBit(16, x, x16, z); 51 z[16] = (x16 >>> 1) | (c >>> 23); 52 } 53 multiply(int[] x, int[] y, int[] z)54 public static void multiply(int[] x, int[] y, int[] z) 55 { 56 int[] tt = Nat.create(33); 57 implMultiply(x, y, tt); 58 reduce(tt, z); 59 } 60 negate(int[] x, int[] z)61 public static void negate(int[] x, int[] z) 62 { 63 if (Nat.isZero(17, x)) 64 { 65 Nat.zero(17, z); 66 } 67 else 68 { 69 Nat.sub(17, P, x, z); 70 } 71 } 72 reduce(int[] xx, int[] z)73 public static void reduce(int[] xx, int[] z) 74 { 75 // assert xx[32] >>> 18 == 0; 76 77 int xx32 = xx[32]; 78 int c = Nat.shiftDownBits(16, xx, 16, 9, xx32, z, 0) >>> 23; 79 c += xx32 >>> 9; 80 c += Nat.addTo(16, xx, z); 81 if (c > P16 || (c == P16 && Nat.eq(16, z, P))) 82 { 83 c += Nat.inc(16, z); 84 c &= P16; 85 } 86 z[16] = c; 87 } 88 reduce23(int[] z)89 public static void reduce23(int[] z) 90 { 91 int z16 = z[16]; 92 int c = Nat.addWordTo(16, z16 >>> 9, z) + (z16 & P16); 93 if (c > P16 || (c == P16 && Nat.eq(16, z, P))) 94 { 95 c += Nat.inc(16, z); 96 c &= P16; 97 } 98 z[16] = c; 99 } 100 square(int[] x, int[] z)101 public static void square(int[] x, int[] z) 102 { 103 int[] tt = Nat.create(33); 104 implSquare(x, tt); 105 reduce(tt, z); 106 } 107 squareN(int[] x, int n, int[] z)108 public static void squareN(int[] x, int n, int[] z) 109 { 110 // assert n > 0; 111 112 int[] tt = Nat.create(33); 113 implSquare(x, tt); 114 reduce(tt, z); 115 116 while (--n > 0) 117 { 118 implSquare(z, tt); 119 reduce(tt, z); 120 } 121 } 122 subtract(int[] x, int[] y, int[] z)123 public static void subtract(int[] x, int[] y, int[] z) 124 { 125 int c = Nat.sub(16, x, y, z) + x[16] - y[16]; 126 if (c < 0) 127 { 128 c += Nat.dec(16, z); 129 c &= P16; 130 } 131 z[16] = c; 132 } 133 twice(int[] x, int[] z)134 public static void twice(int[] x, int[] z) 135 { 136 int x16 = x[16]; 137 int c = Nat.shiftUpBit(16, x, x16 << 23, z) | (x16 << 1); 138 z[16] = c & P16; 139 } 140 implMultiply(int[] x, int[] y, int[] zz)141 protected static void implMultiply(int[] x, int[] y, int[] zz) 142 { 143 Nat512.mul(x, y, zz); 144 145 int x16 = x[16], y16 = y[16]; 146 zz[32] = Nat.mul31BothAdd(16, x16, y, y16, x, zz, 16) + (x16 * y16); 147 } 148 implSquare(int[] x, int[] zz)149 protected static void implSquare(int[] x, int[] zz) 150 { 151 Nat512.square(x, zz); 152 153 int x16 = x[16]; 154 zz[32] = Nat.mulWordAddTo(16, x16 << 1, x, 0, zz, 16) + (x16 * x16); 155 } 156 } 157