diff options
author | nelsonb%netscape.com <devnull@localhost> | 2000-07-21 21:04:14 +0000 |
---|---|---|
committer | nelsonb%netscape.com <devnull@localhost> | 2000-07-21 21:04:14 +0000 |
commit | 1198ad2271334b727c590a3866d99d1960e5f690 (patch) | |
tree | 1de0ea2f6aff2ae3da8579a3e440047e9889c976 /security/nss/lib/freebl/mpi/mplogic.c | |
parent | dec9fa35dea0fa0fd2df505c0932b516294d7eac (diff) | |
download | nss-hg-1198ad2271334b727c590a3866d99d1960e5f690.tar.gz |
Implement mpl_get_bit, mpl_set_bit, mpl_significant_bits.
Diffstat (limited to 'security/nss/lib/freebl/mpi/mplogic.c')
-rw-r--r-- | security/nss/lib/freebl/mpi/mplogic.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/security/nss/lib/freebl/mpi/mplogic.c b/security/nss/lib/freebl/mpi/mplogic.c index 43553fe74..193d49046 100644 --- a/security/nss/lib/freebl/mpi/mplogic.c +++ b/security/nss/lib/freebl/mpi/mplogic.c @@ -43,6 +43,7 @@ /* Some things from the guts of the MPI library we make use of... */ extern mp_err s_mp_lshd(mp_int *mp, mp_size p); extern void s_mp_rshd(mp_int *mp, mp_size p); +extern mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */ #define s_mp_clamp(mp)\ { while(USED(mp) > 1 && DIGIT((mp), USED(mp) - 1) == 0) USED(mp) -= 1; } @@ -406,5 +407,84 @@ mp_err mpl_parity(mp_int *a) /* }}} */ +/* + mpl_set_bit + + Returns MP_OKAY or some error code. + Grows a if needed to set a bit to 1. + */ +mp_err mpl_set_bit(mp_int *a, unsigned int bitNum, unsigned int value) +{ + unsigned int ix; + mp_err rv; + mp_digit mask; + + ARGCHK(a != NULL, MP_BADARG); + + ix = bitNum / MP_DIGIT_BIT; + if (value && (ix > MP_USED(a) - 1)) { + rv = s_mp_pad(a, ix); + if (rv != MP_OKAY) + return rv; + } + + bitNum = bitNum % MP_DIGIT_BIT; + mask = (mp_digit)1 << bitNum; + if (value) + MP_DIGIT(a,ix) |= mask; + else + MP_DIGIT(a,ix) &= ~mask; + return MP_OKAY; +} + +/* + mpl_get_bit + + returns 0 or 1 or some (negative) error code. + */ +mp_err mpl_get_bit(mp_int *a, unsigned int bitNum) +{ + unsigned int bit, ix; + mp_err rv; + + ARGCHK(a != NULL, MP_BADARG); + + ix = bitNum / MP_DIGIT_BIT; + ARGCHK(ix > MP_USED(a) - 1, MP_RANGE); + + bit = bitNum % MP_DIGIT_BIT; + rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1; + return rv; +} + +/* + mpl_significant_bits + returns number of significnant bits in abs(a). + returns 1 if value is zero. + */ +mp_err mpl_significant_bits(mp_int *a) +{ + mp_err bits = 0; + int ix; + + ARGCHK(a != NULL, MP_BADARG); + + ix = MP_USED(a); + for (ix = MP_USED(a); ix > 0; ) { + mp_digit d = MP_DIGIT(a, --ix); + if (d) { + while (d) { + ++bits; + d >>= 1; + } + break; + } + } + bits += ix * MP_DIGIT_BIT; + if (!bits) + bits = 1; + return bits; +} + /*------------------------------------------------------------------------*/ /* HERE THERE BE DRAGONS */ |