shithub: drawterm

Download patch

ref: 07eda1b895f1fd4f4cea3f56deb76e16b0e02c3d
parent: ce450582513dcea0d8f7b721ab693b954332f5ba
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Dec 31 06:17:18 EST 2017

libc, libmp: new constant time encode(2) routines (from 9front)

--- a/include/lib.h
+++ b/include/lib.h
@@ -248,7 +248,6 @@
 extern	char*	fmtstrflush(Fmt*);
 extern	int	runefmtstrinit(Fmt*);
 extern	Rune*	runefmtstrflush(Fmt*);
-extern	int	encodefmt(Fmt*);
 extern	int	fmtstrcpy(Fmt*, char*);
 extern	int	fmtprint(Fmt*, char*, ...);
 extern	int	fmtvprint(Fmt*, char*, va_list);
@@ -268,7 +267,15 @@
 extern	int	enc64(char*, int, uchar*, int);
 extern	int	dec32(uchar*, int, char*, int);
 extern	int	enc32(char*, int, uchar*, int);
+extern	int	dec16(uchar*, int, char*, int);
 extern	int	enc16(char*, int, uchar*, int);
+extern	int	dec64chr(int);
+extern	int	enc64chr(int);
+extern	int	dec32chr(int);
+extern	int	enc32chr(int);
+extern	int	dec16chr(int);
+extern	int	enc16chr(int);
+extern	int	encodefmt(Fmt*);
 void		hnputs(void *p, unsigned short v);
 extern	int	dofmt(Fmt*, char*);
 extern	double	__NaN(void);
--- a/libc/u16.c
+++ b/libc/u16.c
@@ -1,8 +1,30 @@
 #include <u.h>
 #include <libc.h>
-static char t16e[] = "0123456789ABCDEF";
 
+#define between(x,min,max)	(((min-1-x) & (x-max-1))>>8)
+
 int
