|
2 | 2 | ##
|
3 | 3 | ## The bitwise operations behave as if negative numbers were represented in 2's complement.
|
4 | 4 |
|
5 |
| -import std/[algorithm, bitops, math, options] |
| 5 | +import std/[algorithm, bitops, endians, math, options] |
6 | 6 |
|
7 | 7 | type
|
8 | 8 | BigInt* = object
|
@@ -1304,3 +1304,26 @@ func powmod*(base, exponent, modulus: BigInt): BigInt =
|
1304 | 1304 | result = (result * basePow) mod modulus
|
1305 | 1305 | basePow = (basePow * basePow) mod modulus
|
1306 | 1306 | exponent = exponent shr 1
|
| 1307 | + |
| 1308 | +proc toBytes*(a: BigInt; endianness = system.cpuEndian): seq[byte] = |
| 1309 | + ## Convert a `BigInt` to a byte-sequence. |
| 1310 | + ## The byte-sequence *does not* include a sign-bit. |
| 1311 | + if not a.isZero: |
| 1312 | + result = newSeq[byte](a.limbs.len shl 2) |
| 1313 | + var i: int |
| 1314 | + case endianness |
| 1315 | + of bigEndian: |
| 1316 | + for s in [24, 16, 8, 0]: |
| 1317 | + result[i] = uint8(a.limbs[a.limbs.high] shr s) |
| 1318 | + if result[0] != 0x00: inc(i) |
| 1319 | + for l in countdown(a.limbs.high.pred, a.limbs.low): |
| 1320 | + bigEndian32(addr result[i], unsafeAddr a.limbs[l]) |
| 1321 | + inc(i, 4) |
| 1322 | + result.setLen(i) |
| 1323 | + of littleEndian: |
| 1324 | + for l in 0..a.limbs.high: |
| 1325 | + littleEndian32(addr result[i], unsafeAddr a.limbs[l]) |
| 1326 | + inc(i, 4) |
| 1327 | + while result[pred i] == 0x00: |
| 1328 | + dec i |
| 1329 | + result.setLen(i) |
0 commit comments