1 /* 2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include "inner.h" 26 27 static const unsigned char * 28 api_generator(int curve, size_t *len) 29 { 30 switch (curve) { 31 case BR_EC_secp256r1: 32 #if BR_INT128 || BR_UMUL128 33 return br_ec_p256_m64.generator(curve, len); 34 #else 35 return br_ec_p256_m31.generator(curve, len); 36 #endif 37 case BR_EC_curve25519: 38 #if BR_INT128 || BR_UMUL128 39 return br_ec_c25519_m64.generator(curve, len); 40 #else 41 return br_ec_c25519_m31.generator(curve, len); 42 #endif 43 default: 44 return br_ec_prime_i31.generator(curve, len); 45 } 46 } 47 48 static const unsigned char * 49 api_order(int curve, size_t *len) 50 { 51 switch (curve) { 52 case BR_EC_secp256r1: 53 #if BR_INT128 || BR_UMUL128 54 return br_ec_p256_m64.order(curve, len); 55 #else 56 return br_ec_p256_m31.order(curve, len); 57 #endif 58 case BR_EC_curve25519: 59 #if BR_INT128 || BR_UMUL128 60 return br_ec_c25519_m64.order(curve, len); 61 #else 62 return br_ec_c25519_m31.order(curve, len); 63 #endif 64 default: 65 return br_ec_prime_i31.order(curve, len); 66 } 67 } 68 69 static size_t 70 api_xoff(int curve, size_t *len) 71 { 72 switch (curve) { 73 case BR_EC_secp256r1: 74 #if BR_INT128 || BR_UMUL128 75 return br_ec_p256_m64.xoff(curve, len); 76 #else 77 return br_ec_p256_m31.xoff(curve, len); 78 #endif 79 case BR_EC_curve25519: 80 #if BR_INT128 || BR_UMUL128 81 return br_ec_c25519_m64.xoff(curve, len); 82 #else 83 return br_ec_c25519_m31.xoff(curve, len); 84 #endif 85 default: 86 return br_ec_prime_i31.xoff(curve, len); 87 } 88 } 89 90 static uint32_t 91 api_mul(unsigned char *G, size_t Glen, 92 const unsigned char *kb, size_t kblen, int curve) 93 { 94 switch (curve) { 95 case BR_EC_secp256r1: 96 #if BR_INT128 || BR_UMUL128 97 return br_ec_p256_m64.mul(G, Glen, kb, kblen, curve); 98 #else 99 return br_ec_p256_m31.mul(G, Glen, kb, kblen, curve); 100 #endif 101 case BR_EC_curve25519: 102 #if BR_INT128 || BR_UMUL128 103 return br_ec_c25519_m64.mul(G, Glen, kb, kblen, curve); 104 #else 105 return br_ec_c25519_m31.mul(G, Glen, kb, kblen, curve); 106 #endif 107 default: 108 return br_ec_prime_i31.mul(G, Glen, kb, kblen, curve); 109 } 110 } 111 112 static size_t 113 api_mulgen(unsigned char *R, 114 const unsigned char *x, size_t xlen, int curve) 115 { 116 switch (curve) { 117 case BR_EC_secp256r1: 118 #if BR_INT128 || BR_UMUL128 119 return br_ec_p256_m64.mulgen(R, x, xlen, curve); 120 #else 121 return br_ec_p256_m31.mulgen(R, x, xlen, curve); 122 #endif 123 case BR_EC_curve25519: 124 #if BR_INT128 || BR_UMUL128 125 return br_ec_c25519_m64.mulgen(R, x, xlen, curve); 126 #else 127 return br_ec_c25519_m31.mulgen(R, x, xlen, curve); 128 #endif 129 default: 130 return br_ec_prime_i31.mulgen(R, x, xlen, curve); 131 } 132 } 133 134 static uint32_t 135 api_muladd(unsigned char *A, const unsigned char *B, size_t len, 136 const unsigned char *x, size_t xlen, 137 const unsigned char *y, size_t ylen, int curve) 138 { 139 switch (curve) { 140 case BR_EC_secp256r1: 141 #if BR_INT128 || BR_UMUL128 142 return br_ec_p256_m64.muladd(A, B, len, 143 x, xlen, y, ylen, curve); 144 #else 145 return br_ec_p256_m31.muladd(A, B, len, 146 x, xlen, y, ylen, curve); 147 #endif 148 case BR_EC_curve25519: 149 #if BR_INT128 || BR_UMUL128 150 return br_ec_c25519_m64.muladd(A, B, len, 151 x, xlen, y, ylen, curve); 152 #else 153 return br_ec_c25519_m31.muladd(A, B, len, 154 x, xlen, y, ylen, curve); 155 #endif 156 default: 157 return br_ec_prime_i31.muladd(A, B, len, 158 x, xlen, y, ylen, curve); 159 } 160 } 161 162 /* see bearssl_ec.h */ 163 const br_ec_impl br_ec_all_m31 = { 164 (uint32_t)0x23800000, 165 &api_generator, 166 &api_order, 167 &api_xoff, 168 &api_mul, 169 &api_mulgen, 170 &api_muladd 171 }; 172