+enc16chr(int o)
+{
+	int c;
+
+	c  = between(o,  0,  9) & ('0'+o);
+	c |= between(o, 10, 15) & ('A'+(o-10));
+	return c;
+}
+
+int
+dec16chr(int c)
+{
+	int o;
+
+	o  = between(c, '0', '9') & (1+(c-'0'));
+	o |= between(c, 'A', 'F') & (1+10+(c-'A'));
+	o |= between(c, 'a', 'f') & (1+10+(c-'a'));
+	return o-1;
+}
+
+int
 dec16(uchar *out, int lim, char *in, int n)
 {
 	int c, w = 0, i = 0;
@@ -10,14 +32,8 @@
 	uchar *eout = out + lim;
 
 	while(n-- > 0){
-		c = *in++;
-		if('0' <= c && c <= '9')
-			c = c - '0';
-		else if('a' <= c && c <= 'z')
-			c = c - 'a' + 10;
-		else if('A' <= c && c <= 'Z')
-			c = c - 'A' + 10;
-		else
+		c = dec16chr(*in++);
+		if(c < 0)
 			continue;
 		w = (w<<4) + c;
 		i++;
@@ -44,8 +60,8 @@
 		c = *in++;
 		if(out + 2 >= eout)
 			goto exhausted;
-		*out++ = t16e[c>>4];
-		*out++ = t16e[c&0xf];
+		*out++ = enc16chr(c>>4);
+		*out++ = enc16chr(c&15);
 	}
 exhausted:
 	*out = 0;
--- a/libc/u32.c
+++ b/libc/u32.c
@@ -1,21 +1,44 @@
 #include <u.h>
 #include <libc.h>
 
+#define between(x,min,max)	(((min-1-x) & (x-max-1))>>8)
+
 int
+enc32chr(int o)
+{
+	int c;
+
+	c  = between(o,  0, 25) & ('A'+o);
+	c |= between(o, 26, 31) & ('2'+(o-26));
+	return c;
+}
+
+int
+dec32chr(int c)
+{
+	int o;
+
+	o  = between(c, 'A', 'Z') & (1+(c-'A'));
+	o |= between(c, 'a', 'z') & (1+(c-'a'));
+	o |= between(c, '2', '7') & (1+26+(c-'2'));
+	return o-1;
+}
+
+int
 dec32(uchar *dest, int ndest, char *src, int nsrc)
 {
-	char *s, *tab;
 	uchar *start;
-	int i, u[8];
+	int i, j, u[8];
 
 	if(ndest+1 < (5*nsrc+7)/8)
 		return -1;
 	start = dest;
-	tab = "23456789abcdefghijkmnpqrstuvwxyz";
 	while(nsrc>=8){
 		for(i=0; i<8; i++){
-			s = strchr(tab,(int)src[i]);
-			u[i] = s ? s-tab : 0;
+			j = dec32chr(src[i]);
+			if(j < 0)
+				j = 0;
+			u[i] = j;
 		}
 		*dest++ = (u[0]<<3) | (0x7 & (u[1]>>2));
 		*dest++ = ((0x3 & u[1])<<6) | (u[2]<<1) | (0x1 & (u[3]>>4));
@@ -29,8 +52,10 @@
 		if(nsrc == 1 || nsrc == 3 || nsrc == 6)
 			return -1;
 		for(i=0; i<nsrc; i++){
-			s = strchr(tab,(int)src[i]);
-			u[i] = s ? s-tab : 0;
+			j = dec32chr(src[i]);
+			if(j < 0)
+				j = 0;
+			u[i] = j;
 		}
 		*dest++ = (u[0]<<3) | (0x7 & (u[1]>>2));
 		if(nsrc == 2)
@@ -50,60 +75,57 @@
 int
 enc32(char *dest, int ndest, uchar *src, int nsrc)
 {
-	char *tab, *start;
+	char *start;
 	int j;
 
-	if(ndest <= (8*nsrc+4)/5 )
+	if(ndest <= (8*nsrc+4)/5)
 		return -1;
 	start = dest;
-	tab = "23456789abcdefghijkmnpqrstuvwxyz";
 	while(nsrc>=5){
 		j = (0x1f & (src[0]>>3));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1c & (src[0]<<2)) | (0x03 & (src[1]>>6));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1f & (src[1]>>1));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x10 & (src[1]<<4)) | (0x0f & (src[2]>>4));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1e & (src[2]<<1)) | (0x01 & (src[3]>>7));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1f & (src[3]>>2));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x18 & (src[3]<<3)) | (0x07 & (src[4]>>5));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1f & (src[4]));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		src  += 5;
 		nsrc -= 5;
 	}
 	if(nsrc){
 		j = (0x1f & (src[0]>>3));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1c & (src[0]<<2));
 		if(nsrc == 1)
 			goto out;
 		j |= (0x03 & (src[1]>>6));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1f & (src[1]>>1));
+		*dest++ = enc32chr(j);
+		j = (0x10 & (src[1]<<4));
 		if(nsrc == 2)
 			goto out;
-		*dest++ = tab[j];
-		j = (0x10 & (src[1]<<4));
-		if(nsrc == 3)
-			goto out;
 		j |= (0x0f & (src[2]>>4));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1e & (src[2]<<1));
-		if(nsrc == 4)
+		if(nsrc == 3)
 			goto out;
 		j |= (0x01 & (src[3]>>7));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x1f & (src[3]>>2));
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 		j = (0x18 & (src[3]<<3));
 out:
-		*dest++ = tab[j];
+		*dest++ = enc32chr(j);
 	}
 	*dest = 0;
 	return dest-start;
--- a/libc/u64.c
+++ b/libc/u64.c
@@ -1,31 +1,35 @@
 #include <u.h>
 #include <libc.h>
 
-enum {
-	INVAL=	255
-};
+#define between(x,min,max)	(((min-1-x) & (x-max-1))>>8)
 
