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();