mp: add logic operations; mpfmt: include 0x with #
This commit is contained in:
parent
5f15532260
commit
87abbc649f
3 changed files with 210 additions and 1 deletions
|
@ -76,6 +76,15 @@ void mpmul(mpint *b1, mpint *b2, mpint *prod); /* prod = b1*b2 */
|
||||||
void mpexp(mpint *b, mpint *e, mpint *m, mpint *res); /* res = b**e mod m */
|
void mpexp(mpint *b, mpint *e, mpint *m, mpint *res); /* res = b**e mod m */
|
||||||
void mpmod(mpint *b, mpint *m, mpint *remainder); /* remainder = b mod m */
|
void mpmod(mpint *b, mpint *m, mpint *remainder); /* remainder = b mod m */
|
||||||
|
|
||||||
|
/* logical operations */
|
||||||
|
void mpand(mpint *b1, mpint *b2, mpint *res);
|
||||||
|
void mpbic(mpint *b1, mpint *b2, mpint *res);
|
||||||
|
void mpor(mpint *b1, mpint *b2, mpint *res);
|
||||||
|
void mpnot(mpint *b, mpint *res);
|
||||||
|
void mpxor(mpint *b1, mpint *b2, mpint *res);
|
||||||
|
void mptrunc(mpint *b, int n, mpint *res);
|
||||||
|
void mpxtend(mpint *b, int n, mpint *res);
|
||||||
|
|
||||||
/* modular arithmetic, time invariant when 0≤b1≤m-1 and 0≤b2≤m-1 */
|
/* modular arithmetic, time invariant when 0≤b1≤m-1 and 0≤b2≤m-1 */
|
||||||
void mpmodadd(mpint *b1, mpint *b2, mpint *m, mpint *sum); /* sum = b1+b2 % m */
|
void mpmodadd(mpint *b1, mpint *b2, mpint *m, mpint *sum); /* sum = b1+b2 % m */
|
||||||
void mpmodsub(mpint *b1, mpint *b2, mpint *m, mpint *diff); /* diff = b1-b2 % m */
|
void mpmodsub(mpint *b1, mpint *b2, mpint *m, mpint *diff); /* diff = b1-b2 % m */
|
||||||
|
|
|
@ -146,7 +146,13 @@ mpfmt(Fmt *fmt)
|
||||||
if(p == nil)
|
if(p == nil)
|
||||||
return fmtstrcpy(fmt, "*");
|
return fmtstrcpy(fmt, "*");
|
||||||
else{
|
else{
|
||||||
fmtstrcpy(fmt, p);
|
if((fmt->flags & FmtSharp) != 0 && fmt->prec!=10 && fmt->prec!=32 && fmt->prec!=64)
|
||||||
|
if(*p == '-')
|
||||||
|
fmtprint(fmt, "-0x%s", p + 1);
|
||||||
|
else
|
||||||
|
fmtprint(fmt, "0x%s", p);
|
||||||
|
else
|
||||||
|
fmtstrcpy(fmt, p);
|
||||||
free(p);
|
free(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
194
sys/src/libmp/port/mplogic.c
Normal file
194
sys/src/libmp/port/mplogic.c
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
#include "os.h"
|
||||||
|
#include <mp.h>
|
||||||
|
#include "dat.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
mplogic calculates b1|b2 subject to the
|
||||||
|
following flag bits (fl)
|
||||||
|
|
||||||
|
bit 0: subtract 1 from b1
|
||||||
|
bit 1: invert b1
|
||||||
|
bit 2: subtract 1 from b2
|
||||||
|
bit 3: invert b2
|
||||||
|
bit 4: add 1 to output
|
||||||
|
bit 5: invert output
|
||||||
|
|
||||||
|
it inverts appropriate bits automatically
|
||||||
|
depending on the signs of the inputs
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
mplogic(mpint *b1, mpint *b2, mpint *sum, int fl)
|
||||||
|
{
|
||||||
|
mpint *t;
|
||||||
|
mpdigit *dp1, *dp2, *dpo, d1, d2, d;
|
||||||
|
int c1, c2, co;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
assert(((b1->flags | b2->flags | sum->flags) & MPtimesafe) == 0);
|
||||||
|
if(b1->sign < 0) fl ^= 0x03;
|
||||||
|
if(b2->sign < 0) fl ^= 0x0c;
|
||||||
|
sum->sign = (int)(((fl|fl>>2)^fl>>4)<<30)>>31|1;
|
||||||
|
if(sum->sign < 0) fl ^= 0x30;
|
||||||
|
if(b2->top > b1->top){
|
||||||
|
t = b1;
|
||||||
|
b1 = b2;
|
||||||
|
b2 = t;
|
||||||
|
fl = fl >> 2 & 0x03 | fl << 2 & 0x0c | fl & 0x30;
|
||||||
|
}
|
||||||
|
mpbits(sum, b1->top*Dbits);
|
||||||
|
dp1 = b1->p;
|
||||||
|
dp2 = b2->p;
|
||||||
|
dpo = sum->p;
|
||||||
|
c1 = fl & 1;
|
||||||
|
c2 = fl >> 2 & 1;
|
||||||
|
co = fl >> 4 & 1;
|
||||||
|
for(i = 0; i < b1->top; i++){
|
||||||
|
d1 = dp1[i] - c1;
|
||||||
|
if(i < b2->top)
|
||||||
|
d2 = dp2[i] - c2;
|
||||||
|
else
|
||||||
|
d2 = 0;
|
||||||
|
if(d1 != (mpdigit)-1) c1 = 0;
|
||||||
|
if(d2 != (mpdigit)-1) c2 = 0;
|
||||||
|
if((fl & 2) != 0) d1 ^= -1;
|
||||||
|
if((fl & 8) != 0) d2 ^= -1;
|
||||||
|
d = d1 | d2;
|
||||||
|
if((fl & 32) != 0) d ^= -1;
|
||||||
|
d += co;
|
||||||
|
if(d != 0) co = 0;
|
||||||
|
dpo[i] = d;
|
||||||
|
}
|
||||||
|
sum->top = i;
|
||||||
|
mpnorm(sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpor(mpint *b1, mpint *b2, mpint *sum)
|
||||||
|
{
|
||||||
|
mplogic(b1, b2, sum, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpand(mpint *b1, mpint *b2, mpint *sum)
|
||||||
|
{
|
||||||
|
mplogic(b1, b2, sum, 0x2a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpbic(mpint *b1, mpint *b2, mpint *sum)
|
||||||
|
{
|
||||||
|
mplogic(b1, b2, sum, 0x22);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpnot(mpint *b, mpint *r)
|
||||||
|
{
|
||||||
|
mpadd(b, mpone, r);
|
||||||
|
r->sign ^= -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpxor(mpint *b1, mpint *b2, mpint *sum)
|
||||||
|
{
|
||||||
|
mpint *t;
|
||||||
|
mpdigit *dp1, *dp2, *dpo, d1, d2, d;
|
||||||
|
int c1, c2, co;
|
||||||
|
int i, fl;
|
||||||
|
|
||||||
|
assert(((b1->flags | b2->flags | sum->flags) & MPtimesafe) == 0);
|
||||||
|
if(b2->top > b1->top){
|
||||||
|
t = b1;
|
||||||
|
b1 = b2;
|
||||||
|
b2 = t;
|
||||||
|
}
|
||||||
|
fl = (b1->sign & 10) ^ (b2->sign & 12);
|
||||||
|
sum->sign = (int)(fl << 28) >> 31;
|
||||||
|
mpbits(sum, b1->top*Dbits);
|
||||||
|
dp1 = b1->p;
|
||||||
|
dp2 = b2->p;
|
||||||
|
dpo = sum->p;
|
||||||
|
c1 = fl >> 1 & 1;
|
||||||
|
c2 = fl >> 2 & 1;
|
||||||
|
co = fl >> 3 & 1;
|
||||||
|
for(i = 0; i < b1->top; i++){
|
||||||
|
d1 = dp1[i] - c1;
|
||||||
|
if(i < b2->top)
|
||||||
|
d2 = dp2[i] - c2;
|
||||||
|
else
|
||||||
|
d2 = 0;
|
||||||
|
if(d1 != (mpdigit)-1) c1 = 0;
|
||||||
|
if(d2 != (mpdigit)-1) c2 = 0;
|
||||||
|
d = d1 ^ d2;
|
||||||
|
d += co;
|
||||||
|
if(d != 0) co = 0;
|
||||||
|
dpo[i] = d;
|
||||||
|
}
|
||||||
|
sum->top = i;
|
||||||
|
mpnorm(sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mptrunc(mpint *b, int n, mpint *r)
|
||||||
|
{
|
||||||
|
int d, m, i, c;
|
||||||
|
|
||||||
|
assert(((b->flags | r->flags) & MPtimesafe) == 0);
|
||||||
|
mpbits(r, n);
|
||||||
|
r->top = DIGITS(n);
|
||||||
|
d = n / Dbits;
|
||||||
|
m = n % Dbits;
|
||||||
|
r->sign = 1;
|
||||||
|
if(b->sign == -1){
|
||||||
|
c = 1;
|
||||||
|
for(i = 0; i <= r->top; i++){
|
||||||
|
if(i < b->top)
|
||||||
|
r->p[i] = ~(b->p[i] - c);
|
||||||
|
else
|
||||||
|
r->p[i] = -1;
|
||||||
|
if(r->p[i] != 0)
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
if(m != 0)
|
||||||
|
r->p[d] &= (1<<m) - 1;
|
||||||
|
}else if(b->sign == 1){
|
||||||
|
if(d >= b->top){
|
||||||
|
mpassign(b, r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(b != r)
|
||||||
|
for(i = 0; i < d; i++)
|
||||||
|
r->p[i] = b->p[i];
|
||||||
|
if(m != 0)
|
||||||
|
r->p[d] = b->p[d] & (1<<m)-1;
|
||||||
|
}
|
||||||
|
mpnorm(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mpxtend(mpint *b, int n, mpint *r)
|
||||||
|
{
|
||||||
|
int d, m, c, i;
|
||||||
|
|
||||||
|
d = (n - 1) / Dbits;
|
||||||
|
m = (n - 1) % Dbits;
|
||||||
|
if(d >= b->top){
|
||||||
|
mpassign(b, r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mptrunc(b, n, r);
|
||||||
|
mpbits(r, n);
|
||||||
|
if((r->p[d] & 1<<m) == 0){
|
||||||
|
mpnorm(r);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
r->p[d] |= -(1<<m);
|
||||||
|
r->sign = -1;
|
||||||
|
c = 1;
|
||||||
|
for(i = 0; i < r->top; i++){
|
||||||
|
r->p[i] = ~(r->p[i] - c);
|
||||||
|
if(r->p[i] != 0)
|
||||||
|
c = 0;
|
||||||
|
}
|
||||||
|
mpnorm(r);
|
||||||
|
}
|
Loading…
Reference in a new issue