bcode.c (232994) | bcode.c (244861) |
---|---|
1/* $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $ */ 2 3/* 4 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/cdefs.h> | 1/* $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $ */ 2 3/* 4 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/cdefs.h> |
20__FBSDID("$FreeBSD: head/usr.bin/dc/bcode.c 232994 2012-03-15 01:43:44Z kevlo $"); | 20__FBSDID("$FreeBSD: head/usr.bin/dc/bcode.c 244861 2012-12-30 15:20:27Z kevlo $"); |
21 22#include <err.h> 23#include <limits.h> 24#include <openssl/ssl.h> 25#include <signal.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29 30#include "extern.h" 31 | 21 22#include <err.h> 23#include <limits.h> 24#include <openssl/ssl.h> 25#include <signal.h> 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29 30#include "extern.h" 31 |
32BIGNUM zero; 33 | |
34#define __inline 35 36#define MAX_ARRAY_INDEX 2048 37#define READSTACK_SIZE 8 38 39#define NO_ELSE -2 /* -1 is EOF */ 40#define REG_ARRAY_SIZE_SMALL (UCHAR_MAX + 1) 41#define REG_ARRAY_SIZE_BIG (UCHAR_MAX + 1 + USHRT_MAX + 1) --- 203 unchanged lines hidden (view full) --- 245 stack_init(&bmachine.reg[i]); 246 247 bmachine.readstack_sz = READSTACK_SIZE; 248 bmachine.readstack = calloc(sizeof(struct source), 249 bmachine.readstack_sz); 250 if (bmachine.readstack == NULL) 251 err(1, NULL); 252 bmachine.obase = bmachine.ibase = 10; | 32#define __inline 33 34#define MAX_ARRAY_INDEX 2048 35#define READSTACK_SIZE 8 36 37#define NO_ELSE -2 /* -1 is EOF */ 38#define REG_ARRAY_SIZE_SMALL (UCHAR_MAX + 1) 39#define REG_ARRAY_SIZE_BIG (UCHAR_MAX + 1 + USHRT_MAX + 1) --- 203 unchanged lines hidden (view full) --- 243 stack_init(&bmachine.reg[i]); 244 245 bmachine.readstack_sz = READSTACK_SIZE; 246 bmachine.readstack = calloc(sizeof(struct source), 247 bmachine.readstack_sz); 248 if (bmachine.readstack == NULL) 249 err(1, NULL); 250 bmachine.obase = bmachine.ibase = 10; |
253 BN_init(&zero); 254 bn_check(BN_zero(&zero)); | |
255} 256 | 251} 252 |
253u_int 254bmachine_scale(void) 255{ 256 return (bmachine.scale); 257} 258 |
|
257/* Reset the things needed before processing a (new) file */ 258void 259reset_bmachine(struct source *src) 260{ 261 262 bmachine.readsp = 0; 263 bmachine.readstack[0] = *src; 264} --- 137 unchanged lines hidden (view full) --- 402 bn_check(BN_exp(a, a, p, ctx)); 403 bn_check(BN_div(i, f, n->number, a, ctx)); 404 BN_CTX_free(ctx); 405 BN_free(a); 406 BN_free(p); 407 } 408} 409 | 259/* Reset the things needed before processing a (new) file */ 260void 261reset_bmachine(struct source *src) 262{ 263 264 bmachine.readsp = 0; 265 bmachine.readstack[0] = *src; 266} --- 137 unchanged lines hidden (view full) --- 404 bn_check(BN_exp(a, a, p, ctx)); 405 bn_check(BN_div(i, f, n->number, a, ctx)); 406 BN_CTX_free(ctx); 407 BN_free(a); 408 BN_free(p); 409 } 410} 411 |
410__inline void | 412void |
411normalize(struct number *n, u_int s) 412{ 413 414 scale_number(n->number, s - n->scale); 415 n->scale = s; 416} 417 418static u_long 419get_ulong(struct number *n) 420{ 421 422 normalize(n, 0); 423 return (BN_get_word(n->number)); 424} 425 426void 427negate(struct number *n) 428{ 429 | 413normalize(struct number *n, u_int s) 414{ 415 416 scale_number(n->number, s - n->scale); 417 n->scale = s; 418} 419 420static u_long 421get_ulong(struct number *n) 422{ 423 424 normalize(n, 0); 425 return (BN_get_word(n->number)); 426} 427 428void 429negate(struct number *n) 430{ 431 |
430 bn_check(BN_sub(n->number, &zero, n->number)); | 432 BN_set_negative(n->number, !BN_is_negative(n->number)); |
431} 432 433static __inline void 434push_number(struct number *n) 435{ 436 437 stack_pushnumber(&bmachine.stack, n); 438} --- 137 unchanged lines hidden (view full) --- 576static void 577set_scale(void) 578{ 579 struct number *n; 580 u_long scale; 581 582 n = pop_number(); 583 if (n != NULL) { | 433} 434 435static __inline void 436push_number(struct number *n) 437{ 438 439 stack_pushnumber(&bmachine.stack, n); 440} --- 137 unchanged lines hidden (view full) --- 578static void 579set_scale(void) 580{ 581 struct number *n; 582 u_long scale; 583 584 n = pop_number(); 585 if (n != NULL) { |
584 if (BN_cmp(n->number, &zero) < 0) | 586 if (BN_is_negative(n->number)) |
585 warnx("scale must be a nonnegative number"); 586 else { 587 scale = get_ulong(n); 588 if (scale != BN_MASK2 && scale <= UINT_MAX) 589 bmachine.scale = (u_int)scale; 590 else 591 warnx("scale too large"); 592 } --- 280 unchanged lines hidden (view full) --- 873 int reg; 874 875 reg = readreg(); 876 if (reg >= 0) { 877 inumber = pop_number(); 878 if (inumber == NULL) 879 return; 880 idx = get_ulong(inumber); | 587 warnx("scale must be a nonnegative number"); 588 else { 589 scale = get_ulong(n); 590 if (scale != BN_MASK2 && scale <= UINT_MAX) 591 bmachine.scale = (u_int)scale; 592 else 593 warnx("scale too large"); 594 } --- 280 unchanged lines hidden (view full) --- 875 int reg; 876 877 reg = readreg(); 878 if (reg >= 0) { 879 inumber = pop_number(); 880 if (inumber == NULL) 881 return; 882 idx = get_ulong(inumber); |
881 if (BN_cmp(inumber->number, &zero) < 0) | 883 if (BN_is_negative(inumber->number)) |
882 warnx("negative idx"); 883 else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) 884 warnx("idx too big"); 885 else { 886 stack = &bmachine.reg[reg]; 887 v = frame_retrieve(stack, idx); 888 if (v == NULL || v->type == BCODE_NONE) { 889 n = new_number(); --- 22 unchanged lines hidden (view full) --- 912 if (inumber == NULL) 913 return; 914 value = pop(); 915 if (value == NULL) { 916 free_number(inumber); 917 return; 918 } 919 idx = get_ulong(inumber); | 884 warnx("negative idx"); 885 else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) 886 warnx("idx too big"); 887 else { 888 stack = &bmachine.reg[reg]; 889 v = frame_retrieve(stack, idx); 890 if (v == NULL || v->type == BCODE_NONE) { 891 n = new_number(); --- 22 unchanged lines hidden (view full) --- 914 if (inumber == NULL) 915 return; 916 value = pop(); 917 if (value == NULL) { 918 free_number(inumber); 919 return; 920 } 921 idx = get_ulong(inumber); |
920 if (BN_cmp(inumber->number, &zero) < 0) { | 922 if (BN_is_negative(inumber->number)) { |
921 warnx("negative idx"); 922 stack_free_value(value); 923 } else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) { 924 warnx("idx too big"); 925 stack_free_value(value); 926 } else { 927 stack = &bmachine.reg[reg]; 928 frame_assign(stack, idx, value); --- 75 unchanged lines hidden (view full) --- 1004 normalize(b, r->scale); 1005 bn_check(BN_sub(r->number, b->number, a->number)); 1006 push_number(r); 1007 free_number(a); 1008 free_number(b); 1009} 1010 1011void | 923 warnx("negative idx"); 924 stack_free_value(value); 925 } else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) { 926 warnx("idx too big"); 927 stack_free_value(value); 928 } else { 929 stack = &bmachine.reg[reg]; 930 frame_assign(stack, idx, value); --- 75 unchanged lines hidden (view full) --- 1006 normalize(b, r->scale); 1007 bn_check(BN_sub(r->number, b->number, a->number)); 1008 push_number(r); 1009 free_number(a); 1010 free_number(b); 1011} 1012 1013void |
1012bmul_number(struct number *r, struct number *a, struct number *b) | 1014bmul_number(struct number *r, struct number *a, struct number *b, u_int scale) |
1013{ 1014 BN_CTX *ctx; 1015 1016 /* Create copies of the scales, since r might be equal to a or b */ 1017 u_int ascale = a->scale; 1018 u_int bscale = b->scale; 1019 u_int rscale = ascale + bscale; 1020 1021 ctx = BN_CTX_new(); 1022 bn_checkp(ctx); 1023 bn_check(BN_mul(r->number, a->number, b->number, ctx)); 1024 BN_CTX_free(ctx); 1025 | 1015{ 1016 BN_CTX *ctx; 1017 1018 /* Create copies of the scales, since r might be equal to a or b */ 1019 u_int ascale = a->scale; 1020 u_int bscale = b->scale; 1021 u_int rscale = ascale + bscale; 1022 1023 ctx = BN_CTX_new(); 1024 bn_checkp(ctx); 1025 bn_check(BN_mul(r->number, a->number, b->number, ctx)); 1026 BN_CTX_free(ctx); 1027 |
1026 if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) { 1027 r->scale = rscale; 1028 normalize(r, max(bmachine.scale, max(ascale, bscale))); 1029 } else 1030 r->scale = rscale; | 1028 r->scale = rscale; 1029 if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) 1030 normalize(r, max(scale, max(ascale, bscale))); |
1031} 1032 1033static void 1034bmul(void) 1035{ 1036 struct number *a, *b, *r; 1037 1038 a = pop_number(); 1039 if (a == NULL) { 1040 return; 1041 } 1042 b = pop_number(); 1043 if (b == NULL) { 1044 push_number(a); 1045 return; 1046 } 1047 1048 r = new_number(); | 1031} 1032 1033static void 1034bmul(void) 1035{ 1036 struct number *a, *b, *r; 1037 1038 a = pop_number(); 1039 if (a == NULL) { 1040 return; 1041 } 1042 b = pop_number(); 1043 if (b == NULL) { 1044 push_number(a); 1045 return; 1046 } 1047 1048 r = new_number(); |
1049 bmul_number(r, a, b); | 1049 bmul_number(r, a, b, bmachine.scale); |
1050 1051 push_number(r); 1052 free_number(a); 1053 free_number(b); 1054} 1055 1056static void 1057bdiv(void) --- 109 unchanged lines hidden (view full) --- 1167 free_number(a); 1168 free_number(b); 1169} 1170 1171static void 1172bexp(void) 1173{ 1174 struct number *a, *p, *r; | 1050 1051 push_number(r); 1052 free_number(a); 1053 free_number(b); 1054} 1055 1056static void 1057bdiv(void) --- 109 unchanged lines hidden (view full) --- 1167 free_number(a); 1168 free_number(b); 1169} 1170 1171static void 1172bexp(void) 1173{ 1174 struct number *a, *p, *r; |
1175 u_int scale; | 1175 u_int rscale; |
1176 bool neg; 1177 1178 p = pop_number(); 1179 if (p == NULL) { 1180 return; 1181 } 1182 a = pop_number(); 1183 if (a == NULL) { 1184 push_number(p); 1185 return; 1186 } 1187 | 1176 bool neg; 1177 1178 p = pop_number(); 1179 if (p == NULL) { 1180 return; 1181 } 1182 a = pop_number(); 1183 if (a == NULL) { 1184 push_number(p); 1185 return; 1186 } 1187 |
1188 if (p->scale != 0) 1189 warnx("Runtime warning: non-zero scale in exponent"); | 1188 if (p->scale != 0) { 1189 BIGNUM *i, *f; 1190 i = BN_new(); 1191 bn_checkp(i); 1192 f = BN_new(); 1193 bn_checkp(f); 1194 split_number(p, i, f); 1195 if (!BN_is_zero(f)) 1196 warnx("Runtime warning: non-zero fractional part " 1197 "in exponent"); 1198 BN_free(i); 1199 BN_free(f); 1200 } 1201 |
1190 normalize(p, 0); 1191 1192 neg = false; | 1202 normalize(p, 0); 1203 1204 neg = false; |
1193 if (BN_cmp(p->number, &zero) < 0) { | 1205 if (BN_is_negative(p->number)) { |
1194 neg = true; 1195 negate(p); | 1206 neg = true; 1207 negate(p); |
1196 scale = bmachine.scale; | 1208 rscale = bmachine.scale; |
1197 } else { 1198 /* Posix bc says min(a.scale * b, max(a.scale, scale) */ 1199 u_long b; 1200 u_int m; 1201 1202 b = BN_get_word(p->number); 1203 m = max(a->scale, bmachine.scale); | 1209 } else { 1210 /* Posix bc says min(a.scale * b, max(a.scale, scale) */ 1211 u_long b; 1212 u_int m; 1213 1214 b = BN_get_word(p->number); 1215 m = max(a->scale, bmachine.scale); |
1204 scale = a->scale * (u_int)b; 1205 if (scale > m || (a->scale > 0 && (b == BN_MASK2 || | 1216 rscale = a->scale * (u_int)b; 1217 if (rscale > m || (a->scale > 0 && (b == BN_MASK2 || |
1206 b > UINT_MAX))) | 1218 b > UINT_MAX))) |
1207 scale = m; | 1219 rscale = m; |
1208 } 1209 1210 if (BN_is_zero(p->number)) { 1211 r = new_number(); 1212 bn_check(BN_one(r->number)); | 1220 } 1221 1222 if (BN_is_zero(p->number)) { 1223 r = new_number(); 1224 bn_check(BN_one(r->number)); |
1213 normalize(r, scale); | 1225 normalize(r, rscale); |
1214 } else { | 1226 } else { |
1227 u_int ascale, mscale; 1228 1229 ascale = a->scale; |
|
1215 while (!BN_is_bit_set(p->number, 0)) { | 1230 while (!BN_is_bit_set(p->number, 0)) { |
1216 bmul_number(a, a, a); | 1231 ascale *= 2; 1232 bmul_number(a, a, a, ascale); |
1217 bn_check(BN_rshift1(p->number, p->number)); 1218 } 1219 1220 r = dup_number(a); | 1233 bn_check(BN_rshift1(p->number, p->number)); 1234 } 1235 1236 r = dup_number(a); |
1221 normalize(r, scale); | |
1222 bn_check(BN_rshift1(p->number, p->number)); 1223 | 1237 bn_check(BN_rshift1(p->number, p->number)); 1238 |
1239 mscale = ascale; |
|
1224 while (!BN_is_zero(p->number)) { | 1240 while (!BN_is_zero(p->number)) { |
1225 bmul_number(a, a, a); 1226 if (BN_is_bit_set(p->number, 0)) 1227 bmul_number(r, r, a); | 1241 ascale *= 2; 1242 bmul_number(a, a, a, ascale); 1243 if (BN_is_bit_set(p->number, 0)) { 1244 mscale += ascale; 1245 bmul_number(r, r, a, mscale); 1246 } |
1228 bn_check(BN_rshift1(p->number, p->number)); 1229 } 1230 1231 if (neg) { 1232 BN_CTX *ctx; 1233 BIGNUM *one; 1234 1235 one = BN_new(); 1236 bn_checkp(one); 1237 bn_check(BN_one(one)); 1238 ctx = BN_CTX_new(); 1239 bn_checkp(ctx); | 1247 bn_check(BN_rshift1(p->number, p->number)); 1248 } 1249 1250 if (neg) { 1251 BN_CTX *ctx; 1252 BIGNUM *one; 1253 1254 one = BN_new(); 1255 bn_checkp(one); 1256 bn_check(BN_one(one)); 1257 ctx = BN_CTX_new(); 1258 bn_checkp(ctx); |
1240 scale_number(one, r->scale + scale); 1241 normalize(r, scale); 1242 bn_check(BN_div(r->number, NULL, one, r->number, ctx)); | 1259 scale_number(one, r->scale + rscale); 1260 1261 if (BN_is_zero(r->number)) 1262 warnx("divide by zero"); 1263 else 1264 bn_check(BN_div(r->number, NULL, one, 1265 r->number, ctx)); |
1243 BN_free(one); 1244 BN_CTX_free(ctx); | 1266 BN_free(one); 1267 BN_CTX_free(ctx); |
1268 r->scale = rscale; |
|
1245 } else | 1269 } else |
1246 normalize(r, scale); | 1270 normalize(r, rscale); |
1247 } 1248 push_number(r); 1249 free_number(a); 1250 free_number(p); 1251} 1252 1253static bool 1254bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount) --- 22 unchanged lines hidden (view full) --- 1277 onecount = 0; 1278 n = pop_number(); 1279 if (n == NULL) { 1280 return; 1281 } 1282 if (BN_is_zero(n->number)) { 1283 r = new_number(); 1284 push_number(r); | 1271 } 1272 push_number(r); 1273 free_number(a); 1274 free_number(p); 1275} 1276 1277static bool 1278bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount) --- 22 unchanged lines hidden (view full) --- 1301 onecount = 0; 1302 n = pop_number(); 1303 if (n == NULL) { 1304 return; 1305 } 1306 if (BN_is_zero(n->number)) { 1307 r = new_number(); 1308 push_number(r); |
1285 } else if (BN_cmp(n->number, &zero) < 0) | 1309 } else if (BN_is_negative(n->number)) |
1286 warnx("square root of negative number"); 1287 else { 1288 scale = max(bmachine.scale, n->scale); 1289 normalize(n, 2*scale); 1290 x = BN_dup(n->number); 1291 bn_checkp(x); 1292 bn_check(BN_rshift(x, x, BN_num_bits(x)/2)); 1293 y = BN_new(); --- 460 unchanged lines hidden --- | 1310 warnx("square root of negative number"); 1311 else { 1312 scale = max(bmachine.scale, n->scale); 1313 normalize(n, 2*scale); 1314 x = BN_dup(n->number); 1315 bn_checkp(x); 1316 bn_check(BN_rshift(x, x, BN_num_bits(x)/2)); 1317 y = BN_new(); --- 460 unchanged lines hidden --- |