-static uchar t64d[256] = {
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,   62,INVAL,INVAL,INVAL,   63,
-      52,   53,   54,   55,   56,   57,   58,   59,   60,   61,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
-      15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
-      41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
-   INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL
-};
-static char t64e[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+int
+enc64chr(int o)
+{
+	int c;
 
+	c  = between(o,  0, 25) & ('A'+o);
+	c |= between(o, 26, 51) & ('a'+(o-26));
+	c |= between(o, 52, 61) & ('0'+(o-52));
+	c |= between(o, 62, 62) & ('+');
+	c |= between(o, 63, 63) & ('/');
+	return c;
+}
+
 int
+dec64chr(int c)
+{
+	int o;
+
+	o  = between(c, 'A', 'Z') & (1+(c-'A'));
+	o |= between(c, 'a', 'z') & (1+26+(c-'a'));
+	o |= between(c, '0', '9') & (1+52+(c-'0'));
+	o |= between(c, '+', '+') & (1+62);
+	o |= between(c, '/', '/') & (1+63);
+	return o-1;
+}
+
+int
 dec64(uchar *out, int lim, char *in, int n)
 {
 	ulong b24;
@@ -36,9 +40,8 @@
 	b24 = 0;
 	i = 0;
 	while(n-- > 0){
- 
-		c = t64d[*(uchar*)in++];
-		if(c == INVAL)
+		c = dec64chr(*in++);
+		if(c < 0)
 			continue;
 		switch(i){
 		case 0:
@@ -58,8 +61,8 @@
 			*out++ = b24>>16;
 			*out++ = b24>>8;
 			*out++ = b24;
-			i = -1;
-			break;
+			i = 0;
+			continue;
 		}
 		i++;
 	}
@@ -89,34 +92,34 @@
 	char *e = out + lim;
 
 	for(i = n/3; i > 0; i--){
-		b24 = (*in++)<<16;
-		b24 |= (*in++)<<8;
+		b24 = *in++<<16;
+		b24 |= *in++<<8;
 		b24 |= *in++;
 		if(out + 4 >= e)
 			goto exhausted;
-		*out++ = t64e[(b24>>18)];
-		*out++ = t64e[(b24>>12)&0x3f];
-		*out++ = t64e[(b24>>6)&0x3f];
-		*out++ = t64e[(b24)&0x3f];
+		*out++ = enc64chr(b24>>18);
+		*out++ = enc64chr((b24>>12)&0x3f);
+		*out++ = enc64chr((b24>>6)&0x3f);
+		*out++ = enc64chr(b24&0x3f);
 	}
 
 	switch(n%3){
 	case 2:
-		b24 = (*in++)<<16;
-		b24 |= (*in)<<8;
+		b24 = *in++<<16;
+		b24 |= *in<<8;
 		if(out + 4 >= e)
 			goto exhausted;
-		*out++ = t64e[(b24>>18)];
-		*out++ = t64e[(b24>>12)&0x3f];
-		*out++ = t64e[(b24>>6)&0x3f];
+		*out++ = enc64chr(b24>>18);
+		*out++ = enc64chr((b24>>12)&0x3f);
+		*out++ = enc64chr((b24>>6)&0x3f);
 		*out++ = '=';
 		break;
 	case 1:
-		b24 = (*in)<<16;
+		b24 = *in<<16;
 		if(out + 4 >= e)
 			goto exhausted;
-		*out++ = t64e[(b24>>18)];
-		*out++ = t64e[(b24>>12)&0x3f];
+		*out++ = enc64chr(b24>>18);
+		*out++ = enc64chr((b24>>12)&0x3f);
 		*out++ = '=';
 		*out++ = '=';
 		break;
--- a/libmp/mpfmt.c
+++ b/libmp/mpfmt.c
@@ -17,8 +17,6 @@
 	return rv;
 }
 
-static char set16[] = "0123456789ABCDEF";
-
 static int
 topow2(mpint *b, char *buf, int len, int s)
 {
@@ -39,7 +37,7 @@
 			if(j != 0 || out != buf){
 				if(out >= eout)
 					return -1;
-				*out++ = set16[j];
+				*out++ = enc16chr(j);
 			}
 		}
 	}
--- a/libmp/strtomp.c
+++ b/libmp/strtomp.c
@@ -2,58 +2,16 @@
 #include <mp.h>
 #include "dat.h"
 
-static struct {
-	int	inited;
-
-	uchar	t64[256];
-	uchar	t32[256];
-	uchar	t16[256];
-	uchar	t10[256];
-} tab;
-
-enum {
-	INVAL=	255
-};
-
-static char set64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static char set32[] = "23456789abcdefghijkmnpqrstuvwxyz";
-static char set16[] = "0123456789ABCDEF0123456789abcdef";
-static char set10[] = "0123456789";
-
-static void
-init(void)
-{
-	char *p;
-
-	memset(tab.t64, INVAL, sizeof(tab.t64));
-	memset(tab.t32, INVAL, sizeof(tab.t32));
-	memset(tab.t16, INVAL, sizeof(tab.t16));
-	memset(tab.t10, INVAL, sizeof(tab.t10));
-
-	for(p = set64; *p; p++)
-		tab.t64[*p] = p-set64;
-	for(p = set32; *p; p++)
-		tab.t32[*p] = p-set32;
-	for(p = set16; *p; p++)
-		tab.t16[*p] = (p-set16)%16;
-	for(p = set10; *p; p++)
-		tab.t10[*p] = (p-set10);
-
-	tab.inited = 1;
-}
-
 static char*
 frompow2(char *a, mpint *b, int s)
 {
 	char *p, *next;
-	int i;
 	mpdigit x;
-	int sn;
+	int i;
 
-	sn = 1<<s;
-	for(p = a; *p; p++)
-		if(tab.t16[*(uchar*)p] >= sn)
-			break;
+	i = 1<<s;
+	for(p = a; (dec16chr(*p) & 255) < i; p++)
+		;
 
 	mpbits(b, (p-a)*s);
 	b->top = 0;
@@ -64,7 +22,7 @@
 		for(i = 0; i < Dbits; i += s){
 			if(p <= a)
 				break;
-			x |= tab.t16[*(uchar*)--p]<<i;
+			x |= dec16chr(*--p)<<i;
 		}
 		b->p[b->top++] = x;
 	}
@@ -78,9 +36,8 @@
 	mpdigit x, y;
 	int i;
 
-	for(p = a; *p; p++)
-		if(tab.t10[*(uchar*)p] >= 8)
-			break;
+	for(p = a; ((*p - '0') & 255) < 8; p++)
+		;
 
 	mpbits(b, (p-a)*3);
 	b->top = 0;
@@ -89,7 +46,7 @@
 	i = 0;
 	x = y = 0;
 	while(p > a){
-		y = tab.t10[*(uchar*)--p];
+		y = *--p - '0';
 		x |= y << i;
 		i += 3;
 		if(i >= Dbits){
@@ -124,8 +81,8 @@
 		// do a billion at a time in native arithmetic
 		x = 0;
 		for(i = 0; i < 9; i++){
-			y = tab.t10[*(uchar*)a];
-			if(y == INVAL)
+			y = *a - '0';
+			if(y > 9)
 				break;
 			a++;
 			x *= 10;
@@ -139,7 +96,7 @@
 		uitomp(x, r);
 		mpmul(b, pow, b);
 		mpadd(b, r, b);
-		if(i != 9)
+		if(i < 9)
 			break;
 	}
 	mpfree(pow);
@@ -148,7 +105,7 @@
 }
 
 static char*
-fromdecx(char *a, mpint *b, uchar tab[256], int (*dec)(uchar*, int, char*, int))
+fromdecx(char *a, mpint *b, int (*chr)(int), int (*dec)(uchar*, int, char*, int))
 {
 	char *buf = a;
 	uchar *p;
@@ -155,7 +112,7 @@
 	int n, m;
 
 	b->top = 0;
-	for(; tab[*(uchar*)a] != INVAL; a++)
+	for(; (*chr)(*a) >= 0; a++)
 		;
 	n = a-buf;
 	if(n > 0){
@@ -181,9 +138,6 @@
 		setmalloctag(b, getcallerpc(&a));
 	}
 
-	if(tab.inited == 0)
-		init();
-
 	while(*a==' ' || *a=='\t')
 		a++;
 
@@ -230,10 +184,10 @@
 		e = frompow2(a, b, 4);
 		break;
 	case 32:
-		e = fromdecx(a, b, tab.t32, dec32);
+		e = fromdecx(a, b, dec32chr, dec32);
 		break;
 	case 64:
-		e = fromdecx(a, b, tab.t64, dec64);
+		e = fromdecx(a, b, dec64chr, dec64);
 		break;
 	default:
 		abort();