http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/cs/DBIG.cs ---------------------------------------------------------------------- diff --git a/cs/DBIG.cs b/cs/DBIG.cs deleted file mode 100644 index 935fc52..0000000 --- a/cs/DBIG.cs +++ /dev/null @@ -1,374 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* AMCL double length DBIG number class */ - -public class DBIG -{ - protected internal long[] w = new long[ROM.DNLEN]; - -/* Constructors */ - public DBIG(int x) - { - w[0] = x; - for (int i = 1;i < ROM.DNLEN;i++) - { - w[i] = 0; - } - } - - public DBIG(DBIG x) - { - for (int i = 0;i < ROM.DNLEN;i++) - { - w[i] = x.w[i]; - } - } - - public DBIG(BIG x) - { - for (int i = 0;i < ROM.NLEN - 1;i++) - { - w[i] = x.get(i); - } - - w[ROM.NLEN - 1] = x.get(ROM.NLEN - 1) & ROM.MASK; // top word normalized - w[ROM.NLEN] = x.get(ROM.NLEN - 1) >> ROM.BASEBITS; - - for (int i = ROM.NLEN + 1;i < ROM.DNLEN;i++) - { - w[i] = 0; - } - } - -/* get and set digits of this */ - public virtual long get(int i) - { - return w[i]; - } - - public virtual void set(int i, long x) - { - w[i] = x; - } - - public virtual void inc(int i, long x) - { - w[i] += x; - } - -/* test this=0? */ - public virtual bool iszilch() - { - for (int i = 0;i < ROM.DNLEN;i++) - { - if (w[i] != 0) - { - return false; - } - } - return true; - } - -/* normalise this */ - public virtual void norm() - { - long d , carry = 0; - for (int i = 0;i < ROM.DNLEN - 1;i++) - { - d = w[i] + carry; - w[i] = d & ROM.MASK; - carry = d >> ROM.BASEBITS; - } - w[ROM.DNLEN - 1] = (w[ROM.DNLEN - 1] + carry); - } - -/* shift this right by k bits */ - public virtual void shr(int k) - { - int n = k % ROM.BASEBITS; - int m = k / ROM.BASEBITS; - for (int i = 0;i < ROM.DNLEN - m - 1;i++) - { - w[i] = (w[m + i] >> n) | ((w[m + i + 1] << (ROM.BASEBITS - n)) & ROM.MASK); - } - w[ROM.DNLEN - m - 1] = w[ROM.DNLEN - 1] >> n; - for (int i = ROM.DNLEN - m;i < ROM.DNLEN;i++) - { - w[i] = 0; - } - } - -/* shift this left by k bits */ - public virtual void shl(int k) - { - int n = k % ROM.BASEBITS; - int m = k / ROM.BASEBITS; - - w[ROM.DNLEN - 1] = ((w[ROM.DNLEN - 1 - m] << n)) | (w[ROM.DNLEN - m - 2]>>(ROM.BASEBITS - n)); - for (int i = ROM.DNLEN - 2;i > m;i--) - { - w[i] = ((w[i - m] << n) & ROM.MASK) | (w[i - m - 1]>>(ROM.BASEBITS - n)); - } - w[m] = (w[0] << n) & ROM.MASK; - for (int i = 0;i < m;i++) - { - w[i] = 0; - } - } - -/* return number of bits in this */ - public virtual int nbits() - { - int bts , k = ROM.DNLEN - 1; - long c; - norm(); - while (w[k] == 0 && k >= 0) - { - k--; - } - if (k < 0) - { - return 0; - } - bts = ROM.BASEBITS * k; - c = w[k]; - while (c != 0) - { - c /= 2; - bts++; - } - return bts; - } - -/* convert this to string */ - public override string ToString() - { - DBIG b; - string s = ""; - int len = nbits(); - if (len % 4 == 0) - { - len >>= 2; //len/=4; - } - else - { - len >>= 2; - len++; - } - - for (int i = len - 1;i >= 0;i--) - { - b = new DBIG(this); - b.shr(i * 4); - s += (b.w[0] & 15).ToString("x"); - } - return s; - } - -/* return this+x */ -/* - public DBIG plus(DBIG x) { - DBIG s=new DBIG(0); - for (int i=0;i<ROM.DNLEN;i++) - s.w[i]=w[i]+x.w[i]; - return s; - } -*/ -/* return this-x */ -/* - public DBIG minus(DBIG x) { - DBIG d=new DBIG(0); - for (int i=0;i<ROM.DNLEN;i++) - d.w[i]=w[i]-x.w[i]; - return d; - } -*/ -/* this+=x */ - public virtual void add(DBIG x) - { - for (int i = 0;i < ROM.DNLEN;i++) - { - w[i] += x.w[i]; - } - } - -/* this-=x */ - public virtual void sub(DBIG x) - { - for (int i = 0;i < ROM.DNLEN;i++) - { - w[i] -= x.w[i]; - } - } - -/* set this[i]+=x*y+c, and return high part */ -/* This is time critical */ -/* What if you knew the bottom half in advance ?? */ - public virtual long muladd(long a, long b, long c, int i) - { - long x0, x1, y0, y1; - x0 = a & ROM.HMASK; - x1 = (a >> ROM.HBITS); - y0 = b & ROM.HMASK; - y1 = (b >> ROM.HBITS); - long bot = x0 * y0; - long top = x1 * y1; - long mid = x0 * y1 + x1 * y0; - x0 = mid & ROM.HMASK; - x1 = (mid >> ROM.HBITS); - bot += x0 << ROM.HBITS; - bot += c; - bot += w[i]; - top += x1; - long carry = bot >> ROM.BASEBITS; - bot &= ROM.MASK; - top += carry; - w[i] = bot; - return top; - } - -/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ - public static int comp(DBIG a, DBIG b) - { - for (int i = ROM.DNLEN - 1;i >= 0;i--) - { - if (a.w[i] == b.w[i]) - { - continue; - } - if (a.w[i] > b.w[i]) - { - return 1; - } - else - { - return -1; - } - } - return 0; - } - -/* reduces this DBIG mod a BIG, and returns the BIG */ - public virtual BIG mod(BIG c) - { - int k = 0; - norm(); - DBIG m = new DBIG(c); - - if (comp(this,m) < 0) - { - return new BIG(this); - } - - do - { - m.shl(1); - k++; - } while (comp(this,m) >= 0); - - while (k > 0) - { - m.shr(1); - if (comp(this,m) >= 0) - { - sub(m); - norm(); - } - k--; - } - return new BIG(this); - } - -/* reduces this DBIG mod a DBIG in place */ -/* public void mod(DBIG m) - { - int k=0; - if (comp(this,m)<0) return; - - do - { - m.shl(1); - k++; - } - while (comp(this,m)>=0); - - while (k>0) - { - m.shr(1); - if (comp(this,m)>=0) - { - sub(m); - norm(); - } - k--; - } - return; - - }*/ - -/* return this/c */ - public virtual BIG div(BIG c) - { - int k = 0; - DBIG m = new DBIG(c); - BIG a = new BIG(0); - BIG e = new BIG(1); - norm(); - - while (comp(this,m) >= 0) - { - e.fshl(1); - m.shl(1); - k++; - } - - while (k > 0) - { - m.shr(1); - e.shr(1); - if (comp(this,m) > 0) - { - a.add(e); - a.norm(); - sub(m); - norm(); - } - k--; - } - return a; - } - -/* split DBIG at position n, return higher half, keep lower half */ - public virtual BIG Split(int n) - { - BIG t = new BIG(0); - int m = n % ROM.BASEBITS; - long nw , carry = w[ROM.DNLEN - 1] << (ROM.BASEBITS - m); - - for (int i = ROM.DNLEN - 2;i >= ROM.NLEN - 1;i--) - { - nw = (w[i] >> m) | carry; - carry = (w[i] << (ROM.BASEBITS - m)) & ROM.MASK; - t.set(i - ROM.NLEN + 1,nw); - } - w[ROM.NLEN - 1] &= (((long)1 << m) - 1); - return t; - } -}
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/cs/ECDH.cs ---------------------------------------------------------------------- diff --git a/cs/ECDH.cs b/cs/ECDH.cs deleted file mode 100644 index f63dff1..0000000 --- a/cs/ECDH.cs +++ /dev/null @@ -1,778 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* Elliptic Curve API high-level functions */ - -public sealed class ECDH -{ - public const int INVALID_PUBLIC_KEY = -2; - public const int ERROR = -3; - public const int INVALID = -4; - public static readonly int EFS = ROM.MODBYTES; - public static readonly int EGS = ROM.MODBYTES; - public static readonly int EAS = AES.KS; - public static readonly int EBS = AES.BS; - -/* Convert Integer to n-byte array */ - private static sbyte[] inttoBytes(int n, int len) - { - int i; - sbyte[] b = new sbyte[len]; - - for (i = 0;i < len;i++) - { - b[i] = 0; - } - i = len; - while (n > 0 && i > 0) - { - i--; - b[i] = unchecked((sbyte)(n & 0xff)); - n /= 256; - } - return b; - } - -/* Key Derivation Functions */ -/* Input octet Z */ -/* Output key of length olen */ - public static sbyte[] KDF1(sbyte[] Z, int olen) - { -/* NOTE: the parameter olen is the length of the output K in bytes */ - HASH H = new HASH(); - int hlen = HASH.len; - sbyte[] K = new sbyte[olen]; - - sbyte[] B; - int counter , cthreshold , k = 0; - - for (int i = 0;i < K.Length;i++) - { - K[i] = 0; - } - - cthreshold = olen / hlen; - if (olen % hlen != 0) - { - cthreshold++; - } - - for (counter = 0;counter < cthreshold;counter++) - { - H.process_array(Z); - if (counter > 0) - { - H.process_num(counter); - } - B = H.hash(); - if (k + hlen > olen) - { - for (int i = 0;i < olen % hlen;i++) - { - K[k++] = B[i]; - } - } - else - { - for (int i = 0;i < hlen;i++) - { - K[k++] = B[i]; - } - } - } - return K; - } - - public static sbyte[] KDF2(sbyte[] Z, sbyte[] P, int olen) - { -/* NOTE: the parameter olen is the length of the output k in bytes */ - HASH H = new HASH(); - int hlen = HASH.len; - sbyte[] K = new sbyte[olen]; - - sbyte[] B = new sbyte[hlen]; - int counter , cthreshold , k = 0; - - for (int i = 0;i < K.Length;i++) - { - K[i] = 0; - } - - cthreshold = olen / hlen; - if (olen % hlen != 0) - { - cthreshold++; - } - - for (counter = 1;counter <= cthreshold;counter++) - { - H.process_array(Z); - H.process_num(counter); - H.process_array(P); - B = H.hash(); - if (k + hlen > olen) - { - for (int i = 0;i < olen % hlen;i++) - { - K[k++] = B[i]; - } - } - else - { - for (int i = 0;i < hlen;i++) - { - K[k++] = B[i]; - } - } - } - return K; - } - -/* Password based Key Derivation Function */ -/* Input password p, salt s, and repeat count */ -/* Output key of length olen */ - public static sbyte[] PBKDF2(sbyte[] Pass, sbyte[] Salt, int rep, int olen) - { - int i, j, k, d, opt; - d = olen / 32; - if (olen % 32 != 0) - { - d++; - } - sbyte[] F = new sbyte[EFS]; - sbyte[] U = new sbyte[EFS]; - sbyte[] S = new sbyte[Salt.Length + 4]; - - sbyte[] K = new sbyte[d * EFS]; - opt = 0; - - for (i = 1;i <= d;i++) - { - for (j = 0;j < Salt.Length;j++) - { - S[j] = Salt[j]; - } - sbyte[] N = inttoBytes(i,4); - for (j = 0;j < 4;j++) - { - S[Salt.Length + j] = N[j]; - } - - HMAC(S,Pass,F); - - for (j = 0;j < EFS;j++) - { - U[j] = F[j]; - } - for (j = 2;j <= rep;j++) - { - HMAC(U,Pass,U); - for (k = 0;k < EFS;k++) - { - F[k] ^= U[k]; - } - } - for (j = 0;j < EFS;j++) - { - K[opt++] = F[j]; - } - } - sbyte[] key = new sbyte[olen]; - for (i = 0;i < olen;i++) - { - key[i] = K[i]; - } - return key; - } - -/* Calculate HMAC of m using key k. HMAC is tag of length olen */ - public static int HMAC(sbyte[] M, sbyte[] K, sbyte[] tag) - { - /* Input is from an octet m * - * olen is requested output length in bytes. k is the key * - * The output is the calculated tag */ - int b; - sbyte[] B; - sbyte[] K0 = new sbyte[64]; - int olen = tag.Length; - - b = K0.Length; - if (olen < 4 || olen> HASH.len) - { - return 0; - } - - for (int i = 0;i < b;i++) - { - K0[i] = 0; - } - - HASH H = new HASH(); - - if (K.Length > b) - { - H.process_array(K); - B = H.hash(); - for (int i = 0;i < 32;i++) - { - K0[i] = B[i]; - } - } - else - { - for (int i = 0;i < K.Length;i++) - { - K0[i] = K[i]; - } - } - - for (int i = 0;i < b;i++) - { - K0[i] ^= 0x36; - } - H.process_array(K0); - H.process_array(M); - B = H.hash(); - - for (int i = 0;i < b;i++) - { - K0[i] ^= 0x6a; - } - H.process_array(K0); - H.process_array(B); - B = H.hash(); - - for (int i = 0;i < olen;i++) - { - tag[i] = B[i]; - } - - return 1; - } - -/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */ - public static sbyte[] AES_CBC_IV0_ENCRYPT(sbyte[] K, sbyte[] M) - { // AES CBC encryption, with Null IV and key K - /* Input is from an octet string M, output is to an octet string C */ - /* Input is padded as necessary to make up a full final block */ - AES a = new AES(); - bool fin; - int i, j, ipt, opt; - sbyte[] buff = new sbyte[16]; - int clen = 16 + (M.Length / 16) * 16; - - sbyte[] C = new sbyte[clen]; - int padlen; - - a.init(AES.CBC,K,null); - - ipt = opt = 0; - fin = false; - for (;;) - { - for (i = 0;i < 16;i++) - { - if (ipt < M.Length) - { - buff[i] = M[ipt++]; - } - else - { - fin = true; - break; - } - } - if (fin) - { - break; - } - a.encrypt(buff); - for (i = 0;i < 16;i++) - { - C[opt++] = buff[i]; - } - } - -/* last block, filled up to i-th index */ - - padlen = 16 - i; - for (j = i;j < 16;j++) - { - buff[j] = (sbyte)padlen; - } - - a.encrypt(buff); - - for (i = 0;i < 16;i++) - { - C[opt++] = buff[i]; - } - a.end(); - return C; - } - -/* returns plaintext if all consistent, else returns null string */ - public static sbyte[] AES_CBC_IV0_DECRYPT(sbyte[] K, sbyte[] C) - { // padding is removed - AES a = new AES(); - int i, ipt, opt, ch; - sbyte[] buff = new sbyte[16]; - sbyte[] MM = new sbyte[C.Length]; - bool fin, bad; - int padlen; - ipt = opt = 0; - - a.init(AES.CBC,K,null); - - if (C.Length == 0) - { - return new sbyte[0]; - } - ch = C[ipt++]; - - fin = false; - - for (;;) - { - for (i = 0;i < 16;i++) - { - buff[i] = (sbyte)ch; - if (ipt >= C.Length) - { - fin = true; - break; - } - else - { - ch = C[ipt++]; - } - } - a.decrypt(buff); - if (fin) - { - break; - } - for (i = 0;i < 16;i++) - { - MM[opt++] = buff[i]; - } - } - - a.end(); - bad = false; - padlen = buff[15]; - if (i != 15 || padlen < 1 || padlen>16) - { - bad = true; - } - if (padlen >= 2 && padlen <= 16) - { - for (i = 16 - padlen;i < 16;i++) - { - if (buff[i] != padlen) - { - bad = true; - } - } - } - - if (!bad) - { - for (i = 0;i < 16 - padlen;i++) - { - MM[opt++] = buff[i]; - } - } - - if (bad) - { - return new sbyte[0]; - } - - sbyte[] M = new sbyte[opt]; - for (i = 0;i < opt;i++) - { - M[i] = MM[i]; - } - - return M; - } - -/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p), - * where S is the secret key and W is the public key - * and G is fixed generator. - * If RNG is NULL then the private key is provided externally in S - * otherwise it is generated randomly internally */ - public static int KEY_PAIR_GENERATE(RAND RNG, sbyte[] S, sbyte[] W) - { - BIG r, gx, gy, s; - ECP G, WP; - int res = 0; - sbyte[] T = new sbyte[EFS]; - - gx = new BIG(ROM.CURVE_Gx); - if (ROM.CURVETYPE != ROM.MONTGOMERY) - { - gy = new BIG(ROM.CURVE_Gy); - G = new ECP(gx,gy); - } - else - { - G = new ECP(gx); - } - - r = new BIG(ROM.CURVE_Order); - - if (RNG == null) - { - s = BIG.fromBytes(S); - } - else - { - s = BIG.randomnum(r,RNG); - - s.toBytes(T); - for (int i = 0;i < EGS;i++) - { - S[i] = T[i]; - } - } - - WP = G.mul(s); - WP.toBytes(W); - - return res; - } - -/* validate public key. Set full=true for fuller check */ - public static int PUBLIC_KEY_VALIDATE(bool full, sbyte[] W) - { - BIG r; - ECP WP = ECP.fromBytes(W); - int res = 0; - - r = new BIG(ROM.CURVE_Order); - - if (WP.is_infinity()) - { - res = INVALID_PUBLIC_KEY; - } - if (res == 0 && full) - { - WP = WP.mul(r); - if (!WP.is_infinity()) - { - res = INVALID_PUBLIC_KEY; - } - } - return res; - } - -/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */ - public static int ECPSVDP_DH(sbyte[] S, sbyte[] WD, sbyte[] Z) - { - BIG r, s; - ECP W; - int res = 0; - sbyte[] T = new sbyte[EFS]; - - s = BIG.fromBytes(S); - - W = ECP.fromBytes(WD); - if (W.is_infinity()) - { - res = ERROR; - } - - if (res == 0) - { - r = new BIG(ROM.CURVE_Order); - s.mod(r); - W = W.mul(s); - if (W.is_infinity()) - { - res = ERROR; - } - else - { - W.X.toBytes(T); - for (int i = 0;i < EFS;i++) - { - Z[i] = T[i]; - } - } - } - return res; - } - -/* IEEE ECDSA Signature, C and D are signature on F using private key S */ - public static int ECPSP_DSA(RAND RNG, sbyte[] S, sbyte[] F, sbyte[] C, sbyte[] D) - { - sbyte[] T = new sbyte[EFS]; - BIG gx, gy, r, s, f, c, d, u, vx; - ECP G, V; - - HASH H = new HASH(); - H.process_array(F); - sbyte[] B = H.hash(); - - gx = new BIG(ROM.CURVE_Gx); - gy = new BIG(ROM.CURVE_Gy); - - G = new ECP(gx,gy); - r = new BIG(ROM.CURVE_Order); - - s = BIG.fromBytes(S); - f = BIG.fromBytes(B); - - c = new BIG(0); - d = new BIG(0); - V = new ECP(); - - do - { - u = BIG.randomnum(r,RNG); - - V.copy(G); - V = V.mul(u); - vx = V.X; - c.copy(vx); - c.mod(r); - if (c.iszilch()) - { - continue; - } - u.invmodp(r); - d.copy(BIG.modmul(s,c,r)); - d.add(f); - d.copy(BIG.modmul(u,d,r)); - } while (d.iszilch()); - - c.toBytes(T); - for (int i = 0;i < EFS;i++) - { - C[i] = T[i]; - } - d.toBytes(T); - for (int i = 0;i < EFS;i++) - { - D[i] = T[i]; - } - return 0; - } - -/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */ - public static int ECPVP_DSA(sbyte[] W, sbyte[] F, sbyte[] C, sbyte[] D) - { - BIG r, gx, gy, f, c, d, h2; - int res = 0; - ECP G, WP, P; - - HASH H = new HASH(); - H.process_array(F); - sbyte[] B = H.hash(); - - gx = new BIG(ROM.CURVE_Gx); - gy = new BIG(ROM.CURVE_Gy); - - G = new ECP(gx,gy); - r = new BIG(ROM.CURVE_Order); - - c = BIG.fromBytes(C); - d = BIG.fromBytes(D); - f = BIG.fromBytes(B); - - if (c.iszilch() || BIG.comp(c,r) >= 0 || d.iszilch() || BIG.comp(d,r) >= 0) - { - res = INVALID; - } - - if (res == 0) - { - d.invmodp(r); - f.copy(BIG.modmul(f,d,r)); - h2 = BIG.modmul(c,d,r); - - WP = ECP.fromBytes(W); - if (WP.is_infinity()) - { - res = ERROR; - } - else - { - P = new ECP(); - P.copy(WP); - P = P.mul2(h2,G,f); - if (P.is_infinity()) - { - res = INVALID; - } - else - { - d = P.X; - d.mod(r); - if (BIG.comp(d,c) != 0) - { - res = INVALID; - } - } - } - } - - return res; - } - -/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */ - public static sbyte[] ECIES_ENCRYPT(sbyte[] P1, sbyte[] P2, RAND RNG, sbyte[] W, sbyte[] M, sbyte[] V, sbyte[] T) - { - int i; - - sbyte[] Z = new sbyte[EFS]; - sbyte[] VZ = new sbyte[3 * EFS + 1]; - sbyte[] K1 = new sbyte[EAS]; - sbyte[] K2 = new sbyte[EAS]; - sbyte[] U = new sbyte[EGS]; - - if (KEY_PAIR_GENERATE(RNG,U,V) != 0) - { - return new sbyte[0]; - } - if (ECPSVDP_DH(U,W,Z) != 0) - { - return new sbyte[0]; - } - - for (i = 0;i < 2 * EFS + 1;i++) - { - VZ[i] = V[i]; - } - for (i = 0;i < EFS;i++) - { - VZ[2 * EFS + 1 + i] = Z[i]; - } - - - sbyte[] K = KDF2(VZ,P1,EFS); - - for (i = 0;i < EAS;i++) - { - K1[i] = K[i]; - K2[i] = K[EAS + i]; - } - - sbyte[] C = AES_CBC_IV0_ENCRYPT(K1,M); - - sbyte[] L2 = inttoBytes(P2.Length,8); - - sbyte[] AC = new sbyte[C.Length + P2.Length + 8]; - for (i = 0;i < C.Length;i++) - { - AC[i] = C[i]; - } - for (i = 0;i < P2.Length;i++) - { - AC[C.Length + i] = P2[i]; - } - for (i = 0;i < 8;i++) - { - AC[C.Length + P2.Length + i] = L2[i]; - } - - HMAC(AC,K2,T); - - return C; - } - -/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */ - public static sbyte[] ECIES_DECRYPT(sbyte[] P1, sbyte[] P2, sbyte[] V, sbyte[] C, sbyte[] T, sbyte[] U) - { - - int i; - - sbyte[] Z = new sbyte[EFS]; - sbyte[] VZ = new sbyte[3 * EFS + 1]; - sbyte[] K1 = new sbyte[EAS]; - sbyte[] K2 = new sbyte[EAS]; - sbyte[] TAG = new sbyte[T.Length]; - - if (ECPSVDP_DH(U,V,Z) != 0) - { - return new sbyte[0]; - } - - for (i = 0;i < 2 * EFS + 1;i++) - { - VZ[i] = V[i]; - } - for (i = 0;i < EFS;i++) - { - VZ[2 * EFS + 1 + i] = Z[i]; - } - - sbyte[] K = KDF2(VZ,P1,EFS); - - for (i = 0;i < EAS;i++) - { - K1[i] = K[i]; - K2[i] = K[EAS + i]; - } - - sbyte[] M = AES_CBC_IV0_DECRYPT(K1,C); - - if (M.Length == 0) - { - return M; - } - - sbyte[] L2 = inttoBytes(P2.Length,8); - - sbyte[] AC = new sbyte[C.Length + P2.Length + 8]; - - for (i = 0;i < C.Length;i++) - { - AC[i] = C[i]; - } - for (i = 0;i < P2.Length;i++) - { - AC[C.Length + i] = P2[i]; - } - for (i = 0;i < 8;i++) - { - AC[C.Length + P2.Length + i] = L2[i]; - } - - HMAC(AC,K2,TAG); - - bool same = true; - for (i = 0;i < T.Length;i++) - { - if (T[i] != TAG[i]) - { - same = false; - } - } - if (!same) - { - return new sbyte[0]; - } - - return M; - - } -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/cs/ECP.cs ---------------------------------------------------------------------- diff --git a/cs/ECP.cs b/cs/ECP.cs deleted file mode 100644 index 4ad1a5c..0000000 --- a/cs/ECP.cs +++ /dev/null @@ -1,1216 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* Elliptic Curve Point class */ - -public sealed class ECP -{ - private FP x; - private FP y; - private FP z; - private bool INF; - -/* Constructor - set to O */ - public ECP() - { - INF = true; - x = new FP(0); - y = new FP(1); - z = new FP(1); - } -/* test for O point-at-infinity */ - public bool is_infinity() - { - if (ROM.CURVETYPE == ROM.EDWARDS) - { - x.reduce(); - y.reduce(); - z.reduce(); - return (x.iszilch() && y.Equals(z)); - } - else - { - return INF; - } - } -/* Conditional swap of P and Q dependant on d */ - private void cswap(ECP Q, int d) - { - x.cswap(Q.x,d); - if (ROM.CURVETYPE != ROM.MONTGOMERY) - { - y.cswap(Q.y,d); - } - z.cswap(Q.z,d); - if (ROM.CURVETYPE != ROM.EDWARDS) - { - bool bd; - if (d == 0) - { - bd = false; - } - else - { - bd = true; - } - bd = bd & (INF ^ Q.INF); - INF ^= bd; - Q.INF ^= bd; - } - } - -/* Conditional move of Q to P dependant on d */ - private void cmove(ECP Q, int d) - { - x.cmove(Q.x,d); - if (ROM.CURVETYPE != ROM.MONTGOMERY) - { - y.cmove(Q.y,d); - } - z.cmove(Q.z,d); - if (ROM.CURVETYPE != ROM.EDWARDS) - { - bool bd; - if (d == 0) - { - bd = false; - } - else - { - bd = true; - } - INF ^= (INF ^ Q.INF) & bd; - } - } - -/* return 1 if b==c, no branching */ - private static int teq(int b, int c) - { - int x = b ^ c; - x -= 1; // if x=0, x now -1 - return ((x >> 31) & 1); - } - -/* Constant time select from pre-computed table */ - private void select(ECP[] W, int b) - { - ECP MP = new ECP(); - int m = b >> 31; - int babs = (b ^ m) - m; - - babs = (babs - 1) / 2; - - cmove(W[0],teq(babs,0)); // conditional move - cmove(W[1],teq(babs,1)); - cmove(W[2],teq(babs,2)); - cmove(W[3],teq(babs,3)); - cmove(W[4],teq(babs,4)); - cmove(W[5],teq(babs,5)); - cmove(W[6],teq(babs,6)); - cmove(W[7],teq(babs,7)); - - MP.copy(this); - MP.neg(); - cmove(MP,(int)(m & 1)); - } - - -/* Test P == Q */ - public bool Equals(ECP Q) - { - if (is_infinity() && Q.is_infinity()) - { - return true; - } - if (is_infinity() || Q.is_infinity()) - { - return false; - } - if (ROM.CURVETYPE == ROM.WEIERSTRASS) - { - FP zs2 = new FP(z); - zs2.sqr(); - FP zo2 = new FP(Q.z); - zo2.sqr(); - FP zs3 = new FP(zs2); - zs3.mul(z); - FP zo3 = new FP(zo2); - zo3.mul(Q.z); - zs2.mul(Q.x); - zo2.mul(x); - if (!zs2.Equals(zo2)) - { - return false; - } - zs3.mul(Q.y); - zo3.mul(y); - if (!zs3.Equals(zo3)) - { - return false; - } - } - else - { - FP a = new FP(0); - FP b = new FP(0); - a.copy(x); - a.mul(Q.z); - a.reduce(); - b.copy(Q.x); - b.mul(z); - b.reduce(); - if (!a.Equals(b)) - { - return false; - } - if (ROM.CURVETYPE == ROM.EDWARDS) - { - a.copy(y); - a.mul(Q.z); - a.reduce(); - b.copy(Q.y); - b.mul(z); - b.reduce(); - if (!a.Equals(b)) - { - return false; - } - } - } - return true; - } - -/* this=P */ - public void copy(ECP P) - { - x.copy(P.x); - if (ROM.CURVETYPE != ROM.MONTGOMERY) - { - y.copy(P.y); - } - z.copy(P.z); - INF = P.INF; - } -/* this=-this */ - public void neg() - { - if (is_infinity()) - { - return; - } - if (ROM.CURVETYPE == ROM.WEIERSTRASS) - { - y.neg(); - y.reduce(); - } - if (ROM.CURVETYPE == ROM.EDWARDS) - { - x.neg(); - x.reduce(); - } - return; - } -/* set this=O */ - public void inf() - { - INF = true; - x.zero(); - y.one(); - z.one(); - // y=new FP(1); - // z=new FP(1); - } - -/* Calculate RHS of curve equation */ - public static FP RHS(FP x) - { - x.norm(); - FP r = new FP(x); - r.sqr(); - - if (ROM.CURVETYPE == ROM.WEIERSTRASS) - { // x^3+Ax+B - FP b = new FP(new BIG(ROM.CURVE_B)); - r.mul(x); - if (ROM.CURVE_A == -3) - { - FP cx = new FP(x); - cx.imul(3); - cx.neg(); - cx.norm(); - r.add(cx); - } - r.add(b); - } - if (ROM.CURVETYPE == ROM.EDWARDS) - { // (Ax^2-1)/(Bx^2-1) - FP b = new FP(new BIG(ROM.CURVE_B)); - - FP one = new FP(1); - b.mul(r); - b.sub(one); - if (ROM.CURVE_A == -1) - { - r.neg(); - } - r.sub(one); - - b.inverse(); - - r.mul(b); - } - if (ROM.CURVETYPE == ROM.MONTGOMERY) - { // x^3+Ax^2+x - FP x3 = new FP(0); - x3.copy(r); - x3.mul(x); - r.imul(ROM.CURVE_A); - r.add(x3); - r.add(x); - } - r.reduce(); - return r; - } - -/* set (x,y) from two BIGs */ - public ECP(BIG ix, BIG iy) - { - x = new FP(ix); - y = new FP(iy); - z = new FP(1); - FP rhs = RHS(x); - - if (ROM.CURVETYPE == ROM.MONTGOMERY) - { - if (rhs.jacobi() == 1) - { - INF = false; - } - else - { - inf(); - } - } - else - { - FP y2 = new FP(y); - y2.sqr(); - if (y2.Equals(rhs)) - { - INF = false; - } - else - { - inf(); - } - } - } -/* set (x,y) from BIG and a bit */ - public ECP(BIG ix, int s) - { - x = new FP(ix); - FP rhs = RHS(x); - y = new FP(0); - z = new FP(1); - if (rhs.jacobi() == 1) - { - FP ny = rhs.sqrt(); - if (ny.redc().parity() != s) - { - ny.neg(); - } - y.copy(ny); - INF = false; - } - else - { - inf(); - } - } - -/* set from x - calculate y from curve equation */ - public ECP(BIG ix) - { - x = new FP(ix); - FP rhs = RHS(x); - y = new FP(0); - z = new FP(1); - if (rhs.jacobi() == 1) - { - if (ROM.CURVETYPE != ROM.MONTGOMERY) - { - y.copy(rhs.sqrt()); - } - INF = false; - } - else - { - INF = true; - } - } - -/* set to affine - from (x,y,z) to (x,y) */ - public void affine() - { - if (is_infinity()) - { - return; - } - FP one = new FP(1); - if (z.Equals(one)) - { - return; - } - z.inverse(); - if (ROM.CURVETYPE == ROM.WEIERSTRASS) - { - FP z2 = new FP(z); - z2.sqr(); - x.mul(z2); - x.reduce(); - y.mul(z2); - y.mul(z); - y.reduce(); - } - if (ROM.CURVETYPE == ROM.EDWARDS) - { - x.mul(z); - x.reduce(); - y.mul(z); - y.reduce(); - } - if (ROM.CURVETYPE == ROM.MONTGOMERY) - { - x.mul(z); - x.reduce(); - } - z.copy(one); - } -/* extract x as a BIG */ - public BIG X - { - get - { - affine(); - return x.redc(); - } - } -/* extract y as a BIG */ - public BIG Y - { - get - { - affine(); - return y.redc(); - } - } - -/* get sign of Y */ - public int S - { - get - { - affine(); - BIG y = Y; - return y.parity(); - } - } -/* extract x as an FP */ - public FP getx() - { - return x; - } -/* extract y as an FP */ - public FP gety() - { - return y; - } -/* extract z as an FP */ - public FP getz() - { - return z; - } -/* convert to byte array */ - public void toBytes(sbyte[] b) - { - sbyte[] t = new sbyte[ROM.MODBYTES]; - if (ROM.CURVETYPE != ROM.MONTGOMERY) - { - b[0] = 0x04; - } - else - { - b[0] = 0x02; - } - - affine(); - x.redc().toBytes(t); - for (int i = 0;i < ROM.MODBYTES;i++) - { - b[i + 1] = t[i]; - } - if (ROM.CURVETYPE != ROM.MONTGOMERY) - { - y.redc().toBytes(t); - for (int i = 0;i < ROM.MODBYTES;i++) - { - b[i + ROM.MODBYTES + 1] = t[i]; - } - } - } -/* convert from byte array to point */ - public static ECP fromBytes(sbyte[] b) - { - sbyte[] t = new sbyte[ROM.MODBYTES]; - BIG p = new BIG(ROM.Modulus); - - for (int i = 0;i < ROM.MODBYTES;i++) - { - t[i] = b[i + 1]; - } - BIG px = BIG.fromBytes(t); - if (BIG.comp(px,p) >= 0) - { - return new ECP(); - } - - if (b[0] == 0x04) - { - for (int i = 0;i < ROM.MODBYTES;i++) - { - t[i] = b[i + ROM.MODBYTES + 1]; - } - BIG py = BIG.fromBytes(t); - if (BIG.comp(py,p) >= 0) - { - return new ECP(); - } - return new ECP(px,py); - } - else - { - return new ECP(px); - } - } -/* convert to hex string */ - public override string ToString() - { - if (is_infinity()) - { - return "infinity"; - } - affine(); - if (ROM.CURVETYPE == ROM.MONTGOMERY) - { - return "(" + x.redc().ToString() + ")"; - } - else - { - return "(" + x.redc().ToString() + "," + y.redc().ToString() + ")"; - } - } -/* this*=2 */ - public void dbl() - { - if (ROM.CURVETYPE == ROM.WEIERSTRASS) - { - if (INF) - { - return; - } - if (y.iszilch()) - { - inf(); - return; - } - - FP w1 = new FP(x); - FP w6 = new FP(z); - FP w2 = new FP(0); - FP w3 = new FP(x); - FP w8 = new FP(x); - - if (ROM.CURVE_A == -3) - { - w6.sqr(); - w1.copy(w6); - w1.neg(); - w3.add(w1); - w8.add(w6); - w3.mul(w8); - w8.copy(w3); - w8.imul(3); - } - else - { - w1.sqr(); - w8.copy(w1); - w8.imul(3); - } - - w2.copy(y); - w2.sqr(); - w3.copy(x); - w3.mul(w2); - w3.imul(4); - w1.copy(w3); - w1.neg(); - // w1.norm(); - - x.copy(w8); - x.sqr(); - x.add(w1); - x.add(w1); - // x.reduce(); - x.norm(); - - z.mul(y); - z.add(z); - - w2.add(w2); - w2.sqr(); - w2.add(w2); - w3.sub(x); - y.copy(w8); - y.mul(w3); - // w2.norm(); - y.sub(w2); - // y.reduce(); - // z.reduce(); - y.norm(); - z.norm(); - } - if (ROM.CURVETYPE == ROM.EDWARDS) - { - FP C = new FP(x); - FP D = new FP(y); - FP H = new FP(z); - FP J = new FP(0); - - x.mul(y); - x.add(x); - C.sqr(); - D.sqr(); - if (ROM.CURVE_A == -1) - { - C.neg(); - } - y.copy(C); - y.add(D); - // y.norm(); - H.sqr(); - H.add(H); - z.copy(y); - J.copy(y); - J.sub(H); - x.mul(J); - C.sub(D); - y.mul(C); - z.mul(J); - - x.norm(); - y.norm(); - z.norm(); - } - if (ROM.CURVETYPE == ROM.MONTGOMERY) - { - FP A = new FP(x); - FP B = new FP(x); - FP AA = new FP(0); - FP BB = new FP(0); - FP C = new FP(0); - - if (INF) - { - return; - } - - A.add(z); - AA.copy(A); - AA.sqr(); - B.sub(z); - BB.copy(B); - BB.sqr(); - C.copy(AA); - C.sub(BB); - // C.norm(); - - x.copy(AA); - x.mul(BB); - - A.copy(C); - A.imul((ROM.CURVE_A + 2) / 4); - - BB.add(A); - z.copy(BB); - z.mul(C); - // x.reduce(); - // z.reduce(); - x.norm(); - z.norm(); - } - return; - } - -/* this+=Q */ - public void add(ECP Q) - { - if (ROM.CURVETYPE == ROM.WEIERSTRASS) - { - if (INF) - { - copy(Q); - return; - } - if (Q.INF) - { - return; - } - - bool aff = false; - - FP one = new FP(1); - if (Q.z.Equals(one)) - { - aff = true; - } - - FP A, C; - FP B = new FP(z); - FP D = new FP(z); - if (!aff) - { - A = new FP(Q.z); - C = new FP(Q.z); - - A.sqr(); - B.sqr(); - C.mul(A); - D.mul(B); - - A.mul(x); - C.mul(y); - } - else - { - A = new FP(x); - C = new FP(y); - - B.sqr(); - D.mul(B); - } - - B.mul(Q.x); - B.sub(A); - D.mul(Q.y); - D.sub(C); - - if (B.iszilch()) - { - if (D.iszilch()) - { - dbl(); - return; - } - else - { - INF = true; - return; - } - } - - if (!aff) - { - z.mul(Q.z); - } - z.mul(B); - - FP e = new FP(B); - e.sqr(); - B.mul(e); - A.mul(e); - - e.copy(A); - e.add(A); - e.add(B); - x.copy(D); - x.sqr(); - x.sub(e); - - A.sub(x); - y.copy(A); - y.mul(D); - C.mul(B); - y.sub(C); - - // x.reduce(); - // y.reduce(); - // z.reduce(); - x.norm(); - y.norm(); - z.norm(); - } - if (ROM.CURVETYPE == ROM.EDWARDS) - { - FP b = new FP(new BIG(ROM.CURVE_B)); - FP A = new FP(z); - FP B = new FP(0); - FP C = new FP(x); - FP D = new FP(y); - FP E = new FP(0); - FP F = new FP(0); - FP G = new FP(0); - // FP H=new FP(0); - // FP I=new FP(0); - - A.mul(Q.z); - B.copy(A); - B.sqr(); - C.mul(Q.x); - D.mul(Q.y); - - E.copy(C); - E.mul(D); - E.mul(b); - F.copy(B); - F.sub(E); - G.copy(B); - G.add(E); - C.add(D); - - if (ROM.CURVE_A == 1) - { - E.copy(D); - D.sub(C); - } - - B.copy(x); - B.add(y); - D.copy(Q.x); - D.add(Q.y); - B.mul(D); - B.sub(C); - B.mul(F); - x.copy(A); - x.mul(B); - - if (ROM.CURVE_A == 1) - { - C.copy(E); - C.mul(G); - } - if (ROM.CURVE_A == -1) - { - C.mul(G); - } - y.copy(A); - y.mul(C); - z.copy(F); - z.mul(G); - // x.reduce(); y.reduce(); z.reduce(); - x.norm(); - y.norm(); - z.norm(); - } - return; - } - -/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */ - public void dadd(ECP Q, ECP W) - { - FP A = new FP(x); - FP B = new FP(x); - FP C = new FP(Q.x); - FP D = new FP(Q.x); - FP DA = new FP(0); - FP CB = new FP(0); - - A.add(z); - B.sub(z); - - C.add(Q.z); - D.sub(Q.z); - - DA.copy(D); - DA.mul(A); - CB.copy(C); - CB.mul(B); - - A.copy(DA); - A.add(CB); - A.sqr(); - B.copy(DA); - B.sub(CB); - B.sqr(); - - x.copy(A); - z.copy(W.x); - z.mul(B); - - if (z.iszilch()) - { - inf(); - } - else - { - INF = false; - } - - // x.reduce(); - x.norm(); - } -/* this-=Q */ - public void sub(ECP Q) - { - Q.neg(); - add(Q); - Q.neg(); - } - - public static void multiaffine(int m, ECP[] P) - { - int i; - FP t1 = new FP(0); - FP t2 = new FP(0); - - FP[] work = new FP[m]; - - for (i = 0;i < m;i++) - { - work[i] = new FP(0); - } - - work[0].one(); - work[1].copy(P[0].z); - - for (i = 2;i < m;i++) - { - work[i].copy(work[i - 1]); - work[i].mul(P[i - 1].z); - } - - t1.copy(work[m - 1]); - t1.mul(P[m - 1].z); - t1.inverse(); - t2.copy(P[m - 1].z); - work[m - 1].mul(t1); - - for (i = m - 2;;i--) - { - if (i == 0) - { - work[0].copy(t1); - work[0].mul(t2); - break; - } - work[i].mul(t2); - work[i].mul(t1); - t2.mul(P[i].z); - } -/* now work[] contains inverses of all Z coordinates */ - - for (i = 0;i < m;i++) - { - P[i].z.one(); - t1.copy(work[i]); - t1.sqr(); - P[i].x.mul(t1); - t1.mul(work[i]); - P[i].y.mul(t1); - } - } - -/* constant time multiply by small integer of length bts - use ladder */ - public ECP pinmul(int e, int bts) - { - if (ROM.CURVETYPE == ROM.MONTGOMERY) - { - return this.mul(new BIG(e)); - } - else - { - int nb, i, b; - ECP P = new ECP(); - ECP R0 = new ECP(); - ECP R1 = new ECP(); - R1.copy(this); - - for (i = bts - 1;i >= 0;i--) - { - b = (e >> i) & 1; - P.copy(R1); - P.add(R0); - R0.cswap(R1,b); - R1.copy(P); - R0.dbl(); - R0.cswap(R1,b); - } - P.copy(R0); - P.affine(); - return P; - } - } - -/* return e.this */ - - public ECP mul(BIG e) - { - if (e.iszilch() || is_infinity()) - { - return new ECP(); - } - ECP P = new ECP(); - if (ROM.CURVETYPE == ROM.MONTGOMERY) - { -/* use Ladder */ - int nb, i, b; - ECP D = new ECP(); - ECP R0 = new ECP(); - R0.copy(this); - ECP R1 = new ECP(); - R1.copy(this); - R1.dbl(); - D.copy(this); - D.affine(); - nb = e.nbits(); - for (i = nb - 2;i >= 0;i--) - { - b = e.bit(i); - P.copy(R1); - P.dadd(R0,D); - R0.cswap(R1,b); - R1.copy(P); - R0.dbl(); - R0.cswap(R1,b); - } - P.copy(R0); - } - else - { -// fixed size windows - int i, b, nb, m, s, ns; - BIG mt = new BIG(); - BIG t = new BIG(); - ECP Q = new ECP(); - ECP C = new ECP(); - ECP[] W = new ECP[8]; - sbyte[] w = new sbyte[1 + (ROM.NLEN * ROM.BASEBITS + 3) / 4]; - - affine(); - -// precompute table - Q.copy(this); - Q.dbl(); - W[0] = new ECP(); - W[0].copy(this); - - for (i = 1;i < 8;i++) - { - W[i] = new ECP(); - W[i].copy(W[i - 1]); - W[i].add(Q); - } - -// convert the table to affine - if (ROM.CURVETYPE == ROM.WEIERSTRASS) - { - multiaffine(8,W); - } - -// make exponent odd - add 2P if even, P if odd - t.copy(e); - s = t.parity(); - t.inc(1); - t.norm(); - ns = t.parity(); - mt.copy(t); - mt.inc(1); - mt.norm(); - t.cmove(mt,s); - Q.cmove(this,ns); - C.copy(Q); - - nb = 1 + (t.nbits() + 3) / 4; - -// convert exponent to signed 4-bit window - for (i = 0;i < nb;i++) - { - w[i] = (sbyte)(t.lastbits(5) - 16); - t.dec(w[i]); - t.norm(); - t.fshr(4); - } - w[nb] = (sbyte)t.lastbits(5); - - P.copy(W[(w[nb] - 1) / 2]); - for (i = nb - 1;i >= 0;i--) - { - Q.select(W,w[i]); - P.dbl(); - P.dbl(); - P.dbl(); - P.dbl(); - P.add(Q); - } - P.sub(C); // apply correction - } - P.affine(); - return P; - } -/* Return e.this+f.Q */ - - public ECP mul2(BIG e, ECP Q, BIG f) - { - BIG te = new BIG(); - BIG tf = new BIG(); - BIG mt = new BIG(); - ECP S = new ECP(); - ECP T = new ECP(); - ECP C = new ECP(); - ECP[] W = new ECP[8]; - sbyte[] w = new sbyte[1 + (ROM.NLEN * ROM.BASEBITS + 1) / 2]; - int i, s, ns, nb; - sbyte a, b; - - affine(); - Q.affine(); - - te.copy(e); - tf.copy(f); - -// precompute table - W[1] = new ECP(); - W[1].copy(this); - W[1].sub(Q); - W[2] = new ECP(); - W[2].copy(this); - W[2].add(Q); - S.copy(Q); - S.dbl(); - W[0] = new ECP(); - W[0].copy(W[1]); - W[0].sub(S); - W[3] = new ECP(); - W[3].copy(W[2]); - W[3].add(S); - T.copy(this); - T.dbl(); - W[5] = new ECP(); - W[5].copy(W[1]); - W[5].add(T); - W[6] = new ECP(); - W[6].copy(W[2]); - W[6].add(T); - W[4] = new ECP(); - W[4].copy(W[5]); - W[4].sub(S); - W[7] = new ECP(); - W[7].copy(W[6]); - W[7].add(S); - -// convert the table to affine - if (ROM.CURVETYPE == ROM.WEIERSTRASS) - { - multiaffine(8,W); - } - -// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction - - s = te.parity(); - te.inc(1); - te.norm(); - ns = te.parity(); - mt.copy(te); - mt.inc(1); - mt.norm(); - te.cmove(mt,s); - T.cmove(this,ns); - C.copy(T); - - s = tf.parity(); - tf.inc(1); - tf.norm(); - ns = tf.parity(); - mt.copy(tf); - mt.inc(1); - mt.norm(); - tf.cmove(mt,s); - S.cmove(Q,ns); - C.add(S); - - mt.copy(te); - mt.add(tf); - mt.norm(); - nb = 1 + (mt.nbits() + 1) / 2; - -// convert exponent to signed 2-bit window - for (i = 0;i < nb;i++) - { - a = (sbyte)(te.lastbits(3) - 4); - te.dec(a); - te.norm(); - te.fshr(2); - b = (sbyte)(tf.lastbits(3) - 4); - tf.dec(b); - tf.norm(); - tf.fshr(2); - w[i] = (sbyte)(4 * a + b); - } - w[nb] = (sbyte)(4 * te.lastbits(3) + tf.lastbits(3)); - S.copy(W[(w[nb] - 1) / 2]); - - for (i = nb - 1;i >= 0;i--) - { - T.select(W,w[i]); - S.dbl(); - S.dbl(); - S.add(T); - } - S.sub(C); // apply correction - S.affine(); - return S; - } - -/* - public static void main(String[] args) { - - BIG Gx=new BIG(ROM.CURVE_Gx); - BIG Gy; - ECP P; - if (ROM.CURVETYPE!=ROM.MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy); - BIG r=new BIG(ROM.CURVE_Order); - - //r.dec(7); - - System.out.println("Gx= "+Gx.toString()); - if (ROM.CURVETYPE!=ROM.MONTGOMERY) System.out.println("Gy= "+Gy.toString()); - - if (ROM.CURVETYPE!=ROM.MONTGOMERY) P=new ECP(Gx,Gy); - else P=new ECP(Gx); - - System.out.println("P= "+P.toString()); - - ECP R=P.mul(r); - //for (int i=0;i<10000;i++) - // R=P.mul(r); - - System.out.println("R= "+R.toString()); - } */ -} - http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/cs/ECP2.cs ---------------------------------------------------------------------- diff --git a/cs/ECP2.cs b/cs/ECP2.cs deleted file mode 100644 index 28f9295..0000000 --- a/cs/ECP2.cs +++ /dev/null @@ -1,771 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* AMCL Weierstrass elliptic curve functions over FP2 */ - -public sealed class ECP2 -{ - private FP2 x; - private FP2 y; - private FP2 z; - private bool INF; - -/* Constructor - set this=O */ - public ECP2() - { - INF = true; - x = new FP2(0); - y = new FP2(1); - z = new FP2(1); - } - -/* Test this=O? */ - public bool is_infinity() - { - return INF; - } -/* copy this=P */ - public void copy(ECP2 P) - { - x.copy(P.x); - y.copy(P.y); - z.copy(P.z); - INF = P.INF; - } -/* set this=O */ - public void inf() - { - INF = true; - x.zero(); - y.zero(); - z.zero(); - } - -/* Conditional move of Q to P dependant on d */ - public void cmove(ECP2 Q, int d) - { - x.cmove(Q.x,d); - y.cmove(Q.y,d); - z.cmove(Q.z,d); - - bool bd; - if (d == 0) - { - bd = false; - } - else - { - bd = true; - } - INF ^= (INF ^ Q.INF) & bd; - } - -/* return 1 if b==c, no branching */ - public static int teq(int b, int c) - { - int x = b ^ c; - x -= 1; // if x=0, x now -1 - return ((x >> 31) & 1); - } - -/* Constant time select from pre-computed table */ - public void select(ECP2[] W, int b) - { - ECP2 MP = new ECP2(); - int m = b >> 31; - int babs = (b ^ m) - m; - - babs = (babs - 1) / 2; - - cmove(W[0],teq(babs,0)); // conditional move - cmove(W[1],teq(babs,1)); - cmove(W[2],teq(babs,2)); - cmove(W[3],teq(babs,3)); - cmove(W[4],teq(babs,4)); - cmove(W[5],teq(babs,5)); - cmove(W[6],teq(babs,6)); - cmove(W[7],teq(babs,7)); - - MP.copy(this); - MP.neg(); - cmove(MP,(int)(m & 1)); - } - - -/* Test if P == Q */ - public bool Equals(ECP2 Q) - { - if (is_infinity() && Q.is_infinity()) - { - return true; - } - if (is_infinity() || Q.is_infinity()) - { - return false; - } - - FP2 zs2 = new FP2(z); - zs2.sqr(); - FP2 zo2 = new FP2(Q.z); - zo2.sqr(); - FP2 zs3 = new FP2(zs2); - zs3.mul(z); - FP2 zo3 = new FP2(zo2); - zo3.mul(Q.z); - zs2.mul(Q.x); - zo2.mul(x); - if (!zs2.Equals(zo2)) - { - return false; - } - zs3.mul(Q.y); - zo3.mul(y); - if (!zs3.Equals(zo3)) - { - return false; - } - - return true; - } -/* set this=-this */ - public void neg() - { - if (is_infinity()) - { - return; - } - y.neg(); - y.reduce(); - return; - } -/* set to Affine - (x,y,z) to (x,y) */ - public void affine() - { - if (is_infinity()) - { - return; - } - FP2 one = new FP2(1); - if (z.Equals(one)) - { - return; - } - z.inverse(); - - FP2 z2 = new FP2(z); - z2.sqr(); - x.mul(z2); - x.reduce(); - y.mul(z2); - y.mul(z); - y.reduce(); - z.copy(one); - } -/* extract affine x as FP2 */ - public FP2 X - { - get - { - affine(); - return x; - } - } -/* extract affine y as FP2 */ - public FP2 Y - { - get - { - affine(); - return y; - } - } -/* extract projective x */ - public FP2 getx() - { - return x; - } -/* extract projective y */ - public FP2 gety() - { - return y; - } -/* extract projective z */ - public FP2 getz() - { - return z; - } -/* convert to byte array */ - public void toBytes(sbyte[] b) - { - sbyte[] t = new sbyte[ROM.MODBYTES]; - affine(); - x.A.toBytes(t); - for (int i = 0;i < ROM.MODBYTES;i++) - { - b[i] = t[i]; - } - x.B.toBytes(t); - for (int i = 0;i < ROM.MODBYTES;i++) - { - b[i + ROM.MODBYTES] = t[i]; - } - - y.A.toBytes(t); - for (int i = 0;i < ROM.MODBYTES;i++) - { - b[i + 2 * ROM.MODBYTES] = t[i]; - } - y.B.toBytes(t); - for (int i = 0;i < ROM.MODBYTES;i++) - { - b[i + 3 * ROM.MODBYTES] = t[i]; - } - } -/* convert from byte array to point */ - public static ECP2 fromBytes(sbyte[] b) - { - sbyte[] t = new sbyte[ROM.MODBYTES]; - BIG ra; - BIG rb; - - for (int i = 0;i < ROM.MODBYTES;i++) - { - t[i] = b[i]; - } - ra = BIG.fromBytes(t); - for (int i = 0;i < ROM.MODBYTES;i++) - { - t[i] = b[i + ROM.MODBYTES]; - } - rb = BIG.fromBytes(t); - FP2 rx = new FP2(ra,rb); - - for (int i = 0;i < ROM.MODBYTES;i++) - { - t[i] = b[i + 2 * ROM.MODBYTES]; - } - ra = BIG.fromBytes(t); - for (int i = 0;i < ROM.MODBYTES;i++) - { - t[i] = b[i + 3 * ROM.MODBYTES]; - } - rb = BIG.fromBytes(t); - FP2 ry = new FP2(ra,rb); - - return new ECP2(rx,ry); - } -/* convert this to hex string */ - public override string ToString() - { - if (is_infinity()) - { - return "infinity"; - } - affine(); - return "(" + x.ToString() + "," + y.ToString() + ")"; - } - -/* Calculate RHS of twisted curve equation x^3+B/i */ - public static FP2 RHS(FP2 x) - { - x.norm(); - FP2 r = new FP2(x); - r.sqr(); - FP2 b = new FP2(new BIG(ROM.CURVE_B)); - b.div_ip(); - r.mul(x); - r.add(b); - - r.reduce(); - return r; - } -/* construct this from (x,y) - but set to O if not on curve */ - public ECP2(FP2 ix, FP2 iy) - { - x = new FP2(ix); - y = new FP2(iy); - z = new FP2(1); - FP2 rhs = RHS(x); - FP2 y2 = new FP2(y); - y2.sqr(); - if (y2.Equals(rhs)) - { - INF = false; - } - else - { - x.zero(); - INF = true; - } - } - -/* construct this from x - but set to O if not on curve */ - public ECP2(FP2 ix) - { - x = new FP2(ix); - y = new FP2(1); - z = new FP2(1); - FP2 rhs = RHS(x); - if (rhs.sqrt()) - { - y.copy(rhs); - INF = false; - } - else - { - x.zero(); - INF = true; - } - } - -/* this+=this */ - public int dbl() - { - if (INF) - { - return -1; - } - if (y.iszilch()) - { - inf(); - return -1; - } - - FP2 w1 = new FP2(x); - FP2 w2 = new FP2(0); - FP2 w3 = new FP2(x); - FP2 w8 = new FP2(x); - - w1.sqr(); - w8.copy(w1); - w8.imul(3); - - w2.copy(y); - w2.sqr(); - w3.copy(x); - w3.mul(w2); - w3.imul(4); - w1.copy(w3); - w1.neg(); - // w1.norm(); - - x.copy(w8); - x.sqr(); - x.add(w1); - x.add(w1); - x.norm(); - - z.mul(y); - z.add(z); - - w2.add(w2); - w2.sqr(); - w2.add(w2); - w3.sub(x); - y.copy(w8); - y.mul(w3); - // w2.norm(); - y.sub(w2); - - y.norm(); - z.norm(); - - return 1; - } -/* this+=Q - return 0 for add, 1 for double, -1 for O */ - public int add(ECP2 Q) - { - if (INF) - { - copy(Q); - return -1; - } - if (Q.INF) - { - return -1; - } - - bool aff = false; - - if (Q.z.isunity()) - { - aff = true; - } - - FP2 A, C; - FP2 B = new FP2(z); - FP2 D = new FP2(z); - if (!aff) - { - A = new FP2(Q.z); - C = new FP2(Q.z); - - A.sqr(); - B.sqr(); - C.mul(A); - D.mul(B); - - A.mul(x); - C.mul(y); - } - else - { - A = new FP2(x); - C = new FP2(y); - - B.sqr(); - D.mul(B); - } - - B.mul(Q.x); - B.sub(A); - D.mul(Q.y); - D.sub(C); - - if (B.iszilch()) - { - if (D.iszilch()) - { - dbl(); - return 1; - } - else - { - INF = true; - return -1; - } - } - - if (!aff) - { - z.mul(Q.z); - } - z.mul(B); - - FP2 e = new FP2(B); - e.sqr(); - B.mul(e); - A.mul(e); - - e.copy(A); - e.add(A); - e.add(B); - x.copy(D); - x.sqr(); - x.sub(e); - - A.sub(x); - y.copy(A); - y.mul(D); - C.mul(B); - y.sub(C); - - x.norm(); - y.norm(); - z.norm(); - - return 0; - } - -/* set this-=Q */ - public int sub(ECP2 Q) - { - Q.neg(); - int D = add(Q); - Q.neg(); - return D; - } -/* set this*=q, where q is Modulus, using Frobenius */ - public void frob(FP2 X) - { - if (INF) - { - return; - } - FP2 X2 = new FP2(X); - X2.sqr(); - x.conj(); - y.conj(); - z.conj(); - z.reduce(); - x.mul(X2); - y.mul(X2); - y.mul(X); - } - -/* normalises m-array of ECP2 points. Requires work vector of m FP2s */ - - public static void multiaffine(int m, ECP2[] P) - { - int i; - FP2 t1 = new FP2(0); - FP2 t2 = new FP2(0); - - FP2[] work = new FP2[m]; - work[0] = new FP2(1); - work[1] = new FP2(P[0].z); - for (i = 2;i < m;i++) - { - work[i] = new FP2(work[i - 1]); - work[i].mul(P[i - 1].z); - } - - t1.copy(work[m - 1]); - t1.mul(P[m - 1].z); - - t1.inverse(); - - t2.copy(P[m - 1].z); - work[m - 1].mul(t1); - - for (i = m - 2;;i--) - { - if (i == 0) - { - work[0].copy(t1); - work[0].mul(t2); - break; - } - work[i].mul(t2); - work[i].mul(t1); - t2.mul(P[i].z); - } -/* now work[] contains inverses of all Z coordinates */ - - for (i = 0;i < m;i++) - { - P[i].z.one(); - t1.copy(work[i]); - t1.sqr(); - P[i].x.mul(t1); - t1.mul(work[i]); - P[i].y.mul(t1); - } - } - -/* P*=e */ - public ECP2 mul(BIG e) - { -/* fixed size windows */ - int i, b, nb, m, s, ns; - BIG mt = new BIG(); - BIG t = new BIG(); - ECP2 P = new ECP2(); - ECP2 Q = new ECP2(); - ECP2 C = new ECP2(); - ECP2[] W = new ECP2[8]; - sbyte[] w = new sbyte[1 + (ROM.NLEN * ROM.BASEBITS + 3) / 4]; - - if (is_infinity()) - { - return new ECP2(); - } - - affine(); - -/* precompute table */ - Q.copy(this); - Q.dbl(); - W[0] = new ECP2(); - W[0].copy(this); - - for (i = 1;i < 8;i++) - { - W[i] = new ECP2(); - W[i].copy(W[i - 1]); - W[i].add(Q); - } - -/* convert the table to affine */ - - multiaffine(8,W); - -/* make exponent odd - add 2P if even, P if odd */ - t.copy(e); - s = t.parity(); - t.inc(1); - t.norm(); - ns = t.parity(); - mt.copy(t); - mt.inc(1); - mt.norm(); - t.cmove(mt,s); - Q.cmove(this,ns); - C.copy(Q); - - nb = 1 + (t.nbits() + 3) / 4; -/* convert exponent to signed 4-bit window */ - for (i = 0;i < nb;i++) - { - w[i] = (sbyte)(t.lastbits(5) - 16); - t.dec(w[i]); - t.norm(); - t.fshr(4); - } - w[nb] = (sbyte)t.lastbits(5); - - P.copy(W[(w[nb] - 1) / 2]); - for (i = nb - 1;i >= 0;i--) - { - Q.select(W,w[i]); - P.dbl(); - P.dbl(); - P.dbl(); - P.dbl(); - P.add(Q); - } - P.sub(C); - P.affine(); - return P; - } - -/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */ - public static ECP2 mul4(ECP2[] Q, BIG[] u) - { - int i, j, nb; - int[] a = new int[4]; - ECP2 T = new ECP2(); - ECP2 C = new ECP2(); - ECP2 P = new ECP2(); - ECP2[] W = new ECP2[8]; - - BIG mt = new BIG(); - BIG[] t = new BIG[4]; - - sbyte[] w = new sbyte[ROM.NLEN * ROM.BASEBITS + 1]; - - for (i = 0;i < 4;i++) - { - t[i] = new BIG(u[i]); - Q[i].affine(); - } - -/* precompute table */ - - W[0] = new ECP2(); - W[0].copy(Q[0]); - W[0].sub(Q[1]); - W[1] = new ECP2(); - W[1].copy(W[0]); - W[2] = new ECP2(); - W[2].copy(W[0]); - W[3] = new ECP2(); - W[3].copy(W[0]); - W[4] = new ECP2(); - W[4].copy(Q[0]); - W[4].add(Q[1]); - W[5] = new ECP2(); - W[5].copy(W[4]); - W[6] = new ECP2(); - W[6].copy(W[4]); - W[7] = new ECP2(); - W[7].copy(W[4]); - T.copy(Q[2]); - T.sub(Q[3]); - W[1].sub(T); - W[2].add(T); - W[5].sub(T); - W[6].add(T); - T.copy(Q[2]); - T.add(Q[3]); - W[0].sub(T); - W[3].add(T); - W[4].sub(T); - W[7].add(T); - - multiaffine(8,W); - -/* if multiplier is even add 1 to multiplier, and add P to correction */ - mt.zero(); - C.inf(); - for (i = 0;i < 4;i++) - { - if (t[i].parity() == 0) - { - t[i].inc(1); - t[i].norm(); - C.add(Q[i]); - } - mt.add(t[i]); - mt.norm(); - } - - nb = 1 + mt.nbits(); - -/* convert exponent to signed 1-bit window */ - for (j = 0;j < nb;j++) - { - for (i = 0;i < 4;i++) - { - a[i] = (sbyte)(t[i].lastbits(2) - 2); - t[i].dec(a[i]); - t[i].norm(); - t[i].fshr(1); - } - w[j] = (sbyte)(8 * a[0] + 4 * a[1] + 2 * a[2] + a[3]); - } - w[nb] = (sbyte)(8 * t[0].lastbits(2) + 4 * t[1].lastbits(2) + 2 * t[2].lastbits(2) + t[3].lastbits(2)); - - P.copy(W[(w[nb] - 1) / 2]); - for (i = nb - 1;i >= 0;i--) - { - T.select(W,w[i]); - P.dbl(); - P.add(T); - } - P.sub(C); // apply correction - - P.affine(); - return P; - } - - -/* - public static void main(String[] args) { - BIG r=new BIG(ROM.Modulus); - - BIG Pxa=new BIG(ROM.CURVE_Pxa); - BIG Pxb=new BIG(ROM.CURVE_Pxb); - BIG Pya=new BIG(ROM.CURVE_Pya); - BIG Pyb=new BIG(ROM.CURVE_Pyb); - - BIG Fra=new BIG(ROM.CURVE_Fra); - BIG Frb=new BIG(ROM.CURVE_Frb); - - FP2 f=new FP2(Fra,Frb); - - FP2 Px=new FP2(Pxa,Pxb); - FP2 Py=new FP2(Pya,Pyb); - - ECP2 P=new ECP2(Px,Py); - - System.out.println("P= "+P.toString()); - - P=P.mul(r); - System.out.println("P= "+P.toString()); - - ECP2 Q=new ECP2(Px,Py); - Q.frob(f); - System.out.println("Q= "+Q.toString()); - - - } */ - - -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/cs/FF.cs ---------------------------------------------------------------------- diff --git a/cs/FF.cs b/cs/FF.cs deleted file mode 100644 index ed27844..0000000 --- a/cs/FF.cs +++ /dev/null @@ -1,1084 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* Large Finite Field arithmetic */ -/* AMCL mod p functions */ - -public sealed class FF -{ - private readonly BIG[] v; - private readonly int length; - - private static readonly int P_MBITS = ROM.MODBYTES * 8; - private static readonly int P_MB = (P_MBITS % ROM.BASEBITS); - private static readonly long P_OMASK = ((long)(-1) << (P_MBITS % ROM.BASEBITS)); - private static readonly long P_FEXCESS = ((long)1 << (ROM.BASEBITS * ROM.NLEN - P_MBITS)); - private static readonly int P_TBITS = (P_MBITS % ROM.BASEBITS); - - public long P_EXCESS() - { - return ((v[length - 1].get(ROM.NLEN - 1) & P_OMASK) >> (P_MB)); - } - -/* Constructors */ - public FF(int n) - { - v = new BIG[n]; - for (int i = 0;i < n;i++) - { - v[i] = new BIG(0); - } - length = n; - } - - public FF(long[][] x, int n) - { - v = new BIG[n]; - for (int i = 0;i < n;i++) - { - v[i] = new BIG(x[i]); - } - length = n; - } - - public int getlen() - { - return length; - } - -/* set to integer */ - public void set(int m) - { - zero(); - v[0].set(0,(long)m); - } - -/* copy from FF b */ - public void copy(FF b) - { - for (int i = 0;i < length;i++) - { - v[i].copy(b.v[i]); - } - } - -/* x=y<<n */ - public void dsucopy(FF b) - { - for (int i = 0;i < b.length;i++) - { - v[b.length + i].copy(b.v[i]); - v[i].zero(); - } - } - -/* x=y */ - public void dscopy(FF b) - { - for (int i = 0;i < b.length;i++) - { - v[i].copy(b.v[i]); - v[b.length + i].zero(); - } - } - -/* x=y>>n */ - public void sducopy(FF b) - { - for (int i = 0;i < length;i++) - { - v[i].copy(b.v[length + i]); - } - } - -/* set to zero */ - public void zero() - { - for (int i = 0;i < length;i++) - { - v[i].zero(); - } - } - - public void one() - { - v[0].one(); - for (int i = 1;i < length;i++) - { - v[i].zero(); - } - } - -/* test equals 0 */ - public bool iszilch() - { - for (int i = 0;i < length;i++) - { - if (!v[i].iszilch()) - { - return false; - } - } - return true; - } - -/* shift right by 256-bit words */ - public void shrw(int n) - { - for (int i = 0;i < n;i++) - { - v[i].copy(v[i + n]); - v[i + n].zero(); - } - } - -/* shift left by 256-bit words */ - public void shlw(int n) - { - for (int i = 0;i < n;i++) - { - v[n + i].copy(v[i]); - v[i].zero(); - } - } - -/* extract last bit */ - public int parity() - { - return v[0].parity(); - } - - public int lastbits(int m) - { - return v[0].lastbits(m); - } - -/* compare x and y - must be normalised, and of same length */ - public static int comp(FF a, FF b) - { - int i, j; - for (i = a.length - 1;i >= 0;i--) - { - j = BIG.comp(a.v[i],b.v[i]); - if (j != 0) - { - return j; - } - } - return 0; - } - -/* recursive add */ - public void radd(int vp, FF x, int xp, FF y, int yp, int n) - { - for (int i = 0;i < n;i++) - { - v[vp + i].copy(x.v[xp + i]); - v[vp + i].add(y.v[yp + i]); - } - } - -/* recursive inc */ - public void rinc(int vp, FF y, int yp, int n) - { - for (int i = 0;i < n;i++) - { - v[vp + i].add(y.v[yp + i]); - } - } - -/* recursive sub */ - public void rsub(int vp, FF x, int xp, FF y, int yp, int n) - { - for (int i = 0;i < n;i++) - { - v[vp + i].copy(x.v[xp + i]); - v[vp + i].sub(y.v[yp + i]); - } - } - -/* recursive dec */ - public void rdec(int vp, FF y, int yp, int n) - { - for (int i = 0;i < n;i++) - { - v[vp + i].sub(y.v[yp + i]); - } - } - -/* simple add */ - public void add(FF b) - { - for (int i = 0;i < length;i++) - { - v[i].add(b.v[i]); - } - } - -/* simple sub */ - public void sub(FF b) - { - for (int i = 0;i < length;i++) - { - v[i].sub(b.v[i]); - } - } - -/* reverse sub */ - public void revsub(FF b) - { - for (int i = 0;i < length;i++) - { - v[i].rsub(b.v[i]); - } - } - -/* increment/decrement by a small integer */ - public void inc(int m) - { - v[0].inc(m); - norm(); - } - - public void dec(int m) - { - v[0].dec(m); - norm(); - } - - /* normalise - but hold any overflow in top part unless n<0 */ - private void rnorm(int vp, int n) - { - bool trunc = false; - int i; - long carry; - if (n < 0) - { // -v n signals to do truncation - n = -n; - trunc = true; - } - for (i = 0;i < n - 1;i++) - { - carry = v[vp + i].norm(); - v[vp + i].xortop(carry << P_TBITS); - v[vp + i + 1].inc((int)carry); - } - carry = v[vp + n - 1].norm(); - if (trunc) - { - v[vp + n - 1].xortop(carry << P_TBITS); - } - - } - - public void norm() - { - rnorm(0,length); - } - -/* shift left by one bit */ - public void shl() - { - int i , delay_carry = 0; - long carry; - for (i = 0;i < length - 1;i++) - { - carry = v[i].fshl(1); - v[i].inc(delay_carry); - v[i].xortop(carry << P_TBITS); - delay_carry = (int)carry; - } - v[length - 1].fshl(1); - v[length - 1].inc(delay_carry); - } - -/* shift right by one bit */ - - public void shr() - { - int i; - long carry; - for (i = length - 1;i > 0;i--) - { - carry = v[i].fshr(1); - v[i - 1].ortop(carry << P_TBITS); - } - v[0].fshr(1); - } - -/* Convert to Hex String */ - public override string ToString() - { - norm(); - string s = ""; - for (int i = length - 1;i >= 0;i--) - { - s += v[i].ToString(); - } - return s; - } - -/* Convert FFs to/from byte arrays */ - public void toBytes(sbyte[] b) - { - for (int i = 0;i < length;i++) - { - v[i].tobytearray(b,(length - i - 1) * ROM.MODBYTES); - } - } - - public static void fromBytes(FF x, sbyte[] b) - { - for (int i = 0;i < x.length;i++) - { - x.v[i] = BIG.frombytearray(b,(x.length - i - 1) * ROM.MODBYTES); - } - } - -/* in-place swapping using xor - side channel resistant - lengths must be the same */ - private static void cswap(FF a, FF b, int d) - { - for (int i = 0;i < a.length;i++) - { - // BIG.cswap(a.v[i],b.v[i],d); - a.v[i].cswap(b.v[i],d); - } - } - -/* z=x*y, t is workspace */ - private void karmul(int vp, FF x, int xp, FF y, int yp, FF t, int tp, int n) - { - int nd2; - if (n == 1) - { - DBIG d = BIG.mul(x.v[xp],y.v[yp]); - v[vp + 1] = d.Split(8 * ROM.MODBYTES); - v[vp].copy(d); - return; - } - nd2 = n / 2; - radd(vp,x,xp,x,xp + nd2,nd2); - //rnorm(vp,nd2); - radd(vp + nd2,y,yp,y,yp + nd2,nd2); - //rnorm(vp+nd2,nd2); - t.karmul(tp,this,vp,this,vp + nd2,t,tp + n,nd2); - karmul(vp,x,xp,y,yp,t,tp + n,nd2); - karmul(vp + n,x,xp + nd2,y,yp + nd2,t,tp + n,nd2); - t.rdec(tp,this,vp,n); - t.rdec(tp,this,vp + n,n); - rinc(vp + nd2,t,tp,n); - rnorm(vp,2 * n); - } - - private void karsqr(int vp, FF x, int xp, FF t, int tp, int n) - { - int nd2; - if (n == 1) - { - DBIG d = BIG.sqr(x.v[xp]); - v[vp + 1].copy(d.Split(8 * ROM.MODBYTES)); - v[vp].copy(d); - return; - } - - nd2 = n / 2; - karsqr(vp,x,xp,t,tp + n,nd2); - karsqr(vp + n,x,xp + nd2,t,tp + n,nd2); - t.karmul(tp,x,xp,x,xp + nd2,t,tp + n,nd2); - rinc(vp + nd2,t,tp,n); - rinc(vp + nd2,t,tp,n); - rnorm(vp + nd2,n); - } - - - private void karmul_lower(int vp, FF x, int xp, FF y, int yp, FF t, int tp, int n) - { // Calculates Least Significant bottom half of x*y - int nd2; - if (n == 1) - { // only calculate bottom half of product - v[vp].copy(BIG.smul(x.v[xp],y.v[yp])); - return; - } - nd2 = n / 2; - - karmul(vp,x,xp,y,yp,t,tp + n,nd2); - t.karmul_lower(tp,x,xp + nd2,y,yp,t,tp + n,nd2); - rinc(vp + nd2,t,tp,nd2); - t.karmul_lower(tp,x,xp,y,yp + nd2,t,tp + n,nd2); - rinc(vp + nd2,t,tp,nd2); - rnorm(vp + nd2,-nd2); // truncate it - } - - private void karmul_upper(FF x, FF y, FF t, int n) - { // Calculates Most Significant upper half of x*y, given lower part - int nd2; - - nd2 = n / 2; - radd(n,x,0,x,nd2,nd2); - radd(n + nd2,y,0,y,nd2,nd2); - - t.karmul(0,this,n + nd2,this,n,t,n,nd2); // t = (a0+a1)(b0+b1) - karmul(n,x,nd2,y,nd2,t,n,nd2); // z[n]= a1*b1 - /* z[0-nd2]=l(a0b0) z[nd2-n]= h(a0b0)+l(t)-l(a0b0)-l(a1b1) */ - t.rdec(0,this,n,n); // t=t-a1b1 - rinc(nd2,this,0,nd2); // z[nd2-n]+=l(a0b0) = h(a0b0)+l(t)-l(a1b1) - rdec(nd2,t,0,nd2); // z[nd2-n]=h(a0b0)+l(t)-l(a1b1)-l(t-a1b1)=h(a0b0) - rnorm(0,-n); // a0b0 now in z - truncate it - t.rdec(0,this,0,n); // (a0+a1)(b0+b1) - a0b0 - rinc(nd2,t,0,n); - - rnorm(nd2,n); - } - - /* z=x*y. Assumes x and y are of same length. */ - public static FF mul(FF x, FF y) - { - int n = x.length; - FF z = new FF(2 * n); - FF t = new FF(2 * n); - z.karmul(0,x,0,y,0,t,0,n); - return z; - } - -/* return low part of product this*y */ - public void lmul(FF y) - { - int n = length; - FF t = new FF(2 * n); - FF x = new FF(n); - x.copy(this); - karmul_lower(0,x,0,y,0,t,0,n); - } - -/* Set b=b mod c */ - public void mod(FF c) - { - int k = 0; - - norm(); - if (comp(this,c) < 0) - { - return; - } - do - { - c.shl(); - k++; - } while (comp(this,c) >= 0); - - while (k > 0) - { - c.shr(); - if (comp(this,c) >= 0) - { - sub(c); - norm(); - } - k--; - } - } - - /* z=x^2 */ - public static FF sqr(FF x) - { - int n = x.length; - FF z = new FF(2 * n); - FF t = new FF(2 * n); - z.karsqr(0,x,0,t,0,n); - return z; - } - -/* return This mod modulus, N is modulus, ND is Montgomery Constant */ - public FF reduce(FF N, FF ND) - { // fast karatsuba Montgomery reduction - int n = N.length; - FF t = new FF(2 * n); - FF r = new FF(n); - FF m = new FF(n); - - r.sducopy(this); - m.karmul_lower(0,this,0,ND,0,t,0,n); - karmul_upper(N,m,t,n); - m.sducopy(this); - - r.add(N); - r.sub(m); - r.norm(); - - return r; - - } - -/* Set r=this mod b */ -/* this is of length - 2*n */ -/* r,b is of length - n */ - public FF dmod(FF b) - { - int k , n = b.length; - FF m = new FF(2 * n); - FF x = new FF(2 * n); - FF r = new FF(n); - - x.copy(this); - x.norm(); - m.dsucopy(b); - k = 256 * n; - - while (k > 0) - { - m.shr(); - - if (comp(x,m) >= 0) - { - x.sub(m); - x.norm(); - } - k--; - } - - r.copy(x); - r.mod(b); - return r; - } - -/* Set return=1/this mod p. Binary method - a<p on entry */ - - public void invmodp(FF p) - { - int n = p.length; - - FF u = new FF(n); - FF v = new FF(n); - FF x1 = new FF(n); - FF x2 = new FF(n); - FF t = new FF(n); - FF one = new FF(n); - - one.one(); - u.copy(this); - v.copy(p); - x1.copy(one); - x2.zero(); - - // reduce n in here as well! - while (comp(u,one) != 0 && comp(v,one) != 0) - { - while (u.parity() == 0) - { - u.shr(); - if (x1.parity() != 0) - { - x1.add(p); - x1.norm(); - } - x1.shr(); - } - while (v.parity() == 0) - { - v.shr(); - if (x2.parity() != 0) - { - x2.add(p); - x2.norm(); - } - x2.shr(); - } - if (comp(u,v) >= 0) - { - - u.sub(v); - u.norm(); - if (comp(x1,x2) >= 0) - { - x1.sub(x2); - } - else - { - t.copy(p); - t.sub(x2); - x1.add(t); - } - x1.norm(); - } - else - { - v.sub(u); - v.norm(); - if (comp(x2,x1) >= 0) - { - x2.sub(x1); - } - else - { - t.copy(p); - t.sub(x1); - x2.add(t); - } - x2.norm(); - } - } - if (comp(u,one) == 0) - { - copy(x1); - } - else - { - copy(x2); - } - } - -/* nresidue mod m */ - public void nres(FF m) - { - int n = m.length; - FF d = new FF(2 * n); - d.dsucopy(this); - copy(d.dmod(m)); - } - - public void redc(FF m, FF ND) - { - int n = m.length; - FF d = new FF(2 * n); - mod(m); - d.dscopy(this); - copy(d.reduce(m,ND)); - mod(m); - } - - private void mod2m(int m) - { - for (int i = m;i < length;i++) - { - v[i].zero(); - } - } - - /* U=1/a mod 2^m - Arazi & Qi */ - private FF invmod2m() - { - int i , n = length; - - FF b = new FF(n); - FF c = new FF(n); - FF U = new FF(n); - - FF t; - - U.zero(); - U.v[0].copy(v[0]); - U.v[0].invmod2m(); - - for (i = 1;i < n;i <<= 1) - { - b.copy(this); - b.mod2m(i); - t = mul(U,b); - t.shrw(i); - b.copy(t); - c.copy(this); - c.shrw(i); - c.mod2m(i); - c.lmul(U); - c.mod2m(i); - - b.add(c); - b.norm(); - b.lmul(U); - b.mod2m(i); - - c.one(); - c.shlw(i); - b.revsub(c); - b.norm(); - b.shlw(i); - U.add(b); - } - U.norm(); - return U; - } - - public void random(RAND rng) - { - int n = length; - for (int i = 0;i < n;i++) - { - v[i].copy(BIG.random(rng)); - } - /* make sure top bit is 1 */ - while (v[n - 1].nbits() < ROM.MODBYTES * 8) - { - v[n - 1].copy(BIG.random(rng)); - } - } - - /* generate random x */ - public void randomnum(FF p, RAND rng) - { - int n = length; - FF d = new FF(2 * n); - - for (int i = 0;i < 2 * n;i++) - { - d.v[i].copy(BIG.random(rng)); - } - copy(d.dmod(p)); - } - - /* this*=y mod p */ - public void modmul(FF y, FF p, FF nd) - { - //FF d=new FF(2*p.length); - long ex = P_EXCESS(); - long ey = y.P_EXCESS(); - if ((ex + 1) * (ey + 1) + 1 >= P_FEXCESS) - { - mod(p); - } - FF d = mul(this,y); - copy(d.reduce(p,nd)); - } - - /* this*=y mod p */ - public void modsqr(FF p, FF nd) - { - //FF d=new FF(2*p.length); - long ex = P_EXCESS(); - if ((ex + 1) * (ex + 1) + 1 >= P_FEXCESS) - { - mod(p); - } - FF d = sqr(this); - copy(d.reduce(p,nd)); - } - - /* this=this^e mod p using side-channel resistant Montgomery Ladder, for large e */ - public void skpow(FF e, FF p) - { - int i , b , n = p.length; - FF R0 = new FF(n); - FF R1 = new FF(n); - FF ND = p.invmod2m(); - - mod(p); - R0.one(); - R1.copy(this); - R0.nres(p); - R1.nres(p); - - for (i = 8 * ROM.MODBYTES * n - 1;i >= 0;i--) - { - b = e.v[i / 256].bit(i % 256); - copy(R0); - modmul(R1,p,ND); - - cswap(R0,R1,b); - R0.modsqr(p,ND); - - R1.copy(this); - cswap(R0,R1,b); - } - copy(R0); - redc(p,ND); - } - - /* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */ - public void skpow(BIG e, FF p) - { - int i , b , n = p.length; - FF R0 = new FF(n); - FF R1 = new FF(n); - FF ND = p.invmod2m(); - - mod(p); - R0.one(); - R1.copy(this); - R0.nres(p); - R1.nres(p); - - for (i = 8 * ROM.MODBYTES - 1;i >= 0;i--) - { - b = e.bit(i); - copy(R0); - modmul(R1,p,ND); - - cswap(R0,R1,b); - R0.modsqr(p,ND); - - R1.copy(this); - cswap(R0,R1,b); - } - copy(R0); - redc(p,ND); - } - - /* raise to an integer power - right-to-left method */ - public void power(int e, FF p) - { - int n = p.length; - FF w = new FF(n); - FF ND = p.invmod2m(); - bool f = true; - - w.copy(this); - w.nres(p); - - if (e == 2) - { - copy(w); - modsqr(p,ND); - } - else - { - for (; ;) - { - if (e % 2 == 1) - { - if (f) - { - copy(w); - } - else - { - modmul(w,p,ND); - } - f = false; - } - e >>= 1; - if (e == 0) - { - break; - } - w.modsqr(p,ND); - } - } - redc(p,ND); - } - - /* this=this^e mod p, faster but not side channel resistant */ - public void pow(FF e, FF p) - { - int i , b , n = p.length; - FF w = new FF(n); - FF ND = p.invmod2m(); - - w.copy(this); - one(); - nres(p); - w.nres(p); - for (i = 8 * ROM.MODBYTES * n - 1;i >= 0;i--) - { - modsqr(p,ND); - b = e.v[i / 256].bit(i % 256); - if (b == 1) - { - modmul(w,p,ND); - } - } - redc(p,ND); - } - - /* double exponentiation r=x^e.y^f mod p */ - public void pow2(BIG e, FF y, BIG f, FF p) - { - int i , eb , fb , n = p.length; - FF xn = new FF(n); - FF yn = new FF(n); - FF xy = new FF(n); - FF ND = p.invmod2m(); - - xn.copy(this); - yn.copy(y); - xn.nres(p); - yn.nres(p); - xy.copy(xn); - xy.modmul(yn,p,ND); - one(); - nres(p); - - for (i = 8 * ROM.MODBYTES - 1;i >= 0;i--) - { - eb = e.bit(i); - fb = f.bit(i); - modsqr(p,ND); - if (eb == 1) - { - if (fb == 1) - { - modmul(xy,p,ND); - } - else - { - modmul(xn,p,ND); - } - } - else - { - if (fb == 1) - { - modmul(yn,p,ND); - } - } - } - redc(p,ND); - } - - private static int igcd(int x, int y) - { // integer GCD, returns GCD of x and y - int r; - if (y == 0) - { - return x; - } - while ((r = x % y) != 0) - { - x = y; - y = r; - } - return y; - } - - /* quick and dirty check for common factor with n */ - public bool cfactor(int s) - { - int r , n = length; - int g; - - FF x = new FF(n); - FF y = new FF(n); - - y.set(s); - x.copy(this); - x.norm(); - - do - { - x.sub(y); - x.norm(); - while (!x.iszilch() && x.parity() == 0) - { - x.shr(); - } - } while (comp(x,y) > 0); - - g = (int)x.v[0].get(0); - r = igcd(s,g); - if (r > 1) - { - return true; - } - return false; - } - - /* Miller-Rabin test for primality. Slow. */ - public static bool prime(FF p, RAND rng) - { - int i , j , s = 0, n = p.length; - bool loop; - FF d = new FF(n); - FF x = new FF(n); - FF unity = new FF(n); - FF nm1 = new FF(n); - - int sf = 4849845; // 3*5*.. *19 - p.norm(); - - if (p.cfactor(sf)) - { - return false; - } - unity.one(); - nm1.copy(p); - nm1.sub(unity); - nm1.norm(); - d.copy(nm1); - - while (d.parity() == 0) - { - d.shr(); - s++; - } - if (s == 0) - { - return false; - } - for (i = 0;i < 10;i++) - { - x.randomnum(p,rng); - x.pow(d,p); - if (comp(x,unity) == 0 || comp(x,nm1) == 0) - { - continue; - } - loop = false; - for (j = 1;j < s;j++) - { - x.power(2,p); - if (comp(x,unity) == 0) - { - return false; - } - if (comp(x,nm1) == 0) - { - loop = true; - break; - } - } - if (loop) - { - continue; - } - return false; - } - return true; - } - -/* - public static final long[][] P ={{0xAD19A781670957L,0x76A79C00965796L,0xDEFCC5FC9A9717L,0xF02F2940E20E9L,0xBF59E34FL},{0x6894F31844C908L,0x8DADA70E82C79FL,0xFD29F3836046F6L,0x8C1D874D314DD0L,0x46D077BL},{0x3C515217813331L,0x56680FD1CE935BL,0xE55C53EEA8838EL,0x92C2F7E14A4A95L,0xD945E5B1L},{0xACF673E919F5EFL,0x6723E7E7DAB446L,0x6B6FA69B36EB1BL,0xF7D13920ECA300L,0xB5FC2165L}}; - - public static void main(String[] args) { - byte[] raw=new byte[100]; - RAND rng=new RAND(); - - rng.clean(); - for (int i=0;i<100;i++) raw[i]=(byte)i; - - rng.seed(100,raw); - - int n=4; - - FF x=new FF(n); - x.set(3); - - FF p=new FF(P,n); - - if (prime(p,rng)) System.out.println("p is a prime"); - - FF e=new FF(n); - e.copy(p); - e.dec(1); e.norm(); - - System.out.println("e= "+e.toString()); - - x.skpow(e,p); - System.out.println("x= "+x.toString()); - - } */ - -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/cs/FP.cs ---------------------------------------------------------------------- diff --git a/cs/FP.cs b/cs/FP.cs deleted file mode 100644 index 4e7b74e..0000000 --- a/cs/FP.cs +++ /dev/null @@ -1,368 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -/* Finite Field arithmetic */ -/* AMCL mod p functions */ - -public sealed class FP -{ - private readonly BIG x; - private static BIG p = new BIG(ROM.Modulus); - -/* Constructors */ - public FP(int a) - { - x = new BIG(a); - nres(); - } - - public FP(BIG a) - { - x = new BIG(a); - nres(); - } - - public FP(FP a) - { - x = new BIG(a.x); - } - -/* convert to string */ - public override string ToString() - { - string s = redc().ToString(); - return s; - } - - public string toRawString() - { - string s = x.toRawString(); - return s; - } - -/* convert to Montgomery n-residue form */ - public void nres() - { - if (ROM.MODTYPE != ROM.PSEUDO_MERSENNE) - { - DBIG d = new DBIG(x); - d.shl(ROM.NLEN * ROM.BASEBITS); - x.copy(d.mod(p)); - } - } - -/* convert back to regular form */ - public BIG redc() - { - if (ROM.MODTYPE != ROM.PSEUDO_MERSENNE) - { - DBIG d = new DBIG(x); - return BIG.mod(d); - } - else - { - BIG r = new BIG(x); - return r; - } - } - -/* test this=0? */ - public bool iszilch() - { - reduce(); - return x.iszilch(); - } - -/* copy from FP b */ - public void copy(FP b) - { - x.copy(b.x); - } - -/* set this=0 */ - public void zero() - { - x.zero(); - } - -/* set this=1 */ - public void one() - { - x.one(); - nres(); - } - -/* normalise this */ - public void norm() - { - x.norm(); - } - -/* swap FPs depending on d */ - public void cswap(FP b, int d) - { - x.cswap(b.x,d); - } - -/* copy FPs depending on d */ - public void cmove(FP b, int d) - { - x.cmove(b.x,d); - } - -/* this*=b mod Modulus */ - public void mul(FP b) - { - long ea = BIG.EXCESS(x); - long eb = BIG.EXCESS(b.x); - - if ((ea + 1) * (eb + 1) + 1 >= ROM.FEXCESS) - { - reduce(); - } - - DBIG d = BIG.mul(x,b.x); - x.copy(BIG.mod(d)); - } - -/* this*=c mod Modulus, where c is a small int */ - public void imul(int c) - { - norm(); - bool s = false; - if (c < 0) - { - c = -c; - s = true; - } - long afx = (BIG.EXCESS(x) + 1) * (c + 1) + 1; - if (c < ROM.NEXCESS && afx < ROM.FEXCESS) - { - x.imul(c); - } - else - { - if (afx < ROM.FEXCESS) - { - x.pmul(c); - } - else - { - DBIG d = x.pxmul(c); - x.copy(d.mod(p)); - } - } - if (s) - { - neg(); - } - norm(); - } - - -/* this*=this mod Modulus */ - public void sqr() - { - DBIG d; - long ea = BIG.EXCESS(x); - if ((ea + 1) * (ea + 1) + 1 >= ROM.FEXCESS) - { - reduce(); - } - - d = BIG.sqr(x); - x.copy(BIG.mod(d)); - } - -/* this+=b */ - public void add(FP b) - { - x.add(b.x); - if (BIG.EXCESS(x) + 2 >= ROM.FEXCESS) - { - reduce(); - } - } - -/* this = -this mod Modulus */ - public void neg() - { - int sb; - long ov; - BIG m = new BIG(p); - - norm(); - - ov = BIG.EXCESS(x); - sb = 1; - while (ov != 0) - { - sb++; - ov >>= 1; - } - - m.fshl(sb); - x.rsub(m); - - if (BIG.EXCESS(x) >= ROM.FEXCESS) - { - reduce(); - } - } - -/* this-=b */ - public void sub(FP b) - { - FP n = new FP(b); - n.neg(); - this.add(n); - } - -/* this/=2 mod Modulus */ - public void div2() - { - x.norm(); - if (x.parity() == 0) - { - x.fshr(1); - } - else - { - x.add(p); - x.norm(); - x.fshr(1); - } - } - -/* this=1/this mod Modulus */ - public void inverse() - { - BIG r = redc(); - r.invmodp(p); - x.copy(r); - nres(); - } - -/* return TRUE if this==a */ - public bool Equals(FP a) - { - a.reduce(); - reduce(); - if (BIG.comp(a.x,x) == 0) - { - return true; - } - return false; - } - -/* reduce this mod Modulus */ - public void reduce() - { - x.mod(p); - } - -/* return this^e mod Modulus */ - public FP pow(BIG e) - { - int bt; - FP r = new FP(1); - e.norm(); - x.norm(); - FP m = new FP(this); - while (true) - { - bt = e.parity(); - e.fshr(1); - if (bt == 1) - { - r.mul(m); - } - if (e.iszilch()) - { - break; - } - m.sqr(); - } - r.x.mod(p); - return r; - } - -/* return sqrt(this) mod Modulus */ - public FP sqrt() - { - reduce(); - BIG b = new BIG(p); - if (ROM.MOD8 == 5) - { - b.dec(5); - b.norm(); - b.shr(3); - FP i = new FP(this); - i.x.shl(1); - FP v = i.pow(b); - i.mul(v); - i.mul(v); - i.x.dec(1); - FP r = new FP(this); - r.mul(v); - r.mul(i); - r.reduce(); - return r; - } - else - { - b.inc(1); - b.norm(); - b.shr(2); - return pow(b); - } - } - -/* return jacobi symbol (this/Modulus) */ - public int jacobi() - { - BIG w = redc(); - return w.jacobi(p); - } -/* - public static void main(String[] args) { - BIG m=new BIG(ROM.Modulus); - BIG x=new BIG(3); - BIG e=new BIG(m); - e.dec(1); - - System.out.println("m= "+m.nbits()); - - - BIG r=x.powmod(e,m); - - System.out.println("m= "+m.toString()); - System.out.println("r= "+r.toString()); - - BIG.cswap(m,r,0); - - System.out.println("m= "+m.toString()); - System.out.println("r= "+r.toString()); - -// FP y=new FP(3); -// FP s=y.pow(e); -// System.out.println("s= "+s.toString()); - - } */ -}
