1 /* 2 * NIST curve reduction 3 * 4 * Copyright: 5 * (C) 2014 Jack LLoyd 6 * (C) 2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 12 module botan.math.ec_gfp.curve_nistp; 13 14 import botan.constants; 15 static if (BOTAN_HAS_PUBLIC_KEY_CRYPTO): 16 17 import botan.math.ec_gfp.curve_gfp; 18 import botan.math.bigint.bigint; 19 import botan.math.mp.mp_core; 20 import botan.codec.hex; 21 import botan.utils.types; 22 import botan.utils.mem_ops; 23 24 abstract class CurveGFpNIST : CurveGFpRepr 25 { 26 this()(size_t p_bits, auto const ref BigInt a, auto const ref BigInt b) 27 { 28 m_a = a.dup; 29 m_b = b.dup; 30 m_p_words = (p_bits + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS; 31 } 32 33 override ref const(BigInt) getA() const { return m_a; } 34 35 override ref const(BigInt) getB() const { return m_b; } 36 37 override ref const(BigInt) getARep() const { return m_a; } 38 39 override ref const(BigInt) getBRep() const { return m_b; } 40 41 override size_t getPWords() const { return m_p_words; } 42 43 override void toCurveRep(ref BigInt x, ref SecureVector!word ws) const 44 { 45 redc(x, ws); 46 } 47 48 override void fromCurveRep(ref BigInt x, ref SecureVector!word ws) const 49 { 50 redc(x, ws); 51 } 52 53 /** 54 * Montgomery multiplication/reduction 55 * Notes: z cannot alias x or y 56 * Params: 57 * z = output 58 * x = first multiplicand 59 * y = second multiplicand 60 */ 61 override void curveMul(ref BigInt z, const ref BigInt x, const ref BigInt y, ref SecureVector!word ws) const 62 { 63 if (x.isZero() || y.isZero()) 64 { 65 z = 0; 66 return; 67 } 68 69 const size_t p_words = getPWords(); 70 const size_t output_size = 2*p_words + 1; 71 ws.resize(2*(p_words+2)); 72 73 z.growTo(output_size); 74 z.clear(); 75 76 bigint_mul(z.mutablePtr(), output_size, ws.ptr, 77 x.ptr, x.length, x.sigWords(), 78 y.ptr, y.length, y.sigWords()); 79 80 this.redc(z, ws); 81 } 82 83 /** 84 * Montgomery squaring/reduction 85 * Notes: z cannot alias x 86 * Params: 87 * z = output 88 * x = multiplicand 89 */ 90 override void curveSqr(ref BigInt z, const ref BigInt x, ref SecureVector!word ws) const 91 { 92 if (x.isZero()) 93 { 94 z = 0; 95 return; 96 } 97 98 const size_t p_words = getPWords(); 99 const size_t output_size = 2*p_words + 1; 100 101 ws.resize(2*(p_words+2)); 102 103 z.growTo(output_size); 104 z.clear(); 105 106 bigint_sqr(z.mutablePtr(), output_size, ws.ptr, 107 x.ptr, x.length, x.sigWords()); 108 109 this.redc(z, ws); 110 } 111 112 override Vector!char toVector() const 113 { 114 Vector!char ret; 115 ret ~= "\nm_a: "; 116 ret ~= m_a.toString(); 117 ret ~= "\nm_b: "; 118 ret ~= m_b.toString(); 119 ret ~= "\nm_p_words: "; 120 ret ~= m_p_words.to!string; 121 ret ~= "\n"; 122 return ret.move(); 123 } 124 125 protected: 126 abstract void redc(ref BigInt x, ref SecureVector!word ws) const; 127 128 abstract size_t maxRedcSubstractions() const; 129 private: 130 // Curve parameters 131 BigInt m_a, m_b; 132 133 size_t m_p_words; // cache of m_p.sigWords() 134 } 135 136 /** 137 * The NIST P-521 curve 138 */ 139 class CurveGFpP521 : CurveGFpNIST 140 { 141 public: 142 this()(auto const ref BigInt a, auto const ref BigInt b) 143 { 144 if (prime is BigInt.init) 145 prime = BigInt("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); 146 147 super(521, a, b); 148 } 149 150 override ref const(BigInt) getP() const { return prime; } 151 152 override void redc(ref BigInt x, ref SecureVector!word ws) const 153 { 154 const size_t p_words = getPWords(); 155 156 const size_t shift_words = 521 / MP_WORD_BITS, 157 shift_bits = 521 % MP_WORD_BITS; 158 159 const size_t x_sw = x.sigWords(); 160 161 if (x_sw < p_words) 162 return; // already smaller 163 164 if (ws.length < p_words + 1) 165 ws.resize(p_words + 1); 166 167 clearMem(ws.ptr, ws.length); 168 bigint_shr2(ws.ptr, x.ptr, x_sw, shift_words, shift_bits); 169 170 x.maskBits(521); 171 172 bigint_add3(x.mutablePtr(), x.ptr, p_words, ws.ptr, p_words); 173 174 normalize(x, ws, maxRedcSubstractions()); 175 } 176 177 override size_t maxRedcSubstractions() const 178 { 179 return 1; 180 } 181 182 __gshared BigInt prime; 183 } 184