os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

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 }