rsa.om (3415B)
1 func rsa_mul(y: *int, a: *int, b: *int, n: int) { 2 var c: int; 3 var i: int; 4 var j: int; 5 6 i = 0; 7 loop { 8 if i == 2 * n { 9 break; 10 } 11 12 y[i] = 0; 13 14 i = i + 1; 15 } 16 17 i = 0; 18 loop { 19 if i == n { 20 break; 21 } 22 23 j = 0; 24 c = 0; 25 loop { 26 if j == n { 27 break; 28 } 29 30 c = c + (a[i] & (-1 >> 32)) * (b[j] & (-1 >> 32)); 31 c = c + y[i + j]; 32 y[i + j] = c & (-1 >> 32); 33 34 c = c >> 32; 35 j = j + 1; 36 } 37 38 j = j + i; 39 40 loop { 41 if j == 2 * n { 42 break; 43 } 44 45 c = c + y[j]; 46 y[j] = c & (-1 >> 32); 47 48 j = j + 1; 49 c = c >> 32; 50 } 51 52 i = i + 1; 53 } 54 } 55 56 func rsa_trymod(r: *int, d: *int, q: int, n: int): int { 57 var i: int; 58 var a: int; 59 var s: int; 60 61 i = 0; 62 a = 0; 63 s = 1; 64 loop { 65 if i == n { 66 break; 67 } 68 69 a = a + (d[i] & (-1 >> 32)) * (q & (-1 >> 32)); 70 s = s + ((~a) & (-1 >> 32)); 71 s = s + (r[i] & (-1 >> 32)); 72 73 i = i + 1; 74 a = a >> 32; 75 s = s >> 32; 76 } 77 78 s = s + ((~a) & (-1 >> 32)); 79 s = s + (r[i] & (-1 >> 32)); 80 s = s >> 32; 81 82 return ~s & ((q + (-1 >> 32)) >> 32); 83 } 84 85 func rsa_domod(r: *int, d: *int, q: int, n: int) { 86 var i: int; 87 var a: int; 88 var s: int; 89 90 i = 0; 91 a = 0; 92 s = 1; 93 loop { 94 if i == n { 95 break; 96 } 97 98 a = a + (d[i] & (-1 >> 32)) * (q & (-1 >> 32)); 99 s = s + ((~a) & (-1 >> 32)); 100 s = s + (r[i] & (-1 >> 32)); 101 r[i] = s & (-1 >> 32); 102 103 i = i + 1; 104 a = a >> 32; 105 s = s >> 32; 106 } 107 108 s = s + ((~a) & (-1 >> 32)); 109 s = s + (r[i] & (-1 >> 32)); 110 r[i] = s & (-1 >> 32); 111 } 112 113 // Based on https://ridiculousfish.com/blog/posts/labor-of-division-episode-iv.html 114 func rsa_mod(r: *int, x: *int, d: *int, n: int) { 115 var i: int; 116 var j: int; 117 var nd: int; 118 var k: int; 119 var h: int; 120 var q: int; 121 var a: int; 122 123 // Find the size of d 124 nd = n; 125 loop { 126 if (d[nd - 1] & (- 1 >> 32)) != 0 || nd == 0 { 127 break; 128 } 129 130 nd = nd - 1; 131 } 132 133 // Divide by a single word 134 if (nd == 1) { 135 i = 2 * n - 1; 136 a = 0; 137 loop { 138 a = ((a << 32) + (x[i] & (- 1 >> 32))) % (d[nd - 1] & (- 1 >> 32)); 139 r[i] = 0; 140 141 if i == 0 { 142 break; 143 } 144 145 i = i - 1; 146 } 147 148 r[0] = a; 149 return; 150 } 151 152 // Find the fudge factor 153 h = d[nd - 1]; 154 k = 0; 155 loop { 156 if h & (1 << 31) != 0 { 157 break; 158 } 159 160 h = h << 1; 161 162 k = k + 1; 163 } 164 h = h | ((d[nd - 2] & (- 1 >> 32)) << k) >> 32; 165 166 // Copy x to r 167 i = 0; 168 loop { 169 if i == 2 * n { 170 break; 171 } 172 173 r[i] = x[i] & (- 1 >> 32); 174 175 i = i + 1; 176 } 177 r[i] = 0; 178 179 i = 2 * n; 180 j = 2 * n - nd; 181 loop { 182 a = (r[i] << (k + 32)) 183 | (r[i - 1] << k) 184 | ((r[i - 2] << k) >> 32); 185 186 // Compute guess 187 q = a / h; 188 189 // Bump it down 190 q = q - (q >> 32); 191 192 // Try twice since it is at most +2 from the lower guess 193 q = q - rsa_trymod(&r[j], d, q, n); 194 q = q - rsa_trymod(&r[j], d, q, n); 195 196 rsa_domod(&r[j], d, q, n); 197 198 if j == 0 { 199 break; 200 } 201 202 i = i - 1; 203 j = j - 1; 204 } 205 } 206 207 func rsa_sel(y: *int, x: *int, n: int, s: int) { 208 var i: int; 209 210 loop { 211 if i == n { 212 break; 213 } 214 215 y[i] = ((y[i] & ~s) | (x[i] & s)) & (-1 >> 32); 216 217 i = i + 1; 218 } 219 } 220 221 func rsa_pow(y: *int, x: *int, d: *int, m: *int, t: *int, n: int) { 222 var nd: int; 223 var i: int; 224 var e: int; 225 226 y[0] = 1; 227 228 i = 1; 229 loop { 230 if i == 2 * n { 231 break; 232 } 233 234 y[i] = 0; 235 236 i = i + 1; 237 } 238 239 nd = n - 1; 240 loop { 241 i = 0; 242 e = d[nd]; 243 loop { 244 if i == 32 { 245 break; 246 } 247 248 rsa_mul(t, y, y, n); 249 rsa_mod(y, t, m, n); 250 251 rsa_mul(t, y, x, n); 252 rsa_mod(t, t, m, n); 253 254 rsa_sel(y, t, n, -((e >> 31) & 1)); 255 256 i = i + 1; 257 e = e << 1; 258 } 259 260 if nd == 0 { 261 break; 262 } 263 264 nd = nd - 1; 265 } 266 }